@rpcbase/client 0.227.0 → 0.231.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 (237) hide show
  1. package/package.json +11 -113
  2. package/src/apiClient/getServerApiClient.ts +131 -0
  3. package/src/apiClient/index.ts +86 -0
  4. package/src/index.ts +3 -0
  5. package/src/initClient.ts +32 -0
  6. package/src/types.ts +7 -0
  7. package/AppProvider/AnalyticsContainer.js +0 -56
  8. package/AppProvider/debug.js +0 -4
  9. package/AppProvider/index.tsx +0 -79
  10. package/access-control/ACLForm/components/GrantField/OpSelector.tsx +0 -129
  11. package/access-control/ACLForm/components/GrantField/ResourceSelector.tsx +0 -86
  12. package/access-control/ACLForm/components/GrantField/UsersSelector.tsx +0 -96
  13. package/access-control/ACLForm/components/GrantField/grant-field.scss +0 -26
  14. package/access-control/ACLForm/components/GrantField/icons/CheckMark.tsx +0 -16
  15. package/access-control/ACLForm/components/GrantField/icons/CollapseArrow.tsx +0 -14
  16. package/access-control/ACLForm/components/GrantField/icons/ExpandArrow.tsx +0 -14
  17. package/access-control/ACLForm/components/GrantField/index.tsx +0 -91
  18. package/access-control/ACLForm/components/GrantsList.tsx +0 -48
  19. package/access-control/ACLForm/components/RoleForm.tsx +0 -134
  20. package/access-control/ACLForm/components/RoleView.tsx +0 -115
  21. package/access-control/ACLForm/components/RolesList.tsx +0 -79
  22. package/access-control/ACLForm/components/constants.tsx +0 -1
  23. package/access-control/ACLForm/components/resolver.ts +0 -57
  24. package/access-control/ACLForm/components/role-form.scss +0 -19
  25. package/access-control/ACLForm/index.tsx +0 -48
  26. package/access-control/ACLModal/acl-modal.scss +0 -7
  27. package/access-control/ACLModal/index.tsx +0 -66
  28. package/access-control/PolicyEditor/TargetSelector/QueryBuilder.tsx +0 -48
  29. package/access-control/PolicyEditor/TargetSelector/index.tsx +0 -5
  30. package/access-control/PolicyEditor/TargetSelector/query-builder.scss +0 -9
  31. package/access-control/PolicyEditor/index.tsx +0 -165
  32. package/access-control/index.ts +0 -3
  33. package/apiClient.js +0 -15
  34. package/auth/authProps.js +0 -8
  35. package/auth/components/AccountsList/AccountListItem.js +0 -61
  36. package/auth/components/AccountsList/account-list-item.scss +0 -5
  37. package/auth/components/AccountsList/index.js +0 -17
  38. package/auth/components/Footer/index.js +0 -11
  39. package/auth/components/ForgotPassword/forgot-password.scss +0 -37
  40. package/auth/components/ForgotPassword/index.js +0 -114
  41. package/auth/components/SetNewPassword/index.js +0 -130
  42. package/auth/components/SetNewPassword/set-new-password.scss +0 -47
  43. package/auth/components/SignIn/SignInEmailForm.tsx +0 -115
  44. package/auth/components/SignIn/index.js +0 -69
  45. package/auth/components/SignIn/sign-in.scss +0 -56
  46. package/auth/components/SignOut/index.js +0 -144
  47. package/auth/components/SignOut/sign-out.scss +0 -34
  48. package/auth/components/SignUp/SignUpEmailForm.tsx +0 -98
  49. package/auth/components/SignUp/index.js +0 -66
  50. package/auth/components/SignUp/sign-up.scss +0 -56
  51. package/auth/getTenantId.js +0 -12
  52. package/auth/getUid.js +0 -11
  53. package/auth/helpers/redirectSignIn.native.js +0 -9
  54. package/auth/helpers/redirectSignIn.web.js +0 -7
  55. package/auth/index.js +0 -146
  56. package/auth/signOut.js +0 -20
  57. package/auth/useAuthRouter.js +0 -56
  58. package/env.d.ts +0 -3
  59. package/firebase/index.js +0 -1
  60. package/firebase/sw.js +0 -1
  61. package/form/FileInput/FileUploadContext.tsx +0 -162
  62. package/form/FileInput/FileUploadForm/index.tsx +0 -139
  63. package/form/FileInput/FileUploadForm/usePreventUnload.js +0 -21
  64. package/form/FileInput/UploadButton.tsx +0 -23
  65. package/form/FileInput/constants.ts +0 -16
  66. package/form/FileInput/file-input.scss +0 -1
  67. package/form/FileInput/index.tsx +0 -21
  68. package/form/FileInput/upload-worker/get_file_hash.js +0 -63
  69. package/form/FileInput/upload-worker/index.js +0 -16
  70. package/form/FileInput/upload-worker/no_compress_exts.ts +0 -33
  71. package/form/FileInput/upload-worker/upload_file.js +0 -129
  72. package/form/Form.tsx +0 -23
  73. package/form/Input.tsx +0 -62
  74. package/form/SubmitButton/index.tsx +0 -58
  75. package/form/hook-form.tsx +0 -7
  76. package/form/index.tsx +0 -5
  77. package/getBaseUrl.js +0 -14
  78. package/getObjectId.ts +0 -31
  79. package/hashState.js +0 -158
  80. package/helpers/createBatcher/index.js +0 -36
  81. package/helpers/getInitials.js +0 -39
  82. package/helpers/onReady.js +0 -15
  83. package/helpers/post.js +0 -18
  84. package/helpers/postRPC.js +0 -42
  85. package/helpers/useRPC.js +0 -41
  86. package/helpers/useStoredValue/batchedGetStoredValues.js +0 -30
  87. package/helpers/useStoredValue/index.js +0 -107
  88. package/helpers/useStoredValue/setStoredValues.js +0 -14
  89. package/i18n/en/rb.nav.json +0 -13
  90. package/i18n/en/rb.sign_in.json +0 -11
  91. package/i18n/en/rb.sign_out.json +0 -5
  92. package/i18n/fr/rb.sign_in.json +0 -11
  93. package/i18n/fr/rb.sign_out.json +0 -5
  94. package/i18n/index.js +0 -63
  95. package/index.js +0 -6
  96. package/isEqualValues.js +0 -47
  97. package/jest.config.js +0 -16
  98. package/notifications/Notification/index.js +0 -36
  99. package/notifications/Notification/notification.scss +0 -1
  100. package/notifications/NotificationItem/HeaderStatus.js +0 -93
  101. package/notifications/NotificationItem/index.js +0 -65
  102. package/notifications/NotificationItem/notification-item.scss +0 -25
  103. package/notifications/NotificationsContainer/index.js +0 -37
  104. package/notifications/NotificationsContainer/notifications-container.scss +0 -38
  105. package/notifications/NotificationsContainer/useLLTs.js +0 -28
  106. package/notifications/NotificationsContext/index.js +0 -71
  107. package/notifications/NotificationsContext/useNotificationsList.js +0 -75
  108. package/notifications/NotificationsSettingsModal/SettingsForm.js +0 -52
  109. package/notifications/NotificationsSettingsModal/index.js +0 -48
  110. package/notifications/NotificationsSettingsModal/notifications-settings.scss +0 -1
  111. package/notifications/config.js +0 -1
  112. package/notifications/index.js +0 -4
  113. package/page.js +0 -9
  114. package/publish-output.txt +0 -0
  115. package/rpc.js +0 -32
  116. package/rr-trace/get_fingerprint.js +0 -10
  117. package/rr-trace/get_perf_vitals.js +0 -24
  118. package/rr-trace/get_session_id.js +0 -29
  119. package/rr-trace/index.js +0 -138
  120. package/rr-trace/write_session_data.js +0 -86
  121. package/rts/boot.js +0 -3
  122. package/rts/getUseDocument.js +0 -21
  123. package/rts/getUseQuery/index.js +0 -233
  124. package/rts/getUseQuery/useData.js +0 -55
  125. package/rts/index.js +0 -10
  126. package/rts/rts.js +0 -243
  127. package/rts/signout.ts +0 -8
  128. package/rts/store/constants.js +0 -3
  129. package/rts/store/debug.js +0 -24
  130. package/rts/store/get_collection.js +0 -55
  131. package/rts/store/index.js +0 -100
  132. package/rts/store/replace_query_keys.js +0 -30
  133. package/rts/store/satisfies_projection.js +0 -32
  134. package/rts/store/update_docs.js +0 -47
  135. package/storage/index.jest.js +0 -15
  136. package/storage/index.native.js +0 -38
  137. package/storage/index.web.js +0 -25
  138. package/types.ts +0 -6
  139. package/ui/ActivityIndicator/index.js +0 -113
  140. package/ui/Avatar/index.native.js +0 -31
  141. package/ui/Avatar/index.web.js +0 -37
  142. package/ui/Avatar/styles.js +0 -41
  143. package/ui/ErrorBoundary/index.js +0 -12
  144. package/ui/ExpandableFloatView/exp.scss +0 -15
  145. package/ui/ExpandableFloatView/index.tsx +0 -123
  146. package/ui/ExpandableFloatView/useBackdrop.js +0 -45
  147. package/ui/LottiePlayer/LottiePlayer.js +0 -4
  148. package/ui/LottiePlayer/index.js +0 -8
  149. package/ui/Modal/HashStateModal.js +0 -30
  150. package/ui/Modal/Modal.js +0 -93
  151. package/ui/Modal/ModalForm/AlertBanner.js +0 -82
  152. package/ui/Modal/ModalForm/index.js +0 -188
  153. package/ui/Modal/ModalForm/modal-form.scss +0 -63
  154. package/ui/Modal/index.js +0 -10
  155. package/ui/Modal/modal.scss +0 -101
  156. package/ui/Modal/withHashStateModal.js +0 -24
  157. package/ui/RedboxError/index.js +0 -3
  158. package/ui/Search/SearchHistory/index.js +0 -45
  159. package/ui/Search/SearchHistory/search-history.scss +0 -9
  160. package/ui/Search/SearchHistory/useSearchHistory.tsx +0 -57
  161. package/ui/Search/SearchResults/index.tsx +0 -90
  162. package/ui/Search/index.tsx +0 -298
  163. package/ui/Search/search.scss +0 -0
  164. package/ui/SelectPills/index.tsx +0 -96
  165. package/ui/SelectPills/select-pills.scss +0 -66
  166. package/ui/Tabs/index.tsx +0 -161
  167. package/ui/Tabs/tabs.scss +0 -53
  168. package/ui/Tree/index.js +0 -257
  169. package/ui/Tree/model.js +0 -71
  170. package/ui/Tree/node.js +0 -112
  171. package/ui/Tree/tree.scss +0 -98
  172. package/ui/UserAvatar/default_colors.json +0 -82
  173. package/ui/UserAvatar/index.js +0 -55
  174. package/ui/View/index.tsx +0 -17
  175. package/ui/View/index.web.js +0 -44
  176. package/ui/animations/checkmark.json +0 -1
  177. package/ui/helpers/SizeContext/index.tsx +0 -11
  178. package/ui/helpers/helpers.scss +0 -61
  179. package/ui/helpers/index.ts +0 -6
  180. package/ui/helpers/stopEventPropagation.js +0 -5
  181. package/ui/helpers/useActiveListItemIndex/index.tsx +0 -45
  182. package/ui/helpers/useScrollSelectorIntoView/index.tsx +0 -14
  183. package/ui/helpers/useThrottledMeasure/index.js +0 -47
  184. package/ui/helpers/withSuspense/index.js +0 -37
  185. package/ui/icons/AddAccount.tsx +0 -5
  186. package/ui/icons/Billing.tsx +0 -6
  187. package/ui/icons/Close.tsx +0 -14
  188. package/ui/icons/Organization.tsx +0 -5
  189. package/ui/icons/Signout.tsx +0 -5
  190. package/ui/icons/index.tsx +0 -6
  191. package/ui/nav/AccountsDropdown/SwitchAccounts.tsx +0 -28
  192. package/ui/nav/AccountsDropdown/accounts-dropdown.scss +0 -51
  193. package/ui/nav/AccountsDropdown/index.tsx +0 -90
  194. package/ui/nav/AccountsToggle/index.tsx +0 -24
  195. package/ui/nav/ContentView/ContentViewContext.ts +0 -23
  196. package/ui/nav/ContentView/index.tsx +0 -115
  197. package/ui/nav/HeaderContainer/header.scss +0 -52
  198. package/ui/nav/HeaderContainer/index.tsx +0 -23
  199. package/ui/nav/HeaderContainer/variables.scss +0 -1
  200. package/ui/nav/MorphingDropdown/MorphingDropdownContext.tsx +0 -151
  201. package/ui/nav/MorphingDropdown/MorphingDropdownMenu.tsx +0 -38
  202. package/ui/nav/MorphingDropdown/MorphingDropdownPortal.tsx +0 -166
  203. package/ui/nav/MorphingDropdown/MorphingDropdownToggle.tsx +0 -34
  204. package/ui/nav/MorphingDropdown/index.tsx +0 -16
  205. package/ui/nav/MorphingDropdown/morphing-dropdown.scss +0 -35
  206. package/ui/nav/NotificationsDropdown/index.tsx +0 -52
  207. package/ui/nav/NotificationsDropdown/notifications-dropdown.scss +0 -5
  208. package/ui/nav/NotificationsToggle/NotificationsGlyph.tsx +0 -54
  209. package/ui/nav/NotificationsToggle/index.tsx +0 -12
  210. package/ui/nav/NotificationsToggle/notification-animation.json +0 -1
  211. package/ui/nav/NotificationsToggle/notifications-toggle.scss +0 -26
  212. package/ui/nav/SidebarContainer/index.tsx +0 -48
  213. package/ui/nav/SidebarContainer/sidebar-container.scss +0 -21
  214. package/ui/nav/SlideoutContainer/components/Body.tsx +0 -19
  215. package/ui/nav/SlideoutContainer/components/Header.tsx +0 -23
  216. package/ui/nav/SlideoutContainer/components/Wrapper.tsx +0 -46
  217. package/ui/nav/SlideoutContainer/index.tsx +0 -50
  218. package/ui/nav/SlideoutContainer/slideout-container.scss +0 -40
  219. package/ui/nav/index.ts +0 -13
  220. package/ui/oauth/GitHub.js +0 -38
  221. package/ui/oauth/getGitHubSigninUrl.js +0 -30
  222. package/ui/oauth/index.js +0 -9
  223. package/ui/oauth/oauth.scss +0 -16
  224. package/ui/sortable-hoc/AutoScroller.js +0 -76
  225. package/ui/sortable-hoc/DragHandle.js +0 -31
  226. package/ui/sortable-hoc/Manager.js +0 -54
  227. package/ui/sortable-hoc/README.md +0 -1
  228. package/ui/sortable-hoc/SortableContainer/defaultGetHelperDimensions.js +0 -7
  229. package/ui/sortable-hoc/SortableContainer/defaultShouldCancelStart.js +0 -24
  230. package/ui/sortable-hoc/SortableContainer/index.js +0 -994
  231. package/ui/sortable-hoc/SortableContainer/props.js +0 -81
  232. package/ui/sortable-hoc/SortableElement.js +0 -111
  233. package/ui/sortable-hoc/SortableHandle.js +0 -45
  234. package/ui/sortable-hoc/drag-handle.scss +0 -14
  235. package/ui/sortable-hoc/index.js +0 -9
  236. package/ui/sortable-hoc/utils.js +0 -292
  237. package/ui/springs.ts +0 -17
