@open-xamu-co/firebase-nuxt 1.0.0 → 1.1.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 (133) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +0 -14
  3. package/dist/module.d.mts +50 -0
  4. package/dist/module.json +12 -0
  5. package/dist/module.mjs +137 -0
  6. package/dist/runtime/client/types/entities/base.d.ts +29 -0
  7. package/dist/runtime/client/types/entities/base.js +0 -0
  8. package/dist/runtime/client/types/entities/instance.d.ts +42 -0
  9. package/dist/runtime/client/types/entities/instance.js +0 -0
  10. package/dist/runtime/client/types/entities/logs.d.ts +9 -0
  11. package/dist/runtime/client/types/entities/logs.js +0 -0
  12. package/dist/runtime/client/types/entities/user.d.ts +27 -0
  13. package/dist/runtime/client/types/entities/user.js +0 -0
  14. package/dist/runtime/client/types/firestore.d.ts +55 -0
  15. package/dist/runtime/client/types/firestore.js +0 -0
  16. package/dist/runtime/client/types/index.d.ts +5 -0
  17. package/dist/runtime/client/types/index.js +5 -0
  18. package/dist/runtime/client/utils/locale.d.ts +185 -0
  19. package/dist/runtime/client/utils/locale.js +63 -0
  20. package/dist/runtime/client/utils/logger.d.ts +14 -0
  21. package/dist/runtime/client/utils/logger.js +65 -0
  22. package/dist/runtime/client/utils/resolver.d.ts +14 -0
  23. package/dist/runtime/client/utils/resolver.js +88 -0
  24. package/dist/runtime/components/ValueCellphone.d.vue.ts +24 -0
  25. package/dist/runtime/components/ValueCellphone.vue +21 -0
  26. package/dist/runtime/components/ValueCellphone.vue.d.ts +24 -0
  27. package/dist/runtime/components/ValueID.d.vue.ts +18 -0
  28. package/dist/runtime/components/ValueID.vue +14 -0
  29. package/dist/runtime/components/ValueID.vue.d.ts +18 -0
  30. package/dist/runtime/components/ValueIP.d.vue.ts +18 -0
  31. package/dist/runtime/components/ValueIP.vue +28 -0
  32. package/dist/runtime/components/ValueIP.vue.d.ts +18 -0
  33. package/dist/runtime/components/ValueLocation.d.vue.ts +21 -0
  34. package/dist/runtime/components/ValueLocation.vue +20 -0
  35. package/dist/runtime/components/ValueLocation.vue.d.ts +21 -0
  36. package/dist/runtime/components/ValuePrice.d.vue.ts +11 -0
  37. package/dist/runtime/components/ValuePrice.vue +12 -0
  38. package/dist/runtime/components/ValuePrice.vue.d.ts +11 -0
  39. package/dist/runtime/composables/firestore/auth.d.ts +4 -0
  40. package/dist/runtime/composables/firestore/auth.js +46 -0
  41. package/dist/runtime/composables/firestore/index.d.ts +2 -0
  42. package/dist/runtime/composables/firestore/index.js +2 -0
  43. package/dist/runtime/composables/firestore/write.d.ts +21 -0
  44. package/dist/runtime/composables/firestore/write.js +279 -0
  45. package/dist/runtime/composables/index.d.ts +4 -0
  46. package/dist/runtime/composables/index.js +4 -0
  47. package/dist/runtime/composables/store/app.d.ts +82 -0
  48. package/dist/runtime/composables/store/app.js +90 -0
  49. package/dist/runtime/composables/store/instance.d.ts +57 -0
  50. package/dist/runtime/composables/store/instance.js +94 -0
  51. package/dist/runtime/composables/store/session.d.ts +41 -0
  52. package/dist/runtime/composables/store/session.js +89 -0
  53. package/dist/runtime/composables/useAppLogger.d.ts +2 -0
  54. package/dist/runtime/composables/useAppLogger.js +8 -0
  55. package/dist/runtime/composables/useFilesUpload.d.ts +19 -0
  56. package/dist/runtime/composables/useFilesUpload.js +110 -0
  57. package/dist/runtime/composables/usePrice.d.ts +9 -0
  58. package/dist/runtime/composables/usePrice.js +6 -0
  59. package/dist/runtime/composables/useQuery.d.ts +12 -0
  60. package/dist/runtime/composables/useQuery.js +33 -0
  61. package/dist/runtime/composables/utils.d.ts +14 -0
  62. package/dist/runtime/composables/utils.js +65 -0
  63. package/dist/runtime/functions/types/entities/base.d.ts +56 -0
  64. package/dist/runtime/functions/types/entities/base.js +0 -0
  65. package/dist/runtime/functions/types/entities/instance.d.ts +73 -0
  66. package/dist/runtime/functions/types/entities/instance.js +0 -0
  67. package/dist/runtime/functions/types/entities/logs.d.ts +15 -0
  68. package/dist/runtime/functions/types/entities/logs.js +0 -0
  69. package/dist/runtime/functions/types/entities/user.d.ts +13 -0
  70. package/dist/runtime/functions/types/entities/user.js +0 -0
  71. package/dist/runtime/functions/types/index.d.ts +4 -0
  72. package/dist/runtime/functions/types/index.js +4 -0
  73. package/dist/runtime/functions/utils/encrypt.d.ts +24 -0
  74. package/dist/runtime/functions/utils/encrypt.js +17 -0
  75. package/dist/runtime/functions/utils/enums.d.ts +40 -0
  76. package/dist/runtime/functions/utils/enums.js +24 -0
  77. package/dist/runtime/functions/utils/event.d.ts +71 -0
  78. package/dist/runtime/functions/utils/event.js +91 -0
  79. package/dist/runtime/functions/utils/firebase.d.ts +7 -0
  80. package/dist/runtime/functions/utils/firebase.js +21 -0
  81. package/dist/runtime/functions/utils/logger.d.ts +3 -0
  82. package/dist/runtime/functions/utils/logger.js +17 -0
  83. package/dist/runtime/functions/utils/logs.d.ts +10 -0
  84. package/dist/runtime/functions/utils/logs.js +47 -0
  85. package/dist/runtime/functions/utils/price.d.ts +12 -0
  86. package/dist/runtime/functions/utils/price.js +26 -0
  87. package/dist/runtime/functions/utils/queue.d.ts +4 -0
  88. package/dist/runtime/functions/utils/queue.js +11 -0
  89. package/dist/runtime/functions/utils/search.d.ts +15 -0
  90. package/dist/runtime/functions/utils/search.js +38 -0
  91. package/dist/runtime/functions/utils/slugs.d.ts +2 -0
  92. package/dist/runtime/functions/utils/slugs.js +16 -0
  93. package/dist/runtime/plugins/firebase-setup.d.ts +26 -0
  94. package/dist/runtime/plugins/firebase-setup.js +35 -0
  95. package/dist/runtime/plugins/loaded.client.d.ts +2 -0
  96. package/dist/runtime/plugins/loaded.client.js +44 -0
  97. package/dist/runtime/plugins/scrollBehavior.client.d.ts +2 -0
  98. package/dist/runtime/plugins/scrollBehavior.client.js +20 -0
  99. package/dist/runtime/providers/firebase.d.ts +2 -0
  100. package/dist/runtime/providers/firebase.js +7 -0
  101. package/dist/runtime/public/js/file-upload.d.ts +1 -0
  102. package/dist/runtime/public/js/file-upload.js +67 -0
  103. package/dist/runtime/public/sample-loading.png +0 -0
  104. package/dist/runtime/public/sample-missing.png +0 -0
  105. package/dist/runtime/public/sample.png +0 -0
  106. package/dist/runtime/server/api/all-collection-document.get.d.ts +7 -0
  107. package/dist/runtime/server/api/all-collection-document.get.js +56 -0
  108. package/dist/runtime/server/api/all-collection.get.d.ts +8 -0
  109. package/dist/runtime/server/api/all-collection.get.js +67 -0
  110. package/dist/runtime/server/api/media.get.d.ts +8 -0
  111. package/dist/runtime/server/api/media.get.js +114 -0
  112. package/dist/runtime/server/middleware/0.hotlinking.d.ts +5 -0
  113. package/dist/runtime/server/middleware/0.hotlinking.js +28 -0
  114. package/dist/runtime/server/middleware/1.context.d.ts +5 -0
  115. package/dist/runtime/server/middleware/1.context.js +108 -0
  116. package/dist/runtime/server/types/index.d.ts +34 -0
  117. package/dist/runtime/server/types/index.js +0 -0
  118. package/dist/runtime/server/utils/auth.d.ts +10 -0
  119. package/dist/runtime/server/utils/auth.js +31 -0
  120. package/dist/runtime/server/utils/cache.d.ts +21 -0
  121. package/dist/runtime/server/utils/cache.js +20 -0
  122. package/dist/runtime/server/utils/environment.d.ts +45 -0
  123. package/dist/runtime/server/utils/environment.js +50 -0
  124. package/dist/runtime/server/utils/firebase.d.ts +9 -0
  125. package/dist/runtime/server/utils/firebase.js +13 -0
  126. package/dist/runtime/server/utils/firestore.d.ts +27 -0
  127. package/dist/runtime/server/utils/firestore.js +137 -0
  128. package/dist/runtime/server/utils/guards.d.ts +15 -0
  129. package/dist/runtime/server/utils/guards.js +23 -0
  130. package/dist/runtime/server/utils/instance.d.ts +21 -0
  131. package/dist/runtime/server/utils/instance.js +68 -0
  132. package/dist/types.d.mts +7 -0
  133. package/package.json +17 -17
