@pmate/account-sdk 0.5.5 → 0.6.1
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 +35 -28
- package/src/api/AccountService.ts +97 -0
- package/src/api/Api.ts +99 -0
- package/src/api/AppService.ts +71 -0
- package/src/api/EntityService.ts +41 -0
- package/src/api/ProfileService.ts +133 -0
- package/src/api/cacheInMem.ts +73 -0
- package/src/api/index.ts +5 -0
- package/src/atoms/accountAtom.ts +18 -0
- package/src/atoms/accountProfileAtom.ts +13 -0
- package/src/atoms/appConfigAtom.ts +24 -0
- package/src/atoms/atomWithLoadable.ts +48 -0
- package/src/atoms/createProfileAtom.ts +27 -0
- package/src/atoms/index.ts +17 -0
- package/src/atoms/learningLangAtom.ts +8 -0
- package/src/atoms/localStorageAtom.ts +39 -0
- package/src/atoms/loginAtom.ts +8 -0
- package/src/atoms/motherTongueAtom.ts +8 -0
- package/src/atoms/profileAtom.ts +24 -0
- package/src/atoms/profileDraftAtom.ts +7 -0
- package/src/atoms/profilesAtom.ts +20 -0
- package/src/atoms/sessionCheckAtom.ts +10 -0
- package/src/atoms/switchProfileAtom.ts +9 -0
- package/src/atoms/updateProfileAtom.ts +35 -0
- package/src/atoms/uploadAvatarAtom.ts +49 -0
- package/src/atoms/userLogoutAtom.ts +8 -0
- package/src/atoms/userSettingsAtom.ts +58 -0
- package/src/components/AuthProviderV2.tsx +300 -0
- package/src/components/Button.tsx +39 -0
- package/src/components/Drawer.tsx +80 -0
- package/src/components/index.ts +1 -0
- package/src/constants.ts +1 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useAppBackgroundStyle.ts +25 -0
- package/src/hooks/useAppConfig.ts +51 -0
- package/src/hooks/useAuthApp.ts +165 -0
- package/src/hooks/useAuthSnapshot.ts +84 -0
- package/src/hooks/useIsAuthenticated.ts +19 -0
- package/src/hooks/useProfileStepFlow.ts +78 -0
- package/src/i18n/index.ts +59 -0
- package/src/index.ts +9 -0
- package/src/locales/ar-SA.json +183 -0
- package/src/locales/de-DE.json +183 -0
- package/src/locales/el-GR.json +183 -0
- package/src/locales/en.json +183 -0
- package/src/locales/es-ES.json +183 -0
- package/src/locales/fi-FI.json +183 -0
- package/src/locales/fil-PH.json +183 -0
- package/src/locales/fr-FR.json +183 -0
- package/src/locales/hi-IN.json +183 -0
- package/src/locales/ja-JP.json +183 -0
- package/src/locales/ko-KR.json +183 -0
- package/src/locales/pt-BR.json +183 -0
- package/src/locales/pt-PT.json +183 -0
- package/src/locales/ru-RU.json +183 -0
- package/src/locales/ta-IN.json +183 -0
- package/src/locales/uk-UA.json +183 -0
- package/src/locales/zh-CN.json +183 -0
- package/src/locales/zh-TW.json +183 -0
- package/src/node/index.ts +271 -0
- package/src/types/account.types.ts +28 -0
- package/src/types/app.ts +22 -0
- package/src/types/profile.ts +6 -0
- package/src/utils/AccountManagerV2.ts +352 -0
- package/src/utils/Redirect.ts +17 -0
- package/src/utils/accountStorage.ts +46 -0
- package/src/utils/errors.ts +1 -0
- package/src/utils/index.ts +11 -0
- package/src/utils/location.ts +34 -0
- package/src/utils/profileStep.ts +26 -0
- package/src/utils/resolveAppId.ts +13 -0
- package/src/utils/selectedProfileStorage.ts +46 -0
- package/src/utils/tokenStorage.ts +47 -0
- package/dist/index.cjs.js +0 -22
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.d.ts +0 -305
- package/dist/index.es.js +0 -8897
- package/dist/index.es.js.map +0 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AccountState } from "@pmate/meta"
|
|
2
|
+
import { resolveAppId } from "./resolveAppId"
|
|
3
|
+
|
|
4
|
+
export const ACCOUNT_STATE_KEY = "account-state-v2"
|
|
5
|
+
|
|
6
|
+
const canUseStorage = () => typeof localStorage !== "undefined"
|
|
7
|
+
|
|
8
|
+
const buildAccountStateStorageKey = (app?: string): string =>
|
|
9
|
+
`${ACCOUNT_STATE_KEY}:${resolveAppId(app)}`
|
|
10
|
+
|
|
11
|
+
export const getAccountState = (app?: string): AccountState | null => {
|
|
12
|
+
if (!canUseStorage()) {
|
|
13
|
+
return null
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const raw = localStorage.getItem(buildAccountStateStorageKey(app))
|
|
17
|
+
if (!raw) {
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
return JSON.parse(raw) as AccountState
|
|
21
|
+
} catch {
|
|
22
|
+
return null
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const setAccountState = (state: AccountState, app?: string): void => {
|
|
27
|
+
if (!canUseStorage()) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
localStorage.setItem(buildAccountStateStorageKey(app), JSON.stringify(state))
|
|
32
|
+
} catch {
|
|
33
|
+
// ignore write errors
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const clearAccountState = (app?: string): void => {
|
|
38
|
+
if (!canUseStorage()) {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
localStorage.removeItem(buildAccountStateStorageKey(app))
|
|
43
|
+
} catch {
|
|
44
|
+
// ignore delete errors
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export class NotAuthenticatedError extends Error {}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export {
|
|
2
|
+
getLangFull,
|
|
3
|
+
isNicknameValid,
|
|
4
|
+
legacyLangMap,
|
|
5
|
+
normalizeLang,
|
|
6
|
+
} from "@pmate/lang"
|
|
7
|
+
export * from "./AccountManagerV2"
|
|
8
|
+
export * from "./resolveAppId"
|
|
9
|
+
export * from "./errors"
|
|
10
|
+
export * from "./profileStep"
|
|
11
|
+
export * from "./Redirect"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const LOCATION_CHANGE_EVENT = "pmate:locationchange"
|
|
2
|
+
|
|
3
|
+
const ensureLocationEvents = () => {
|
|
4
|
+
const history = window.history as History & { __pmatePatched?: boolean }
|
|
5
|
+
if (history.__pmatePatched) {
|
|
6
|
+
return
|
|
7
|
+
}
|
|
8
|
+
history.__pmatePatched = true
|
|
9
|
+
const notify = () => window.dispatchEvent(new Event(LOCATION_CHANGE_EVENT))
|
|
10
|
+
const wrap = (type: "pushState" | "replaceState") => {
|
|
11
|
+
const original = history[type]
|
|
12
|
+
history[type] = function (...args) {
|
|
13
|
+
const result = original.apply(
|
|
14
|
+
history,
|
|
15
|
+
args as Parameters<History["pushState"]>
|
|
16
|
+
)
|
|
17
|
+
notify()
|
|
18
|
+
return result
|
|
19
|
+
} as History["pushState"]
|
|
20
|
+
}
|
|
21
|
+
wrap("pushState")
|
|
22
|
+
wrap("replaceState")
|
|
23
|
+
window.addEventListener("popstate", notify)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const subscribeToLocationChange = (listener: () => void) => {
|
|
27
|
+
ensureLocationEvents()
|
|
28
|
+
window.addEventListener(LOCATION_CHANGE_EVENT, listener)
|
|
29
|
+
return () => window.removeEventListener(LOCATION_CHANGE_EVENT, listener)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const getWindowPathname = () => window.location.pathname
|
|
33
|
+
|
|
34
|
+
export const getWindowSearch = () => window.location.search
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type ProfileStepType =
|
|
2
|
+
| "nickname"
|
|
3
|
+
| "learning-language"
|
|
4
|
+
| "mother-tongue"
|
|
5
|
+
| "gender"
|
|
6
|
+
| "is-adult"
|
|
7
|
+
| "age"
|
|
8
|
+
|
|
9
|
+
const PROFILE_STEP_TYPE_SET: Record<ProfileStepType, true> = {
|
|
10
|
+
nickname: true,
|
|
11
|
+
"learning-language": true,
|
|
12
|
+
"mother-tongue": true,
|
|
13
|
+
gender: true,
|
|
14
|
+
"is-adult": true,
|
|
15
|
+
age: true,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const isProfileStepType = (value: string): value is ProfileStepType => {
|
|
19
|
+
return Boolean(PROFILE_STEP_TYPE_SET[value as ProfileStepType])
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ProfileStep {
|
|
23
|
+
type: ProfileStepType
|
|
24
|
+
title: string
|
|
25
|
+
required: boolean
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const resolveAppId = (fallbackApp?: string) => {
|
|
2
|
+
const envApp = ""
|
|
3
|
+
if (envApp) {
|
|
4
|
+
return envApp
|
|
5
|
+
}
|
|
6
|
+
if (typeof window !== "undefined") {
|
|
7
|
+
const urlApp = new URLSearchParams(window.location.search).get("app")
|
|
8
|
+
if (urlApp) {
|
|
9
|
+
return urlApp
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return fallbackApp || "pmate"
|
|
13
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { resolveAppId } from "./resolveAppId"
|
|
2
|
+
|
|
3
|
+
export const SELECTED_PROFILE_KEY = "selected-profile-v2"
|
|
4
|
+
|
|
5
|
+
const canUseStorage = () => typeof localStorage !== "undefined"
|
|
6
|
+
|
|
7
|
+
const buildSelectedProfileStorageKey = (app?: string): string =>
|
|
8
|
+
`${SELECTED_PROFILE_KEY}:${resolveAppId(app)}`
|
|
9
|
+
|
|
10
|
+
export const getSelectedProfileId = (app?: string): string | null => {
|
|
11
|
+
if (!canUseStorage()) {
|
|
12
|
+
return null
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const raw = localStorage.getItem(buildSelectedProfileStorageKey(app))
|
|
16
|
+
if (!raw) {
|
|
17
|
+
return null
|
|
18
|
+
}
|
|
19
|
+
const parsed = JSON.parse(raw) as unknown
|
|
20
|
+
return typeof parsed === "string" ? parsed : null
|
|
21
|
+
} catch {
|
|
22
|
+
return null
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const setSelectedProfileId = (id: string, app?: string): void => {
|
|
27
|
+
if (!canUseStorage()) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
localStorage.setItem(buildSelectedProfileStorageKey(app), JSON.stringify(id))
|
|
32
|
+
} catch {
|
|
33
|
+
// ignore write errors
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const clearSelectedProfileId = (app?: string): void => {
|
|
38
|
+
if (!canUseStorage()) {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
localStorage.removeItem(buildSelectedProfileStorageKey(app))
|
|
43
|
+
} catch {
|
|
44
|
+
// ignore delete errors
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { resolveAppId } from "./resolveAppId"
|
|
2
|
+
|
|
3
|
+
export const TOKEN_STORAGE_KEY = "pmate-auth-token"
|
|
4
|
+
|
|
5
|
+
const canUseStorage = () => typeof localStorage !== "undefined"
|
|
6
|
+
|
|
7
|
+
const buildTokenStorageKey = (app?: string): string => {
|
|
8
|
+
return `${TOKEN_STORAGE_KEY}:${resolveAppId(app)}`
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const getAuthToken = (app?: string): string | null => {
|
|
12
|
+
if (!canUseStorage()) {
|
|
13
|
+
return null
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const raw = localStorage.getItem(buildTokenStorageKey(app))
|
|
17
|
+
if (!raw) {
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
const parsed = JSON.parse(raw) as unknown
|
|
21
|
+
return typeof parsed === "string" ? parsed : null
|
|
22
|
+
} catch {
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const setAuthToken = (token: string, app?: string): void => {
|
|
28
|
+
if (!canUseStorage()) {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
localStorage.setItem(buildTokenStorageKey(app), JSON.stringify(token))
|
|
33
|
+
} catch {
|
|
34
|
+
// ignore write errors
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const clearAuthToken = (app?: string): void => {
|
|
39
|
+
if (!canUseStorage()) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
localStorage.removeItem(buildTokenStorageKey(app))
|
|
44
|
+
} catch {
|
|
45
|
+
// ignore delete errors
|
|
46
|
+
}
|
|
47
|
+
}
|