@terreno/rtk 0.0.9
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.
- package/README.md +97 -0
- package/dist/authSlice.d.ts +73 -0
- package/dist/authSlice.d.ts.map +1 -0
- package/dist/authSlice.js +227 -0
- package/dist/authSlice.js.map +1 -0
- package/dist/constants.d.ts +16 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +76 -0
- package/dist/constants.js.map +1 -0
- package/dist/emptyApi.d.ts +19 -0
- package/dist/emptyApi.d.ts.map +1 -0
- package/dist/emptyApi.js +297 -0
- package/dist/emptyApi.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mongooseSlice.d.ts +11 -0
- package/dist/mongooseSlice.d.ts.map +1 -0
- package/dist/mongooseSlice.js +9 -0
- package/dist/mongooseSlice.js.map +1 -0
- package/dist/platform.d.ts +2 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +3 -0
- package/dist/platform.js.map +1 -0
- package/dist/socket.d.ts +20 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +317 -0
- package/dist/socket.js.map +1 -0
- package/dist/tagGenerator.d.ts +2 -0
- package/dist/tagGenerator.d.ts.map +1 -0
- package/dist/tagGenerator.js +60 -0
- package/dist/tagGenerator.js.map +1 -0
- package/package.json +47 -0
- package/src/authSlice.ts +274 -0
- package/src/constants.ts +105 -0
- package/src/emptyApi.ts +335 -0
- package/src/index.ts +7 -0
- package/src/mongooseSlice.ts +19 -0
- package/src/platform.ts +3 -0
- package/src/socket.ts +436 -0
- package/src/tagGenerator.ts +82 -0
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# @terreno/rtk
|
|
2
|
+
|
|
3
|
+
Redux Toolkit Query utilities for @terreno/api backends with React Native / Expo support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Authentication slice with JWT token management
|
|
8
|
+
- Secure token storage (SecureStore on mobile, AsyncStorage on web)
|
|
9
|
+
- Automatic token refresh
|
|
10
|
+
- Socket.io connection management with auth
|
|
11
|
+
- RTK Query base API with auth header injection
|
|
12
|
+
- OpenAPI SDK generation support
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
This package is part of the terreno workspace. Add it as a dependency:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun install @terreno/rtk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### Setting up the store
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import {generateAuthSlice} from "@terreno/rtk";
|
|
28
|
+
import {configureStore} from "@reduxjs/toolkit";
|
|
29
|
+
import {openapi} from "./openApiSdk";
|
|
30
|
+
|
|
31
|
+
const {authReducer, middleware} = generateAuthSlice(openapi);
|
|
32
|
+
|
|
33
|
+
export const store = configureStore({
|
|
34
|
+
reducer: {
|
|
35
|
+
auth: authReducer,
|
|
36
|
+
[openapi.reducerPath]: openapi.reducer,
|
|
37
|
+
},
|
|
38
|
+
middleware: (getDefault) =>
|
|
39
|
+
getDefault().concat(openapi.middleware, ...middleware),
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Generating an OpenAPI SDK
|
|
44
|
+
|
|
45
|
+
Create an `openapi-config.ts` in your project:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import type {ConfigFile} from "@rtk-query/codegen-openapi";
|
|
49
|
+
|
|
50
|
+
const config: ConfigFile = {
|
|
51
|
+
apiFile: "@terreno/rtk",
|
|
52
|
+
apiImport: "emptySplitApi",
|
|
53
|
+
argSuffix: "Args",
|
|
54
|
+
exportName: "openapi",
|
|
55
|
+
flattenArg: true,
|
|
56
|
+
hooks: true,
|
|
57
|
+
outputFile: "./store/openApiSdk.ts",
|
|
58
|
+
responseSuffix: "Res",
|
|
59
|
+
schemaFile: "http://localhost:3000/openapi.json",
|
|
60
|
+
tag: true,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default config;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Then run the codegen:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx @rtk-query/codegen-openapi openapi-config.ts
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Using socket connections
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import {useSocketConnection, getAuthToken, baseUrl} from "@terreno/rtk";
|
|
76
|
+
|
|
77
|
+
const {socket, isSocketConnected} = useSocketConnection({
|
|
78
|
+
baseUrl,
|
|
79
|
+
getAuthToken,
|
|
80
|
+
shouldConnect: !!userId,
|
|
81
|
+
onConnect: () => console.log("Connected"),
|
|
82
|
+
onDisconnect: () => console.log("Disconnected"),
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Exports
|
|
87
|
+
|
|
88
|
+
- `generateAuthSlice` - Creates auth slice with login/logout/token management
|
|
89
|
+
- `generateProfileEndpoints` - RTK Query endpoints for auth operations
|
|
90
|
+
- `emptySplitApi` - Base RTK Query API with auth
|
|
91
|
+
- `useSocketConnection` - Socket.io connection hook
|
|
92
|
+
- `getAuthToken` - Get current auth token
|
|
93
|
+
- `baseUrl`, `baseWebsocketsUrl`, `baseTasksUrl` - URL constants from Expo config
|
|
94
|
+
- `IsWeb` - Platform detection helper
|
|
95
|
+
- `generateTags` - RTK Query tag generator for cache invalidation
|
|
96
|
+
- `ListResponse`, `populateId` - Mongoose list response utilities
|
|
97
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type PayloadAction } from "@reduxjs/toolkit";
|
|
2
|
+
import type { Api, BaseQueryFn, EndpointBuilder } from "@reduxjs/toolkit/query/react";
|
|
3
|
+
import { type RootState } from "./constants";
|
|
4
|
+
type AuthState = {
|
|
5
|
+
userId: string | null;
|
|
6
|
+
error: string | null;
|
|
7
|
+
lastTokenRefreshTimestamp: number | null;
|
|
8
|
+
};
|
|
9
|
+
export interface UserResponse {
|
|
10
|
+
data: {
|
|
11
|
+
userId: string;
|
|
12
|
+
token: string;
|
|
13
|
+
refreshToken: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface EmailLoginRequest {
|
|
17
|
+
email: string;
|
|
18
|
+
password: string;
|
|
19
|
+
}
|
|
20
|
+
export interface EmailSignupRequest {
|
|
21
|
+
email: string;
|
|
22
|
+
password: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
export interface ResetPasswordRequest {
|
|
26
|
+
email: string;
|
|
27
|
+
password: string;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
export interface GoogleLoginRequest {
|
|
31
|
+
idToken: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function generateProfileEndpoints(builder: EndpointBuilder<BaseQueryFn<unknown, unknown, unknown>, any, string>, path: string): {
|
|
34
|
+
createEmailUser: import("@reduxjs/toolkit/query").MutationDefinition<EmailSignupRequest, BaseQueryFn<unknown, unknown, unknown>, any, UserResponse, string, unknown>;
|
|
35
|
+
emailLogin: import("@reduxjs/toolkit/query").MutationDefinition<EmailLoginRequest, BaseQueryFn<unknown, unknown, unknown>, any, UserResponse, string, unknown>;
|
|
36
|
+
emailSignUp: import("@reduxjs/toolkit/query").MutationDefinition<EmailSignupRequest, BaseQueryFn<unknown, unknown, unknown>, any, UserResponse, string, unknown>;
|
|
37
|
+
googleLogin: import("@reduxjs/toolkit/query").MutationDefinition<GoogleLoginRequest, BaseQueryFn<unknown, unknown, unknown>, any, UserResponse, string, unknown>;
|
|
38
|
+
resetPassword: import("@reduxjs/toolkit/query").MutationDefinition<ResetPasswordRequest, BaseQueryFn<unknown, unknown, unknown>, any, UserResponse, string, unknown>;
|
|
39
|
+
};
|
|
40
|
+
export declare const generateAuthSlice: (api: Api<any, any, any, any, any>) => {
|
|
41
|
+
authReducer: import("@reduxjs/toolkit").Reducer<AuthState>;
|
|
42
|
+
authSlice: import("@reduxjs/toolkit").Slice<AuthState, {
|
|
43
|
+
logout: (state: {
|
|
44
|
+
userId: string | null;
|
|
45
|
+
error: string | null;
|
|
46
|
+
lastTokenRefreshTimestamp: number | null;
|
|
47
|
+
}) => void;
|
|
48
|
+
setUserId: (state: {
|
|
49
|
+
userId: string | null;
|
|
50
|
+
error: string | null;
|
|
51
|
+
lastTokenRefreshTimestamp: number | null;
|
|
52
|
+
}, { payload: { userId } }: PayloadAction<{
|
|
53
|
+
userId: string;
|
|
54
|
+
}>) => void;
|
|
55
|
+
tokenRefreshedSuccess: (state: {
|
|
56
|
+
userId: string | null;
|
|
57
|
+
error: string | null;
|
|
58
|
+
lastTokenRefreshTimestamp: number | null;
|
|
59
|
+
}) => void;
|
|
60
|
+
}, "auth", "auth", import("@reduxjs/toolkit").SliceSelectors<AuthState>>;
|
|
61
|
+
logout: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"auth/logout">;
|
|
62
|
+
middleware: import("@reduxjs/toolkit").ListenerMiddleware<unknown, import("@reduxjs/toolkit").ThunkDispatch<unknown, unknown, import("@reduxjs/toolkit").UnknownAction>, unknown>[];
|
|
63
|
+
setUserId: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
64
|
+
userId: string;
|
|
65
|
+
}, "auth/setUserId">;
|
|
66
|
+
tokenRefreshedSuccess: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"auth/tokenRefreshedSuccess">;
|
|
67
|
+
};
|
|
68
|
+
export declare const selectCurrentUserId: (state: RootState) => string | undefined;
|
|
69
|
+
export declare const selectLastTokenRefreshTimestamp: (state: RootState) => number | null;
|
|
70
|
+
export declare const useSelectCurrentUserId: () => string | undefined;
|
|
71
|
+
export declare function getAuthToken(): Promise<string | null>;
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=authSlice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authSlice.d.ts","sourceRoot":"","sources":["../src/authSlice.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwC,KAAK,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAC3F,OAAO,KAAK,EAAC,GAAG,EAAE,WAAW,EAAE,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAIpF,OAAO,EAAqB,KAAK,SAAS,EAAC,MAAM,aAAa,CAAC;AAG/D,KAAK,SAAS,GAAG;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IAEjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IAEjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,wBAAgB,wBAAwB,CAEtC,OAAO,EAAE,eAAe,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAC7E,IAAI,EAAE,MAAM;;;;;;EAiDb;AAGD,eAAO,MAAM,iBAAiB,GAAI,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;;;;oBA5FzD,MAAM,GAAG,IAAI;mBACd,MAAM,GAAG,IAAI;uCACO,MAAM,GAAG,IAAI;;;oBAFhC,MAAM,GAAG,IAAI;mBACd,MAAM,GAAG,IAAI;uCACO,MAAM,GAAG,IAAI;oCAmII,aAAa,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAC,CAAC;;oBArInE,MAAM,GAAG,IAAI;mBACd,MAAM,GAAG,IAAI;uCACO,MAAM,GAAG,IAAI;;;;;;gBAmI2B,MAAM;;;CAqG1E,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,OAAO,SAAS,KAAG,MAAM,GAAG,SAA+B,CAAC;AAChG,eAAO,MAAM,+BAA+B,GAAI,OAAO,SAAS,KAAG,MAAM,GAAG,IACrC,CAAC;AAExC,eAAO,MAAM,sBAAsB,QAAO,MAAM,GAAG,SAIlD,CAAC;AAEF,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAe3D"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// Note: we will open source this when we get a chance, so there should be no imports from private
|
|
2
|
+
// files.
|
|
3
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
4
|
+
import { createListenerMiddleware, createSlice } from "@reduxjs/toolkit";
|
|
5
|
+
import * as SecureStore from "expo-secure-store";
|
|
6
|
+
import { useSelector } from "react-redux";
|
|
7
|
+
import { LOGOUT_ACTION_TYPE } from "./constants";
|
|
8
|
+
import { IsWeb } from "./platform";
|
|
9
|
+
// Define a service using a base URL and expected endpoints
|
|
10
|
+
export function generateProfileEndpoints(
|
|
11
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic
|
|
12
|
+
builder, path) {
|
|
13
|
+
return {
|
|
14
|
+
// This is a slightly different version of emailSignUp for creating another user using the
|
|
15
|
+
// auth/signup endpoint. This is useful for things like creating a user from an admin account.
|
|
16
|
+
// Unlike emailSignUp, this doesn't log in as the user.
|
|
17
|
+
createEmailUser: builder.mutation({
|
|
18
|
+
invalidatesTags: [path, "conversations"],
|
|
19
|
+
query: ({ email, password, ...body }) => ({
|
|
20
|
+
body: { email, password, ...body },
|
|
21
|
+
method: "POST",
|
|
22
|
+
url: `auth/signup`,
|
|
23
|
+
}),
|
|
24
|
+
}),
|
|
25
|
+
emailLogin: builder.mutation({
|
|
26
|
+
extraOptions: { maxRetries: 0 },
|
|
27
|
+
invalidatesTags: [path],
|
|
28
|
+
query: ({ email, password }) => ({
|
|
29
|
+
body: { email, password },
|
|
30
|
+
method: "POST",
|
|
31
|
+
url: "auth/login",
|
|
32
|
+
}),
|
|
33
|
+
}),
|
|
34
|
+
emailSignUp: builder.mutation({
|
|
35
|
+
invalidatesTags: [path],
|
|
36
|
+
query: ({ email, password, ...body }) => ({
|
|
37
|
+
body: { email, password, ...body },
|
|
38
|
+
method: "POST",
|
|
39
|
+
url: `auth/signup`,
|
|
40
|
+
}),
|
|
41
|
+
}),
|
|
42
|
+
googleLogin: builder.mutation({
|
|
43
|
+
extraOptions: { maxRetries: 0 },
|
|
44
|
+
invalidatesTags: [path],
|
|
45
|
+
query: (body) => ({
|
|
46
|
+
body,
|
|
47
|
+
method: "POST",
|
|
48
|
+
url: `/auth/google`,
|
|
49
|
+
}),
|
|
50
|
+
}),
|
|
51
|
+
resetPassword: builder.mutation({
|
|
52
|
+
extraOptions: { maxRetries: 0 },
|
|
53
|
+
query: ({ _id, password, oldPassword, newPassword, ...body }) => ({
|
|
54
|
+
body: { _id, newPassword, oldPassword, password, ...body },
|
|
55
|
+
method: "POST",
|
|
56
|
+
url: `/resetPassword`,
|
|
57
|
+
}),
|
|
58
|
+
}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic
|
|
62
|
+
export const generateAuthSlice = (api) => {
|
|
63
|
+
const authSlice = createSlice({
|
|
64
|
+
extraReducers: (builder) => {
|
|
65
|
+
builder.addMatcher(api.endpoints.emailLogin.matchFulfilled, () => {
|
|
66
|
+
console.debug("Login success");
|
|
67
|
+
});
|
|
68
|
+
builder.addMatcher(api.endpoints.emailLogin.matchRejected,
|
|
69
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic
|
|
70
|
+
(state, action) => {
|
|
71
|
+
state.error = action.payload?.data?.message;
|
|
72
|
+
console.debug("Login rejected", action.payload?.data?.message);
|
|
73
|
+
});
|
|
74
|
+
builder.addMatcher(api.endpoints.emailLogin.matchPending, (state) => {
|
|
75
|
+
state.error = null;
|
|
76
|
+
console.debug("Login pending");
|
|
77
|
+
});
|
|
78
|
+
builder.addMatcher(api.endpoints.emailSignUp.matchFulfilled, () => {
|
|
79
|
+
console.debug("Signup success");
|
|
80
|
+
});
|
|
81
|
+
builder.addMatcher(api.endpoints.emailSignUp.matchRejected,
|
|
82
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic
|
|
83
|
+
(state, action) => {
|
|
84
|
+
state.error = action.payload?.data?.message;
|
|
85
|
+
console.debug("Signup rejected", action.payload);
|
|
86
|
+
});
|
|
87
|
+
builder.addMatcher(api.endpoints.emailSignUp.matchPending, (state) => {
|
|
88
|
+
state.error = null;
|
|
89
|
+
console.debug("Signup pending");
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
initialState: { error: null, lastTokenRefreshTimestamp: null, userId: null },
|
|
93
|
+
name: "auth",
|
|
94
|
+
reducers: {
|
|
95
|
+
logout: (state) => {
|
|
96
|
+
state.userId = null;
|
|
97
|
+
state.lastTokenRefreshTimestamp = null;
|
|
98
|
+
},
|
|
99
|
+
setUserId: (state, { payload: { userId } }) => {
|
|
100
|
+
state.userId = userId;
|
|
101
|
+
},
|
|
102
|
+
tokenRefreshedSuccess: (state) => {
|
|
103
|
+
state.lastTokenRefreshTimestamp = Date.now();
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
// Since we need to do async actions to store tokens in expo-secure-store,
|
|
108
|
+
// we need to use a listener middleware.
|
|
109
|
+
const loginListenerMiddleware = createListenerMiddleware();
|
|
110
|
+
loginListenerMiddleware.startListening({
|
|
111
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic
|
|
112
|
+
effect: async (action, listenerApi) => {
|
|
113
|
+
if (action.payload?.token &&
|
|
114
|
+
(action.meta?.arg?.endpointName === "emailLogin" ||
|
|
115
|
+
action.meta?.arg?.endpointName === "emailSignUp" ||
|
|
116
|
+
action.meta?.arg?.endpointName === "googleLogin")) {
|
|
117
|
+
if (!IsWeb) {
|
|
118
|
+
if (!action.payload.token) {
|
|
119
|
+
console.error("No token found in app login response.", action.payload);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
await SecureStore.setItemAsync("AUTH_TOKEN", action.payload.token);
|
|
124
|
+
await SecureStore.setItemAsync("REFRESH_TOKEN", action.payload.refreshToken);
|
|
125
|
+
console.debug("Saved auth token to secure storage.");
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error(`Error setting auth token: ${error}`);
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
if (!action.payload.token) {
|
|
134
|
+
console.error("No token found in web login response.", action.payload);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
// On web, we don't have secure storage, and cookie support is not in Expo yet,
|
|
138
|
+
// so this is what we're left with. This can be vulnerable to XSS attacks.
|
|
139
|
+
try {
|
|
140
|
+
// Check if we're in a browser environment (not SSR)
|
|
141
|
+
if (typeof window !== "undefined") {
|
|
142
|
+
await AsyncStorage.setItem("AUTH_TOKEN", action.payload.token);
|
|
143
|
+
await AsyncStorage.setItem("REFRESH_TOKEN", action.payload.refreshToken);
|
|
144
|
+
console.debug("Saved auth token to async storage.");
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
console.warn("Cannot store auth token: window is not defined (SSR context)");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
console.error(`Error setting auth token: ${error}`);
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
listenerApi.dispatch(authSlice.actions.setUserId({ userId: action.payload.userId }));
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
type: "terreno-rtk/executeMutation/fulfilled",
|
|
159
|
+
});
|
|
160
|
+
// const clearLocalStorage = async (): Promise<void> => {
|
|
161
|
+
// try {
|
|
162
|
+
// const keys = await AsyncStorage.getAllKeys();
|
|
163
|
+
// const keysToRemove = keys.filter((key) => key.includes("formInstance"));
|
|
164
|
+
// if (keysToRemove.length > 0) {
|
|
165
|
+
// await AsyncStorage.multiRemove(keysToRemove);
|
|
166
|
+
// console.debug("Cleared local storage.");
|
|
167
|
+
// }
|
|
168
|
+
// } catch (error) {
|
|
169
|
+
// console.error("Error:", error);
|
|
170
|
+
// }
|
|
171
|
+
// };
|
|
172
|
+
// Since we need to do async actions to store tokens in expo-secure-store,
|
|
173
|
+
// we need to use a listener middleware.
|
|
174
|
+
const logoutListenerMiddleware = createListenerMiddleware();
|
|
175
|
+
logoutListenerMiddleware.startListening({
|
|
176
|
+
effect: async () => {
|
|
177
|
+
// TODO: We should only clear local storage when we're logging out, not disconnected.
|
|
178
|
+
// await clearLocalStorage();
|
|
179
|
+
if (!IsWeb) {
|
|
180
|
+
await SecureStore.deleteItemAsync("AUTH_TOKEN");
|
|
181
|
+
await SecureStore.deleteItemAsync("REFRESH_TOKEN");
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// Check if we're in a browser environment (not SSR)
|
|
185
|
+
if (typeof window !== "undefined") {
|
|
186
|
+
await AsyncStorage.removeItem("AUTH_TOKEN");
|
|
187
|
+
await AsyncStorage.removeItem("REFRESH_TOKEN");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
console.debug("Cleared auth token from secure storage as part of logout.");
|
|
191
|
+
},
|
|
192
|
+
type: LOGOUT_ACTION_TYPE,
|
|
193
|
+
});
|
|
194
|
+
return {
|
|
195
|
+
authReducer: authSlice.reducer,
|
|
196
|
+
authSlice,
|
|
197
|
+
logout: authSlice.actions.logout,
|
|
198
|
+
middleware: [logoutListenerMiddleware.middleware, loginListenerMiddleware.middleware],
|
|
199
|
+
setUserId: authSlice.actions.setUserId,
|
|
200
|
+
tokenRefreshedSuccess: authSlice.actions.tokenRefreshedSuccess,
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
export const selectCurrentUserId = (state) => state.auth?.userId;
|
|
204
|
+
export const selectLastTokenRefreshTimestamp = (state) => state.auth?.lastTokenRefreshTimestamp;
|
|
205
|
+
export const useSelectCurrentUserId = () => {
|
|
206
|
+
return useSelector((state) => {
|
|
207
|
+
return state.auth?.userId;
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
export async function getAuthToken() {
|
|
211
|
+
let token;
|
|
212
|
+
if (!IsWeb) {
|
|
213
|
+
token = await SecureStore.getItemAsync("AUTH_TOKEN");
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// Check if we're in a browser environment (not SSR)
|
|
217
|
+
if (typeof window !== "undefined") {
|
|
218
|
+
token = await AsyncStorage.getItem("AUTH_TOKEN");
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
console.warn("Cannot get auth token: window is not defined (SSR context)");
|
|
222
|
+
token = null;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return token;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=authSlice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authSlice.js","sourceRoot":"","sources":["../src/authSlice.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,SAAS;AACT,OAAO,YAAY,MAAM,2CAA2C,CAAC;AACrE,OAAO,EAAC,wBAAwB,EAAE,WAAW,EAAqB,MAAM,kBAAkB,CAAC;AAE3F,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAExC,OAAO,EAAC,kBAAkB,EAAiB,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAuCjC,2DAA2D;AAC3D,MAAM,UAAU,wBAAwB;AACtC,sDAAsD;AACtD,OAA6E,EAC7E,IAAY;IAEZ,OAAO;QACL,0FAA0F;QAC1F,8FAA8F;QAC9F,uDAAuD;QACvD,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAmC;YAClE,eAAe,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC;YACxC,KAAK,EAAE,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAC,EAAE,EAAE,CAAC,CAAC;gBACtC,IAAI,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAC;gBAChC,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,aAAa;aACnB,CAAC;SACH,CAAC;QACF,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAkC;YAC5D,YAAY,EAAE,EAAC,UAAU,EAAE,CAAC,EAAC;YAC7B,eAAe,EAAE,CAAC,IAAI,CAAC;YACvB,KAAK,EAAE,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAE,EAAE,CAAC,CAAC;gBAC7B,IAAI,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAC;gBACvB,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,YAAY;aAClB,CAAC;SACH,CAAC;QACF,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAmC;YAC9D,eAAe,EAAE,CAAC,IAAI,CAAC;YACvB,KAAK,EAAE,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAC,EAAE,EAAE,CAAC,CAAC;gBACtC,IAAI,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAC;gBAChC,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,aAAa;aACnB,CAAC;SACH,CAAC;QACF,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAmC;YAC9D,YAAY,EAAE,EAAC,UAAU,EAAE,CAAC,EAAC;YAC7B,eAAe,EAAE,CAAC,IAAI,CAAC;YACvB,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChB,IAAI;gBACJ,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,cAAc;aACpB,CAAC;SACH,CAAC;QACF,aAAa,EAAE,OAAO,CAAC,QAAQ,CAAqC;YAClE,YAAY,EAAE,EAAC,UAAU,EAAE,CAAC,EAAC;YAC7B,KAAK,EAAE,CAAC,EAAC,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,IAAI,EAAC,EAAE,EAAE,CAAC,CAAC;gBAC9D,IAAI,EAAE,EAAC,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAC;gBACxD,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,gBAAgB;aACtB,CAAC;SACH,CAAC;KACH,CAAC;AACJ,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAiC,EAAE,EAAE;IACrE,MAAM,SAAS,GAAG,WAAW,CAAC;QAC5B,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;YACzB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,cAAc,EAAE,GAAG,EAAE;gBAC/D,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,UAAU,CAChB,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,aAAa;YACtC,sDAAsD;YACtD,CAAC,KAAK,EAAE,MAAkC,EAAE,EAAE;gBAC5C,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC;gBAC5C,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YACjE,CAAC,CACF,CAAC;YACF,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;gBACnB,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,cAAc,EAAE,GAAG,EAAE;gBAChE,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,UAAU,CAChB,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,aAAa;YACvC,sDAAsD;YACtD,CAAC,KAAK,EAAE,MAAkC,EAAE,EAAE;gBAC5C,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC;gBAC5C,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YACnD,CAAC,CACF,CAAC;YACF,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;gBACnE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;gBACnB,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC;QACD,YAAY,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAc;QACvF,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE;YACR,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAChB,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;gBACpB,KAAK,CAAC,yBAAyB,GAAG,IAAI,CAAC;YACzC,CAAC;YACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAC,OAAO,EAAE,EAAC,MAAM,EAAC,EAAkC,EAAE,EAAE;gBACzE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;YACxB,CAAC;YACD,qBAAqB,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/B,KAAK,CAAC,yBAAyB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/C,CAAC;SACF;KACF,CAAC,CAAC;IACH,0EAA0E;IAC1E,wCAAwC;IACxC,MAAM,uBAAuB,GAAG,wBAAwB,EAAE,CAAC;IAC3D,uBAAuB,CAAC,cAAc,CAAC;QACrC,sDAAsD;QACtD,MAAM,EAAE,KAAK,EAAE,MAAW,EAAE,WAAW,EAAE,EAAE;YACzC,IACE,MAAM,CAAC,OAAO,EAAE,KAAK;gBACrB,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,KAAK,YAAY;oBAC9C,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,KAAK,aAAa;oBAChD,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,KAAK,aAAa,CAAC,EACnD,CAAC;gBACD,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;wBAC1B,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;wBACvE,OAAO;oBACT,CAAC;oBACD,IAAI,CAAC;wBACH,MAAM,WAAW,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACnE,MAAM,WAAW,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;wBAC7E,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;oBACvD,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC;wBACpD,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;wBAC1B,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;wBACvE,OAAO;oBACT,CAAC;oBACD,+EAA+E;oBAC/E,0EAA0E;oBAC1E,IAAI,CAAC;wBACH,oDAAoD;wBACpD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;4BAClC,MAAM,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;4BAC/D,MAAM,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;4BACzE,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;wBACtD,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;wBAC/E,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC;wBACpD,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;gBACD,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,EAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAC,CAAC,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QACD,IAAI,EAAE,uCAAuC;KAC9C,CAAC,CAAC;IAEH,yDAAyD;IACzD,UAAU;IACV,oDAAoD;IACpD,+EAA+E;IAC/E,qCAAqC;IACrC,sDAAsD;IACtD,iDAAiD;IACjD,QAAQ;IACR,sBAAsB;IACtB,sCAAsC;IACtC,MAAM;IACN,KAAK;IACL,0EAA0E;IAC1E,wCAAwC;IACxC,MAAM,wBAAwB,GAAG,wBAAwB,EAAE,CAAC;IAC5D,wBAAwB,CAAC,cAAc,CAAC;QACtC,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,qFAAqF;YACrF,6BAA6B;YAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,WAAW,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;gBAChD,MAAM,WAAW,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,oDAAoD;gBACpD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;oBAClC,MAAM,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;oBAC5C,MAAM,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,EAAE,kBAAkB;KACzB,CAAC,CAAC;IACH,OAAO;QACL,WAAW,EAAE,SAAS,CAAC,OAAO;QAC9B,SAAS;QACT,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,MAAM;QAChC,UAAU,EAAE,CAAC,wBAAwB,CAAC,UAAU,EAAE,uBAAuB,CAAC,UAAU,CAAC;QACrF,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,SAAS;QACtC,qBAAqB,EAAE,SAAS,CAAC,OAAO,CAAC,qBAAqB;KAC/D,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAgB,EAAsB,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;AAChG,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,KAAgB,EAAiB,EAAE,CACjF,KAAK,CAAC,IAAI,EAAE,yBAAyB,CAAC;AAExC,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAuB,EAAE;IAC7D,OAAO,WAAW,CAAC,CAAC,KAAgB,EAAsB,EAAE;QAC1D,OAAO,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,KAAoB,CAAC;IAEzB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,oDAAoD;QACpD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,KAAK,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;YAC3E,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type RootState = any;
|
|
2
|
+
export declare const LOGOUT_ACTION_TYPE = "auth/logout";
|
|
3
|
+
export declare const TOKEN_REFRESHED_SUCCESS = "auth/tokenRefreshedSuccess";
|
|
4
|
+
export declare const AUTH_DEBUG: boolean;
|
|
5
|
+
export declare const logAuth: (...args: string[]) => void;
|
|
6
|
+
export declare const logSocket: (user?: {
|
|
7
|
+
featureFlags?: {
|
|
8
|
+
debugWebsockets?: {
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
} | boolean, ...args: string[]) => void;
|
|
13
|
+
export declare let baseUrl: string;
|
|
14
|
+
export declare let baseWebsocketsUrl: string;
|
|
15
|
+
export declare let baseTasksUrl: string;
|
|
16
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC;AAC5B,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAChD,eAAO,MAAM,uBAAuB,+BAA+B,CAAC;AAEpE,eAAO,MAAM,UAAU,SAAqD,CAAC;AAK7E,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,MAAM,EAAE,KAAG,IAI3C,CAAC;AAUF,eAAO,MAAM,SAAS,GACpB,OAAO;IAAC,YAAY,CAAC,EAAE;QAAC,eAAe,CAAC,EAAE;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAC,CAAA;KAAC,CAAA;CAAC,GAAG,OAAO,EACzE,GAAG,MAAM,MAAM,EAAE,KAChB,IAQF,CAAC;AAUF,eAAO,IAAI,OAAO,EAAE,MAAM,CAAC;AAC3B,eAAO,IAAI,iBAAiB,EAAE,MAAM,CAAC;AACrC,eAAO,IAAI,YAAY,EAAE,MAAM,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import Constants from "expo-constants";
|
|
2
|
+
export const LOGOUT_ACTION_TYPE = "auth/logout";
|
|
3
|
+
export const TOKEN_REFRESHED_SUCCESS = "auth/tokenRefreshedSuccess";
|
|
4
|
+
export const AUTH_DEBUG = Constants.expoConfig?.extra?.AUTH_DEBUG === "true";
|
|
5
|
+
if (AUTH_DEBUG) {
|
|
6
|
+
console.debug("AUTH_DEBUG is enabled");
|
|
7
|
+
}
|
|
8
|
+
export const logAuth = (...args) => {
|
|
9
|
+
if (AUTH_DEBUG) {
|
|
10
|
+
console.debug(...args);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
// Handy debug logging socket events, but not enabled by default.
|
|
14
|
+
// Can also be enabled by user feature flag.
|
|
15
|
+
const WEBSOCKETS_DEBUG = Constants.expoConfig?.extra?.WEBSOCKETS_DEBUG === "true";
|
|
16
|
+
if (WEBSOCKETS_DEBUG) {
|
|
17
|
+
console.debug("WEBSOCKETS_DEBUG is enabled");
|
|
18
|
+
}
|
|
19
|
+
// Handy debug logging for websockets, enabled by user.featureFlags.debugWebsockets.enabled or passing in true.
|
|
20
|
+
export const logSocket = (user, ...args) => {
|
|
21
|
+
if (typeof user === "boolean"
|
|
22
|
+
? user
|
|
23
|
+
: user?.featureFlags?.debugWebsockets?.enabled || WEBSOCKETS_DEBUG) {
|
|
24
|
+
console.debug(`[websocket]`, ...args);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
// When we use "expo publish", we want to point the API at the prod API. In the future,
|
|
28
|
+
// we'll want to point at the staging API, and probably have a development release channel.
|
|
29
|
+
if (Constants.expoGoConfig?.debuggerHost?.includes("exp.direct")) {
|
|
30
|
+
console.error("Expo Tunnel is not currently supported for connecting to the API, please use LAN or Local mode.");
|
|
31
|
+
}
|
|
32
|
+
export let baseUrl;
|
|
33
|
+
export let baseWebsocketsUrl;
|
|
34
|
+
export let baseTasksUrl;
|
|
35
|
+
if (Constants.expoConfig?.extra?.BASE_URL) {
|
|
36
|
+
// For prod/staging
|
|
37
|
+
baseUrl = Constants.expoConfig?.extra?.BASE_URL;
|
|
38
|
+
baseWebsocketsUrl = `${baseUrl.replace("api.", "ws.")}/`;
|
|
39
|
+
baseTasksUrl = `${baseUrl.replace("api.", "tasks.")}/tasks`;
|
|
40
|
+
console.debug(`Base URL set to apiUrl ${baseUrl} for env ${Constants.expoConfig?.extra?.APP_ENV ?? "unknown"}, websocket to ${baseWebsocketsUrl}, tasks to ${baseTasksUrl}`);
|
|
41
|
+
}
|
|
42
|
+
else if (process.env.EXPO_PUBLIC_API_URL) {
|
|
43
|
+
// For dev web
|
|
44
|
+
baseUrl = process.env.EXPO_PUBLIC_API_URL;
|
|
45
|
+
baseWebsocketsUrl = `${baseUrl.replace("api.", "ws.")}/`;
|
|
46
|
+
baseTasksUrl = `${baseUrl.replace("api.", "tasks.")}/tasks`;
|
|
47
|
+
console.debug(`Base URL set to apiUrl ${baseUrl} for env ${Constants.expoConfig?.extra?.APP_ENV ?? "unknown"}, websocket to ${baseWebsocketsUrl}, tasks to ${baseTasksUrl}`);
|
|
48
|
+
}
|
|
49
|
+
else if (Constants.expoConfig?.hostUri) {
|
|
50
|
+
// For dev simulator/device
|
|
51
|
+
baseUrl = `http://${Constants.expoConfig?.hostUri?.split(`:`).shift()?.concat(":3000")}`;
|
|
52
|
+
baseWebsocketsUrl = `ws://${Constants.expoConfig?.hostUri?.split(`:`).shift()?.concat(":3000")}/`;
|
|
53
|
+
baseTasksUrl = `http://${Constants.expoConfig?.hostUri?.split(`:`).shift()?.concat(":3000")}/tasks`;
|
|
54
|
+
console.debug(`Base URL set to hostUri ${baseUrl}, websocket to ${baseWebsocketsUrl}`, Constants.expoConfig?.hostUri);
|
|
55
|
+
}
|
|
56
|
+
else if (Constants.experienceUrl) {
|
|
57
|
+
// For dev web
|
|
58
|
+
baseUrl = `http:${Constants.experienceUrl?.split(`:`)[1]?.concat(":3000")}`;
|
|
59
|
+
baseWebsocketsUrl = `ws:${Constants.experienceUrl?.split(`:`)[1]?.concat(":3000")}/`;
|
|
60
|
+
baseTasksUrl = `http:${Constants.experienceUrl?.split(`:`)[1]?.concat(":3000")}/tasks`;
|
|
61
|
+
console.debug(`Base URL set to experienceUrl ${baseUrl}, websocket to ${baseWebsocketsUrl}`, Constants.expoConfig?.hostUri);
|
|
62
|
+
}
|
|
63
|
+
else if (!Constants.expoConfig?.extra?.BASE_URL &&
|
|
64
|
+
!Constants.expoConfig?.hostUri &&
|
|
65
|
+
!Constants.experienceUrl) {
|
|
66
|
+
// For dev web, which doesn't have experienceUrl for some reason?
|
|
67
|
+
baseUrl = `http://localhost:3000`;
|
|
68
|
+
baseWebsocketsUrl = `ws://localhost:3000/`;
|
|
69
|
+
baseTasksUrl = `http://localhost:3000/tasks`;
|
|
70
|
+
console.debug(`Base URL set to localhost ${baseUrl}, websocket to ${baseWebsocketsUrl}`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.error("No base URL found", Constants.expoConfig, Constants.experienceUrl);
|
|
74
|
+
throw new Error("No base URL found");
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type FetchArgs } from "@reduxjs/toolkit/query/react";
|
|
2
|
+
export declare function getTokenExpirationTimes(): Promise<{
|
|
3
|
+
refreshRemainingSecs?: number;
|
|
4
|
+
authRemainingSecs?: number;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const getFriendlyExpirationInfo: () => Promise<string>;
|
|
7
|
+
export declare const shouldShowStillThereModal: () => Promise<boolean>;
|
|
8
|
+
export declare const refreshAuthToken: () => Promise<void>;
|
|
9
|
+
export declare const emptySplitApi: import("@reduxjs/toolkit/query").Api<import("@reduxjs/toolkit/query").BaseQueryFn<string | FetchArgs, unknown, import("@reduxjs/toolkit/query").FetchBaseQueryError | {
|
|
10
|
+
error: string;
|
|
11
|
+
status: string;
|
|
12
|
+
}, {} & import("@reduxjs/toolkit/query").RetryOptions, {}>, {
|
|
13
|
+
createEmailUser: import("@reduxjs/toolkit/query").MutationDefinition<import("./authSlice").EmailSignupRequest, import("@reduxjs/toolkit/query").BaseQueryFn<unknown, unknown, unknown>, any, import("./authSlice").UserResponse, string, unknown>;
|
|
14
|
+
emailLogin: import("@reduxjs/toolkit/query").MutationDefinition<import("./authSlice").EmailLoginRequest, import("@reduxjs/toolkit/query").BaseQueryFn<unknown, unknown, unknown>, any, import("./authSlice").UserResponse, string, unknown>;
|
|
15
|
+
emailSignUp: import("@reduxjs/toolkit/query").MutationDefinition<import("./authSlice").EmailSignupRequest, import("@reduxjs/toolkit/query").BaseQueryFn<unknown, unknown, unknown>, any, import("./authSlice").UserResponse, string, unknown>;
|
|
16
|
+
googleLogin: import("@reduxjs/toolkit/query").MutationDefinition<import("./authSlice").GoogleLoginRequest, import("@reduxjs/toolkit/query").BaseQueryFn<unknown, unknown, unknown>, any, import("./authSlice").UserResponse, string, unknown>;
|
|
17
|
+
resetPassword: import("@reduxjs/toolkit/query").MutationDefinition<import("./authSlice").ResetPasswordRequest, import("@reduxjs/toolkit/query").BaseQueryFn<unknown, unknown, unknown>, any, import("./authSlice").UserResponse, string, unknown>;
|
|
18
|
+
}, "terreno-rtk", never, typeof import("@reduxjs/toolkit/query").coreModuleName | typeof import("@reduxjs/toolkit/query/react").reactHooksModuleName>;
|
|
19
|
+
//# sourceMappingURL=emptyApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emptyApi.d.ts","sourceRoot":"","sources":["../src/emptyApi.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,8BAA8B,CAAC;AAuBtC,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IACvD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC,CAoCD;AAGD,eAAO,MAAM,yBAAyB,QAAa,OAAO,CAAC,MAAM,CAyBhE,CAAC;AAIF,eAAO,MAAM,yBAAyB,QAAa,OAAO,CAAC,OAAO,CAMjE,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,IAAI,CA4CrD,CAAC;AA4KF,eAAO,MAAM,aAAa;;;;;;;;;qJAOxB,CAAC"}
|