@wopr-network/platform-core 1.14.7 → 1.14.8

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/.env.example CHANGED
@@ -14,6 +14,16 @@ AFFILIATE_BASE_URL=https://wopr.network/join?ref=
14
14
  # internal network. Enabling on public deployments weakens SSRF protections.
15
15
  # ALLOW_PRIVATE_NODE_HOSTS=false
16
16
 
17
+ # --- Provider API probe URLs ---
18
+ # Override the default health-check/validation endpoints per provider.
19
+ # Useful for air-gapped, proxied, or self-hosted deployments.
20
+ # ANTHROPIC_API_URL=https://api.anthropic.com/v1/models
21
+ # OPENAI_API_URL=https://api.openai.com/v1/models
22
+ # GOOGLE_API_URL=https://generativelanguage.googleapis.com/v1/models
23
+ # DISCORD_API_URL=https://discord.com/api/v10/users/@me
24
+ # ELEVENLABS_API_URL=https://api.elevenlabs.io/v1/user
25
+ # DEEPGRAM_API_URL=https://api.deepgram.com/v1/projects
26
+
17
27
  # --- Affiliate billing caps ---
18
28
 
19
29
  # Maximum number of referrals an affiliate can earn credit for in a 30-day window (default: 20)
@@ -2,5 +2,9 @@ import type { Provider } from "../security/types.js";
2
2
  /**
3
3
  * Base API URLs used to validate provider keys.
4
4
  * Centralised here so every consumer references one source of truth.
5
+ *
6
+ * Each URL can be overridden via env var for proxied / air-gapped / self-hosted deployments:
7
+ * ANTHROPIC_API_URL, OPENAI_API_URL, GOOGLE_API_URL,
8
+ * DISCORD_API_URL, ELEVENLABS_API_URL, DEEPGRAM_API_URL
5
9
  */
6
10
  export declare const PROVIDER_API_URLS: Record<Provider, string>;
@@ -1,12 +1,16 @@
1
1
  /**
2
2
  * Base API URLs used to validate provider keys.
3
3
  * Centralised here so every consumer references one source of truth.
4
+ *
5
+ * Each URL can be overridden via env var for proxied / air-gapped / self-hosted deployments:
6
+ * ANTHROPIC_API_URL, OPENAI_API_URL, GOOGLE_API_URL,
7
+ * DISCORD_API_URL, ELEVENLABS_API_URL, DEEPGRAM_API_URL
4
8
  */
5
9
  export const PROVIDER_API_URLS = {
6
- anthropic: "https://api.anthropic.com/v1/models",
7
- openai: "https://api.openai.com/v1/models",
8
- google: "https://generativelanguage.googleapis.com/v1/models",
9
- discord: "https://discord.com/api/v10/users/@me",
10
- elevenlabs: "https://api.elevenlabs.io/v1/user",
11
- deepgram: "https://api.deepgram.com/v1/projects",
10
+ anthropic: process.env.ANTHROPIC_API_URL || "https://api.anthropic.com/v1/models",
11
+ openai: process.env.OPENAI_API_URL || "https://api.openai.com/v1/models",
12
+ google: process.env.GOOGLE_API_URL || "https://generativelanguage.googleapis.com/v1/models",
13
+ discord: process.env.DISCORD_API_URL || "https://discord.com/api/v10/users/@me",
14
+ elevenlabs: process.env.ELEVENLABS_API_URL || "https://api.elevenlabs.io/v1/user",
15
+ deepgram: process.env.DEEPGRAM_API_URL || "https://api.deepgram.com/v1/projects",
12
16
  };
@@ -14,10 +14,10 @@ export type DrizzleDb = PgDatabase<PgQueryResultHKT, PlatformSchema>;
14
14
  export type PlatformDb = DrizzleDb;
15
15
  /** Create a Drizzle database instance wrapping the given pg.Pool. */
16
16
  export declare function createDb(pool: Pool): PlatformDb;
17
- export { schema };
18
17
  export type { SQL } from "drizzle-orm";
