@inzombieland/core 0.0.1 → 1.18.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 (45) hide show
  1. package/AppProvider.vue +36 -0
  2. package/LICENSE +8 -0
  3. package/api-client.d.ts +7 -0
  4. package/api-client.mjs +130 -0
  5. package/bus.d.ts +7 -0
  6. package/bus.mjs +22 -0
  7. package/comet-client.d.ts +11 -0
  8. package/comet-client.mjs +73 -0
  9. package/composables/use-active-sessions.d.ts +26 -0
  10. package/composables/use-active-sessions.mjs +14 -0
  11. package/composables/use-api-actions.d.ts +13 -0
  12. package/composables/use-api-actions.mjs +5 -0
  13. package/composables/use-app-locale.d.ts +1 -0
  14. package/composables/use-app-locale.mjs +13 -0
  15. package/composables/use-subscribe.d.ts +10 -0
  16. package/composables/use-subscribe.mjs +22 -0
  17. package/composables/use-theme-mode.d.ts +1 -0
  18. package/composables/use-theme-mode.mjs +14 -0
  19. package/composables/use-user.d.ts +32 -0
  20. package/composables/use-user.mjs +5 -0
  21. package/get-user.d.ts +2 -0
  22. package/get-user.mjs +55 -0
  23. package/get-visitor.d.ts +11 -0
  24. package/get-visitor.mjs +48 -0
  25. package/helpers/api-helper.d.ts +6 -0
  26. package/helpers/api-helper.mjs +99 -0
  27. package/helpers/current-device.d.ts +67 -0
  28. package/helpers/current-device.mjs +368 -0
  29. package/helpers/date-helper.d.ts +15 -0
  30. package/helpers/date-helper.mjs +230 -0
  31. package/helpers/device-helper.d.ts +43 -0
  32. package/helpers/device-helper.mjs +15 -0
  33. package/helpers/index.d.ts +4 -0
  34. package/helpers/index.mjs +15 -0
  35. package/index.d.ts +53 -0
  36. package/index.mjs +60 -0
  37. package/init-application.d.ts +1 -0
  38. package/init-application.mjs +89 -0
  39. package/package.json +12 -1
  40. package/refresh-token.d.ts +2 -0
  41. package/refresh-token.mjs +39 -0
  42. package/types.d.ts +71 -0
  43. package/types.mjs +0 -0
  44. package/user-actions.d.ts +15 -0
  45. package/user-actions.mjs +38 -0
