@loupekit/shared 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.
@@ -0,0 +1,52 @@
1
+ export type CommentStatus = "open" | "in_progress" | "done";
2
+ export interface LoupeUser {
3
+ id: string;
4
+ name: string;
5
+ email?: string;
6
+ }
7
+ export interface Anchor {
8
+ tag: string;
9
+ cssPath: string;
10
+ xpath: string;
11
+ testid: string | null;
12
+ text: string;
13
+ attrs: Record<string, string>;
14
+ nthOfType: number;
15
+ rect: {
16
+ x: number;
17
+ y: number;
18
+ w: number;
19
+ h: number;
20
+ };
21
+ viewport: {
22
+ w: number;
23
+ h: number;
24
+ };
25
+ }
26
+ export interface ElementContext {
27
+ html: string;
28
+ styles: Record<string, string>;
29
+ }
30
+ export interface Comment {
31
+ id: string;
32
+ projectKey: string;
33
+ url: string;
34
+ author: LoupeUser;
35
+ body: string;
36
+ status: CommentStatus;
37
+ anchor: Anchor;
38
+ context: ElementContext;
39
+ offset: {
40
+ x: number;
41
+ y: number;
42
+ };
43
+ /** A URL (object storage) in server mode, or an inline data URL in offline mode. */
44
+ screenshot?: string;
45
+ createdAt: string;
46
+ }
47
+ /**
48
+ * Normalize a page URL so comments don't fragment across tracking/volatile params.
49
+ * Keeps the path + a filtered, sorted query. Drops utm_*, click ids, and Loupe's
50
+ * own dev params (api/key). Accepts a full URL or a path+search string.
51
+ */
52
+ export declare function normalizeUrl(input: string): string;
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ // Canonical types + pure helpers shared across the SDK, server, dashboard, and MCP.
2
+ const DROP_EXACT = new Set([
3
+ "api", "key", "fbclid", "gclid", "gbraid", "wbraid", "msclkid",
4
+ "ref", "ref_src", "mc_cid", "mc_eid", "_hsenc", "_hsmi", "igshid",
5
+ ]);
6
+ /**
7
+ * Normalize a page URL so comments don't fragment across tracking/volatile params.
8
+ * Keeps the path + a filtered, sorted query. Drops utm_*, click ids, and Loupe's
9
+ * own dev params (api/key). Accepts a full URL or a path+search string.
10
+ */
11
+ export function normalizeUrl(input) {
12
+ try {
13
+ const u = new URL(input, "http://loupe.local");
14
+ let path = u.pathname;
15
+ const kept = [];
16
+ for (const [k, v] of u.searchParams) {
17
+ const key = k.toLowerCase();
18
+ if (DROP_EXACT.has(key) || key.startsWith("utm_"))
19
+ continue;
20
+ kept.push([k, v]);
21
+ }
22
+ kept.sort((a, b) => (a[0] === b[0] ? a[1].localeCompare(b[1]) : a[0].localeCompare(b[0])));
23
+ const qs = new URLSearchParams(kept).toString();
24
+ if (path.length > 1 && path.endsWith("/"))
25
+ path = path.slice(0, -1);
26
+ return path + (qs ? `?${qs}` : "");
27
+ }
28
+ catch {
29
+ const i = input.indexOf("?");
30
+ return i >= 0 ? input.slice(0, i) : input;
31
+ }
32
+ }
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@loupekit/shared",
3
+ "version": "0.1.0",
4
+ "description": "Loupe shared types + helpers (normalizeUrl).",
5
+ "license": "MIT",
6
+ "repository": { "type": "git", "url": "https://github.com/mohamed-ashraf-elsaed/loupe.git", "directory": "packages/shared" },
7
+ "homepage": "https://mohamed-ashraf-elsaed.github.io/loupe/",
8
+ "publishConfig": { "access": "public" },
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" }
14
+ },
15
+ "files": ["dist"],
16
+ "scripts": {
17
+ "build": "tsc -p tsconfig.json"
18
+ }
19
+ }