@churchapps/apihelper 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/auth/CustomAuthProvider.js +1 -1
  2. package/dist/controllers/CustomBaseController.d.ts.map +1 -1
  3. package/dist/controllers/CustomBaseController.js.map +1 -1
  4. package/dist/controllers/ErrorController.d.ts.map +1 -1
  5. package/dist/controllers/ErrorController.js +5 -5
  6. package/dist/controllers/ErrorController.js.map +1 -1
  7. package/dist/helpers/AwsHelper.d.ts.map +1 -1
  8. package/dist/helpers/AwsHelper.js.map +1 -1
  9. package/dist/helpers/BasePermissions.d.ts.map +1 -1
  10. package/dist/helpers/BasePermissions.js +3 -9
  11. package/dist/helpers/BasePermissions.js.map +1 -1
  12. package/dist/helpers/DB.d.ts.map +1 -1
  13. package/dist/helpers/DB.js +0 -1
  14. package/dist/helpers/DB.js.map +1 -1
  15. package/dist/helpers/DBCreator.d.ts.map +1 -1
  16. package/dist/helpers/DBCreator.js.map +1 -1
  17. package/dist/helpers/EmailHelper.d.ts +1 -1
  18. package/dist/helpers/EmailHelper.d.ts.map +1 -1
  19. package/dist/helpers/EmailHelper.js +11 -10
  20. package/dist/helpers/EmailHelper.js.map +1 -1
  21. package/dist/helpers/EncryptionHelper.d.ts.map +1 -1
  22. package/dist/helpers/EncryptionHelper.js +4 -4
  23. package/dist/helpers/EncryptionHelper.js.map +1 -1
  24. package/dist/helpers/EnvironmentBase.d.ts.map +1 -1
  25. package/dist/helpers/EnvironmentBase.js.map +1 -1
  26. package/dist/helpers/FileStorageHelper.d.ts.map +1 -1
  27. package/dist/helpers/FileStorageHelper.js.map +1 -1
  28. package/dist/helpers/LoggingHelper.d.ts.map +1 -1
  29. package/dist/helpers/LoggingHelper.js +1 -1
  30. package/dist/helpers/LoggingHelper.js.map +1 -1
  31. package/dist/helpers/MySqlHelper.d.ts.map +1 -1
  32. package/dist/helpers/MySqlHelper.js.map +1 -1
  33. package/dist/helpers/OmitEmpty.d.ts.map +1 -1
  34. package/dist/helpers/OmitEmpty.js +1 -1
  35. package/dist/helpers/OmitEmpty.js.map +1 -1
  36. package/dist/helpers/Pool.d.ts.map +1 -1
  37. package/dist/helpers/Pool.js +2 -2
  38. package/dist/helpers/Pool.js.map +1 -1
  39. package/dist/helpers/SlugHelper.d.ts.map +1 -1
  40. package/dist/helpers/SlugHelper.js +5 -3
  41. package/dist/helpers/SlugHelper.js.map +1 -1
  42. package/package.json +64 -70
  43. package/.github/FUNDING.yml +0 -1
  44. package/.prettierrc.json +0 -13
  45. package/CLAUDE.md +0 -110
  46. package/eslint.config.mjs +0 -40
  47. package/scripts/copy-assets.js +0 -35
  48. package/src/auth/AuthenticatedUser.ts +0 -44
  49. package/src/auth/CustomAuthProvider.ts +0 -25
  50. package/src/auth/Principal.ts +0 -38
  51. package/src/auth/index.ts +0 -3
  52. package/src/controllers/CustomBaseController.ts +0 -62
  53. package/src/controllers/ErrorController.ts +0 -33
  54. package/src/controllers/index.ts +0 -2
  55. package/src/helpers/AwsHelper.ts +0 -129
  56. package/src/helpers/BasePermissions.ts +0 -15
  57. package/src/helpers/DB.ts +0 -41
  58. package/src/helpers/DBCreator.ts +0 -39
  59. package/src/helpers/EmailHelper.ts +0 -95
  60. package/src/helpers/EncryptionHelper.ts +0 -25
  61. package/src/helpers/EnvironmentBase.ts +0 -36
  62. package/src/helpers/FileStorageHelper.ts +0 -71
  63. package/src/helpers/Interfaces.ts +0 -2
  64. package/src/helpers/LoggingHelper.ts +0 -71
  65. package/src/helpers/MySqlHelper.ts +0 -5
  66. package/src/helpers/OmitEmpty.ts +0 -128
  67. package/src/helpers/Pool.ts +0 -56
  68. package/src/helpers/SlugHelper.ts +0 -37
  69. package/src/helpers/index.ts +0 -17
  70. package/src/index.ts +0 -3
  71. package/src/models/ErrorLog.ts +0 -7
  72. package/src/models/index.ts +0 -1
  73. package/src/tools/templates/ChurchEmailTemplate.html +0 -383
  74. package/src/tools/templates/EmailTemplate.html +0 -424
  75. package/tsconfig.json +0 -26