19
18
  export { and, asc, count, desc, eq, gt, gte, ilike, inArray, isNull, like, lt, lte, ne, or, sql } from "drizzle-orm";
20
19
  export { pgTable, text } from "drizzle-orm/pg-core";
21
20
  export type { AuthUser, IAuthUserRepository } from "./auth-user-repository.js";
22
21
  export { BetterAuthUserRepository } from "./auth-user-repository.js";
23
22
  export { creditColumn } from "./credit-column.js";
23
+ export { schema };
package/dist/db/index.js CHANGED
@@ -4,7 +4,6 @@ import * as schema from "./schema/index.js";
4
4
  export function createDb(pool) {
5
5
  return drizzle(pool, { schema });
6
6
  }
7
- export { schema };
8
7
  // Re-export commonly used drizzle-orm operators so consumers using pnpm link
9
8
  // resolve them from the same drizzle-orm instance as the schema tables.
10
9
  export { and, asc, count, desc, eq, gt, gte, ilike, inArray, isNull, like, lt, lte, ne, or, sql } from "drizzle-orm";
@@ -12,3 +11,4 @@ export { and, asc, count, desc, eq, gt, gte, ilike, inArray, isNull, like, lt, l
12
11
  export { pgTable, text } from "drizzle-orm/pg-core";
13
12
  export { BetterAuthUserRepository } from "./auth-user-repository.js";
14
13
  export { creditColumn } from "./credit-column.js";
14
+ export { schema };
@@ -1,8 +1,6 @@
1
1
  import type { NodeStatus } from "./node-state-machine.js";
2
2
  import type { NewProvisioningNode, Node, NodeRegistration, NodeTransition, ProvisionDataUpdate, SelfHostedNodeRegistration } from "./repository-types.js";
3
- export type { Node, NodeTransition };
4
- export type { NodeRegistration, SelfHostedNodeRegistration };
5
- export type { NewProvisioningNode, ProvisionDataUpdate };
3
+ export type { NewProvisioningNode, Node, NodeRegistration, NodeTransition, ProvisionDataUpdate, SelfHostedNodeRegistration, };
6
4
  export interface INodeRepository {
7
5
  getById(id: string): Promise<Node | null>;
8
6
  getBySecret(secret: string): Promise<Node | null>;
@@ -1,15 +1,20 @@
1
1
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
- import { PROVIDER_API_URLS } from "../config/provider-endpoints.js";
3
2
  import { PROVIDER_ENDPOINTS, validateProviderKey } from "./key-validation.js";
4
3
  describe("key-validation", () => {
5
4
  describe("PROVIDER_API_URLS", () => {
6
- it("exports a URL for every supported provider", () => {
7
- expect(PROVIDER_API_URLS.anthropic).toBe("https://api.anthropic.com/v1/models");
8
- expect(PROVIDER_API_URLS.openai).toBe("https://api.openai.com/v1/models");
9
- expect(PROVIDER_API_URLS.google).toBe("https://generativelanguage.googleapis.com/v1/models");
10
- expect(PROVIDER_API_URLS.discord).toBe("https://discord.com/api/v10/users/@me");
11
- expect(PROVIDER_API_URLS.elevenlabs).toBe("https://api.elevenlabs.io/v1/user");
12
- expect(PROVIDER_API_URLS.deepgram).toBe("https://api.deepgram.com/v1/projects");
5
+ afterEach(() => {
6
+ vi.unstubAllEnvs();
7
+ vi.resetModules();
8
+ });
9
+ it("exports a URL for every supported provider", async () => {
10
+ vi.resetModules();
11
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
12
+ expect(urls.anthropic).toBe("https://api.anthropic.com/v1/models");
13
+ expect(urls.openai).toBe("https://api.openai.com/v1/models");
14
+ expect(urls.google).toBe("https://generativelanguage.googleapis.com/v1/models");
15
+ expect(urls.discord).toBe("https://discord.com/api/v10/users/@me");
16
+ expect(urls.elevenlabs).toBe("https://api.elevenlabs.io/v1/user");
17
+ expect(urls.deepgram).toBe("https://api.deepgram.com/v1/projects");
13
18
  });
14
19
  });
15
20
  describe("PROVIDER_ENDPOINTS", () => {
@@ -84,4 +89,56 @@ describe("key-validation", () => {
84
89
  }));
85
90
  });
86
91
  });
92
+ describe("PROVIDER_API_URLS env overrides", () => {
93
+ afterEach(() => {
94
+ vi.unstubAllEnvs();
95
+ vi.resetModules();
96
+ });
97
+ it("uses ANTHROPIC_API_URL when set", async () => {
98
+ vi.stubEnv("ANTHROPIC_API_URL", "https://custom-anthropic.example.com/v1/models");
99
+ vi.resetModules();
100
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
101
+ expect(urls.anthropic).toBe("https://custom-anthropic.example.com/v1/models");
102
+ });
103
+ it("uses OPENAI_API_URL when set", async () => {
104
+ vi.stubEnv("OPENAI_API_URL", "https://custom-openai.example.com/v1/models");
105
+ vi.resetModules();
106
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
107
+ expect(urls.openai).toBe("https://custom-openai.example.com/v1/models");
108
+ });
109
+ it("uses GOOGLE_API_URL when set", async () => {
110
+ vi.stubEnv("GOOGLE_API_URL", "https://custom-google.example.com/v1/models");
111
+ vi.resetModules();
112
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
113
+ expect(urls.google).toBe("https://custom-google.example.com/v1/models");
114
+ });
115
+ it("uses DISCORD_API_URL when set", async () => {
116
+ vi.stubEnv("DISCORD_API_URL", "https://custom-discord.example.com/api/v10/users/@me");
117
+ vi.resetModules();
118
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
119
+ expect(urls.discord).toBe("https://custom-discord.example.com/api/v10/users/@me");
120
+ });
121
+ it("uses ELEVENLABS_API_URL when set", async () => {
122
+ vi.stubEnv("ELEVENLABS_API_URL", "https://custom-elevenlabs.example.com/v1/user");
123
+ vi.resetModules();
124
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
125
+ expect(urls.elevenlabs).toBe("https://custom-elevenlabs.example.com/v1/user");
126
+ });
127
+ it("uses DEEPGRAM_API_URL when set", async () => {
128
+ vi.stubEnv("DEEPGRAM_API_URL", "https://custom-deepgram.example.com/v1/projects");
129
+ vi.resetModules();
130
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
131
+ expect(urls.deepgram).toBe("https://custom-deepgram.example.com/v1/projects");
132
+ });
133
+ it("falls back to defaults when env vars are not set", async () => {
134
+ vi.resetModules();
135
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
136
+ expect(urls.anthropic).toBe("https://api.anthropic.com/v1/models");
137
+ expect(urls.openai).toBe("https://api.openai.com/v1/models");
138
+ expect(urls.google).toBe("https://generativelanguage.googleapis.com/v1/models");
139
+ expect(urls.discord).toBe("https://discord.com/api/v10/users/@me");
140
+ expect(urls.elevenlabs).toBe("https://api.elevenlabs.io/v1/user");
141
+ expect(urls.deepgram).toBe("https://api.deepgram.com/v1/projects");
142
+ });
143
+ });
87
144
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wopr-network/platform-core",
3
- "version": "1.14.7",
3
+ "version": "1.14.8",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,12 +3,16 @@ import type { Provider } from "../security/types.js";
3
3
  /**
4
4
  * Base API URLs used to validate provider keys.
5
5
  * Centralised here so every consumer references one source of truth.
6
+ *
7
+ * Each URL can be overridden via env var for proxied / air-gapped / self-hosted deployments:
8
+ * ANTHROPIC_API_URL, OPENAI_API_URL, GOOGLE_API_URL,
9
+ * DISCORD_API_URL, ELEVENLABS_API_URL, DEEPGRAM_API_URL
6
10
  */
7
11
  export const PROVIDER_API_URLS: Record<Provider, string> = {
8
- anthropic: "https://api.anthropic.com/v1/models",
9
- openai: "https://api.openai.com/v1/models",
10
- google: "https://generativelanguage.googleapis.com/v1/models",
11
- discord: "https://discord.com/api/v10/users/@me",
12
- elevenlabs: "https://api.elevenlabs.io/v1/user",
13
- deepgram: "https://api.deepgram.com/v1/projects",
12
+ anthropic: process.env.ANTHROPIC_API_URL || "https://api.anthropic.com/v1/models",
13
+ openai: process.env.OPENAI_API_URL || "https://api.openai.com/v1/models",
14
+ google: process.env.GOOGLE_API_URL || "https://generativelanguage.googleapis.com/v1/models",
15
+ discord: process.env.DISCORD_API_URL || "https://discord.com/api/v10/users/@me",
16
+ elevenlabs: process.env.ELEVENLABS_API_URL || "https://api.elevenlabs.io/v1/user",
17
+ deepgram: process.env.DEEPGRAM_API_URL || "https://api.deepgram.com/v1/projects",
14
18
  };
package/src/db/index.ts CHANGED
@@ -23,8 +23,6 @@ export function createDb(pool: Pool): PlatformDb {
23
23
  return drizzle(pool, { schema }) as unknown as PlatformDb;
24
24
  }
25
25
 
26
- export { schema };
27
-
28
26
  export type { SQL } from "drizzle-orm";
29
27
  // Re-export commonly used drizzle-orm operators so consumers using pnpm link
30
28
  // resolve them from the same drizzle-orm instance as the schema tables.
@@ -34,3 +32,4 @@ export { pgTable, text } from "drizzle-orm/pg-core";
34
32
  export type { AuthUser, IAuthUserRepository } from "./auth-user-repository.js";
35
33
  export { BetterAuthUserRepository } from "./auth-user-repository.js";
36
34
  export { creditColumn } from "./credit-column.js";
35
+ export { schema };
@@ -9,9 +9,14 @@ import type {
9
9
  } from "./repository-types.js";
10
10
 
11
11
  // Re-export domain types so existing consumers don't break
12
- export type { Node, NodeTransition };
13
- export type { NodeRegistration, SelfHostedNodeRegistration };
14
- export type { NewProvisioningNode, ProvisionDataUpdate };
12
+ export type {
13
+ NewProvisioningNode,
14
+ Node,
15
+ NodeRegistration,
16
+ NodeTransition,
17
+ ProvisionDataUpdate,
18
+ SelfHostedNodeRegistration,
19
+ };
15
20
 
16
21
  export interface INodeRepository {
17
22
  getById(id: string): Promise<Node | null>;
@@ -1,16 +1,22 @@
1
1
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
- import { PROVIDER_API_URLS } from "../config/provider-endpoints.js";
3
2
  import { PROVIDER_ENDPOINTS, validateProviderKey } from "./key-validation.js";
4
3
 
5
4
  describe("key-validation", () => {
6
5
  describe("PROVIDER_API_URLS", () => {
7
- it("exports a URL for every supported provider", () => {
8
- expect(PROVIDER_API_URLS.anthropic).toBe("https://api.anthropic.com/v1/models");
9
- expect(PROVIDER_API_URLS.openai).toBe("https://api.openai.com/v1/models");
10
- expect(PROVIDER_API_URLS.google).toBe("https://generativelanguage.googleapis.com/v1/models");
11
- expect(PROVIDER_API_URLS.discord).toBe("https://discord.com/api/v10/users/@me");
12
- expect(PROVIDER_API_URLS.elevenlabs).toBe("https://api.elevenlabs.io/v1/user");
13
- expect(PROVIDER_API_URLS.deepgram).toBe("https://api.deepgram.com/v1/projects");
6
+ afterEach(() => {
7
+ vi.unstubAllEnvs();
8
+ vi.resetModules();
9
+ });
10
+
11
+ it("exports a URL for every supported provider", async () => {
12
+ vi.resetModules();
13
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
14
+ expect(urls.anthropic).toBe("https://api.anthropic.com/v1/models");
15
+ expect(urls.openai).toBe("https://api.openai.com/v1/models");
16
+ expect(urls.google).toBe("https://generativelanguage.googleapis.com/v1/models");
17
+ expect(urls.discord).toBe("https://discord.com/api/v10/users/@me");
18
+ expect(urls.elevenlabs).toBe("https://api.elevenlabs.io/v1/user");
19
+ expect(urls.deepgram).toBe("https://api.deepgram.com/v1/projects");
14
20
  });
15
21
  });
16
22
 
@@ -108,4 +114,64 @@ describe("key-validation", () => {
108
114
  );
109
115
  });
110
116
  });
117
+
118
+ describe("PROVIDER_API_URLS env overrides", () => {
119
+ afterEach(() => {
120
+ vi.unstubAllEnvs();
121
+ vi.resetModules();
122
+ });
123
+
124
+ it("uses ANTHROPIC_API_URL when set", async () => {
125
+ vi.stubEnv("ANTHROPIC_API_URL", "https://custom-anthropic.example.com/v1/models");
126
+ vi.resetModules();
127
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
128
+ expect(urls.anthropic).toBe("https://custom-anthropic.example.com/v1/models");
129
+ });
130
+
131
+ it("uses OPENAI_API_URL when set", async () => {
132
+ vi.stubEnv("OPENAI_API_URL", "https://custom-openai.example.com/v1/models");
133
+ vi.resetModules();
134
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
135
+ expect(urls.openai).toBe("https://custom-openai.example.com/v1/models");
136
+ });
137
+
138
+ it("uses GOOGLE_API_URL when set", async () => {
139
+ vi.stubEnv("GOOGLE_API_URL", "https://custom-google.example.com/v1/models");
140
+ vi.resetModules();
141
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
142
+ expect(urls.google).toBe("https://custom-google.example.com/v1/models");
143
+ });
144
+
145
+ it("uses DISCORD_API_URL when set", async () => {
146
+ vi.stubEnv("DISCORD_API_URL", "https://custom-discord.example.com/api/v10/users/@me");
147
+ vi.resetModules();
148
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
149
+ expect(urls.discord).toBe("https://custom-discord.example.com/api/v10/users/@me");
150
+ });
151
+
152
+ it("uses ELEVENLABS_API_URL when set", async () => {
153
+ vi.stubEnv("ELEVENLABS_API_URL", "https://custom-elevenlabs.example.com/v1/user");
154
+ vi.resetModules();
155
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
156
+ expect(urls.elevenlabs).toBe("https://custom-elevenlabs.example.com/v1/user");
157
+ });
158
+
159
+ it("uses DEEPGRAM_API_URL when set", async () => {
160
+ vi.stubEnv("DEEPGRAM_API_URL", "https://custom-deepgram.example.com/v1/projects");
161
+ vi.resetModules();
162
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
163
+ expect(urls.deepgram).toBe("https://custom-deepgram.example.com/v1/projects");
164
+ });
165
+
166
+ it("falls back to defaults when env vars are not set", async () => {
167
+ vi.resetModules();
168
+ const { PROVIDER_API_URLS: urls } = await import("../config/provider-endpoints.js");
169
+ expect(urls.anthropic).toBe("https://api.anthropic.com/v1/models");
170
+ expect(urls.openai).toBe("https://api.openai.com/v1/models");
171
+ expect(urls.google).toBe("https://generativelanguage.googleapis.com/v1/models");
172
+ expect(urls.discord).toBe("https://discord.com/api/v10/users/@me");
173
+ expect(urls.elevenlabs).toBe("https://api.elevenlabs.io/v1/user");
174
+ expect(urls.deepgram).toBe("https://api.deepgram.com/v1/projects");
175
+ });
176
+ });
111
177
  });