@phygitallabs/tapquest-core 2.0.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.
Files changed (78) hide show
  1. package/README.md +210 -0
  2. package/index.ts +1 -0
  3. package/package.json +43 -0
  4. package/src/constants/firebase.ts +36 -0
  5. package/src/constants/service.ts +30 -0
  6. package/src/helper/helpers.ts +3 -0
  7. package/src/helper/index.ts +1 -0
  8. package/src/index.ts +25 -0
  9. package/src/modules/achievement/helpers/index.ts +98 -0
  10. package/src/modules/achievement/hooks/index.ts +171 -0
  11. package/src/modules/achievement/index.ts +5 -0
  12. package/src/modules/achievement/types/index.ts +45 -0
  13. package/src/modules/achivementWithReward/hooks/achivementPlusRewardModel.ts +83 -0
  14. package/src/modules/achivementWithReward/hooks/index.ts +5 -0
  15. package/src/modules/achivementWithReward/index.ts +5 -0
  16. package/src/modules/auth/README.md +527 -0
  17. package/src/modules/auth/constants/index.ts +9 -0
  18. package/src/modules/auth/helpers/index.ts +161 -0
  19. package/src/modules/auth/helpers/refreshToken.ts +63 -0
  20. package/src/modules/auth/index.ts +20 -0
  21. package/src/modules/auth/providers/AuthProvider.tsx +207 -0
  22. package/src/modules/auth/providers/index.ts +1 -0
  23. package/src/modules/auth/services/FirebaseAuthService.ts +290 -0
  24. package/src/modules/auth/services/authServiceFactory.ts +22 -0
  25. package/src/modules/auth/services/index.ts +3 -0
  26. package/src/modules/auth/store/authSlice.ts +137 -0
  27. package/src/modules/auth/types/index.ts +109 -0
  28. package/src/modules/campaign/hooks/index.ts +6 -0
  29. package/src/modules/campaign/hooks/useCampaignService.ts +7 -0
  30. package/src/modules/campaign/index.tsx +7 -0
  31. package/src/modules/campaign/types/campaign.ts +51 -0
  32. package/src/modules/campaign/types/enums.ts +4 -0
  33. package/src/modules/campaign/types/index.ts +4 -0
  34. package/src/modules/campaign/types/requests.ts +46 -0
  35. package/src/modules/data-tracking/hooks/index.ts +67 -0
  36. package/src/modules/data-tracking/index.ts +1 -0
  37. package/src/modules/generate-certificate/hooks/index.ts +8 -0
  38. package/src/modules/generate-certificate/index.ts +3 -0
  39. package/src/modules/generate-certificate/types/generateCertificate.ts +7 -0
  40. package/src/modules/generate-certificate/types/index.ts +7 -0
  41. package/src/modules/location/hooks/index.ts +8 -0
  42. package/src/modules/location/hooks/useLocationService.ts +8 -0
  43. package/src/modules/location/index.tsx +11 -0
  44. package/src/modules/location/types/index.ts +18 -0
  45. package/src/modules/location/types/locationModel.ts +21 -0
  46. package/src/modules/location/utils/index.ts +5 -0
  47. package/src/modules/location/utils/locationHelpers.ts +13 -0
  48. package/src/modules/memory/hooks/index.ts +3 -0
  49. package/src/modules/memory/index.ts +3 -0
  50. package/src/modules/memory/types/index.ts +3 -0
  51. package/src/modules/notification/index.ts +2 -0
  52. package/src/modules/notification/providers/index.tsx +50 -0
  53. package/src/modules/notification/types/index.ts +3 -0
  54. package/src/modules/reward/hooks/index.ts +14 -0
  55. package/src/modules/reward/hooks/useRewardService.ts +14 -0
  56. package/src/modules/reward/index.tsx +16 -0
  57. package/src/modules/reward/types/enums.ts +13 -0
  58. package/src/modules/reward/types/index.ts +4 -0
  59. package/src/modules/reward/types/requests.ts +281 -0
  60. package/src/modules/reward/types/reward.ts +90 -0
  61. package/src/modules/scan-chip/hooks/index.tsx +67 -0
  62. package/src/modules/scan-chip/index.ts +2 -0
  63. package/src/modules/scan-chip/types/index.ts +25 -0
  64. package/src/modules/send-email/hooks/index.ts +2 -0
  65. package/src/modules/send-email/index.ts +1 -0
  66. package/src/modules/user-profile/hooks/index.ts +3 -0
  67. package/src/modules/user-profile/index.ts +3 -0
  68. package/src/modules/user-profile/types/index.ts +3 -0
  69. package/src/providers/ServicesProvider.tsx +173 -0
  70. package/src/providers/TapquestCoreProvider.tsx +64 -0
  71. package/src/providers/index.ts +1 -0
  72. package/src/store/hooks.ts +6 -0
  73. package/src/store/index.ts +45 -0
  74. package/src/types/common.d.ts +8 -0
  75. package/src/types/media.ts +26 -0
  76. package/src/types/service.d.ts +34 -0
  77. package/tsconfig.json +28 -0
  78. package/tsup.config.ts +10 -0
