locallytics 0.1.9 → 0.2.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 (88) hide show
  1. package/dist/adapters/drizzle.d.mts +25 -0
  2. package/dist/adapters/drizzle.d.ts +25 -0
  3. package/dist/adapters/drizzle.js +38 -0
  4. package/dist/adapters/drizzle.mjs +7 -0
  5. package/dist/adapters/prisma.d.mts +25 -0
  6. package/dist/adapters/prisma.d.ts +25 -0
  7. package/dist/adapters/prisma.js +38 -0
  8. package/dist/adapters/prisma.mjs +7 -0
  9. package/dist/adapters.d.mts +7 -0
  10. package/dist/adapters.d.ts +7 -0
  11. package/dist/adapters.js +39 -0
  12. package/dist/adapters.mjs +8 -0
  13. package/dist/browser.d.mts +41 -0
  14. package/dist/browser.d.ts +41 -0
  15. package/dist/browser.js +79 -0
  16. package/dist/browser.mjs +10 -0
  17. package/dist/index.d.mts +59 -0
  18. package/dist/index.d.ts +59 -6
  19. package/dist/index.js +367 -7
  20. package/dist/index.mjs +336 -0
  21. package/dist/react.d.mts +48 -0
  22. package/dist/react.d.ts +48 -0
  23. package/dist/react.js +132 -0
  24. package/dist/react.mjs +61 -0
  25. package/dist/shared/chunk-8tbv1rg5.js +45 -0
  26. package/package.json +60 -48
  27. package/README.md +0 -73
  28. package/dist/client/LocallyticsGrabber.d.ts +0 -30
  29. package/dist/client/LocallyticsGrabber.d.ts.map +0 -1
  30. package/dist/client/LocallyticsGrabber.js +0 -71
  31. package/dist/client/LocallyticsGrabber.js.map +0 -1
  32. package/dist/client/batcher.d.ts +0 -48
  33. package/dist/client/batcher.d.ts.map +0 -1
  34. package/dist/client/batcher.js +0 -134
  35. package/dist/client/batcher.js.map +0 -1
  36. package/dist/client/tracker.d.ts +0 -18
  37. package/dist/client/tracker.d.ts.map +0 -1
  38. package/dist/client/tracker.js +0 -101
  39. package/dist/client/tracker.js.map +0 -1
  40. package/dist/db/factory.d.ts +0 -11
  41. package/dist/db/factory.d.ts.map +0 -1
  42. package/dist/db/factory.js +0 -46
  43. package/dist/db/factory.js.map +0 -1
  44. package/dist/db/mysql.d.ts +0 -17
  45. package/dist/db/mysql.d.ts.map +0 -1
  46. package/dist/db/mysql.js +0 -144
  47. package/dist/db/mysql.js.map +0 -1
  48. package/dist/db/postgres.d.ts +0 -16
  49. package/dist/db/postgres.d.ts.map +0 -1
  50. package/dist/db/postgres.js +0 -142
  51. package/dist/db/postgres.js.map +0 -1
  52. package/dist/db/sqlite.d.ts +0 -17
  53. package/dist/db/sqlite.d.ts.map +0 -1
  54. package/dist/db/sqlite.js +0 -130
  55. package/dist/db/sqlite.js.map +0 -1
  56. package/dist/index.d.ts.map +0 -1
  57. package/dist/index.js.map +0 -1
  58. package/dist/server/handlers.d.ts +0 -10
  59. package/dist/server/handlers.d.ts.map +0 -1
  60. package/dist/server/handlers.js +0 -96
  61. package/dist/server/handlers.js.map +0 -1
  62. package/dist/server/index.d.ts +0 -42
  63. package/dist/server/index.d.ts.map +0 -1
  64. package/dist/server/index.js +0 -96
  65. package/dist/server/index.js.map +0 -1
  66. package/dist/server/queries.d.ts +0 -10
  67. package/dist/server/queries.d.ts.map +0 -1
  68. package/dist/server/queries.js +0 -24
  69. package/dist/server/queries.js.map +0 -1
  70. package/dist/server/validator.d.ts +0 -32
  71. package/dist/server/validator.d.ts.map +0 -1
  72. package/dist/server/validator.js +0 -129
  73. package/dist/server/validator.js.map +0 -1
  74. package/dist/types/index.d.ts +0 -135
  75. package/dist/types/index.d.ts.map +0 -1
  76. package/dist/types/index.js +0 -24
  77. package/dist/types/index.js.map +0 -1
  78. package/dist/utils/hash.d.ts +0 -16
  79. package/dist/utils/hash.d.ts.map +0 -1
  80. package/dist/utils/hash.js +0 -36
  81. package/dist/utils/hash.js.map +0 -1
  82. package/dist/utils/rate-limit.d.ts +0 -32
  83. package/dist/utils/rate-limit.d.ts.map +0 -1
  84. package/dist/utils/rate-limit.js +0 -73
  85. package/dist/utils/rate-limit.js.map +0 -1
  86. package/src/db/schema-mysql.sql +0 -17
  87. package/src/db/schema-sqlite.sql +0 -29
  88. package/src/db/schema.sql +0 -35
