@mindbowser_inc/ui-feedback-plugin 0.4.0 → 0.4.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/README.md CHANGED
@@ -185,7 +185,7 @@ The browser obtains **temporary, rotating credentials** from a Cognito Identity
185
185
  The AWS SDK is not bundled with the plugin — install it alongside:
186
186
 
187
187
  ```bash
188
- npm install @aws-sdk/client-s3 @aws-sdk/credential-provider-cognito-identity
188
+ npm install @aws-sdk/client-s3
189
189
  ```
190
190
 
191
191
  ### Quick start
@@ -0,0 +1,165 @@
1
+ var p = Object.defineProperty;
2
+ var h = (c, t, e) => t in c ? p(c, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[t] = e;
3
+ var l = (c, t, e) => h(c, typeof t != "symbol" ? t + "" : t, e);
4
+ class u {
5
+ constructor(t) {
6
+ l(this, "cfg");
7
+ l(this, "_s3", null);
8
+ this.cfg = t;
9
+ }
10
+ // Minimal Cognito Identity Pool credential provider using plain fetch.
11
+ // Avoids @aws-sdk/credential-provider-cognito-identity, whose named export fails to
12
+ // resolve ("e is not a function") under some consumer bundlers.
13
+ async cognito(t, e) {
14
+ const s = await fetch(`https://cognito-identity.${this.cfg.region}.amazonaws.com/`, {
15
+ method: "POST",
16
+ headers: {
17
+ "Content-Type": "application/x-amz-json-1.1",
18
+ "X-Amz-Target": `AWSCognitoIdentityService.${t}`
19
+ },
20
+ body: JSON.stringify(e)
21
+ });
22
+ if (!s.ok) throw new Error(`Cognito ${t} failed: ${s.status} ${await s.text()}`);
23
+ return s.json();
24
+ }
25
+ async credentials() {
26
+ const t = `ufp:identity:${this.cfg.identityPoolId}`;
27
+ let e = null;
28
+ try {
29
+ e = localStorage.getItem(t);
30
+ } catch {
31
+ }
32
+ if (!e) {
33
+ e = (await this.cognito("GetId", { IdentityPoolId: this.cfg.identityPoolId })).IdentityId;
34
+ try {
35
+ localStorage.setItem(t, e);
36
+ } catch {
37
+ }
38
+ }
39
+ const { Credentials: s } = await this.cognito("GetCredentialsForIdentity", { IdentityId: e });
40
+ return {
41
+ accessKeyId: s.AccessKeyId,
42
+ secretAccessKey: s.SecretKey,
43
+ sessionToken: s.SessionToken,
44
+ expiration: new Date(s.Expiration * 1e3)
45
+ };
46
+ }
47
+ async s3() {
48
+ if (this._s3) return this._s3;
49
+ const { S3Client: t } = await import("@aws-sdk/client-s3");
50
+ return this._s3 = new t({
51
+ region: this.cfg.region,
52
+ credentials: () => this.credentials()
53
+ }), this._s3;
54
+ }
55
+ async pageHash(t) {
56
+ const e = new TextEncoder().encode(t), s = await crypto.subtle.digest("SHA-256", e);
57
+ return Array.from(new Uint8Array(s)).map((n) => n.toString(16).padStart(2, "0")).join("").slice(0, 16);
58
+ }
59
+ async put(t, e, s) {
60
+ const { PutObjectCommand: n } = await import("@aws-sdk/client-s3");
61
+ await (await this.s3()).send(new n({
62
+ Bucket: this.cfg.bucket,
63
+ Key: t,
64
+ Body: e,
65
+ ContentType: s
66
+ }));
67
+ }
68
+ async getJson(t) {
69
+ const { GetObjectCommand: e } = await import("@aws-sdk/client-s3"), i = await (await (await this.s3()).send(new e({ Bucket: this.cfg.bucket, Key: t }))).Body.transformToString();
70
+ return JSON.parse(i);
71
+ }
72
+ async listKeys(t) {
73
+ const { ListObjectsV2Command: e } = await import("@aws-sdk/client-s3"), s = await this.s3(), n = [];
74
+ let i;
75
+ do {
76
+ const o = await s.send(new e({
77
+ Bucket: this.cfg.bucket,
78
+ Prefix: t,
79
+ ContinuationToken: i
80
+ }));
81
+ for (const a of o.Contents ?? [])
82
+ a.Key && n.push(a.Key);
83
+ i = o.NextContinuationToken;
84
+ } while (i);
85
+ return n;
86
+ }
87
+ indexKey(t) {
88
+ return `ufp/_index/${t}.json`;
89
+ }
90
+ async lookupComment(t) {
91
+ const { p: e, h: s } = await this.getJson(this.indexKey(t));
92
+ return { key: `ufp/${e}/${s}/comments/${t}.json` };
93
+ }
94
+ async addComment(t) {
95
+ const e = await this.pageHash(t.pageUrl), s = crypto.randomUUID();
96
+ return await Promise.all([
97
+ this.put(
98
+ `ufp/${t.projectKey}/${e}/comments/${s}.json`,
99
+ JSON.stringify({ id: s, ...t }),
100
+ "application/json"
101
+ ),
102
+ this.put(
103
+ this.indexKey(s),
104
+ JSON.stringify({ p: t.projectKey, h: e }),
105
+ "application/json"
106
+ )
107
+ ]), s;
108
+ }
109
+ async getComments(t, e) {
110
+ const s = await this.pageHash(t), n = await this.listKeys(`ufp/${e}/${s}/comments/`);
111
+ return (await Promise.all(
112
+ n.map(
113
+ (o) => this.getJson(o).catch(() => null)
114
+ )
115
+ )).filter((o) => o !== null && !o.deleted).sort((o, a) => a.createdAt - o.createdAt);
116
+ }
117
+ async updateComment(t, e) {
118
+ const { key: s } = await this.lookupComment(t), n = await this.getJson(s);
119
+ await this.put(s, JSON.stringify({ ...n, ...e }), "application/json");
120
+ }
121
+ async deleteComment(t) {
122
+ const { key: e } = await this.lookupComment(t), s = await this.getJson(e);
123
+ await this.put(e, JSON.stringify({ ...s, deleted: !0 }), "application/json");
124
+ }
125
+ async addReply(t) {
126
+ const e = crypto.randomUUID();
127
+ return await this.put(
128
+ `ufp/replies/${t.commentId}/${e}.json`,
129
+ JSON.stringify({ id: e, ...t }),
130
+ "application/json"
131
+ ), e;
132
+ }
133
+ async getReplies(t) {
134
+ const e = await this.listKeys(`ufp/replies/${t}/`);
135
+ return (await Promise.all(
136
+ e.map((n) => this.getJson(n).catch(() => null))
137
+ )).filter((n) => n !== null).sort((n, i) => n.createdAt - i.createdAt);
138
+ }
139
+ subscribeToComments(t, e, s) {
140
+ let n = !0;
141
+ const i = this.cfg.pollInterval ?? 5e3, o = async () => {
142
+ if (n) {
143
+ try {
144
+ const a = await this.getComments(t, e);
145
+ n && s(a);
146
+ } catch (a) {
147
+ console.error("[ui-feedback-plugin] AWS poll error:", a);
148
+ }
149
+ n && setTimeout(o, i);
150
+ }
151
+ };
152
+ return o(), () => {
153
+ n = !1;
154
+ };
155
+ }
156
+ async uploadScreenshot(t, e) {
157
+ const { p: s, h: n } = await this.getJson(this.indexKey(t)), i = `ufp/${s}/${n}/screenshots/${t}.png`, o = e.split(",")[1], a = atob(o), y = new Uint8Array(a.length);
158
+ for (let r = 0; r < a.length; r++) y[r] = a.charCodeAt(r);
159
+ return await this.put(i, y, "image/png"), `https://${this.cfg.bucket}.s3.${this.cfg.region}.amazonaws.com/${i}`;
160
+ }
161
+ }
162
+ export {
163
+ u as AWSAdapter
164
+ };
165
+ //# sourceMappingURL=aws-DyQmIBI9.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-DyQmIBI9.mjs","sources":["../src/adapters/aws.ts"],"sourcesContent":["// AWS Cognito Identity Pool adapter — browser talks directly to S3, no backend required.\n// Requires @aws-sdk/client-s3.\n//\n// ── AWS SETUP ────────────────────────────────────────────────────────────────────\n//\n// 1. CREATE S3 BUCKET\n// - Keep \"Block all public access\" ON (we'll add a narrow public policy for screenshots).\n// - Enable versioning (optional, helpful for recovery).\n//\n// 2. CONFIGURE CORS (required for browser access)\n// Go to Bucket → Permissions → CORS and paste:\n// [\n// {\n// \"AllowedOrigins\": [\"https://your-domain.com\"],\n// \"AllowedMethods\": [\"GET\", \"PUT\", \"HEAD\"],\n// \"AllowedHeaders\": [\"*\"],\n// \"ExposeHeaders\": [\"ETag\"],\n// \"MaxAgeSeconds\": 3000\n// }\n// ]\n// Use \"*\" for AllowedOrigins during local dev, restrict to real domains in production.\n//\n// 3. ADD BUCKET POLICY (public read for screenshots only)\n// Go to Bucket → Permissions → Bucket policy and paste (replace YOUR_BUCKET):\n// {\n// \"Version\": \"2012-10-17\",\n// \"Statement\": [{\n// \"Sid\": \"PublicReadScreenshots\",\n// \"Effect\": \"Allow\",\n// \"Principal\": \"*\",\n// \"Action\": \"s3:GetObject\",\n// \"Resource\": \"arn:aws:s3:::YOUR_BUCKET/ufp/*/screenshots/*\"\n// }]\n// }\n// Comments and replies remain private (only accessible via Cognito credentials).\n//\n// 4. CREATE IAM POLICY (least privilege — see README for full JSON)\n// Allows:\n// - s3:PutObject on ufp/*/comments/*.json (max 50 KB)\n// - s3:PutObject on ufp/replies/*/*.json (max 50 KB)\n// - s3:PutObject on ufp/_index/*.json (max 50 KB)\n// - s3:PutObject on ufp/*/screenshots/*.png (max 3 MB)\n// - s3:GetObject on ufp/*\n// - s3:ListBucket on the bucket with prefix ufp/*\n// NO s3:DeleteObject — soft delete is used instead.\n//\n// 5. CREATE IAM ROLE\n// - Trusted entity: Web Identity\n// - Identity provider: Amazon Cognito\n// - Attach the policy from step 4\n//\n// 6. CREATE COGNITO IDENTITY POOL\n// - Enable unauthenticated identities\n// - Unauthenticated role: the IAM role from step 5\n// - Authenticated role: none (or a different role)\n// - Copy the Identity Pool ID (format: us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)\n//\n// 7. CONFIGURE THE PLUGIN\n// initFeedbackPlugin({\n// backend: {\n// provider: 'aws',\n// region: 'us-east-1',\n// bucket: 'your-bucket-name',\n// identityPoolId: 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',\n// },\n// projectKey: 'my-project',\n// })\n//\n// ── DATA LAYOUT IN S3 ────────────────────────────────────────────────────────────\n//\n// ufp/{projectKey}/{pageHash}/comments/{commentId}.json\n// ufp/{projectKey}/{pageHash}/screenshots/{commentId}.png ← publicly readable\n// ufp/replies/{commentId}/{replyId}.json\n// ufp/_index/{commentId}.json ← { \"p\": projectKey, \"h\": pageHash }\n//\n// ── SOFT DELETE ──────────────────────────────────────────────────────────────────\n// deleteComment overwrites the comment JSON with { ...comment, deleted: true }.\n// The file stays in S3 but is filtered out on read. No s3:DeleteObject needed.\n//\n// ── REAL-TIME ────────────────────────────────────────────────────────────────────\n// S3 has no push. subscribeToComments polls on a configurable interval (default 5s).\n\nimport type { FeedbackComment, Reply, DatabaseAdapter, ScreenshotAdapter, AWSProviderConfig } from '../core/types'\nimport type { S3Client as S3ClientType } from '@aws-sdk/client-s3'\n\nexport class AWSAdapter implements DatabaseAdapter, ScreenshotAdapter {\n private cfg: AWSProviderConfig\n private _s3: S3ClientType | null = null\n\n constructor(config: AWSProviderConfig) {\n this.cfg = config\n }\n\n // Minimal Cognito Identity Pool credential provider using plain fetch.\n // Avoids @aws-sdk/credential-provider-cognito-identity, whose named export fails to\n // resolve (\"e is not a function\") under some consumer bundlers.\n private async cognito(target: string, body: object): Promise<any> {\n const res = await fetch(`https://cognito-identity.${this.cfg.region}.amazonaws.com/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-amz-json-1.1',\n 'X-Amz-Target': `AWSCognitoIdentityService.${target}`,\n },\n body: JSON.stringify(body),\n })\n if (!res.ok) throw new Error(`Cognito ${target} failed: ${res.status} ${await res.text()}`)\n return res.json()\n }\n\n private async credentials() {\n const storageKey = `ufp:identity:${this.cfg.identityPoolId}`\n let identityId: string | null = null\n try { identityId = localStorage.getItem(storageKey) } catch { /* ignore */ }\n if (!identityId) {\n identityId = (await this.cognito('GetId', { IdentityPoolId: this.cfg.identityPoolId })).IdentityId as string\n try { localStorage.setItem(storageKey, identityId) } catch { /* ignore */ }\n }\n const { Credentials: c } = await this.cognito('GetCredentialsForIdentity', { IdentityId: identityId })\n return {\n accessKeyId: c.AccessKeyId as string,\n secretAccessKey: c.SecretKey as string,\n sessionToken: c.SessionToken as string,\n expiration: new Date(c.Expiration * 1000),\n }\n }\n\n private async s3(): Promise<S3ClientType> {\n if (this._s3) return this._s3\n const { S3Client } = await import('@aws-sdk/client-s3')\n this._s3 = new S3Client({\n region: this.cfg.region,\n credentials: () => this.credentials(),\n })\n return this._s3\n }\n\n private async pageHash(url: string): Promise<string> {\n const data = new TextEncoder().encode(url)\n const buf = await crypto.subtle.digest('SHA-256', data)\n return Array.from(new Uint8Array(buf))\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n .slice(0, 16)\n }\n\n private async put(key: string, body: string | Uint8Array, contentType: string): Promise<void> {\n const { PutObjectCommand } = await import('@aws-sdk/client-s3')\n const client = await this.s3()\n await client.send(new PutObjectCommand({\n Bucket: this.cfg.bucket,\n Key: key,\n Body: body,\n ContentType: contentType,\n }))\n }\n\n private async getJson<T>(key: string): Promise<T> {\n const { GetObjectCommand } = await import('@aws-sdk/client-s3')\n const client = await this.s3()\n const res = await client.send(new GetObjectCommand({ Bucket: this.cfg.bucket, Key: key }))\n const text = await res.Body!.transformToString()\n return JSON.parse(text) as T\n }\n\n private async listKeys(prefix: string): Promise<string[]> {\n const { ListObjectsV2Command } = await import('@aws-sdk/client-s3')\n const client = await this.s3()\n const keys: string[] = []\n let token: string | undefined\n do {\n const res = await client.send(new ListObjectsV2Command({\n Bucket: this.cfg.bucket,\n Prefix: prefix,\n ContinuationToken: token,\n }))\n for (const obj of res.Contents ?? []) {\n if (obj.Key) keys.push(obj.Key)\n }\n token = res.NextContinuationToken\n } while (token)\n return keys\n }\n\n private indexKey(id: string) {\n return `ufp/_index/${id}.json`\n }\n\n private async lookupComment(id: string): Promise<{ key: string }> {\n const { p, h } = await this.getJson<{ p: string; h: string }>(this.indexKey(id))\n return { key: `ufp/${p}/${h}/comments/${id}.json` }\n }\n\n async addComment(comment: Omit<FeedbackComment, 'id'>): Promise<string> {\n const hash = await this.pageHash(comment.pageUrl)\n const id = crypto.randomUUID()\n await Promise.all([\n this.put(\n `ufp/${comment.projectKey}/${hash}/comments/${id}.json`,\n JSON.stringify({ id, ...comment }),\n 'application/json'\n ),\n this.put(\n this.indexKey(id),\n JSON.stringify({ p: comment.projectKey, h: hash }),\n 'application/json'\n ),\n ])\n return id\n }\n\n async getComments(pageUrl: string, projectKey: string): Promise<FeedbackComment[]> {\n const hash = await this.pageHash(pageUrl)\n const keys = await this.listKeys(`ufp/${projectKey}/${hash}/comments/`)\n const rows = await Promise.all(\n keys.map(k =>\n this.getJson<FeedbackComment & { deleted?: boolean }>(k).catch(() => null)\n )\n )\n return rows\n .filter((r): r is FeedbackComment => r !== null && !r.deleted)\n .sort((a, b) => b.createdAt - a.createdAt)\n }\n\n async updateComment(id: string, data: Partial<FeedbackComment>): Promise<void> {\n const { key } = await this.lookupComment(id)\n const existing = await this.getJson<FeedbackComment>(key)\n await this.put(key, JSON.stringify({ ...existing, ...data }), 'application/json')\n }\n\n async deleteComment(id: string): Promise<void> {\n const { key } = await this.lookupComment(id)\n const existing = await this.getJson<FeedbackComment>(key)\n // Soft delete — overwrite with deleted flag. No s3:DeleteObject permission needed.\n await this.put(key, JSON.stringify({ ...existing, deleted: true }), 'application/json')\n }\n\n async addReply(reply: Omit<Reply, 'id'>): Promise<string> {\n const id = crypto.randomUUID()\n await this.put(\n `ufp/replies/${reply.commentId}/${id}.json`,\n JSON.stringify({ id, ...reply }),\n 'application/json'\n )\n return id\n }\n\n async getReplies(commentId: string): Promise<Reply[]> {\n const keys = await this.listKeys(`ufp/replies/${commentId}/`)\n const rows = await Promise.all(\n keys.map(k => this.getJson<Reply>(k).catch(() => null))\n )\n return rows\n .filter((r): r is Reply => r !== null)\n .sort((a, b) => a.createdAt - b.createdAt)\n }\n\n subscribeToComments(\n pageUrl: string,\n projectKey: string,\n callback: (comments: FeedbackComment[]) => void\n ): () => void {\n let active = true\n const interval = this.cfg.pollInterval ?? 5000\n\n const poll = async () => {\n if (!active) return\n try {\n const comments = await this.getComments(pageUrl, projectKey)\n if (active) callback(comments)\n } catch (err) {\n console.error('[ui-feedback-plugin] AWS poll error:', err)\n }\n if (active) setTimeout(poll, interval)\n }\n\n poll()\n return () => { active = false }\n }\n\n async uploadScreenshot(commentId: string, dataUrl: string): Promise<string> {\n const { p, h } = await this.getJson<{ p: string; h: string }>(this.indexKey(commentId))\n const key = `ufp/${p}/${h}/screenshots/${commentId}.png`\n\n const base64 = dataUrl.split(',')[1]\n const binary = atob(base64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n\n await this.put(key, bytes, 'image/png')\n return `https://${this.cfg.bucket}.s3.${this.cfg.region}.amazonaws.com/${key}`\n }\n}\n"],"names":["AWSAdapter","config","__publicField","target","body","res","storageKey","identityId","c","S3Client","url","data","buf","b","key","contentType","PutObjectCommand","GetObjectCommand","text","prefix","ListObjectsV2Command","client","keys","token","obj","id","p","h","comment","hash","pageUrl","projectKey","k","r","a","existing","reply","commentId","callback","active","interval","poll","comments","err","dataUrl","base64","binary","bytes","i"],"mappings":"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"}
@@ -1251,7 +1251,7 @@ async function he(e) {
1251
1251
  return { db: n, screenshot: n };
1252
1252
  }
1253
1253
  if (t.provider === "aws") {
1254
- const { AWSAdapter: r } = await import("./aws-DieAIoX4.mjs"), n = new r(t);
1254
+ const { AWSAdapter: r } = await import("./aws-DyQmIBI9.mjs"), n = new r(t);
1255
1255
  return { db: n, screenshot: n };
1256
1256
  }
1257
1257
  if (t.provider === "local") {
@@ -2977,7 +2977,7 @@ Content-Type: `+l.contentType+`\r
2977
2977
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2978
2978
  * See the License for the specific language governing permissions and
2979
2979
  * limitations under the License.
2980
- */const ow="storage";function TS(A,e,t,r){return A=At(A),ES(A,e,t,r)}function SS(A){return A=At(A),vS(A)}function RS(A,e){return A=At(A),IS(A,e)}function xS(A=_f(),e){A=At(A);const r=Bf(A,ow).getImmediate({identifier:e}),n=sf("storage");return n&&kS(r,...n),r}function kS(A,e,t,r={}){FS(A,e,t,r)}function LS(A,{instanceIdentifier:e}){const t=A.getProvider("app").getImmediate(),r=A.getProvider("auth-internal"),n=A.getProvider("app-check-internal");return new Tl(t,r,n,e,yf)}function DS(){Tn(new Qr(ow,LS,"PUBLIC").setMultipleInstances(!0)),mA(sw,iw,""),mA(sw,iw,"esm2017")}DS();class HS{constructor(e){it(this,"db");it(this,"storage");const{provider:t,...r}=e;let n;const s=cQ().find(i=>i.name==="ui-feedback-plugin");s?n=s:n=Cf(r,"ui-feedback-plugin"),this.db=nT(n),this.storage=xS(n)}async addComment(e){return(await Op(Zn(this.db,"ufp_comments"),e)).id}async getComments(e,t){const r=Sp(Zn(this.db,"ufp_comments"),co("pageUrl","==",e),co("projectKey","==",t));return(await Hp(r)).docs.map(i=>({id:i.id,...i.data()})).sort((i,o)=>o.createdAt-i.createdAt)}async updateComment(e,t){await BT(al(this.db,"ufp_comments",e),t)}async deleteComment(e){await yT(al(this.db,"ufp_comments",e))}async addReply(e){return(await Op(Zn(this.db,"ufp_comments",e.commentId,"replies"),e)).id}async getReplies(e){return(await Hp(Zn(this.db,"ufp_comments",e,"replies"))).docs.map(n=>({id:n.id,...n.data()})).sort((n,s)=>n.createdAt-s.createdAt)}subscribeToComments(e,t,r){const n=Sp(Zn(this.db,"ufp_comments"),co("pageUrl","==",e),co("projectKey","==",t));return CT(n,s=>{const i=s.docs.map(o=>({id:o.id,...o.data()})).sort((o,a)=>a.createdAt-o.createdAt);r(i)},s=>{console.error("[ui-feedback-plugin] Firestore listener error:",s)})}async uploadScreenshot(e,t){const r=RS(this.storage,`ufp_screenshots/${e}.png`);return await TS(r,t,"data_url"),SS(r)}}const OS=Object.freeze(Object.defineProperty({__proto__:null,FirebaseAdapter:HS},Symbol.toStringTag,{value:"Module"}));function PS(A){return{id:A.id,pageUrl:A.page_url,projectKey:A.project_key,authorName:A.author_name,text:A.text,screenshotUrl:A.screenshot_url??"",annotation:A.annotation,resolved:A.resolved,createdAt:A.created_at}}function NS(A){return{page_url:A.pageUrl,project_key:A.projectKey,author_name:A.authorName,text:A.text,screenshot_url:A.screenshotUrl,annotation:A.annotation,resolved:A.resolved,created_at:A.createdAt}}function MS(A){return{id:A.id,commentId:A.comment_id,authorName:A.author_name,text:A.text,createdAt:A.created_at}}function VS(A){return{comment_id:A.commentId,author_name:A.authorName,text:A.text,created_at:A.createdAt}}class KS{constructor(e,t){it(this,"client");it(this,"_url");it(this,"_key");it(this,"_client",null);this._url=e,this._key=t}async _getClient(){if(this._client)return this._client;try{const{createClient:e}=await Promise.resolve().then(()=>Mx);return this._client=e(this._url,this._key),this._client}catch{throw new Error("[ui-feedback-plugin] @supabase/supabase-js is not installed. Run: npm install @supabase/supabase-js")}}async addComment(e){const t=await this._getClient(),{data:r,error:n}=await t.from("ufp_comments").insert(NS(e)).select("id").single();if(n)throw n;return r.id}async getComments(e,t){const r=await this._getClient(),{data:n,error:s}=await r.from("ufp_comments").select("*").eq("page_url",e).eq("project_key",t);if(s)throw s;return(n??[]).map(PS).sort((o,a)=>a.createdAt-o.createdAt)}async updateComment(e,t){const r=await this._getClient(),n={};t.resolved!==void 0&&(n.resolved=t.resolved),t.screenshotUrl!==void 0&&(n.screenshot_url=t.screenshotUrl),t.text!==void 0&&(n.text=t.text),t.annotation!==void 0&&(n.annotation=t.annotation);const{error:s}=await r.from("ufp_comments").update(n).eq("id",e);if(s)throw s}async deleteComment(e){const t=await this._getClient(),{error:r}=await t.from("ufp_comments").delete().eq("id",e);if(r)throw r}async addReply(e){const t=await this._getClient(),{data:r,error:n}=await t.from("ufp_replies").insert(VS(e)).select("id").single();if(n)throw n;return r.id}async getReplies(e){const t=await this._getClient(),{data:r,error:n}=await t.from("ufp_replies").select("*").eq("comment_id",e);if(n)throw n;return(r??[]).map(MS).sort((i,o)=>i.createdAt-o.createdAt)}subscribeToComments(e,t,r){let n=null,s=!0;const i=async()=>{if(s)try{const o=await this.getComments(e,t);s&&r(o)}catch(o){console.error("[ui-feedback-plugin] Supabase fetch error:",o)}};return i(),this._getClient().then(o=>{s&&(n=o.channel("ufp-comments").on("postgres_changes",{event:"*",schema:"public",table:"ufp_comments"},()=>{i()}).subscribe())}).catch(console.error),()=>{s=!1,n&&this._getClient().then(o=>o.removeChannel(n)).catch(()=>{})}}async uploadScreenshot(e,t){var p;const r=await this._getClient(),[n,s]=t.split(","),i=((p=n.match(/:(.*?);/))==null?void 0:p[1])??"image/png",o=atob(s),a=new Uint8Array(o.length);for(let m=0;m<o.length;m++)a[m]=o.charCodeAt(m);const l=new Blob([a],{type:i}),u=`${e}.png`,{error:d}=await r.storage.from("ufp-screenshots").upload(u,l,{contentType:"image/png",upsert:!0});if(d)throw d;const{data:g}=r.storage.from("ufp-screenshots").getPublicUrl(u);return g.publicUrl}}const $S=Object.freeze(Object.defineProperty({__proto__:null,SupabaseAdapter:KS},Symbol.toStringTag,{value:"Module"}));class jS{constructor(e){it(this,"cfg");it(this,"_s3",null);this.cfg=e}async s3(){if(this._s3)return this._s3;const[{S3Client:e},{fromCognitoIdentityPool:t}]=await Promise.all([import("@aws-sdk/client-s3"),import("@aws-sdk/credential-provider-cognito-identity")]);return this._s3=new e({region:this.cfg.region,credentials:t({identityPoolId:this.cfg.identityPoolId,clientConfig:{region:this.cfg.region}})}),this._s3}async pageHash(e){const t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(n=>n.toString(16).padStart(2,"0")).join("").slice(0,16)}async put(e,t,r){const{PutObjectCommand:n}=await import("@aws-sdk/client-s3");await(await this.s3()).send(new n({Bucket:this.cfg.bucket,Key:e,Body:t,ContentType:r}))}async getJson(e){const{GetObjectCommand:t}=await import("@aws-sdk/client-s3"),s=await(await(await this.s3()).send(new t({Bucket:this.cfg.bucket,Key:e}))).Body.transformToString();return JSON.parse(s)}async listKeys(e){const{ListObjectsV2Command:t}=await import("@aws-sdk/client-s3"),r=await this.s3(),n=[];let s;do{const i=await r.send(new t({Bucket:this.cfg.bucket,Prefix:e,ContinuationToken:s}));for(const o of i.Contents??[])o.Key&&n.push(o.Key);s=i.NextContinuationToken}while(s);return n}indexKey(e){return`ufp/_index/${e}.json`}async lookupComment(e){const{p:t,h:r}=await this.getJson(this.indexKey(e));return{key:`ufp/${t}/${r}/comments/${e}.json`}}async addComment(e){const t=await this.pageHash(e.pageUrl),r=crypto.randomUUID();return await Promise.all([this.put(`ufp/${e.projectKey}/${t}/comments/${r}.json`,JSON.stringify({id:r,...e}),"application/json"),this.put(this.indexKey(r),JSON.stringify({p:e.projectKey,h:t}),"application/json")]),r}async getComments(e,t){const r=await this.pageHash(e),n=await this.listKeys(`ufp/${t}/${r}/comments/`);return(await Promise.all(n.map(i=>this.getJson(i).catch(()=>null)))).filter(i=>i!==null&&!i.deleted).sort((i,o)=>o.createdAt-i.createdAt)}async updateComment(e,t){const{key:r}=await this.lookupComment(e),n=await this.getJson(r);await this.put(r,JSON.stringify({...n,...t}),"application/json")}async deleteComment(e){const{key:t}=await this.lookupComment(e),r=await this.getJson(t);await this.put(t,JSON.stringify({...r,deleted:!0}),"application/json")}async addReply(e){const t=crypto.randomUUID();return await this.put(`ufp/replies/${e.commentId}/${t}.json`,JSON.stringify({id:t,...e}),"application/json"),t}async getReplies(e){const t=await this.listKeys(`ufp/replies/${e}/`);return(await Promise.all(t.map(n=>this.getJson(n).catch(()=>null)))).filter(n=>n!==null).sort((n,s)=>n.createdAt-s.createdAt)}subscribeToComments(e,t,r){let n=!0;const s=this.cfg.pollInterval??5e3,i=async()=>{if(n){try{const o=await this.getComments(e,t);n&&r(o)}catch(o){console.error("[ui-feedback-plugin] AWS poll error:",o)}n&&setTimeout(i,s)}};return i(),()=>{n=!1}}async uploadScreenshot(e,t){const{p:r,h:n}=await this.getJson(this.indexKey(e)),s=`ufp/${r}/${n}/screenshots/${e}.png`,i=t.split(",")[1],o=atob(i),a=new Uint8Array(o.length);for(let l=0;l<o.length;l++)a[l]=o.charCodeAt(l);return await this.put(s,a,"image/png"),`https://${this.cfg.bucket}.s3.${this.cfg.region}.amazonaws.com/${s}`}}const GS=Object.freeze(Object.defineProperty({__proto__:null,AWSAdapter:jS},Symbol.toStringTag,{value:"Module"}));class WS{constructor(){it(this,"listeners",new Set)}getCommentsFromStorage(){const e=sessionStorage.getItem("ufp_comments");return e?JSON.parse(e):[]}saveCommentsToStorage(e){sessionStorage.setItem("ufp_comments",JSON.stringify(e)),this.notifyListeners()}getRepliesFromStorage(){const e=sessionStorage.getItem("ufp_replies");return e?JSON.parse(e):[]}saveRepliesToStorage(e){sessionStorage.setItem("ufp_replies",JSON.stringify(e))}notifyListeners(){const e=this.getCommentsFromStorage();for(const t of this.listeners)t(e)}async addComment(e){const t=this.getCommentsFromStorage(),r=Math.random().toString(36).substring(2,9),n={...e,id:r};return t.push(n),this.saveCommentsToStorage(t),r}async getComments(e,t){return this.getCommentsFromStorage().filter(n=>n.pageUrl===e&&n.projectKey===t)}async updateComment(e,t){const r=this.getCommentsFromStorage(),n=r.findIndex(s=>s.id===e);n!==-1&&(r[n]={...r[n],...t},this.saveCommentsToStorage(r))}async deleteComment(e){const r=this.getCommentsFromStorage().filter(i=>i.id!==e);this.saveCommentsToStorage(r);const s=this.getRepliesFromStorage().filter(i=>i.commentId!==e);this.saveRepliesToStorage(s)}async addReply(e){const t=this.getRepliesFromStorage(),r=Math.random().toString(36).substring(2,9),n={...e,id:r};return t.push(n),this.saveRepliesToStorage(t),r}async getReplies(e){return this.getRepliesFromStorage().filter(r=>r.commentId===e)}subscribeToComments(e,t,r){const n=s=>{r(s.filter(i=>i.pageUrl===e&&i.projectKey===t))};return this.listeners.add(n),n(this.getCommentsFromStorage()),()=>{this.listeners.delete(n)}}async uploadScreenshot(e,t){return t}}const qS=Object.freeze(Object.defineProperty({__proto__:null,LocalAdapter:WS},Symbol.toStringTag,{value:"Module"}));function fo(A,e){var t={};for(var r in A)Object.prototype.hasOwnProperty.call(A,r)&&e.indexOf(r)<0&&(t[r]=A[r]);if(A!=null&&typeof Object.getOwnPropertySymbols=="function")for(var n=0,r=Object.getOwnPropertySymbols(A);n<r.length;n++)e.indexOf(r[n])<0&&Object.prototype.propertyIsEnumerable.call(A,r[n])&&(t[r[n]]=A[r[n]]);return t}function JS(A,e,t,r){function n(s){return s instanceof t?s:new t(function(i){i(s)})}return new(t||(t=Promise))(function(s,i){function o(u){try{l(r.next(u))}catch(d){i(d)}}function a(u){try{l(r.throw(u))}catch(d){i(d)}}function l(u){u.done?s(u.value):n(u.value).then(o,a)}l((r=r.apply(A,e||[])).next())})}typeof SuppressedError=="function"&&SuppressedError;const zS=A=>A?(...e)=>A(...e):(...e)=>fetch(...e);class go extends Error{constructor(e,t="FunctionsError",r){super(e),this.name=t,this.context=r}toJSON(){return{name:this.name,message:this.message,context:this.context}}}class aw extends go{constructor(e){super("Failed to send a request to the Edge Function","FunctionsFetchError",e)}}class Sl extends go{constructor(e){super("Relay Error invoking the Edge Function","FunctionsRelayError",e)}}class Rl extends go{constructor(e){super("Edge Function returned a non-2xx status code","FunctionsHttpError",e)}}var po;(function(A){A.Any="any",A.ApNortheast1="ap-northeast-1",A.ApNortheast2="ap-northeast-2",A.ApSouth1="ap-south-1",A.ApSoutheast1="ap-southeast-1",A.ApSoutheast2="ap-southeast-2",A.CaCentral1="ca-central-1",A.EuCentral1="eu-central-1",A.EuWest1="eu-west-1",A.EuWest2="eu-west-2",A.EuWest3="eu-west-3",A.SaEast1="sa-east-1",A.UsEast1="us-east-1",A.UsWest1="us-west-1",A.UsWest2="us-west-2"})(po||(po={}));class XS{constructor(e,{headers:t={},customFetch:r,region:n=po.Any}={}){this.url=e,this.headers=t,this.region=n,this.fetch=zS(r)}setAuth(e){this.headers.Authorization=`Bearer ${e}`}invoke(e){return JS(this,arguments,void 0,function*(t,r={}){var n;let s,i;try{const{headers:o,method:a,body:l,signal:u,timeout:d}=r;let g={},{region:p}=r;p||(p=this.region);const m=new URL(`${this.url}/${t}`);p&&p!=="any"&&(g["x-region"]=p,m.searchParams.set("forceFunctionRegion",p));let _;l&&(o&&!Object.prototype.hasOwnProperty.call(o,"Content-Type")||!o)?typeof Blob<"u"&&l instanceof Blob||l instanceof ArrayBuffer?(g["Content-Type"]="application/octet-stream",_=l):typeof l=="string"?(g["Content-Type"]="text/plain",_=l):typeof FormData<"u"&&l instanceof FormData?_=l:(g["Content-Type"]="application/json",_=JSON.stringify(l)):l&&typeof l!="string"&&!(typeof Blob<"u"&&l instanceof Blob)&&!(l instanceof ArrayBuffer)&&!(typeof FormData<"u"&&l instanceof FormData)?_=JSON.stringify(l):_=l;let B=u;d&&(i=new AbortController,s=setTimeout(()=>i.abort(),d),u?(B=i.signal,u.addEventListener("abort",()=>i.abort())):B=i.signal);const b=yield this.fetch(m.toString(),{method:a||"POST",headers:Object.assign(Object.assign(Object.assign({},g),this.headers),o),body:_,signal:B}).catch(D=>{throw new aw(D)}),F=b.headers.get("x-relay-error");if(F&&F==="true")throw new Sl(b);if(!b.ok)throw new Rl(b);let I=((n=b.headers.get("Content-Type"))!==null&&n!==void 0?n:"text/plain").split(";")[0].trim(),S;return I==="application/json"?S=yield b.json():I==="application/octet-stream"||I==="application/pdf"?S=yield b.blob():I==="text/event-stream"?S=b:I==="multipart/form-data"?S=yield b.formData():S=yield b.text(),{data:S,error:null,response:b}}catch(o){return{data:null,error:o,response:o instanceof Rl||o instanceof Sl?o.context:void 0}}finally{s&&clearTimeout(s)}})}}const cw=3,lw=A=>Math.min(1e3*2**A,3e4),YS=[520,503],uw=["GET","HEAD","OPTIONS"];var xl=class extends Error{constructor(A){super(A.message),this.name="PostgrestError",this.details=A.details,this.hint=A.hint,this.code=A.code}toJSON(){return{name:this.name,message:this.message,details:this.details,hint:this.hint,code:this.code}}};function hw(A,e){return new Promise(t=>{if(e!=null&&e.aborted){t();return}const r=setTimeout(()=>{e==null||e.removeEventListener("abort",n),t()},A);function n(){clearTimeout(r),t()}e==null||e.addEventListener("abort",n)})}function ZS(A,e,t,r){return!(!r||t>=cw||!uw.includes(A)||!YS.includes(e))}var eR=class{constructor(A){var e,t,r,n,s;this.shouldThrowOnError=!1,this.retryEnabled=!0,this.method=A.method,this.url=A.url,this.headers=new Headers(A.headers),this.schema=A.schema,this.body=A.body,this.shouldThrowOnError=(e=A.shouldThrowOnError)!==null&&e!==void 0?e:!1,this.signal=A.signal,this.isMaybeSingle=(t=A.isMaybeSingle)!==null&&t!==void 0?t:!1,this.shouldStripNulls=(r=A.shouldStripNulls)!==null&&r!==void 0?r:!1,this.urlLengthLimit=(n=A.urlLengthLimit)!==null&&n!==void 0?n:8e3,this.retryEnabled=(s=A.retry)!==null&&s!==void 0?s:!0,A.fetch?this.fetch=A.fetch:this.fetch=fetch}throwOnError(){return this.shouldThrowOnError=!0,this}stripNulls(){if(this.headers.get("Accept")==="text/csv")throw new Error("stripNulls() cannot be used with csv()");return this.shouldStripNulls=!0,this}setHeader(A,e){return this.headers=new Headers(this.headers),this.headers.set(A,e),this}retry(A){return this.retryEnabled=A,this}then(A,e){var t=this;if(this.schema===void 0||(["GET","HEAD"].includes(this.method)?this.headers.set("Accept-Profile",this.schema):this.headers.set("Content-Profile",this.schema)),this.method!=="GET"&&this.method!=="HEAD"&&this.headers.set("Content-Type","application/json"),this.shouldStripNulls){const i=this.headers.get("Accept");i==="application/vnd.pgrst.object+json"?this.headers.set("Accept","application/vnd.pgrst.object+json;nulls=stripped"):(!i||i==="application/json")&&this.headers.set("Accept","application/vnd.pgrst.array+json;nulls=stripped")}const r=this.fetch;let s=(async()=>{let i=0;for(;;){const l={};t.headers.forEach((d,g)=>{l[g]=d}),i>0&&(l["X-Retry-Count"]=String(i));let u;try{u=await r(t.url.toString(),{method:t.method,headers:l,body:JSON.stringify(t.body,(d,g)=>typeof g=="bigint"?g.toString():g),signal:t.signal})}catch(d){if((d==null?void 0:d.name)==="AbortError"||(d==null?void 0:d.code)==="ABORT_ERR"||!uw.includes(t.method))throw d;if(t.retryEnabled&&i<cw){const g=lw(i);i++,await hw(g,t.signal);continue}throw d}if(ZS(t.method,u.status,i,t.retryEnabled)){var o,a;const d=(o=(a=u.headers)===null||a===void 0?void 0:a.get("Retry-After"))!==null&&o!==void 0?o:null,g=d!==null?Math.max(0,parseInt(d,10)||0)*1e3:lw(i);await u.text(),i++,await hw(g,t.signal);continue}return await t.processResponse(u)}})();return this.shouldThrowOnError||(s=s.catch(i=>{var o;let a="",l="",u="";const d=i==null?void 0:i.cause;if(d){var g,p,m,_;const F=(g=d==null?void 0:d.message)!==null&&g!==void 0?g:"",I=(p=d==null?void 0:d.code)!==null&&p!==void 0?p:"";a=`${(m=i==null?void 0:i.name)!==null&&m!==void 0?m:"FetchError"}: ${i==null?void 0:i.message}`,a+=`
2980
+ */const ow="storage";function TS(A,e,t,r){return A=At(A),ES(A,e,t,r)}function SS(A){return A=At(A),vS(A)}function RS(A,e){return A=At(A),IS(A,e)}function xS(A=_f(),e){A=At(A);const r=Bf(A,ow).getImmediate({identifier:e}),n=sf("storage");return n&&kS(r,...n),r}function kS(A,e,t,r={}){FS(A,e,t,r)}function LS(A,{instanceIdentifier:e}){const t=A.getProvider("app").getImmediate(),r=A.getProvider("auth-internal"),n=A.getProvider("app-check-internal");return new Tl(t,r,n,e,yf)}function DS(){Tn(new Qr(ow,LS,"PUBLIC").setMultipleInstances(!0)),mA(sw,iw,""),mA(sw,iw,"esm2017")}DS();class HS{constructor(e){it(this,"db");it(this,"storage");const{provider:t,...r}=e;let n;const s=cQ().find(i=>i.name==="ui-feedback-plugin");s?n=s:n=Cf(r,"ui-feedback-plugin"),this.db=nT(n),this.storage=xS(n)}async addComment(e){return(await Op(Zn(this.db,"ufp_comments"),e)).id}async getComments(e,t){const r=Sp(Zn(this.db,"ufp_comments"),co("pageUrl","==",e),co("projectKey","==",t));return(await Hp(r)).docs.map(i=>({id:i.id,...i.data()})).sort((i,o)=>o.createdAt-i.createdAt)}async updateComment(e,t){await BT(al(this.db,"ufp_comments",e),t)}async deleteComment(e){await yT(al(this.db,"ufp_comments",e))}async addReply(e){return(await Op(Zn(this.db,"ufp_comments",e.commentId,"replies"),e)).id}async getReplies(e){return(await Hp(Zn(this.db,"ufp_comments",e,"replies"))).docs.map(n=>({id:n.id,...n.data()})).sort((n,s)=>n.createdAt-s.createdAt)}subscribeToComments(e,t,r){const n=Sp(Zn(this.db,"ufp_comments"),co("pageUrl","==",e),co("projectKey","==",t));return CT(n,s=>{const i=s.docs.map(o=>({id:o.id,...o.data()})).sort((o,a)=>a.createdAt-o.createdAt);r(i)},s=>{console.error("[ui-feedback-plugin] Firestore listener error:",s)})}async uploadScreenshot(e,t){const r=RS(this.storage,`ufp_screenshots/${e}.png`);return await TS(r,t,"data_url"),SS(r)}}const OS=Object.freeze(Object.defineProperty({__proto__:null,FirebaseAdapter:HS},Symbol.toStringTag,{value:"Module"}));function PS(A){return{id:A.id,pageUrl:A.page_url,projectKey:A.project_key,authorName:A.author_name,text:A.text,screenshotUrl:A.screenshot_url??"",annotation:A.annotation,resolved:A.resolved,createdAt:A.created_at}}function NS(A){return{page_url:A.pageUrl,project_key:A.projectKey,author_name:A.authorName,text:A.text,screenshot_url:A.screenshotUrl,annotation:A.annotation,resolved:A.resolved,created_at:A.createdAt}}function MS(A){return{id:A.id,commentId:A.comment_id,authorName:A.author_name,text:A.text,createdAt:A.created_at}}function VS(A){return{comment_id:A.commentId,author_name:A.authorName,text:A.text,created_at:A.createdAt}}class KS{constructor(e,t){it(this,"client");it(this,"_url");it(this,"_key");it(this,"_client",null);this._url=e,this._key=t}async _getClient(){if(this._client)return this._client;try{const{createClient:e}=await Promise.resolve().then(()=>Mx);return this._client=e(this._url,this._key),this._client}catch{throw new Error("[ui-feedback-plugin] @supabase/supabase-js is not installed. Run: npm install @supabase/supabase-js")}}async addComment(e){const t=await this._getClient(),{data:r,error:n}=await t.from("ufp_comments").insert(NS(e)).select("id").single();if(n)throw n;return r.id}async getComments(e,t){const r=await this._getClient(),{data:n,error:s}=await r.from("ufp_comments").select("*").eq("page_url",e).eq("project_key",t);if(s)throw s;return(n??[]).map(PS).sort((o,a)=>a.createdAt-o.createdAt)}async updateComment(e,t){const r=await this._getClient(),n={};t.resolved!==void 0&&(n.resolved=t.resolved),t.screenshotUrl!==void 0&&(n.screenshot_url=t.screenshotUrl),t.text!==void 0&&(n.text=t.text),t.annotation!==void 0&&(n.annotation=t.annotation);const{error:s}=await r.from("ufp_comments").update(n).eq("id",e);if(s)throw s}async deleteComment(e){const t=await this._getClient(),{error:r}=await t.from("ufp_comments").delete().eq("id",e);if(r)throw r}async addReply(e){const t=await this._getClient(),{data:r,error:n}=await t.from("ufp_replies").insert(VS(e)).select("id").single();if(n)throw n;return r.id}async getReplies(e){const t=await this._getClient(),{data:r,error:n}=await t.from("ufp_replies").select("*").eq("comment_id",e);if(n)throw n;return(r??[]).map(MS).sort((i,o)=>i.createdAt-o.createdAt)}subscribeToComments(e,t,r){let n=null,s=!0;const i=async()=>{if(s)try{const o=await this.getComments(e,t);s&&r(o)}catch(o){console.error("[ui-feedback-plugin] Supabase fetch error:",o)}};return i(),this._getClient().then(o=>{s&&(n=o.channel("ufp-comments").on("postgres_changes",{event:"*",schema:"public",table:"ufp_comments"},()=>{i()}).subscribe())}).catch(console.error),()=>{s=!1,n&&this._getClient().then(o=>o.removeChannel(n)).catch(()=>{})}}async uploadScreenshot(e,t){var p;const r=await this._getClient(),[n,s]=t.split(","),i=((p=n.match(/:(.*?);/))==null?void 0:p[1])??"image/png",o=atob(s),a=new Uint8Array(o.length);for(let m=0;m<o.length;m++)a[m]=o.charCodeAt(m);const l=new Blob([a],{type:i}),u=`${e}.png`,{error:d}=await r.storage.from("ufp-screenshots").upload(u,l,{contentType:"image/png",upsert:!0});if(d)throw d;const{data:g}=r.storage.from("ufp-screenshots").getPublicUrl(u);return g.publicUrl}}const $S=Object.freeze(Object.defineProperty({__proto__:null,SupabaseAdapter:KS},Symbol.toStringTag,{value:"Module"}));class jS{constructor(e){it(this,"cfg");it(this,"_s3",null);this.cfg=e}async cognito(e,t){const r=await fetch(`https://cognito-identity.${this.cfg.region}.amazonaws.com/`,{method:"POST",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`AWSCognitoIdentityService.${e}`},body:JSON.stringify(t)});if(!r.ok)throw new Error(`Cognito ${e} failed: ${r.status} ${await r.text()}`);return r.json()}async credentials(){const e=`ufp:identity:${this.cfg.identityPoolId}`;let t=null;try{t=localStorage.getItem(e)}catch{}if(!t){t=(await this.cognito("GetId",{IdentityPoolId:this.cfg.identityPoolId})).IdentityId;try{localStorage.setItem(e,t)}catch{}}const{Credentials:r}=await this.cognito("GetCredentialsForIdentity",{IdentityId:t});return{accessKeyId:r.AccessKeyId,secretAccessKey:r.SecretKey,sessionToken:r.SessionToken,expiration:new Date(r.Expiration*1e3)}}async s3(){if(this._s3)return this._s3;const{S3Client:e}=await import("@aws-sdk/client-s3");return this._s3=new e({region:this.cfg.region,credentials:()=>this.credentials()}),this._s3}async pageHash(e){const t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(n=>n.toString(16).padStart(2,"0")).join("").slice(0,16)}async put(e,t,r){const{PutObjectCommand:n}=await import("@aws-sdk/client-s3");await(await this.s3()).send(new n({Bucket:this.cfg.bucket,Key:e,Body:t,ContentType:r}))}async getJson(e){const{GetObjectCommand:t}=await import("@aws-sdk/client-s3"),s=await(await(await this.s3()).send(new t({Bucket:this.cfg.bucket,Key:e}))).Body.transformToString();return JSON.parse(s)}async listKeys(e){const{ListObjectsV2Command:t}=await import("@aws-sdk/client-s3"),r=await this.s3(),n=[];let s;do{const i=await r.send(new t({Bucket:this.cfg.bucket,Prefix:e,ContinuationToken:s}));for(const o of i.Contents??[])o.Key&&n.push(o.Key);s=i.NextContinuationToken}while(s);return n}indexKey(e){return`ufp/_index/${e}.json`}async lookupComment(e){const{p:t,h:r}=await this.getJson(this.indexKey(e));return{key:`ufp/${t}/${r}/comments/${e}.json`}}async addComment(e){const t=await this.pageHash(e.pageUrl),r=crypto.randomUUID();return await Promise.all([this.put(`ufp/${e.projectKey}/${t}/comments/${r}.json`,JSON.stringify({id:r,...e}),"application/json"),this.put(this.indexKey(r),JSON.stringify({p:e.projectKey,h:t}),"application/json")]),r}async getComments(e,t){const r=await this.pageHash(e),n=await this.listKeys(`ufp/${t}/${r}/comments/`);return(await Promise.all(n.map(i=>this.getJson(i).catch(()=>null)))).filter(i=>i!==null&&!i.deleted).sort((i,o)=>o.createdAt-i.createdAt)}async updateComment(e,t){const{key:r}=await this.lookupComment(e),n=await this.getJson(r);await this.put(r,JSON.stringify({...n,...t}),"application/json")}async deleteComment(e){const{key:t}=await this.lookupComment(e),r=await this.getJson(t);await this.put(t,JSON.stringify({...r,deleted:!0}),"application/json")}async addReply(e){const t=crypto.randomUUID();return await this.put(`ufp/replies/${e.commentId}/${t}.json`,JSON.stringify({id:t,...e}),"application/json"),t}async getReplies(e){const t=await this.listKeys(`ufp/replies/${e}/`);return(await Promise.all(t.map(n=>this.getJson(n).catch(()=>null)))).filter(n=>n!==null).sort((n,s)=>n.createdAt-s.createdAt)}subscribeToComments(e,t,r){let n=!0;const s=this.cfg.pollInterval??5e3,i=async()=>{if(n){try{const o=await this.getComments(e,t);n&&r(o)}catch(o){console.error("[ui-feedback-plugin] AWS poll error:",o)}n&&setTimeout(i,s)}};return i(),()=>{n=!1}}async uploadScreenshot(e,t){const{p:r,h:n}=await this.getJson(this.indexKey(e)),s=`ufp/${r}/${n}/screenshots/${e}.png`,i=t.split(",")[1],o=atob(i),a=new Uint8Array(o.length);for(let l=0;l<o.length;l++)a[l]=o.charCodeAt(l);return await this.put(s,a,"image/png"),`https://${this.cfg.bucket}.s3.${this.cfg.region}.amazonaws.com/${s}`}}const GS=Object.freeze(Object.defineProperty({__proto__:null,AWSAdapter:jS},Symbol.toStringTag,{value:"Module"}));class WS{constructor(){it(this,"listeners",new Set)}getCommentsFromStorage(){const e=sessionStorage.getItem("ufp_comments");return e?JSON.parse(e):[]}saveCommentsToStorage(e){sessionStorage.setItem("ufp_comments",JSON.stringify(e)),this.notifyListeners()}getRepliesFromStorage(){const e=sessionStorage.getItem("ufp_replies");return e?JSON.parse(e):[]}saveRepliesToStorage(e){sessionStorage.setItem("ufp_replies",JSON.stringify(e))}notifyListeners(){const e=this.getCommentsFromStorage();for(const t of this.listeners)t(e)}async addComment(e){const t=this.getCommentsFromStorage(),r=Math.random().toString(36).substring(2,9),n={...e,id:r};return t.push(n),this.saveCommentsToStorage(t),r}async getComments(e,t){return this.getCommentsFromStorage().filter(n=>n.pageUrl===e&&n.projectKey===t)}async updateComment(e,t){const r=this.getCommentsFromStorage(),n=r.findIndex(s=>s.id===e);n!==-1&&(r[n]={...r[n],...t},this.saveCommentsToStorage(r))}async deleteComment(e){const r=this.getCommentsFromStorage().filter(i=>i.id!==e);this.saveCommentsToStorage(r);const s=this.getRepliesFromStorage().filter(i=>i.commentId!==e);this.saveRepliesToStorage(s)}async addReply(e){const t=this.getRepliesFromStorage(),r=Math.random().toString(36).substring(2,9),n={...e,id:r};return t.push(n),this.saveRepliesToStorage(t),r}async getReplies(e){return this.getRepliesFromStorage().filter(r=>r.commentId===e)}subscribeToComments(e,t,r){const n=s=>{r(s.filter(i=>i.pageUrl===e&&i.projectKey===t))};return this.listeners.add(n),n(this.getCommentsFromStorage()),()=>{this.listeners.delete(n)}}async uploadScreenshot(e,t){return t}}const qS=Object.freeze(Object.defineProperty({__proto__:null,LocalAdapter:WS},Symbol.toStringTag,{value:"Module"}));function fo(A,e){var t={};for(var r in A)Object.prototype.hasOwnProperty.call(A,r)&&e.indexOf(r)<0&&(t[r]=A[r]);if(A!=null&&typeof Object.getOwnPropertySymbols=="function")for(var n=0,r=Object.getOwnPropertySymbols(A);n<r.length;n++)e.indexOf(r[n])<0&&Object.prototype.propertyIsEnumerable.call(A,r[n])&&(t[r[n]]=A[r[n]]);return t}function JS(A,e,t,r){function n(s){return s instanceof t?s:new t(function(i){i(s)})}return new(t||(t=Promise))(function(s,i){function o(u){try{l(r.next(u))}catch(d){i(d)}}function a(u){try{l(r.throw(u))}catch(d){i(d)}}function l(u){u.done?s(u.value):n(u.value).then(o,a)}l((r=r.apply(A,e||[])).next())})}typeof SuppressedError=="function"&&SuppressedError;const zS=A=>A?(...e)=>A(...e):(...e)=>fetch(...e);class go extends Error{constructor(e,t="FunctionsError",r){super(e),this.name=t,this.context=r}toJSON(){return{name:this.name,message:this.message,context:this.context}}}class aw extends go{constructor(e){super("Failed to send a request to the Edge Function","FunctionsFetchError",e)}}class Sl extends go{constructor(e){super("Relay Error invoking the Edge Function","FunctionsRelayError",e)}}class Rl extends go{constructor(e){super("Edge Function returned a non-2xx status code","FunctionsHttpError",e)}}var po;(function(A){A.Any="any",A.ApNortheast1="ap-northeast-1",A.ApNortheast2="ap-northeast-2",A.ApSouth1="ap-south-1",A.ApSoutheast1="ap-southeast-1",A.ApSoutheast2="ap-southeast-2",A.CaCentral1="ca-central-1",A.EuCentral1="eu-central-1",A.EuWest1="eu-west-1",A.EuWest2="eu-west-2",A.EuWest3="eu-west-3",A.SaEast1="sa-east-1",A.UsEast1="us-east-1",A.UsWest1="us-west-1",A.UsWest2="us-west-2"})(po||(po={}));class XS{constructor(e,{headers:t={},customFetch:r,region:n=po.Any}={}){this.url=e,this.headers=t,this.region=n,this.fetch=zS(r)}setAuth(e){this.headers.Authorization=`Bearer ${e}`}invoke(e){return JS(this,arguments,void 0,function*(t,r={}){var n;let s,i;try{const{headers:o,method:a,body:l,signal:u,timeout:d}=r;let g={},{region:p}=r;p||(p=this.region);const m=new URL(`${this.url}/${t}`);p&&p!=="any"&&(g["x-region"]=p,m.searchParams.set("forceFunctionRegion",p));let _;l&&(o&&!Object.prototype.hasOwnProperty.call(o,"Content-Type")||!o)?typeof Blob<"u"&&l instanceof Blob||l instanceof ArrayBuffer?(g["Content-Type"]="application/octet-stream",_=l):typeof l=="string"?(g["Content-Type"]="text/plain",_=l):typeof FormData<"u"&&l instanceof FormData?_=l:(g["Content-Type"]="application/json",_=JSON.stringify(l)):l&&typeof l!="string"&&!(typeof Blob<"u"&&l instanceof Blob)&&!(l instanceof ArrayBuffer)&&!(typeof FormData<"u"&&l instanceof FormData)?_=JSON.stringify(l):_=l;let B=u;d&&(i=new AbortController,s=setTimeout(()=>i.abort(),d),u?(B=i.signal,u.addEventListener("abort",()=>i.abort())):B=i.signal);const b=yield this.fetch(m.toString(),{method:a||"POST",headers:Object.assign(Object.assign(Object.assign({},g),this.headers),o),body:_,signal:B}).catch(D=>{throw new aw(D)}),F=b.headers.get("x-relay-error");if(F&&F==="true")throw new Sl(b);if(!b.ok)throw new Rl(b);let I=((n=b.headers.get("Content-Type"))!==null&&n!==void 0?n:"text/plain").split(";")[0].trim(),S;return I==="application/json"?S=yield b.json():I==="application/octet-stream"||I==="application/pdf"?S=yield b.blob():I==="text/event-stream"?S=b:I==="multipart/form-data"?S=yield b.formData():S=yield b.text(),{data:S,error:null,response:b}}catch(o){return{data:null,error:o,response:o instanceof Rl||o instanceof Sl?o.context:void 0}}finally{s&&clearTimeout(s)}})}}const cw=3,lw=A=>Math.min(1e3*2**A,3e4),YS=[520,503],uw=["GET","HEAD","OPTIONS"];var xl=class extends Error{constructor(A){super(A.message),this.name="PostgrestError",this.details=A.details,this.hint=A.hint,this.code=A.code}toJSON(){return{name:this.name,message:this.message,details:this.details,hint:this.hint,code:this.code}}};function hw(A,e){return new Promise(t=>{if(e!=null&&e.aborted){t();return}const r=setTimeout(()=>{e==null||e.removeEventListener("abort",n),t()},A);function n(){clearTimeout(r),t()}e==null||e.addEventListener("abort",n)})}function ZS(A,e,t,r){return!(!r||t>=cw||!uw.includes(A)||!YS.includes(e))}var eR=class{constructor(A){var e,t,r,n,s;this.shouldThrowOnError=!1,this.retryEnabled=!0,this.method=A.method,this.url=A.url,this.headers=new Headers(A.headers),this.schema=A.schema,this.body=A.body,this.shouldThrowOnError=(e=A.shouldThrowOnError)!==null&&e!==void 0?e:!1,this.signal=A.signal,this.isMaybeSingle=(t=A.isMaybeSingle)!==null&&t!==void 0?t:!1,this.shouldStripNulls=(r=A.shouldStripNulls)!==null&&r!==void 0?r:!1,this.urlLengthLimit=(n=A.urlLengthLimit)!==null&&n!==void 0?n:8e3,this.retryEnabled=(s=A.retry)!==null&&s!==void 0?s:!0,A.fetch?this.fetch=A.fetch:this.fetch=fetch}throwOnError(){return this.shouldThrowOnError=!0,this}stripNulls(){if(this.headers.get("Accept")==="text/csv")throw new Error("stripNulls() cannot be used with csv()");return this.shouldStripNulls=!0,this}setHeader(A,e){return this.headers=new Headers(this.headers),this.headers.set(A,e),this}retry(A){return this.retryEnabled=A,this}then(A,e){var t=this;if(this.schema===void 0||(["GET","HEAD"].includes(this.method)?this.headers.set("Accept-Profile",this.schema):this.headers.set("Content-Profile",this.schema)),this.method!=="GET"&&this.method!=="HEAD"&&this.headers.set("Content-Type","application/json"),this.shouldStripNulls){const i=this.headers.get("Accept");i==="application/vnd.pgrst.object+json"?this.headers.set("Accept","application/vnd.pgrst.object+json;nulls=stripped"):(!i||i==="application/json")&&this.headers.set("Accept","application/vnd.pgrst.array+json;nulls=stripped")}const r=this.fetch;let s=(async()=>{let i=0;for(;;){const l={};t.headers.forEach((d,g)=>{l[g]=d}),i>0&&(l["X-Retry-Count"]=String(i));let u;try{u=await r(t.url.toString(),{method:t.method,headers:l,body:JSON.stringify(t.body,(d,g)=>typeof g=="bigint"?g.toString():g),signal:t.signal})}catch(d){if((d==null?void 0:d.name)==="AbortError"||(d==null?void 0:d.code)==="ABORT_ERR"||!uw.includes(t.method))throw d;if(t.retryEnabled&&i<cw){const g=lw(i);i++,await hw(g,t.signal);continue}throw d}if(ZS(t.method,u.status,i,t.retryEnabled)){var o,a;const d=(o=(a=u.headers)===null||a===void 0?void 0:a.get("Retry-After"))!==null&&o!==void 0?o:null,g=d!==null?Math.max(0,parseInt(d,10)||0)*1e3:lw(i);await u.text(),i++,await hw(g,t.signal);continue}return await t.processResponse(u)}})();return this.shouldThrowOnError||(s=s.catch(i=>{var o;let a="",l="",u="";const d=i==null?void 0:i.cause;if(d){var g,p,m,_;const F=(g=d==null?void 0:d.message)!==null&&g!==void 0?g:"",I=(p=d==null?void 0:d.code)!==null&&p!==void 0?p:"";a=`${(m=i==null?void 0:i.name)!==null&&m!==void 0?m:"FetchError"}: ${i==null?void 0:i.message}`,a+=`
2981
2981
 
2982
2982
  Caused by: ${(_=d==null?void 0:d.name)!==null&&_!==void 0?_:"Error"}: ${F}`,I&&(a+=` (${I})`),d!=null&&d.stack&&(a+=`
2983
2983
  ${d.stack}`)}else{var B;a=(B=i==null?void 0:i.stack)!==null&&B!==void 0?B:""}const b=this.url.toString().length;return(i==null?void 0:i.name)==="AbortError"||(i==null?void 0:i.code)==="ABORT_ERR"?(u="",l="Request was aborted (timeout or manual cancellation)",b>this.urlLengthLimit&&(l+=`. Note: Your request URL is ${b} characters, which may exceed server limits. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [many IDs])), consider using an RPC function to pass values server-side.`)):((d==null?void 0:d.name)==="HeadersOverflowError"||(d==null?void 0:d.code)==="UND_ERR_HEADERS_OVERFLOW")&&(u="",l="HTTP headers exceeded server limits (typically 16KB)",b>this.urlLengthLimit&&(l+=`. Your request URL is ${b} characters. If selecting many fields, consider using views. If filtering with large arrays (e.g., .in('id', [200+ IDs])), consider using an RPC function instead.`)),{success:!1,error:{message:`${(o=i==null?void 0:i.name)!==null&&o!==void 0?o:"FetchError"}: ${i==null?void 0:i.message}`,details:a,hint:l,code:u},data:null,count:null,status:0,statusText:""}})),s.then(A,e)}async processResponse(A){var e=this;let t=null,r=null,n=null,s=A.status,i=A.statusText;if(A.ok){var o,a;if(e.method!=="HEAD"){var l;const g=await A.text();if(g!=="")if(e.headers.get("Accept")==="text/csv")r=g;else if(e.headers.get("Accept")&&(!((l=e.headers.get("Accept"))===null||l===void 0)&&l.includes("application/vnd.pgrst.plan+text")))r=g;else try{r=JSON.parse(g)}catch{if(t={message:g},r=null,e.shouldThrowOnError)throw new xl({message:g,details:"",hint:"",code:""})}}const u=(o=e.headers.get("Prefer"))===null||o===void 0?void 0:o.match(/count=(exact|planned|estimated)/),d=(a=A.headers.get("content-range"))===null||a===void 0?void 0:a.split("/");u&&d&&d.length>1&&(n=parseInt(d[1])),e.isMaybeSingle&&Array.isArray(r)&&(r.length>1?(t={code:"PGRST116",details:`Results contain ${r.length} rows, application/vnd.pgrst.object+json requires 1 row`,hint:null,message:"JSON object requested, multiple (or no) rows returned"},r=null,n=null,s=406,i="Not Acceptable"):r.length===1?r=r[0]:r=null)}else{const u=await A.text();try{t=JSON.parse(u),Array.isArray(t)&&A.status===404&&(r=[],t=null,s=200,i="OK")}catch{A.status===404&&u===""?(s=204,i="No Content"):t={message:u}}if(t&&e.shouldThrowOnError)throw new xl(t)}return{success:t===null,error:t,data:r,count:n,status:s,statusText:i}}returns(){return this}overrideTypes(){return this}},tR=class extends eR{throwOnError(){return super.throwOnError()}select(A){let e=!1;const t=(A??"*").split("").map(r=>/\s/.test(r)&&!e?"":(r==='"'&&(e=!e),r)).join("");return this.url.searchParams.set("select",t),this.headers.append("Prefer","return=representation"),this}order(A,{ascending:e=!0,nullsFirst:t,foreignTable:r,referencedTable:n=r}={}){const s=n?`${n}.order`:"order",i=this.url.searchParams.get(s);return this.url.searchParams.set(s,`${i?`${i},`:""}${A}.${e?"asc":"desc"}${t===void 0?"":t?".nullsfirst":".nullslast"}`),this}limit(A,{foreignTable:e,referencedTable:t=e}={}){const r=typeof t>"u"?"limit":`${t}.limit`;return this.url.searchParams.set(r,`${A}`),this}range(A,e,{foreignTable:t,referencedTable:r=t}={}){const n=typeof r>"u"?"offset":`${r}.offset`,s=typeof r>"u"?"limit":`${r}.limit`;return this.url.searchParams.set(n,`${A}`),this.url.searchParams.set(s,`${e-A+1}`),this}abortSignal(A){return this.signal=A,this}single(){return this.headers.set("Accept","application/vnd.pgrst.object+json"),this}maybeSingle(){return this.isMaybeSingle=!0,this}csv(){return this.headers.set("Accept","text/csv"),this}geojson(){return this.headers.set("Accept","application/geo+json"),this}explain({analyze:A=!1,verbose:e=!1,settings:t=!1,buffers:r=!1,wal:n=!1,format:s="text"}={}){var i;const o=[A?"analyze":null,e?"verbose":null,t?"settings":null,r?"buffers":null,n?"wal":null].filter(Boolean).join("|"),a=(i=this.headers.get("Accept"))!==null&&i!==void 0?i:"application/json";return this.headers.set("Accept",`application/vnd.pgrst.plan+${s}; for="${a}"; options=${o};`),s==="json"?this:this}rollback(){return this.headers.append("Prefer","tx=rollback"),this}returns(){return this}maxAffected(A){return this.headers.append("Prefer","handling=strict"),this.headers.append("Prefer",`max-affected=${A}`),this}};const dw=new RegExp("[,()]");var Vr=class extends tR{throwOnError(){return super.throwOnError()}eq(A,e){return this.url.searchParams.append(A,`eq.${e}`),this}neq(A,e){return this.url.searchParams.append(A,`neq.${e}`),this}gt(A,e){return this.url.searchParams.append(A,`gt.${e}`),this}gte(A,e){return this.url.searchParams.append(A,`gte.${e}`),this}lt(A,e){return this.url.searchParams.append(A,`lt.${e}`),this}lte(A,e){return this.url.searchParams.append(A,`lte.${e}`),this}like(A,e){return this.url.searchParams.append(A,`like.${e}`),this}likeAllOf(A,e){return this.url.searchParams.append(A,`like(all).{${e.join(",")}}`),this}likeAnyOf(A,e){return this.url.searchParams.append(A,`like(any).{${e.join(",")}}`),this}ilike(A,e){return this.url.searchParams.append(A,`ilike.${e}`),this}ilikeAllOf(A,e){return this.url.searchParams.append(A,`ilike(all).{${e.join(",")}}`),this}ilikeAnyOf(A,e){return this.url.searchParams.append(A,`ilike(any).{${e.join(",")}}`),this}regexMatch(A,e){return this.url.searchParams.append(A,`match.${e}`),this}regexIMatch(A,e){return this.url.searchParams.append(A,`imatch.${e}`),this}is(A,e){return this.url.searchParams.append(A,`is.${e}`),this}isDistinct(A,e){return this.url.searchParams.append(A,`isdistinct.${e}`),this}in(A,e){const t=Array.from(new Set(e)).map(r=>typeof r=="string"&&dw.test(r)?`"${r}"`:`${r}`).join(",");return this.url.searchParams.append(A,`in.(${t})`),this}notIn(A,e){const t=Array.from(new Set(e)).map(r=>typeof r=="string"&&dw.test(r)?`"${r}"`:`${r}`).join(",");return this.url.searchParams.append(A,`not.in.(${t})`),this}contains(A,e){return typeof e=="string"?this.url.searchParams.append(A,`cs.${e}`):Array.isArray(e)?this.url.searchParams.append(A,`cs.{${e.join(",")}}`):this.url.searchParams.append(A,`cs.${JSON.stringify(e)}`),this}containedBy(A,e){return typeof e=="string"?this.url.searchParams.append(A,`cd.${e}`):Array.isArray(e)?this.url.searchParams.append(A,`cd.{${e.join(",")}}`):this.url.searchParams.append(A,`cd.${JSON.stringify(e)}`),this}rangeGt(A,e){return this.url.searchParams.append(A,`sr.${e}`),this}rangeGte(A,e){return this.url.searchParams.append(A,`nxl.${e}`),this}rangeLt(A,e){return this.url.searchParams.append(A,`sl.${e}`),this}rangeLte(A,e){return this.url.searchParams.append(A,`nxr.${e}`),this}rangeAdjacent(A,e){return this.url.searchParams.append(A,`adj.${e}`),this}overlaps(A,e){return typeof e=="string"?this.url.searchParams.append(A,`ov.${e}`):this.url.searchParams.append(A,`ov.{${e.join(",")}}`),this}textSearch(A,e,{config:t,type:r}={}){let n="";r==="plain"?n="pl":r==="phrase"?n="ph":r==="websearch"&&(n="w");const s=t===void 0?"":`(${t})`;return this.url.searchParams.append(A,`${n}fts${s}.${e}`),this}match(A){return Object.entries(A).filter(([e,t])=>t!==void 0).forEach(([e,t])=>{this.url.searchParams.append(e,`eq.${t}`)}),this}not(A,e,t){return this.url.searchParams.append(A,`not.${e}.${t}`),this}or(A,{foreignTable:e,referencedTable:t=e}={}){const r=t?`${t}.or`:"or";return this.url.searchParams.append(r,`(${A})`),this}filter(A,e,t){return this.url.searchParams.append(A,`${e}.${t}`),this}},AR=class{constructor(A,{headers:e={},schema:t,fetch:r,urlLengthLimit:n=8e3,retry:s}){this.url=A,this.headers=new Headers(e),this.schema=t,this.fetch=r,this.urlLengthLimit=n,this.retry=s}cloneRequestState(){return{url:new URL(this.url.toString()),headers:new Headers(this.headers)}}select(A,e){const{head:t=!1,count:r}=e??{},n=t?"HEAD":"GET";let s=!1;const i=(A??"*").split("").map(l=>/\s/.test(l)&&!s?"":(l==='"'&&(s=!s),l)).join(""),{url:o,headers:a}=this.cloneRequestState();return o.searchParams.set("select",i),r&&a.append("Prefer",`count=${r}`),new Vr({method:n,url:o,headers:a,schema:this.schema,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}insert(A,{count:e,defaultToNull:t=!0}={}){var r;const n="POST",{url:s,headers:i}=this.cloneRequestState();if(e&&i.append("Prefer",`count=${e}`),t||i.append("Prefer","missing=default"),Array.isArray(A)){const o=A.reduce((a,l)=>a.concat(Object.keys(l)),[]);if(o.length>0){const a=[...new Set(o)].map(l=>`"${l}"`);s.searchParams.set("columns",a.join(","))}}return new Vr({method:n,url:s,headers:i,schema:this.schema,body:A,fetch:(r=this.fetch)!==null&&r!==void 0?r:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}upsert(A,{onConflict:e,ignoreDuplicates:t=!1,count:r,defaultToNull:n=!0}={}){var s;const i="POST",{url:o,headers:a}=this.cloneRequestState();if(a.append("Prefer",`resolution=${t?"ignore":"merge"}-duplicates`),e!==void 0&&o.searchParams.set("on_conflict",e),r&&a.append("Prefer",`count=${r}`),n||a.append("Prefer","missing=default"),Array.isArray(A)){const l=A.reduce((u,d)=>u.concat(Object.keys(d)),[]);if(l.length>0){const u=[...new Set(l)].map(d=>`"${d}"`);o.searchParams.set("columns",u.join(","))}}return new Vr({method:i,url:o,headers:a,schema:this.schema,body:A,fetch:(s=this.fetch)!==null&&s!==void 0?s:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}update(A,{count:e}={}){var t;const r="PATCH",{url:n,headers:s}=this.cloneRequestState();return e&&s.append("Prefer",`count=${e}`),new Vr({method:r,url:n,headers:s,schema:this.schema,body:A,fetch:(t=this.fetch)!==null&&t!==void 0?t:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}delete({count:A}={}){var e;const t="DELETE",{url:r,headers:n}=this.cloneRequestState();return A&&n.append("Prefer",`count=${A}`),new Vr({method:t,url:r,headers:n,schema:this.schema,fetch:(e=this.fetch)!==null&&e!==void 0?e:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}};function ns(A){"@babel/helpers - typeof";return ns=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ns(A)}function rR(A,e){if(ns(A)!="object"||!A)return A;var t=A[Symbol.toPrimitive];if(t!==void 0){var r=t.call(A,e);if(ns(r)!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(A)}function nR(A){var e=rR(A,"string");return ns(e)=="symbol"?e:e+""}function sR(A,e,t){return(e=nR(e))in A?Object.defineProperty(A,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):A[e]=t,A}function fw(A,e){var t=Object.keys(A);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(A);e&&(r=r.filter(function(n){return Object.getOwnPropertyDescriptor(A,n).enumerable})),t.push.apply(t,r)}return t}function wo(A){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?arguments[e]:{};e%2?fw(Object(t),!0).forEach(function(r){sR(A,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(A,Object.getOwnPropertyDescriptors(t)):fw(Object(t)).forEach(function(r){Object.defineProperty(A,r,Object.getOwnPropertyDescriptor(t,r))})}return A}var iR=class fB{constructor(e,{headers:t={},schema:r,fetch:n,timeout:s,urlLengthLimit:i=8e3,retry:o}={}){this.url=e,this.headers=new Headers(t),this.schemaName=r,this.urlLengthLimit=i;const a=n??globalThis.fetch;s!==void 0&&s>0?this.fetch=(l,u)=>{const d=new AbortController,g=setTimeout(()=>d.abort(),s),p=u==null?void 0:u.signal;if(p){if(p.aborted)return clearTimeout(g),a(l,u);const m=()=>{clearTimeout(g),d.abort()};return p.addEventListener("abort",m,{once:!0}),a(l,wo(wo({},u),{},{signal:d.signal})).finally(()=>{clearTimeout(g),p.removeEventListener("abort",m)})}return a(l,wo(wo({},u),{},{signal:d.signal})).finally(()=>clearTimeout(g))}:this.fetch=a,this.retry=o}from(e){if(!e||typeof e!="string"||e.trim()==="")throw new Error("Invalid relation name: relation must be a non-empty string.");return new AR(new URL(`${this.url}/${e}`),{headers:new Headers(this.headers),schema:this.schemaName,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}schema(e){return new fB(this.url,{headers:this.headers,schema:e,fetch:this.fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}rpc(e,t={},{head:r=!1,get:n=!1,count:s}={}){var i;let o;const a=new URL(`${this.url}/rpc/${e}`);let l;const u=p=>p!==null&&typeof p=="object"&&(!Array.isArray(p)||p.some(u)),d=r&&Object.values(t).some(u);d?(o="POST",l=t):r||n?(o=r?"HEAD":"GET",Object.entries(t).filter(([p,m])=>m!==void 0).map(([p,m])=>[p,Array.isArray(m)?`{${m.join(",")}}`:`${m}`]).forEach(([p,m])=>{a.searchParams.append(p,m)})):(o="POST",l=t);const g=new Headers(this.headers);return d?g.set("Prefer",s?`count=${s},return=minimal`:"return=minimal"):s&&g.set("Prefer",`count=${s}`),new Vr({method:o,url:a,headers:g,schema:this.schemaName,body:l,fetch:(i=this.fetch)!==null&&i!==void 0?i:fetch,urlLengthLimit:this.urlLengthLimit,retry:this.retry})}};class gw{constructor(){}static detectEnvironment(){var e;if(typeof WebSocket<"u")return{type:"native",wsConstructor:WebSocket};const t=globalThis;if(typeof globalThis<"u"&&typeof t.WebSocket<"u")return{type:"native",wsConstructor:t.WebSocket};const r=typeof global<"u"?global:void 0;if(r&&typeof r.WebSocket<"u")return{type:"native",wsConstructor:r.WebSocket};if(typeof globalThis<"u"&&typeof t.WebSocketPair<"u"&&typeof globalThis.WebSocket>"u")return{type:"cloudflare",error:"Cloudflare Workers detected. WebSocket clients are not supported in Cloudflare Workers.",workaround:"Use Cloudflare Workers WebSocket API for server-side WebSocket handling, or deploy to a different runtime."};if(typeof globalThis<"u"&&t.EdgeRuntime||typeof navigator<"u"&&(!((e=navigator.userAgent)===null||e===void 0)&&e.includes("Vercel-Edge")))return{type:"unsupported",error:"Edge runtime detected (Vercel Edge/Netlify Edge). WebSockets are not supported in edge functions.",workaround:"Use serverless functions or a different deployment target for WebSocket functionality."};const n=globalThis.process;if(n){const s=n.versions;if(s&&s.node){const i=s.node,o=parseInt(i.replace(/^v/,"").split(".")[0]);return o>=22?typeof globalThis.WebSocket<"u"?{type:"native",wsConstructor:globalThis.WebSocket}:{type:"unsupported",error:`Node.js ${o} detected but native WebSocket not found.`,workaround:"Provide a WebSocket implementation via the transport option."}:{type:"unsupported",error:`Node.js ${o} detected without native WebSocket support.`,workaround:`For Node.js < 22, install "ws" package and provide it via the transport option: