fakebase-studio 1.0.9 → 1.0.10

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
@@ -19,3 +19,7 @@ npx fakebase-studio@latest
19
19
  ```
20
20
  postgresql://user:password@host:port/database
21
21
  ```
22
+
23
+ ## Telemetry
24
+
25
+ Fakebase collects minimal anonymous telemetry to help us understand usage. See [SECURITY.md](SECURITY.md) for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fakebase-studio",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "fakebase-studio": "bin/fakebase.js"
@@ -22,11 +22,14 @@
22
22
  "build:server": "tsc -p server/tsconfig.json",
23
23
  "build:ui": "npm ci --prefix ui && npm run build --prefix ui",
24
24
  "build": "npm run build:server && npm run build:ui",
25
- "prepack": "npm run build"
25
+ "prepack": "npm run build",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest"
26
28
  },
27
29
  "dependencies": {
28
30
  "@fastify/cors": "^11.2.0",
29
31
  "@fastify/static": "^9.0.0",
32
+ "@supabase/supabase-js": "^2.99.3",
30
33
  "class-variance-authority": "^0.7.1",
31
34
  "clsx": "^2.1.1",
32
35
  "fastify": "^5.7.2",
@@ -39,6 +42,7 @@
39
42
  "@types/pg": "^8.16.0",
40
43
  "concurrently": "^9.1.2",
41
44
  "tsx": "^4.21.0",
42
- "typescript": "^5.4.0"
45
+ "typescript": "^5.4.0",
46
+ "vitest": "^4.1.0"
43
47
  }
44
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAWA,wBAAsB,WAAW,kBA4EhC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAYA,wBAAsB,WAAW,kBA8EhC"}
@@ -5,6 +5,7 @@ import path from "path";
5
5
  import { fileURLToPath } from "url";
6
6
  import { registerRoutes } from "./routes/index.js";
7
7
  import { closeAllPools } from "./db.js";
8
+ import { recordTelemetryPing } from "./services/telemetry.service.js";
8
9
  const __filename = fileURLToPath(import.meta.url);
9
10
  const __dirname = path.dirname(__filename);
