@rpcbase/client 0.230.0 → 0.232.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.
- package/package.json +13 -114
- package/src/apiClient/getServerApiClient.ts +131 -0
- package/src/apiClient/index.ts +86 -0
- package/src/index.ts +3 -0
- package/src/initClient.ts +32 -0
- package/src/types.ts +7 -0
- package/AppProvider/AnalyticsContainer.js +0 -56
- package/AppProvider/debug.js +0 -4
- package/AppProvider/index.tsx +0 -79
- package/access-control/ACLForm/components/GrantField/OpSelector.tsx +0 -129
- package/access-control/ACLForm/components/GrantField/ResourceSelector.tsx +0 -86
- package/access-control/ACLForm/components/GrantField/UsersSelector.tsx +0 -96
- package/access-control/ACLForm/components/GrantField/grant-field.scss +0 -26
- package/access-control/ACLForm/components/GrantField/icons/CheckMark.tsx +0 -16
- package/access-control/ACLForm/components/GrantField/icons/CollapseArrow.tsx +0 -14
- package/access-control/ACLForm/components/GrantField/icons/ExpandArrow.tsx +0 -14
- package/access-control/ACLForm/components/GrantField/index.tsx +0 -91
- package/access-control/ACLForm/components/GrantsList.tsx +0 -48
- package/access-control/ACLForm/components/RoleForm.tsx +0 -134
- package/access-control/ACLForm/components/RoleView.tsx +0 -115
- package/access-control/ACLForm/components/RolesList.tsx +0 -79
- package/access-control/ACLForm/components/constants.tsx +0 -1
- package/access-control/ACLForm/components/resolver.ts +0 -57
- package/access-control/ACLForm/components/role-form.scss +0 -19
- package/access-control/ACLForm/index.tsx +0 -48
- package/access-control/ACLModal/acl-modal.scss +0 -7
- package/access-control/ACLModal/index.tsx +0 -66
- package/access-control/PolicyEditor/TargetSelector/QueryBuilder.tsx +0 -48
- package/access-control/PolicyEditor/TargetSelector/index.tsx +0 -5
- package/access-control/PolicyEditor/TargetSelector/query-builder.scss +0 -9
- package/access-control/PolicyEditor/index.tsx +0 -165
- package/access-control/index.ts +0 -3
- package/apiClient.js +0 -15
- package/auth/authProps.js +0 -8
- package/auth/components/AccountsList/AccountListItem.js +0 -61
- package/auth/components/AccountsList/account-list-item.scss +0 -5
- package/auth/components/AccountsList/index.js +0 -17
- package/auth/components/Footer/index.js +0 -11
- package/auth/components/ForgotPassword/forgot-password.scss +0 -37
- package/auth/components/ForgotPassword/index.js +0 -114
- package/auth/components/SetNewPassword/index.js +0 -130
- package/auth/components/SetNewPassword/set-new-password.scss +0 -47
- package/auth/components/SignIn/SignInEmailForm.tsx +0 -115
- package/auth/components/SignIn/index.js +0 -69
- package/auth/components/SignIn/sign-in.scss +0 -56
- package/auth/components/SignOut/index.js +0 -144
- package/auth/components/SignOut/sign-out.scss +0 -34
- package/auth/components/SignUp/SignUpEmailForm.tsx +0 -98
- package/auth/components/SignUp/index.js +0 -66
- package/auth/components/SignUp/sign-up.scss +0 -56
- package/auth/getTenantId.js +0 -12
- package/auth/getUid.js +0 -11
- package/auth/helpers/redirectSignIn.native.js +0 -9
- package/auth/helpers/redirectSignIn.web.js +0 -7
- package/auth/index.js +0 -146
- package/auth/signOut.js +0 -20
- package/auth/useAuthRouter.js +0 -56
- package/env.d.ts +0 -3
- package/firebase/index.js +0 -1
- package/firebase/sw.js +0 -1
- package/form/FileInput/FileUploadContext.tsx +0 -162
- package/form/FileInput/FileUploadForm/index.tsx +0 -139
- package/form/FileInput/FileUploadForm/usePreventUnload.js +0 -21
- package/form/FileInput/UploadButton.tsx +0 -23
- package/form/FileInput/constants.ts +0 -16
- package/form/FileInput/file-input.scss +0 -1
- package/form/FileInput/index.tsx +0 -21
- package/form/FileInput/upload-worker/get_file_hash.js +0 -63
- package/form/FileInput/upload-worker/index.js +0 -16
- package/form/FileInput/upload-worker/no_compress_exts.ts +0 -33
- package/form/FileInput/upload-worker/upload_file.js +0 -129
- package/form/Form.tsx +0 -23
- package/form/Input.tsx +0 -62
- package/form/SubmitButton/index.tsx +0 -58
- package/form/hook-form.tsx +0 -7
- package/form/index.tsx +0 -5
- package/getBaseUrl.js +0 -14
- package/getObjectId.ts +0 -31
- package/hashState.js +0 -158
- package/helpers/createBatcher/index.js +0 -36
- package/helpers/getInitials.js +0 -39
- package/helpers/onReady.js +0 -15
- package/helpers/post.js +0 -18
- package/helpers/postRPC.js +0 -42
- package/helpers/useRPC.js +0 -41
- package/helpers/useStoredValue/batchedGetStoredValues.js +0 -30
- package/helpers/useStoredValue/index.js +0 -107
- package/helpers/useStoredValue/setStoredValues.js +0 -14
- package/i18n/en/rb.nav.json +0 -13
- package/i18n/en/rb.sign_in.json +0 -11
- package/i18n/en/rb.sign_out.json +0 -5
- package/i18n/fr/rb.sign_in.json +0 -11
- package/i18n/fr/rb.sign_out.json +0 -5
- package/i18n/index.js +0 -63
- package/index.js +0 -6
- package/isEqualValues.js +0 -47
- package/jest.config.js +0 -16
- package/notifications/Notification/index.js +0 -36
- package/notifications/Notification/notification.scss +0 -1
- package/notifications/NotificationItem/HeaderStatus.js +0 -93
- package/notifications/NotificationItem/index.js +0 -65
- package/notifications/NotificationItem/notification-item.scss +0 -25
- package/notifications/NotificationsContainer/index.js +0 -37
- package/notifications/NotificationsContainer/notifications-container.scss +0 -38
- package/notifications/NotificationsContainer/useLLTs.js +0 -28
- package/notifications/NotificationsContext/index.js +0 -71
- package/notifications/NotificationsContext/useNotificationsList.js +0 -75
- package/notifications/NotificationsSettingsModal/SettingsForm.js +0 -52
- package/notifications/NotificationsSettingsModal/index.js +0 -48
- package/notifications/NotificationsSettingsModal/notifications-settings.scss +0 -1
- package/notifications/config.js +0 -1
- package/notifications/index.js +0 -4
- package/page.js +0 -9
- package/publish-output.txt +0 -0
- package/rpc.js +0 -32
- package/rr-trace/get_fingerprint.js +0 -10
- package/rr-trace/get_perf_vitals.js +0 -24
- package/rr-trace/get_session_id.js +0 -29
- package/rr-trace/index.js +0 -138
- package/rr-trace/write_session_data.js +0 -86
- package/rts/boot.js +0 -3
- package/rts/getUseDocument.js +0 -21
- package/rts/getUseQuery/index.js +0 -233
- package/rts/getUseQuery/useData.js +0 -55
- package/rts/index.js +0 -10
- package/rts/rts.js +0 -243
- package/rts/signout.ts +0 -8
- package/rts/store/constants.js +0 -3
- package/rts/store/debug.js +0 -24
- package/rts/store/get_collection.js +0 -55
- package/rts/store/index.js +0 -100
- package/rts/store/replace_query_keys.js +0 -31
- package/rts/store/satisfies_projection.js +0 -32
- package/rts/store/update_docs.js +0 -47
- package/storage/index.jest.js +0 -15
- package/storage/index.native.js +0 -38
- package/storage/index.web.js +0 -25
- package/types.ts +0 -6
- package/ui/ActivityIndicator/index.js +0 -113
- package/ui/Avatar/index.native.js +0 -31
- package/ui/Avatar/index.web.js +0 -37
- package/ui/Avatar/styles.js +0 -41
- package/ui/ErrorBoundary/index.js +0 -12
- package/ui/ExpandableFloatView/exp.scss +0 -15
- package/ui/ExpandableFloatView/index.tsx +0 -123
- package/ui/ExpandableFloatView/useBackdrop.js +0 -45
- package/ui/LottiePlayer/LottiePlayer.js +0 -4
- package/ui/LottiePlayer/index.js +0 -8
- package/ui/Modal/HashStateModal.js +0 -30
- package/ui/Modal/Modal.js +0 -93
- package/ui/Modal/ModalForm/AlertBanner.js +0 -82
- package/ui/Modal/ModalForm/index.js +0 -188
- package/ui/Modal/ModalForm/modal-form.scss +0 -63
- package/ui/Modal/index.js +0 -10
- package/ui/Modal/modal.scss +0 -101
- package/ui/Modal/withHashStateModal.js +0 -24
- package/ui/RedboxError/index.js +0 -3
- package/ui/Search/SearchHistory/index.js +0 -45
- package/ui/Search/SearchHistory/search-history.scss +0 -9
- package/ui/Search/SearchHistory/useSearchHistory.tsx +0 -57
- package/ui/Search/SearchResults/index.tsx +0 -90
- package/ui/Search/index.tsx +0 -298
- package/ui/Search/search.scss +0 -0
- package/ui/SelectPills/index.tsx +0 -96
- package/ui/SelectPills/select-pills.scss +0 -66
- package/ui/Tabs/index.tsx +0 -161
- package/ui/Tabs/tabs.scss +0 -53
- package/ui/Tree/index.js +0 -257
- package/ui/Tree/model.js +0 -71
- package/ui/Tree/node.js +0 -112
- package/ui/Tree/tree.scss +0 -98
- package/ui/UserAvatar/default_colors.json +0 -82
- package/ui/UserAvatar/index.js +0 -55
- package/ui/View/index.tsx +0 -17
- package/ui/View/index.web.js +0 -44
- package/ui/animations/checkmark.json +0 -1
- package/ui/helpers/SizeContext/index.tsx +0 -11
- package/ui/helpers/helpers.scss +0 -61
- package/ui/helpers/index.ts +0 -6
- package/ui/helpers/stopEventPropagation.js +0 -5
- package/ui/helpers/useActiveListItemIndex/index.tsx +0 -45
- package/ui/helpers/useScrollSelectorIntoView/index.tsx +0 -14
- package/ui/helpers/useThrottledMeasure/index.js +0 -47
- package/ui/helpers/withSuspense/index.js +0 -37
- package/ui/icons/AddAccount.tsx +0 -5
- package/ui/icons/Billing.tsx +0 -6
- package/ui/icons/Close.tsx +0 -14
- package/ui/icons/Organization.tsx +0 -5
- package/ui/icons/Signout.tsx +0 -5
- package/ui/icons/index.tsx +0 -6
- package/ui/nav/AccountsDropdown/SwitchAccounts.tsx +0 -28
- package/ui/nav/AccountsDropdown/accounts-dropdown.scss +0 -51
- package/ui/nav/AccountsDropdown/index.tsx +0 -90
- package/ui/nav/AccountsToggle/index.tsx +0 -24
- package/ui/nav/ContentView/ContentViewContext.ts +0 -23
- package/ui/nav/ContentView/index.tsx +0 -115
- package/ui/nav/HeaderContainer/header.scss +0 -52
- package/ui/nav/HeaderContainer/index.tsx +0 -23
- package/ui/nav/HeaderContainer/variables.scss +0 -1
- package/ui/nav/MorphingDropdown/MorphingDropdownContext.tsx +0 -151
- package/ui/nav/MorphingDropdown/MorphingDropdownMenu.tsx +0 -38
- package/ui/nav/MorphingDropdown/MorphingDropdownPortal.tsx +0 -166
- package/ui/nav/MorphingDropdown/MorphingDropdownToggle.tsx +0 -34
- package/ui/nav/MorphingDropdown/index.tsx +0 -16
- package/ui/nav/MorphingDropdown/morphing-dropdown.scss +0 -35
- package/ui/nav/NotificationsDropdown/index.tsx +0 -52
- package/ui/nav/NotificationsDropdown/notifications-dropdown.scss +0 -5
- package/ui/nav/NotificationsToggle/NotificationsGlyph.tsx +0 -54
- package/ui/nav/NotificationsToggle/index.tsx +0 -12
- package/ui/nav/NotificationsToggle/notification-animation.json +0 -1
- package/ui/nav/NotificationsToggle/notifications-toggle.scss +0 -26
- package/ui/nav/SidebarContainer/index.tsx +0 -48
- package/ui/nav/SidebarContainer/sidebar-container.scss +0 -21
- package/ui/nav/SlideoutContainer/components/Body.tsx +0 -19
- package/ui/nav/SlideoutContainer/components/Header.tsx +0 -23
- package/ui/nav/SlideoutContainer/components/Wrapper.tsx +0 -46
- package/ui/nav/SlideoutContainer/index.tsx +0 -50
- package/ui/nav/SlideoutContainer/slideout-container.scss +0 -40
- package/ui/nav/index.ts +0 -13
- package/ui/oauth/GitHub.js +0 -38
- package/ui/oauth/getGitHubSigninUrl.js +0 -30
- package/ui/oauth/index.js +0 -9
- package/ui/oauth/oauth.scss +0 -16
- package/ui/sortable-hoc/AutoScroller.js +0 -76
- package/ui/sortable-hoc/DragHandle.js +0 -31
- package/ui/sortable-hoc/Manager.js +0 -54
- package/ui/sortable-hoc/README.md +0 -1
- package/ui/sortable-hoc/SortableContainer/defaultGetHelperDimensions.js +0 -7
- package/ui/sortable-hoc/SortableContainer/defaultShouldCancelStart.js +0 -24
- package/ui/sortable-hoc/SortableContainer/index.js +0 -994
- package/ui/sortable-hoc/SortableContainer/props.js +0 -81
- package/ui/sortable-hoc/SortableElement.js +0 -111
- package/ui/sortable-hoc/SortableHandle.js +0 -45
- package/ui/sortable-hoc/drag-handle.scss +0 -14
- package/ui/sortable-hoc/index.js +0 -9
- package/ui/sortable-hoc/utils.js +0 -292
- package/ui/springs.ts +0 -17
package/package.json
CHANGED
|
@@ -1,81 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rpcbase/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.232.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./src/index.ts",
|
|
4
6
|
"scripts": {
|
|
5
|
-
"build": "
|
|
6
|
-
"
|
|
7
|
-
},
|
|
8
|
-
"publishConfig": {
|
|
9
|
-
"registry": "https://registry.npmjs.org/"
|
|
7
|
+
"build": "tsc --watch",
|
|
8
|
+
"release": "wireit"
|
|
10
9
|
},
|
|
11
10
|
"wireit": {
|
|
12
|
-
"install": {
|
|
13
|
-
"command": "NODE_ENV=development yarn install --mutex network --frozen-lockfile",
|
|
14
|
-
"files": [
|
|
15
|
-
"yarn.lock"
|
|
16
|
-
],
|
|
17
|
-
"output": [
|
|
18
|
-
"node_modules/"
|
|
19
|
-
],
|
|
20
|
-
"allowUsuallyExcludedPaths": true
|
|
21
|
-
},
|
|
22
|
-
"build-firebase": {
|
|
23
|
-
"command": "webpack -c firebase/webpack.config.js",
|
|
24
|
-
"dependencies": [
|
|
25
|
-
"install"
|
|
26
|
-
],
|
|
27
|
-
"files": [
|
|
28
|
-
"firebase/entry*.js",
|
|
29
|
-
"firebase/webpack.config.js"
|
|
30
|
-
],
|
|
31
|
-
"output": [
|
|
32
|
-
"firebase/index.js",
|
|
33
|
-
"firebase/sw.js"
|
|
34
|
-
]
|
|
35
|
-
},
|
|
36
|
-
"build": {
|
|
37
|
-
"dependencies": [
|
|
38
|
-
"build-firebase"
|
|
39
|
-
]
|
|
40
|
-
},
|
|
41
|
-
"test": {
|
|
42
|
-
"command": "jest --coverage --coverageDirectory coverage/",
|
|
43
|
-
"dependencies": [
|
|
44
|
-
"build"
|
|
45
|
-
],
|
|
46
|
-
"files": [
|
|
47
|
-
"**/*.js",
|
|
48
|
-
"!coverage/",
|
|
49
|
-
"!node_modules/"
|
|
50
|
-
],
|
|
51
|
-
"output": [
|
|
52
|
-
"coverage/"
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
"apply-version": {
|
|
56
|
-
"command": "node ../../scripts/prflow/apply-prerelease-versions.js $BRANCH_NAME",
|
|
57
|
-
"files": [
|
|
58
|
-
"package.json"
|
|
59
|
-
],
|
|
60
|
-
"output": [],
|
|
61
|
-
"env": {
|
|
62
|
-
"BRANCH_NAME": {
|
|
63
|
-
"external": true
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
11
|
"release": {
|
|
68
|
-
"command": "
|
|
69
|
-
"dependencies": [
|
|
70
|
-
"test",
|
|
71
|
-
"apply-version"
|
|
72
|
-
],
|
|
12
|
+
"command": "../../scripts/publish.js",
|
|
13
|
+
"dependencies": [],
|
|
73
14
|
"files": [
|
|
74
|
-
"package.json"
|
|
75
|
-
|
|
76
|
-
"output": [
|
|
77
|
-
"publish-output.txt"
|
|
15
|
+
"package.json",
|
|
16
|
+
"src/**/*"
|
|
78
17
|
],
|
|
18
|
+
"output": [],
|
|
79
19
|
"env": {
|
|
80
20
|
"NPM_RELEASE_CHANNEL": {
|
|
81
21
|
"external": true
|
|
@@ -83,50 +23,9 @@
|
|
|
83
23
|
}
|
|
84
24
|
}
|
|
85
25
|
},
|
|
26
|
+
"peerDependencies": {},
|
|
86
27
|
"dependencies": {
|
|
87
|
-
"
|
|
88
|
-
"@rpcbase/lottie": "3.5.3",
|
|
89
|
-
"@rpcbase/redbox-react": "0.3.0",
|
|
90
|
-
"@ui-kitten/components": "5.3.1",
|
|
91
|
-
"figma-squircle": "0.3.1",
|
|
92
|
-
"firebase": "11.0.2",
|
|
93
|
-
"framer-motion": "11.11.17",
|
|
94
|
-
"fuzzysort": "3.1.0",
|
|
95
|
-
"i18next": "23.16.4",
|
|
96
|
-
"i18next-chained-backend": "4.6.2",
|
|
97
|
-
"i18next-resources-to-backend": "1.2.1",
|
|
98
|
-
"js-tree": "2.0.2",
|
|
99
|
-
"lz-string": "1.5.0",
|
|
100
|
-
"posthog-js": "1.188.0",
|
|
101
|
-
"pouchdb-adapter-indexeddb": "9.0.0",
|
|
102
|
-
"pouchdb-core": "9.0.0",
|
|
103
|
-
"pouchdb-find": "9.0.0",
|
|
104
|
-
"react-bootstrap-typeahead": "6.3.2",
|
|
105
|
-
"react-i18next": "15.1.0",
|
|
106
|
-
"rrweb": "1.1.3",
|
|
107
|
-
"socket.io-client": "4.8.1",
|
|
108
|
-
"web-vitals": "4.2.4"
|
|
28
|
+
"axios": "1.7.9"
|
|
109
29
|
},
|
|
110
|
-
"devDependencies": {
|
|
111
|
-
"@babel/core": "7.26.0",
|
|
112
|
-
"@babel/plugin-transform-modules-commonjs": "7.25.9",
|
|
113
|
-
"@babel/plugin-transform-runtime": "7.25.9",
|
|
114
|
-
"@babel/preset-react": "7.25.9",
|
|
115
|
-
"@testing-library/dom": "10.4.0",
|
|
116
|
-
"@testing-library/react": "16.0.1",
|
|
117
|
-
"axios": "1.7.7",
|
|
118
|
-
"babel-jest": "29.7.0",
|
|
119
|
-
"bluebird": "3.7.2",
|
|
120
|
-
"jest": "29.7.0",
|
|
121
|
-
"jest-environment-jsdom": "29.7.0",
|
|
122
|
-
"lodash": "4.17.21",
|
|
123
|
-
"page": "1.11.6",
|
|
124
|
-
"react": "19.0.0-rc.1",
|
|
125
|
-
"react-dom": "19.0.0-rc.1",
|
|
126
|
-
"@rpcbase/react-native-web": "0.19.13",
|
|
127
|
-
"react-test-renderer": "19.0.0-rc.1",
|
|
128
|
-
"validator": "13.12.0",
|
|
129
|
-
"webpack": "5.96.1",
|
|
130
|
-
"webpack-cli": "5.1.4"
|
|
131
|
-
}
|
|
30
|
+
"devDependencies": {}
|
|
132
31
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import assert from "assert"
|
|
3
|
+
|
|
4
|
+
import { Application, IRouter, Request, Response } from "express"
|
|
5
|
+
|
|
6
|
+
// import { Ctx } from "@rpcbase/api"
|
|
7
|
+
type Ctx = any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export const getServerApiClient = async(app: Application) => {
|
|
11
|
+
const callRoute = async <TResponse = Record<string, unknown>>(
|
|
12
|
+
app: Application,
|
|
13
|
+
method: string,
|
|
14
|
+
path: string,
|
|
15
|
+
req: Partial<Request>,
|
|
16
|
+
res: Partial<Response>
|
|
17
|
+
): Promise<TResponse> => {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
let isEnded = false
|
|
20
|
+
|
|
21
|
+
const mockReq = {
|
|
22
|
+
...req,
|
|
23
|
+
method: method.toUpperCase(),
|
|
24
|
+
url: path
|
|
25
|
+
} as Request
|
|
26
|
+
|
|
27
|
+
const mockRes = {
|
|
28
|
+
...res,
|
|
29
|
+
json: (data: any) => {
|
|
30
|
+
if (!isEnded) {
|
|
31
|
+
isEnded = true
|
|
32
|
+
resolve(data)
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
status: (statusCode: number) => {
|
|
36
|
+
console.log("Status:", statusCode)
|
|
37
|
+
return mockRes
|
|
38
|
+
},
|
|
39
|
+
} as Response
|
|
40
|
+
|
|
41
|
+
const routerStack: any[] = (app.router as unknown as IRouter).stack
|
|
42
|
+
|
|
43
|
+
const firstApiMiddlewareIndex = routerStack.findIndex((layer) => layer.name === "__FIRST_API_MIDDLEWARE__")
|
|
44
|
+
if (!(firstApiMiddlewareIndex > -1)) {
|
|
45
|
+
throw new Error("middleware: __FIRST_API_MIDDLEWARE__ was not found in stack")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const apiStack = routerStack.slice(firstApiMiddlewareIndex + 1)
|
|
49
|
+
|
|
50
|
+
const processLayer = async (index: number) => {
|
|
51
|
+
if (index >= apiStack.length || isEnded) return
|
|
52
|
+
|
|
53
|
+
const layer = apiStack[index]
|
|
54
|
+
|
|
55
|
+
const isNonMatchingLayer = !layer.match(path)
|
|
56
|
+
if (isNonMatchingLayer) {
|
|
57
|
+
// console.log("not machthing route:", path, "to layer:", index, layer.name, layer, "reason: ", {isNonMatchingLayer})
|
|
58
|
+
await processLayer(index + 1)
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const runHandler = async(handler: any) => new Promise<void>((resolveMiddleware, rejectMiddleware) => {
|
|
63
|
+
handler(mockReq, mockRes, (err?: any) => {
|
|
64
|
+
if (err) {
|
|
65
|
+
console.error("Middleware error:", err)
|
|
66
|
+
if (!isEnded) {
|
|
67
|
+
isEnded = true
|
|
68
|
+
rejectMiddleware(err)
|
|
69
|
+
}
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
resolveMiddleware()
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
if (layer.route) {
|
|
77
|
+
if (!layer.route.methods[method.toLowerCase()]) {
|
|
78
|
+
// console.log("not machthing route:", path, "to route layer:", index, layer.name, layer, "reason: method not matching")
|
|
79
|
+
await processLayer(index + 1)
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
assert(layer.route.stack.length === 1, `expected only one handler per route for route: ${layer.route.path}`)
|
|
84
|
+
|
|
85
|
+
await runHandler(layer.route.stack[0].handle)
|
|
86
|
+
|
|
87
|
+
} else {
|
|
88
|
+
await runHandler(layer.handle)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!isEnded) {
|
|
92
|
+
await processLayer(index + 1)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// AWAIT ??
|
|
97
|
+
processLayer(0)
|
|
98
|
+
|
|
99
|
+
// Set a timeout to prevent hanging
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
if (!isEnded) {
|
|
102
|
+
reject("Route handler timed out")
|
|
103
|
+
}
|
|
104
|
+
}, 30000)
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const createMethod = (method: string) => {
|
|
109
|
+
return async <TResponse = Record<string, unknown>>(
|
|
110
|
+
path: string,
|
|
111
|
+
payload: Record<string, unknown>,
|
|
112
|
+
ctx?: Ctx,
|
|
113
|
+
): Promise<TResponse> => {
|
|
114
|
+
assert(ctx, "Context must be provided in SSR mode")
|
|
115
|
+
|
|
116
|
+
ctx.req.body = payload
|
|
117
|
+
return callRoute<TResponse>(app, method, path, ctx.req, ctx.res)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const apiClient = {
|
|
122
|
+
get: createMethod("get"),
|
|
123
|
+
post: createMethod("post"),
|
|
124
|
+
put: createMethod("put"),
|
|
125
|
+
delete: createMethod("delete")
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return apiClient
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export default getServerApiClient
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import assert from "assert"
|
|
2
|
+
|
|
3
|
+
import type { Application } from "express"
|
|
4
|
+
|
|
5
|
+
// import { Ctx } from "@rpcbase/api"
|
|
6
|
+
type Ctx = any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
type ServerArgs = {
|
|
10
|
+
app: Application;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type PayloadNotCtx = Record<string, unknown> & {
|
|
14
|
+
[P in keyof Ctx]?: never;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type ApiClientMethod = <TResponse = Record<string, unknown>>(
|
|
18
|
+
path: string,
|
|
19
|
+
payload: PayloadNotCtx,
|
|
20
|
+
ctx?: Ctx,
|
|
21
|
+
) => Promise<TResponse>;
|
|
22
|
+
|
|
23
|
+
export type HttpMethod = "get" | "put" | "post" | "delete";
|
|
24
|
+
type MethodRecord<T> = Record<HttpMethod, T>;
|
|
25
|
+
|
|
26
|
+
export type ApiClient = MethodRecord<ApiClientMethod>;
|
|
27
|
+
|
|
28
|
+
let apiClient: ApiClient
|
|
29
|
+
|
|
30
|
+
export const initApiClient = async (args?: ServerArgs) => {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
if (import.meta.env.SSR) {
|
|
33
|
+
assert(args, "Server args must be provided in SSR mode")
|
|
34
|
+
|
|
35
|
+
const { getServerApiClient } = await import("./getServerApiClient")
|
|
36
|
+
|
|
37
|
+
apiClient = await getServerApiClient(args.app)
|
|
38
|
+
} else {
|
|
39
|
+
const axios = (await import("axios")).default
|
|
40
|
+
|
|
41
|
+
const axiosClient = axios.create({
|
|
42
|
+
baseURL: "/",
|
|
43
|
+
withCredentials: true,
|
|
44
|
+
headers: {
|
|
45
|
+
"Content-Type": "application/json",
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const createMethod = (method: string): ApiClientMethod => {
|
|
50
|
+
return async <TResponse = Record<string, unknown>>(
|
|
51
|
+
path: string,
|
|
52
|
+
payload: PayloadNotCtx,
|
|
53
|
+
_ctx?: Ctx,
|
|
54
|
+
): Promise<TResponse> => {
|
|
55
|
+
const config = {
|
|
56
|
+
method,
|
|
57
|
+
url: path,
|
|
58
|
+
data: payload,
|
|
59
|
+
headers: {
|
|
60
|
+
// ...(typeof ctxOrPath !== 'string' && {
|
|
61
|
+
// // 'X-Custom-Header': ctxOrPath.someHeaderValue,
|
|
62
|
+
// // ...ctxOrPath.additionalHeaders,
|
|
63
|
+
// }),
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const response = await axiosClient(config)
|
|
69
|
+
return response.data
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.log("AXIOS API ERROR", error)
|
|
72
|
+
throw error
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
apiClient = {
|
|
78
|
+
get: createMethod("get"),
|
|
79
|
+
put: createMethod("put"),
|
|
80
|
+
post: createMethod("post"),
|
|
81
|
+
delete: createMethod("delete"),
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { apiClient }
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { initApiClient } from "./apiClient"
|
|
2
|
+
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
+
const showErrorOverlay = (err: { title: string, message: string, reason: string, plugin: string }) => {
|
|
5
|
+
const ErrorOverlay = customElements.get("vite-error-overlay")
|
|
6
|
+
// don't open outside vite environment
|
|
7
|
+
if (!ErrorOverlay) {return}
|
|
8
|
+
console.log(err)
|
|
9
|
+
const overlay = new ErrorOverlay(err)
|
|
10
|
+
document.body.appendChild(overlay)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const handleServerErrors = () => {
|
|
15
|
+
if ((window as any).__staticRouterHydrationData?.errors) {
|
|
16
|
+
|
|
17
|
+
const {errors} = (window as any).__staticRouterHydrationData
|
|
18
|
+
|
|
19
|
+
Object.values(errors).forEach((error: any) => {
|
|
20
|
+
showErrorOverlay({
|
|
21
|
+
plugin: "ssr-router",
|
|
22
|
+
...error.reason
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const initClient = () => {
|
|
29
|
+
initApiClient()
|
|
30
|
+
|
|
31
|
+
handleServerErrors()
|
|
32
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Ctx } from "@rpcbase/api";
|
|
2
|
+
import { Params } from "@rpcbase/router"
|
|
3
|
+
|
|
4
|
+
export type LoaderArgs = {params: Params, ctx: Ctx}
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
export type Loader = ({params, ctx}: LoaderArgs) => Promise<any>
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
import {useEffect} from "react"
|
|
3
|
-
import {usePostHog} from "posthog-js/react"
|
|
4
|
-
import FingerprintJS from "@fingerprintjs/fingerprintjs"
|
|
5
|
-
|
|
6
|
-
import getUid from "../auth/getUid"
|
|
7
|
-
|
|
8
|
-
// TMP: RB_TENANT_ID must come from the server, not be set in env here
|
|
9
|
-
import {RB_TENANT_ID, POSTHOG_KEY} from "env"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const AnalyticsContainer = ({children}) => {
|
|
13
|
-
const {hostname} = window.location
|
|
14
|
-
if (__DEV__ || hostname === "localhost" || hostname.endsWith(".local")) return null
|
|
15
|
-
if (!POSTHOG_KEY) return null
|
|
16
|
-
|
|
17
|
-
const posthog = usePostHog()
|
|
18
|
-
|
|
19
|
-
const uid = getUid()
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
if (!posthog) return
|
|
23
|
-
|
|
24
|
-
if (uid) {
|
|
25
|
-
posthog.identify(uid, {
|
|
26
|
-
uid,
|
|
27
|
-
env: __DEV__ ? "dev" : "prod",
|
|
28
|
-
})
|
|
29
|
-
posthog.group("customer", RB_TENANT_ID, {
|
|
30
|
-
name: "default",
|
|
31
|
-
})
|
|
32
|
-
posthog.group("env", __DEV__ ? "dev" : "prod")
|
|
33
|
-
}
|
|
34
|
-
// user isn't identified, use fingerprint instead
|
|
35
|
-
else {
|
|
36
|
-
const run = async() => {
|
|
37
|
-
const fp = await FingerprintJS.load()
|
|
38
|
-
const fpResult = await fp.get()
|
|
39
|
-
|
|
40
|
-
posthog.identify(fpResult.visitorId, {
|
|
41
|
-
type: "fingerprint",
|
|
42
|
-
env: __DEV__ ? "dev" : "prod",
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
run()
|
|
47
|
-
}
|
|
48
|
-
}, [posthog, uid])
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<>{children}</>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export default AnalyticsContainer
|
package/AppProvider/debug.js
DELETED
package/AppProvider/index.tsx
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import "./debug"
|
|
2
|
-
import {useEffect} from "react"
|
|
3
|
-
import {PostHogProvider} from "posthog-js/react"
|
|
4
|
-
|
|
5
|
-
import page from "../page"
|
|
6
|
-
import {HashStateProvider} from "../hashState"
|
|
7
|
-
|
|
8
|
-
import AnalyticsContainer from "./AnalyticsContainer"
|
|
9
|
-
|
|
10
|
-
// TODO: flags here should be optional
|
|
11
|
-
import {flagValues} from "config/flags"
|
|
12
|
-
|
|
13
|
-
import {POSTHOG_KEY} from "env"
|
|
14
|
-
import {useAuthRouter} from "../auth/useAuthRouter"
|
|
15
|
-
import getTenantId from "../auth/getTenantId"
|
|
16
|
-
import getUid from "../auth/getUid"
|
|
17
|
-
import {NotificationsProvider, NotificationsContainer} from "../notifications"
|
|
18
|
-
import {connect as rts_connect} from "../rts/rts"
|
|
19
|
-
|
|
20
|
-
// initial rts connect
|
|
21
|
-
const tenantId = getTenantId()
|
|
22
|
-
rts_connect(tenantId, getUid())
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const PostHogWrapper = ({children, ...props}) => {
|
|
26
|
-
|
|
27
|
-
const {hostname} = window.location
|
|
28
|
-
|
|
29
|
-
const hasPostHogKey = !!POSTHOG_KEY
|
|
30
|
-
|
|
31
|
-
if (__DEV__ || hostname === "localhost" || hostname.endsWith(".local") || !hasPostHogKey) {
|
|
32
|
-
return (
|
|
33
|
-
<>{children}</>
|
|
34
|
-
)
|
|
35
|
-
} else {
|
|
36
|
-
return (
|
|
37
|
-
<PostHogProvider
|
|
38
|
-
apiKey={POSTHOG_KEY}
|
|
39
|
-
options={{
|
|
40
|
-
api_host: "https://eu.posthog.com",
|
|
41
|
-
// TODO: this doesn't work
|
|
42
|
-
bootstrap: {
|
|
43
|
-
featureFlags: flagValues,
|
|
44
|
-
},
|
|
45
|
-
}}
|
|
46
|
-
>
|
|
47
|
-
<AnalyticsContainer>
|
|
48
|
-
{children}
|
|
49
|
-
</AnalyticsContainer>
|
|
50
|
-
</PostHogProvider>
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const AppProvider = ({children, ...props}) => {
|
|
56
|
-
|
|
57
|
-
const {authComponent} = useAuthRouter()
|
|
58
|
-
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
page.start()
|
|
61
|
-
}, [])
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<PostHogWrapper>
|
|
65
|
-
<HashStateProvider>
|
|
66
|
-
<NotificationsProvider>
|
|
67
|
-
<div className={cx({"d-none": !!authComponent})}>
|
|
68
|
-
{children}
|
|
69
|
-
</div>
|
|
70
|
-
{authComponent}
|
|
71
|
-
<NotificationsContainer />
|
|
72
|
-
</NotificationsProvider>
|
|
73
|
-
</HashStateProvider>
|
|
74
|
-
</PostHogWrapper>
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default AppProvider
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import _get from "lodash/get"
|
|
2
|
-
import {useState} from "react"
|
|
3
|
-
import ToggleButton from "react-bootstrap/ToggleButton"
|
|
4
|
-
import ToggleButtonGroup from "react-bootstrap/ToggleButtonGroup"
|
|
5
|
-
|
|
6
|
-
import {useFormContext} from "react-hook-form"
|
|
7
|
-
|
|
8
|
-
import {GRANTS_FIELD} from "../constants"
|
|
9
|
-
import {CheckMark} from "./icons/CheckMark"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const OPS = {
|
|
13
|
-
create: "Create",
|
|
14
|
-
read: "Read",
|
|
15
|
-
update: "Update",
|
|
16
|
-
delete: "Delete",
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const OpSelector = ({field, index, update}) => {
|
|
20
|
-
const PREFIX = `select-op-field-${field.id}`
|
|
21
|
-
|
|
22
|
-
const {
|
|
23
|
-
formState: {errors},
|
|
24
|
-
setValue,
|
|
25
|
-
} = useFormContext()
|
|
26
|
-
|
|
27
|
-
const fieldKey = `${GRANTS_FIELD}.${index}.ops`
|
|
28
|
-
const err = _get(errors, fieldKey, null)
|
|
29
|
-
|
|
30
|
-
const [ops, setOps] = useState(field.ops || {})
|
|
31
|
-
|
|
32
|
-
const updateOps = (nextOps) => {
|
|
33
|
-
setOps(nextOps)
|
|
34
|
-
setValue(fieldKey, nextOps, {
|
|
35
|
-
shouldTouch: true,
|
|
36
|
-
shouldValidate: !!err, // revalidate if there is an error
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const handleChange = (selected) => {
|
|
41
|
-
const nextOps = {...ops}
|
|
42
|
-
// remove unselected keys from ops
|
|
43
|
-
Object.keys(nextOps).forEach((k) => !selected.includes[k] && delete nextOps[k])
|
|
44
|
-
// add new selected keys
|
|
45
|
-
selected.forEach((s) => (nextOps[s] = "own"))
|
|
46
|
-
updateOps(nextOps)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const getCRUDOps = () => Object.keys(ops)
|
|
50
|
-
|
|
51
|
-
const getOpScope = (k) => ops[k]
|
|
52
|
-
|
|
53
|
-
const updateOpScope = (k, selected) => {
|
|
54
|
-
const nextOps = {...ops}
|
|
55
|
-
nextOps[k] = selected
|
|
56
|
-
updateOps(nextOps)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const getCaption = () => {
|
|
60
|
-
if (err) {
|
|
61
|
-
return <p className="text-danger pt-1">{err.message}</p>
|
|
62
|
-
} else {
|
|
63
|
-
// iterate on OPS first, not ops to preserve semantic order
|
|
64
|
-
const targetOps = Object.keys(OPS).filter((k) => Object.keys(ops).includes(k))
|
|
65
|
-
let captionStr
|
|
66
|
-
if (targetOps.length === 0) {
|
|
67
|
-
captionStr = "Select operations above"
|
|
68
|
-
} else captionStr = `Allow ${targetOps.map((k) => `${OPS[k]}:${ops[k]}`).join(", ")}`
|
|
69
|
-
return <p className="text-secondary mt-1">{captionStr}</p>
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return (
|
|
74
|
-
<div className="op-selector">
|
|
75
|
-
<div className="mb-1 fw-bold">Grant Operation:</div>
|
|
76
|
-
<ToggleButtonGroup
|
|
77
|
-
type="checkbox"
|
|
78
|
-
// TODO: support vertical layout when the modal isn't wide enough
|
|
79
|
-
// vertical
|
|
80
|
-
className={cx("w-100", {"border": !!err, "border-danger": !!err})}
|
|
81
|
-
value={getCRUDOps()}
|
|
82
|
-
onChange={handleChange}
|
|
83
|
-
>
|
|
84
|
-
{Object.keys(OPS).map((k) => (
|
|
85
|
-
<ToggleButton
|
|
86
|
-
variant="light"
|
|
87
|
-
key={`${PREFIX}-${index}-${k}`}
|
|
88
|
-
id={`${PREFIX}-${index}-${k}`}
|
|
89
|
-
value={k}
|
|
90
|
-
className="toggle-button-op py-1"
|
|
91
|
-
>
|
|
92
|
-
<>
|
|
93
|
-
<div className="">
|
|
94
|
-
<CheckMark hide={!getCRUDOps().includes(k)} />
|
|
95
|
-
{OPS[k]}
|
|
96
|
-
</div>
|
|
97
|
-
<ToggleButtonGroup
|
|
98
|
-
className="pt-1"
|
|
99
|
-
type="radio"
|
|
100
|
-
name={`${k}_op_scope`}
|
|
101
|
-
value={getOpScope(k)}
|
|
102
|
-
onChange={(selected) => updateOpScope(k, selected)}
|
|
103
|
-
>
|
|
104
|
-
<ToggleButton
|
|
105
|
-
variant="primary"
|
|
106
|
-
id={`${PREFIX}-${index}-${k}-own`}
|
|
107
|
-
value={"own"}
|
|
108
|
-
className="toggle-button-op py-1 text-monospace"
|
|
109
|
-
>
|
|
110
|
-
own
|
|
111
|
-
</ToggleButton>
|
|
112
|
-
<ToggleButton
|
|
113
|
-
variant="primary"
|
|
114
|
-
id={`${PREFIX}-${index}-${k}-any`}
|
|
115
|
-
value={"any"}
|
|
116
|
-
className="toggle-button-op py-1 text-monospace"
|
|
117
|
-
>
|
|
118
|
-
any
|
|
119
|
-
</ToggleButton>
|
|
120
|
-
</ToggleButtonGroup>
|
|
121
|
-
</>
|
|
122
|
-
</ToggleButton>
|
|
123
|
-
))}
|
|
124
|
-
</ToggleButtonGroup>
|
|
125
|
-
|
|
126
|
-
{getCaption()}
|
|
127
|
-
</div>
|
|
128
|
-
)
|
|
129
|
-
}
|