@bash-app/bash-common 3.1.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,153 +1,153 @@
1
- import {
2
- AmountOfGuests,
3
- EventTask,
4
- AssociatedBash,
5
- BashEvent,
6
- Invitation,
7
- TargetAudience,
8
- Ticket,
9
- User,
10
- TicketTier, Service, Review, Media, BashComment, Recurrence, Contact,
11
- BashNotification, BashEventPromoCode,
12
- Reminder
13
- } from "@prisma/client";
14
-
15
-
16
- export interface BashEventExt extends BashEvent {
17
- targetAudience?: TargetAudience;
18
- amountOfGuests?: AmountOfGuests;
19
- recurrence?: Recurrence;
20
- creator?: User;
21
- ticketTiers: TicketTierExt[];
22
- media: Media[];
23
- eventTasks: EventTask[];
24
- promoCodes?: BashEventPromoCode[];
25
- tickets?: Ticket[]; // Only include tickets that the user has purchased and not all tickets (could be thousands + privacy)
26
- // Do not include in fetch. Could be hundreds of these
27
- invitations: InvitationExt[];
28
- }
29
-
30
- export interface BashNotificationsExt extends BashNotification {
31
- creator?: User;
32
- bashEvent?: BashEvent;
33
- eventTask?: EventTask;
34
- invitation?: Invitation;
35
- reminders?: Reminder[];
36
- }
37
-
38
- export const BASH_EVENT_DATA_TO_INCLUDE = {
39
- targetAudience: true,
40
- amountOfGuests: true,
41
- recurrence: true,
42
- ticketTiers: true,
43
- creator: true,
44
- eventTasks: true,
45
- media: true,
46
- promoCodes: true,
47
- }
48
-
49
- export const BASH_EVENT_DATA_TO_CLONE = [
50
- 'targetAudience',
51
- 'amountOfGuests',
52
- 'ticketTiers',
53
- 'media',
54
- 'recurrence',
55
- 'invitations',
56
- 'promoCodes',
57
- ] as const;
58
-
59
- type RemoveCommonProperties<T, U> = keyof (Omit<T, keyof U> & Omit<U, keyof T>);
60
- type UnionFromArray<T extends ReadonlyArray<any>> = T[number];
61
- type BashEventExtMinusDataToCloneType = Omit<BashEventExt, UnionFromArray<typeof BASH_EVENT_DATA_TO_CLONE>>;
62
-
63
- export const BASH_EVENT_DATA_TO_REMOVE: RemoveCommonProperties<BashEvent, BashEventExtMinusDataToCloneType>[] = [
64
- 'creator',
65
- 'eventTasks',
66
- 'tickets'
67
- ];
68
-
69
- export interface InvitationExt extends Invitation {
70
- creator: User;
71
- sentTo: User;
72
- tickets: Ticket[];
73
- }
74
-
75
- export const INVITATION_DATA_TO_INCLUDE = {
76
- creator: true,
77
- sentTo: true,
78
- tickets: true
79
- }
80
-
81
- export interface InvitationExtraData extends Invitation {
82
- isFreeGuest?: boolean;
83
- isOrganizer?: boolean;
84
- }
85
-
86
- export interface AssociatedBashExt extends AssociatedBash {
87
- bashEvent: BashEventExt;
88
- invitation: InvitationExt;
89
- }
90
-
91
-
92
- export const ASSOCIATED_BASH_DATA_TO_INCLUDE = {
93
- bashEvent: {
94
- include: BASH_EVENT_DATA_TO_INCLUDE
95
- },
96
- invitation: {
97
- include: INVITATION_DATA_TO_INCLUDE
98
- }
99
- }
100
-
101
- export interface TicketTierExt extends TicketTier {
102
- bashEvent: BashEvent;
103
- tickets: TicketExt[];
104
- }
105
-
106
- export interface TicketExt extends Ticket {
107
- owner: User;
108
- forUser: User;
109
- }
110
-
111
- export interface ReviewExt extends Review {
112
- comments: BashComment[];
113
- }
114
-
115
- export interface UserExtraData extends User {
116
- password: string;
117
- }
118
-
119
- export interface UserExt extends User {
120
- services: Service[];
121
-
122
- // Do not include in fetch as there could be thousands of these
123
- associatedBashes?: AssociatedBash[]
124
- reviews?: ReviewExt[];
125
- contacts?: Contact[];
126
- }
127
-
128
- export const USER_DATA_TO_INCLUDE = {
129
- services: true,
130
- }
131
-
132
- export const USER_DATA_SELECT_REVIEWS_COMMENTS = {
133
- reviews: {
134
- include: {
135
- comments: true
136
- }
137
- }
138
- }
139
-
140
- export const PUBLIC_USER_DATA_TO_SELECT = {
141
- id: true,
142
- email: true,
143
- givenName: true,
144
- familyName: true,
145
- fullName: true,
146
- username: true,
147
- image: true,
148
- uploadedImage: true,
149
- services: true,
150
- }
151
-
152
- export type Public_User = Pick<UserExt, keyof typeof PUBLIC_USER_DATA_TO_SELECT>
153
- & Partial<Pick<UserExt, keyof typeof USER_DATA_SELECT_REVIEWS_COMMENTS>>;
1
+ import {
2
+ AmountOfGuests,
3
+ EventTask,
4
+ AssociatedBash,
5
+ BashEvent,
6
+ Invitation,
7
+ TargetAudience,
8
+ Ticket,
9
+ User,
10
+ TicketTier, Service, Review, Media, BashComment, Recurrence, Contact,
11
+ BashNotification, BashEventPromoCode,
12
+ Reminder
13
+ } from "@prisma/client";
14
+
15
+
16
+ export interface BashEventExt extends BashEvent {
17
+ targetAudience?: TargetAudience;
18
+ amountOfGuests?: AmountOfGuests;
19
+ recurrence?: Recurrence;
20
+ creator?: User;
21
+ ticketTiers: TicketTierExt[];
22
+ media: Media[];
23
+ eventTasks: EventTask[];
24
+ promoCodes?: BashEventPromoCode[];
25
+ tickets?: Ticket[]; // Only include tickets that the user has purchased and not all tickets (could be thousands + privacy)
26
+ // Do not include in fetch. Could be hundreds of these
27
+ invitations: InvitationExt[];
28
+ }
29
+
30
+ export interface BashNotificationsExt extends BashNotification {
31
+ creator?: User;
32
+ bashEvent?: BashEvent;
33
+ eventTask?: EventTask;
34
+ invitation?: Invitation;
35
+ reminders?: Reminder[];
36
+ }
37
+
38
+ export const BASH_EVENT_DATA_TO_INCLUDE = {
39
+ targetAudience: true,
40
+ amountOfGuests: true,
41
+ recurrence: true,
42
+ ticketTiers: true,
43
+ creator: true,
44
+ eventTasks: true,
45
+ media: true,
46
+ promoCodes: true,
47
+ }
48
+
49
+ export const BASH_EVENT_DATA_TO_CLONE = [
50
+ 'targetAudience',
51
+ 'amountOfGuests',
52
+ 'ticketTiers',
53
+ 'media',
54
+ 'recurrence',
55
+ 'invitations',
56
+ 'promoCodes',
57
+ ] as const;
58
+
59
+ type RemoveCommonProperties<T, U> = keyof (Omit<T, keyof U> & Omit<U, keyof T>);
60
+ type UnionFromArray<T extends ReadonlyArray<any>> = T[number];
61
+ type BashEventExtMinusDataToCloneType = Omit<BashEventExt, UnionFromArray<typeof BASH_EVENT_DATA_TO_CLONE>>;
62
+
63
+ export const BASH_EVENT_DATA_TO_REMOVE: RemoveCommonProperties<BashEvent, BashEventExtMinusDataToCloneType>[] = [
64
+ 'creator',
65
+ 'eventTasks',
66
+ 'tickets'
67
+ ];
68
+
69
+ export interface InvitationExt extends Invitation {
70
+ creator: User;
71
+ sentTo: User;
72
+ tickets: Ticket[];
73
+ }
74
+
75
+ export const INVITATION_DATA_TO_INCLUDE = {
76
+ creator: true,
77
+ sentTo: true,
78
+ tickets: true
79
+ }
80
+
81
+ export interface InvitationExtraData extends Invitation {
82
+ isFreeGuest?: boolean;
83
+ isOrganizer?: boolean;
84
+ }
85
+
86
+ export interface AssociatedBashExt extends AssociatedBash {
87
+ bashEvent: BashEventExt;
88
+ invitation: InvitationExt;
89
+ }
90
+
91
+
92
+ export const ASSOCIATED_BASH_DATA_TO_INCLUDE = {
93
+ bashEvent: {
94
+ include: BASH_EVENT_DATA_TO_INCLUDE
95
+ },
96
+ invitation: {
97
+ include: INVITATION_DATA_TO_INCLUDE
98
+ }
99
+ }
100
+
101
+ export interface TicketTierExt extends TicketTier {
102
+ bashEvent: BashEvent;
103
+ tickets: TicketExt[];
104
+ }
105
+
106
+ export interface TicketExt extends Ticket {
107
+ owner: User;
108
+ forUser: User;
109
+ }
110
+
111
+ export interface ReviewExt extends Review {
112
+ comments: BashComment[];
113
+ }
114
+
115
+ export interface UserExtraData extends User {
116
+ password: string;
117
+ }
118
+
119
+ export interface UserExt extends User {
120
+ services: Service[];
121
+
122
+ // Do not include in fetch as there could be thousands of these
123
+ associatedBashes?: AssociatedBash[]
124
+ reviews?: ReviewExt[];
125
+ contacts?: Contact[];
126
+ }
127
+
128
+ export const USER_DATA_TO_INCLUDE = {
129
+ services: true,
130
+ }
131
+
132
+ export const USER_DATA_SELECT_REVIEWS_COMMENTS = {
133
+ reviews: {
134
+ include: {
135
+ comments: true
136
+ }
137
+ }
138
+ }
139
+
140
+ export const PUBLIC_USER_DATA_TO_SELECT = {
141
+ id: true,
142
+ email: true,
143
+ givenName: true,
144
+ familyName: true,
145
+ fullName: true,
146
+ username: true,
147
+ image: true,
148
+ uploadedImage: true,
149
+ services: true,
150
+ }
151
+
152
+ export type Public_User = Pick<UserExt, keyof typeof PUBLIC_USER_DATA_TO_SELECT>
153
+ & Partial<Pick<UserExt, keyof typeof USER_DATA_SELECT_REVIEWS_COMMENTS>>;
package/src/index.ts CHANGED
@@ -1,9 +1,9 @@
1
- export * from "./extendedSchemas";
2
- export * from "./definitions";
3
- export * from "./utils/ticketListUtils";
4
- export * from "./utils/dateTimeUtils";
5
- export * from "./utils/recurrenceUtils";
6
- export * from "./utils/addressUtils";
7
- export * from "./utils/paymentUtils";
8
- export * from "./utils/awsS3Utils";
9
- export * from "./utils/qrCodeUtils";
1
+ export * from "./extendedSchemas";
2
+ export * from "./definitions";
3
+ export * from "./utils/ticketListUtils";
4
+ export * from "./utils/dateTimeUtils";
5
+ export * from "./utils/recurrenceUtils";
6
+ export * from "./utils/addressUtils";
7
+ export * from "./utils/paymentUtils";
8
+ export * from "./utils/awsS3Utils";
9
+ export * from "./utils/qrCodeUtils";
@@ -1,173 +1,173 @@
1
-
2
- const ADDRESS_DELIM = '|';
3
-
4
- const googleMapsApiKey = process.env.REACT_APP_GOOGLE_MAP_API_KEY as string;
5
-
6
-
7
- export interface IAddress {
8
- place: string;
9
- street: string;
10
- city: string;
11
- state: string;
12
- zipCode: string;
13
- country: string;
14
- }
15
-
16
- export function addressHasEnoughDataForGeolocation(address: IAddress): boolean {
17
- return !!((address.place && address.city && address.state) || (address.street && address.city && address.state));
18
- }
19
-
20
- export function addressValuesToDatabaseAddressString(addressValues: IAddress): string {
21
- const { place = '', street, city, state, zipCode, country } = addressValues;
22
- return [place, street, city, state, zipCode, country].join(ADDRESS_DELIM);
23
- }
24
-
25
- export function databaseAddressStringToAddressValues(addressString: string | undefined | null): IAddress {
26
- if (addressString) {
27
- const addressArray = addressString.split(ADDRESS_DELIM);
28
- return {
29
- place: addressArray[0],
30
- street: addressArray[1],
31
- city: addressArray[2],
32
- state: addressArray[3],
33
- zipCode: addressArray[4],
34
- country: 'USA'
35
- }
36
- }
37
- return { place: '', street: '', city: '', state: '', zipCode: '', country: '' };
38
- }
39
-
40
-
41
- export function databaseAddressStringToOneLineString(addressString: string | undefined | null): string {
42
- if (addressString) {
43
- const address = databaseAddressStringToAddressValues(addressString);
44
- let addressArr = address.place ? [address.place] : [];
45
- addressArr = [...addressArr, address.street, address.city, address.state];
46
- const addressStr = addressArr.filter((str) => !!str).join(', ');
47
- return `${addressStr} ${address.zipCode}`;
48
- }
49
- return '';
50
- }
51
-
52
- export function databaseAddressStringToDisplayString(addressString: string | undefined | null): string {
53
- if (addressString) {
54
- const oneLineString = databaseAddressStringToOneLineString(addressString);
55
- const formatted = oneLineString.replace(/([A-Z])(?=[A-Z][a-z])/g, "$1 ") // Add space between a single uppercase letter and a capitalized word
56
- .replace(/(\d)(?=[A-Z])/g, "$1 ") // Add space between numbers and letters
57
- .replace(/,/g, ", "); // Add space after commas
58
- return formatted;
59
- }
60
- return '';
61
- }
62
-
63
-
64
- export async function getAddressFromCoordinates( lat: number, lng: number ): Promise<IAddress> {
65
- const apiUrl = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${googleMapsApiKey}&loading=async`;
66
- try {
67
- const response = await fetch(apiUrl);
68
- const data = await response.json();
69
- if (data.results.length > 0) {
70
- const addressComponents = data.results[0].address_components;
71
-
72
- let street = "";
73
- let city = "";
74
- let state = "";
75
- let zipCode = "";
76
-
77
- addressComponents.forEach((component: any) => {
78
- if (component.types.includes("route")) {
79
- street = component.long_name;
80
- } else if (component.types.includes("locality")) {
81
- city = component.long_name;
82
- } else if (component.types.includes("administrative_area_level_1")) {
83
- state = component.short_name;
84
- } else if (component.types.includes("postal_code")) {
85
- zipCode = component.long_name;
86
- }
87
- });
88
-
89
- return { place: '', street, city, state, zipCode, country: 'USA' };
90
- } else {
91
- throw new Error("No address found");
92
- }
93
- } catch (error) {
94
- console.error(error);
95
- return {
96
- place: '',
97
- street: "",
98
- city: "",
99
- state: "",
100
- zipCode: "",
101
- country: 'USA'
102
- };
103
- }
104
- }
105
-
106
- export function extractAddressComponents(place: any): IAddress {
107
- const addressComponents = place.address_components;
108
- let streetNumber = '';
109
- let streetName = '';
110
- let city = '';
111
- let state = '';
112
- let zipCode = '';
113
- let country = 'USA';
114
-
115
- addressComponents.forEach((component: any) => {
116
- const types = component.types;
117
- if (types.includes('street_number')) {
118
- streetNumber = component.long_name;
119
- }
120
- if (types.includes('route')) {
121
- streetName = component.long_name;
122
- }
123
- if (types.includes('locality')) {
124
- city = component.long_name;
125
- }
126
- if (types.includes('administrative_area_level_1')) {
127
- state = component.short_name;
128
- }
129
- if (types.includes('postal_code')) {
130
- zipCode = component.long_name;
131
- }
132
- if (types.includes('country')) {
133
- country = component.long_name;
134
- }
135
- });
136
-
137
- const street = `${streetNumber} ${streetName}`.trim();
138
-
139
- return {
140
- place: place.name || '',
141
- street,
142
- city,
143
- state,
144
- zipCode,
145
- country
146
- };
147
- }
148
-
149
-
150
- export async function getGeoCoordinatesFromAddress(address: IAddress): Promise<{lat: number, lng: number} | undefined> {
151
- const addressStr = `${address.street}, ${address.city}, ${address.state} ${address.zipCode}, ${address.country}`;
152
-
153
- const response = await fetch(
154
- `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(addressStr)}&key=${googleMapsApiKey}`
155
- );
156
- if (!response.ok) {
157
- console.error('Geocode response was not ok for address: ' + addressStr);
158
- }
159
-
160
- const data = await response.json();
161
-
162
- if (data.status === 'OK') {
163
- if (data.results?.length) {
164
- return data.results[0].geometry.location;
165
- }
166
- else {
167
- console.error('Geocode results were empty with address: ' + addressStr);
168
- }
169
- }
170
- else {
171
- console.error(`Geocode was not successful with address: ${addressStr}\nfor the following reason: ${data.status}`);
172
- }
173
- }
1
+
2
+ const ADDRESS_DELIM = '|';
3
+
4
+ const googleMapsApiKey = process.env.REACT_APP_GOOGLE_MAP_API_KEY as string;
5
+
6
+
7
+ export interface IAddress {
8
+ place: string;
9
+ street: string;
10
+ city: string;
11
+ state: string;
12
+ zipCode: string;
13
+ country: string;
14
+ }
15
+
16
+ export function addressHasEnoughDataForGeolocation(address: IAddress): boolean {
17
+ return !!((address.place && address.city && address.state) || (address.street && address.city && address.state));
18
+ }
19
+
20
+ export function addressValuesToDatabaseAddressString(addressValues: IAddress): string {
21
+ const { place = '', street, city, state, zipCode, country } = addressValues;
22
+ return [place, street, city, state, zipCode, country].join(ADDRESS_DELIM);
23
+ }
24
+
25
+ export function databaseAddressStringToAddressValues(addressString: string | undefined | null): IAddress {
26
+ if (addressString) {
27
+ const addressArray = addressString.split(ADDRESS_DELIM);
28
+ return {
29
+ place: addressArray[0],
30
+ street: addressArray[1],
31
+ city: addressArray[2],
32
+ state: addressArray[3],
33
+ zipCode: addressArray[4],
34
+ country: 'USA'
35
+ }
36
+ }
37
+ return { place: '', street: '', city: '', state: '', zipCode: '', country: '' };
38
+ }
39
+
40
+
41
+ export function databaseAddressStringToOneLineString(addressString: string | undefined | null): string {
42
+ if (addressString) {
43
+ const address = databaseAddressStringToAddressValues(addressString);
44
+ let addressArr = address.place ? [address.place] : [];
45
+ addressArr = [...addressArr, address.street, address.city, address.state];
46
+ const addressStr = addressArr.filter((str) => !!str).join(', ');
47
+ return `${addressStr} ${address.zipCode}`;
48
+ }
49
+ return '';
50
+ }
51
+
52
+ export function databaseAddressStringToDisplayString(addressString: string | undefined | null): string {
53
+ if (addressString) {
54
+ const oneLineString = databaseAddressStringToOneLineString(addressString);
55
+ const formatted = oneLineString.replace(/([A-Z])(?=[A-Z][a-z])/g, "$1 ") // Add space between a single uppercase letter and a capitalized word
56
+ .replace(/(\d)(?=[A-Z])/g, "$1 ") // Add space between numbers and letters
57
+ .replace(/,/g, ", "); // Add space after commas
58
+ return formatted;
59
+ }
60
+ return '';
61
+ }
62
+
63
+
64
+ export async function getAddressFromCoordinates( lat: number, lng: number ): Promise<IAddress> {
65
+ const apiUrl = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${googleMapsApiKey}&loading=async`;
66
+ try {
67
+ const response = await fetch(apiUrl);
68
+ const data = await response.json();
69
+ if (data.results.length > 0) {
70
+ const addressComponents = data.results[0].address_components;
71
+
72
+ let street = "";
73
+ let city = "";
74
+ let state = "";
75
+ let zipCode = "";
76
+
77
+ addressComponents.forEach((component: any) => {
78
+ if (component.types.includes("route")) {
79
+ street = component.long_name;
80
+ } else if (component.types.includes("locality")) {
81
+ city = component.long_name;
82
+ } else if (component.types.includes("administrative_area_level_1")) {
83
+ state = component.short_name;
84
+ } else if (component.types.includes("postal_code")) {
85
+ zipCode = component.long_name;
86
+ }
87
+ });
88
+
89
+ return { place: '', street, city, state, zipCode, country: 'USA' };
90
+ } else {
91
+ throw new Error("No address found");
92
+ }
93
+ } catch (error) {
94
+ console.error(error);
95
+ return {
96
+ place: '',
97
+ street: "",
98
+ city: "",
99
+ state: "",
100
+ zipCode: "",
101
+ country: 'USA'
102
+ };
103
+ }
104
+ }
105
+
106
+ export function extractAddressComponents(place: any): IAddress {
107
+ const addressComponents = place.address_components;
108
+ let streetNumber = '';
109
+ let streetName = '';
110
+ let city = '';
111
+ let state = '';
112
+ let zipCode = '';
113
+ let country = 'USA';
114
+
115
+ addressComponents.forEach((component: any) => {
116
+ const types = component.types;
117
+ if (types.includes('street_number')) {
118
+ streetNumber = component.long_name;
119
+ }
120
+ if (types.includes('route')) {
121
+ streetName = component.long_name;
122
+ }
123
+ if (types.includes('locality')) {
124
+ city = component.long_name;
125
+ }
126
+ if (types.includes('administrative_area_level_1')) {
127
+ state = component.short_name;
128
+ }
129
+ if (types.includes('postal_code')) {
130
+ zipCode = component.long_name;
131
+ }
132
+ if (types.includes('country')) {
133
+ country = component.long_name;
134
+ }
135
+ });
136
+
137
+ const street = `${streetNumber} ${streetName}`.trim();
138
+
139
+ return {
140
+ place: place.name || '',
141
+ street,
142
+ city,
143
+ state,
144
+ zipCode,
145
+ country
146
+ };
147
+ }
148
+
149
+
150
+ export async function getGeoCoordinatesFromAddress(address: IAddress): Promise<{lat: number, lng: number} | undefined> {
151
+ const addressStr = `${address.street}, ${address.city}, ${address.state} ${address.zipCode}, ${address.country}`;
152
+
153
+ const response = await fetch(
154
+ `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(addressStr)}&key=${googleMapsApiKey}`
155
+ );
156
+ if (!response.ok) {
157
+ console.error('Geocode response was not ok for address: ' + addressStr);
158
+ }
159
+
160
+ const data = await response.json();
161
+
162
+ if (data.status === 'OK') {
163
+ if (data.results?.length) {
164
+ return data.results[0].geometry.location;
165
+ }
166
+ else {
167
+ console.error('Geocode results were empty with address: ' + addressStr);
168
+ }
169
+ }
170
+ else {
171
+ console.error(`Geocode was not successful with address: ${addressStr}\nfor the following reason: ${data.status}`);
172
+ }
173
+ }