@wopr-network/platform-ui-core 1.1.3 → 1.1.4

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/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@wopr-network/platform-ui-core",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "Brand-agnostic AI agent platform UI — deploy as any brand via env vars",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/wopr-network/platform-ui-core.git"
8
8
  },
9
9
  "license": "UNLICENSED",
10
+ "packageManager": "pnpm@10.31.0",
10
11
  "exports": {
11
12
  ".": "./src/lib/index.ts",
12
13
  "./app/*": "./src/app/*",
@@ -31,6 +32,16 @@
31
32
  "vitest.config.ts",
32
33
  ".env.wopr"
33
34
  ],
35
+ "scripts": {
36
+ "dev": "next dev",
37
+ "build": "next build",
38
+ "start": "next start",
39
+ "lint": "biome check src/",
40
+ "format": "biome format --write src/",
41
+ "check": "biome check src/ && tsc --noEmit",
42
+ "test": "vitest run",
43
+ "test:e2e": "playwright test"
44
+ },
34
45
  "dependencies": {
35
46
  "@hookform/resolvers": "^5.2.2",
36
47
  "@stripe/react-stripe-js": "^5.6.0",
@@ -79,14 +90,7 @@
79
90
  "typescript": "^5",
80
91
  "vitest": "^4.0.18"
81
92
  },