@@ -0,0 +1,230 @@
1
+ const isoExp = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)((-(\d{2}):(\d{2})|Z)?)$/;
2
+ export function stringToDate(dateString) {
3
+ if (typeof dateString === "string") {
4
+ if (dateString === "0001-01-01T00:00:00Z") {
5
+ return;
6
+ }
7
+ let date = new Date(Number.NaN);
8
+ const parts = isoExp.exec(dateString);
9
+ if (parts) {
10
+ date = parts.at(-1) === "Z" ? new Date(
11
+ Date.UTC(
12
+ Number(parts[1]),
13
+ Number(parts[2]) - 1,
14
+ Number(parts[3]),
15
+ Number(parts[4]),
16
+ Number(parts[5]),
17
+ Number(parts[6])
18
+ )
19
+ ) : new Date(
20
+ Number(parts[1]),
21
+ Number(parts[2]) - 1,
22
+ Number(parts[3]),
23
+ Number(parts[4]),
24
+ Number(parts[5]),
25
+ Number(parts[6])
26
+ );
27
+ }
28
+ return date;
29
+ }
30
+ return void 0;
31
+ }
32
+ const masks = {
33
+ default: "dd mmm yyyy",
34
+ "default:R": "dd mmmm:R yyyy",
35
+ "default:RC": "dd mmmm:R yyyy:C",
36
+ defaultshortday: "d mmm yyyy",
37
+ "defaultshortday:C": "d mmm yyyy:C",
38
+ "defaultshortday:R": "d mmmm:R yyyy",
39
+ "defaultshortday:RC": "d mmmm:R yyyy:C",
40
+ shortDate: "m/d/yy",
41
+ mediumDate: "mmm d, yyyy",
42
+ longDate: "mmmm d, yyyy",
43
+ fullDate: "dddd, mmmm d, yyyy",
44
+ shortTime: "h:MM TT",
45
+ mediumTime: "h:MM:ss TT",
46
+ longTime: "h:MM:ss TT Z",
47
+ isoDate: "yyyy-mm-dd",
48
+ isoTime: "HH:MM:ss",
49
+ isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
50
+ isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'",
51
+ time: "HH:MM",
52
+ dateTime: "dd.mm.yyyy HH:MM",
53
+ clever: "clever"
54
+ };
55
+ const i18n = {
56
+ en: {
57
+ dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
58
+ dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
59
+ monthName: [
60
+ "January",
61
+ "February",
62
+ "March",
63
+ "April",
64
+ "May",
65
+ "June",
66
+ "July",
67
+ "August",
68
+ "September",
69
+ "October",
70
+ "November",
71
+ "December"
72
+ ],
73
+ yesterday: "'Yesterday'",
74
+ today: "'Today'"
75
+ },
76
+ ru: {
77
+ dayNames: ["\u0432\u043E\u0441\u043A\u0440\u0435\u0441\u0435\u043D\u044C\u0435", "\u043F\u043E\u043D\u0435\u0434\u0435\u043B\u044C\u043D\u0438\u043A", "\u0432\u0442\u043E\u0440\u043D\u0438\u043A", "\u0441\u0440\u0435\u0434\u0430", "\u0447\u0435\u0442\u0432\u0435\u0440\u0433", "\u043F\u044F\u0442\u043D\u0438\u0446\u0430", "\u0441\u0443\u0431\u0431\u043E\u0442\u0430"],
78
+ dayNamesShort: ["\u0412\u0441", "\u041F\u043D", "\u0412\u0442", "\u0421\u0440", "\u0427\u0442", "\u041F\u0442", "\u0421\u0431"],
79
+ monthName: [
80
+ "\u044F\u043D\u0432\u0430\u0440\u044C",
81
+ "\u0444\u0435\u0432\u0440\u0430\u043B\u044C",
82
+ "\u043C\u0430\u0440\u0442",
83
+ "\u0430\u043F\u0440\u0435\u043B\u044C",
84
+ "\u043C\u0430\u0439",
85
+ "\u0438\u044E\u043D\u044C",
86
+ "\u0438\u044E\u043B\u044C",
87
+ "\u0430\u0432\u0433\u0443\u0441\u0442",
88
+ "\u0441\u0435\u043D\u0442\u044F\u0431\u0440\u044C",
89
+ "\u043E\u043A\u0442\u044F\u0431\u0440\u044C",
90
+ "\u043D\u043E\u044F\u0431\u0440\u044C",
91
+ "\u0434\u0435\u043A\u0430\u0431\u0440\u044C"
92
+ ],
93
+ yesterday: "'\u0412\u0447\u0435\u0440\u0430'",
94
+ today: "'\u0421\u0435\u0433\u043E\u0434\u043D\u044F'"
95
+ }
96
+ };
97
+ const token = /d{1,4}:?C?|m{1,4}:?[RC]?|yy(?:yy|y)?:?[RC]?|([HhMsTt])\1?|[LloZ]|"[^"]*"|'[^']*'/g;
98
+ const timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g;
99
+ const timezoneClip = /[^-+\dA-Z]/g;
100
+ const pad = (value, len = 2) => {
101
+ let val = String(value);
102
+ while (val.length < len) {
103
+ val = `0${val}`;
104
+ }
105
+ return val;
106
+ };
107
+ const createOnlyDate = (date) => {
108
+ const d = new Date(date);
109
+ d.setHours(0, 0, 0, 0);
110
+ return d;
111
+ };
112
+ const countCalendarDayBetween = (date1, date2) => {
113
+ const day1 = createOnlyDate(date1);
114
+ const day2 = createOnlyDate(date2);
115
+ const dayCount = (day1.getTime() - day2.getTime()) / (24 * 60 * 60 * 1e3);
116
+ return Math.abs(dayCount);
117
+ };
118
+ const checkIsYesterday = (now, date) => {
119
+ return now > date && countCalendarDayBetween(now, date) === 1;
120
+ };
121
+ const getDayName = (day, locale, short = false) => {
122
+ return short ? i18n[locale].dayNamesShort[day] : i18n[locale].dayNames[day];
123
+ };
124
+ const monthDeclination = (month, locale) => {
125
+ return month === 3 || month === 8 ? `${i18n[locale].monthName[month - 1]}\u0430` : `${i18n[locale].monthName[month - 1].slice(0, -1)}\u044F`;
126
+ };
127
+ const getMonthName = (month, locale, countChar = 0, declination = false) => {
128
+ const monthName = locale === "ru" && declination ? monthDeclination(month, locale) : i18n[locale].monthName[month - 1];
129
+ if (countChar && countChar > 0) {
130
+ return monthName.slice(0, 3);
131
+ }
132
+ return monthName;
133
+ };
134
+ const getMask = (format, locale, isCurrentDay, isYesterday, isCurrentYear) => {
135
+ const defaultFormat = {
136
+ en: "mmmm d, yyyy",
137
+ ru: "d mmmm:R yyyy"
138
+ };
139
+ const formats = {
140
+ default: defaultFormat,
141
+ get clever() {
142
+ if (isCurrentDay) {
143
+ return {
144
+ en: `${i18n.en.today} 'at' H:MM TT`,
145
+ ru: `${i18n.ru.today}, HH:MM`
146
+ };
147
+ } else if (isYesterday) {
148
+ return {
149
+ en: `${i18n.en.yesterday} 'at' H:MM TT`,
150
+ ru: `${i18n.ru.yesterday}, HH:MM`
151
+ };
152
+ } else if (isCurrentYear) {
153
+ return {
154
+ en: "mmmm d",
155
+ ru: "d mmmm:R"
156
+ };
157
+ } else {
158
+ return defaultFormat;
159
+ }
160
+ }
161
+ };
162
+ let mask = String(masks[format] ?? (format || masks.default));
163
+ if (mask.startsWith("UTC:")) {
164
+ mask = mask.slice(4);
165
+ }
166
+ if (formats[format]?.[locale]) {
167
+ return formats[format]?.[locale] ?? "";
168
+ }
169
+ return mask;
170
+ };
171
+ export function dateFormat(date = /* @__PURE__ */ new Date(), format = "default", locale = "en", dateTimeNow) {
172
+ date = date ? new Date(date) : /* @__PURE__ */ new Date();
173
+ if (Number.isNaN(date)) {
174
+ throw new SyntaxError("invalid date");
175
+ }
176
+ const utc = (masks[format] ?? format).startsWith("UTC:");
177
+ const now = dateTimeNow ?? /* @__PURE__ */ new Date();
178
+ const currentYear = utc ? now.getUTCFullYear() : now.getFullYear();
179
+ const currentMonth = utc ? now.getUTCMonth() : now.getMonth();
180
+ const currentDate = utc ? now.getUTCDate() : now.getDate();
181
+ const isYesterday = checkIsYesterday(now, date);
182
+ const d = utc ? date.getUTCDate() : date.getDate();
183
+ const D = utc ? date.getUTCDay() : date.getDay();
184
+ const m = utc ? date.getUTCMonth() : date.getMonth();
185
+ const y = utc ? date.getUTCFullYear() : date.getFullYear();
186
+ const isCurrentYear = y === currentYear;
187
+ const isCurrentDay = y === currentYear && m === currentMonth && d === currentDate;
188
+ const H = utc ? date.getUTCHours() : date.getHours();
189
+ const M = utc ? date.getUTCMinutes() : date.getMinutes();
190
+ const s = utc ? date.getUTCSeconds() : date.getSeconds();
191
+ const L = utc ? date.getUTCMilliseconds() : date.getMilliseconds();
192
+ const o = utc ? 0 : date.getTimezoneOffset();
193
+ const flags = {
194
+ d,
195
+ dd: pad(d),
196
+ ddd: getDayName(D, locale, true),
197
+ dddd: getDayName(D, locale),
198
+ m: m + 1,
199
+ mm: pad(m + 1),
200
+ mmm: getMonthName(m + 1, locale, 3),
201
+ mmmm: getMonthName(m + 1, locale),
202
+ "mmmm:R": getMonthName(m + 1, locale, 0, true),
203
+ "mm:C": isYesterday || isCurrentDay ? "" : pad(m + 1),
204
+ "yy:C": isCurrentYear ? "" : String(y).slice(2),
205
+ yy: String(y).slice(2),
206
+ "yyyy:C": isCurrentYear ? "" : y,
207
+ yyyy: y,
208
+ yyy: y,
209
+ h: H % 12 || 12,
210
+ hh: pad(H % 12 || 12),
211
+ H,
212
+ HH: pad(H),
213
+ M,
214
+ MM: pad(M),
215
+ s,
216
+ ss: pad(s),
217
+ l: pad(L, 3),
218
+ L: pad(L > 99 ? Math.round(L / 10) : L),
219
+ tt: H < 12 ? "am" : "pm",
220
+ TT: H < 12 ? "AM" : "PM",
221
+ Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop()?.replace(timezoneClip, ""),
222
+ o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4)
223
+ };
224
+ const mask = getMask(format, locale, isCurrentDay, isYesterday, isCurrentYear);
225
+ const parsedDate = mask.replaceAll(token, ($0) => {
226
+ return $0 in flags ? String(flags[$0]) : $0.slice(1, -1);
227
+ });
228
+ return parsedDate.trim();
229
+ }
230
+ export const dateHelper = { stringToDate, dateFormat };
@@ -0,0 +1,43 @@
1
+ export interface Device {
2
+ mobile: () => boolean;
3
+ tablet: () => boolean;
4
+ desktop: () => boolean;
5
+ ios: () => boolean;
6
+ macos: () => boolean;
7
+ ipad: () => boolean;
8
+ iphone: () => boolean;
9
+ ipod: () => boolean;
10
+ android: () => boolean;
11
+ androidPhone: () => boolean;
12
+ androidTablet: () => boolean;
13
+ blackberry: () => boolean;
14
+ blackberryPhone: () => boolean;
15
+ blackberryTablet: () => boolean;
16
+ windows: () => boolean;
17
+ windowsPhone: () => boolean;
18
+ windowsTablet: () => boolean;
19
+ fxos: () => boolean;
20
+ fxosPhone: () => boolean;
21
+ fxosTablet: () => boolean;
22
+ meego: () => boolean;
23
+ television: () => boolean;
24
+ isMobileApp: boolean;
25
+ mobileApp: () => boolean;
26
+ iosMobileApp: () => boolean;
27
+ androidMobileApp: () => boolean;
28
+ tabletApp: () => boolean;
29
+ iosTabletApp: () => boolean;
30
+ androidTabletApp: () => boolean;
31
+ landscape: () => boolean;
32
+ portrait: () => boolean;
33
+ onChangeOrientation: (cb: (newOrientation: DeviceOrientation) => void) => void;
34
+ noConflict: (currentDevice: Device) => void;
35
+ type: DeviceType;
36
+ orientation: DeviceOrientation;
37
+ os: DeviceOs;
38
+ osName: () => string;
39
+ }
40
+ export type DeviceType = "mobile" | "tablet" | "desktop" | "unknown";
41
+ export type DeviceOrientation = "landscape" | "portrait" | "unknown";
42
+ export type DeviceOs = "ios" | "macos" | "iphone" | "ipad" | "ipod" | "android" | "blackberry" | "windows" | "fxos" | "meego" | "television" | "unknown";
43
+ export declare const deviceHelper: () => Device;
@@ -0,0 +1,15 @@
1
+ import { device as currentDevice } from "./current-device.mjs";
2
+ export const deviceHelper = () => {
3
+ const device = currentDevice;
4
+ const isMobileApp = import.meta.env.VITE_IS_MOBILE_APP === "true" || import.meta.env.VITE_IS_MOBILE_APP === true;
5
+ return {
6
+ ...device,
7
+ isMobileApp,
8
+ mobileApp: () => isMobileApp && device.mobile(),
9
+ iosMobileApp: () => isMobileApp && device.mobile() && device.ios(),
10
+ androidMobileApp: () => isMobileApp && device.androidPhone(),
11
+ tabletApp: () => isMobileApp && device.tablet(),
12
+ iosTabletApp: () => isMobileApp && device.tablet() && device.ios(),
13
+ androidTabletApp: () => isMobileApp && device.androidTablet()
14
+ };
15
+ };
@@ -0,0 +1,4 @@
1
+ export { apiHelper } from "./api-helper";
2
+ export { dateHelper } from "./date-helper";
3
+ export { deviceHelper, type Device } from "./device-helper";
4
+ export declare function once<T extends (...args: any[]) => any>(fn: T): T;
@@ -0,0 +1,15 @@
1
+ export { apiHelper } from "./api-helper.mjs";
2
+ export { dateHelper } from "./date-helper.mjs";
3
+ export { deviceHelper } from "./device-helper.mjs";
4
+ export function once(fn) {
5
+ let executed = false;
6
+ let result;
7
+ return function(...args) {
8
+ if (!executed) {
9
+ executed = true;
10
+ result = fn(...args);
11
+ return result;
12
+ }
13
+ return result;
14
+ };
15
+ }
package/index.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ import { type Ref } from "vue";
2
+ import type { ActiveSession, Fetch, FetchConfig, User } from "./types";
3
+ export type { ActiveSession, Fetch, FetchConfig, User };
4
+ export { default as AppProvider } from "./AppProvider.vue";
5
+ export { useUser } from "./composables/use-user";
6
+ export { useSubscribe } from "./composables/use-subscribe";
7
+ export { useActiveSessions } from "./composables/use-active-sessions";
8
+ export { useThemeMode } from "./composables/use-theme-mode";
9
+ export { useAppLocale } from "./composables/use-app-locale";
10
+ export { getVisitor, getVisitorId, type Visitor } from "./get-visitor";
11
+ export declare function initApiFetch($fetch: Fetch, config: FetchConfig): {
12
+ fetch: Fetch;
13
+ getUser: () => Promise<import("./types").GetUserResponse>;
14
+ useApiFetch: () => Fetch;
15
+ userActions: {
16
+ signIn: (body: {
17
+ username: string;
18
+ password: string;
19
+ rememberMe: boolean;
20
+ }) => Promise<import("./types").GetUserResponse | {
21
+ key: string;
22
+ }>;
23
+ logout: () => Promise<void>;
24
+ fetchActiveSessions: () => Promise<{
25
+ sessions: ActiveSession[];
26
+ }>;
27
+ };
28
+ };
29
+ export declare const useUserActions: () => Ref<{
30
+ signIn: (body: {
31
+ username: string;
32
+ password: string;
33
+ rememberMe: boolean;
34
+ }) => Promise<import("./types").GetUserResponse | {
35
+ key: string;
36
+ }>;
37
+ logout: () => Promise<void>;
38
+ fetchActiveSessions: () => Promise<{
39
+ sessions: ActiveSession[];
40
+ }>;
41
+ }, {
42
+ signIn: (body: {
43
+ username: string;
44
+ password: string;
45
+ rememberMe: boolean;
46
+ }) => Promise<import("./types").GetUserResponse | {
47
+ key: string;
48
+ }>;
49
+ logout: () => Promise<void>;
50
+ fetchActiveSessions: () => Promise<{
51
+ sessions: ActiveSession[];
52
+ }>;
53
+ }> | undefined;
package/index.mjs ADDED
@@ -0,0 +1,60 @@
1
+ import { useLocalStorage } from "@vueuse/core";
2
+ import { ref } from "vue";
3
+ import { createApiFetch } from "./api-client.mjs";
4
+ import bus from "./bus.mjs";
5
+ import { newCometClient } from "./comet-client.mjs";
6
+ import { useApiActions } from "./composables/use-api-actions.mjs";
7
+ import { createApiGetUser } from "./get-user.mjs";
8
+ import { createApiGetVisitorIdentifier } from "./get-visitor.mjs";
9
+ import { createInitApplication } from "./init-application.mjs";
10
+ import { createApiRefreshToken } from "./refresh-token.mjs";
11
+ import { createApiUserActions } from "./user-actions.mjs";
12
+ export { default as AppProvider } from "./AppProvider.vue";
13
+ export { useUser } from "./composables/use-user.mjs";
14
+ export { useSubscribe } from "./composables/use-subscribe.mjs";
15
+ export { useActiveSessions } from "./composables/use-active-sessions.mjs";
16
+ export { useThemeMode } from "./composables/use-theme-mode.mjs";
17
+ export { useAppLocale } from "./composables/use-app-locale.mjs";
18
+ export { getVisitor, getVisitorId } from "./get-visitor.mjs";
19
+ const apiActions = useApiActions();
20
+ let userActions;
21
+ export function initApiFetch($fetch, config) {
22
+ const fetch = createApiFetch($fetch, config);
23
+ const getUser = createApiGetUser(fetch, config);
24
+ const getVisitorIdentifier = createApiGetVisitorIdentifier(config);
25
+ const initApplication = createInitApplication();
26
+ const refreshToken = createApiRefreshToken(fetch, config);
27
+ userActions = ref(createApiUserActions(fetch, config, getUser));
28
+ apiActions.value = {
29
+ initialized: true,
30
+ getVisitorIdentifier,
31
+ refreshToken
32
+ };
33
+ if (typeof window !== "undefined") {
34
+ const loggedIn = useLocalStorage("lin", "no");
35
+ const cometServerURL = config.cometServerURL;
36
+ let cometClient;
37
+ bus.subscribe("user:onUpdated", (user) => {
38
+ if (user) {
39
+ cometClient || (cometClient = newCometClient(user, cometServerURL));
40
+ if (!cometClient.isStarted) {
41
+ cometClient.start();
42
+ cometClient.isStarted = true;
43
+ }
44
+ } else if (cometClient) {
45
+ cometClient.stop();
46
+ cometClient.isStarted = false;
47
+ }
48
+ loggedIn.value = user ? "yes" : "no";
49
+ });
50
+ bus.subscribe("app:beforeMount", () => {
51
+ getVisitorIdentifier();
52
+ initApplication();
53
+ });
54
+ }
55
+ const useApiFetch = () => fetch;
56
+ return { fetch, getUser, useApiFetch, userActions: userActions.value };
57
+ }
58
+ export const useUserActions = () => {
59
+ return userActions;
60
+ };
@@ -0,0 +1 @@
1
+ export declare const createInitApplication: () => () => void;
@@ -0,0 +1,89 @@
1
+ import { StyleProvider, Themes, Locale as VarletLocale } from "@varlet/ui";
2
+ import { setNotifyDefaultOptions, Locale as VantLocale } from "vant";
3
+ import enUS from "vant/es/locale/lang/en-US";
4
+ import ruRU from "vant/es/locale/lang/ru-RU";
5
+ import { watch } from "vue";
6
+ import { useI18n } from "vue-i18n";
7
+ import { useRouter } from "vue-router";
8
+ import { useActiveSessions } from "./composables/use-active-sessions.mjs";
9
+ import { useSubscribe } from "./composables/use-subscribe.mjs";
10
+ import { useUser } from "./composables/use-user.mjs";
11
+ import { once } from "./helpers/index.mjs";
12
+ import { getVisitorId, useAppLocale, useThemeMode, useUserActions } from "./index.mjs";
13
+ function initApplication() {
14
+ const router = useRouter();
15
+ const user = useUser();
16
+ const theme = useThemeMode();
17
+ const locale = useAppLocale();
18
+ const i18n = useI18n();
19
+ watch(user, (user2) => {
20
+ if (user2 && user2.theme !== theme.value?.value) {
21
+ theme.value = { value: user2.theme };
22
+ }
23
+ if (user2 && user2.locale !== locale.value?.value) {
24
+ locale.value = { value: user2.locale };
25
+ }
26
+ });
27
+ watch(
28
+ theme,
29
+ (theme2) => {
30
+ if (theme2?.value === "dark") {
31
+ document.documentElement.classList.remove("light", "van-theme-light");
32
+ document.documentElement.classList.add("dark", "van-theme-dark");
33
+ StyleProvider(Themes.dark);
34
+ } else {
35
+ document.documentElement.classList.remove("dark", "van-theme-dark");
36
+ document.documentElement.classList.add("light", "van-theme-light");
37
+ StyleProvider(null);
38
+ }
39
+ },
40
+ { immediate: true }
41
+ );
42
+ watch(
43
+ locale,
44
+ (locale2) => {
45
+ if ("setLocale" in i18n && typeof i18n.setLocale === "function") {
46
+ i18n.setLocale(locale2?.value);
47
+ }
48
+ if (locale2?.value === "en") {
49
+ VantLocale.use(locale2, enUS);
50
+ VarletLocale.add("en-US", VarletLocale.enUS);
51
+ }
52
+ if (locale2?.value === "ru") {
53
+ VantLocale.use(locale2, ruRU);
54
+ VarletLocale.add("en-US", VarletLocale.enUS);
55
+ }
56
+ },
57
+ { immediate: true }
58
+ );
59
+ setNotifyDefaultOptions({ position: "bottom" });
60
+ useSubscribe("WS.SessionsUpdated", async (session) => {
61
+ const user2 = useUser();
62
+ if (!user2.value) {
63
+ return;
64
+ }
65
+ const activeSessions = useActiveSessions();
66
+ if (activeSessions.value.length > 0) {
67
+ activeSessions.value = [...activeSessions.value].map((activeSession) => {
68
+ if (activeSession.id === session?.sessionId) {
69
+ activeSession.isOnline = session?.status === "Online";
70
+ activeSession.signedOut = session?.status === "SignedOut";
71
+ activeSession.dateTime = /* @__PURE__ */ new Date();
72
+ }
73
+ return activeSession;
74
+ });
75
+ }
76
+ if (session?.status === "SignedOut" && session?.visitorId === getVisitorId()) {
77
+ const userActions = useUserActions();
78
+ const data = await userActions?.value.fetchActiveSessions();
79
+ const isCurrentSession = data?.sessions.some((s) => s.isCurrentSession && s.id === session?.sessionId);
80
+ if (isCurrentSession) {
81
+ await userActions?.value.logout();
82
+ await router.push({ path: "/" });
83
+ }
84
+ }
85
+ });
86
+ }
87
+ export const createInitApplication = once(() => {
88
+ return () => initApplication();
89
+ });
package/package.json CHANGED
@@ -1,11 +1,22 @@
1
1
  {
2
2
  "name": "@inzombieland/core",
3
- "version": "0.0.1",
3
+ "version": "1.18.0",
4
4
  "type": "module",
5
5
  "license": "ISC",
6
6
  "main": "./index.mjs",
7
7
  "types": "./index.d.ts",
8
8
  "publishConfig": {
9
9
  "access": "public"
10
+ },
11
+ "dependencies": {
12
+ "@fingerprintjs/fingerprintjs": "^4.6.2",
13
+ "@vant/touch-emulator": "^1.4.0",
14
+ "@varlet/ui": "^3.10.5",
15
+ "@vueuse/core": "^12.8.2",
16
+ "centrifuge": "^5.3.4",
17
+ "ofetch": "^1.4.1",
18
+ "rxjs": "^7.8.2",
19
+ "vant": "^4.9.19",
20
+ "zod": "^3.24.2"
10
21
  }
11
22
  }
