@open-xamu-co/firebase-nuxt 1.2.0-next.2 → 2.0.0-next.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  Firebase nuxt
2
2
 
3
+ # [2.0.0-next.1](https://github.com/xamu-co/firebase-nuxt/compare/v1.2.0-next.2...v2.0.0-next.1) (2026-01-13)
4
+
5
+
6
+ ### Features
7
+
8
+ * configurable root instance ([def2d1a](https://github.com/xamu-co/firebase-nuxt/commit/def2d1a9c0a38fe0ddc0a3d2b225952b5c03f6bb))
9
+
10
+
11
+ ### BREAKING CHANGES
12
+
13
+ * environment as function params
14
+
3
15
  # [1.2.0-next.2](https://github.com/xamu-co/firebase-nuxt/compare/v1.2.0-next.1...v1.2.0-next.2) (2026-01-11)
4
16
 
5
17
 
package/README.md CHANGED
@@ -57,12 +57,18 @@ F_CLIENT_EMAIL=""
57
57
  # App check, site key, public
58
58
  RECAPTCHA_ENTERPRISE_SITE_KEY=
59
59
 
60
+ # CSRF protection (32 bytes)
61
+ # By default csurf uses `crypto.randomBytes(22).toString("base64")`
62
+ CSURF_SECRET=
63
+
60
64
  # Project
61
65
  ORIGIN=
62
66
  COUNTRIES_API=
63
67
  # Allow search engines to index the site
64
68
  INDEXABLE=false
65
- # Match instance locally
69
+ # ROOT instance ID
70
+ ROOT_INSTANCE="root"
71
+ # Force instance matching
66
72
  INSTANCE=""
67
73
  # App name, this will override the site name on the head
68
74
  APP_NAME=""
package/dist/module.d.mts CHANGED
@@ -8,27 +8,27 @@ import { FirebaseNuxtPublicRuntimeConfig } from '../dist/runtime/server/utils/en
8
8
  */
9
9
  interface FirebaseNuxtModuleOptions {
10
10
  /** Enable tenants */
11
- tenants: boolean;
11
+ tenants?: boolean;
12
12
  /** Enable media */
13
- media: boolean;
13
+ media?: boolean;
14
14
  /**
15
15
  * Whether the current auth is authorized to read the given instance's collection
16
16
  *
17
17
  * @server Runs server side only
18
18
  */
19
- readInstanceCollection: (collection: string, context: H3Context) => boolean;
19
+ readInstanceCollection?: (collection: string, context: H3Context) => boolean;
20
20
  /**
21
21
  * Whether the current auth is authorized to read the given collection
22
22
  *
23
23
  * @server Runs server side only
24
24
  */
25
- readCollection: (collection: string, context: H3Context) => boolean;
25
+ readCollection?: (collection: string, context: H3Context) => boolean;
26
26
  /**
27
27
  * Whether the current auth is a super user
28
28
  *
29
29
  * @server Runs server side only
30
30
  */
31
- sudo: (context: H3Context) => boolean;
31
+ sudo?: (context: H3Context) => boolean;
32
32
  }
33
33
  declare module "@nuxt/schema" {
34
34
  interface PublicRuntimeConfig extends FirebaseNuxtPublicRuntimeConfig {
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0"
6
6
  },
7
- "version": "1.2.0-next.1",
7
+ "version": "1.2.0-next.2",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -19,8 +19,8 @@ const module$1 = defineNuxtModule({
19
19
  "firebase/firestore",
20
20
  "firebase/analytics"
21
21
  ];
22
- nuxt.options.devtools.enabled = debugNuxt;
23
- nuxt.options.devtools.timeline = { enabled: debugNuxt };
22
+ nuxt.options.devtools.enabled = debugNuxt.value();
23
+ nuxt.options.devtools.timeline = { enabled: debugNuxt.value() };
24
24
  nuxt.options.experimental.asyncContext = true;
25
25
  nuxt.options.experimental.viewTransition = true;
26
26
  nuxt.options.nitro.compressPublicAssets = true;
@@ -42,12 +42,16 @@ const module$1 = defineNuxtModule({
42
42
  "pinia"
43
43
  ]
44
44
  };
45
- if (debugNuxt) {
46
- nuxt.options.devServer = { ...nuxt.options.devServer, host: "0.0.0.0", port };
45
+ if (debugNuxt.value()) {
46
+ nuxt.options.devServer = {
47
+ ...nuxt.options.devServer,
48
+ host: "0.0.0.0",
49
+ port: port.value()
50
+ };
47
51
  }
48
52
  nuxt.options.runtimeConfig.public = {
49
53
  ...nuxt.options.runtimeConfig.public,
50
- ...publicRuntimeConfig,
54
+ ...publicRuntimeConfig.value(),
51
55
  tenants: moduleOptions.tenants
52
56
  // Globally available
53
57
  };
@@ -87,26 +91,30 @@ const module$1 = defineNuxtModule({
87
91
  handler: resolve(runtimePath, "server/api/media.get")
88
92
  });
89
93
  }
90
- addServerHandler({
91
- method: "get",
92
- route: "/api/all/:collectionId",
93
- handler: resolve(runtimePath, "server/api/all-collection.get")
94
- });
95
- addServerHandler({
96
- method: "get",
97
- route: "/api/all/:collectionId/:documentId",
98
- handler: resolve(runtimePath, "server/api/all-collection-document.get")
99
- });
100
- addServerHandler({
101
- method: "get",
102
- route: "/api/instance/all/:collectionId",
103
- handler: resolve(runtimePath, "server/api/all-collection.get")
104
- });
105
- addServerHandler({
106
- method: "get",
107
- route: "/api/instance/all/:collectionId/:documentId",
108
- handler: resolve(runtimePath, "server/api/all-collection-document.get")
109
- });
94
+ if (moduleOptions.readCollection) {
95
+ addServerHandler({
96
+ method: "get",
97
+ route: "/api/all/:collectionId",
98
+ handler: resolve(runtimePath, "server/api/all-collection.get")
99
+ });
100
+ addServerHandler({
101
+ method: "get",
102
+ route: "/api/all/:collectionId/:documentId",
103
+ handler: resolve(runtimePath, "server/api/all-collection-document.get")
104
+ });
105
+ }
106
+ if (moduleOptions.readInstanceCollection) {
107
+ addServerHandler({
108
+ method: "get",
109
+ route: "/api/instance/all/:collectionId",
110
+ handler: resolve(runtimePath, "server/api/all-collection.get")
111
+ });
112
+ addServerHandler({
113
+ method: "get",
114
+ route: "/api/instance/all/:collectionId/:documentId",
115
+ handler: resolve(runtimePath, "server/api/all-collection-document.get")
116
+ });
117
+ }
110
118
  },
111
119
  moduleDependencies() {
112
120
  const { resolve } = createResolver(import.meta.url);
@@ -117,7 +125,7 @@ const module$1 = defineNuxtModule({
117
125
  defaults: {
118
126
  addCsrfTokenToEventCtx: true,
119
127
  // Run server side
120
- encryptSecret: csurfSecret || void 0
128
+ encryptSecret: csurfSecret.value() || void 0
121
129
  }
122
130
  },
123
131
  "@open-xamu-co/ui-nuxt": {
@@ -1,6 +1,7 @@
1
1
  import type { DocumentReference, Timestamp } from "firebase/firestore";
2
2
  import type { GetSharedRef } from "./user.js";
3
3
  import type { SharedDocument } from "./instance.js";
4
+ import type { FirebaseData } from "../../../functions/types/index.js";
4
5
  export interface FirebaseDocument {
5
6
  /** @automated Document path */
6
7
  id?: string;
@@ -16,11 +17,13 @@ export interface FirebaseDocument {
16
17
  */
17
18
  lock?: boolean | string[];
18
19
  }
19
- export type FromData<Data extends Record<string, any>> = {
20
- [K in keyof Data as K extends `${string}Ref` | `${string}Refs` ? never : K]: K extends `${string}At` ? string | Date | undefined : Data[K];
21
- } & {
22
- id?: string;
23
- lock?: boolean | string[];
20
+ /**
21
+ * Clear refs from data
22
+ *
23
+ * Utility types return any, so avoid them like the plague
24
+ */
25
+ export type FromData<Data extends FirebaseData, O extends keyof Data = never> = {
26
+ [K in keyof Data as K extends O ? never : K extends `${string}Ref` | `${string}Refs` ? never : K]: K extends `${string}At` ? string | Date | undefined : Data[K];
24
27
  };
25
28
  export type GetRef<T extends SharedDocument, O extends keyof T = never> = GetSharedRef<T, O> & {
26
29
  createdAt?: Timestamp;
@@ -1,14 +1,14 @@
1
1
  import type { iPagination, tLogger } from "@open-xamu-co/ui-common-types";
2
- import type { FirebaseDocument, FromData } from "./entities/base.js";
2
+ import type { FromData } from "./entities/base.js";
3
3
  export interface PseudoNode extends Record<string, any> {
4
4
  [key: `${string}Ref`]: Record<string, any>;
5
5
  [key: `${string}Refs`]: Record<string, any>[];
6
6
  }
7
- export interface PseudoDocumentSnapshot<T extends PseudoNode, R extends FirebaseDocument = FromData<T>> extends Record<string, any> {
7
+ export interface PseudoDocumentSnapshot<T extends PseudoNode, R extends FromData<T> = FromData<T>> extends Record<string, any> {
8
8
  data(): T | undefined;
9
9
  exists: boolean | (() => this is PseudoDocumentSnapshot<T, R>);
10
10
  }
11
- export interface PseudoDocumentReference<T extends PseudoNode, R extends FirebaseDocument = FromData<T>> extends Record<string, any> {
11
+ export interface PseudoDocumentReference<T extends PseudoNode, R extends FromData<T> = FromData<T>> extends Record<string, any> {
12
12
  get: () => Promise<PseudoDocumentSnapshot<T, R>>;
13
13
  converter: any;
14
14
  type: any;
@@ -1,5 +1,11 @@
1
+ import type { iNodeFnResponseStream } from "@open-xamu-co/ui-common-types";
2
+ import type { SharedDocument } from "./entities/instance.js";
1
3
  export * from "./entities/base.js";
2
4
  export * from "./entities/user.js";
3
5
  export * from "./entities/instance.js";
4
6
  export * from "./entities/logs.js";
5
7
  export * from "./firestore.js";
8
+ export type Resolve<T extends SharedDocument, P extends [T?, ...any[]] = [T]> = [
9
+ (v?: boolean | iNodeFnResponseStream<T>) => void,
10
+ ...P
11
+ ];
@@ -1,14 +1,14 @@
1
- import type { FirebaseDocument, FromData } from "../types/entities/base.js";
1
+ import type { FromData } from "../types/entities/base.js";
2
2
  import type { iSnapshotConfig, PseudoDocumentReference, PseudoDocumentSnapshot, PseudoNode } from "../types/firestore.js";
3
3
  export declare function getDocumentId(path?: string): string;
4
4
  /** Timestamp breaks nuxt */
5
- export declare function resolveSnapshotDefaults<T extends PseudoNode, R extends FirebaseDocument = FromData<T>>(id: string, node?: T): R;
5
+ export declare function resolveSnapshotDefaults<T extends PseudoNode, R extends FromData<T> = FromData<T>>(id: string, node?: T): R;
6
6
  /**
7
7
  * Get a document snapshot from a reference
8
8
  */
9
- type Resolver = <Tr extends PseudoNode, Rr extends FirebaseDocument = FromData<Tr>>(ref: PseudoDocumentReference<Tr, Rr>) => Promise<PseudoDocumentSnapshot<Tr, Rr>>;
9
+ type Resolver = <Tr extends PseudoNode, Rr extends FromData<Tr> = FromData<Tr>>(ref: PseudoDocumentReference<Tr, Rr>) => Promise<PseudoDocumentSnapshot<Tr, Rr>>;
10
10
  /**
11
11
  * Get object from firebase snapshot
12
12
  */
13
- export declare function makeResolveRefs(resolver: Resolver): <T extends PseudoNode, R extends FirebaseDocument = FromData<T>>(snapshot: PseudoDocumentSnapshot<T, R>, { level, omit }?: iSnapshotConfig, withAuth?: boolean) => Promise<R | undefined>;
13
+ export declare function makeResolveRefs(resolver: Resolver): <T extends PseudoNode, R extends FromData<T> = FromData<T>>(snapshot: PseudoDocumentSnapshot<T, R>, { level, omit }?: iSnapshotConfig, withAuth?: boolean) => Promise<R | undefined>;
14
14
  export {};
@@ -1,7 +1,5 @@
1
1
  import { type Auth } from "firebase/auth";
2
2
  import type { InstanceMember, User } from "../../client/types/index.js";
3
- interface iSessionUser extends User, Omit<InstanceMember, "user"> {
4
- }
5
3
  /**
6
4
  * Session store
7
5
  * Handle authentication state
@@ -13,7 +11,7 @@ interface iSessionUser extends User, Omit<InstanceMember, "user"> {
13
11
  export declare const useSessionStore: import("pinia").StoreDefinition<"session", Pick<{
14
12
  token: import("#app").CookieRef<string | null>;
15
13
  expiredToken: import("#app").CookieRef<boolean>;
16
- user: import("#app").CookieRef<iSessionUser | undefined>;
14
+ user: import("#app").CookieRef<(User & Omit<InstanceMember, "user">) | undefined>;
17
15
  path: import("vue").ComputedRef<string>;
18
16
  setUser: ({ createdAt, updatedAt, ...userData }: User, token: string) => void;
19
17
  unsetSession: (expiredToken?: boolean) => void;
@@ -22,7 +20,7 @@ export declare const useSessionStore: import("pinia").StoreDefinition<"session",
22
20
  }, "user" | "token" | "expiredToken">, Pick<{
23
21
  token: import("#app").CookieRef<string | null>;
24
22
  expiredToken: import("#app").CookieRef<boolean>;
25
- user: import("#app").CookieRef<iSessionUser | undefined>;
23
+ user: import("#app").CookieRef<(User & Omit<InstanceMember, "user">) | undefined>;
26
24
  path: import("vue").ComputedRef<string>;
27
25
  setUser: ({ createdAt, updatedAt, ...userData }: User, token: string) => void;
28
26
  unsetSession: (expiredToken?: boolean) => void;
@@ -31,11 +29,10 @@ export declare const useSessionStore: import("pinia").StoreDefinition<"session",
31
29
  }, "path">, Pick<{
32
30
  token: import("#app").CookieRef<string | null>;
33
31
  expiredToken: import("#app").CookieRef<boolean>;
34
- user: import("#app").CookieRef<iSessionUser | undefined>;
32
+ user: import("#app").CookieRef<(User & Omit<InstanceMember, "user">) | undefined>;
35
33
  path: import("vue").ComputedRef<string>;
36
34
  setUser: ({ createdAt, updatedAt, ...userData }: User, token: string) => void;
37
35
  unsetSession: (expiredToken?: boolean) => void;
38
36
  logout: (clientAuth?: Auth) => Promise<void>;
39
37
  remove: (clientAuth?: Auth) => Promise<void>;
40
38
  }, "remove" | "setUser" | "unsetSession" | "logout">>;
41
- export {};
@@ -1,7 +1,7 @@
1
1
  import type { QueryDocumentSnapshot } from "firebase-admin/firestore";
2
2
  import { type Request } from "firebase-functions/tasks";
3
3
  import type { tLogger } from "@open-xamu-co/ui-common-types";
4
- import type { SharedData } from "../types/entities/instance.js";
4
+ import type { SharedData } from "../types/entities/instance.js.js";
5
5
  interface OnCreatedOptions<T extends SharedData> {
6
6
  /**
7
7
  * Fields to exclude from the new document
@@ -2,7 +2,7 @@
2
2
  * AVOID NODE IMPORTS ON THIS FILE
3
3
  */
4
4
  import type { tLogger } from "@open-xamu-co/ui-common-types";
5
- import type { LogData } from "../types/entities/logs.js";
5
+ import type { LogData } from "../types/entities/logs.js.js";
6
6
  /**
7
7
  * Log to the db for later analysis
8
8
  * TODO: Bypass some firebase error codes from being logged
@@ -1,4 +1,4 @@
1
- import type { PriceData } from "../types/entities/base.js";
1
+ import type { PriceData } from "../types/entities/base.js.js";
2
2
  export interface iPriceProps extends Pick<PriceData, "price" | "base" | "iva"> {
3
3
  quantity?: number;
4
4
  }
@@ -44,7 +44,7 @@ const cachedBufferHandler = defineCachedFunction(
44
44
  });
45
45
  }
46
46
  const serverStorage = getStorage();
47
- const bucket = serverStorage.bucket(storageBucket);
47
+ const bucket = serverStorage.bucket(storageBucket.value());
48
48
  const file = bucket.file(baseAndExtension);
49
49
  const [, extension] = baseAndExtension.split(".");
50
50
  switch (extension) {
@@ -48,7 +48,7 @@ export default defineEventHandler(async (event) => {
48
48
  event.context.currentInstanceHost = cleanHost;
49
49
  const origin = getRequestHeader(event, "X-Forwarded-Origin") || getRequestHeader(event, "Origin") || `https://${cleanHost}`;
50
50
  const { hostname } = new URL(origin);
51
- let corsOrigin = production ? `https://${cleanHost}` : "*";
51
+ let corsOrigin = production.value() ? `https://${cleanHost}` : "*";
52
52
  if (instance.config?.domains?.includes(hostname)) corsOrigin = origin;
53
53
  const corsHeadersExpose = [corsHeaders, "Content-Type", "Cache-control"].join(", ");
54
54
  const corsHeadersAccept = [
@@ -14,7 +14,7 @@ export const defineConditionallyCachedEventHandler = (handler, { getKey, instanc
14
14
  } : getKey
15
15
  });
16
16
  return defineEventHandler(async (event) => {
17
- if (sudo(event.context) || debugNitro) return handler(event);
17
+ if (sudo(event.context) || debugNitro.value()) return handler(event);
18
18
  return cachedHandler(event);
19
19
  });
20
20
  };
@@ -1,4 +1,5 @@
1
1
  import type { FirebaseOptions } from "firebase/app";
2
+ import { type IntParam, type StringParam, type BooleanParam } from "firebase-functions/params";
2
3
  import { eCacheControl } from "../../functions/utils/enums.js";
3
4
  /**
4
5
  * Public runtime config
@@ -6,6 +7,7 @@ import { eCacheControl } from "../../functions/utils/enums.js";
6
7
  export interface FirebaseNuxtPublicRuntimeConfig {
7
8
  appName: string;
8
9
  production: boolean;
10
+ rootInstanceId: string;
9
11
  forcedInstanceId: string;
10
12
  indexable: boolean;
11
13
  tenants: boolean;
@@ -13,6 +15,7 @@ export interface FirebaseNuxtPublicRuntimeConfig {
13
15
  recaptchaEnterpriseKey: string;
14
16
  debugAppCheck: boolean;
15
17
  debugFirebase: boolean;
18
+ countriesUrl: string;
16
19
  cache: {
17
20
  none: eCacheControl;
18
21
  frequent: eCacheControl;
@@ -21,29 +24,41 @@ export interface FirebaseNuxtPublicRuntimeConfig {
21
24
  longterm: eCacheControl;
22
25
  };
23
26
  }
24
- export declare const port: number;
25
- export declare const production: boolean;
26
- export declare const indexable: boolean;
27
- export declare const origin: string;
28
- export declare const forcedInstanceId: string;
29
- export declare const appName: string;
30
- export declare const debugNuxt: boolean;
31
- export declare const debugNitro: boolean;
32
- export declare const debugCSS: boolean;
33
- export declare const debugAppCheck: boolean;
34
- export declare const debugFirebase: boolean;
35
- export declare const storageBucket: string;
36
- export declare const projectId: string;
37
- export declare const privateKey: string;
38
- export declare const clientEmail: string;
27
+ export declare const port: Pick<IntParam, "value">;
28
+ export declare const production: {
29
+ value(): boolean;
30
+ };
31
+ export declare const indexable: BooleanParam;
32
+ export declare const origin: StringParam;
33
+ export declare const countriesUrl: StringParam;
34
+ export declare const rootInstanceId: Pick<StringParam, "value">;
35
+ export declare const forcedInstanceId: StringParam;
36
+ export declare const appName: StringParam;
37
+ export declare const debugNuxt: Pick<BooleanParam, "value">;
38
+ export declare const debugNitro: Pick<BooleanParam, "value">;
39
+ export declare const debugCSS: Pick<BooleanParam, "value">;
40
+ export declare const debugAppCheck: Pick<BooleanParam, "value">;
41
+ export declare const debugFirebase: Pick<BooleanParam, "value">;
42
+ export declare const storageBucket: StringParam;
43
+ export declare const projectId: StringParam;
44
+ export declare const privateKey: StringParam;
45
+ export declare const clientEmail: StringParam;
39
46
  /** App check, public key */
40
- export declare const recaptchaEnterpriseKey: string;
47
+ export declare const recaptchaEnterpriseKey: StringParam;
41
48
  /**
42
49
  * CSurf encryption secret
43
50
  * Required for CSRF protected routes
44
51
  */
45
- export declare const csurfSecret: string;
52
+ export declare const csurfSecret: StringParam;
53
+ /**
54
+ * Firebase client data
55
+ */
56
+ export declare const firebaseConfig: {
57
+ value(): FirebaseNuxtPublicRuntimeConfig["firebaseConfig"];
58
+ };
46
59
  /**
47
60
  * Public runtime config
48
61
  */
49
- export declare const publicRuntimeConfig: FirebaseNuxtPublicRuntimeConfig;
62
+ export declare const publicRuntimeConfig: {
63
+ value(): FirebaseNuxtPublicRuntimeConfig;
64
+ };
@@ -1,50 +1,80 @@
1
- import { defineString, defineBoolean, defineInt } from "firebase-functions/params";
1
+ import {
2
+ defineString,
3
+ defineBoolean,
4
+ defineInt
5
+ } from "firebase-functions/params";
2
6
  import { eCacheControl } from "../../functions/utils/enums.js";
3
7
  const environment = defineString("NODE_ENV", { default: "development" });
4
- export const port = defineInt("PORT", { default: 3e3 }).value() || 3e3;
5
- export const production = environment.equals("production").value();
6
- export const indexable = defineBoolean("INDEXABLE", { default: false }).value();
7
- export const origin = defineString("ORIGIN").value();
8
- export const forcedInstanceId = defineString("INSTANCE").value();
9
- export const appName = defineString("APP_NAME").value();
10
- export const debugNuxt = !production && defineBoolean("DEBUG_NUXT", { default: false }).value();
11
- export const debugNitro = !production && defineBoolean("DEBUG_NITRO", { default: false }).value();
12
- export const debugCSS = !production && defineBoolean("DEBUG_CSS", { default: false }).value();
13
- export const debugAppCheck = !production && defineBoolean("DEBUG_APP_CHECK", { default: false }).value();
14
- export const debugFirebase = !production && defineBoolean("DEBUG_FIREBASE", { default: false }).value();
15
- export const storageBucket = defineString("F_STORAGE_BUCKET").value();
16
- export const projectId = defineString("F_PROJECT_ID").value();
17
- export const privateKey = defineString("F_PRIVATE_KEY").value();
18
- export const clientEmail = defineString("F_CLIENT_EMAIL").value();
19
- export const recaptchaEnterpriseKey = defineString("RECAPTCHA_ENTERPRISE_SITE_KEY").value();
20
- export const csurfSecret = defineString("CSURF_SECRET").value();
21
- const firebaseConfig = {
22
- projectId,
23
- apiKey: defineString("F_API_KEY").value(),
24
- authDomain: defineString("F_AUTH_DOMAIN").value(),
25
- storageBucket,
26
- messagingSenderId: defineString("F_MESSAGING_SENDER_ID").value(),
27
- appId: defineString("F_APP_ID").value(),
28
- measurementId: defineString("F_MEASUREMENT_ID").value()
8
+ export const port = {
9
+ value: () => defineInt("PORT", { default: 3e3 }).value() || 3e3
10
+ };
11
+ export const production = environment.equals("production");
12
+ export const indexable = defineBoolean("INDEXABLE", { default: false });
13
+ export const origin = defineString("ORIGIN");
14
+ export const countriesUrl = defineString("COUNTRIES_API");
15
+ export const rootInstanceId = {
16
+ value: () => defineString("ROOT_INSTANCE", { default: "root" }).value() || "root"
17
+ };
18
+ export const forcedInstanceId = defineString("INSTANCE");
19
+ export const appName = defineString("APP_NAME");
20
+ export const debugNuxt = {
21
+ value: () => !production.value() && defineBoolean("DEBUG_NUXT", { default: false }).value()
22
+ };
23
+ export const debugNitro = {
24
+ value: () => !production.value() && defineBoolean("DEBUG_NITRO", { default: false }).value()
25
+ };
26
+ export const debugCSS = {
27
+ value: () => !production.value() && defineBoolean("DEBUG_CSS", { default: false }).value()
28
+ };
29
+ export const debugAppCheck = {
30
+ value: () => !production.value() && defineBoolean("DEBUG_APP_CHECK", { default: false }).value()
31
+ };
32
+ export const debugFirebase = {
33
+ value: () => !production.value() && defineBoolean("DEBUG_FIREBASE", { default: false }).value()
34
+ };
35
+ export const storageBucket = defineString("F_STORAGE_BUCKET");
36
+ export const projectId = defineString("F_PROJECT_ID");
37
+ export const privateKey = defineString("F_PRIVATE_KEY");
38
+ export const clientEmail = defineString("F_CLIENT_EMAIL");
39
+ export const recaptchaEnterpriseKey = defineString("RECAPTCHA_ENTERPRISE_SITE_KEY");
40
+ export const csurfSecret = defineString("CSURF_SECRET");
41
+ export const firebaseConfig = {
42
+ value() {
43
+ return {
44
+ projectId: projectId.value(),
45
+ apiKey: defineString("F_API_KEY").value(),
46
+ authDomain: defineString("F_AUTH_DOMAIN").value(),
47
+ storageBucket: storageBucket.value(),
48
+ messagingSenderId: defineString("F_MESSAGING_SENDER_ID").value(),
49
+ appId: defineString("F_APP_ID").value(),
50
+ measurementId: defineString("F_MEASUREMENT_ID").value()
51
+ };
52
+ }
29
53
  };
30
54
  export const publicRuntimeConfig = {
31
- // App
32
- appName,
33
- production,
34
- forcedInstanceId,
35
- indexable,
36
- // Firebase
37
- firebaseConfig,
38
- recaptchaEnterpriseKey,
39
- debugAppCheck,
40
- debugFirebase,
41
- // Utils
42
- cache: {
43
- none: eCacheControl.NONE,
44
- frequent: eCacheControl.FREQUENT,
45
- normal: eCacheControl.NORMAL,
46
- midterm: eCacheControl.MIDTERM,
47
- longterm: eCacheControl.LONGTERM
48
- },
49
- tenants: false
55
+ value() {
56
+ return {
57
+ // App
58
+ appName: appName.value(),
59
+ production: production.value(),
60
+ rootInstanceId: rootInstanceId.value(),
61
+ forcedInstanceId: forcedInstanceId.value(),
62
+ indexable: indexable.value(),
63
+ // Firebase
64
+ firebaseConfig: firebaseConfig.value(),
65
+ recaptchaEnterpriseKey: recaptchaEnterpriseKey.value(),
66
+ debugAppCheck: debugAppCheck.value(),
67
+ debugFirebase: debugFirebase.value(),
68
+ countriesUrl: countriesUrl.value(),
69
+ // Utils
70
+ cache: {
71
+ none: eCacheControl.NONE,
72
+ frequent: eCacheControl.FREQUENT,
73
+ normal: eCacheControl.NORMAL,
74
+ midterm: eCacheControl.MIDTERM,
75
+ longterm: eCacheControl.LONGTERM
76
+ },
77
+ tenants: false
78
+ };
79
+ }
50
80
  };
@@ -3,7 +3,11 @@ import { clientEmail, privateKey, projectId } from "../utils/environment.js";
3
3
  import { makeLogger } from "../../client/utils/logger.js";
4
4
  import { getFirebase } from "../../functions/utils/firebase.js";
5
5
  export function getServerFirebase(at = "Unknown") {
6
- const credential = cert({ projectId, privateKey, clientEmail });
6
+ const credential = cert({
7
+ projectId: projectId.value(),
8
+ privateKey: privateKey.value(),
9
+ clientEmail: clientEmail.value()
10
+ });
7
11
  return getFirebase(at, { credential });
8
12
  }
9
13
  export function apiLogger(event, ...args) {
@@ -1,8 +1,7 @@
1
1
  import { type H3Event, type EventHandlerRequest } from "h3";
2
- import { type DocumentData, DocumentSnapshot, Query } from "firebase-admin/firestore";
3
- import { QuerySnapshot } from "@google-cloud/firestore";
2
+ import { type DocumentData, DocumentSnapshot, QuerySnapshot, Query } from "firebase-admin/firestore";
4
3
  import type { iPage, iPageEdge } from "@open-xamu-co/ui-common-types";
5
- import type { PseudoNode, FirebaseDocument, iSnapshotConfig } from "../../client/types/index.js";
4
+ import type { PseudoNode, FirebaseDocument, iSnapshotConfig, FromData } from "../../client/types/index.js";
6
5
  /**
7
6
  * Logging for debugging purposes on server
8
7
  */
@@ -10,11 +9,11 @@ export declare function debugFirebaseServer<T extends EventHandlerRequest>(event
10
9
  /**
11
10
  * This one is used on api endpoints
12
11
  */
13
- export declare function resolveServerDocumentRefs<T extends PseudoNode, R extends FirebaseDocument = FirebaseDocument>(event: H3Event, snapshot?: DocumentSnapshot<T, R>, collection?: string, withAuth?: boolean): Promise<R | undefined>;
12
+ export declare function resolveServerDocumentRefs<T extends PseudoNode, R extends FromData<T> = FromData<T>>(event: H3Event, snapshot?: DocumentSnapshot<T, R>, collection?: string, withAuth?: boolean): Promise<R | undefined>;
14
13
  /**
15
14
  * Resolve general refs
16
15
  */
17
- export declare function resolveServerRefs<T extends PseudoNode, R extends FirebaseDocument = FirebaseDocument>(snapshot: DocumentSnapshot<T, R>, config?: iSnapshotConfig, withAuth?: boolean): Promise<R | undefined>;
16
+ export declare function resolveServerRefs<T extends PseudoNode, R extends FromData<T> = FromData<T>>(snapshot: DocumentSnapshot<T, R>, config?: iSnapshotConfig, withAuth?: boolean): Promise<R | undefined>;
18
17
  export declare function mapEdges<T extends Record<string, any>>(collectionSnapshot: QuerySnapshot<T>, encoder: (v: any) => string, snapshotConfig: iSnapshotConfig): Promise<iPageEdge<FirebaseDocument, string>[]>;
19
18
  export declare function getOrderedQuery<T extends EventHandlerRequest>(event: H3Event<T>, query: Query): Query;
20
19
  /**
@@ -10,7 +10,7 @@ const encodeCursor = (ref) => {
10
10
  return Buffer.from(ref.path).toString("base64");
11
11
  };
12
12
  export function debugFirebaseServer(event, mss, ...args) {
13
- if (debugFirebase && import.meta.server) {
13
+ if (import.meta.server && debugFirebase.value()) {
14
14
  const url = getRequestURL(event);
15
15
  console.group("\x1B[34m%s\x1B[0m", url);
16
16
  console.log(`${mss},`, ...args);
@@ -18,4 +18,4 @@ export declare const getInstance: (_: any, fullHost: string) => Promise<Instance
18
18
  *
19
19
  * @cache 1 hour
20
20
  */
21
- export declare const getRootInstance: (_: any) => Promise<Instance | undefined>;
21
+ export declare const getRootInstance: (...args: any[]) => Promise<unknown>;
@@ -1,10 +1,11 @@
1
1
  import { createError } from "h3";
2
2
  import { defineCachedFunction } from "nitropack/runtime";
3
- import { production, forcedInstanceId } from "../utils/environment.js";
4
3
  import { debugFirebaseServer, resolveServerDocumentRefs } from "./firestore.js";
5
4
  import { getServerFirebase } from "./firebase.js";
5
+ import { useRuntimeConfig } from "#imports";
6
6
  export const getInstance = defineCachedFunction(
7
7
  async (event, fullHost) => {
8
+ const { production, forcedInstanceId } = useRuntimeConfig().public;
8
9
  const { firebaseFirestore } = getServerFirebase("api:getInstance");
9
10
  const instancesRef = firebaseFirestore.collection("instances");
10
11
  let snapshot;
@@ -53,16 +54,20 @@ export const getInstance = defineCachedFunction(
53
54
  );
54
55
  export const getRootInstance = defineCachedFunction(
55
56
  async (event) => {
57
+ const { rootInstanceId } = useRuntimeConfig().public;
56
58
  const { firebaseFirestore } = getServerFirebase("api:getRootInstance");
57
59
  const instancesRef = firebaseFirestore.collection("instances");
58
60
  debugFirebaseServer(event, "middleware:getRootInstance");
59
- const snapshot = await instancesRef.doc("root").get();
61
+ const snapshot = await instancesRef.doc(rootInstanceId).get();
60
62
  return resolveServerDocumentRefs(event, snapshot, "instances", false) || {};
61
63
  },
62
64
  {
63
65
  name: "getRootInstance",
64
66
  maxAge: 60 * 60 * 24,
65
67
  // 1 day
66
- getKey: (_) => "root"
68
+ getKey: (_) => {
69
+ const { rootInstanceId } = useRuntimeConfig().public;
70
+ return rootInstanceId;
71
+ }
67
72
  }
68
73
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-xamu-co/firebase-nuxt",
3
- "version": "1.2.0-next.2",
3
+ "version": "2.0.0-next.1",
4
4
  "description": "Nuxt 3 module for the xamu project",
5
5
  "author": "@xamu-co",
6
6
  "type": "module",