web-comments 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +188 -6
  2. package/dist/auth/bearer-token.js +43 -0
  3. package/dist/auth/cloudflare-access.js +90 -0
  4. package/dist/auth/dev-user.js +21 -0
  5. package/dist/auth/session-endpoint.js +47 -0
  6. package/dist/chunks/chunk-6VWNCJ3A.js +72 -0
  7. package/dist/chunks/chunk-GHNSLFY2.js +72 -0
  8. package/dist/chunks/chunk-LBIURYPH.js +192 -0
  9. package/dist/chunks/chunk-PLAC65HG.js +71 -0
  10. package/dist/chunks/chunk-WSFCRVEQ.js +9 -0
  11. package/dist/index.js +44 -0
  12. package/dist/react.js +19 -0
  13. package/dist/server.js +501 -0
  14. package/dist/store/d1.js +16 -0
  15. package/dist/store/drizzle/mysql.js +13 -0
  16. package/dist/store/drizzle/pg.js +13 -0
  17. package/dist/store/drizzle/sqlite.js +13 -0
  18. package/dist/store/drizzle.js +10 -0
  19. package/dist/store/memory.js +75 -0
  20. package/dist/store/r2.js +25 -0
  21. package/dist/store/s3.js +43 -0
  22. package/dist/types/auth/bearer-token.d.ts +13 -0
  23. package/dist/types/auth/cloudflare-access.d.ts +33 -0
  24. package/dist/types/auth/dev-user.d.ts +6 -0
  25. package/dist/types/auth/session-endpoint.d.ts +25 -0
  26. package/dist/types/react.d.ts +8 -0
  27. package/dist/types/server/auth.d.ts +16 -0
  28. package/dist/types/server/index.d.ts +71 -0
  29. package/dist/types/server/store.d.ts +59 -0
  30. package/dist/types/server/validate.d.ts +20 -0
  31. package/dist/types/shared/types.d.ts +108 -0
  32. package/dist/types/store/d1.d.ts +9 -0
  33. package/dist/types/store/drizzle/index.d.ts +22 -0
  34. package/dist/types/store/drizzle/mysql.d.ts +506 -0
  35. package/dist/types/store/drizzle/pg.d.ts +476 -0
  36. package/dist/types/store/drizzle/sqlite.d.ts +506 -0
  37. package/dist/types/store/memory.d.ts +10 -0
  38. package/dist/types/store/r2.d.ts +20 -0
  39. package/dist/types/store/s3.d.ts +21 -0
  40. package/dist/types/widget/anchor.d.ts +9 -0
  41. package/dist/types/widget/api.d.ts +43 -0
  42. package/dist/types/widget/app.d.ts +29 -0
  43. package/dist/types/widget/capture.d.ts +33 -0
  44. package/dist/types/widget/format.d.ts +15 -0
  45. package/dist/types/widget/index.d.ts +41 -0
  46. package/dist/types/widget/styles.d.ts +6 -0
  47. package/dist/types/widget/thread.d.ts +32 -0
  48. package/dist/types/widget/tracker.d.ts +68 -0
  49. package/dist/widget.global.js +44 -0
  50. package/package.json +132 -6
  51. package/types/widget.global.d.ts +5 -0
  52. package/index.d.ts +0 -2
  53. package/index.js +0 -6