@@ -0,0 +1,90 @@
1
+ // Re-export from @phygitallabs/reward package
2
+ export type {
3
+ CmentityUserReward,
4
+ EntityRewardModel,
5
+ UserReward
6
+ } from "@phygitallabs/reward";
7
+
8
+ // Import EntityRewardModel for local use
9
+ import type { EntityRewardModel } from "@phygitallabs/reward";
10
+
11
+ // Define other types locally since they're not exported from reward package
12
+ export interface RewardRule {
13
+ id: string;
14
+ name: string;
15
+ description?: string;
16
+ type: string;
17
+ conditions: Record<string, any>;
18
+ is_active: boolean;
19
+ priority?: number;
20
+ created_at: string;
21
+ updated_at: string;
22
+ }
23
+
24
+ export interface RewardGroup {
25
+ id: string;
26
+ name: string;
27
+ description?: string;
28
+ is_active: boolean;
29
+ reward_ids: string[];
30
+ rewards?: EntityRewardModel[];
31
+ project_id?: string;
32
+ campaign_id?: string;
33
+ achievement_id?: string;
34
+ labels?: Record<string, any>;
35
+ custom_info?: Record<string, any>;
36
+ metadata?: Record<string, any>;
37
+ created_at: string;
38
+ updated_at: string;
39
+ }
40
+
41
+ export interface RewardNotifyTheme {
42
+ backgroundImage: string;
43
+ giftImage: string;
44
+ }
45
+
46
+ export interface RewardFilter {
47
+ user_id?: string;
48
+ device_uid?: string;
49
+ reward_model_id?: string;
50
+ group_reward_id?: string;
51
+ project_id?: string;
52
+ campaign_id?: string;
53
+ achievement_id?: string;
54
+ status?: string;
55
+ claim_status?: string;
56
+ is_claimable?: boolean;
57
+ is_expired?: boolean;
58
+ type?: string;
59
+ labels?: Record<string, any>;
60
+ created_from?: string;
61
+ created_to?: string;
62
+ claimed_from?: string;
63
+ claimed_to?: string;
64
+ }
65
+
66
+ export interface RewardModelFilter {
67
+ name?: string;
68
+ type?: string;
69
+ is_active?: boolean;
70
+ is_claimable?: boolean;
71
+ project_id?: string;
72
+ campaign_id?: string;
73
+ achievement_id?: string;
74
+ group_reward_id?: string;
75
+ labels?: Record<string, any>;
76
+ created_from?: string;
77
+ created_to?: string;
78
+ valid_from?: string;
79
+ valid_until?: string;
80
+ }
81
+
82
+ export interface ClaimUserRewardPayload {
83
+ certificate?: {
84
+ thumbnail_url?: string;
85
+ type?: string;
86
+ url?: string;
87
+ };
88
+ user_info: Record<string, any>;
89
+ }
90
+
@@ -0,0 +1,67 @@
1
+ import { useEffect } from "react";
2
+ import { useChipScanStory } from "@phygitallabs/api-core";
3
+ import { usePGLCoreService } from "@phygitallabs/api-core";
4
+ import { setChipAuthToken } from "../../auth/helpers";
5
+
6
+ import { ScanChipResponse } from "../types";
7
+
8
+ interface UseScanChipProps {
9
+ token?: string;
10
+ id?: string;
11
+ onScanChipError?: () => void;
12
+ }
13
+ export { useChipScanStory, usePGLCoreService };
14
+ export function useScanChip({ token, id, onScanChipError }: UseScanChipProps): ScanChipResponse {
15
+ const { updateHeaders } = usePGLCoreService();
16
+
17
+ useEffect(() => {
18
+ if (!!token) {
19
+
20
+ const header = {
21
+ "Chip-Authorization": token,
22
+ };
23
+
24
+ setChipAuthToken(token);
25
+ updateHeaders(header);
26
+
27
+ }
28
+ }, [token, updateHeaders]);
29
+
30
+ const { data, isLoading, isError, isSuccess } = useChipScanStory({
31
+ token,
32
+ id,
33
+ });
34
+
35
+ useEffect(() => {
36
+ if (isError) {
37
+ onScanChipError?.();
38
+ }
39
+ }, [isError, onScanChipError]);
40
+
41
+
42
+ if (!data)
43
+ return {
44
+ data: null,
45
+ isLoading,
46
+ isError,
47
+ isSuccess
48
+ };
49
+
50
+ return {
51
+ data: {
52
+ externalUrl: data?.external_url,
53
+ campaignDetail: data?.project,
54
+ locationDetail: data?.location,
55
+ scanCounter: data?.scan_counter,
56
+ campaignId: data?.campaign_id,
57
+ chipModelId: data?.chip_model_id,
58
+ organizationId: data?.organization_id,
59
+ projectId: data?.project_id,
60
+ locationId: data?.location_id,
61
+ chipUid: data?.uid,
62
+ },
63
+ isLoading,
64
+ isError,
65
+ isSuccess
66
+ }
67
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./hooks";
2
+ export * from "./types";
@@ -0,0 +1,25 @@
1
+ import { ChipScanModel, ProjectModel, LocationModel } from "@phygitallabs/api-core";
2
+
3
+ export type ScanChipData = {
4
+ externalUrl?: string;
5
+ campaignDetail?: ProjectModel;
6
+ locationDetail?: LocationModel;
7
+ scanCounter?: number;
8
+ campaignId?: string;
9
+ chipModelId?: string;
10
+ organizationId?: string;
11
+ projectId?: string;
12
+ locationId?: string;
13
+ chipUid?: string;
14
+ }
15
+
16
+
17
+ export interface ScanChipResponse {
18
+ data: ScanChipData | null;
19
+ isLoading: boolean;
20
+ isError: boolean;
21
+ isSuccess: boolean;
22
+ }
23
+
24
+
25
+ export type { ChipScanModel, LocationModel, ProjectModel };
@@ -0,0 +1,2 @@
1
+ import { useSendEmail } from "@phygitallabs/api-core";
2
+ export {useSendEmail}
@@ -0,0 +1 @@
1
+ export * from "./hooks";
@@ -0,0 +1,3 @@
1
+ import { useMyProfile, useUpdateMyProfile, useSyncCheckin, useCancelUserRewardsRequest } from "@phygitallabs/api-core";
2
+
3
+ export { useMyProfile, useUpdateMyProfile, useSyncCheckin, useCancelUserRewardsRequest };
@@ -0,0 +1,3 @@
1
+ export * from "./hooks";
2
+
3
+ export * from "./types";
@@ -0,0 +1,3 @@
1
+ import { UserSourceType } from "@phygitallabs/api-core";
2
+
3
+ export { UserSourceType };
@@ -0,0 +1,173 @@
1
+ import React, { useEffect, useState, useMemo } from "react";
2
+ import { QueryClient } from "@tanstack/react-query";
3
+ import { PGLCoreServiceProvider } from "@phygitallabs/api-core";
4
+ import { RewardServiceProvider } from "@phygitallabs/reward";
5
+ import { AchievementServiceProvider } from "@phygitallabs/achievement";
6
+ import { GenerateCertificateServiceProvider } from "@phygitallabs/generate-certificate";
7
+
8
+ import serviceApiUrl from "../constants/service";
9
+ import { APIConfig, ServiceConfig } from "../types/service";
10
+
11
+ import { checkDeviceUid, getAccessToken, getRetryAttemptsRefreshToken, setRetryAttemptsRefreshToken, createRefreshTokenFunction } from "../modules/auth/helpers";
12
+
13
+ import { httpMaxRetries } from "../modules/auth";
14
+
15
+ import { useAuth } from "../modules/auth";
16
+
17
+ import axios from "axios";
18
+
19
+ interface ServicesProviderProps {
20
+ children: React.ReactNode;
21
+ queryClient: QueryClient;
22
+ apiConfig: APIConfig;
23
+ firebaseConfig?: any;
24
+ }
25
+
26
+ export const ServicesProvider: React.FC<ServicesProviderProps> = ({
27
+ children,
28
+ queryClient,
29
+ apiConfig = {
30
+ environment: "dev",
31
+ version: "v1"
32
+ },
33
+ firebaseConfig
34
+ }) => {
35
+ const { refreshUser, signOut } = useAuth();
36
+ const { environment, version } = apiConfig;
37
+ const [commonServiceConfig, setCommonServiceConfig] = useState<ServiceConfig | null>(null);
38
+
39
+ // Create memoized refresh token function
40
+ const memoizedRefreshToken = useMemo(() => {
41
+ if (!firebaseConfig?.apiKey) {
42
+ console.warn("Firebase API key not provided, refresh token functionality will not work");
43
+ return null;
44
+ }
45
+ return createRefreshTokenFunction({
46
+ firebaseApiKey: firebaseConfig.apiKey
47
+ });
48
+ }, [firebaseConfig?.apiKey]);
49
+
50
+ // Init client
51
+ useEffect(() => {
52
+ const initClient = async () => {
53
+ try {
54
+ const deviceUid = await checkDeviceUid();
55
+
56
+ const responseInterceptors = ({
57
+ onFulfilled: (response: any) => response,
58
+ onRejected: async (error: any) => {
59
+
60
+ // TODO: Remove
61
+ // Feature: use refresh token to get new access token when token expired, have maximum `retry attempts`
62
+ const originalRequest = error.config;
63
+
64
+ if (error.response?.status === 401 && !originalRequest._retry) {
65
+ const retryAttempts = parseInt(
66
+ getRetryAttemptsRefreshToken() || "0",
67
+ 10
68
+ );
69
+
70
+ if (retryAttempts >= httpMaxRetries) {
71
+ await signOut();
72
+ return Promise.reject(error);
73
+ }
74
+
75
+ setRetryAttemptsRefreshToken(`${retryAttempts + 1}`);
76
+ originalRequest._retry = true;
77
+
78
+ try {
79
+ if (!memoizedRefreshToken) {
80
+ await signOut();
81
+ return Promise.reject(error);
82
+ }
83
+
84
+ const result = await memoizedRefreshToken();
85
+
86
+ if (result?.accessToken) {
87
+ originalRequest.headers[
88
+ "Authorization"
89
+ ] = `Bearer ${result.accessToken}`;
90
+
91
+ setRetryAttemptsRefreshToken("0");
92
+
93
+ refreshUser(result);
94
+
95
+ return axios(originalRequest);
96
+ }
97
+ } catch (refreshError) {
98
+ console.log("Failed to refresh token:", refreshError);
99
+ }
100
+ }
101
+
102
+ return Promise.reject(error);
103
+ },
104
+ })
105
+
106
+ const requestInterceptors = ({
107
+ onFulfilled: (config: any) => {
108
+ // Feature: set access token to request header
109
+ const currentToken = getAccessToken();
110
+
111
+ if (currentToken && !config.headers.Authorization) {
112
+ config.headers.Authorization = `Bearer ${currentToken}`;
113
+ }
114
+ return config;
115
+ },
116
+ onRejected: (error: any) => Promise.reject(error),
117
+ })
118
+
119
+ const axiosConfig = {
120
+ headers: {
121
+ "Content-Type": "application/json",
122
+ "Device-UID": deviceUid,
123
+ }
124
+ }
125
+
126
+ const config: ServiceConfig = {
127
+ queryClient,
128
+ axiosConfig,
129
+ responseInterceptors,
130
+ requestInterceptors,
131
+ useDevTool: true,
132
+ };
133
+
134
+ setCommonServiceConfig(config);
135
+
136
+ } catch (error) {
137
+ console.error(error);
138
+ }
139
+ }
140
+
141
+ initClient();
142
+ }, [queryClient]);
143
+
144
+ if (!commonServiceConfig) {
145
+ return <></>
146
+ }
147
+
148
+ return (
149
+ <PGLCoreServiceProvider
150
+ {...commonServiceConfig}
151
+ baseURL={`${serviceApiUrl[environment].API_BASE_URL}/${version}`}
152
+ baseCoreURL={`${serviceApiUrl[environment].API_BASE_CORE_URL}/${version}`}
153
+ >
154
+ <RewardServiceProvider
155
+ {...commonServiceConfig}
156
+ // baseURL={`${serviceApiUrl[environment].API_REWARD_URL}/${version}`}
157
+ baseURL={`${serviceApiUrl[environment].API_REWARD_URL}/v1`} // todo: using v1 until backend fully migrate
158
+ >
159
+ <AchievementServiceProvider
160
+ {...commonServiceConfig}
161
+ baseURL={`${serviceApiUrl[environment].API_ACHIEVEMENT_URL}/${version}`}
162
+ >
163
+ <GenerateCertificateServiceProvider
164
+ {...commonServiceConfig}
165
+ baseURL={`${serviceApiUrl[environment].API_GENERATE_CERTIFICATE_URL}/v1`}
166
+ >
167
+ {children}
168
+ </GenerateCertificateServiceProvider>
169
+ </AchievementServiceProvider>
170
+ </RewardServiceProvider>
171
+ </PGLCoreServiceProvider>
172
+ );
173
+ };
@@ -0,0 +1,64 @@
1
+ import React, { useMemo } from "react";
2
+ import { Provider } from "react-redux";
3
+ import { PersistGate } from "redux-persist/integration/react";
4
+
5
+ import { ServicesProvider } from "./ServicesProvider";
6
+ import { APIConfig } from "../types/service";
7
+ import { QueryClient } from "@tanstack/react-query";
8
+
9
+ import { store, persistor } from "../store";
10
+ import { AuthCallbacks } from "../modules/auth/types";
11
+ import { AuthProvider } from "../modules/auth/providers";
12
+ import { FirebaseConfig } from "../modules/auth/types";
13
+
14
+ interface TapquestCoreProviderProps {
15
+ children: React.ReactNode;
16
+ queryClient: QueryClient;
17
+ apiConfig: APIConfig;
18
+ firebaseConfig?: FirebaseConfig;
19
+ authCallbacks?: AuthCallbacks;
20
+ }
21
+
22
+ export const TapquestCoreProvider: React.FC<TapquestCoreProviderProps> = ({
23
+ children,
24
+ queryClient,
25
+ apiConfig,
26
+ firebaseConfig,
27
+ authCallbacks
28
+ }) => {
29
+
30
+ const internalAuthService = useMemo(() => {
31
+ if (firebaseConfig && typeof window !== "undefined") {
32
+ try {
33
+ // Dynamic import to avoid loading Firebase modules during build
34
+ const { createAuthService } = require("../modules/auth/services");
35
+ return createAuthService({ firebaseConfig });
36
+ } catch (error) {
37
+ console.warn("Failed to create auth service from firebase config:", error);
38
+ return null;
39
+ }
40
+ }
41
+
42
+ return null;
43
+ }, [firebaseConfig]);
44
+
45
+ return (
46
+ <Provider store={store}>
47
+ <PersistGate loading={null} persistor={persistor}>
48
+ <AuthProvider
49
+ authService={internalAuthService}
50
+ authCallbacks={authCallbacks}
51
+ >
52
+ <ServicesProvider
53
+ queryClient={queryClient}
54
+ apiConfig={apiConfig}
55
+ firebaseConfig={firebaseConfig}
56
+ >
57
+ {children}
58
+ </ServicesProvider>
59
+ </AuthProvider>
60
+
61
+ </PersistGate>
62
+ </Provider>
63
+ );
64
+ };
@@ -0,0 +1 @@
1
+ export * from './TapquestCoreProvider';
@@ -0,0 +1,6 @@
1
+ import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
2
+ import type { TapquestCoreRootState, TapquestCoreAppDispatch } from './index';
3
+
4
+ // Typed hooks for internal use within tapquest-core
5
+ export const useAppDispatch = () => useDispatch<TapquestCoreAppDispatch>();
6
+ export const useAppSelector: TypedUseSelectorHook<TapquestCoreRootState> = useSelector;
@@ -0,0 +1,45 @@
1
+ import { configureStore } from "@reduxjs/toolkit";
2
+ import storage from "redux-persist/lib/storage";
3
+ import { persistReducer, persistStore, PersistConfig } from "redux-persist";
4
+ import { authSlice } from "../modules/auth/store/authSlice";
5
+
6
+ // Auth persist config
7
+ const authPersistConfig: PersistConfig<any> = {
8
+ key: "tapquest-auth",
9
+ storage,
10
+ whitelist: ["user", "isSignedIn"], // Only persist user and sign-in status
11
+ };
12
+
13
+ // Create persisted auth reducer
14
+ const persistedAuthReducer = persistReducer(authPersistConfig, authSlice.reducer);
15
+
16
+ // Configure the tapquest-core store
17
+ export const store = configureStore({
18
+ reducer: {
19
+ auth: persistedAuthReducer,
20
+ },
21
+ middleware: (getDefaultMiddleware) =>
22
+ getDefaultMiddleware({
23
+ serializableCheck: {
24
+ // Ignore redux-persist actions
25
+ ignoredActions: [
26
+ 'persist/FLUSH',
27
+ 'persist/REHYDRATE',
28
+ 'persist/PAUSE',
29
+ 'persist/PERSIST',
30
+ 'persist/PURGE',
31
+ 'persist/REGISTER',
32
+ ],
33
+ },
34
+ }),
35
+ });
36
+
37
+ // Create persistor
38
+ export const persistor = persistStore(store);
39
+
40
+ // Export types
41
+ export type TapquestCoreRootState = ReturnType<typeof store.getState>;
42
+ export type TapquestCoreAppDispatch = typeof store.dispatch;
43
+
44
+ // Export store instance for internal use
45
+ export { store as tapquestCoreStore };
@@ -0,0 +1,8 @@
1
+ export enum Environment {
2
+ DEV = "dev",
3
+ STAGING = "staging",
4
+ PRODUCTION = "production",
5
+ }
6
+
7
+ export type EnvironmentType = "dev" | "staging" | "production";
8
+ export type APIVersionType = "v1" | "v2";
@@ -0,0 +1,26 @@
1
+ export enum MediaType {
2
+ IMAGE = "image",
3
+ VIDEO = "video",
4
+ }
5
+
6
+ export type DateTimeNumber = number;
7
+
8
+ export interface Media {
9
+ url: string;
10
+ type: MediaType;
11
+ thumbnail_url?: string;
12
+ }
13
+
14
+ export enum EntityStatus {
15
+ ACTIVE = "Active",
16
+ INACTIVE = "Inactive",
17
+ }
18
+
19
+ export interface CommonModel {
20
+ id: string;
21
+ status: EntityStatus;
22
+ created_at: DateTimeNumber;
23
+ updated_at: DateTimeNumber;
24
+ created_by?: string;
25
+ updated_by?: string;
26
+ }
@@ -0,0 +1,34 @@
1
+ import { QueryClient } from "@tanstack/react-query";
2
+ import { InternalAxiosRequestConfig } from "axios";
3
+
4
+ import { EnvironmentType } from "./common";
5
+
6
+ export interface RequestInterceptor {
7
+ onFulfilled?: (
8
+ config: InternalAxiosRequestConfig
9
+ ) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>;
10
+ onRejected?: (error: any) => any;
11
+ }
12
+
13
+ export interface ResponseInterceptor {
14
+ onFulfilled?: (response: any) => any;
15
+ onRejected?: (error: any) => any;
16
+ }
17
+
18
+ export interface APIConfig {
19
+ environment: EnvironmentType;
20
+ version: APIVersionType;
21
+ }
22
+
23
+ export interface ServiceConfig {
24
+ queryClient: QueryClient;
25
+ axiosConfig: {
26
+ headers: {
27
+ "Content-Type": string;
28
+ "Device-UID": string;
29
+ };
30
+ };
31
+ responseInterceptors: any;
32
+ requestInterceptors: any;
33
+ useDevTool: boolean;
34
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2021", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "allowJs": false,
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true,
15
+ "jsx": "react-jsx",
16
+ "baseUrl": ".",
17
+ "paths": {
18
+ "react": ["./node_modules/@types/react"]
19
+ },
20
+ /* Linting */
21
+ "strict": true,
22
+ "noUnusedLocals": true,
23
+ "noUnusedParameters": true,
24
+ "noFallthroughCasesInSwitch": true
25
+ },
26
+ "exclude": ["node_modules", "dist"],
27
+ "include": ["."]
28
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ entry: ["src/index.ts"],
5
+ format: ["cjs", "esm"],
6
+ dts: true,
7
+ splitting: false,
8
+ sourcemap: true,
9
+ clean: true,
10
+ });