@churchapps/helpers 1.2.24 → 1.2.26

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 (43) hide show
  1. package/dist/interfaces/Messaging.d.ts +21 -0
  2. package/dist/interfaces/Messaging.d.ts.map +1 -1
  3. package/dist/interfaces/Permissions.d.ts +9 -0
  4. package/dist/interfaces/Permissions.d.ts.map +1 -1
  5. package/dist/interfaces/Permissions.js +5 -0
  6. package/dist/interfaces/Permissions.js.map +1 -1
  7. package/package.json +10 -5
  8. package/.github/FUNDING.yml +0 -1
  9. package/.yarnrc.yml +0 -6
  10. package/eslint.config.js +0 -48
  11. package/scripts/build-cjs.js +0 -33
  12. package/src/ApiHelper.ts +0 -169
  13. package/src/AppearanceHelper.ts +0 -69
  14. package/src/ArrayHelper.ts +0 -139
  15. package/src/CommonEnvironmentHelper.ts +0 -104
  16. package/src/CurrencyHelper.ts +0 -66
  17. package/src/DateHelper.ts +0 -180
  18. package/src/DonationHelper.ts +0 -25
  19. package/src/ErrorHelper.ts +0 -38
  20. package/src/EventHelper.ts +0 -83
  21. package/src/FileHelper.ts +0 -57
  22. package/src/PersonHelper.ts +0 -80
  23. package/src/PlanHelper.ts +0 -135
  24. package/src/UniqueIdHelper.ts +0 -159
  25. package/src/UserHelper.ts +0 -61
  26. package/src/contentProviders/ContentProvider.ts +0 -15
  27. package/src/contentProviders/LessonsContentProvider.ts +0 -278
  28. package/src/contentProviders/index.ts +0 -2
  29. package/src/index.ts +0 -16
  30. package/src/interfaces/Access.ts +0 -138
  31. package/src/interfaces/Attendance.ts +0 -45
  32. package/src/interfaces/Content.ts +0 -84
  33. package/src/interfaces/Doing.ts +0 -142
  34. package/src/interfaces/Donation.ts +0 -193
  35. package/src/interfaces/Error.ts +0 -17
  36. package/src/interfaces/Lessons.ts +0 -61
  37. package/src/interfaces/Membership.ts +0 -184
  38. package/src/interfaces/Messaging.ts +0 -96
  39. package/src/interfaces/Permissions.ts +0 -78
  40. package/src/interfaces/Reporting.ts +0 -41
  41. package/src/interfaces/UserContextInterface.ts +0 -13
  42. package/src/interfaces/index.ts +0 -14
  43. package/tsconfig.json +0 -36