82
- "scripts": {
83
- "dev": "next dev",
84
- "build": "next build",
85
- "start": "next start",
86
- "lint": "biome check src/",
87
- "format": "biome format --write src/",
88
- "check": "biome check src/ && tsc --noEmit",
89
- "test": "vitest run",
90
- "test:e2e": "playwright test"
93
+ "release": {
94
+ "extends": "@wopr-network/semantic-release-config"
91
95
  }
92
- }
96
+ }
@@ -0,0 +1,21 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+
3
+ describe("buy-credits-panel logger usage", () => {
4
+ beforeEach(() => {
5
+ vi.resetModules();
6
+ });
7
+
8
+ it("should use logger instead of raw console.error", async () => {
9
+ const fs = await import("node:fs");
10
+ const source = fs.readFileSync("src/components/billing/buy-credits-panel.tsx", "utf-8");
11
+
12
+ // Must import logger
13
+ expect(source).toContain('import { logger } from "@/lib/logger"');
14
+
15
+ // Must NOT have raw console.error
16
+ expect(source).not.toMatch(/console\.error\(/);
17
+
18
+ // Must use log.error
19
+ expect(source).toMatch(/log\.error\(/);
20
+ });
21
+ });
@@ -90,7 +90,7 @@ describe("GpuDashboard", () => {
90
90
  mockListGpuNodes.mockResolvedValue([]);
91
91
  render(<GpuDashboard />);
92
92
  await waitFor(() => {
93
- expect(screen.getByText(/GPU Management/i)).toBeTruthy();
93
+ expect(screen.getByText(/GPU Management/i)).toBeInTheDocument();
94
94
  });
95
95
  });
96
96
 
@@ -98,10 +98,10 @@ describe("GpuDashboard", () => {
98
98
  mockListGpuNodes.mockResolvedValue([fakeNode({ name: "my-gpu" })]);
99
99
  render(<GpuDashboard />);
100
100
  await waitFor(() => {
101
- expect(screen.getByText("my-gpu")).toBeTruthy();
101
+ expect(screen.getByText("my-gpu")).toBeInTheDocument();
102
102
  });
103
- expect(screen.getByText("running")).toBeTruthy();
104
- expect(screen.getByText("42%")).toBeTruthy();
103
+ expect(screen.getByText("running")).toBeInTheDocument();
104
+ expect(screen.getByText("42%")).toBeInTheDocument();
105
105
  // Temperature appears in both the KPI card and the table row
106
106
  expect(screen.getAllByText("65°C").length).toBeGreaterThan(0);
107
107
  });
@@ -110,7 +110,7 @@ describe("GpuDashboard", () => {
110
110
  mockListGpuNodes.mockResolvedValue([]);
111
111
  render(<GpuDashboard />);
112
112
  await waitFor(() => {
113
- expect(screen.getByText(/No GPU nodes provisioned/i)).toBeTruthy();
113
+ expect(screen.getByText(/No GPU nodes provisioned/i)).toBeInTheDocument();
114
114
  });
115
115
  });
116
116
 
@@ -118,7 +118,7 @@ describe("GpuDashboard", () => {
118
118
  mockListGpuNodes.mockRejectedValue(new Error("API down"));
119
119
  render(<GpuDashboard />);
120
120
  await waitFor(() => {
121
- expect(screen.getByText("API down")).toBeTruthy();
121
+ expect(screen.getByText("API down")).toBeInTheDocument();
122
122
  });
123
123
  });
124
124
 
@@ -130,8 +130,8 @@ describe("GpuDashboard", () => {
130
130
  render(<GpuDashboard />);
131
131
  await waitFor(() => {
132
132
  // Total nodes = 2, Running = 1
133
- expect(screen.getByText("Total Nodes")).toBeTruthy();
134
- expect(screen.getByText("Running")).toBeTruthy();
133
+ expect(screen.getByText("Total Nodes")).toBeInTheDocument();
134
+ expect(screen.getByText("Running")).toBeInTheDocument();
135
135
  });
136
136
  });
137
137
 
@@ -139,8 +139,8 @@ describe("GpuDashboard", () => {
139
139
  mockListGpuNodes.mockResolvedValue([]);
140
140
  render(<GpuDashboard />);
141
141
  await waitFor(() => {
142
- expect(screen.getByText(/Allocation \/ Tenant Mapping/i)).toBeTruthy();
143
- expect(screen.getByText(/GPU Configuration/i)).toBeTruthy();
142
+ expect(screen.getByText(/Allocation \/ Tenant Mapping/i)).toBeInTheDocument();
143
+ expect(screen.getByText(/GPU Configuration/i)).toBeInTheDocument();
144
144
  });
145
145
  });
146
146
 
@@ -206,7 +206,7 @@ describe("GpuDashboard", () => {
206
206
 
207
207
  await userEvent.click(screen.getByText(/Provision Node/i));
208
208
 
209
- expect(screen.getByText(/Provision New GPU Node/i)).toBeTruthy();
209
+ expect(screen.getByText(/Provision New GPU Node/i)).toBeInTheDocument();
210
210
  });
211
211
 
212
212
  it("submits provision form and adds new node", async () => {
@@ -61,14 +61,14 @@ describe("NetworkPage", () => {
61
61
  it("renders page heading", async () => {
62
62
  vi.mocked(listInstances).mockResolvedValue(MOCK_INSTANCES);
63
63
  render(<NetworkPage />);
64
- expect(screen.getByText(/friends/i)).toBeTruthy();
64
+ expect(screen.getByText(/friends/i)).toBeInTheDocument();
65
65
  });
66
66
 
67
67
  it("shows instance selector after load", async () => {
68
68
  vi.mocked(listInstances).mockResolvedValue(MOCK_INSTANCES);
69
69
  render(<NetworkPage />);
70
70
  await waitFor(() => {
71
- expect(screen.getByRole("combobox", { name: /select instance/i })).toBeTruthy();
71
+ expect(screen.getByRole("combobox", { name: /select instance/i })).toBeInTheDocument();
72
72
  });
73
73
  });
74
74
 
@@ -76,7 +76,7 @@ describe("NetworkPage", () => {
76
76
  vi.mocked(listInstances).mockResolvedValue(MOCK_INSTANCES);
77
77
  render(<NetworkPage />);
78
78
  await waitFor(() => {
79
- expect(screen.getByText(/select an instance to manage friends/i)).toBeTruthy();
79
+ expect(screen.getByText(/select an instance to manage friends/i)).toBeInTheDocument();
80
80
  });
81
81
  });
82
82
 
@@ -94,7 +94,7 @@ describe("NetworkPage", () => {
94
94
  vi.mocked(listInstances).mockRejectedValue(new Error("network error"));
95
95
  render(<NetworkPage />);
96
96
  await waitFor(() => {
97
- expect(screen.getByText(/network error/i)).toBeTruthy();
97
+ expect(screen.getByText(/network error/i)).toBeInTheDocument();
98
98
  });
99
99
  });
100
100
  });
@@ -8,9 +8,12 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
8
8
  import { Skeleton } from "@/components/ui/skeleton";
9
9
  import type { CreditOption } from "@/lib/api";
10
10
  import { createCreditCheckout, getCreditOptions } from "@/lib/api";
11
+ import { logger } from "@/lib/logger";
11
12
  import { cn } from "@/lib/utils";
12
13
  import { isAllowedRedirectUrl } from "@/lib/validate-redirect-url";
13
14
 
15
+ const log = logger("billing:buy-credits");
16
+
14
17
  export function BuyCreditsPanel() {
15
18
  const [tiers, setTiers] = useState<CreditOption[]>([]);
16
19
  const [tiersLoading, setTiersLoading] = useState(true);
@@ -28,7 +31,7 @@ export function BuyCreditsPanel() {
28
31
  setTiersLoading(false);
29
32
  })
30
33
  .catch((err) => {
31
- console.error("Failed to load credit options:", err);
34
+ log.error("Failed to load credit options:", err);
32
35
  setLoadError(true);
33
36
  setTiersLoading(false);
34
37
  });
@@ -47,7 +50,7 @@ export function BuyCreditsPanel() {
47
50
  })
48
51
  .catch((err) => {
49
52
  if (!cancelled) {
50
- console.error("Failed to load credit options:", err);
53
+ log.error("Failed to load credit options:", err);
51
54
  setLoadError(true);
52
55
  setTiersLoading(false);
53
56
  }
package/src/lib/api.ts CHANGED
@@ -1274,8 +1274,8 @@ export interface CheckoutResponse {
1274
1274
  export async function getCreditBalance(): Promise<CreditBalance> {
1275
1275
  const res = await trpcVanilla.billing.creditsBalance.query({});
1276
1276
  return {
1277
- balance: (res?.balance_credits ?? res?.balance_cents ?? 0) / 100,
1278
- dailyBurn: (res?.daily_burn_credits ?? res?.daily_burn_cents ?? 0) / 100,
1277
+ balance: (res?.balance_cents ?? 0) / 100,
1278
+ dailyBurn: (res?.daily_burn_cents ?? 0) / 100,
1279
1279
  runway: res?.runway_days ?? null,
1280
1280
  };
1281
1281
  }