@@ -1,129 +0,0 @@
1
- import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, CopyObjectCommand, ListObjectsV2Command, ListObjectsV2Output } from "@aws-sdk/client-s3";
2
- import { createPresignedPost } from "@aws-sdk/s3-presigned-post";
3
- import { EnvironmentBase } from "./EnvironmentBase.js";
4
- import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";
5
-
6
- export class AwsHelper {
7
-
8
- //Pulls from AWS SSM Parameter Store
9
- static async readParameter(parameterName: string): Promise<string> {
10
- let result = "";
11
- try {
12
- const ssm = new SSMClient({ region: "us-east-2" });
13
- const params = { Name: parameterName, WithDecryption: true };
14
- const command = new GetParameterCommand(params);
15
- const response = await ssm.send(command);
16
- result = response?.Parameter?.Value || "";
17
- } catch {
18
- result = "";
19
- }
20
- return result;
21
- }
22
-
23
-
24
- private static _client: S3Client;
25
-
26
- private static getClient(): S3Client {
27
- if (!this._client) {
28
- this._client = new S3Client({});
29
- }
30
- return this._client;
31
- }
32
-
33
- static async S3PresignedUrl(key: string): Promise<{url: string, fields: Record<string, string>, key: string}> {
34
- if (key.startsWith("/")) key = key.substring(1);
35
- const { url, fields } = await createPresignedPost(this.getClient(), {
36
- Bucket: EnvironmentBase.s3Bucket,
37
- Key: key,
38
- Conditions: [
39
- ["starts-with", "$Content-Type", ""],
40
- { acl: "public-read" }
41
- ],
42
- Expires: 3600 // 1 hour
43
- });
44
- return { url, fields, key };
45
- }
46
-
47
- static async S3Upload(key: string, contentType: string, contents: Buffer): Promise<void> {
48
- if (key.startsWith("/")) key = key.substring(1);
49
- const command = new PutObjectCommand({
50
- Bucket: EnvironmentBase.s3Bucket,
51
- Key: key,
52
- Body: contents,
53
- ACL: "public-read",
54
- ContentType: contentType
55
- });
56
- await this.getClient().send(command);
57
- }
58
-
59
- static async S3Remove(key: string): Promise<void> {
60
- if (key.startsWith("/")) key = key.substring(1);
61
- const command = new DeleteObjectCommand({
62
- Bucket: EnvironmentBase.s3Bucket,
63
- Key: key
64
- });
65
- await this.getClient().send(command);
66
- }
67
-
68
- static async S3Rename(oldKey: string, newKey: string): Promise<void> {
69
- console.log(`Renaming: ${oldKey} to ${newKey}`);
70
- await this.S3Copy(oldKey, newKey);
71
- await this.S3Remove(oldKey);
72
- }
73
-
74
- static S3Move(oldKey: string, newKey: string): Promise<void> {
75
- return this.S3Rename(oldKey, newKey);
76
- }
77
-
78
- static async S3Copy(oldKey: string, newKey: string): Promise<void> {
79
- const command = new CopyObjectCommand({
80
- Bucket: EnvironmentBase.s3Bucket,
81
- CopySource: `/${EnvironmentBase.s3Bucket}/${oldKey}`,
82
- Key: newKey,
83
- ACL: "public-read"
84
- });
85
- await this.getClient().send(command);
86
- }
87
-
88
- static async S3List(path: string): Promise<string[]> {
89
- return this.S3ListMultiPage(this.getClient(), EnvironmentBase.s3Bucket, path);
90
- }
91
-
92
- static async S3ListMultiPage(s3:S3Client, bucket:string, path: string): Promise<string[]> {
93
- const result: string[] = [];
94
- let continuationToken: string | undefined;
95
-
96
- do {
97
- const { Contents, NextContinuationToken } = await this.S3ListManual(s3, bucket, path, continuationToken);
98
- result.push(...(Contents?.map((item) => item.Key).filter((key): key is string => key !== undefined) || []));
99
- continuationToken = NextContinuationToken;
100
- } while (continuationToken);
101
-
102
- return result;
103
- }
104
-
105
- private static async S3ListManual(s3:S3Client, bucket:string, path: string, continuationToken?: string): Promise<ListObjectsV2Output> {
106
- const command = new ListObjectsV2Command({
107
- Bucket: bucket,
108
- Prefix: path,
109
- MaxKeys: 10000,
110
- ContinuationToken: continuationToken
111
- });
112
- return s3.send(command);
113
- }
114
-
115
- static async S3Read(key: string): Promise<string | null> {
116
- try {
117
- const command = new GetObjectCommand({
118
- Bucket: EnvironmentBase.s3Bucket,
119
- Key: key
120
- });
121
- const response = await this.getClient().send(command);
122
- return await response.Body?.transformToString();
123
- } catch (error) {
124
- console.error("Error reading from S3:", error);
125
- return null;
126
- }
127
- }
128
-
129
- }
@@ -1,15 +0,0 @@
1
- export class BasePermissions {
2
- static forms = {
3
- admin: { contentType: "Forms", action: "Admin" },
4
- edit: { contentType: "Forms", action: "Edit" }
5
- };
6
- static links = {
7
- edit: { contentType: "Links", action: "Edit" }
8
- };
9
- static pages = {
10
- edit: { contentType: "Pages", action: "Edit" }
11
- };
12
- static settings = {
13
- edit: { contentType: "Settings", action: "Edit" }
14
- };
15
- }
package/src/helpers/DB.ts DELETED
@@ -1,41 +0,0 @@
1
- import { Pool } from "./Pool.js";
2
- import { PoolConnection, QueryError } from "mysql2";
3
- import { LoggingHelper } from "./LoggingHelper.js";
4
-
5
- export class DB {
6
-
7
- // wraps in promise
8
- static async getConnection() {
9
- const promise: Promise<PoolConnection> = new Promise((resolve, reject) => {
10
- Pool.current.getConnection((ex: QueryError | null, conn: PoolConnection) => { if (ex) reject(ex); else resolve(conn); });
11
- });;
12
- const connection: PoolConnection = await promise;
13
- return connection;
14
- }
15
-
16
- // wraps in promise
17
- static async getQuery(connection: PoolConnection, sql: string, params: unknown[]) {
18
- const promise: Promise<unknown> = new Promise((resolve, reject) => {
19
- connection.query(sql, params, async (ex: QueryError | null, rows: unknown) => {
20
- if (ex) { LoggingHelper.getCurrent().error(ex); reject(ex); }
21
- else { resolve(rows); }
22
- });
23
- });
24
- const query: unknown = await promise;
25
- return query;
26
- }
27
-
28
- public static async query(sql: string, params: unknown[]) {
29
- let result: unknown = null;
30
- const connection = await this.getConnection();
31
- try { result = await this.getQuery(connection, sql, params); }
32
- catch (ex: unknown) { LoggingHelper.getCurrent().error(ex as Error); }
33
- finally { connection.release(); }
34
- return result;
35
- }
36
-
37
- public static async queryOne(sql: string, params: unknown[]) {
38
- const result = await this.query(sql, params) as unknown[];
39
- return result?.length > 0 ? result[0] : null;
40
- }
41
- }
@@ -1,39 +0,0 @@
1
- import dotenv from "dotenv";
2
- import fs from "fs";
3
- import { DB } from "./DB.js";
4
-
5
- export class DBCreator {
6
-
7
- private static tables: { title: string, file: string }[] = [
8
- { title: "Links", file: "links.mysql" },
9
- { title: "Pages", file: "pages.mysql" },
10
- { title: "Settings", file: "settings.mysql" }
11
- ]
12
-
13
- public static async init(selectedTables: string[]) {
14
- dotenv.config();
15
-
16
- const todo: { title: string, file: string }[] = [];
17
- selectedTables.forEach(async st => {
18
- this.tables.forEach(async t => {
19
- if (t.title === st) todo.push(t);
20
- });
21
- });
22
-
23
- for (const td of todo) await this.runScript(td.title, "./src/tools/dbScripts/" + td.file, false);
24
- return;
25
- }
26
-
27
- public static async runScript(title: string, file: string, customDelimeter: boolean) {
28
- console.log("Creating '" + title + "'");
29
- const sql = fs.readFileSync(file, "utf-8");
30
- let del = /;(?=END)\s*$|;(?!\nEND)\s*$/gm;
31
- if (customDelimeter) {
32
- del = /\$\$$/gm;
33
- }
34
- const statements = sql.split(del);
35
- for (const statement of statements) if (statement.length > 3) await DB.query(statement, []);
36
- }
37
-
38
-
39
- }
@@ -1,95 +0,0 @@
1
- import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';
2
- import nodemailer from 'nodemailer'
3
- // Removed nodemailer-direct-transport due to security vulnerabilities
4
- import { EnvironmentBase } from './EnvironmentBase.js';
5
- import { IEmailPayload } from './Interfaces.js';
6
- import fs from "fs";
7
- import path from "path";
8
-
9
- export class EmailHelper {
10
-
11
- private static getSESClient(): SESClient {
12
- return new SESClient({ region: "us-east-2" });
13
- }
14
-
15
- public static async sendTemplatedEmail(from: string, to: string, appName: string, appUrl: string, subject: string, contents: string, emailTemplate: "EmailTemplate.html" | "ChurchEmailTemplate.html" = "EmailTemplate.html", replyTo?: string) {
16
- if (!appName) appName = "B1";
17
- if (!appUrl) appUrl = "https://b1.church";
18
-
19
- const template = EmailHelper.readTemplate(emailTemplate);
20
- const emailBody = template
21
- .replace("{appLink}", "<a target='_blank' rel='noreferrer noopener' href=\"" + appUrl + "/\">" + appName + "</a>")
22
- .replace("{contents}", contents);
23
- await EmailHelper.sendEmail({ from, to, subject, body: emailBody, replyTo });
24
- }
25
-
26
- public static readTemplate(templateFile?: string) {
27
- if (!templateFile) templateFile = "EmailTemplate.html";
28
- const filePath = path.join(__dirname, "../../src/tools/templates/" + templateFile);
29
- const buffer = fs.readFileSync(filePath);
30
- const contents = buffer.toString();
31
- return contents;
32
- }
33
-
34
- private static async sendSes({ from, to, subject, body, replyTo }: IEmailPayload) {
35
- const sesClient = this.getSESClient();
36
- const sendCommand = new SendEmailCommand({
37
- Destination: {
38
- ToAddresses: [to]
39
- },
40
- Message: {
41
- Body: {
42
- Html: {
43
- Charset: 'UTF-8',
44
- Data: body
45
- }
46
- },
47
- Subject: {
48
- Charset: 'UTF-8',
49
- Data: subject
50
- }
51
- },
52
- Source: from,
53
- ReplyToAddresses: replyTo ? [replyTo] : undefined
54
- });
55
- await sesClient.send(sendCommand);
56
- }
57
-
58
- public static async sendEmail({ from, to, subject, body, replyTo }: IEmailPayload): Promise<void> {
59
- try {
60
- // Use a safer fallback - streamline transport (for testing/dev) or require proper SMTP config
61
- let transporter: nodemailer.Transporter = nodemailer.createTransport({
62
- streamTransport: true,
63
- newline: 'unix',
64
- buffer: true
65
- });
66
-
67
- if (EnvironmentBase.mailSystem === 'SES') {
68
- await this.sendSes({ from, to, subject, body, replyTo });
69
- } else {
70
- if (EnvironmentBase.mailSystem === "SMTP") {
71
- transporter = nodemailer.createTransport({
72
- host: EnvironmentBase.smtpHost,
73
- secure: EnvironmentBase.smtpSecure,
74
- auth: {
75
- user: EnvironmentBase.smtpUser,
76
- pass: EnvironmentBase.smtpPass
77
- }
78
- });
79
- }
80
-
81
- if (EnvironmentBase.mailSystem === "") {
82
- console.log("****Email server not configured: ");
83
- console.log(subject);
84
- console.log(body);
85
- } else {
86
- await transporter.sendMail({ from, to, subject, html: body, replyTo });
87
- }
88
- }
89
- return null;
90
- } catch (err) {
91
- throw err;
92
- }
93
- }
94
-
95
- }
@@ -1,25 +0,0 @@
1
- import crypto from "crypto";
2
- import { EnvironmentBase } from "./EnvironmentBase.js";
3
-
4
- export class EncryptionHelper {
5
- private static algorithm = 'aes-256-ctr';
6
-
7
- static encrypt = (plainValue: string) => {
8
- const iv = crypto.randomBytes(16);
9
- const cipher = crypto.createCipheriv(EncryptionHelper.algorithm, EnvironmentBase.encryptionKey, iv);
10
- const encrypted = Buffer.concat([cipher.update(plainValue), cipher.final()]);
11
- return iv.toString('base64') + "|" + encrypted.toString('base64');
12
- }
13
-
14
- static decrypt = (encryptedPair: string) => {
15
- const parts = encryptedPair.split("|");
16
- if (parts.length !== 2) return "";
17
- else {
18
- const iv = Buffer.from(parts[0], 'base64');
19
- const content = Buffer.from(parts[1], 'base64');
20
- const decipher = crypto.createDecipheriv(EncryptionHelper.algorithm, EnvironmentBase.encryptionKey, iv);
21
- const decrpyted = Buffer.concat([decipher.update(content), decipher.final()]);
22
- return decrpyted.toString();
23
- }
24
- }
25
- }
@@ -1,36 +0,0 @@
1
- import { AwsHelper } from "./AwsHelper.js";
2
-
3
- export class EnvironmentBase {
4
- static appEnv: string;
5
- static appName: string;
6
- static s3Bucket: string;
7
- static connectionString: string;
8
- static contentRoot: string;
9
- static encryptionKey: string;
10
- static fileStore: string;
11
- static jwtSecret: string;
12
-
13
- static mailSystem: string;
14
- static smtpHost: string;
15
- static smtpPass: string;
16
- static smtpSecure: boolean;
17
- static smtpUser: string;
18
-
19
-
20
- static async populateBase(jsonData: Record<string, unknown>, appName:string, appEnv: string) {
21
- EnvironmentBase.appName = jsonData.appName as string;
22
- EnvironmentBase.appEnv = jsonData.appEnv as string;
23
- EnvironmentBase.connectionString = process.env.CONNECTION_STRING || await AwsHelper.readParameter(`/${appEnv}/${appName}/connectionString`);
24
- EnvironmentBase.contentRoot = jsonData.contentRoot as string;
25
- EnvironmentBase.encryptionKey = process.env.ENCRYPTION_KEY || await AwsHelper.readParameter(`/${appEnv}/encryptionKey`);
26
- EnvironmentBase.fileStore = jsonData.fileStore as string;
27
- EnvironmentBase.jwtSecret = process.env.JWT_SECRET || await AwsHelper.readParameter(`/${appEnv}/jwtSecret`);
28
- EnvironmentBase.mailSystem = jsonData.mailSystem as string;
29
- EnvironmentBase.s3Bucket = jsonData.s3Bucket as string;
30
- EnvironmentBase.smtpHost = process.env.SMTP_HOST;
31
- EnvironmentBase.smtpPass = process.env.SMTP_PASS;
32
- EnvironmentBase.smtpSecure = process.env.SMTP_SECURE === "true";
33
- EnvironmentBase.smtpUser = process.env.SMTP_USER;
34
- }
35
-
36
- }
@@ -1,71 +0,0 @@
1
- import { AwsHelper } from "./AwsHelper.js";
2
- import fs from "fs";
3
- import path from "path";
4
- import { EnvironmentBase } from "./EnvironmentBase.js";
5
-
6
- export class FileStorageHelper {
7
- private static rootPath = path.resolve("./content") + "/";
8
-
9
- static list = async (filePath: string) => {
10
- let result = []
11
- switch (EnvironmentBase.fileStore) {
12
- case "S3": result = await AwsHelper.S3List(filePath); break;
13
- default: result = await FileStorageHelper.listLocal(filePath); break;
14
- }
15
- return result
16
- }
17
-
18
- static move = async (oldKey: string, newKey: string) => {
19
- switch (EnvironmentBase.fileStore) {
20
- case "S3": await AwsHelper.S3Move(oldKey, newKey); break;
21
- default: await FileStorageHelper.moveLocal(oldKey, newKey); break;
22
- }
23
- }
24
-
25
- static store = async (key: string, contentType: string, contents: Buffer) => {
26
- switch (EnvironmentBase.fileStore) {
27
- case "S3": await AwsHelper.S3Upload(key, contentType, contents); break;
28
- default: await FileStorageHelper.storeLocal(key, contents); break;
29
- }
30
- }
31
-
32
- static remove = async (key: string) => {
33
- switch (EnvironmentBase.fileStore) {
34
- case "S3": await AwsHelper.S3Remove(key); break;
35
- default: await FileStorageHelper.removeLocal(key); break;
36
- }
37
- }
38
-
39
- static removeFolder = async (key: string) => {
40
- switch (EnvironmentBase.fileStore) {
41
- case "S3": break; // no need on s3
42
- default: await FileStorageHelper.removeLocalFolder(key); break;
43
- }
44
- }
45
-
46
- private static storeLocal = async (key: string, contents: Buffer) => {
47
- const fileName = FileStorageHelper.rootPath + key;
48
- const dirName = path.dirname(fileName);
49
- if (!fs.existsSync(dirName)) fs.mkdirSync(dirName, { recursive: true });
50
- fs.writeFileSync(fileName, contents);
51
- }
52
-
53
- private static moveLocal = async (oldKey: string, newKey: string) => {
54
- fs.rename(oldKey, newKey, err => { throw err; });
55
- }
56
-
57
- private static removeLocal = async (key: string) => {
58
- fs.unlinkSync(FileStorageHelper.rootPath + key);
59
- }
60
-
61
- private static removeLocalFolder = async (key: string) => {
62
- fs.rmdirSync(FileStorageHelper.rootPath + key);
63
- }
64
-
65
- private static listLocal = async (filePath: string) => {
66
- const fullPath = FileStorageHelper.rootPath + filePath;
67
- if (!fs.existsSync(fullPath)) return [];
68
- else return fs.readdirSync(FileStorageHelper.rootPath + filePath);
69
- }
70
-
71
- }
@@ -1,2 +0,0 @@
1
- export interface IPermission { contentType: string; action: string; apiName?: string }
2
- export interface IEmailPayload { from: string, to: string, subject: string, body: string, replyTo?: string }
@@ -1,71 +0,0 @@
1
- import winston from "winston";
2
- import WinstonCloudWatch from "winston-cloudwatch";
3
- //import AWS from "aws-sdk";
4
- import { EnvironmentBase } from "./EnvironmentBase.js";
5
-
6
- export class LoggingHelper {
7
- private static _current: LoggingHelper = null;
8
- public static getCurrent = () => {
9
- if (LoggingHelper._current === null) {
10
- LoggingHelper._current = new LoggingHelper();
11
- LoggingHelper._current.init("API");
12
- }
13
- return LoggingHelper._current;
14
- }
15
-
16
- private _logger: winston.Logger = null;
17
- private wc: WinstonCloudWatch;
18
- private pendingMessages = false;
19
- private logGroupName = EnvironmentBase.appName + "_" + EnvironmentBase.appEnv;
20
- private logDestination = "console";
21
-
22
-
23
-
24
- public error(msg: string | object) {
25
- throw msg instanceof Error ? msg : new Error(typeof msg === 'string' ? msg : JSON.stringify(msg));
26
- }
27
-
28
- public info(msg: string | object) {
29
- if (this._logger === null) this.init("API");
30
- this.pendingMessages = true;
31
- this._logger.info(msg);
32
- }
33
-
34
- public log(streamName: string, level: string, msg: string | object) {
35
- if (this._logger === null) this.init(streamName);
36
- this.pendingMessages = true;
37
- if (level === "info") this._logger.info(msg);
38
- else this._logger.error(msg);
39
- }
40
-
41
-
42
- private init(streamName: string) {
43
- this.pendingMessages = false;
44
- //AWS.config.update({ region: "us-east-2" });
45
- if (EnvironmentBase.appEnv === "staging") this.logDestination = "cloudwatch";
46
- else if (EnvironmentBase.appEnv === "prod") this.logDestination = "cloudwatch";
47
-
48
- if (this.logDestination === "cloudwatch") {
49
- this.wc = new WinstonCloudWatch({ logGroupName: this.logGroupName, logStreamName: streamName, name: this.logGroupName + "_" + streamName });
50
- this._logger = winston.createLogger({ transports: [this.wc], format: winston.format.json() });
51
- } else this._logger = winston.createLogger({ transports: [new winston.transports.Console()], format: winston.format.json() });
52
- this._logger.info("Logger initialized");
53
- }
54
-
55
- public flush() {
56
- const promise = new Promise((resolve) => {
57
- if (this.pendingMessages) {
58
- if (this.wc) {
59
- this.wc.kthxbye(() => {
60
- // this._logger = null;
61
- this.pendingMessages = false;
62
- });
63
- }
64
- resolve(null);
65
- } else resolve(null);
66
- });
67
- return promise;
68
- }
69
-
70
-
71
- }
@@ -1,5 +0,0 @@
1
- export class MySqlHelper {
2
- static toQuotedAndCommaSeparatedString(values: string[]) {
3
- return values.length === 0 ? "" : "'" + values.join("','") + "'";
4
- }
5
- }
@@ -1,128 +0,0 @@
1
- // Based on https://www.npmjs.com/package/omit-empty
2
- // The project appears to be abandoned, but needed modification to allow for empty arrays.
3
-
4
- "use strict";
5
-
6
-
7
- interface OmitEmptyOptions {
8
- omitZero?: boolean;
9
- omitEmptyArray?: boolean;
10
- excludedProperties?: string[];
11
- }
12
-
13
- interface RuntimeOptions {
14
- omitZero: boolean;
15
- omitEmptyArray: boolean;
16
- excludedProperties: string[];
17
- }
18
-
19
- export class OmitEmpty {
20
- public static omitEmpty(obj: unknown, options: OmitEmptyOptions = {}): unknown {
21
- const runtimeOpts = OmitEmpty._buildRuntimeOpts(options);
22
-
23
- const omit = (value: unknown, opts: RuntimeOptions): unknown => {
24
- if (Array.isArray(value)) {
25
- value = value.map(v => omit(v, opts)).filter(v => !OmitEmpty.isEmpty(v, opts));
26
- }
27
-
28
- if (OmitEmpty.getType(value) === "object" && value !== null) {
29
- const result: Record<string, unknown> = {};
30
- for (const key of Object.keys(value as Record<string, unknown>)) {
31
- if (!opts.excludedProperties.includes(key)) {
32
- const val = omit((value as Record<string, unknown>)[key], opts);
33
- if (val !== void 0) {
34
- result[key] = val;
35
- }
36
- }
37
- }
38
- value = result;
39
- }
40
-
41
- if (!OmitEmpty.isEmpty(value, opts)) {
42
- return value;
43
- }
44
- };
45
-
46
- const res = omit(obj, runtimeOpts);
47
- if (res === void 0) {
48
- return OmitEmpty.getType(obj) === "object" ? {} : res;
49
- }
50
- return res;
51
- }
52
-
53
-
54
- private static _buildRuntimeOpts(options: OmitEmptyOptions = {}): RuntimeOptions {
55
- return {
56
- omitZero: options.omitZero || false,
57
- omitEmptyArray: options.omitEmptyArray || false,
58
- excludedProperties: options.excludedProperties || []
59
- };
60
- };
61
-
62
- private static getType(value: unknown): string {
63
- if (value === null) return "null";
64
- if (value === undefined) return "undefined";
65
- if (Array.isArray(value)) return "array";
66
- if (value instanceof Date) return "date";
67
- if (value instanceof RegExp) return "regexp";
68
- if (value instanceof Error) return "error";
69
- if (value instanceof Map) return "map";
70
- if (value instanceof Set) return "set";
71
- if (value instanceof File) return "file";
72
-
73
- const type = typeof value;
74
- if (type === "object") {
75
- // Check if it's an arguments object
76
- if (Object.prototype.toString.call(value) === '[object Arguments]') {
77
- return "arguments";
78
- }
79
- }
80
- return type;
81
- }
82
-
83
- private static isEmpty(value: unknown, runtimeOpts: RuntimeOptions): boolean {
84
- switch (OmitEmpty.getType(value)) {
85
- case "null":
86
- case "undefined":
87
- return true;
88
- case "boolean":
89
- case "function":
90
- case "date":
91
- case "regexp":
92
- return false;
93
- case "string":
94
- case "arguments":
95
- return (value as string).length === 0;
96
- case "file":
97
- case "map":
98
- case "set":
99
- return (value as { size: number }).size === 0;
100
- case "number":
101
- return runtimeOpts.omitZero ? value === 0 : false;
102
- case "error":
103
- return (value as Error).message === "";
104
- case "array":
105
- if (runtimeOpts.omitEmptyArray) {
106
- for (const ele of (value as unknown[])) {
107
- if (!OmitEmpty.isEmpty(ele, runtimeOpts)) {
108
- return false;
109
- }
110
- }
111
- return true;
112
- } else {
113
- return false;
114
- }
115
- case "object":
116
- for (const key of Object.keys(value as Record<string, unknown>)) {
117
- if (!OmitEmpty.isEmpty((value as Record<string, unknown>)[key], runtimeOpts)) {
118
- return false;
119
- }
120
- }
121
- return true;
122
- default: {
123
- return true;
124
- }
125
- }
126
- }
127
-
128
- }