@@ -0,0 +1,89 @@
1
+ import { deleteUser } from "firebase/auth";
2
+ import { defineStore, skipHydrate } from "pinia";
3
+ import { computed } from "vue";
4
+ import { useRouter } from "vue-router";
5
+ import { getDocumentId } from "../../client/utils/resolver.js";
6
+ import { useCookie, useRuntimeConfig, useSwal } from "#imports";
7
+ const cookieOptionsDefaults = {
8
+ sameSite: "strict",
9
+ maxAge: 365 * 24 * 60 * 60
10
+ // 1 year
11
+ };
12
+ export const useSessionStore = defineStore("session", () => {
13
+ const { production } = useRuntimeConfig().public;
14
+ const cookieOptions = {
15
+ ...cookieOptionsDefaults,
16
+ secure: production,
17
+ partitioned: production
18
+ };
19
+ const token = useCookie("session.token", {
20
+ ...cookieOptions,
21
+ default: () => null
22
+ });
23
+ const expiredToken = useCookie("session.expiredToken", {
24
+ ...cookieOptions,
25
+ default: () => false
26
+ });
27
+ const user = useCookie("session.user", {
28
+ ...cookieOptions,
29
+ partitioned: false,
30
+ default: () => void 0
31
+ });
32
+ const path = computed(() => {
33
+ const id = user.value?.id;
34
+ return id ? `users/${getDocumentId(id)}` : "";
35
+ });
36
+ function setToken(newToken, newExpiredToken = false) {
37
+ token.value = newToken || null;
38
+ expiredToken.value = newExpiredToken;
39
+ }
40
+ function setUser({ createdAt, updatedAt, ...userData }, token2) {
41
+ user.value = { ...user.value, ...userData };
42
+ setToken(token2, false);
43
+ }
44
+ function unsetSession(expiredToken2 = false) {
45
+ setToken("", expiredToken2);
46
+ user.value = void 0;
47
+ }
48
+ async function logout(clientAuth) {
49
+ if (import.meta.server) return;
50
+ const Swal = useSwal();
51
+ const { value } = await Swal.firePrevent({
52
+ title: "Cerrar sesion",
53
+ text: "\xBFEsta seguro de querer cerrar sesion?"
54
+ });
55
+ if (value) {
56
+ unsetSession();
57
+ await clientAuth?.signOut();
58
+ window.location.href = "/";
59
+ }
60
+ }
61
+ async function remove(clientAuth) {
62
+ if (import.meta.server) return;
63
+ const router = useRouter();
64
+ const Swal = useSwal();
65
+ const { value } = await Swal.firePrevent({
66
+ title: "Eliminar cuenta",
67
+ text: "\xBFEsta seguro de querer eliminar tu cuenta?",
68
+ footer: "Borraremos toda tu informaci\xF3n, esta acci\xF3n no es reversible, aunque puedes volver a registrarte mas tarde"
69
+ });
70
+ const user2 = clientAuth?.currentUser;
71
+ if (user2 && value) {
72
+ await deleteUser(user2);
73
+ router.push("/");
74
+ }
75
+ }
76
+ return {
77
+ // User
78
+ token: skipHydrate(token),
79
+ expiredToken: skipHydrate(expiredToken),
80
+ user: skipHydrate(user),
81
+ // User getters
82
+ path,
83
+ // User actions
84
+ setUser,
85
+ unsetSession,
86
+ logout,
87
+ remove
88
+ };
89
+ });
@@ -0,0 +1,2 @@
1
+ import type { tLogger } from "@open-xamu-co/ui-common-types";
2
+ export default function useAppLogger(...args: Parameters<tLogger>): Promise<any>;
@@ -0,0 +1,8 @@
1
+ import { makeLogger } from "../client/utils/logger.js";
2
+ import { useInstanceStore, useSessionStore } from "#imports";
3
+ export default async function useAppLogger(...args) {
4
+ const INSTANCE = useInstanceStore();
5
+ const SESSION = useSessionStore();
6
+ const logger = makeLogger({ instanceId: INSTANCE.id, authId: SESSION.path });
7
+ return logger(...args);
8
+ }
@@ -0,0 +1,19 @@
1
+ import { DocumentReference } from "firebase/firestore";
2
+ interface UploadOptions {
3
+ type?: "images";
4
+ customMetadata?: Record<string, any>;
5
+ /**
6
+ * File upload callback
7
+ *
8
+ * Runs if not all files were uploaded
9
+ */
10
+ uploaded?: (paths: string[]) => any;
11
+ }
12
+ /**
13
+ * upload files, get urls
14
+ *
15
+ * Files should not bother with instances
16
+ */
17
+ export default function useFilesUpload(files: File[] | undefined, targetRef: DocumentReference, // Document related to the files
18
+ options?: UploadOptions): Promise<string[]>;
19
+ export {};
@@ -0,0 +1,110 @@
1
+ import { toRaw } from "vue";
2
+ import { collection, doc, getDoc, increment, setDoc } from "firebase/firestore";
3
+ import { getToken } from "firebase/app-check";
4
+ import { getDocumentId } from "../client/utils/resolver.js";
5
+ import useAppLogger from "./useAppLogger.js";
6
+ import {
7
+ useNuxtApp,
8
+ useAppStore,
9
+ useInstanceStore,
10
+ useSessionStore,
11
+ useRuntimeConfig
12
+ } from "#imports";
13
+ export default async function useFilesUpload(files = [], targetRef, options = {}) {
14
+ const APP = useAppStore();
15
+ const SESSION = useSessionStore();
16
+ const INSTANCE = useInstanceStore();
17
+ const { $clientFirestore, $clientAppCheck } = useNuxtApp();
18
+ const { firebaseConfig } = useRuntimeConfig().public;
19
+ const appData = toRaw(firebaseConfig);
20
+ const { type = "images", customMetadata = {}, uploaded } = options;
21
+ if (!SESSION.token || !$clientFirestore || !$clientAppCheck) {
22
+ throw new Error("Subida no autorizada");
23
+ }
24
+ const memberId = getDocumentId(SESSION.path);
25
+ const memberPath = `${INSTANCE.id}/members/${memberId}`;
26
+ const updatedByRef = memberId ? doc($clientFirestore, memberPath) : void 0;
27
+ const parentCollection = targetRef.parent;
28
+ const grandParentDocument = parentCollection.parent;
29
+ const counterPath = grandParentDocument?.path || INSTANCE.id;
30
+ const countersCollectionRef = collection($clientFirestore, `${counterPath}/counters`);
31
+ const counterId = `${type}_${parentCollection.id}_${targetRef.id}`;
32
+ const counterRef = doc(countersCollectionRef, counterId);
33
+ const counterSnapshot = await getDoc(counterRef);
34
+ const { current = 0, createdByRef = updatedByRef } = counterSnapshot.data() || {};
35
+ const { token: appCheckToken } = await getToken($clientAppCheck);
36
+ try {
37
+ setDoc(
38
+ counterRef,
39
+ { current: increment(files.length), createdByRef, updatedByRef },
40
+ { merge: true }
41
+ );
42
+ } catch (err) {
43
+ useAppLogger("composables:files:useFilesUpload:counter", counterRef.path, err);
44
+ }
45
+ const paths = [];
46
+ for (let index = 0; index < files.length; index++) {
47
+ const file = files[index];
48
+ const path = `${targetRef.path}_${current + index + 1}`;
49
+ const filePath = `${type}/${path}/original.${file.type.split("/")[1]}`;
50
+ const id = `${targetRef.id}_${file.name}`;
51
+ if (!file.size) {
52
+ useAppLogger("composables:files:useFilesUpload:map", new Error("Invalid file"), {
53
+ path,
54
+ size: file.size,
55
+ type: file.type,
56
+ name: file.name,
57
+ lastModified: file.lastModified
58
+ });
59
+ continue;
60
+ }
61
+ paths.push(path);
62
+ await APP.saveThumbnail(path, file);
63
+ APP.useQueue(
64
+ id,
65
+ `Subiendo archivo`,
66
+ async () => {
67
+ try {
68
+ const worker = new Worker("/js/file-upload.js", { type: "module" });
69
+ const uploadedSize = await new Promise((resolve, reject) => {
70
+ worker.postMessage({
71
+ filePath,
72
+ file,
73
+ customMetadata: { filePath, memberPath, ...customMetadata },
74
+ appData,
75
+ appCheckToken
76
+ });
77
+ worker.onmessage = ({ data }) => {
78
+ const { result, error, message, type: type2 } = data;
79
+ switch (type2) {
80
+ case "result":
81
+ resolve(result);
82
+ break;
83
+ case "message":
84
+ console.log(message);
85
+ break;
86
+ case "error":
87
+ console.log(message, error);
88
+ reject(error);
89
+ break;
90
+ }
91
+ };
92
+ worker.onerror = (err) => reject(err);
93
+ worker.onmessageerror = (err) => reject(err);
94
+ });
95
+ if (!uploadedSize) throw `No se subi\xF3 el archivo ${id}`;
96
+ await new Promise((resolve) => setTimeout(resolve, 1e3 * 10));
97
+ return `Archivo subido (${(uploadedSize / 1e6).toFixed(2)}MB)`;
98
+ } catch (err) {
99
+ paths.splice(paths.indexOf(path), 1);
100
+ uploaded?.(paths);
101
+ useAppLogger("composables:files:useFilesUpload:upload", path, err);
102
+ throw `No se subi\xF3 el archivo ${id}`;
103
+ }
104
+ },
105
+ 10
106
+ // Minutes per upload
107
+ );
108
+ }
109
+ return paths;
110
+ }
@@ -0,0 +1,9 @@
1
+ import { type iPriceProps } from "../functions/utils/price.js";
2
+ export default function usePrice(props?: iPriceProps): {
3
+ iva: number;
4
+ base: number;
5
+ price: number;
6
+ formattedIva: string;
7
+ formattedBase: string;
8
+ formattedPrice: string;
9
+ };
@@ -0,0 +1,6 @@
1
+ import { makeUsePrice } from "../functions/utils/price.js";
2
+ import { useRootStore } from "#imports";
3
+ export default function usePrice(props) {
4
+ const ROOT = useRootStore();
5
+ return makeUsePrice(ROOT.tax)(props);
6
+ }
@@ -0,0 +1,12 @@
1
+ import type { NitroFetchOptions, NitroFetchRequest } from "nitropack";
2
+ /**
3
+ * Fetch wrapper with csrf token
4
+ */
5
+ export declare function useCsrfQuery<T, R extends NitroFetchRequest = NitroFetchRequest>(url: Extract<R, string>, baseOptions?: NitroFetchOptions<R>): Promise<any>;
6
+ /**
7
+ * Fetch wrapper
8
+ *
9
+ * Refresh auth token before each request
10
+ * @see https://stackoverflow.com/questions/47803495/error-firebase-id-token-has-expired
11
+ */
12
+ export declare function useQuery<T, R extends NitroFetchRequest = NitroFetchRequest>(url: Extract<R, string>, baseOptions?: NitroFetchOptions<R>): Promise<import("nitropack").TypedInternalResponse<NitroFetchRequest, T, "get">>;
@@ -0,0 +1,33 @@
1
+ import { useRequestHeaders, useNuxtApp, useRuntimeConfig, useSessionStore } from "#imports";
2
+ async function getQueryOptions(baseOptions) {
3
+ const SESSION = useSessionStore();
4
+ const { $clientAuth } = useNuxtApp();
5
+ const { cache } = useRuntimeConfig().public;
6
+ const { query, ...options } = { ...baseOptions };
7
+ const headers = {
8
+ ...useRequestHeaders(),
9
+ // Server headers (required for instance)
10
+ authorization: SESSION.token || "",
11
+ "Cache-Control": cache.frequent,
12
+ ...options?.headers,
13
+ // Overrides
14
+ "Xamu-Context-Source": import.meta.client ? "client" : "server"
15
+ };
16
+ if (SESSION.user) {
17
+ if (import.meta.client) {
18
+ const freshToken = await $clientAuth?.currentUser?.getIdToken();
19
+ headers.authorization = freshToken || headers.authorization;
20
+ }
21
+ SESSION.setUser(SESSION.user, headers.authorization);
22
+ }
23
+ return { credentials: "same-origin", ...options, query, headers };
24
+ }
25
+ export async function useCsrfQuery(url, baseOptions) {
26
+ const { $csrfFetch } = useNuxtApp();
27
+ const { responseType, ...options } = await getQueryOptions(baseOptions);
28
+ return $csrfFetch(url, options);
29
+ }
30
+ export async function useQuery(url, baseOptions) {
31
+ const options = await getQueryOptions(baseOptions);
32
+ return $fetch(url, options);
33
+ }
@@ -0,0 +1,14 @@
1
+ export declare function useImagePath(path?: string, preset?: "avatar" | "small" | "medium" | "large"): string;
2
+ /**
3
+ * Return object with differing properties if any
4
+ */
5
+ export declare function getValuesDiff<V extends Record<string, any>>(values: V, expectedValues: Partial<V>): Partial<V> | undefined;
6
+ export declare function useCreateError(message: string, statusCode?: number): import("nuxt/app").NuxtError<unknown>;
7
+ /**
8
+ * Append tracking information to external urls
9
+ */
10
+ export declare function useUTMLink(link: string): string;
11
+ /**
12
+ * Attemp to reload image after a few seconds
13
+ */
14
+ export declare function onImageError(event: Event, attemp?: number): string | undefined;
@@ -0,0 +1,65 @@
1
+ import { isEqual } from "lodash-es";
2
+ import { createError, useAppStore, useInstanceStore } from "#imports";
3
+ export function useImagePath(path, preset = "avatar") {
4
+ if (!path || path === "/sample-loading.png") return "/sample-loading.png";
5
+ else if (path.startsWith("/api/media/images")) return path;
6
+ else if (path.startsWith("/firebase")) path = path.replace("/firebase", "/api/media/images");
7
+ else path = `/api/media/images/${path}/${preset}.webp`;
8
+ return `${path}?temp=${Date.now()}`;
9
+ }
10
+ export function getValuesDiff(values, expectedValues) {
11
+ const keysWithDifference = [];
12
+ const differentValues = {};
13
+ for (const k in expectedValues) {
14
+ if (!Object.hasOwn(expectedValues, k)) continue;
15
+ const expected = ![null, void 0, ""].includes(expectedValues[k]);
16
+ const provided = values[k] || values[k] === 0;
17
+ if (k in values || expected && !provided) {
18
+ const equal = isEqual(values[k], expectedValues[k]);
19
+ const emptyArray = isEqual(values[k] || [], expectedValues[k]);
20
+ if (equal || emptyArray) continue;
21
+ keysWithDifference.push(k);
22
+ differentValues[k] = values[k] ?? "";
23
+ }
24
+ }
25
+ if (!keysWithDifference.length) return;
26
+ return differentValues;
27
+ }
28
+ export function useCreateError(message, statusCode = 500) {
29
+ return createError({ message, statusCode, fatal: true });
30
+ }
31
+ export function useUTMLink(link) {
32
+ const INSTANCE = useInstanceStore();
33
+ const { hostname } = new URL(INSTANCE.current?.url || "");
34
+ const url = new URL(link);
35
+ url.searchParams.append("utm_source", hostname);
36
+ url.searchParams.append("utm_content", "textlink");
37
+ return url.toString();
38
+ }
39
+ export function onImageError(event, attemp = 0) {
40
+ if (attemp >= 20) return;
41
+ const APP = useAppStore();
42
+ const img = event.target;
43
+ const [src] = img.src.split("?");
44
+ if (src.includes("/api/media/images/instances/")) {
45
+ const key = src.slice(18, src.lastIndexOf("/"));
46
+ const thumbnail = APP.thumbnails[key];
47
+ if (thumbnail) return img.src = thumbnail;
48
+ }
49
+ setTimeout(async () => {
50
+ try {
51
+ const now = Date.now();
52
+ const unchached = `${src}?t=${now}`;
53
+ const response = await fetch(src);
54
+ if (!response.ok) {
55
+ if (response.status === 503 || response.status === 404) {
56
+ return onImageError(event, attemp++);
57
+ }
58
+ return;
59
+ }
60
+ img.src = unchached;
61
+ } catch (error) {
62
+ return;
63
+ }
64
+ }, 1e3 * 5);
65
+ }
@@ -0,0 +1,56 @@
1
+ import type { FieldValue, Timestamp } from "firebase-admin/firestore";
2
+ import type { ePaymentValidator } from "../../utils/enums.js";
3
+ export type FirebaseValues<T extends FirebaseData> = {
4
+ [K in keyof T]?: T[K] | FieldValue;
5
+ };
6
+ /**
7
+ * Extended firebase DocumentData
8
+ *
9
+ * @abstract
10
+ */
11
+ export interface FirebaseData extends Record<string, any> {
12
+ /** @automated Creation date */
13
+ createdAt?: Timestamp;
14
+ /** @automated Last update date */
15
+ updatedAt?: Timestamp;
16
+ /**
17
+ * Lock document & prevent deletion
18
+ * A boolean or an array of reference paths locking the document
19
+ *
20
+ * @automated
21
+ */
22
+ lock?: boolean | string[];
23
+ }
24
+ /**
25
+ * Price data
26
+ *
27
+ * @abstract
28
+ */
29
+ export interface PriceData {
30
+ /** Full price */
31
+ price?: number;
32
+ /** base price (no iva) */
33
+ base?: number;
34
+ /** Iva price */
35
+ iva?: number;
36
+ /** @automated unique item ref */
37
+ reference?: string;
38
+ }
39
+ /**
40
+ * Payment data
41
+ *
42
+ * @abstract
43
+ */
44
+ export interface PaymentData extends PriceData {
45
+ /** @automated Integrity hash */
46
+ integrity?: string;
47
+ /** @automated Payment validation source */
48
+ validator?: ePaymentValidator;
49
+ /**
50
+ * Client has paid
51
+ * @automated Payment date
52
+ */
53
+ paidAt?: false | Timestamp;
54
+ observations?: string;
55
+ oldObservations?: string;
56
+ }
File without changes
@@ -0,0 +1,73 @@
1
+ import type { DocumentReference } from "firebase-admin/firestore";
2
+ import type { FirebaseData } from "./base.js";
3
+ import type { LogData } from "./logs.js";
4
+ import type { UserData } from "./user.js";
5
+ /**
6
+ * Document can be modified by any user
7
+ *
8
+ * This data is used to keep track of the changes
9
+ */
10
+ export interface SharedData extends FirebaseData {
11
+ createdByRef?: DocumentReference;
12
+ updatedByRef?: DocumentReference;
13
+ deletedByRef?: DocumentReference;
14
+ }
15
+ /**
16
+ * Root instance
17
+ * Stores data that is shared across all instances
18
+ *
19
+ * @collection instances
20
+ */
21
+ export interface RootData extends InstanceData {
22
+ config?: InstanceData["config"] & {
23
+ /**
24
+ * IVA percentage
25
+ * Keep track of the IVA percentage
26
+ * @example 19
27
+ */
28
+ iva?: number;
29
+ };
30
+ /** @example "Xamu" */
31
+ poweredBy?: string;
32
+ }
33
+ /**
34
+ * App instance
35
+ *
36
+ * @collection instances
37
+ */
38
+ export interface InstanceData extends SharedData {
39
+ locationCity?: string;
40
+ locationState?: string;
41
+ locationCountry?: string;
42
+ /**
43
+ * Canonical site url
44
+ *
45
+ * @example https://my-store.mydomain.com
46
+ * @automated
47
+ */
48
+ url?: string;
49
+ config?: {
50
+ [key: string]: any;
51
+ /**
52
+ * When tenants are enabled, domains are required
53
+ */
54
+ domains?: string[];
55
+ };
56
+ }
57
+ /**
58
+ * Firebase log
59
+ *
60
+ * @collection instances/logs
61
+ */
62
+ export interface InstanceLogData extends LogData, SharedData {
63
+ }
64
+ /**
65
+ * Instance member
66
+ *
67
+ * @collection instances/members
68
+ */
69
+ export interface InstanceMemberData extends SharedData {
70
+ userRef?: DocumentReference<UserData>;
71
+ /** Could be non existent */
72
+ rootMemberRef?: DocumentReference<InstanceMemberData>;
73
+ }
@@ -0,0 +1,15 @@
1
+ import type { FirebaseData } from "./base.js";
2
+ /** General log entity */
3
+ export interface LogData extends FirebaseData {
4
+ at?: string;
5
+ code?: string;
6
+ message?: string;
7
+ error?: string;
8
+ /** Additional log tracking metadata */
9
+ metadata?: any;
10
+ /**
11
+ * Internal logs, omit some automation
12
+ * @automated
13
+ */
14
+ internal?: boolean;
15
+ }
File without changes
@@ -0,0 +1,13 @@
1
+ import type { SharedData } from "./instance.js";
2
+ /**
3
+ * Firebase user
4
+ *
5
+ * @collection
6
+ */
7
+ export interface UserData extends SharedData {
8
+ uid?: string;
9
+ photoURL?: string | null;
10
+ isAnonymous?: boolean | null;
11
+ name?: string | null;
12
+ email?: string | null;
13
+ }
File without changes
@@ -0,0 +1,4 @@
1
+ export * from "./entities/base.js";
2
+ export * from "./entities/user.js";
3
+ export * from "./entities/instance.js";
4
+ export * from "./entities/logs.js";
@@ -0,0 +1,4 @@
1
+ export * from "./entities/base.js";
2
+ export * from "./entities/user.js";
3
+ export * from "./entities/instance.js";
4
+ export * from "./entities/logs.js";
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Encrypts a given text using AES-256-CBC algorithm.
3
+ *
4
+ * This function takes in a text to be encrypted and an encryption key.
5
+ * It generates a random initialization vector (IV) and uses it along with the key to create a cipher.
6
+ * The text is then encrypted using the cipher and the encrypted text is concatenated with the IV.
7
+ *
8
+ * @param {string} text - The text to be encrypted.
9
+ * @param {string} key - The encryption key.
10
+ * @returns {string} The encrypted text, concatenated with the initialization vector.
11
+ */
12
+ export declare function encrypt(text: string, key: string): string;
13
+ /**
14
+ * Decrypts a given encrypted text using AES-256-CBC algorithm.
15
+ *
16
+ * This function takes in an encrypted text and an encryption key.
17
+ * It splits the encrypted text into the initialization vector (IV) and the actual encrypted text.
18
+ * It then uses the IV and the key to create a decipher and decrypts the text.
19
+ *
20
+ * @param {string} text - The encrypted text to be decrypted.
21
+ * @param {string} key - The encryption key.
22
+ * @returns {string} The decrypted text.
23
+ */
24
+ export declare function decrypt(text: string, key: string): string;
@@ -0,0 +1,17 @@
1
+ import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
2
+ export function encrypt(text, key) {
3
+ const iv = randomBytes(16);
4
+ const cipher = createCipheriv("aes-256-cbc", Buffer.from(key.padEnd(32, "0")), iv);
5
+ let encrypted = cipher.update(text);
6
+ encrypted = Buffer.concat([encrypted, cipher.final()]);
7
+ return iv.toString("hex") + ":" + encrypted.toString("hex");
8
+ }
9
+ export function decrypt(text, key) {
10
+ const parts = text.split(":");
11
+ const iv = Buffer.from(parts.shift(), "hex");
12
+ const encryptedText = Buffer.from(parts.join(":"), "hex");
13
+ const decipher = createDecipheriv("aes-256-cbc", Buffer.from(key.padEnd(32, "0")), iv);
14
+ let decrypted = decipher.update(encryptedText);
15
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
16
+ return decrypted.toString();
17
+ }
@@ -0,0 +1,40 @@
1
+ export declare enum eIdDocumentType {
2
+ /** Cédula de ciudadanía */
3
+ CC = "CC",
4
+ /** Cédula de extranjería */
5
+ CE = "CE",
6
+ /** Pasaporte */
7
+ PA = "PA",
8
+ /** Tarjeta de identidad */
9
+ TI = "TI",
10
+ /** Numero de identificación tributario */
11
+ NIT = "NIT"
12
+ }
13
+ /**
14
+ * Purchase validation source
15
+ */
16
+ export declare enum ePaymentValidator {
17
+ /** Gateway did its job */
18
+ WEBHOOK = "WEBHOOK",
19
+ /** Timeout elapsep */
20
+ TIMEOUT_TASK = "TIMEOUT_TASK",
21
+ /** User returned from gateway */
22
+ TURNBACK = "TURNBACK",
23
+ /** Admin handled the charge */
24
+ ADMIN = "ADMIN"
25
+ }
26
+ /**
27
+ * Cache control
28
+ */
29
+ export declare enum eCacheControl {
30
+ NONE = "no-cache, no-store, must-revalidate",
31
+ /** Cache for a few minutes */
32
+ FREQUENT = "public, max-age=120, stale-while-revalidate=60",
33
+ /** Cache for an hour */
34
+ NORMAL = "public, max-age=3600, must-revalidate",
35
+ /** Cache for a month */
36
+ MIDTERM = "public, max-age=2592000, must-revalidate",
37
+ /** Cache for a year */
38
+ LONGTERM = "public, max-age=31536000, must-revalidate"
39
+ }
40
+ export {};
@@ -0,0 +1,24 @@
1
+ export var eIdDocumentType = /* @__PURE__ */ ((eIdDocumentType2) => {
2
+ eIdDocumentType2["CC"] = "CC";
3
+ eIdDocumentType2["CE"] = "CE";
4
+ eIdDocumentType2["PA"] = "PA";
5
+ eIdDocumentType2["TI"] = "TI";
6
+ eIdDocumentType2["NIT"] = "NIT";
7
+ return eIdDocumentType2;
8
+ })(eIdDocumentType || {});
9
+ export var ePaymentValidator = /* @__PURE__ */ ((ePaymentValidator2) => {
10
+ ePaymentValidator2["WEBHOOK"] = "WEBHOOK";
11
+ ePaymentValidator2["TIMEOUT_TASK"] = "TIMEOUT_TASK";
12
+ ePaymentValidator2["TURNBACK"] = "TURNBACK";
13
+ ePaymentValidator2["ADMIN"] = "ADMIN";
14
+ return ePaymentValidator2;
15
+ })(ePaymentValidator || {});
16
+ export var eCacheControl = /* @__PURE__ */ ((eCacheControl2) => {
17
+ eCacheControl2["NONE"] = "no-cache, no-store, must-revalidate";
18
+ eCacheControl2["FREQUENT"] = "public, max-age=120, stale-while-revalidate=60";
19
+ eCacheControl2["NORMAL"] = "public, max-age=3600, must-revalidate";
20
+ eCacheControl2["MIDTERM"] = "public, max-age=2592000, must-revalidate";
21
+ eCacheControl2["LONGTERM"] = "public, max-age=31536000, must-revalidate";
22
+ return eCacheControl2;
23
+ })(eCacheControl || {});
24
+ export {};