@@ -1,129 +0,0 @@
1
- /* @flow */
2
- import assert from "assert"
3
- // import debug from "debug"
4
- import brotliPromise from "brotli-wasm"
5
-
6
- import getBaseUrl from "../../../getBaseUrl"
7
-
8
- import {NO_COMPRESS_EXTS} from "./no_compress_exts"
9
- import {UPLOAD_CHUNK_SIZE, EVENTS} from "../constants"
10
-
11
- // const log = debug("rb:upload_worker")
12
- const log = (...args) => console.log(...args)
13
-
14
- let _brotli
15
-
16
-
17
- const check_should_compress = (file) => {
18
- for (const ext of NO_COMPRESS_EXTS) {
19
- if (file.name.endsWith(ext)) return false
20
- }
21
- return true
22
- }
23
-
24
- const upload_file = async(file, hash) => {
25
- assert(file, "upload_file has no file")
26
-
27
- const should_compress = check_should_compress(file)
28
- log("filename:", file.name, "should_compress:", should_compress)
29
-
30
- if (should_compress && !_brotli) {
31
- _brotli = await brotliPromise
32
- }
33
-
34
- const reader = new FileReader()
35
- const size = file.size
36
-
37
- log("total file size", file.size)
38
-
39
- const total_chunks = Math.ceil(size / UPLOAD_CHUNK_SIZE)
40
-
41
- let current_chunks_count = 0
42
-
43
- let offset = 0
44
- let total_bytes_read = 0
45
-
46
- reader.onloadend = async(e) => {
47
- if (e.target.readyState === FileReader.DONE) {
48
- const chunk_index = current_chunks_count
49
-
50
- // how many bytes did we just read
51
- const read_chunk_length = e.target.result.byteLength
52
-
53
- const chunk = should_compress
54
- ? _brotli.compress(new Uint8Array(e.target.result))
55
- : e.target.result
56
-
57
- log("will upload chunk of size:", chunk.size)
58
-
59
- const data = new FormData()
60
-
61
- data.append("file_chunk", new Blob([chunk]))
62
- data.append("is_compressed", should_compress ? "yes" : "no")
63
- data.append("chunk_index", chunk_index)
64
- data.append("total_chunks", total_chunks)
65
- data.append("chunk_size", UPLOAD_CHUNK_SIZE)
66
- data.append("original_filename", file.name)
67
- data.append("mime_type", file.type)
68
- data.append("hash", hash)
69
- let res_json
70
- try {
71
- const res = await fetch(`${getBaseUrl()}/rb-api/v1/files/upload_chunk`, {
72
- method: "POST",
73
- credentials: "include",
74
- body: data,
75
- })
76
- res_json = await res.json()
77
- assert(res_json.status === "ok", "failed to fetch")
78
- } catch (error) {
79
- log("Error uploading chunk:", error)
80
- console.log("error json", res_json)
81
- // self.postMessage({
82
- // type: EVENTS.UPLOAD_ERROR,
83
- // payload: {
84
- // filename: file.name,
85
- // hash,
86
- // error: error.message,
87
- // },
88
- // })
89
- //
90
- return
91
- }
92
-
93
- total_bytes_read += read_chunk_length
94
-
95
- current_chunks_count++
96
-
97
- log(
98
- `upload chunks ${current_chunks_count} chunk // ${total_bytes_read} total_bytes_read...`
99
- )
100
-
101
- // there are more bytes to be read
102
- if (total_bytes_read < size) {
103
- offset += UPLOAD_CHUNK_SIZE
104
- const blob = file.slice(offset, offset + UPLOAD_CHUNK_SIZE)
105
- reader.readAsArrayBuffer(blob)
106
- }
107
- // reading complete, finalize upload
108
- else {
109
- console.log("upload complete!")
110
- console.log("FINALLL RESS", res_json)
111
- self.postMessage({
112
- type: EVENTS.UPLOAD_COMPLETE,
113
- payload: {
114
- filename: file.name,
115
- hash,
116
- },
117
- })
118
- }
119
- } else {
120
- log("unknown filereader state", e.target.readyState)
121
- }
122
- }
123
-
124
- // start reading the first chunk
125
- const blob = file.slice(offset, offset + UPLOAD_CHUNK_SIZE)
126
- reader.readAsArrayBuffer(blob)
127
- }
128
-
129
- export default upload_file
package/form/Form.tsx DELETED
@@ -1,23 +0,0 @@
1
- import {FormProvider, SubmitHandler, UseFormReturn} from "react-hook-form"
2
-
3
-
4
- type FormProps = {
5
- ref?: React.Ref<HTMLFormElement>;
6
- children: React.ReactNode;
7
- onSubmit: SubmitHandler<any>;
8
- className?: string;
9
- form: UseFormReturn<any>;
10
- }
11
-
12
- export const Form = ({ref, children, onSubmit, className = "", ...form}: FormProps) => {
13
-
14
- // const/*"needs-validation"*/
15
-
16
- return (
17
- <FormProvider {...form}>
18
- <form ref={ref} onSubmit={onSubmit} className={cx(className)} noValidate>
19
- {children}
20
- </form>
21
- </FormProvider>
22
- )
23
- }
package/form/Input.tsx DELETED
@@ -1,62 +0,0 @@
1
- import React from "react"
2
- // import {NestedKeyOf} from "@rpcbase/client/types"
3
- import _snakeCase from "lodash/snakeCase"
4
- import _get from "lodash/get"
5
- import {useFormContext} from "./hook-form"
6
-
7
-
8
- type NestedKeys<T> = {
9
- [K in keyof T & (string | number)]: T[K] extends object
10
- ? `${K}` | `${K}.${NestedKeys<T[K]>}`
11
- : `${K}`;
12
- }[keyof T & (string | number)];
13
-
14
-
15
- export type InputProps<T> = {
16
- field: NestedKeys<T>;
17
- label?: string;
18
- hint?: string;
19
- placeholder?: string;
20
- id?: string;
21
- disabled?: boolean;
22
- className?: string;
23
- }
24
-
25
- export const Input = <T,>({
26
- field,
27
- label,
28
- hint,
29
- placeholder,
30
- id: idProp,
31
- className,
32
- disabled: isDisabled,
33
- ...props
34
- }: InputProps<T> & React.InputHTMLAttributes<HTMLInputElement>) => {
35
- const form = useFormContext()
36
-
37
- const id = idProp || _snakeCase(`input_${field}`)
38
-
39
- const error = _get(form.formState.errors, field)
40
-
41
- const {isSubmitting} = form.formState
42
-
43
- const disabled = isDisabled || isSubmitting
44
-
45
- return (
46
- <div className={className}>
47
- {label && <label htmlFor={id}>{label}</label>}
48
- <input
49
- id={id}
50
- className={cx("form-control form-control-sm", {
51
- "is-invalid": !!error,
52
- })}
53
- type="text"
54
- placeholder={placeholder}
55
- disabled={disabled}
56
- {...form.register(field)}
57
- />
58
- {!error && hint && <div className="form-text">{hint}</div>}
59
- {error && <div className="invalid-feedback">{error.message}</div>}
60
- </div>
61
- )
62
- }
@@ -1,58 +0,0 @@
1
- import {ReactNode} from "react"
2
- import {useFormContext} from "react-hook-form"
3
-
4
- import ActivityIndicator from "../../ui/ActivityIndicator"
5
-
6
-
7
- interface Props {
8
- id?: string;
9
- className?: string;
10
- disabled: boolean;
11
- isLoading: boolean;
12
- title: string;
13
- submittingTitle?: string;
14
- onClick: () => void | Promise<void>;
15
- children?: ReactNode;
16
- }
17
-
18
- export const SubmitButton = ({
19
- id = "btn-submit",
20
- className = "",
21
- title,
22
- submittingTitle,
23
- children,
24
- ...props
25
- }: Props) => {
26
-
27
- const formContext = useFormContext()
28
-
29
- let isSubmitting = formContext?.formState?.isSubmitting
30
-
31
- const isDisabled = props.disabled || props.isLoading || isSubmitting
32
- const isLoading = props.isLoading || isSubmitting
33
-
34
- if (!formContext && isLoading) {
35
- isSubmitting = true
36
- }
37
-
38
- if (title && children) {
39
- throw new Error("button cannot have both title and children props")
40
- }
41
-
42
- return (
43
- <button
44
- id={id}
45
- type="submit"
46
- className={cx("btn btn-primary d-flex flex-row align-items-center align-self-start", className)}
47
- disabled={isDisabled}
48
- onClick={props.onClick}
49
- >
50
- {isLoading && (
51
- <ActivityIndicator style={{marginRight: 7}} color="#FFF" size={15} />
52
- )}
53
- {title && !isSubmitting && title}
54
- {submittingTitle && isSubmitting && submittingTitle}
55
- {children}
56
- </button>
57
- )
58
- }
@@ -1,7 +0,0 @@
1
-
2
-
3
- import {useForm, useFormContext} from "react-hook-form"
4
- import type {Resolver} from "react-hook-form"
5
-
6
-
7
- export {useForm, useFormContext, Resolver}
package/form/index.tsx DELETED
@@ -1,5 +0,0 @@
1
- export * from "./hook-form"
2
- export * from "./Form"
3
- export * from "./Input"
4
- export * from "./FileInput"
5
- export * from "./SubmitButton"
package/getBaseUrl.js DELETED
@@ -1,14 +0,0 @@
1
- /* @flow */
2
- import {SERVER_PORT, APP_DOMAIN} from "env"
3
-
4
- const protocol = (typeof window !== "undefined" && window?.location?.protocol) || "http:"
5
-
6
- // there is no SERVER_PORT in production, as we use the default port and we are behind the gateway
7
- // we assume we specify the port only when localhost or 127.0.0.1
8
- const isLocal = ["localhost", "127.0.0.1"].includes(APP_DOMAIN)
9
-
10
- const BASE_URL = isLocal ? `${protocol}//${APP_DOMAIN}:${SERVER_PORT}` : `https://${APP_DOMAIN}`
11
-
12
- const getBaseUrl = () => BASE_URL
13
-
14
- export default getBaseUrl
package/getObjectId.ts DELETED
@@ -1,31 +0,0 @@
1
- import assert from "assert"
2
- import mongoose from "mongoose"
3
- import isHexadecimal from "validator/lib/isHexadecimal"
4
-
5
- import { RB_TENANT_ID } from "env"
6
-
7
- const getRandomBytes = (n: number): Uint8Array => {
8
- let array = new Uint8Array(n)
9
- window.crypto.getRandomValues(array)
10
- return array
11
- }
12
-
13
- // validate env var is defined
14
- assert(RB_TENANT_ID, "expected RB_TENANT_ID to be defined")
15
- // is hexadecimal
16
- assert(isHexadecimal(RB_TENANT_ID), "expected RB_TENANT_ID to be a hexadecimal")
17
- // is 4 bytes
18
- assert(RB_TENANT_ID.length === 8, "RB_TENANT_ID must be exactly 4 bytes long ie: 8 hex chars")
19
-
20
- // generates a 12 bytes mongodb object id using the org id prefix or custom customer id
21
- export const getObjectId = (): mongoose.Types.ObjectId => {
22
- const tsBytes = Math.floor(Date.now() / 1000).toString(16)
23
- assert(tsBytes.length === 8, "expected tsBytes.length to be 4")
24
-
25
- const randomBytes = getRandomBytes(4)
26
- const randomHex = Buffer.from(randomBytes).toString("hex")
27
-
28
- const objId = `${tsBytes}${RB_TENANT_ID}${randomHex}`
29
-
30
- return new mongoose.Types.ObjectId(objId)
31
- }
package/hashState.js DELETED
@@ -1,158 +0,0 @@
1
- /* @flow */
2
- import {useState, useEffect, createContext, useContext, useCallback} from "react"
3
- import LZString from "lz-string"
4
- import _isNil from "lodash/isNil"
5
- import _omitBy from "lodash/omitBy"
6
-
7
- import isEqualValues from "./isEqualValues"
8
-
9
-
10
- const PAGE_NAVIGATION_EVENT = "RB_PAGE_NAVIGATION"
11
-
12
- const EMPTY_STATE_TOKEN = "N4XyA" // lz-string encoded empty state ''
13
-
14
- // WARNING: this assumes hash_str starts with "#"
15
- const parse_hash_str = (_hash_str) => {
16
- let hash_str
17
- if (_hash_str) hash_str = _hash_str
18
- else if (typeof window !== "undefined" && window?.location?.hash) {
19
- hash_str = window.location.hash
20
- } else {
21
- hash_str = ""
22
- }
23
- if (hash_str.length < 1) {
24
- return {}
25
- }
26
- const current_state_str = hash_str.slice(1)
27
- let parsed
28
- try {
29
- const decoded = LZString.decompressFromEncodedURIComponent(current_state_str)
30
- parsed = JSON.parse(decoded)
31
- } catch (e) {
32
- console.error(e)
33
- }
34
-
35
- return parsed || {}
36
- }
37
-
38
- // On first load, retrieve hashState from URL
39
- const __initial_state = _omitBy(parse_hash_str(), _isNil)
40
-
41
- export const encodeHashState = (payload) =>
42
- LZString.compressToEncodedURIComponent(JSON.stringify(payload))
43
-
44
- // add payload to window hash
45
- const apply_hash_state = (payload) => {
46
- const str = encodeHashState(payload)
47
-
48
- if (!history) return
49
-
50
- if (str === EMPTY_STATE_TOKEN) {
51
- history.replaceState(null, null, window.location.pathname + window.location.search)
52
- } else {
53
- history.replaceState(null, null, `${window.location.pathname}${window.location.search}#${encodeHashState(payload)}`)
54
- }
55
- }
56
-
57
- export const HashContext = createContext({
58
- hashState: {},
59
- serializeHashState: () => null,
60
- encodeHashLink: () => null,
61
- })
62
-
63
- export const useHashState = () => {
64
- return useContext(HashContext)
65
- }
66
-
67
- export const withHashState = (Component) => {
68
- const WrappedComp = ({children, ...props}) => {
69
- const hashCtx = useContext(HashContext)
70
-
71
- return (
72
- <Component
73
- {...props}
74
- hashState={hashCtx.hashState}
75
- serializeHashState={hashCtx.serializeHashState}
76
- encodeHashLink={hashCtx.encodeHashLink}
77
- />
78
- )
79
- }
80
-
81
- WrappedComp.displayName = `withHashState(${Component.displayName})`
82
-
83
- return WrappedComp
84
- }
85
-
86
- export const HashStateProvider = ({children}) => {
87
- const [hashState, setHashState] = useState(__initial_state)
88
-
89
- useEffect(() => {
90
- const onChange = (ev) => {
91
- const newHashStr = ev.detail.context?.hash
92
- if (!newHashStr) return
93
- // WARNING: page.js strips the "#" we add it back
94
- const parsed = _omitBy(parse_hash_str(`#${newHashStr}`), _isNil)
95
- const newState = {
96
- ...hashState,
97
- ...parsed,
98
- }
99
- // apply only if changed
100
- if (!isEqualValues(hashState, newState)) {
101
- setHashState(newState)
102
- }
103
- }
104
- document.body.addEventListener(PAGE_NAVIGATION_EVENT, onChange)
105
-
106
- return () => document.body.removeEventListener(PAGE_NAVIGATION_EVENT, onChange)
107
- }, [hashState, setHashState])
108
-
109
- useEffect(() => {
110
- apply_hash_state(hashState)
111
- window.__PRIVATE_HASH_STATE_DO_NOT_USE__ = hashState
112
- }, [hashState])
113
-
114
- const serializeHashState = useCallback((payload) => {
115
- setHashState((current) => {
116
- // clone and remove nil values
117
- const newState = _omitBy(
118
- {
119
- ...current,
120
- ...payload,
121
- },
122
- _isNil,
123
- )
124
- return newState
125
- })
126
- }, [])
127
-
128
- const encodeHashLink = useCallback((payload) => {
129
- const newState = _omitBy(
130
- {
131
- ...hashState,
132
- ...payload,
133
- },
134
- _isNil,
135
- )
136
-
137
- return encodeHashState(newState)
138
- }, [])
139
-
140
- return (
141
- <HashContext.Provider
142
- value={{
143
- hashState,
144
- serializeHashState,
145
- encodeHashLink,
146
- }}
147
- >
148
- {children}
149
- </HashContext.Provider>
150
- )
151
- }
152
-
153
-
154
- export const hashStateMiddleware = (context, next) => {
155
- next()
156
- const ev = new CustomEvent(PAGE_NAVIGATION_EVENT, {detail: {context}})
157
- document.body.dispatchEvent(ev)
158
- }
@@ -1,36 +0,0 @@
1
- /* @flow */
2
-
3
- const createBatcher = (func, delay) => {
4
- let queue = []
5
- let timeout = null
6
-
7
- function processBatch() {
8
- const batch = [...queue]
9
- queue = []
10
- timeout = null
11
-
12
- func(batch.map((item) => item.args))
13
- .then((results) => {
14
- for (let i = 0; i < batch.length; i++) {
15
- batch[i].resolve(results[i])
16
- }
17
- })
18
- .catch((err) => {
19
- for (let item of batch) {
20
- item.reject(err)
21
- }
22
- })
23
- }
24
-
25
- return (...args) => {
26
- return new Promise((resolve, reject) => {
27
- queue.push({args, resolve, reject})
28
-
29
- if (!timeout) {
30
- timeout = setTimeout(processBatch, delay)
31
- }
32
- })
33
- }
34
- }
35
-
36
- export default createBatcher
@@ -1,39 +0,0 @@
1
- /* @flow */
2
- const _deburr = require("lodash/deburr")
3
-
4
-
5
- const KNOWN_PREFIXES = ["O", "de", "Van"]
6
- const INITIALS_MAX_LENGTH = 3
7
-
8
- const getInitials = (input) => {
9
- const cleaned = _deburr(input)
10
-
11
- const initials = []
12
-
13
- const splitted = cleaned.split(/'|’| |-/)
14
-
15
- // when single word, return begining of that word as initials
16
- if (splitted.length === 1) {
17
- return splitted[0].toUpperCase().slice(0, INITIALS_MAX_LENGTH)
18
- }
19
-
20
- for (let i = 0; i < splitted.length; i++) {
21
- const part = splitted[i]
22
- // TMP: this breaks for lowercased words
23
- // skip if first letter not capitalized
24
- // if (!/[A-Z]/.test(part[0])) {
25
- // continue
26
- // }
27
-
28
- // skip if prefix, but not if prefix not followed by other non prefix word
29
- if (KNOWN_PREFIXES.includes(part) && i < splitted.length - 1) {
30
- continue
31
- }
32
-
33
- initials.push(part[0])
34
- }
35
-
36
- return initials.slice(0, INITIALS_MAX_LENGTH).join("")
37
- }
38
-
39
- module.exports = getInitials
@@ -1,15 +0,0 @@
1
- /* @flow */
2
-
3
- const onReady = (callback) => {
4
- if (["interactive", "complete"].includes(document.readyState)) {
5
- callback()
6
- } else if (document.readyState === "loading") {
7
- window.addEventListener("DOMContentLoaded", () => {
8
- callback()
9
- })
10
- } else {
11
- throw new Error("unknown ready state, cannot initialize")
12
- }
13
- }
14
-
15
- export default onReady
package/helpers/post.js DELETED
@@ -1,18 +0,0 @@
1
- /* @flow */
2
- import axios from "axios"
3
-
4
- import getBaseUrl from "../getBaseUrl"
5
-
6
- const client = axios.create({
7
- withCredentials: true,
8
- headers: {
9
- "Content-Type": "application/json"
10
- },
11
- })
12
-
13
- const post = async(url, payload) => {
14
- const res = await client.post(`${getBaseUrl()}${url}`, payload)
15
- return res.data
16
- }
17
-
18
- export default post
@@ -1,42 +0,0 @@
1
- /* @flow */
2
- import assert from "assert"
3
- import axios from "axios"
4
- import _get from "lodash/get"
5
- import _set from "lodash/set"
6
-
7
- import {get_txn_id} from "@rpcbase/std"
8
-
9
- import getBaseUrl from "../getBaseUrl"
10
- import getTenantId from "../auth/getTenantId"
11
- import {add_local_txn} from "../rts/rts"
12
-
13
- const TENANT_ID_HEADER = "rb-tenant-id"
14
-
15
- const client = axios.create({
16
- withCredentials: true,
17
- headers: {
18
- "Content-Type": "application/json",
19
- },
20
- })
21
-
22
- const postRPC = async(url, payload, options = {}) => {
23
- if (!options?.headers?.["rts-txn-id"]) {
24
- _set(options, ["headers", "rts-txn-id"], get_txn_id())
25
- }
26
-
27
- const txn_id = _get(options, ["headers", "rts-txn-id"])
28
- assert(txn_id, `unable to find txn_id for request ${url}`)
29
- add_local_txn(txn_id)
30
-
31
- options.headers[TENANT_ID_HEADER] = getTenantId()
32
-
33
- const res = await client.post(`${getBaseUrl()}${url}`, payload, options)
34
-
35
- if (res.data === "") {
36
- console.warn("postRPC:error: got empty res", res)
37
- }
38
-
39
- return res.data
40
- }
41
-
42
- export default postRPC
package/helpers/useRPC.js DELETED
@@ -1,41 +0,0 @@
1
- /* @flow */
2
- import {useCallback, useMemo, useState, useEffect, useRef} from "react"
3
- import isEqual from "fast-deep-equal"
4
-
5
- const useRPC = (fn, payload) => {
6
- const previousPayloadRef = useRef(null)
7
-
8
- const [loading, setLoading] = useState(true)
9
- const [error, setError] = useState()
10
- const [data, setData] = useState()
11
-
12
- const memoFn = useCallback(fn, [fn])
13
- const memoPayload = useMemo(() => {
14
- return payload || {}
15
- }, [payload])
16
-
17
- useEffect(() => {
18
- if (isEqual(previousPayloadRef.current, memoPayload)) {
19
- return
20
- }
21
-
22
- previousPayloadRef.current = memoPayload
23
-
24
- const load = async() => {
25
- setLoading(true)
26
-
27
- const res = await memoFn(memoPayload)
28
-
29
- setLoading(false)
30
- setData(res)
31
- if (res.status !== "ok") {
32
- setError(res.message)
33
- }
34
- }
35
- load()
36
- }, [memoFn, memoPayload])
37
-
38
- return {loading, error, data}
39
- }
40
-
41
- export default useRPC