@@ -0,0 +1,192 @@
1
+ import {
2
+ pg_exports
3
+ } from "./chunk-6VWNCJ3A.js";
4
+ import {
5
+ mysql_exports
6
+ } from "./chunk-PLAC65HG.js";
7
+ import {
8
+ sqlite_exports
9
+ } from "./chunk-GHNSLFY2.js";
10
+
11
+ // src/store/drizzle/index.ts
12
+ import { and, asc, desc, eq, inArray, sql } from "drizzle-orm";
13
+ var SCHEMAS = { sqlite: sqlite_exports, pg: pg_exports, mysql: mysql_exports };
14
+ var IN_CHUNK = 90;
15
+ function drizzleStore(options) {
16
+ const { threads, comments, users, createTablesSql } = SCHEMAS[options.dialect];
17
+ const db = options.db;
18
+ async function together(build) {
19
+ if (typeof db.batch === "function") {
20
+ await db.batch(build(db));
21
+ return;
22
+ }
23
+ await db.transaction(async (tx) => {
24
+ for (const query of build(tx)) await query;
25
+ });
26
+ }
27
+ async function commentsOf(threadIds) {
28
+ const byThread = new Map(threadIds.map((id) => [id, []]));
29
+ for (let i = 0; i < threadIds.length; i += IN_CHUNK) {
30
+ const rows = await db.select().from(comments).where(inArray(comments.threadId, threadIds.slice(i, i + IN_CHUNK))).orderBy(asc(comments.createdAt), asc(comments.id));
31
+ for (const row of rows) byThread.get(row.threadId)?.push(toComment(row));
32
+ }
33
+ return byThread;
34
+ }
35
+ async function threadRows(site, id) {
36
+ const rows = await db.select().from(threads).where(and(eq(threads.site, site), eq(threads.id, id))).limit(1);
37
+ return rows[0];
38
+ }
39
+ return {
40
+ async setup() {
41
+ if (options.createTables === false) return;
42
+ for (const statement of createTablesSql) {
43
+ if (options.dialect === "sqlite") await db.run(sql.raw(statement));
44
+ else await db.execute(sql.raw(statement));
45
+ }
46
+ },
47
+ async listThreads(site, { page, limit }) {
48
+ const rows = await db.select().from(threads).where(
49
+ page === void 0 ? eq(threads.site, site) : and(eq(threads.site, site), eq(threads.page, page))
50
+ ).orderBy(page === void 0 ? desc(threads.createdAt) : asc(threads.createdAt)).limit(limit);
51
+ const byThread = await commentsOf(rows.map((row) => row.id));
52
+ return rows.map((row) => toThread(row, byThread.get(row.id) ?? []));
53
+ },
54
+ async getThread(site, id) {
55
+ const row = await threadRows(site, id);
56
+ if (!row) return null;
57
+ const byThread = await commentsOf([row.id]);
58
+ return toThread(row, byThread.get(row.id) ?? []);
59
+ },
60
+ async insertThread(thread, first) {
61
+ await together((on) => [
62
+ on.insert(threads).values(threadRow(thread)),
63
+ on.insert(comments).values(commentRow(first))
64
+ ]);
65
+ },
66
+ async insertComment(site, comment) {
67
+ if (!await threadRows(site, comment.threadId)) return;
68
+ await db.insert(comments).values(commentRow(comment));
69
+ },
70
+ async updateThread(site, id, changes) {
71
+ const set = changedColumns(changes);
72
+ if (Object.keys(set).length === 0) return;
73
+ await db.update(threads).set(set).where(and(eq(threads.site, site), eq(threads.id, id)));
74
+ },
75
+ async getComment(site, id) {
76
+ const rows = await db.select().from(comments).where(eq(comments.id, id)).limit(1);
77
+ const row = rows[0];
78
+ if (!row || !await threadRows(site, row.threadId)) return null;
79
+ return toComment(row);
80
+ },
81
+ async deleteComment(site, id) {
82
+ const comment = await this.getComment(site, id);
83
+ if (comment) await db.delete(comments).where(eq(comments.id, id));
84
+ },
85
+ async deleteThread(site, id) {
86
+ if (!await threadRows(site, id)) return;
87
+ await together((on) => [
88
+ on.delete(comments).where(eq(comments.threadId, id)),
89
+ on.delete(threads).where(and(eq(threads.site, site), eq(threads.id, id)))
90
+ ]);
91
+ },
92
+ async saveUser(who, seenAt) {
93
+ const values = {
94
+ id: who.id,
95
+ name: who.name,
96
+ email: who.email ?? null,
97
+ avatarUrl: who.avatarUrl ?? null,
98
+ kind: who.kind,
99
+ lastSeenAt: seenAt
100
+ };
101
+ const { id: _, ...set } = values;
102
+ const insert = db.insert(users).values(values);
103
+ await (options.dialect === "mysql" ? insert.onDuplicateKeyUpdate({ set }) : insert.onConflictDoUpdate({ target: users.id, set }));
104
+ }
105
+ };
106
+ }
107
+ function json(value) {
108
+ return value === null ? null : JSON.parse(value);
109
+ }
110
+ function rowAuthor(row) {
111
+ return {
112
+ id: row.authorId,
113
+ name: row.authorName,
114
+ kind: row.authorKind,
115
+ ...row.authorAvatar ? { avatarUrl: row.authorAvatar } : {}
116
+ };
117
+ }
118
+ function toComment(row) {
119
+ return {
120
+ id: row.id,
121
+ threadId: row.threadId,
122
+ body: row.body,
123
+ author: rowAuthor(row),
124
+ createdAt: row.createdAt
125
+ };
126
+ }
127
+ function toThread(row, comments) {
128
+ return {
129
+ id: row.id,
130
+ site: row.site,
131
+ page: row.page,
132
+ url: row.url,
133
+ anchor: JSON.parse(row.anchor),
134
+ context: json(row.context),
135
+ screenshots: JSON.parse(row.screenshots),
136
+ status: row.status,
137
+ author: rowAuthor(row),
138
+ createdAt: row.createdAt,
139
+ updatedAt: row.updatedAt,
140
+ resolvedAt: row.resolvedAt,
141
+ resolvedBy: json(row.resolvedBy),
142
+ comments
143
+ };
144
+ }
145
+ function threadRow(thread) {
146
+ return {
147
+ id: thread.id,
148
+ site: thread.site,
149
+ page: thread.page,
150
+ url: thread.url,
151
+ anchor: JSON.stringify(thread.anchor),
152
+ context: thread.context ? JSON.stringify(thread.context) : null,
153
+ screenshots: JSON.stringify(thread.screenshots),
154
+ status: thread.status,
155
+ authorId: thread.author.id,
156
+ authorName: thread.author.name,
157
+ authorAvatar: thread.author.avatarUrl ?? null,
158
+ authorKind: thread.author.kind,
159
+ createdAt: thread.createdAt,
160
+ updatedAt: thread.updatedAt,
161
+ resolvedAt: thread.resolvedAt,
162
+ resolvedBy: thread.resolvedBy ? JSON.stringify(thread.resolvedBy) : null
163
+ };
164
+ }
165
+ function commentRow(comment) {
166
+ return {
167
+ id: comment.id,
168
+ threadId: comment.threadId,
169
+ body: comment.body,
170
+ authorId: comment.author.id,
171
+ authorName: comment.author.name,
172
+ authorAvatar: comment.author.avatarUrl ?? null,
173
+ authorKind: comment.author.kind,
174
+ createdAt: comment.createdAt
175
+ };
176
+ }
177
+ function changedColumns(changes) {
178
+ const set = {};
179
+ if (changes.status !== void 0) set.status = changes.status;
180
+ if (changes.anchor !== void 0) set.anchor = JSON.stringify(changes.anchor);
181
+ if (changes.screenshots !== void 0) set.screenshots = JSON.stringify(changes.screenshots);
182
+ if (changes.updatedAt !== void 0) set.updatedAt = changes.updatedAt;
183
+ if (changes.resolvedAt !== void 0) set.resolvedAt = changes.resolvedAt;
184
+ if (changes.resolvedBy !== void 0) {
185
+ set.resolvedBy = changes.resolvedBy ? JSON.stringify(changes.resolvedBy) : null;
186
+ }
187
+ return set;
188
+ }
189
+
190
+ export {
191
+ drizzleStore
192
+ };
@@ -0,0 +1,71 @@
1
+ import {
2
+ __export
3
+ } from "./chunk-WSFCRVEQ.js";
4
+
5
+ // src/store/drizzle/mysql.ts
6
+ var mysql_exports = {};
7
+ __export(mysql_exports, {
8
+ comments: () => comments,
9
+ createTablesSql: () => createTablesSql,
10
+ threads: () => threads,
11
+ users: () => users
12
+ });
13
+ import { index, mysqlTable, text, varchar } from "drizzle-orm/mysql-core";
14
+ var id = (name) => varchar(name, { length: 64 });
15
+ var threads = mysqlTable(
16
+ "wc_threads",
17
+ {
18
+ id: id("id").primaryKey(),
19
+ site: varchar("site", { length: 128 }).notNull(),
20
+ page: varchar("page", { length: 512 }).notNull(),
21
+ url: text("url").notNull(),
22
+ anchor: text("anchor").notNull(),
23
+ context: text("context"),
24
+ screenshots: text("screenshots").notNull(),
25
+ status: varchar("status", { length: 16 }).notNull(),
26
+ authorId: varchar("author_id", { length: 255 }).notNull(),
27
+ authorName: varchar("author_name", { length: 255 }).notNull(),
28
+ authorAvatar: text("author_avatar"),
29
+ authorKind: varchar("author_kind", { length: 16 }).notNull(),
30
+ createdAt: varchar("created_at", { length: 32 }).notNull(),
31
+ updatedAt: varchar("updated_at", { length: 32 }).notNull(),
32
+ resolvedAt: varchar("resolved_at", { length: 32 }),
33
+ resolvedBy: text("resolved_by")
34
+ },
35
+ (t) => [index("wc_threads_page").on(t.site, t.page, t.createdAt)]
36
+ );
37
+ var comments = mysqlTable(
38
+ "wc_comments",
39
+ {
40
+ id: id("id").primaryKey(),
41
+ threadId: id("thread_id").notNull(),
42
+ body: text("body").notNull(),
43
+ authorId: varchar("author_id", { length: 255 }).notNull(),
44
+ authorName: varchar("author_name", { length: 255 }).notNull(),
45
+ authorAvatar: text("author_avatar"),
46
+ authorKind: varchar("author_kind", { length: 16 }).notNull(),
47
+ createdAt: varchar("created_at", { length: 32 }).notNull()
48
+ },
49
+ (t) => [index("wc_comments_thread").on(t.threadId, t.createdAt)]
50
+ );
51
+ var users = mysqlTable("wc_users", {
52
+ id: varchar("id", { length: 255 }).primaryKey(),
53
+ name: varchar("name", { length: 255 }).notNull(),
54
+ email: varchar("email", { length: 320 }),
55
+ avatarUrl: text("avatar_url"),
56
+ kind: varchar("kind", { length: 16 }).notNull(),
57
+ lastSeenAt: varchar("last_seen_at", { length: 32 }).notNull()
58
+ });
59
+ var createTablesSql = [
60
+ `CREATE TABLE IF NOT EXISTS wc_threads (id VARCHAR(64) NOT NULL PRIMARY KEY, site VARCHAR(128) NOT NULL, page VARCHAR(512) NOT NULL, url TEXT NOT NULL, anchor TEXT NOT NULL, context TEXT, screenshots TEXT NOT NULL, status VARCHAR(16) NOT NULL, author_id VARCHAR(255) NOT NULL, author_name VARCHAR(255) NOT NULL, author_avatar TEXT, author_kind VARCHAR(16) NOT NULL, created_at VARCHAR(32) NOT NULL, updated_at VARCHAR(32) NOT NULL, resolved_at VARCHAR(32), resolved_by TEXT, KEY wc_threads_page (site, page, created_at)) DEFAULT CHARSET=utf8mb4`,
61
+ `CREATE TABLE IF NOT EXISTS wc_comments (id VARCHAR(64) NOT NULL PRIMARY KEY, thread_id VARCHAR(64) NOT NULL, body TEXT NOT NULL, author_id VARCHAR(255) NOT NULL, author_name VARCHAR(255) NOT NULL, author_avatar TEXT, author_kind VARCHAR(16) NOT NULL, created_at VARCHAR(32) NOT NULL, KEY wc_comments_thread (thread_id, created_at)) DEFAULT CHARSET=utf8mb4`,
62
+ `CREATE TABLE IF NOT EXISTS wc_users (id VARCHAR(255) NOT NULL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(320), avatar_url TEXT, kind VARCHAR(16) NOT NULL, last_seen_at VARCHAR(32) NOT NULL) DEFAULT CHARSET=utf8mb4`
63
+ ];
64
+
65
+ export {
66
+ threads,
67
+ comments,
68
+ users,
69
+ createTablesSql,
70
+ mysql_exports
71
+ };
@@ -0,0 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ export {
8
+ __export
9
+ };