10
11
  export async function startServer() {
@@ -61,6 +62,7 @@ export async function startServer() {
61
62
  // Start server
62
63
  await app.listen({ port, host });
63
64
  console.log(`Fakebase Studio running on http://localhost:${port}`);
65
+ recordTelemetryPing();
64
66
  process.once("SIGINT", () => {
65
67
  app
66
68
  .close()
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC;QAClB,MAAM,EAAE;YACN,KAAK,EAAE,OAAO;SACf;KACF,CAAC,CAAC;IAEH,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,uBAAuB;IACvB,GAAG,CAAC,eAAe,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAC5C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACrB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,6DAA6D;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC;IAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC;IAE3D,MAAM,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE;QAC9B,MAAM,EAAE,YAAY;YAClB,CAAC,CAAC,CAAC,oBAAoB,IAAI,EAAE,EAAE,oBAAoB,IAAI,EAAE,CAAC;YAC1D,CAAC,CAAC,IAAI;KACT,CAAC,CAAC;IAEH,sBAAsB;IACtB,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAE1B,mCAAmC;IACnC,+DAA+D;IAC/D,MAAM,UAAU,GAAG,YAAY;QAC7B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC;QACrC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAEvC,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE;YAChC,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,KAAK,EAAE,qCAAqC;SACvD,CAAC,CAAC;QAEH,2EAA2E;QAC3E,GAAG,CAAC,kBAAkB,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YACxC,4BAA4B;YAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC5B,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC;YACD,8CAA8C;YAC9C,OAAO,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,eAAe;IACf,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,EAAE,CAAC,CAAC;IAEnE,mBAAmB,EAAE,CAAC;IAEtB,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;QAC1B,GAAG;aACA,KAAK,EAAE;aACP,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;QAC3B,GAAG;aACA,KAAK,EAAE;aACP,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,mDAAmD;AACnD,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function recordTelemetryPing(): Promise<void>;
2
+ //# sourceMappingURL=telemetry.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.service.d.ts","sourceRoot":"","sources":["../../services/telemetry.service.ts"],"names":[],"mappings":"AAuCA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAYzD"}
@@ -0,0 +1,47 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import os from "os";
4
+ import crypto from "crypto";
5
+ import { createRequire } from "module";
6
+ import { createClient } from "@supabase/supabase-js";
7
+ const require = createRequire(import.meta.url);
8
+ const TELEMETRY_URL = "https://eoemfvtnmxikxrzavywj.supabase.co";
9
+ const TELEMETRY_KEY_PUBLIC_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImVvZW1mdnRubXhpa3hyemF2eXdqIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzQxNzgxMzIsImV4cCI6MjA4OTc1NDEzMn0.ia8rOpC6np3zoJW2z7Egt1hoy0rULKtJQNVFSvqudR4";
10
+ const supabase = createClient(TELEMETRY_URL, TELEMETRY_KEY_PUBLIC_KEY);
11
+ const CONFIG_DIR = path.join(os.homedir(), ".fakebase-studio");
12
+ const ID_FILE = path.join(CONFIG_DIR, "installation-id");
13
+ async function getInstallationId() {
14
+ try {
15
+ const id = await fs.readFile(ID_FILE, "utf-8");
16
+ return id.trim();
17
+ }
18
+ catch {
19
+ const id = crypto.randomUUID();
20
+ await fs.mkdir(CONFIG_DIR, { recursive: true });
21
+ await fs.writeFile(ID_FILE, id, "utf-8");
22
+ return id;
23
+ }
24
+ }
25
+ function getVersion() {
26
+ try {
27
+ const pkg = require("../../package.json");
28
+ return pkg.version || "unknown";
29
+ }
30
+ catch {
31
+ return "unknown";
32
+ }
33
+ }
34
+ export async function recordTelemetryPing() {
35
+ try {
36
+ const id = await getInstallationId();
37
+ const version = getVersion();
38
+ await supabase.rpc("upsert_installation", {
39
+ p_id: id,
40
+ p_version: version,
41
+ });
42
+ }
43
+ catch {
44
+ // Silently fail -- telemetry must never break the app
45
+ }
46
+ }
47
+ //# sourceMappingURL=telemetry.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.service.js","sourceRoot":"","sources":["../../services/telemetry.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,aAAa,GAAG,0CAA0C,CAAC;AACjE,MAAM,wBAAwB,GAC5B,kNAAkN,CAAC;AAErN,MAAM,QAAQ,GAAG,YAAY,CAAC,aAAa,EAAE,wBAAwB,CAAC,CAAC;AAEvE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;AAEzD,KAAK,UAAU,iBAAiB;IAC9B,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/B,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC1C,OAAO,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAE7B,MAAM,QAAQ,CAAC,GAAG,CAAC,qBAAqB,EAAE;YACxC,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,OAAO;SACnB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=telemetry.service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.service.test.d.ts","sourceRoot":"","sources":["../../services/telemetry.service.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ const { mockRpc, mockReadFile, mockWriteFile, mockMkdir } = vi.hoisted(() => {
3
+ const mockRpc = vi.fn().mockResolvedValue({ error: null });
4
+ const mockReadFile = vi.fn();
5
+ const mockWriteFile = vi.fn().mockResolvedValue(undefined);
6
+ const mockMkdir = vi.fn().mockResolvedValue(undefined);
7
+ return { mockRpc, mockReadFile, mockWriteFile, mockMkdir };
8
+ });
9
+ vi.mock("@supabase/supabase-js", () => ({
10
+ createClient: () => ({ rpc: mockRpc }),
11
+ }));
12
+ vi.mock("fs/promises", () => ({
13
+ default: {
14
+ readFile: mockReadFile,
15
+ writeFile: mockWriteFile,
16
+ mkdir: mockMkdir,
17
+ },
18
+ }));
19
+ import { recordTelemetryPing } from "./telemetry.service.js";
20
+ beforeEach(() => {
21
+ vi.clearAllMocks();
22
+ });
23
+ describe("recordTelemetryPing", () => {
24
+ it("creates a new installation ID and calls RPC on first run", async () => {
25
+ mockReadFile.mockRejectedValueOnce(new Error("ENOENT"));
26
+ await recordTelemetryPing();
27
+ expect(mockMkdir).toHaveBeenCalledOnce();
28
+ expect(mockWriteFile).toHaveBeenCalledOnce();
29
+ const writtenId = mockWriteFile.mock.calls[0][1];
30
+ expect(writtenId).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
31
+ expect(mockRpc).toHaveBeenCalledWith("upsert_installation", {
32
+ p_id: writtenId,
33
+ p_version: "1.0.10",
34
+ });
35
+ });
36
+ it("reuses existing installation ID from disk", async () => {
37
+ const existingId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
38
+ mockReadFile.mockResolvedValueOnce(existingId);
39
+ await recordTelemetryPing();
40
+ expect(mockWriteFile).not.toHaveBeenCalled();
41
+ expect(mockRpc).toHaveBeenCalledWith("upsert_installation", {
42
+ p_id: existingId,
43
+ p_version: "1.0.10",
44
+ });
45
+ });
46
+ it("trims whitespace from stored installation ID", async () => {
47
+ mockReadFile.mockResolvedValueOnce(" aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\n");
48
+ await recordTelemetryPing();
49
+ expect(mockRpc.mock.calls[0][1].p_id).toBe("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");
50
+ });
51
+ it("never throws even if Supabase fails", async () => {
52
+ mockReadFile.mockResolvedValueOnce("some-id");
53
+ mockRpc.mockRejectedValueOnce(new Error("network down"));
54
+ await expect(recordTelemetryPing()).resolves.toBeUndefined();
55
+ });
56
+ it("never throws even if filesystem fails entirely", async () => {
57
+ mockReadFile.mockRejectedValueOnce(new Error("ENOENT"));
58
+ mockMkdir.mockRejectedValueOnce(new Error("EPERM"));
59
+ await expect(recordTelemetryPing()).resolves.toBeUndefined();
60
+ });
61
+ });
62
+ //# sourceMappingURL=telemetry.service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.service.test.js","sourceRoot":"","sources":["../../services/telemetry.service.test.ts"],"names":[],"mappings":"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"}