@@ -0,0 +1,2 @@
1
+ import type { Fetch, FetchConfig } from "./types";
2
+ export declare const createApiRefreshToken: (fetch: Fetch, config: FetchConfig) => () => Promise<string>;
@@ -0,0 +1,39 @@
1
+ import { flush, setToken } from "./api-client.mjs";
2
+ import { once } from "./helpers/index.mjs";
3
+ let refreshingTokenInProgress = false;
4
+ let refreshingTokenPromise = null;
5
+ function refreshToken(fetch, config) {
6
+ if (refreshingTokenInProgress && refreshingTokenPromise) {
7
+ return refreshingTokenPromise;
8
+ }
9
+ return refreshingTokenStart(fetch, config);
10
+ }
11
+ function refreshingTokenStart(fetch, config) {
12
+ refreshingTokenInProgress = true;
13
+ refreshingTokenPromise = refreshTokenRequest(fetch, config).finally(() => {
14
+ refreshingTokenInProgress = false;
15
+ refreshingTokenPromise = null;
16
+ });
17
+ return refreshingTokenPromise;
18
+ }
19
+ async function refreshTokenRequest(fetch, config) {
20
+ setToken(null);
21
+ try {
22
+ const { accessToken } = await fetch(
23
+ "/account/0/token",
24
+ config.useRequestHeaders?.(["cookie"])
25
+ );
26
+ if (!accessToken) {
27
+ flush();
28
+ throw new Error("No access token");
29
+ }
30
+ setToken(accessToken);
31
+ return accessToken;
32
+ } catch (error) {
33
+ flush();
34
+ throw error;
35
+ }
36
+ }
37
+ export const createApiRefreshToken = once((fetch, config) => {
38
+ return () => refreshToken(fetch, config);
39
+ });
package/types.d.ts ADDED
@@ -0,0 +1,71 @@
1
+ import type { FetchOptions, FetchRequest, FetchResponse } from "ofetch";
2
+ import type { ZodError } from "zod";
3
+ export type FetchExtraOptions = FetchOptions & {
4
+ checkResponse?: (data: unknown) => {
5
+ success: boolean;
6
+ error?: ZodError;
7
+ data?: unknown;
8
+ };
9
+ headers?: HeadersInit & {
10
+ event?: string;
11
+ };
12
+ };
13
+ export interface ResponseMap {
14
+ blob: Blob;
15
+ text: string;
16
+ arrayBuffer: ArrayBuffer;
17
+ stream: ReadableStream<Uint8Array>;
18
+ }
19
+ export type ResponseType = keyof ResponseMap | "json";
20
+ export type MappedType<R extends ResponseType, JsonType = any> = R extends keyof ResponseMap ? ResponseMap[R] : JsonType;
21
+ export interface Fetch {
22
+ <T = any, R extends ResponseType = "json">(request: FetchRequest, options?: FetchOptions<R> & FetchExtraOptions): Promise<MappedType<R, T>>;
23
+ raw: <T = any, R extends ResponseType = "json">(request: FetchRequest, options?: FetchOptions<R> & FetchExtraOptions) => Promise<FetchResponse<MappedType<R, T>>>;
24
+ native: typeof globalThis.fetch;
25
+ create: (defaults: FetchOptions & FetchExtraOptions) => Fetch;
26
+ }
27
+ export type FetchConfig = {
28
+ apiBaseURL: string;
29
+ cometServerURL: string;
30
+ appClientID: string;
31
+ appClientSecret: string;
32
+ isMobileApp: boolean;
33
+ isDesktopApp: boolean;
34
+ appName: string;
35
+ getHostname: () => string;
36
+ getDevice: () => Promise<string> | string;
37
+ useRequestHeaders?: (include: string[]) => {};
38
+ };
39
+ export type GetUserResponse = {
40
+ token?: string | null;
41
+ user?: User | null;
42
+ };
43
+ export type User = {
44
+ id: string;
45
+ firstName: string;
46
+ lastName: string;
47
+ middleName: string;
48
+ email: string;
49
+ emailVerified: boolean;
50
+ phone: string;
51
+ phoneVerified: boolean;
52
+ gender: "" | "male" | "female";
53
+ birthday: Date;
54
+ passwordLastSet: Date;
55
+ theme: "light" | "dark";
56
+ locale: string;
57
+ avatar: string;
58
+ };
59
+ export type ActiveSession = {
60
+ id: string;
61
+ visitorId: string;
62
+ device: string;
63
+ appName: string;
64
+ location: string;
65
+ ipAddress: string;
66
+ isCurrentSession?: boolean;
67
+ isOnline?: boolean;
68
+ signedOut?: boolean;
69
+ dateTime: Date;
70
+ firstSignIn: Date;
71
+ };
package/types.mjs ADDED
File without changes
@@ -0,0 +1,15 @@
1
+ import type { ActiveSession, Fetch, FetchConfig, GetUserResponse } from "./types";
2
+ export type UserActions = ReturnType<typeof createApiUserActions>;
3
+ export declare const createApiUserActions: (fetch: Fetch, config: FetchConfig, getUser: () => Promise<GetUserResponse>) => {
4
+ signIn: (body: {
5
+ username: string;
6
+ password: string;
7
+ rememberMe: boolean;
8
+ }) => Promise<GetUserResponse | {
9
+ key: string;
10
+ }>;
11
+ logout: () => Promise<void>;
12
+ fetchActiveSessions: () => Promise<{
13
+ sessions: ActiveSession[];
14
+ }>;
15
+ };