@@ -1,142 +0,0 @@
1
- import { Pool } from "pg";
2
- /**
3
- * Get SQL WHERE clause parts for a date range
4
- */
5
- function getDateRangeFilter(dateRange) {
6
- const now = new Date();
7
- if (dateRange === "last24h") {
8
- const start = new Date(now.getTime() - 24 * 60 * 60 * 1000);
9
- return {
10
- whereClause: "timestamp >= $1",
11
- params: [start.toISOString()],
12
- paramOffset: 1,
13
- };
14
- }
15
- if (dateRange === "last7d") {
16
- const start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
17
- return {
18
- whereClause: "timestamp >= $1",
19
- params: [start.toISOString()],
20
- paramOffset: 1,
21
- };
22
- }
23
- if (dateRange === "last30d") {
24
- const start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
25
- return {
26
- whereClause: "timestamp >= $1",
27
- params: [start.toISOString()],
28
- paramOffset: 1,
29
- };
30
- }
31
- return {
32
- whereClause: "timestamp >= $1 AND timestamp <= $2",
33
- params: [dateRange.start.toISOString(), dateRange.end.toISOString()],
34
- paramOffset: 2,
35
- };
36
- }
37
- /**
38
- * PostgreSQL implementation of the analytics database
39
- */
40
- export class PostgresDB {
41
- constructor(connectionString) {
42
- this.pool = new Pool({
43
- connectionString,
44
- max: 10,
45
- idleTimeoutMillis: 30000,
46
- connectionTimeoutMillis: 5000,
47
- });
48
- }
49
- async insertPageview(event, ipHash) {
50
- const query = `
51
- INSERT INTO locallytics_pageviews (
52
- session_id, page_url, referrer, user_agent,
53
- screen_width, screen_height, ip_hash, timestamp
54
- ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
55
- `;
56
- await this.pool.query(query, [
57
- event.sessionId,
58
- event.pageUrl,
59
- event.referrer,
60
- event.userAgent,
61
- event.screenWidth,
62
- event.screenHeight,
63
- ipHash,
64
- event.timestamp,
65
- ]);
66
- }
67
- async getPageviews(dateRange) {
68
- const { whereClause, params } = getDateRangeFilter(dateRange);
69
- const query = `
70
- SELECT COUNT(*) as count
71
- FROM locallytics_pageviews
72
- WHERE ${whereClause}
73
- `;
74
- const result = await this.pool.query(query, params);
75
- return parseInt(result.rows[0]?.count ?? "0", 10);
76
- }
77
- async getUniqueVisitors(dateRange) {
78
- const { whereClause, params } = getDateRangeFilter(dateRange);
79
- const query = `
80
- SELECT COUNT(DISTINCT session_id) as count
81
- FROM locallytics_pageviews
82
- WHERE ${whereClause}
83
- `;
84
- const result = await this.pool.query(query, params);
85
- return parseInt(result.rows[0]?.count ?? "0", 10);
86
- }
87
- async getTopPages(dateRange, limit) {
88
- const { whereClause, params, paramOffset } = getDateRangeFilter(dateRange);
89
- const query = `
90
- SELECT page_url as "pageUrl", COUNT(*) as count
91
- FROM locallytics_pageviews
92
- WHERE ${whereClause}
93
- GROUP BY page_url
94
- ORDER BY count DESC
95
- LIMIT $${paramOffset + 1}
96
- `;
97
- const result = await this.pool.query(query, [...params, limit]);
98
- return result.rows.map((row) => ({
99
- pageUrl: row.pageUrl,
100
- count: parseInt(row.count, 10),
101
- }));
102
- }
103
- async getTopReferrers(dateRange, limit) {
104
- const { whereClause, params, paramOffset } = getDateRangeFilter(dateRange);
105
- const query = `
106
- SELECT referrer as "pageUrl", COUNT(*) as count
107
- FROM locallytics_pageviews
108
- WHERE ${whereClause} AND referrer IS NOT NULL
109
- GROUP BY referrer
110
- ORDER BY count DESC
111
- LIMIT $${paramOffset + 1}
112
- `;
113
- const result = await this.pool.query(query, [...params, limit]);
114
- return result.rows.map((row) => ({
115
- pageUrl: row.pageUrl,
116
- count: parseInt(row.count, 10),
117
- }));
118
- }
119
- async getDailyStats(dateRange) {
120
- const { whereClause, params } = getDateRangeFilter(dateRange);
121
- const query = `
122
- SELECT
123
- DATE(timestamp) as date,
124
- COUNT(*) as pageviews,
125
- COUNT(DISTINCT session_id) as "uniqueVisitors"
126
- FROM locallytics_pageviews
127
- WHERE ${whereClause}
128
- GROUP BY DATE(timestamp)
129
- ORDER BY date DESC
130
- `;
131
- const result = await this.pool.query(query, params);
132
- return result.rows.map((row) => ({
133
- date: row.date.toISOString().split("T")[0] ?? "",
134
- pageviews: parseInt(row.pageviews, 10),
135
- uniqueVisitors: parseInt(row.uniqueVisitors, 10),
136
- }));
137
- }
138
- async close() {
139
- await this.pool.end();
140
- }
141
- }
142
- //# sourceMappingURL=postgres.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/db/postgres.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- import type { AnalyticsDB, DailyStats, DateRange, PageStats, PageviewEvent } from "../types/index.js";
2
- /**
3
- * SQLite implementation of the analytics database
4
- */
5
- export declare class SQLiteDB implements AnalyticsDB {
6
- private db;
7
- private constructor();
8
- static create(filePath: string): Promise<SQLiteDB>;
9
- insertPageview(event: PageviewEvent, ipHash: string | null): Promise<void>;
10
- getPageviews(dateRange: DateRange): Promise<number>;
11
- getUniqueVisitors(dateRange: DateRange): Promise<number>;
12
- getTopPages(dateRange: DateRange, limit: number): Promise<PageStats[]>;
13
- getTopReferrers(dateRange: DateRange, limit: number): Promise<PageStats[]>;
14
- getDailyStats(dateRange: DateRange): Promise<DailyStats[]>;
15
- close(): Promise<void>;
16
- }
17
- //# sourceMappingURL=sqlite.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/db/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACd,MAAM,mBAAmB,CAAC;AAuD3B;;GAEG;AACH,qBAAa,QAAS,YAAW,WAAW;IAC1C,OAAO,CAAC,EAAE,CAAW;IAErB,OAAO;WAIM,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOlD,cAAc,CAClB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,IAAI,CAAC;IAoBV,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAanD,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAaxD,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAuBtE,eAAe,CACnB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,EAAE,CAAC;IAuBjB,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA2B1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
package/dist/db/sqlite.js DELETED
@@ -1,130 +0,0 @@
1
- /**
2
- * Get SQL WHERE clause parts for a date range (SQLite version)
3
- */
4
- function getDateRangeFilter(dateRange) {
5
- const now = new Date();
6
- if (dateRange === "last24h") {
7
- const start = new Date(now.getTime() - 24 * 60 * 60 * 1000);
8
- return {
9
- whereClause: "timestamp >= ?",
10
- params: [start.toISOString()],
11
- };
12
- }
13
- if (dateRange === "last7d") {
14
- const start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
15
- return {
16
- whereClause: "timestamp >= ?",
17
- params: [start.toISOString()],
18
- };
19
- }
20
- if (dateRange === "last30d") {
21
- const start = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
22
- return {
23
- whereClause: "timestamp >= ?",
24
- params: [start.toISOString()],
25
- };
26
- }
27
- // Custom date range
28
- return {
29
- whereClause: "timestamp >= ? AND timestamp <= ?",
30
- params: [dateRange.start.toISOString(), dateRange.end.toISOString()],
31
- };
32
- }
33
- /**
34
- * SQLite implementation of the analytics database
35
- */
36
- export class SQLiteDB {
37
- constructor(db) {
38
- this.db = db;
39
- }
40
- static async create(filePath) {
41
- const BetterSqlite3Module = await import("better-sqlite3");
42
- const BetterSqlite3 = BetterSqlite3Module.default;
43
- const db = new BetterSqlite3(filePath);
44
- return new SQLiteDB(db);
45
- }
46
- async insertPageview(event, ipHash) {
47
- const stmt = this.db.prepare(`
48
- INSERT INTO locallytics_pageviews (
49
- session_id, page_url, referrer, user_agent,
50
- screen_width, screen_height, ip_hash, timestamp
51
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
52
- `);
53
- stmt.run(event.sessionId, event.pageUrl, event.referrer, event.userAgent, event.screenWidth, event.screenHeight, ipHash, event.timestamp);
54
- }
55
- async getPageviews(dateRange) {
56
- const { whereClause, params } = getDateRangeFilter(dateRange);
57
- const stmt = this.db.prepare(`
58
- SELECT COUNT(*) as count
59
- FROM locallytics_pageviews
60
- WHERE ${whereClause}
61
- `);
62
- const result = stmt.get(...params);
63
- return result?.count ?? 0;
64
- }
65
- async getUniqueVisitors(dateRange) {
66
- const { whereClause, params } = getDateRangeFilter(dateRange);
67
- const stmt = this.db.prepare(`
68
- SELECT COUNT(DISTINCT session_id) as count
69
- FROM locallytics_pageviews
70
- WHERE ${whereClause}
71
- `);
72
- const result = stmt.get(...params);
73
- return result?.count ?? 0;
74
- }
75
- async getTopPages(dateRange, limit) {
76
- const { whereClause, params } = getDateRangeFilter(dateRange);
77
- const stmt = this.db.prepare(`
78
- SELECT page_url as pageUrl, COUNT(*) as count
79
- FROM locallytics_pageviews
80
- WHERE ${whereClause}
81
- GROUP BY page_url
82
- ORDER BY count DESC
83
- LIMIT ?
84
- `);
85
- const results = stmt.all(...params, limit);
86
- return results.map((row) => ({
87
- pageUrl: row.pageUrl,
88
- count: row.count,
89
- }));
90
- }
91
- async getTopReferrers(dateRange, limit) {
92
- const { whereClause, params } = getDateRangeFilter(dateRange);
93
- const stmt = this.db.prepare(`
94
- SELECT referrer as pageUrl, COUNT(*) as count
95
- FROM locallytics_pageviews
96
- WHERE ${whereClause} AND referrer IS NOT NULL
97
- GROUP BY referrer
98
- ORDER BY count DESC
99
- LIMIT ?
100
- `);
101
- const results = stmt.all(...params, limit);
102
- return results.map((row) => ({
103
- pageUrl: row.pageUrl,
104
- count: row.count,
105
- }));
106
- }
107
- async getDailyStats(dateRange) {
108
- const { whereClause, params } = getDateRangeFilter(dateRange);
109
- const stmt = this.db.prepare(`
110
- SELECT
111
- date(timestamp) as date,
112
- COUNT(*) as pageviews,
113
- COUNT(DISTINCT session_id) as uniqueVisitors
114
- FROM locallytics_pageviews
115
- WHERE ${whereClause}
116
- GROUP BY date(timestamp)
117
- ORDER BY date DESC
118
- `);
119
- const results = stmt.all(...params);
120
- return results.map((row) => ({
121
- date: row.date,
122
- pageviews: row.pageviews,
123
- uniqueVisitors: row.uniqueVisitors,
124
- }));
125
- }
126
- async close() {
127
- this.db.close();
128
- }
129
- }
130
- //# sourceMappingURL=sqlite.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/db/sqlite.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjE,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AAEjB,iBAAiB;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAajE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,10 +0,0 @@
1
- import type { AnalyticsDB, LocallyticsConfig, RouteHandler } from "../types/index.js";
2
- /**
3
- * Create route handlers for analytics API
4
- *
5
- * @param db - Database instance
6
- * @param config - Locallytics configuration
7
- * @returns GET and POST handlers
8
- */
9
- export declare function createHandlers(db: AnalyticsDB, config: LocallyticsConfig): RouteHandler;
10
- //# sourceMappingURL=handlers.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,iBAAiB,EACjB,YAAY,EACb,MAAM,mBAAmB,CAAC;AAkC3B;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,WAAW,EACf,MAAM,EAAE,iBAAiB,GACxB,YAAY,CAyFd"}
@@ -1,96 +0,0 @@
1
- import { LocallyticsError } from "../types/index.js";
2
- import { getIPFromRequest, hashIP } from "../utils/hash.js";
3
- import { RateLimiter } from "../utils/rate-limit.js";
4
- import { getAnalyticsData } from "./queries.js";
5
- import { checkDNT, validatePageviewBatch } from "./validator.js";
6
- /**
7
- * Parse date range from query string
8
- */
9
- function parseDateRange(value) {
10
- if (!value || value === "last7d") {
11
- return "last7d";
12
- }
13
- if (value === "last24h" || value === "last30d") {
14
- return value;
15
- }
16
- if (value.includes(",")) {
17
- const [startStr, endStr] = value.split(",");
18
- if (startStr && endStr) {
19
- const start = new Date(startStr);
20
- const end = new Date(endStr);
21
- if (!Number.isNaN(start.getTime()) && !Number.isNaN(end.getTime())) {
22
- return { start, end };
23
- }
24
- }
25
- }
26
- return "last7d";
27
- }
28
- /**
29
- * Create route handlers for analytics API
30
- *
31
- * @param db - Database instance
32
- * @param config - Locallytics configuration
33
- * @returns GET and POST handlers
34
- */
35
- export function createHandlers(db, config) {
36
- const rateLimiter = new RateLimiter(100, 60000);
37
- /**
38
- * POST handler - track pageview events
39
- */
40
- async function POST(request) {
41
- try {
42
- if (checkDNT(request)) {
43
- return Response.json({ success: true, tracked: false });
44
- }
45
- const ip = getIPFromRequest(request);
46
- const rateLimitKey = ip ?? "unknown";
47
- if (!rateLimiter.check(rateLimitKey)) {
48
- const error = LocallyticsError.rateLimit();
49
- return Response.json({ error: error.message, code: error.code }, { status: error.statusCode });
50
- }
51
- const body = await request.json();
52
- const events = validatePageviewBatch(body);
53
- const ipHash = ip ? hashIP(ip) : null;
54
- await Promise.all(events.map((event) => db.insertPageview(event, ipHash)));
55
- return Response.json({
56
- success: true,
57
- tracked: true,
58
- count: events.length,
59
- });
60
- }
61
- catch (error) {
62
- if (error instanceof LocallyticsError) {
63
- return Response.json({ error: error.message, code: error.code }, { status: error.statusCode });
64
- }
65
- // Log unexpected errors but don't expose details
66
- console.error("[Locallytics] POST error:", error);
67
- return Response.json({ error: "Internal server error", code: "INTERNAL_ERROR" }, { status: 500 });
68
- }
69
- }
70
- /**
71
- * GET handler - fetch analytics data
72
- */
73
- async function GET(request) {
74
- try {
75
- if (config.apiKey) {
76
- const authHeader = request.headers.get("authorization");
77
- const providedKey = authHeader?.replace("Bearer ", "");
78
- if (providedKey !== config.apiKey) {
79
- const error = LocallyticsError.unauthorized();
80
- return Response.json({ error: error.message, code: error.code }, { status: error.statusCode });
81
- }
82
- }
83
- const url = new URL(request.url);
84
- const dateRange = parseDateRange(url.searchParams.get("range"));
85
- const data = await getAnalyticsData(db, dateRange);
86
- return Response.json(data);
87
- }
88
- catch (error) {
89
- // Log unexpected errors but don't expose details
90
- console.error("[Locallytics] GET error:", error);
91
- return Response.json({ error: "Internal server error", code: "INTERNAL_ERROR" }, { status: 500 });
92
- }
93
- }
94
- return { GET, POST };
95
- }
96
- //# sourceMappingURL=handlers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"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"}
@@ -1,42 +0,0 @@
1
- import type { AnalyticsDataOptions, AnalyticsResult, LocallyticsConfig, RouteHandler } from "../types/index.js";
2
- /**
3
- * Initialize Locallytics and create route handlers
4
- *
5
- * @param config - Locallytics configuration
6
- * @returns GET and POST route handlers for Next.js App Router
7
- *
8
- * @example
9
- * ```typescript
10
- * // app/api/analytics/route.ts
11
- * import { locallytics } from 'locallytics';
12
- *
13
- * const analytics = await locallytics({
14
- * database: process.env.DATABASE_URL!,
15
- * apiKey: process.env.ANALYTICS_API_KEY,
16
- * });
17
- *
18
- * export const { GET, POST } = analytics;
19
- * ```
20
- */
21
- export declare function locallytics(config: LocallyticsConfig): Promise<RouteHandler>;
22
- /**
23
- * Server-side helper to fetch analytics data
24
- * Use in React Server Components
25
- *
26
- * @param options - Options including date range (optional)
27
- * @returns Analytics data
28
- *
29
- * @example
30
- * ```tsx
31
- * // app/dashboard/page.tsx
32
- * import { LocallyticsData } from 'locallytics';
33
- *
34
- * export default async function Dashboard() {
35
- * const data = await LocallyticsData(); // No arguments needed!
36
- *
37
- * return <div>{data.pageviews} pageviews</div>;
38
- * }
39
- * ```
40
- */
41
- export declare function LocallyticsData(options?: AnalyticsDataOptions): Promise<AnalyticsResult>;
42
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,YAAY,EACb,MAAM,mBAAmB,CAAC;AAG3B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,YAAY,CAAC,CAGvB;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CACnC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,eAAe,CAAC,CA6D1B"}
@@ -1,96 +0,0 @@
1
- import { createDatabase } from "../db/factory.js";
2
- import { createHandlers } from "./handlers.js";
3
- /**
4
- * Initialize Locallytics and create route handlers
5
- *
6
- * @param config - Locallytics configuration
7
- * @returns GET and POST route handlers for Next.js App Router
8
- *
9
- * @example
10
- * ```typescript
11
- * // app/api/analytics/route.ts
12
- * import { locallytics } from 'locallytics';
13
- *
14
- * const analytics = await locallytics({
15
- * database: process.env.DATABASE_URL!,
16
- * apiKey: process.env.ANALYTICS_API_KEY,
17
- * });
18
- *
19
- * export const { GET, POST } = analytics;
20
- * ```
21
- */
22
- export async function locallytics(config) {
23
- const db = await createDatabase(config);
24
- return createHandlers(db, config);
25
- }
26
- import { headers } from "next/headers";
27
- /**
28
- * Server-side helper to fetch analytics data
29
- * Use in React Server Components
30
- *
31
- * @param options - Options including date range (optional)
32
- * @returns Analytics data
33
- *
34
- * @example
35
- * ```tsx
36
- * // app/dashboard/page.tsx
37
- * import { LocallyticsData } from 'locallytics';
38
- *
39
- * export default async function Dashboard() {
40
- * const data = await LocallyticsData(); // No arguments needed!
41
- *
42
- * return <div>{data.pageviews} pageviews</div>;
43
- * }
44
- * ```
45
- */
46
- export async function LocallyticsData(options = {}) {
47
- const { dateRange = "last7d", endpoint = "/api/analytics" } = options;
48
- const headersList = await Promise.resolve(headers());
49
- const host = headersList.get("host") ?? "localhost:3000";
50
- const protocol = headersList.get("x-forwarded-proto") ?? "http";
51
- let rangeParam;
52
- if (typeof dateRange === "string") {
53
- rangeParam = dateRange;
54
- }
55
- else {
56
- rangeParam = `${dateRange.start.toISOString()},${dateRange.end.toISOString()}`;
57
- }
58
- const url = `${protocol}://${host}${endpoint}?range=${encodeURIComponent(rangeParam)}`;
59
- const authHeader = headersList.get("authorization");
60
- const fetchHeaders = {};
61
- if (authHeader) {
62
- fetchHeaders.authorization = authHeader;
63
- }
64
- try {
65
- const response = await fetch(url, {
66
- headers: fetchHeaders,
67
- cache: "no-store",
68
- });
69
- if (!response.ok) {
70
- const errorData = (await response.json().catch(() => ({})));
71
- const errorMessage = errorData.message ??
72
- errorData.error ??
73
- `Failed to fetch analytics: ${response.status}`;
74
- return {
75
- pageviews: 0,
76
- uniqueVisitors: 0,
77
- topPages: [],
78
- topReferrers: [],
79
- dailyStats: [],
80
- error: errorMessage,
81
- };
82
- }
83
- return response.json();
84
- }
85
- catch (error) {
86
- return {
87
- pageviews: 0,
88
- uniqueVisitors: 0,
89
- topPages: [],
90
- topReferrers: [],
91
- dailyStats: [],
92
- error: error instanceof Error ? error.message : "Unknown error occurred",
93
- };
94
- }
95
- }
96
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOlD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAyB;IAEzB,MAAM,EAAE,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAgC,EAAE;IAElC,MAAM,EAAE,SAAS,GAAG,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,EAAE,GAAG,OAAO,CAAC;IAEtE,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC;IACzD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,MAAM,CAAC;IAEhE,IAAI,UAAkB,CAAC;IACvB,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,UAAU,GAAG,SAAS,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,UAAU,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;IACjF,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,QAAQ,MAAM,IAAI,GAAG,QAAQ,UAAU,kBAAkB,CACtE,UAAU,CACX,EAAE,CAAC;IAEJ,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACpD,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,IAAI,UAAU,EAAE,CAAC;QACf,YAAY,CAAC,aAAa,GAAG,UAAU,CAAC;IAC1C,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,OAAO,EAAE,YAAY;YACrB,KAAK,EAAE,UAAU;SAClB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAGzD,CAAC;YACF,MAAM,YAAY,GACf,SAAS,CAAC,OAAkB;gBAC5B,SAAS,CAAC,KAAgB;gBAC3B,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC;YAElD,OAAO;gBACL,SAAS,EAAE,CAAC;gBACZ,cAAc,EAAE,CAAC;gBACjB,QAAQ,EAAE,EAAE;gBACZ,YAAY,EAAE,EAAE;gBAChB,UAAU,EAAE,EAAE;gBACd,KAAK,EAAE,YAAY;aACpB,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAA8B,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,SAAS,EAAE,CAAC;YACZ,cAAc,EAAE,CAAC;YACjB,QAAQ,EAAE,EAAE;YACZ,YAAY,EAAE,EAAE;YAChB,UAAU,EAAE,EAAE;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;SACzE,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,10 +0,0 @@
1
- import type { AnalyticsDB, AnalyticsResult, DateRange } from "../types/index.js";
2
- /**
3
- * Fetch all analytics data in parallel
4
- *
5
- * @param db - Database instance
6
- * @param dateRange - Date range for the query
7
- * @returns Complete analytics data
8
- */
9
- export declare function getAnalyticsData(db: AnalyticsDB, dateRange: DateRange): Promise<AnalyticsResult>;
10
- //# sourceMappingURL=queries.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/server/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,SAAS,EACV,MAAM,mBAAmB,CAAC;AAE3B;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,WAAW,EACf,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,eAAe,CAAC,CAiB1B"}
@@ -1,24 +0,0 @@
1
- /**
2
- * Fetch all analytics data in parallel
3
- *
4
- * @param db - Database instance
5
- * @param dateRange - Date range for the query
6
- * @returns Complete analytics data
7
- */
8
- export async function getAnalyticsData(db, dateRange) {
9
- const [pageviews, uniqueVisitors, topPages, topReferrers, dailyStats] = await Promise.all([
10
- db.getPageviews(dateRange),
11
- db.getUniqueVisitors(dateRange),
12
- db.getTopPages(dateRange, 10),
13
- db.getTopReferrers(dateRange, 10),
14
- db.getDailyStats(dateRange),
15
- ]);
16
- return {
17
- pageviews,
18
- uniqueVisitors,
19
- topPages,
20
- topReferrers,
21
- dailyStats,
22
- };
23
- }
24
- //# sourceMappingURL=queries.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/server/queries.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAe,EACf,SAAoB;IAEpB,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,GACnE,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC;QAC1B,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;QAC/B,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC;QAC7B,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,EAAE,CAAC;QACjC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC;KAC5B,CAAC,CAAC;IAEL,OAAO;QACL,SAAS;QACT,cAAc;QACd,QAAQ;QACR,YAAY;QACZ,UAAU;KACX,CAAC;AACJ,CAAC"}