@ga-components/logger 1.0.2 → 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
@@ -11,6 +11,7 @@ interface LogEntry {
11
11
  stackTrace: string | null;
12
12
  payload: Record<string, unknown>;
13
13
  repo: string;
14
+ endpoint: string | null;
14
15
  }
15
16
  interface LoggerConfig {
16
17
  env: LogEnv;
@@ -27,12 +28,14 @@ interface LoggerConfig {
27
28
  declare class Logger {
28
29
  private config;
29
30
  private initialized;
31
+ private fetchIntercepted;
30
32
  init(config: LoggerConfig): void;
31
33
  setUserId(userId: string | null): void;
34
+ interceptFetch(): void;
32
35
  private send;
33
- info(message: string, payload?: Record<string, unknown>): Promise<void>;
34
- warn(message: string, payload?: Record<string, unknown>): Promise<void>;
35
- error(message: string, error?: Error, payload?: Record<string, unknown>): Promise<void>;
36
+ info(message: string, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
37
+ warn(message: string, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
38
+ error(message: string, error?: Error, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
36
39
  }
37
40
  declare const logger: Logger;
38
41
 
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ interface LogEntry {
11
11
  stackTrace: string | null;
12
12
  payload: Record<string, unknown>;
13
13
  repo: string;
14
+ endpoint: string | null;
14
15
  }
15
16
  interface LoggerConfig {
16
17
  env: LogEnv;
@@ -27,12 +28,14 @@ interface LoggerConfig {
27
28
  declare class Logger {
28
29
  private config;
29
30
  private initialized;
31
+ private fetchIntercepted;
30
32
  init(config: LoggerConfig): void;
31
33
  setUserId(userId: string | null): void;
34
+ interceptFetch(): void;
32
35
  private send;
33
- info(message: string, payload?: Record<string, unknown>): Promise<void>;
34
- warn(message: string, payload?: Record<string, unknown>): Promise<void>;
35
- error(message: string, error?: Error, payload?: Record<string, unknown>): Promise<void>;
36
+ info(message: string, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
37
+ warn(message: string, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
38
+ error(message: string, error?: Error, payload?: Record<string, unknown>, endpoint?: string): Promise<void>;
36
39
  }
37
40
  declare const logger: Logger;
38
41
 
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,7 +74,34 @@ var Logger = class {
73
74
  }
74
75
  this.config.userId = userId;
75
76
  }
76
- async send(level, message, payload = {}, error) {
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
+ }
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.");
79
107
  return;
@@ -88,7 +116,8 @@ var Logger = class {
88
116
  page: typeof window !== "undefined" ? window.location.pathname : "",
89
117
  stackTrace: error?.stack ?? null,
90
118
  payload,
91
- repo: this.config.repo
119
+ repo: this.config.repo,
120
+ endpoint: endpoint ?? null
92
121
  };
93
122
  try {
94
123
  const db2 = getDb();
@@ -100,14 +129,14 @@ var Logger = class {
100
129
  console.error("[ga-logger] failed to send log:", e);
101
130
  }
102
131
  }
103
- info(message, payload) {
104
- return this.send("info", message, payload);
132
+ info(message, payload, endpoint) {
133
+ return this.send("info", message, payload, void 0, endpoint);
105
134
  }
106
- warn(message, payload) {
107
- return this.send("warn", message, payload);
135
+ warn(message, payload, endpoint) {
136
+ return this.send("warn", message, payload, void 0, endpoint);
108
137
  }
109
- error(message, error, payload) {
110
- return this.send("error", message, payload, error);
138
+ error(message, error, payload, endpoint) {
139
+ return this.send("error", message, payload, error, endpoint);
111
140
  }
112
141
  };
113
142
  var logger = new Logger();
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(level: LogLevel, message: string, payload: Record<string, unknown> = {}, error?: Error) {\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 };\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>) {\n return this.send(\"info\", message, payload);\n }\n\n warn(message: string, payload?: Record<string, unknown>) {\n return this.send(\"warn\", message, payload);\n }\n\n error(message: string, error?: Error, payload?: Record<string, unknown>) {\n return this.send(\"error\", message, payload, error);\n }\n}\n\nexport const logger = new Logger();\n\n","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,KAAK,OAAiB,SAAiB,UAAmC,CAAC,GAAG,OAAe;AACvG,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,IACtB;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;AACrD,WAAO,KAAK,KAAK,QAAQ,SAAS,OAAO;AAAA,EAC7C;AAAA,EAEA,KAAK,SAAiB,SAAmC;AACrD,WAAO,KAAK,KAAK,QAAQ,SAAS,OAAO;AAAA,EAC7C;AAAA,EAEA,MAAM,SAAiB,OAAe,SAAmC;AACrE,WAAO,KAAK,KAAK,SAAS,SAAS,SAAS,KAAK;AAAA,EACrD;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,7 +48,34 @@ var Logger = class {
47
48
  }
48
49
  this.config.userId = userId;
49
50
  }
50
- async send(level, message, payload = {}, error) {
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
+ }
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.");
53
81
  return;
@@ -62,7 +90,8 @@ var Logger = class {
62
90
  page: typeof window !== "undefined" ? window.location.pathname : "",
63
91
  stackTrace: error?.stack ?? null,
64
92
  payload,
65
- repo: this.config.repo
93
+ repo: this.config.repo,
94
+ endpoint: endpoint ?? null
66
95
  };
67
96
  try {
68
97
  const db2 = getDb();
@@ -74,14 +103,14 @@ var Logger = class {
74
103
  console.error("[ga-logger] failed to send log:", e);
75
104
  }
76
105
  }
77
- info(message, payload) {
78
- return this.send("info", message, payload);
106
+ info(message, payload, endpoint) {
107
+ return this.send("info", message, payload, void 0, endpoint);
79
108
  }
80
- warn(message, payload) {
81
- return this.send("warn", message, payload);
109
+ warn(message, payload, endpoint) {
110
+ return this.send("warn", message, payload, void 0, endpoint);
82
111
  }
83
- error(message, error, payload) {
84
- return this.send("error", message, payload, error);
112
+ error(message, error, payload, endpoint) {
113
+ return this.send("error", message, payload, error, endpoint);
85
114
  }
86
115
  };
87
116
  var logger = new Logger();
@@ -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(level: LogLevel, message: string, payload: Record<string, unknown> = {}, error?: Error) {\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 };\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>) {\n return this.send(\"info\", message, payload);\n }\n\n warn(message: string, payload?: Record<string, unknown>) {\n return this.send(\"warn\", message, payload);\n }\n\n error(message: string, error?: Error, payload?: Record<string, unknown>) {\n return this.send(\"error\", message, payload, error);\n }\n}\n\nexport const logger = new Logger();\n\n","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,KAAK,OAAiB,SAAiB,UAAmC,CAAC,GAAG,OAAe;AACvG,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,IACtB;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;AACrD,WAAO,KAAK,KAAK,QAAQ,SAAS,OAAO;AAAA,EAC7C;AAAA,EAEA,KAAK,SAAiB,SAAmC;AACrD,WAAO,KAAK,KAAK,QAAQ,SAAS,OAAO;AAAA,EAC7C;AAAA,EAEA,MAAM,SAAiB,OAAe,SAAmC;AACrE,WAAO,KAAK,KAAK,SAAS,SAAS,SAAS,KAAK;AAAA,EACrD;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":";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;AACtB,SAAQ,mBAAmB;AAAA;AAAA,EAE3B,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;AAAA,EAGA,iBAAiB;AACb,QAAI,KAAK,iBAAkB;AAC3B,UAAM,gBAAgB,OAAO;AAE7B,WAAO,QAAQ,UAAU,SAAS;AAC9B,YAAM,MAAM,OAAO,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,IAAK,KAAK,CAAC,EAAc;AACzE,YAAM,UAAU,KAAK,CAAC,GAAG,UAAU,OAAO,YAAY;AACtD,YAAM,WAAW,GAAG,MAAM,IAAI,GAAG;AAEjC,UAAI;AACA,cAAM,WAAW,MAAM,cAAc,GAAG,IAAI;AAG5C,YAAI,CAAC,SAAS,IAAI;AACd,eAAK,KAAK,SAAS,QAAQ,SAAS,MAAM,IAAI,QAAQ,IAAI,EAAE,UAAU,QAAQ,SAAS,OAAO,CAAC;AAAA,QACnG;AAEA,eAAO;AAAA,MACX,SAAS,OAAO;AAEZ,aAAK;AAAA,UACD;AAAA,UACA,iBAAiB,QAAQ;AAAA,UACzB,EAAE,SAAS;AAAA,UACX,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC5D;AACA,cAAM;AAAA,MACV;AAAA,IACJ;AAEA,SAAK,mBAAmB;AACxB,YAAQ,KAAK,sCAAiC;AAAA,EAClD;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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ga-components/logger",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",