@@ -1,104 +0,0 @@
1
-
2
- export class CommonEnvironmentHelper {
3
- public static AttendanceApi = "";
4
- public static DoingApi = "";
5
- public static GivingApi = "";
6
- public static MembershipApi = "";
7
- public static ReportingApi = "";
8
- public static MessagingApi = "";
9
- public static MessagingApiSocket = "";
10
- public static ContentApi = "";
11
- public static AskApi = "";
12
- public static GoogleAnalyticsTag = "";
13
-
14
- static ContentRoot = "";
15
- static B1Root = "";
16
- static B1AdminRoot = "";
17
- static LessonsRoot = "";
18
-
19
- static init = (stage: string) => {
20
- switch (stage) {
21
- case "demo": CommonEnvironmentHelper.initDemo(); break;
22
- case "staging": CommonEnvironmentHelper.initStaging(); break;
23
- case "prod": CommonEnvironmentHelper.initProd(); break;
24
- default: CommonEnvironmentHelper.initDev(); break;
25
- }
26
- };
27
-
28
- static initDev = () => {
29
- this.initStaging(); //Use staging values for anything not provided
30
- CommonEnvironmentHelper.AttendanceApi = process.env.REACT_APP_ATTENDANCE_API || process.env.NEXT_PUBLIC_ATTENDANCE_API || CommonEnvironmentHelper.AttendanceApi;
31
- CommonEnvironmentHelper.DoingApi = process.env.REACT_APP_DOING_API || process.env.NEXT_PUBLIC_DOING_API || CommonEnvironmentHelper.DoingApi;
32
- CommonEnvironmentHelper.GivingApi = process.env.REACT_APP_GIVING_API || process.env.NEXT_PUBLIC_GIVING_API || CommonEnvironmentHelper.GivingApi;
33
- CommonEnvironmentHelper.MembershipApi = process.env.REACT_APP_MEMBERSHIP_API || process.env.NEXT_PUBLIC_MEMBERSHIP_API || CommonEnvironmentHelper.MembershipApi;
34
- CommonEnvironmentHelper.ReportingApi = process.env.REACT_APP_REPORTING_API || process.env.NEXT_PUBLIC_REPORTING_API || CommonEnvironmentHelper.ReportingApi;
35
- CommonEnvironmentHelper.MessagingApi = process.env.REACT_APP_MESSAGING_API || process.env.NEXT_PUBLIC_MESSAGING_API || CommonEnvironmentHelper.MessagingApi;
36
- CommonEnvironmentHelper.MessagingApiSocket = process.env.REACT_APP_MESSAGING_API_SOCKET || process.env.NEXT_PUBLIC_MESSAGING_API_SOCKET || CommonEnvironmentHelper.MessagingApiSocket;
37
- CommonEnvironmentHelper.ContentApi = process.env.REACT_APP_CONTENT_API || process.env.NEXT_PUBLIC_CONTENT_API || CommonEnvironmentHelper.ContentApi;
38
- CommonEnvironmentHelper.AskApi = process.env.REACT_APP_ASK_API || process.env.NEXT_PUBLIC_ASK_API || CommonEnvironmentHelper.AskApi;
39
- CommonEnvironmentHelper.GoogleAnalyticsTag = process.env.REACT_APP_GOOGLE_ANALYTICS || process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS || CommonEnvironmentHelper.GoogleAnalyticsTag;
40
-
41
- CommonEnvironmentHelper.ContentRoot = process.env.REACT_APP_CONTENT_ROOT || process.env.NEXT_PUBLIC_CONTENT_ROOT || CommonEnvironmentHelper.ContentRoot;
42
- CommonEnvironmentHelper.B1Root = process.env.REACT_APP_B1_ROOT || process.env.NEXT_PUBLIC_B1_ROOT || CommonEnvironmentHelper.B1Root;
43
- CommonEnvironmentHelper.B1AdminRoot = process.env.REACT_APP_B1ADMIN_ROOT || process.env.NEXT_PUBLIC_B1ADMIN_ROOT || CommonEnvironmentHelper.B1AdminRoot;
44
- CommonEnvironmentHelper.LessonsRoot = process.env.REACT_APP_LESSONS_ROOT || process.env.NEXT_PUBLIC_LESSONS_ROOT || CommonEnvironmentHelper.LessonsRoot;
45
- };
46
-
47
- //NOTE: None of these values are secret.
48
- static initDemo = () => {
49
- CommonEnvironmentHelper.AttendanceApi = "https://api.demo.churchapps.org/attendance";
50
- CommonEnvironmentHelper.DoingApi = "https://api.demo.churchapps.org/doing";
51
- CommonEnvironmentHelper.GivingApi = "https://api.demo.churchapps.org/giving";
52
- CommonEnvironmentHelper.MembershipApi = "https://api.demo.churchapps.org/membership";
53
- CommonEnvironmentHelper.ReportingApi = "https://api.demo.churchapps.org/reporting";
54
- CommonEnvironmentHelper.MessagingApi = "https://api.demo.churchapps.org/messaging";
55
- CommonEnvironmentHelper.MessagingApiSocket = "wss://socket.demo.churchapps.org";
56
- CommonEnvironmentHelper.ContentApi = "https://api.demo.churchapps.org/content";
57
- CommonEnvironmentHelper.AskApi = "https://askapi.demo.churchapps.org";
58
- CommonEnvironmentHelper.GoogleAnalyticsTag = "";
59
-
60
- CommonEnvironmentHelper.ContentRoot = "https://democontent.churchapps.org";
61
- CommonEnvironmentHelper.B1Root = "https://{key}.demo.b1.church";
62
- CommonEnvironmentHelper.B1AdminRoot = "https://demo.b1.church";
63
- CommonEnvironmentHelper.LessonsRoot = "https://demo.lessons.church";
64
- };
65
-
66
- //NOTE: None of these values are secret.
67
- static initStaging = () => {
68
- CommonEnvironmentHelper.AttendanceApi = "https://api.staging.churchapps.org/attendance";
69
- CommonEnvironmentHelper.DoingApi = "https://api.staging.churchapps.org/doing";
70
- CommonEnvironmentHelper.GivingApi = "https://api.staging.churchapps.org/giving";
71
- CommonEnvironmentHelper.MembershipApi = "https://api.staging.churchapps.org/membership";
72
- CommonEnvironmentHelper.ReportingApi = "https://api.staging.churchapps.org/reporting";
73
- CommonEnvironmentHelper.MessagingApi = "https://api.staging.churchapps.org/messaging";
74
- CommonEnvironmentHelper.MessagingApiSocket = "wss://socket.staging.churchapps.org";
75
- CommonEnvironmentHelper.ContentApi = "https://api.staging.churchapps.org/content";
76
- CommonEnvironmentHelper.AskApi = "https://askapi.staging.churchapps.org";
77
- CommonEnvironmentHelper.GoogleAnalyticsTag = "";
78
-
79
- CommonEnvironmentHelper.ContentRoot = "https://content.staging.churchapps.org";
80
- CommonEnvironmentHelper.B1Root = "https://{key}.staging.b1.church";
81
- CommonEnvironmentHelper.B1AdminRoot = "https://admin.staging.b1.church";
82
- CommonEnvironmentHelper.LessonsRoot = "https://staging.lessons.church";
83
- };
84
-
85
- //NOTE: None of these values are secret.
86
- static initProd = () => {
87
- CommonEnvironmentHelper.AttendanceApi = "https://api.churchapps.org/attendance";
88
- CommonEnvironmentHelper.DoingApi = "https://api.churchapps.org/doing";
89
- CommonEnvironmentHelper.GivingApi = "https://api.churchapps.org/giving";
90
- CommonEnvironmentHelper.MembershipApi = "https://api.churchapps.org/membership";
91
- CommonEnvironmentHelper.ReportingApi = "https://api.churchapps.org/reporting";
92
- CommonEnvironmentHelper.MessagingApi = "https://api.churchapps.org/messaging";
93
- CommonEnvironmentHelper.MessagingApiSocket = "wss://socket.churchapps.org";
94
- CommonEnvironmentHelper.ContentApi = "https://api.churchapps.org/content";
95
- CommonEnvironmentHelper.AskApi = "https://askapi.churchapps.org";
96
-
97
- CommonEnvironmentHelper.ContentRoot = "https://content.churchapps.org";
98
- CommonEnvironmentHelper.B1Root = "https://{key}.b1.church";
99
- CommonEnvironmentHelper.B1AdminRoot = "https://admin.b1.church";
100
- CommonEnvironmentHelper.LessonsRoot = "https://lessons.church";
101
- };
102
-
103
- }
104
-
@@ -1,66 +0,0 @@
1
- export class CurrencyHelper {
2
- static formatCurrency(amount: number) {
3
- const formatter = new Intl.NumberFormat("en-US", {
4
- style: "currency",
5
- currency: "USD",
6
- minimumFractionDigits: 2
7
- });
8
- return formatter.format(amount);
9
- }
10
-
11
- static formatCurrencyWithLocale(amount: number, currency: string = "USD") {
12
- const normalizedCurrency = currency.toUpperCase();
13
- const locale = this.getLocaleForCurrency(normalizedCurrency);
14
-
15
- const formatter = new Intl.NumberFormat(locale, {
16
- style: "currency",
17
- currency: normalizedCurrency,
18
- minimumFractionDigits: 2
19
- });
20
- return formatter.format(amount);
21
- }
22
-
23
- static getCurrencySymbol(currency?: string) {
24
- const normalizedCurrency = currency?.toLowerCase() || "usd";
25
- const stripeCurrencyFees: any = {
26
- usd: { percent: 2.9, fixed: 0.3, symbol: "$" },
27
- eur: { percent: 2.9, fixed: 0.25, symbol: "€" },
28
- gbp: { percent: 2.9, fixed: 0.2, symbol: "£" },
29
- cad: { percent: 2.9, fixed: 0.3, symbol: "$" },
30
- aud: { percent: 2.9, fixed: 0.3, symbol: "$" },
31
- inr: { percent: 2.9, fixed: 3.0, symbol: "₹" },
32
- jpy: { percent: 2.9, fixed: 30.0, symbol: "¥" },
33
- sgd: { percent: 2.9, fixed: 0.5, symbol: "S$" },
34
- hkd: { percent: 2.9, fixed: 2.35, symbol: "元" },
35
- sek: { percent: 2.9, fixed: 2.5, symbol: "kr" },
36
- nok: { percent: 2.9, fixed: 2.0, symbol: "kr" },
37
- dkk: { percent: 2.9, fixed: 1.8, symbol: "kr" },
38
- chf: { percent: 2.9, fixed: 0.3, symbol: "CHF" },
39
- mxn: { percent: 2.9, fixed: 3.0, symbol: "MXN" },
40
- brl: { percent: 3.9, fixed: 0.5, symbol: "R$" }
41
- };
42
- return stripeCurrencyFees[normalizedCurrency]?.symbol || "$";
43
- }
44
-
45
- private static getLocaleForCurrency(currency: string): string {
46
- const currencyLocaleMap: { [key: string]: string } = {
47
- USD: "en-US",
48
- EUR: "en-GB",
49
- GBP: "en-GB",
50
- CAD: "en-CA",
51
- AUD: "en-AU",
52
- INR: "en-IN",
53
- JPY: "ja-JP",
54
- SGD: "en-SG",
55
- HKD: "en-HK",
56
- SEK: "sv-SE",
57
- NOK: "nb-NO",
58
- DKK: "da-DK",
59
- CHF: "de-CH",
60
- MXN: "es-MX",
61
- BRL: "pt-BR"
62
- };
63
-
64
- return currencyLocaleMap[currency] || "en-US";
65
- }
66
- }
package/src/DateHelper.ts DELETED
@@ -1,180 +0,0 @@
1
- import dayjs from "dayjs";
2
- import utc from "dayjs/plugin/utc.js";
3
- import customParseFormat from "dayjs/plugin/customParseFormat.js";
4
-
5
- // Extend dayjs with plugins
6
- dayjs.extend(utc);
7
- dayjs.extend(customParseFormat);
8
-
9
- export class DateHelper {
10
-
11
- //Fixes timezone issues when you just need the date.
12
- static toDate(input: any) {
13
- const str = input.toString();
14
- // Check if it's a YYYY-MM-DD format (HTML5 date input)
15
- const dateOnlyMatch = str.match(/^(\d{4})-(\d{2})-(\d{2})$/);
16
- if (dateOnlyMatch) {
17
- // Parse as local date at noon to avoid timezone issues
18
- const [, year, month, day] = dateOnlyMatch;
19
- return new Date(parseInt(year), parseInt(month) - 1, parseInt(day), 12, 0, 0);
20
- }
21
- // For other formats, use existing behavior
22
- return new Date(Date.parse(str.replace("Z", "")));
23
- }
24
-
25
- static toDateTime(input: any) {
26
- return new Date(Date.parse(input.toString()));
27
- }
28
-
29
- //obsolete. Do not use
30
- static convertToDate(input: any) {
31
- return this.toDateTime(input);
32
- }
33
-
34
- static addDays(date: Date, days: number) {
35
- const result = new Date(date.getTime());
36
- result.setDate(result.getDate() + days);
37
- return result;
38
- }
39
-
40
- static prettyDate(date: Date) {
41
- if (date === undefined || date === null) return "";
42
- return this.formatDateTime(date, "MMM d, yyyy");
43
- }
44
-
45
- static prettyDateTime(date: Date) {
46
- if (date === undefined || date === null) return "";
47
- return this.formatDateTime(date, "MMM d, yyyy h:mm a");
48
- }
49
-
50
- static prettyTime(date: Date) {
51
- if (date === undefined || date === null) return "";
52
- return this.formatDateTime(date, "h:mm a");
53
- }
54
-
55
- static getLastSunday() {
56
- const result = new Date();
57
- while (result.getDay() !== 0) result.setDate(result.getDate() - 1);
58
- return result;
59
- }
60
-
61
- static getNextSunday() {
62
- const result = this.getLastSunday();
63
- result.setDate(result.getDate() + 7);
64
- return result;
65
- }
66
-
67
- static getWeekSunday(year: number, week: number) {
68
- const result = new Date(year, 0, 1);
69
- while (result.getDay() !== 0) result.setDate(result.getDate() + 1);
70
- result.setDate(result.getDate() + ((week - 1) * 7));
71
- return result;
72
- }
73
-
74
- static formatHtml5Date(date: Date | string | null | undefined): string {
75
- if (!date) return "";
76
-
77
- // If already a YYYY-MM-DD string, return as-is
78
- if (typeof date === "string" && /^\d{4}-\d{2}-\d{2}$/.test(date)) return date;
79
-
80
- // If ISO string, extract date portion (ignore timezone)
81
- if (typeof date === "string") {
82
- const match = date.match(/^(\d{4}-\d{2}-\d{2})/);
83
- if (match) return match[1];
84
- }
85
-
86
- // For Date objects, use LOCAL year/month/day (not UTC)
87
- const d = date instanceof Date ? date : new Date(date);
88
- if (isNaN(d.getTime())) return "";
89
-
90
- const year = d.getFullYear();
91
- const month = String(d.getMonth() + 1).padStart(2, "0");
92
- const day = String(d.getDate()).padStart(2, "0");
93
- return `${year}-${month}-${day}`;
94
- }
95
-
96
- // For DATE-only fields - preserves calendar date without timezone conversion
97
- static toMysqlDateOnly(date: Date | string | null | undefined): string | null {
98
- if (date === null || date === undefined) return null;
99
-
100
- if (typeof date === "string") {
101
- const match = date.match(/^(\d{4}-\d{2}-\d{2})/);
102
- return match ? match[1] : null;
103
- }
104
-
105
- const year = date.getFullYear();
106
- const month = String(date.getMonth() + 1).padStart(2, "0");
107
- const day = String(date.getDate()).padStart(2, "0");
108
- return `${year}-${month}-${day}`;
109
- }
110
-
111
- static formatHtml5Time(time: Date): string {
112
- if (time === undefined || time === null) return "";
113
- const h = time.getHours();
114
- const m = time.getMinutes();
115
- const s = time.getSeconds();
116
- return `${h < 10 ? ("0" + h) : h}:${m < 10 ? ("0" + m) : m}:${s < 10 ? ("0" + s) : s}`;
117
- }
118
-
119
- static formatHtml5DateTime(date: Date): string {
120
- if (date === undefined || date === null) return "";
121
- else {
122
- return this.formatDateTime(date, "yyyy-MM-dd") + "T" + this.formatDateTime(date, "HH:mm");
123
- }
124
- }
125
-
126
- static getDisplayDuration(d: Date): string {
127
- const seconds = Math.round((new Date().getTime() - d.getTime()) / 1000);
128
- if (seconds > 86400) {
129
- const days = Math.floor(seconds / 86400);
130
- return (days === 1) ? "1d" : days.toString() + "d";
131
- } else if (seconds > 3600) {
132
- const hours = Math.floor(seconds / 3600);
133
- return (hours === 1) ? "1h" : hours.toString() + "h";
134
- } else if (seconds > 60) {
135
- const minutes = Math.floor(seconds / 60);
136
- return (minutes === 1) ? "1m" : minutes.toString() + "m";
137
- } else return (seconds === 1) ? "1s" : Math.floor(seconds).toString() + "s";
138
- }
139
-
140
- static getShortDate(d: Date): string {
141
- return (d.getMonth() + 1).toString() + "/" + (d.getDate()).toString() + "/" + d.getFullYear().toString();
142
- }
143
-
144
- static convertDatePickerFormat(d: Date): Date {
145
- const date = this.formatHtml5Date(d).split("-");
146
- if (date.length === 3) return new Date(`${date[1]}-${date[2]}-${date[0]}`);
147
- return new Date();
148
- }
149
-
150
- private static formatDateTime(date: Date, format: string) {
151
- try {
152
- // Convert date-fns format to dayjs format
153
- const dayjsFormat = format
154
- .replace(/yyyy/g, "YYYY")
155
- .replace(/yy/g, "YY")
156
- .replace(/d/g, "D")
157
- .replace(/DD/g, "DD")
158
- .replace(/a/g, "A");
159
-
160
- return dayjs(date).format(dayjsFormat);
161
- } catch { return ""; }
162
- }
163
-
164
- public static toMysqlDate(d: Date) {
165
- if (d === null || d === undefined) {
166
- return undefined;
167
- }
168
- return dayjs(d).format("YYYY-MM-DD HH:mm:ss");
169
- }
170
-
171
- public static subtractHoursFromNow(hour: number) {
172
- const now = new Date();
173
- return new Date(now.setHours(now.getHours() - hour));
174
- }
175
-
176
- public static toUTCDate(d: Date) {
177
- return dayjs(d).utc().format("YYYY-MM-DD HH:mm:ss");
178
- }
179
-
180
- }
@@ -1,25 +0,0 @@
1
- export class DonationHelper {
2
-
3
- static getInterval(intervalName:string) {
4
- let intervalCount = 1;
5
- let intervalType = "month";
6
- const parts = intervalName.split("_");
7
- if (parts.length === 2) {
8
- switch (parts[0]) {
9
- case "two": intervalCount = 2; break;
10
- case "three": intervalCount = 3; break;
11
- }
12
- intervalType = parts[1];
13
- }
14
- const result = { interval_count: intervalCount, interval: intervalType };
15
- return result;
16
- }
17
-
18
- static getIntervalKeyName(intervalCount: number, intervalType: string) {
19
- let firstPart = "one";
20
- if (intervalCount === 2) firstPart = "two";
21
- else if (intervalCount === 3) firstPart = "three";
22
- return firstPart + "_" + intervalType;
23
- }
24
-
25
- }
@@ -1,38 +0,0 @@
1
- import { ErrorLogInterface, ErrorAppDataInterface } from "./interfaces/Error.js";
2
-
3
-
4
- export class ErrorHelper {
5
-
6
- static getAppData: () => { churchId: string, userId: string, originUrl: string, application: string };
7
- static customErrorHandler: (errorLog: ErrorLogInterface) => void;
8
-
9
- static init = (getAppData: () => ErrorAppDataInterface, customErrorHandler: (errorLog: ErrorLogInterface) => void) => {
10
- ErrorHelper.getAppData = getAppData;
11
- ErrorHelper.customErrorHandler = customErrorHandler;
12
- };
13
-
14
- static logError = (errorType: string, message: string, details: string) => {
15
-
16
-
17
- if (this.getAppData) {
18
- const data = this.getAppData();
19
- const log: ErrorLogInterface = {
20
- application: data.application,
21
- errorTime: new Date(),
22
- userId: data.userId,
23
- churchId: data.churchId,
24
- originUrl: data.originUrl,
25
- errorType: errorType,
26
- message: message,
27
- details: details
28
- };
29
-
30
- if (log.errorType === "401" && log.message.indexOf("/users/login") > -1) return;
31
- //temporarily disabled error logging
32
- //ApiHelper.postAnonymous("/errors", [log], "MembershipApi");
33
- if (ErrorHelper.customErrorHandler) ErrorHelper.customErrorHandler(log);
34
- }
35
- };
36
-
37
-
38
- }
@@ -1,83 +0,0 @@
1
- import { EventInterface } from "./interfaces/index.js";
2
-
3
- // Lazy initialization to handle both bundlers and Node.js ESM
4
- let RRule: any = null;
5
- let initPromise: Promise<void> | null = null;
6
-
7
- const ensureRRule = () => {
8
- if (RRule) return Promise.resolve();
9
- if (!initPromise) {
10
- initPromise = import("rrule").then((mod) => {
11
- RRule = (mod as any).RRule ?? (mod as any).default?.RRule ?? mod;
12
- });
13
- }
14
- return initPromise;
15
- };
16
-
17
- // Synchronous getter for RRule - throws if not initialized
18
- const getRRule = () => {
19
- if (!RRule) {
20
- throw new Error("EventHelper: RRule not initialized. Ensure ensureRRule() is called first.");
21
- }
22
- return RRule;
23
- };
24
-
25
- // Initialize on first use for bundlers (they process the dynamic import statically)
26
- // The promise is created immediately to start loading
27
- initPromise = import("rrule").then((mod) => {
28
- RRule = (mod as any).RRule ?? (mod as any).default?.RRule ?? mod;
29
- }).catch(() => {
30
- // rrule not available - EventHelper methods will fail gracefully
31
- });
32
-
33
- // Define ParsedOptions as any since RRule is dynamically loaded
34
- type ParsedOptions = any;
35
-
36
- export class EventHelper {
37
-
38
- static getRange = (event:EventInterface, startDate:Date, endDate:Date) => {
39
- const start = new Date(event.start);
40
- const rrule = EventHelper.getFullRRule(event);
41
-
42
- const dates = rrule.between(startDate, endDate);
43
-
44
- dates.forEach((d: Date) => {
45
- d.setHours(start.getHours());
46
- d.setMinutes(start.getMinutes());
47
- d.setSeconds(start.getSeconds());
48
- });
49
- return dates;
50
- };
51
-
52
- static getFullRRule = (event:EventInterface) => {
53
- const RR = getRRule();
54
- const rrule = RR.fromString(event.recurrenceRule);
55
- rrule.options.dtstart = new Date(event.start);
56
- return rrule;
57
- };
58
-
59
- static removeExcludeDates = (events:EventInterface[]) => {
60
- for (let i = events.length - 1; i >= 0; i--) {
61
- if (events[i].exceptionDates?.length > 0) {
62
- const parsedDates = events[i].exceptionDates.map((d: string | Date)=>new Date(d).toISOString());
63
- if (parsedDates.indexOf(events[i].start.toISOString()) > -1) events.splice(i, 1);
64
- }
65
- }
66
- };
67
-
68
- static getPartialRRuleString = (options:ParsedOptions) => {
69
- const RR = getRRule();
70
- const parts = new RR(options).toString().split("RRULE:");
71
- const result = parts.length === 2 ? parts[1] : "";
72
- return result;
73
- };
74
-
75
- static cleanRule = (options:ParsedOptions) => {
76
- options.byhour = undefined;
77
- options.byminute = undefined;
78
- options.bysecond = undefined;
79
- };
80
-
81
- // Export for consumers who need to ensure initialization
82
- static ensureInitialized = ensureRRule;
83
- }
package/src/FileHelper.ts DELETED
@@ -1,57 +0,0 @@
1
- export class FileHelper {
2
-
3
- static postPresignedFile = (presigned: any, uploadedFile: File, progressCallback: (percent: number) => void) => {
4
- const formData = new FormData();
5
- formData.append("key", presigned.key);
6
- formData.append("acl", "public-read");
7
- formData.append("Content-Type", uploadedFile.type);
8
- for (const property in presigned.fields) formData.append(property, presigned.fields[property]);
9
- formData.append("file", uploadedFile);
10
-
11
- // Use XMLHttpRequest for upload progress tracking since fetch doesn't support it natively
12
- return new Promise((resolve, reject) => {
13
- const xhr = new XMLHttpRequest();
14
-
15
- xhr.upload.addEventListener("progress", (event) => {
16
- if (event.lengthComputable) {
17
- const percent = Math.round((event.loaded / event.total) * 100);
18
- progressCallback(percent);
19
- }
20
- });
21
-
22
- xhr.addEventListener("load", () => {
23
- if (xhr.status >= 200 && xhr.status < 300) {
24
- resolve({
25
- status: xhr.status,
26
- statusText: xhr.statusText,
27
- data: xhr.responseText
28
- });
29
- } else {
30
- reject(new Error(`HTTP Error: ${xhr.status} ${xhr.statusText}`));
31
- }
32
- });
33
-
34
- xhr.addEventListener("error", () => {
35
- reject(new Error("Network error occurred"));
36
- });
37
-
38
- xhr.open("POST", presigned.url);
39
- xhr.send(formData);
40
- });
41
- };
42
-
43
- static dataURLtoBlob(dataurl: string) {
44
- const arr = dataurl.split(",");
45
- if (arr.length < 2) throw new Error("Invalid data URL format");
46
- const mimeMatch = arr[0].match(/:(.*?);/);
47
- if (!mimeMatch) throw new Error("Invalid MIME type in data URL");
48
- const mime = mimeMatch[1];
49
- const bstr = atob(arr[1]);
50
- let n = bstr.length;
51
- const u8arr = new Uint8Array(n);
52
- while (n--) {
53
- u8arr[n] = bstr.charCodeAt(n);
54
- }
55
- return new Blob([u8arr], { type: mime });
56
- }
57
- }
@@ -1,80 +0,0 @@
1
- import { PersonInterface, ContactInfoInterface } from "./interfaces/index.js";
2
- import { CommonEnvironmentHelper } from "./CommonEnvironmentHelper.js";
3
-
4
- export class PersonHelper {
5
-
6
- public static getPhotoPath(churchId: string, person: any) {
7
- if (!person.photoUpdated) {
8
- if (person.id?.startsWith("PER0000")) return "https://app.staging.b1.church/images/demo/avatars/" + person.id + ".svg";
9
- else return "";
10
- } else return "/" + churchId + "/membership/people/" + person.id + ".png?dt=" + new Date(person.photoUpdated).getTime().toString();
11
- }
12
-
13
- static getPhotoUrl(person: PersonInterface) {
14
- if (!person?.photo) return "/images/sample-profile.png";
15
- else {
16
- return (person?.photo?.startsWith("data:image/png;base64,") || person.photo?.indexOf("://") > -1)
17
- ? person.photo
18
- : CommonEnvironmentHelper.ContentRoot + person.photo;
19
- }
20
- }
21
-
22
- static getAge(birthdate: Date): string {
23
- if (birthdate !== undefined && birthdate !== null) {
24
- const ageDifMs = Date.now() - new Date(birthdate).getTime();
25
- const ageDate = new Date(ageDifMs);
26
- const years = Math.abs(ageDate.getUTCFullYear() - 1970);
27
- return years + " years";
28
- } else return "";
29
- }
30
-
31
- public static getDisplayNameFromPerson(person: any) {
32
- if (person?.name?.nick !== null && person?.name?.nick !== "" && person?.name?.nick !== undefined) return person.name.first + " \"" + person.name.nick + "\" " + person.name.last;
33
- else return person.name.first + " " + person.name.last;
34
- }
35
-
36
- static getDisplayName(firstName: string, lastName: string, nickName: string): string {
37
- if (nickName !== undefined && nickName !== null && nickName.length > 0) return firstName + ' "' + nickName + '" ' + lastName;
38
- else return firstName + " " + lastName;
39
- }
40
-
41
- public static getBirthMonth(birthdate: Date): number {
42
- if (birthdate) return new Date(birthdate).getMonth() + 1;
43
- else return -1;
44
- }
45
-
46
- public static compareAddress(address1: ContactInfoInterface, address2: ContactInfoInterface): boolean {
47
- const displayAddress1: string = this.addressToString(address1).trim();
48
- const displayAddress2: string = this.addressToString(address2).trim();
49
-
50
- if (displayAddress1 !== displayAddress2) {
51
- return true;
52
- }
53
- return false;
54
- }
55
-
56
- public static addressToString(address: ContactInfoInterface): string {
57
- return `${address.address1 || ""} ${address.address2 || ""} ${address.city || ""}${(address.city && address.state) ? "," : ""} ${address.state || ""} ${address.zip || ""}`;
58
- }
59
-
60
- public static changeOnlyAddress(contactInfo1: ContactInfoInterface, contactInfo2: ContactInfoInterface): ContactInfoInterface {
61
- const updatedAddress: ContactInfoInterface = {
62
- ...contactInfo1,
63
- address1: contactInfo2.address1,
64
- address2: contactInfo2.address2,
65
- city: contactInfo2.city,
66
- state: contactInfo2.state,
67
- zip: contactInfo2.zip
68
- };
69
-
70
- return updatedAddress;
71
- }
72
-
73
- public static checkAddressAvailabilty(person: PersonInterface): boolean {
74
- const addressString: string = this.addressToString(person.contactInfo).trim();
75
- if (addressString !== "") {
76
- return true;
77
- }
78
- return false;
79
- }
80
- }