@ga-components/logger 1.0.3 → 1.0.4

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/dist/index.d.mts CHANGED
@@ -28,8 +28,10 @@ interface LoggerConfig {
28
28
  declare class Logger {
29
29
  private config;
30
30
  private initialized;
31
+ private fetchIntercepted;
31
32
  init(config: LoggerConfig): void;
32
33
  setUserId(userId: string | null): void;
34
+ interceptFetch(): void;
33
35
  private send;
34
36
  info(message: string, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
35
37
  warn(message: string, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
package/dist/index.d.ts CHANGED
@@ -28,8 +28,10 @@ interface LoggerConfig {
28
28
  declare class Logger {
29
29
  private config;
30
30
  private initialized;
31
+ private fetchIntercepted;
31
32
  init(config: LoggerConfig): void;
32
33
  setUserId(userId: string | null): void;
34
+ interceptFetch(): void;
33
35
  private send;
34
36
  info(message: string, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
35
37
  warn(message: string, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@ var Logger = class {
59
59
  constructor() {
60
60
  this.config = null;
61
61
  this.initialized = false;
62
+ this.fetchIntercepted = false;
62
63
  }
63
64
  init(config) {
64
65
  this.config = config;
@@ -73,6 +74,33 @@ var Logger = class {
73
74
  }
74
75
  this.config.userId = userId;
75
76
  }
77
+ // Auto intercept semua fetch
78
+ interceptFetch() {
79
+ if (this.fetchIntercepted) return;
80
+ const originalFetch = window.fetch;
81
+ window.fetch = async (...args) => {
82
+ const url = typeof args[0] === "string" ? args[0] : args[0].url;
83
+ const method = (args[1]?.method ?? "GET").toUpperCase();
84
+ const endpoint = `${method} ${url}`;
85
+ try {
86
+ const response = await originalFetch(...args);
87
+ if (!response.ok) {
88
+ this.send("error", `HTTP ${response.status} ${endpoint}`, { endpoint, status: response.status });
89
+ }
90
+ return response;
91
+ } catch (error) {
92
+ this.send(
93
+ "error",
94
+ `Network error ${endpoint}`,
95
+ { endpoint },
96
+ error instanceof Error ? error : new Error(String(error))
97
+ );
98
+ throw error;
99
+ }
100
+ };
101
+ this.fetchIntercepted = true;
102
+ console.info("[ga-logger] fetch intercepted \u2705");
103
+ }
76
104
  async send(level, message, payload = {}, error, endpoint) {
77
105
  if (!this.initialized || !this.config) {
78
106
  console.warn("[ga-logger] not initialized. Call logger.init() first.");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/logger.ts","../src/config/firebase.ts"],"sourcesContent":["export { logger } from \"./core/logger\";\nexport type { LogEntry, LoggerConfig, LogLevel, LogEnv } from \"./types\";\n","import { collection, addDoc, Timestamp } from \"firebase/firestore\";\nimport { initFirebase, getDb } from \"../config/firebase\";\nimport type { LogEntry, LogLevel, LoggerConfig } from \"../types\";\n\nconst sessionId = `sess_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n\nclass Logger {\n private config: LoggerConfig | null = null;\n private initialized = false;\n\n init(config: LoggerConfig) {\n this.config = config;\n initFirebase(config);\n this.initialized = true;\n console.info(\"[ga-logger] initialized —\", config.env);\n }\n\n setUserId(userId: string | null) {\n if (!this.config) {\n console.warn(\"[ga-logger] not initialized. Call logger.init() first.\");\n return;\n }\n this.config.userId = userId;\n }\n\n private async send(\n level: LogLevel,\n message: string,\n payload: Record<string, unknown> = {},\n error?: Error,\n endpoint?: string,\n ) {\n if (!this.initialized || !this.config) {\n console.warn(\"[ga-logger] not initialized. Call logger.init() first.\");\n return;\n }\n\n const entry: LogEntry = {\n timestamp: new Date(),\n level,\n message,\n env: this.config.env,\n userId: this.config.userId ?? null,\n sessionId,\n page: typeof window !== \"undefined\" ? window.location.pathname : \"\",\n stackTrace: error?.stack ?? null,\n payload,\n repo: this.config.repo,\n endpoint: endpoint ?? null,\n };\n try {\n const db = getDb();\n await addDoc(collection(db, \"logs\"), {\n ...entry,\n timestamp: Timestamp.fromDate(entry.timestamp),\n });\n } catch (e) {\n console.error(\"[ga-logger] failed to send log:\", e);\n }\n }\n\n info(message: string, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"info\", message, payload, undefined, endpoint);\n }\n\n warn(message: string, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"warn\", message, payload, undefined, endpoint);\n }\n\n error(message: string, error?: Error, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"error\", message, payload, error, endpoint);\n }\n}\n\nexport const logger = new Logger();","import { initializeApp, getApps, FirebaseApp } from \"firebase/app\";\nimport { getFirestore, Firestore } from \"firebase/firestore\";\nimport { LoggerConfig } from \"../types\";\n\nlet app: FirebaseApp;\nlet db: Firestore;\n\nexport const initFirebase = (config: LoggerConfig) => {\n if (!getApps().length) {\n app = initializeApp(\n {\n apiKey: config.apiKey,\n authDomain: config.authDomain,\n projectId: config.projectId,\n storageBucket: config.storageBucket,\n messagingSenderId: config.messagingSenderId,\n appId: config.appId,\n },\n \"ga-logger\",\n );\n } else {\n app = getApps()[0];\n }\n\n db = getFirestore(app);\n return db;\n};\n\nexport const getDb = () => db;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,oBAA8C;;;ACA9C,iBAAoD;AACpD,uBAAwC;AAGxC,IAAI;AACJ,IAAI;AAEG,IAAM,eAAe,CAAC,WAAyB;AAClD,MAAI,KAAC,oBAAQ,EAAE,QAAQ;AACnB,cAAM;AAAA,MACF;AAAA,QACI,QAAQ,OAAO;AAAA,QACf,YAAY,OAAO;AAAA,QACnB,WAAW,OAAO;AAAA,QAClB,eAAe,OAAO;AAAA,QACtB,mBAAmB,OAAO;AAAA,QAC1B,OAAO,OAAO;AAAA,MAClB;AAAA,MACA;AAAA,IACJ;AAAA,EACJ,OAAO;AACH,cAAM,oBAAQ,EAAE,CAAC;AAAA,EACrB;AAEA,WAAK,+BAAa,GAAG;AACrB,SAAO;AACX;AAEO,IAAM,QAAQ,MAAM;;;ADxB3B,IAAM,YAAY,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAE9E,IAAM,SAAN,MAAa;AAAA,EAAb;AACI,SAAQ,SAA8B;AACtC,SAAQ,cAAc;AAAA;AAAA,EAEtB,KAAK,QAAsB;AACvB,SAAK,SAAS;AACd,iBAAa,MAAM;AACnB,SAAK,cAAc;AACnB,YAAQ,KAAK,kCAA6B,OAAO,GAAG;AAAA,EACxD;AAAA,EAEA,UAAU,QAAuB;AAC7B,QAAI,CAAC,KAAK,QAAQ;AACd,cAAQ,KAAK,wDAAwD;AACrE;AAAA,IACJ;AACA,SAAK,OAAO,SAAS;AAAA,EACzB;AAAA,EAEA,MAAc,KACV,OACA,SACA,UAAmC,CAAC,GACpC,OACA,UACF;AACE,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,QAAQ;AACnC,cAAQ,KAAK,wDAAwD;AACrE;AAAA,IACJ;AAEA,UAAM,QAAkB;AAAA,MACpB,WAAW,oBAAI,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA,KAAK,KAAK,OAAO;AAAA,MACjB,QAAQ,KAAK,OAAO,UAAU;AAAA,MAC9B;AAAA,MACA,MAAM,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AAAA,MACjE,YAAY,OAAO,SAAS;AAAA,MAC5B;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,UAAU,YAAY;AAAA,IAC1B;AACA,QAAI;AACA,YAAMC,MAAK,MAAM;AACjB,gBAAM,8BAAO,8BAAWA,KAAI,MAAM,GAAG;AAAA,QACjC,GAAG;AAAA,QACH,WAAW,4BAAU,SAAS,MAAM,SAAS;AAAA,MACjD,CAAC;AAAA,IACL,SAAS,GAAG;AACR,cAAQ,MAAM,mCAAmC,CAAC;AAAA,IACtD;AAAA,EACJ;AAAA,EAEA,KAAK,SAAiB,SAAmC,UAAmB;AACxE,WAAO,KAAK,KAAK,QAAQ,SAAS,SAAS,QAAW,QAAQ;AAAA,EAClE;AAAA,EAEA,KAAK,SAAiB,SAAmC,UAAmB;AACxE,WAAO,KAAK,KAAK,QAAQ,SAAS,SAAS,QAAW,QAAQ;AAAA,EAClE;AAAA,EAEA,MAAM,SAAiB,OAAe,SAAmC,UAAmB;AACxF,WAAO,KAAK,KAAK,SAAS,SAAS,SAAS,OAAO,QAAQ;AAAA,EAC/D;AACJ;AAEO,IAAM,SAAS,IAAI,OAAO;","names":["import_firestore","db"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/logger.ts","../src/config/firebase.ts"],"sourcesContent":["export { logger } from \"./core/logger\";\nexport type { LogEntry, LoggerConfig, LogLevel, LogEnv } from \"./types\";\n","import { collection, addDoc, Timestamp } from \"firebase/firestore\";\nimport { initFirebase, getDb } from \"../config/firebase\";\nimport type { LogEntry, LogLevel, LoggerConfig } from \"../types\";\n\nconst sessionId = `sess_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n\nclass Logger {\n private config: LoggerConfig | null = null;\n private initialized = false;\n private fetchIntercepted = false;\n\n init(config: LoggerConfig) {\n this.config = config;\n initFirebase(config);\n this.initialized = true;\n console.info(\"[ga-logger] initialized —\", config.env);\n }\n\n setUserId(userId: string | null) {\n if (!this.config) {\n console.warn(\"[ga-logger] not initialized. Call logger.init() first.\");\n return;\n }\n this.config.userId = userId;\n }\n\n // Auto intercept semua fetch\n interceptFetch() {\n if (this.fetchIntercepted) return;\n const originalFetch = window.fetch;\n\n window.fetch = async (...args) => {\n const url = typeof args[0] === \"string\" ? args[0] : (args[0] as Request).url;\n const method = (args[1]?.method ?? \"GET\").toUpperCase();\n const endpoint = `${method} ${url}`;\n\n try {\n const response = await originalFetch(...args);\n\n // Auto log jika 4xx atau 5xx\n if (!response.ok) {\n this.send(\"error\", `HTTP ${response.status} ${endpoint}`, { endpoint, status: response.status });\n }\n\n return response;\n } catch (error) {\n // Network error / timeout\n this.send(\n \"error\",\n `Network error ${endpoint}`,\n { endpoint },\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n };\n\n this.fetchIntercepted = true;\n console.info(\"[ga-logger] fetch intercepted ✅\");\n }\n\n private async send(\n level: LogLevel,\n message: string,\n payload: Record<string, unknown> = {},\n error?: Error,\n endpoint?: string,\n ) {\n if (!this.initialized || !this.config) {\n console.warn(\"[ga-logger] not initialized. Call logger.init() first.\");\n return;\n }\n\n const entry: LogEntry = {\n timestamp: new Date(),\n level,\n message,\n env: this.config.env,\n userId: this.config.userId ?? null,\n sessionId,\n page: typeof window !== \"undefined\" ? window.location.pathname : \"\",\n stackTrace: error?.stack ?? null,\n payload,\n repo: this.config.repo,\n endpoint: endpoint ?? null,\n };\n try {\n const db = getDb();\n await addDoc(collection(db, \"logs\"), {\n ...entry,\n timestamp: Timestamp.fromDate(entry.timestamp),\n });\n } catch (e) {\n console.error(\"[ga-logger] failed to send log:\", e);\n }\n }\n\n info(message: string, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"info\", message, payload, undefined, endpoint);\n }\n\n warn(message: string, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"warn\", message, payload, undefined, endpoint);\n }\n\n error(message: string, error?: Error, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"error\", message, payload, error, endpoint);\n }\n}\n\nexport const logger = new Logger();","import { initializeApp, getApps, FirebaseApp } from \"firebase/app\";\nimport { getFirestore, Firestore } from \"firebase/firestore\";\nimport { LoggerConfig } from \"../types\";\n\nlet app: FirebaseApp;\nlet db: Firestore;\n\nexport const initFirebase = (config: LoggerConfig) => {\n if (!getApps().length) {\n app = initializeApp(\n {\n apiKey: config.apiKey,\n authDomain: config.authDomain,\n projectId: config.projectId,\n storageBucket: config.storageBucket,\n messagingSenderId: config.messagingSenderId,\n appId: config.appId,\n },\n \"ga-logger\",\n );\n } else {\n app = getApps()[0];\n }\n\n db = getFirestore(app);\n return db;\n};\n\nexport const getDb = () => db;\n"],"mappings":"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","names":["import_firestore","db"]}
package/dist/index.mjs CHANGED
@@ -33,6 +33,7 @@ var Logger = class {
33
33
  constructor() {
34
34
  this.config = null;
35
35
  this.initialized = false;
36
+ this.fetchIntercepted = false;
36
37
  }
37
38
  init(config) {
38
39
  this.config = config;
@@ -47,6 +48,33 @@ var Logger = class {
47
48
  }
48
49
  this.config.userId = userId;
49
50
  }
51
+ // Auto intercept semua fetch
52
+ interceptFetch() {
53
+ if (this.fetchIntercepted) return;
54
+ const originalFetch = window.fetch;
55
+ window.fetch = async (...args) => {
56
+ const url = typeof args[0] === "string" ? args[0] : args[0].url;
57
+ const method = (args[1]?.method ?? "GET").toUpperCase();
58
+ const endpoint = `${method} ${url}`;
59
+ try {
60
+ const response = await originalFetch(...args);
61
+ if (!response.ok) {
62
+ this.send("error", `HTTP ${response.status} ${endpoint}`, { endpoint, status: response.status });
63
+ }
64
+ return response;
65
+ } catch (error) {
66
+ this.send(
67
+ "error",
68
+ `Network error ${endpoint}`,
69
+ { endpoint },
70
+ error instanceof Error ? error : new Error(String(error))
71
+ );
72
+ throw error;
73
+ }
74
+ };
75
+ this.fetchIntercepted = true;
76
+ console.info("[ga-logger] fetch intercepted \u2705");
77
+ }
50
78
  async send(level, message, payload = {}, error, endpoint) {
51
79
  if (!this.initialized || !this.config) {
52
80
  console.warn("[ga-logger] not initialized. Call logger.init() first.");
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/logger.ts","../src/config/firebase.ts"],"sourcesContent":["import { collection, addDoc, Timestamp } from \"firebase/firestore\";\nimport { initFirebase, getDb } from \"../config/firebase\";\nimport type { LogEntry, LogLevel, LoggerConfig } from \"../types\";\n\nconst sessionId = `sess_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n\nclass Logger {\n private config: LoggerConfig | null = null;\n private initialized = false;\n\n init(config: LoggerConfig) {\n this.config = config;\n initFirebase(config);\n this.initialized = true;\n console.info(\"[ga-logger] initialized —\", config.env);\n }\n\n setUserId(userId: string | null) {\n if (!this.config) {\n console.warn(\"[ga-logger] not initialized. Call logger.init() first.\");\n return;\n }\n this.config.userId = userId;\n }\n\n private async send(\n level: LogLevel,\n message: string,\n payload: Record<string, unknown> = {},\n error?: Error,\n endpoint?: string,\n ) {\n if (!this.initialized || !this.config) {\n console.warn(\"[ga-logger] not initialized. Call logger.init() first.\");\n return;\n }\n\n const entry: LogEntry = {\n timestamp: new Date(),\n level,\n message,\n env: this.config.env,\n userId: this.config.userId ?? null,\n sessionId,\n page: typeof window !== \"undefined\" ? window.location.pathname : \"\",\n stackTrace: error?.stack ?? null,\n payload,\n repo: this.config.repo,\n endpoint: endpoint ?? null,\n };\n try {\n const db = getDb();\n await addDoc(collection(db, \"logs\"), {\n ...entry,\n timestamp: Timestamp.fromDate(entry.timestamp),\n });\n } catch (e) {\n console.error(\"[ga-logger] failed to send log:\", e);\n }\n }\n\n info(message: string, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"info\", message, payload, undefined, endpoint);\n }\n\n warn(message: string, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"warn\", message, payload, undefined, endpoint);\n }\n\n error(message: string, error?: Error, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"error\", message, payload, error, endpoint);\n }\n}\n\nexport const logger = new Logger();","import { initializeApp, getApps, FirebaseApp } from \"firebase/app\";\nimport { getFirestore, Firestore } from \"firebase/firestore\";\nimport { LoggerConfig } from \"../types\";\n\nlet app: FirebaseApp;\nlet db: Firestore;\n\nexport const initFirebase = (config: LoggerConfig) => {\n if (!getApps().length) {\n app = initializeApp(\n {\n apiKey: config.apiKey,\n authDomain: config.authDomain,\n projectId: config.projectId,\n storageBucket: config.storageBucket,\n messagingSenderId: config.messagingSenderId,\n appId: config.appId,\n },\n \"ga-logger\",\n );\n } else {\n app = getApps()[0];\n }\n\n db = getFirestore(app);\n return db;\n};\n\nexport const getDb = () => db;\n"],"mappings":";AAAA,SAAS,YAAY,QAAQ,iBAAiB;;;ACA9C,SAAS,eAAe,eAA4B;AACpD,SAAS,oBAA+B;AAGxC,IAAI;AACJ,IAAI;AAEG,IAAM,eAAe,CAAC,WAAyB;AAClD,MAAI,CAAC,QAAQ,EAAE,QAAQ;AACnB,UAAM;AAAA,MACF;AAAA,QACI,QAAQ,OAAO;AAAA,QACf,YAAY,OAAO;AAAA,QACnB,WAAW,OAAO;AAAA,QAClB,eAAe,OAAO;AAAA,QACtB,mBAAmB,OAAO;AAAA,QAC1B,OAAO,OAAO;AAAA,MAClB;AAAA,MACA;AAAA,IACJ;AAAA,EACJ,OAAO;AACH,UAAM,QAAQ,EAAE,CAAC;AAAA,EACrB;AAEA,OAAK,aAAa,GAAG;AACrB,SAAO;AACX;AAEO,IAAM,QAAQ,MAAM;;;ADxB3B,IAAM,YAAY,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAE9E,IAAM,SAAN,MAAa;AAAA,EAAb;AACI,SAAQ,SAA8B;AACtC,SAAQ,cAAc;AAAA;AAAA,EAEtB,KAAK,QAAsB;AACvB,SAAK,SAAS;AACd,iBAAa,MAAM;AACnB,SAAK,cAAc;AACnB,YAAQ,KAAK,kCAA6B,OAAO,GAAG;AAAA,EACxD;AAAA,EAEA,UAAU,QAAuB;AAC7B,QAAI,CAAC,KAAK,QAAQ;AACd,cAAQ,KAAK,wDAAwD;AACrE;AAAA,IACJ;AACA,SAAK,OAAO,SAAS;AAAA,EACzB;AAAA,EAEA,MAAc,KACV,OACA,SACA,UAAmC,CAAC,GACpC,OACA,UACF;AACE,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,QAAQ;AACnC,cAAQ,KAAK,wDAAwD;AACrE;AAAA,IACJ;AAEA,UAAM,QAAkB;AAAA,MACpB,WAAW,oBAAI,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA,KAAK,KAAK,OAAO;AAAA,MACjB,QAAQ,KAAK,OAAO,UAAU;AAAA,MAC9B;AAAA,MACA,MAAM,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AAAA,MACjE,YAAY,OAAO,SAAS;AAAA,MAC5B;AAAA,MACA,MAAM,KAAK,OAAO;AAAA,MAClB,UAAU,YAAY;AAAA,IAC1B;AACA,QAAI;AACA,YAAMA,MAAK,MAAM;AACjB,YAAM,OAAO,WAAWA,KAAI,MAAM,GAAG;AAAA,QACjC,GAAG;AAAA,QACH,WAAW,UAAU,SAAS,MAAM,SAAS;AAAA,MACjD,CAAC;AAAA,IACL,SAAS,GAAG;AACR,cAAQ,MAAM,mCAAmC,CAAC;AAAA,IACtD;AAAA,EACJ;AAAA,EAEA,KAAK,SAAiB,SAAmC,UAAmB;AACxE,WAAO,KAAK,KAAK,QAAQ,SAAS,SAAS,QAAW,QAAQ;AAAA,EAClE;AAAA,EAEA,KAAK,SAAiB,SAAmC,UAAmB;AACxE,WAAO,KAAK,KAAK,QAAQ,SAAS,SAAS,QAAW,QAAQ;AAAA,EAClE;AAAA,EAEA,MAAM,SAAiB,OAAe,SAAmC,UAAmB;AACxF,WAAO,KAAK,KAAK,SAAS,SAAS,SAAS,OAAO,QAAQ;AAAA,EAC/D;AACJ;AAEO,IAAM,SAAS,IAAI,OAAO;","names":["db"]}
1
+ {"version":3,"sources":["../src/core/logger.ts","../src/config/firebase.ts"],"sourcesContent":["import { collection, addDoc, Timestamp } from \"firebase/firestore\";\nimport { initFirebase, getDb } from \"../config/firebase\";\nimport type { LogEntry, LogLevel, LoggerConfig } from \"../types\";\n\nconst sessionId = `sess_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n\nclass Logger {\n private config: LoggerConfig | null = null;\n private initialized = false;\n private fetchIntercepted = false;\n\n init(config: LoggerConfig) {\n this.config = config;\n initFirebase(config);\n this.initialized = true;\n console.info(\"[ga-logger] initialized —\", config.env);\n }\n\n setUserId(userId: string | null) {\n if (!this.config) {\n console.warn(\"[ga-logger] not initialized. Call logger.init() first.\");\n return;\n }\n this.config.userId = userId;\n }\n\n // Auto intercept semua fetch\n interceptFetch() {\n if (this.fetchIntercepted) return;\n const originalFetch = window.fetch;\n\n window.fetch = async (...args) => {\n const url = typeof args[0] === \"string\" ? args[0] : (args[0] as Request).url;\n const method = (args[1]?.method ?? \"GET\").toUpperCase();\n const endpoint = `${method} ${url}`;\n\n try {\n const response = await originalFetch(...args);\n\n // Auto log jika 4xx atau 5xx\n if (!response.ok) {\n this.send(\"error\", `HTTP ${response.status} ${endpoint}`, { endpoint, status: response.status });\n }\n\n return response;\n } catch (error) {\n // Network error / timeout\n this.send(\n \"error\",\n `Network error ${endpoint}`,\n { endpoint },\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n };\n\n this.fetchIntercepted = true;\n console.info(\"[ga-logger] fetch intercepted ✅\");\n }\n\n private async send(\n level: LogLevel,\n message: string,\n payload: Record<string, unknown> = {},\n error?: Error,\n endpoint?: string,\n ) {\n if (!this.initialized || !this.config) {\n console.warn(\"[ga-logger] not initialized. Call logger.init() first.\");\n return;\n }\n\n const entry: LogEntry = {\n timestamp: new Date(),\n level,\n message,\n env: this.config.env,\n userId: this.config.userId ?? null,\n sessionId,\n page: typeof window !== \"undefined\" ? window.location.pathname : \"\",\n stackTrace: error?.stack ?? null,\n payload,\n repo: this.config.repo,\n endpoint: endpoint ?? null,\n };\n try {\n const db = getDb();\n await addDoc(collection(db, \"logs\"), {\n ...entry,\n timestamp: Timestamp.fromDate(entry.timestamp),\n });\n } catch (e) {\n console.error(\"[ga-logger] failed to send log:\", e);\n }\n }\n\n info(message: string, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"info\", message, payload, undefined, endpoint);\n }\n\n warn(message: string, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"warn\", message, payload, undefined, endpoint);\n }\n\n error(message: string, error?: Error, payload?: Record<string, unknown>, endpoint?: string) {\n return this.send(\"error\", message, payload, error, endpoint);\n }\n}\n\nexport const logger = new Logger();","import { initializeApp, getApps, FirebaseApp } from \"firebase/app\";\nimport { getFirestore, Firestore } from \"firebase/firestore\";\nimport { LoggerConfig } from \"../types\";\n\nlet app: FirebaseApp;\nlet db: Firestore;\n\nexport const initFirebase = (config: LoggerConfig) => {\n if (!getApps().length) {\n app = initializeApp(\n {\n apiKey: config.apiKey,\n authDomain: config.authDomain,\n projectId: config.projectId,\n storageBucket: config.storageBucket,\n messagingSenderId: config.messagingSenderId,\n appId: config.appId,\n },\n \"ga-logger\",\n );\n } else {\n app = getApps()[0];\n }\n\n db = getFirestore(app);\n return db;\n};\n\nexport const getDb = () => db;\n"],"mappings":"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","names":["db"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ga-components/logger",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",