@inzombieland/nuxt-common 0.0.3 → 0.0.8
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/LICENSE +8 -0
- package/assets/css/layer.css +305 -0
- package/module.cjs +5 -0
- package/module.d.mts +7 -0
- package/module.d.ts +7 -0
- package/module.json +9 -0
- package/module.mjs +70 -0
- package/package.json +5 -3
- package/runtime/AppProvider.vue +129 -0
- package/runtime/SidebarProvider.vue +138 -0
- package/runtime/api/account/account.get.d.ts +2 -0
- package/runtime/api/account/account.get.mjs +19 -0
- package/runtime/api/account/authcheck.get.d.ts +8 -0
- package/runtime/api/account/authcheck.get.mjs +28 -0
- package/runtime/api/account/default-handler.d.ts +2 -0
- package/runtime/api/account/default-handler.mjs +37 -0
- package/runtime/api/account/middleware.d.ts +2 -0
- package/runtime/api/account/middleware.mjs +18 -0
- package/runtime/api/account/token.get.d.ts +2 -0
- package/runtime/api/account/token.get.mjs +31 -0
- package/runtime/api/index.d.ts +37 -0
- package/runtime/api/index.mjs +26 -0
- package/runtime/api/user-actions.d.ts +118 -0
- package/runtime/api/user-actions.mjs +165 -0
- package/runtime/composables/use-active-sessions.d.ts +5 -0
- package/runtime/composables/use-active-sessions.mjs +15 -0
- package/runtime/composables/use-api-fetch.d.ts +3 -0
- package/runtime/composables/use-api-fetch.mjs +3 -0
- package/runtime/composables/use-helpers.d.ts +16 -0
- package/runtime/composables/use-helpers.mjs +10 -0
- package/runtime/composables/use-layer-manager.d.ts +3 -0
- package/runtime/composables/use-layer-manager.mjs +3 -0
- package/runtime/composables/use-subscribe.d.ts +10 -0
- package/runtime/composables/use-subscribe.mjs +22 -0
- package/runtime/composables/use-toggle-sidebar.d.ts +3 -0
- package/runtime/composables/use-toggle-sidebar.mjs +8 -0
- package/runtime/composables/use-user-actions.d.ts +2 -0
- package/runtime/composables/use-user-actions.mjs +4 -0
- package/runtime/composables/use-user.d.ts +3 -0
- package/runtime/composables/use-user.mjs +3 -0
- package/runtime/composables/use-validators.d.ts +8 -0
- package/runtime/composables/use-validators.mjs +17 -0
- package/runtime/middleware/auth.d.ts +2 -0
- package/runtime/middleware/auth.mjs +10 -0
- package/runtime/middleware/guest.d.ts +2 -0
- package/runtime/middleware/guest.mjs +12 -0
- package/runtime/middleware/index.d.ts +4 -0
- package/runtime/middleware/index.mjs +4 -0
- package/runtime/middleware/locale.global.d.ts +2 -0
- package/runtime/middleware/locale.global.mjs +13 -0
- package/runtime/packages/api/api-client.d.ts +8 -0
- package/runtime/packages/api/api-client.mjs +150 -0
- package/runtime/packages/api/bus.d.ts +7 -0
- package/runtime/packages/api/bus.mjs +22 -0
- package/runtime/packages/api/comet-client.d.ts +11 -0
- package/runtime/packages/api/comet-client.mjs +73 -0
- package/runtime/packages/api/get-user.d.ts +8 -0
- package/runtime/packages/api/get-user.mjs +54 -0
- package/runtime/packages/api/get-visitor.d.ts +11 -0
- package/runtime/packages/api/get-visitor.mjs +32 -0
- package/runtime/packages/api/helpers/api-helper.d.ts +6 -0
- package/runtime/packages/api/helpers/api-helper.mjs +99 -0
- package/runtime/packages/api/helpers/current-device.d.ts +67 -0
- package/runtime/packages/api/helpers/current-device.mjs +368 -0
- package/runtime/packages/api/helpers/date-helper.d.ts +15 -0
- package/runtime/packages/api/helpers/date-helper.mjs +231 -0
- package/runtime/packages/api/helpers/index.d.ts +4 -0
- package/runtime/packages/api/helpers/index.mjs +15 -0
- package/runtime/packages/api/index.d.ts +26 -0
- package/runtime/packages/api/index.mjs +50 -0
- package/runtime/packages/api/package.json +20 -0
- package/runtime/packages/api/refresh-token.d.ts +2 -0
- package/runtime/packages/api/refresh-token.mjs +39 -0
- package/runtime/packages/api/types.d.ts +51 -0
- package/runtime/packages/api/types.mjs +0 -0
- package/runtime/packages/api/use-api-actions.d.ts +13 -0
- package/runtime/packages/api/use-api-actions.mjs +5 -0
- package/runtime/packages/api/use-user.d.ts +47 -0
- package/runtime/packages/api/use-user.mjs +5 -0
- package/runtime/packages/helpers/index.d.ts +3 -0
- package/runtime/packages/helpers/index.mjs +14 -0
- package/runtime/packages/helpers/package.json +11 -0
- package/runtime/packages/helpers/phone-helper.d.ts +13 -0
- package/runtime/packages/helpers/phone-helper.mjs +58 -0
- package/runtime/packages/helpers/string-helper.d.ts +4 -0
- package/runtime/packages/helpers/string-helper.mjs +8 -0
- package/runtime/packages/layer-manager/LayerComponent.vue +54 -0
- package/runtime/packages/layer-manager/LayersProvider.vue +171 -0
- package/runtime/packages/layer-manager/index.d.ts +2 -0
- package/runtime/packages/layer-manager/index.mjs +2 -0
- package/runtime/packages/layer-manager/package.json +11 -0
- package/runtime/packages/layer-manager/types.d.ts +8 -0
- package/runtime/packages/layer-manager/types.mjs +0 -0
- package/runtime/packages/layer-manager/use-layer-actions.d.ts +23 -0
- package/runtime/packages/layer-manager/use-layer-actions.mjs +5 -0
- package/runtime/plugin.d.ts +2 -0
- package/runtime/plugin.mjs +42 -0
- package/runtime/plugins/device.d.ts +136 -0
- package/runtime/plugins/device.mjs +29 -0
- package/runtime/plugins/otp-input.d.ts +2 -0
- package/runtime/plugins/otp-input.mjs +5 -0
- package/runtime/plugins/sanitize-html.d.ts +2 -0
- package/runtime/plugins/sanitize-html.mjs +90 -0
- package/runtime/plugins/sanitize-url.d.ts +2 -0
- package/runtime/plugins/sanitize-url.mjs +9 -0
- package/runtime/server/middleware/basic-auth.d.ts +2 -0
- package/runtime/server/middleware/basic-auth.mjs +34 -0
- package/runtime/thirdparty/helpers/index.d.mts +5 -0
- package/runtime/thirdparty/helpers/index.d.ts +7 -0
- package/runtime/thirdparty/helpers/index.mjs +69 -0
- package/runtime/thirdparty/helpers/index.mjs.map +1 -0
- package/runtime/thirdparty/sanitize-url/index.d.mts +2 -0
- package/runtime/thirdparty/sanitize-url/index.d.ts +1 -0
- package/runtime/thirdparty/sanitize-url/index.mjs +98 -0
- package/runtime/thirdparty/sanitize-url/index.mjs.map +1 -0
- package/runtime/ui/varlet.d.ts +7 -0
- package/runtime/ui/varlet.mjs +13 -0
- package/types.d.mts +16 -0
- package/types.d.ts +16 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { once } from "../packages/helpers";
|
|
2
|
+
export declare const useHelpers: () => {
|
|
3
|
+
once: typeof once;
|
|
4
|
+
dateHelper: {
|
|
5
|
+
stringToDate: typeof import("src/runtime/packages/api/helpers/date-helper").stringToDate;
|
|
6
|
+
dateFormat: typeof import("src/runtime/packages/api/helpers/date-helper").dateFormat;
|
|
7
|
+
};
|
|
8
|
+
phoneHelper: {
|
|
9
|
+
getPlainPhoneNumber: typeof import("@inzombieland/helpers/phone-helper").getPlainPhoneNumber;
|
|
10
|
+
convertToPhone: typeof import("@inzombieland/helpers/phone-helper").convertToPhone;
|
|
11
|
+
maskPhone: typeof import("@inzombieland/helpers/phone-helper").maskPhone;
|
|
12
|
+
};
|
|
13
|
+
stringHelper: {
|
|
14
|
+
maskEmail: typeof import("@inzombieland/helpers/string-helper").maskEmail;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Subscription } from "../packages/api/bus";
|
|
2
|
+
export declare const useSubscribe: <T>(eventName: string, func: (data: T) => void, options?: {
|
|
3
|
+
once?: boolean;
|
|
4
|
+
unsubscribeOnUnmount?: boolean;
|
|
5
|
+
}) => Subscription | undefined;
|
|
6
|
+
declare const _default: <T>(eventName: string, func: (data: T) => void, options?: {
|
|
7
|
+
once?: boolean;
|
|
8
|
+
unsubscribeOnUnmount?: boolean;
|
|
9
|
+
}) => Subscription | undefined;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { onMounted, onUnmounted } from "vue";
|
|
2
|
+
import bus from "../packages/api/bus.mjs";
|
|
3
|
+
export const useSubscribe = (eventName, func, options = { once: false, unsubscribeOnUnmount: true }) => {
|
|
4
|
+
let subscription;
|
|
5
|
+
onMounted(() => {
|
|
6
|
+
subscription = bus.subscribe(eventName, (data) => {
|
|
7
|
+
func(data);
|
|
8
|
+
if (options.once) {
|
|
9
|
+
subscription?.unsubscribe();
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
onUnmounted(() => {
|
|
14
|
+
if (options.unsubscribeOnUnmount) {
|
|
15
|
+
subscription?.unsubscribe();
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return subscription;
|
|
19
|
+
};
|
|
20
|
+
export default (eventName, func, options) => {
|
|
21
|
+
return useSubscribe(eventName, func, options);
|
|
22
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const useValidators: () => {
|
|
2
|
+
emailValidator: (value: string) => boolean;
|
|
3
|
+
phoneValidator: (value: string) => boolean;
|
|
4
|
+
phoneOrEmailValidator: (value: string) => boolean;
|
|
5
|
+
minLengthValidator: (minLength: number) => (value: string) => boolean;
|
|
6
|
+
maxLengthValidator: (maxLength: number) => (value: string) => boolean;
|
|
7
|
+
passwordValidator: (value: string) => boolean;
|
|
8
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const EMAIL_REGEXP = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-z\-0-9]+\.)+[a-z]{2,}))$/i;
|
|
2
|
+
const PHONE1_REGEXP = /^((?:\+7|8|7)?(\d){10})$/gm;
|
|
3
|
+
const PHONE2_REGEXP = /^((?:\+7|8|7|\+7-|8-|7-)?(\d){3}-(\d){3}-(\d){2}-(\d){2})$/gm;
|
|
4
|
+
const PHONE3_REGEXP = /^((?:\+7|8|7|\+7\s|8\s|7\s)?\((\d){3}\)\s?(\d){3}[-\s](\d){2}[-\s](\d){2})$/gm;
|
|
5
|
+
const PASSWORD_REGEXP = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\w!@#$%^&*()+\-=[\]{};':"\\|,.<>/?]{8,}$/;
|
|
6
|
+
const emailValidator = (value) => EMAIL_REGEXP.test(value.toLowerCase());
|
|
7
|
+
const phoneValidator = (value) => PHONE1_REGEXP.test(value) || PHONE2_REGEXP.test(value) || PHONE3_REGEXP.test(value);
|
|
8
|
+
export const useValidators = () => {
|
|
9
|
+
return {
|
|
10
|
+
emailValidator,
|
|
11
|
+
phoneValidator,
|
|
12
|
+
phoneOrEmailValidator: (value) => phoneValidator(value) || emailValidator(value),
|
|
13
|
+
minLengthValidator: (minLength) => (value) => value.length >= minLength,
|
|
14
|
+
maxLengthValidator: (maxLength) => (value) => value.length <= maxLength,
|
|
15
|
+
passwordValidator: (value) => PASSWORD_REGEXP.test(value)
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineNuxtRouteMiddleware, navigateTo } from "#app";
|
|
2
|
+
import { useLocalePath } from "#i18n";
|
|
3
|
+
import { useUser } from "../composables/use-user.mjs";
|
|
4
|
+
export default defineNuxtRouteMiddleware(() => {
|
|
5
|
+
const user = useUser();
|
|
6
|
+
if (!user.value) {
|
|
7
|
+
const localePath = useLocalePath();
|
|
8
|
+
return navigateTo(localePath("/account/login"));
|
|
9
|
+
}
|
|
10
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineNuxtRouteMiddleware, navigateTo } from "#app";
|
|
2
|
+
import { useLocalePath } from "#i18n";
|
|
3
|
+
import { useRuntimeConfig } from "#imports";
|
|
4
|
+
import { useUser } from "../composables/use-user.mjs";
|
|
5
|
+
export default defineNuxtRouteMiddleware(() => {
|
|
6
|
+
const user = useUser();
|
|
7
|
+
if (user.value) {
|
|
8
|
+
const localePath = useLocalePath();
|
|
9
|
+
const baseURL = useRuntimeConfig().public.baseURL ?? "";
|
|
10
|
+
return navigateTo(localePath(baseURL));
|
|
11
|
+
}
|
|
12
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineNuxtRouteMiddleware, navigateTo } from "#app";
|
|
2
|
+
import { useCookie, useRuntimeConfig } from "#imports";
|
|
3
|
+
import { useUser } from "../composables/use-user.mjs";
|
|
4
|
+
export default defineNuxtRouteMiddleware((to) => {
|
|
5
|
+
if (import.meta.server) return;
|
|
6
|
+
const user = useUser();
|
|
7
|
+
const { value: localeCookie } = useCookie("locale");
|
|
8
|
+
const locale = user.value?.locale ?? localeCookie ?? "en";
|
|
9
|
+
const { routingStrategy, defaultLocale } = useRuntimeConfig().public;
|
|
10
|
+
if (routingStrategy === "prefix" && to.path === `/${defaultLocale}` && locale !== defaultLocale) {
|
|
11
|
+
return navigateTo(`/${locale}`);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type User } from "./use-user";
|
|
2
|
+
import type { Fetch, FetchConfig, FetchExtraOptions as FetchOptions } from "./types";
|
|
3
|
+
export declare const setUser: (newUser?: User | null) => void;
|
|
4
|
+
export declare const updateUser: (newUser: Partial<User>) => void;
|
|
5
|
+
export declare const getToken: () => string | null | undefined;
|
|
6
|
+
export declare const setToken: (newToken?: string | null) => void;
|
|
7
|
+
export declare const flush: () => void;
|
|
8
|
+
export declare const createApiFetch: (fetch: Fetch, config: FetchConfig) => (url: string, options?: FetchOptions) => Promise<any>;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { useLocalStorage } from "@vueuse/core";
|
|
2
|
+
import bus from "./bus.mjs";
|
|
3
|
+
import { newCometClient } from "./comet-client.mjs";
|
|
4
|
+
import { getVisitor } from "./get-visitor.mjs";
|
|
5
|
+
import { apiHelper, once } from "./helpers/index.mjs";
|
|
6
|
+
import { useApiActions } from "./use-api-actions.mjs";
|
|
7
|
+
import { useUser } from "./use-user.mjs";
|
|
8
|
+
let token = null;
|
|
9
|
+
export const setUser = (newUser) => {
|
|
10
|
+
const user = useUser();
|
|
11
|
+
user.value = newUser;
|
|
12
|
+
bus.publish("user:onUpdated", user.value);
|
|
13
|
+
};
|
|
14
|
+
export const updateUser = (newUser) => {
|
|
15
|
+
const user = useUser();
|
|
16
|
+
if (user.value && newUser) {
|
|
17
|
+
setUser({ ...user.value, ...newUser });
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
export const getToken = () => {
|
|
21
|
+
return token;
|
|
22
|
+
};
|
|
23
|
+
export const setToken = (newToken) => {
|
|
24
|
+
token = newToken;
|
|
25
|
+
};
|
|
26
|
+
export const flush = () => {
|
|
27
|
+
setToken(null);
|
|
28
|
+
setUser(null);
|
|
29
|
+
const loggedIn = useLocalStorage("lin", "no");
|
|
30
|
+
loggedIn.value = "no";
|
|
31
|
+
};
|
|
32
|
+
const eventHandler = (requestID, eventName) => {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const subscription = bus.subscribe(eventName, (data) => {
|
|
35
|
+
if (requestID !== data?.requestID) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
subscription?.unsubscribe();
|
|
39
|
+
resolve(data);
|
|
40
|
+
});
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
if (subscription?.closed) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
subscription?.unsubscribe();
|
|
46
|
+
reject(new Error("Event Response Timeout"));
|
|
47
|
+
}, 1e4);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
const successHandler = async (response, options = {}) => {
|
|
51
|
+
const eventNameResult = options.headers?.event;
|
|
52
|
+
const checkResponse = options.checkResponse;
|
|
53
|
+
if (typeof eventNameResult === "string" && Boolean(eventNameResult)) {
|
|
54
|
+
const requestID = response?._data?.RequestID;
|
|
55
|
+
const data = await eventHandler(requestID, eventNameResult);
|
|
56
|
+
return resolveData(data);
|
|
57
|
+
} else {
|
|
58
|
+
return resolveData(response?._data);
|
|
59
|
+
}
|
|
60
|
+
function resolveData(resData) {
|
|
61
|
+
const data = apiHelper.convertToClient(resData);
|
|
62
|
+
if (import.meta.env.MODE !== "production" && checkResponse && !checkResponse(data)?.success) {
|
|
63
|
+
console.error(checkResponse(data).error);
|
|
64
|
+
}
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const errorHandler = (error) => {
|
|
69
|
+
const { _data } = error?.response ?? { status: 500, _data: {} };
|
|
70
|
+
const data = apiHelper.convertToClient(_data.data ?? _data);
|
|
71
|
+
let message = "";
|
|
72
|
+
if (typeof data === "string") {
|
|
73
|
+
message = data.trim();
|
|
74
|
+
}
|
|
75
|
+
return new Error(message);
|
|
76
|
+
};
|
|
77
|
+
const optionsHandler = (options = {}, config) => {
|
|
78
|
+
const { apiBaseURL, appClientID, appClientSecret, isMobileApp, isDesktopApp, getHostname } = config;
|
|
79
|
+
const baseURL = "/api";
|
|
80
|
+
const headers = {};
|
|
81
|
+
const visitor = { platform: "web", hostname: getHostname() };
|
|
82
|
+
if (token) {
|
|
83
|
+
headers.authorization = `JWT ${token}`;
|
|
84
|
+
} else if (typeof window !== "undefined" && appClientID && appClientSecret) {
|
|
85
|
+
const credentials = btoa(`${appClientID}:${appClientSecret}`);
|
|
86
|
+
headers.authorization = `Basic ${credentials}`;
|
|
87
|
+
}
|
|
88
|
+
if (isMobileApp) {
|
|
89
|
+
options.baseURL = apiBaseURL;
|
|
90
|
+
visitor.platform = "mobile";
|
|
91
|
+
}
|
|
92
|
+
if (isDesktopApp) {
|
|
93
|
+
options.baseURL = apiBaseURL;
|
|
94
|
+
visitor.platform = "desktop";
|
|
95
|
+
}
|
|
96
|
+
if (typeof window !== "undefined") {
|
|
97
|
+
visitor.hostname = location.hostname;
|
|
98
|
+
}
|
|
99
|
+
const { platform, hostname } = visitor;
|
|
100
|
+
const visitorIdentifier = getVisitor();
|
|
101
|
+
if (visitorIdentifier) {
|
|
102
|
+
const { id, ip, device, appName } = visitorIdentifier;
|
|
103
|
+
headers.visitor = btoa(`${platform}|:|${hostname}|:|${id}|:|${ip}|:|${device}|:|${appName}`);
|
|
104
|
+
} else {
|
|
105
|
+
headers.visitor = btoa(`${platform}|:|${hostname}`);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
baseURL,
|
|
109
|
+
...options,
|
|
110
|
+
body: apiHelper.convertToServer(options.body),
|
|
111
|
+
headers: { ...options.headers, ...headers }
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
const fetchRequest = (url, options = {}, fetch, config) => {
|
|
115
|
+
const request = async () => {
|
|
116
|
+
const opts = optionsHandler(options, config);
|
|
117
|
+
try {
|
|
118
|
+
const response = await fetch.raw(url, opts);
|
|
119
|
+
return await successHandler(response, options);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
const { status } = error?.response ?? { status: 500 };
|
|
122
|
+
if (status === 401 && url !== "/account/1/offline") {
|
|
123
|
+
const apiActions = useApiActions();
|
|
124
|
+
await apiActions.value?.refreshToken?.();
|
|
125
|
+
return request();
|
|
126
|
+
}
|
|
127
|
+
throw errorHandler(error);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
return request();
|
|
131
|
+
};
|
|
132
|
+
export const createApiFetch = once((fetch, config) => {
|
|
133
|
+
if (typeof window !== "undefined") {
|
|
134
|
+
const cometServerURL = config.cometServerURL;
|
|
135
|
+
let cometClient;
|
|
136
|
+
bus.subscribe("user:onUpdated", (user) => {
|
|
137
|
+
if (user) {
|
|
138
|
+
cometClient || (cometClient = newCometClient(user, cometServerURL));
|
|
139
|
+
if (!cometClient.isStarted) {
|
|
140
|
+
cometClient.start();
|
|
141
|
+
cometClient.isStarted = true;
|
|
142
|
+
}
|
|
143
|
+
} else if (cometClient) {
|
|
144
|
+
cometClient.stop();
|
|
145
|
+
cometClient.isStarted = false;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
return (url, options) => fetchRequest(url, options, fetch, config);
|
|
150
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Subject } from "rxjs";
|
|
2
|
+
const hasOwnProp = {}.hasOwnProperty;
|
|
3
|
+
let subjects = {};
|
|
4
|
+
export default {
|
|
5
|
+
publish(eventName, data) {
|
|
6
|
+
subjects[eventName] || (subjects[eventName] = new Subject());
|
|
7
|
+
subjects[eventName]?.next(data);
|
|
8
|
+
},
|
|
9
|
+
subscribe(eventName, func) {
|
|
10
|
+
subjects[eventName] || (subjects[eventName] = new Subject());
|
|
11
|
+
return subjects[eventName]?.subscribe(func);
|
|
12
|
+
},
|
|
13
|
+
unsubscribeAll() {
|
|
14
|
+
const _subjects = subjects;
|
|
15
|
+
for (const eventName in _subjects) {
|
|
16
|
+
if (hasOwnProp.call(_subjects, eventName)) {
|
|
17
|
+
_subjects[eventName]?.unsubscribe();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
subjects = {};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { User } from "./use-user";
|
|
2
|
+
declare global {
|
|
3
|
+
interface Window {
|
|
4
|
+
wsPublish: (eventName: string, data: unknown) => void;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export declare function newCometClient(user: User, cometServerURL: string): {
|
|
8
|
+
isStarted: boolean;
|
|
9
|
+
start: () => void;
|
|
10
|
+
stop: () => void;
|
|
11
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Centrifuge } from "centrifuge";
|
|
2
|
+
import { getToken } from "./api-client.mjs";
|
|
3
|
+
import bus from "./bus.mjs";
|
|
4
|
+
import { apiHelper } from "./helpers/index.mjs";
|
|
5
|
+
import { useApiActions } from "./use-api-actions.mjs";
|
|
6
|
+
if (typeof window !== "undefined" && import.meta.env.MODE !== "production") {
|
|
7
|
+
window.wsPublish = (eventName, data) => {
|
|
8
|
+
setTimeout(() => bus.publish(`WS.${eventName}`, data), 0);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function newCometClient(user, cometServerURL) {
|
|
12
|
+
const transports = [
|
|
13
|
+
{
|
|
14
|
+
transport: "websocket",
|
|
15
|
+
endpoint: `wss://${cometServerURL}/connection/websocket`
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
transport: "http_stream",
|
|
19
|
+
endpoint: `https//${cometServerURL}/connection/http_stream`
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
transport: "sse",
|
|
23
|
+
endpoint: `https//${cometServerURL}/connection/sse`
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
const centrifuge = new Centrifuge(transports, {
|
|
27
|
+
token: getToken() ?? "",
|
|
28
|
+
debug: import.meta.env.MODE !== "production",
|
|
29
|
+
getToken: async () => {
|
|
30
|
+
const apiActions = useApiActions();
|
|
31
|
+
return await apiActions.value?.refreshToken?.() ?? "";
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const publish = (eventName, data) => () => {
|
|
35
|
+
bus.publish(`WS.${eventName}`, apiHelper.convertToClient(data));
|
|
36
|
+
};
|
|
37
|
+
let userSubscription;
|
|
38
|
+
return {
|
|
39
|
+
isStarted: false,
|
|
40
|
+
start: () => {
|
|
41
|
+
userSubscription || (userSubscription = centrifuge.newSubscription(`personal:user#${user?.id}`));
|
|
42
|
+
if (userSubscription.state === "subscribed") {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const publicationHandler = (message) => {
|
|
46
|
+
if (message?.data && Array.isArray(message.data)) {
|
|
47
|
+
message.data.forEach((event) => {
|
|
48
|
+
const eventName = event.NotificationName;
|
|
49
|
+
const data = event.Data;
|
|
50
|
+
if (import.meta.env.MODE !== "production") {
|
|
51
|
+
console.log("IO event handled:", eventName, data);
|
|
52
|
+
if (!eventName) {
|
|
53
|
+
console.log(`[${/* @__PURE__ */ new Date()}] Comet: no name event`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
setTimeout(publish(eventName, data), 400);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
userSubscription.on("publication", publicationHandler);
|
|
62
|
+
userSubscription.subscribe();
|
|
63
|
+
centrifuge.connect();
|
|
64
|
+
},
|
|
65
|
+
stop: () => {
|
|
66
|
+
if (userSubscription) {
|
|
67
|
+
userSubscription.unsubscribe();
|
|
68
|
+
userSubscription.removeAllListeners();
|
|
69
|
+
}
|
|
70
|
+
centrifuge.disconnect();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type User } from "./use-user";
|
|
2
|
+
import type { Fetch, FetchConfig } from "./types";
|
|
3
|
+
type GetUserResponse = {
|
|
4
|
+
token?: string | null;
|
|
5
|
+
user?: User | null;
|
|
6
|
+
};
|
|
7
|
+
export declare const createApiGetUser: (fetch: Fetch, config: FetchConfig) => () => Promise<GetUserResponse>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useLocalStorage } from "@vueuse/core";
|
|
2
|
+
import { flush, getToken, setUser } from "./api-client.mjs";
|
|
3
|
+
import { once } from "./helpers/index.mjs";
|
|
4
|
+
import { useApiActions } from "./use-api-actions.mjs";
|
|
5
|
+
import { useUser } from "./use-user.mjs";
|
|
6
|
+
let gettingUserInProgress = false;
|
|
7
|
+
let gettingUserPromise = null;
|
|
8
|
+
function getUser(fetch, config) {
|
|
9
|
+
if (gettingUserInProgress && gettingUserPromise) {
|
|
10
|
+
return gettingUserPromise;
|
|
11
|
+
}
|
|
12
|
+
return gettingUserStart(fetch, config);
|
|
13
|
+
}
|
|
14
|
+
function gettingUserStart(fetch, config) {
|
|
15
|
+
gettingUserInProgress = true;
|
|
16
|
+
gettingUserPromise = getUserRequest(fetch, config).finally(() => {
|
|
17
|
+
gettingUserInProgress = false;
|
|
18
|
+
gettingUserPromise = null;
|
|
19
|
+
});
|
|
20
|
+
return gettingUserPromise;
|
|
21
|
+
}
|
|
22
|
+
async function getUserRequest(fetch, config) {
|
|
23
|
+
const token = getToken();
|
|
24
|
+
const user = useUser();
|
|
25
|
+
if (token && user.value) {
|
|
26
|
+
return { token, user: user.value };
|
|
27
|
+
}
|
|
28
|
+
if (!token) {
|
|
29
|
+
const loggedIn = useLocalStorage("lin", "no");
|
|
30
|
+
if (loggedIn.value !== "yes") {
|
|
31
|
+
flush();
|
|
32
|
+
return { token: null, user: null };
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const apiActions = useApiActions();
|
|
36
|
+
await apiActions.value?.getVisitorIdentifier?.();
|
|
37
|
+
await apiActions.value?.refreshToken?.();
|
|
38
|
+
} catch {
|
|
39
|
+
flush();
|
|
40
|
+
return { token: null, user: null };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const user2 = await fetch("/account", config.useRequestHeaders?.(["cookie", "authorization"]));
|
|
45
|
+
setUser(user2);
|
|
46
|
+
return { token, user: user2 };
|
|
47
|
+
} catch {
|
|
48
|
+
flush();
|
|
49
|
+
return { token: null, user: null };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export const createApiGetUser = once((fetch, config) => {
|
|
53
|
+
return () => getUser(fetch, config);
|
|
54
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FetchConfig } from "./types";
|
|
2
|
+
export declare type Visitor = {
|
|
3
|
+
id?: string;
|
|
4
|
+
ip?: string;
|
|
5
|
+
device?: string;
|
|
6
|
+
appName?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const getVisitorId: () => string | undefined;
|
|
9
|
+
export declare const getVisitor: () => Visitor | null;
|
|
10
|
+
export declare const getVisitorIdentifier: (config: FetchConfig) => Promise<void>;
|
|
11
|
+
export declare const createApiGetVisitorIdentifier: (config: FetchConfig) => () => Promise<void>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { hashComponents, load } from "@fingerprintjs/fingerprintjs";
|
|
2
|
+
import { ofetch } from "ofetch";
|
|
3
|
+
import { once } from "./helpers/index.mjs";
|
|
4
|
+
let visitor = null;
|
|
5
|
+
export const getVisitorId = () => {
|
|
6
|
+
return visitor?.id;
|
|
7
|
+
};
|
|
8
|
+
export const getVisitor = () => {
|
|
9
|
+
return visitor;
|
|
10
|
+
};
|
|
11
|
+
const setVisitor = (newVisitor) => {
|
|
12
|
+
visitor = !visitor ? newVisitor : { ...visitor, ...newVisitor };
|
|
13
|
+
};
|
|
14
|
+
export const getVisitorIdentifier = async (config) => {
|
|
15
|
+
if (typeof window === "undefined" || visitor) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const fp = await load();
|
|
19
|
+
const result = await fp.get();
|
|
20
|
+
const { canvas, colorDepth, hdr, languages, screenFrame, screenResolution, ...components } = result.components;
|
|
21
|
+
const id = hashComponents(components);
|
|
22
|
+
const ip = "unknown";
|
|
23
|
+
ofetch("https://api.ipify.org?format=json").then((data) => {
|
|
24
|
+
setVisitor({ ip: data?.ip ?? "unknown" });
|
|
25
|
+
});
|
|
26
|
+
const device = await config.getDevice() || "unknown";
|
|
27
|
+
const appName = config.appName || "unknown";
|
|
28
|
+
setVisitor({ id, ip, device, appName });
|
|
29
|
+
};
|
|
30
|
+
export const createApiGetVisitorIdentifier = once((config) => {
|
|
31
|
+
return () => getVisitorIdentifier(config);
|
|
32
|
+
});
|