pmxt-core 2.44.4 → 2.44.6

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.
Files changed (38) hide show
  1. package/dist/errors.d.ts +6 -0
  2. package/dist/errors.js +10 -1
  3. package/dist/exchanges/kalshi/api.d.ts +1 -1
  4. package/dist/exchanges/kalshi/api.js +1 -1
  5. package/dist/exchanges/kalshi/fetcher.d.ts +11 -1
  6. package/dist/exchanges/kalshi/fetcher.js +49 -17
  7. package/dist/exchanges/kalshi/normalizer.d.ts +12 -0
  8. package/dist/exchanges/kalshi/normalizer.js +125 -1
  9. package/dist/exchanges/limitless/api.d.ts +1 -1
  10. package/dist/exchanges/limitless/api.js +1 -1
  11. package/dist/exchanges/mock/index.d.ts +3 -2
  12. package/dist/exchanges/mock/index.js +14 -5
  13. package/dist/exchanges/myriad/api.d.ts +1 -1
  14. package/dist/exchanges/myriad/api.js +1 -1
  15. package/dist/exchanges/opinion/api.d.ts +1 -1
  16. package/dist/exchanges/opinion/api.js +1 -1
  17. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  18. package/dist/exchanges/polymarket/api-clob.js +1 -1
  19. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  20. package/dist/exchanges/polymarket/api-data.js +1 -1
  21. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  22. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  23. package/dist/exchanges/probable/api.d.ts +1 -1
  24. package/dist/exchanges/probable/api.js +1 -1
  25. package/dist/feeds/binance/binance-feed.d.ts +9 -0
  26. package/dist/feeds/binance/binance-feed.js +34 -7
  27. package/dist/feeds/chainlink/chainlink-feed.d.ts +14 -0
  28. package/dist/feeds/chainlink/chainlink-feed.js +62 -7
  29. package/dist/feeds/interfaces.d.ts +10 -0
  30. package/dist/router/Router.d.ts +9 -0
  31. package/dist/router/Router.js +153 -2
  32. package/dist/router/types.d.ts +5 -0
  33. package/dist/server/app.d.ts +26 -2
  34. package/dist/server/app.js +50 -9
  35. package/dist/server/feed-routes.js +34 -12
  36. package/dist/server/sql-route.d.ts +2 -0
  37. package/dist/server/sql-route.js +277 -0
  38. package/package.json +3 -3
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createWebSocketHandler = void 0;
7
7
  exports.createApp = createApp;
8
+ exports.attachWebSocketEndpoint = attachWebSocketEndpoint;
8
9
  exports.startServer = startServer;
9
10
  const express_1 = __importDefault(require("express"));
10
11
  const cors_1 = __importDefault(require("cors"));
@@ -13,6 +14,9 @@ const path_1 = __importDefault(require("path"));
13
14
  const ws_handler_1 = require("./ws-handler");
14
15
  Object.defineProperty(exports, "createWebSocketHandler", { enumerable: true, get: function () { return ws_handler_1.createWebSocketHandler; } });
15
16
  const exchange_factory_1 = require("./exchange-factory");
17
+ const feed_routes_1 = require("./feed-routes");
18
+ const sql_route_1 = require("./sql-route");
19
+ const router_1 = require("../router");
16
20
  const errors_1 = require("../errors");
17
21
  const logger_1 = require("../utils/logger");
18
22
  function loadMethodVerbs() {
@@ -142,7 +146,14 @@ const defaultExchanges = {
142
146
  opinion: null,
143
147
  metaculus: null,
144
148
  smarkets: null,
149
+ mock: null,
145
150
  };
151
+ function getDefaultExchange(exchangeName) {
152
+ if (!defaultExchanges[exchangeName]) {
153
+ defaultExchanges[exchangeName] = (0, exchange_factory_1.createExchange)(exchangeName);
154
+ }
155
+ return defaultExchanges[exchangeName];
156
+ }
146
157
  /**
147
158
  * Build an Express app that serves the PMXT sidecar API surface without
148
159
  * binding to a port.
@@ -151,12 +162,25 @@ const defaultExchanges = {
151
162
  * wrap the sidecar in their own auth / quota / usage middleware and serve
152
163
  * it as part of a larger Express application.
153
164
  *
154
- * The returned app registers:
165
+ * The returned app registers HTTP routes only:
155
166
  * - `GET /health`
156
167
  * - (optional) the built-in `x-pmxt-access-token` auth check
157
168
  * - `POST /api/:exchange/:method`
158
169
  * - the error handler
159
170
  *
171
+ * WebSocket upgrades do not pass through Express routing. Local servers
172
+ * created from this app can expose `/ws` by attaching the WebSocket endpoint
173
+ * to the underlying HTTP server:
174
+ *
175
+ * ```ts
176
+ * import { createApp, attachWebSocketEndpoint } from 'pmxt-core';
177
+ *
178
+ * const accessToken = process.env.PMXT_ACCESS_TOKEN;
179
+ * const app = createApp({ accessToken });
180
+ * const server = app.listen(4000, "127.0.0.1");
181
+ * attachWebSocketEndpoint(server, { accessToken });
182
+ * ```
183
+ *
160
184
  * Usage:
161
185
  * ```ts
162
186
  * import express from 'express';
@@ -195,6 +219,10 @@ function createApp(options = {}) {
195
219
  next();
196
220
  });
197
221
  }
222
+ app.use("/v0/sql", (0, sql_route_1.createSqlRouter)());
223
+ // Mount before /api/:exchange/:method so "feeds" is not interpreted as
224
+ // an exchange name by the generic dispatcher.
225
+ app.use("/api/feeds", (0, feed_routes_1.createFeedRouter)());
198
226
  // Shared dispatch used by both GET and POST handlers below. Given the
199
227
  // method name, the positional args, and optional credentials, it
200
228
  // resolves the exchange instance (singleton or per-request) and
@@ -208,7 +236,12 @@ function createApp(options = {}) {
208
236
  // calls — not a server-side env var. Each request may carry a
209
237
  // different key, so Router is never cached as a singleton.
210
238
  const bearer = req.headers.authorization?.replace(/^Bearer\s+/i, "") || "";
211
- exchange = (0, exchange_factory_1.createExchange)(exchangeName, undefined, bearer);
239
+ exchange = new router_1.Router({
240
+ apiKey: bearer,
241
+ localExchanges: {
242
+ mock: getDefaultExchange("mock"),
243
+ },
244
+ });
212
245
  }
213
246
  else if (credentials &&
214
247
  (credentials.privateKey ||
@@ -217,10 +250,7 @@ function createApp(options = {}) {
217
250
  exchange = (0, exchange_factory_1.createExchange)(exchangeName, credentials);
218
251
  }
219
252
  else {
220
- if (!defaultExchanges[exchangeName]) {
221
- defaultExchanges[exchangeName] = (0, exchange_factory_1.createExchange)(exchangeName);
222
- }
223
- exchange = defaultExchanges[exchangeName];
253
+ exchange = getDefaultExchange(exchangeName);
224
254
  }
225
255
  if (req.headers["x-pmxt-verbose"] === "true") {
226
256
  exchange.verbose = true;
@@ -327,6 +357,19 @@ function createApp(options = {}) {
327
357
  });
328
358
  return app;
329
359
  }
360
+ /**
361
+ * Attach the PMXT streaming WebSocket endpoint to an HTTP server.
362
+ *
363
+ * Use this with servers built from `createApp()` when you need `/ws` support
364
+ * for watchOrderBook, watchOrderBooks, or watchTrades. The access token should
365
+ * match the one passed to `createApp()` so HTTP and WebSocket requests share
366
+ * the same local auth policy.
367
+ */
368
+ function attachWebSocketEndpoint(server, options = {}) {
369
+ const wsHandler = (0, ws_handler_1.createWebSocketHandler)(options);
370
+ wsHandler.attach(server);
371
+ return wsHandler;
372
+ }
330
373
  /**
331
374
  * Start the PMXT sidecar server on the given port with the built-in
332
375
  * access-token auth middleware enabled. Returns the underlying
@@ -338,8 +381,6 @@ function createApp(options = {}) {
338
381
  async function startServer(port, accessToken) {
339
382
  const app = createApp({ accessToken });
340
383
  const server = app.listen(port, "127.0.0.1");
341
- // Attach WebSocket handler for streaming subscriptions
342
- const wsHandler = (0, ws_handler_1.createWebSocketHandler)({ accessToken });
343
- wsHandler.attach(server);
384
+ attachWebSocketEndpoint(server, { accessToken });
344
385
  return server;
345
386
  }
@@ -66,6 +66,8 @@ function createFeedRouter() {
66
66
  // GET /api/feeds/:feed/fetchOHLCV?symbol=BTC/USDT&timeframe=1h&since=...&limit=...
67
67
  router.get('/:feed/fetchOHLCV', async (req, res, next) => {
68
68
  try {
69
+ if (sendUnsupportedIfNeeded(req, res, 'fetchOHLCV'))
70
+ return;
69
71
  const symbol = req.query.symbol;
70
72
  if (typeof symbol !== 'string') {
71
73
  res.status(400).json({ success: false, error: 'Missing required query parameter: symbol' });
@@ -87,10 +89,10 @@ function createFeedRouter() {
87
89
  router.get('/:feed/fetchOrderBook', async (req, res, next) => {
88
90
  try {
89
91
  const feed = req._feed;
90
- if (typeof feed.fetchOrderBook !== 'function') {
91
- res.status(501).json({ success: false, error: `Feed '${req.params.feed}' does not support fetchOrderBook` });
92
+ if (sendUnsupportedIfNeeded(req, res, 'fetchOrderBook'))
92
93
  return;
93
- }
94
+ if (typeof feed.fetchOrderBook !== 'function')
95
+ return sendUnsupported(res, getFeedParam(req), 'fetchOrderBook');
94
96
  const symbol = req.query.symbol;
95
97
  if (typeof symbol !== 'string') {
96
98
  res.status(400).json({ success: false, error: 'Missing required query parameter: symbol' });
@@ -107,10 +109,10 @@ function createFeedRouter() {
107
109
  router.get('/:feed/fetchOracleRound', async (req, res, next) => {
108
110
  try {
109
111
  const feed = req._feed;
110
- if (typeof feed.fetchOracleRound !== 'function') {
111
- res.status(501).json({ success: false, error: `Feed '${req.params.feed}' does not support fetchOracleRound` });
112
+ if (sendUnsupportedIfNeeded(req, res, 'fetchOracleRound'))
112
113
  return;
113
- }
114
+ if (typeof feed.fetchOracleRound !== 'function')
115
+ return sendUnsupported(res, getFeedParam(req), 'fetchOracleRound');
114
116
  const feedName = req.query.feed;
115
117
  if (typeof feedName !== 'string') {
116
118
  res.status(400).json({ success: false, error: 'Missing required query parameter: feed' });
@@ -127,10 +129,10 @@ function createFeedRouter() {
127
129
  router.get('/:feed/fetchOracleHistory', async (req, res, next) => {
128
130
  try {
129
131
  const feed = req._feed;
130
- if (typeof feed.fetchOracleHistory !== 'function') {
131
- res.status(501).json({ success: false, error: `Feed '${req.params.feed}' does not support fetchOracleHistory` });
132
+ if (sendUnsupportedIfNeeded(req, res, 'fetchOracleHistory'))
132
133
  return;
133
- }
134
+ if (typeof feed.fetchOracleHistory !== 'function')
135
+ return sendUnsupported(res, getFeedParam(req), 'fetchOracleHistory');
134
136
  const feedName = req.query.feed;
135
137
  if (typeof feedName !== 'string') {
136
138
  res.status(400).json({ success: false, error: 'Missing required query parameter: feed' });
@@ -150,10 +152,10 @@ function createFeedRouter() {
150
152
  router.get('/:feed/fetchHistoricalPrices', async (req, res, next) => {
151
153
  try {
152
154
  const feed = req._feed;
153
- if (typeof feed.fetchHistoricalPrices !== 'function') {
154
- res.status(501).json({ success: false, error: `Feed '${req.params.feed}' does not support fetchHistoricalPrices` });
155
+ if (sendUnsupportedIfNeeded(req, res, 'fetchHistoricalPrices'))
155
156
  return;
156
- }
157
+ if (typeof feed.fetchHistoricalPrices !== 'function')
158
+ return sendUnsupported(res, getFeedParam(req), 'fetchHistoricalPrices');
157
159
  const symbol = req.query.symbol;
158
160
  if (typeof symbol !== 'string') {
159
161
  res.status(400).json({ success: false, error: 'Missing required query parameter: symbol' });
@@ -178,3 +180,23 @@ function createFeedRouter() {
178
180
  });
179
181
  return router;
180
182
  }
183
+ function getRequestFeed(req) {
184
+ return req._feed;
185
+ }
186
+ function sendUnsupportedIfNeeded(req, res, method) {
187
+ const feed = getRequestFeed(req);
188
+ if (feed.has?.[method] !== false)
189
+ return false;
190
+ sendUnsupported(res, feed.name || getFeedParam(req), method);
191
+ return true;
192
+ }
193
+ function sendUnsupported(res, feedName, method) {
194
+ res.status(501).json({
195
+ success: false,
196
+ error: `Feed '${feedName}' does not support ${method}`,
197
+ });
198
+ }
199
+ function getFeedParam(req) {
200
+ const value = req.params.feed;
201
+ return Array.isArray(value) ? value[0] ?? 'unknown' : value;
202
+ }
@@ -0,0 +1,2 @@
1
+ import { Router } from "express";
2
+ export declare function createSqlRouter(): Router;
@@ -0,0 +1,277 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSqlRouter = createSqlRouter;
4
+ const express_1 = require("express");
5
+ const MAX_QUERY_LENGTH = 10_000;
6
+ const ALLOWED_FIRST_KEYWORDS = new Set([
7
+ "SELECT",
8
+ "WITH",
9
+ "SHOW",
10
+ "DESCRIBE",
11
+ "DESC",
12
+ "EXISTS",
13
+ "EXPLAIN",
14
+ ]);
15
+ const WRITE_KEYWORDS = [
16
+ "INSERT",
17
+ "CREATE",
18
+ "DROP",
19
+ "ALTER",
20
+ "DELETE",
21
+ "TRUNCATE",
22
+ "ATTACH",
23
+ "DETACH",
24
+ "GRANT",
25
+ "REVOKE",
26
+ "KILL",
27
+ "RENAME",
28
+ ];
29
+ const BLOCKED_FUNCTIONS = new Set([
30
+ "hostname",
31
+ "fqdn",
32
+ "displayname",
33
+ "version",
34
+ "buildid",
35
+ "serveruuid",
36
+ "uptime",
37
+ "tcpport",
38
+ "currentuser",
39
+ "user",
40
+ "currentdatabase",
41
+ "currentprofiles",
42
+ "enabledprofiles",
43
+ "defaultprofiles",
44
+ "currentroles",
45
+ "enabledroles",
46
+ "defaultroles",
47
+ "filesystemavailable",
48
+ "filesystemcapacity",
49
+ "filesystemunreserved",
50
+ "getsetting",
51
+ "getmacro",
52
+ ]);
53
+ const BLOCKED_DB_PREFIXES = ["system.", "information_schema."];
54
+ function stripComments(sql) {
55
+ return sql
56
+ .replace(/\/\*[\s\S]*?\*\//g, " ")
57
+ .replace(/--[^\n]*/g, " ")
58
+ .trim();
59
+ }
60
+ function stripStrings(sql) {
61
+ return sql.replace(/'(?:[^'\\]|\\.)*'/g, "''");
62
+ }
63
+ function validateSqlQuery(sql) {
64
+ if (typeof sql !== "string") {
65
+ return { valid: false, error: "query is required" };
66
+ }
67
+ const trimmed = sql.trim();
68
+ if (trimmed.length === 0) {
69
+ return { valid: false, error: "query is required" };
70
+ }
71
+ if (trimmed.length > MAX_QUERY_LENGTH) {
72
+ return {
73
+ valid: false,
74
+ error: `query exceeds maximum length (${MAX_QUERY_LENGTH} chars)`,
75
+ };
76
+ }
77
+ const withoutStrings = stripStrings(trimmed);
78
+ if (withoutStrings.includes(";")) {
79
+ return { valid: false, error: "multi-statement queries are not allowed" };
80
+ }
81
+ const stripped = stripComments(trimmed);
82
+ const firstWord = (stripped.split(/\s+/)[0] || "").toUpperCase();
83
+ if (!ALLOWED_FIRST_KEYWORDS.has(firstWord)) {
84
+ return {
85
+ valid: false,
86
+ error: `query type "${firstWord}" is not allowed - only SELECT, WITH, ` +
87
+ "SHOW, DESCRIBE, and EXPLAIN are permitted",
88
+ };
89
+ }
90
+ if (firstWord === "SHOW") {
91
+ const upper = stripped.toUpperCase();
92
+ if (/^SHOW\s+(GRANTS|CREATE|ACCESS|PROCESSLIST|SETTINGS)/.test(upper)) {
93
+ return { valid: false, error: "that SHOW command is not allowed" };
94
+ }
95
+ }
96
+ const safeText = stripStrings(stripped);
97
+ for (const keyword of WRITE_KEYWORDS) {
98
+ if (new RegExp(`\\b${keyword}\\b`, "i").test(safeText)) {
99
+ return { valid: false, error: `"${keyword}" is not allowed in queries` };
100
+ }
101
+ }
102
+ const lower = safeText.toLowerCase();
103
+ for (const prefix of BLOCKED_DB_PREFIXES) {
104
+ if (lower.includes(prefix)) {
105
+ return {
106
+ valid: false,
107
+ error: "queries against system tables are not allowed",
108
+ };
109
+ }
110
+ }
111
+ const funcCalls = lower.matchAll(/\b([a-z_][a-z0-9_]*)\s*\(/g);
112
+ for (const match of funcCalls) {
113
+ if (BLOCKED_FUNCTIONS.has(match[1])) {
114
+ return { valid: false, error: `function "${match[1]}" is not allowed` };
115
+ }
116
+ }
117
+ return { valid: true, query: trimmed };
118
+ }
119
+ function allowedPlans() {
120
+ return new Set((process.env.SQL_ALLOWED_PLANS || "Enterprise")
121
+ .split(",")
122
+ .map((plan) => plan.trim().toLowerCase())
123
+ .filter(Boolean));
124
+ }
125
+ function hasSqlAccess(req) {
126
+ if (!req.account)
127
+ return true;
128
+ const plan = req.account.plan_name ?? req.account.plan ?? "";
129
+ return typeof plan === "string" && allowedPlans().has(plan.toLowerCase());
130
+ }
131
+ function isConfigured() {
132
+ return Boolean(process.env.CLICKHOUSE_HTTP_URL);
133
+ }
134
+ function scrubErrorMessage(message) {
135
+ const user = process.env.CLICKHOUSE_SQL_USER || "readonly";
136
+ const escapedUser = user.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
137
+ return message
138
+ .replace(/\s*\(version\s+[\d.]+ \(official build\)\)/gi, "")
139
+ .replace(new RegExp(`${escapedUser}:\\s*`, "g"), "");
140
+ }
141
+ function extractErrorMessage(body) {
142
+ if (typeof body !== "string")
143
+ return String(body);
144
+ const trimmed = body.trim();
145
+ if (trimmed.startsWith("{")) {
146
+ try {
147
+ const parsed = JSON.parse(trimmed);
148
+ return scrubErrorMessage(parsed.exception || parsed.error || trimmed);
149
+ }
150
+ catch {
151
+ // Fall through to plain-text handling.
152
+ }
153
+ }
154
+ return scrubErrorMessage(trimmed.split("\n")[0] || "ClickHouse query failed");
155
+ }
156
+ async function queryClickHouse(sql) {
157
+ const baseUrl = process.env.CLICKHOUSE_HTTP_URL;
158
+ if (!baseUrl) {
159
+ throw Object.assign(new Error("SQL query service is not available"), {
160
+ chStatusCode: 503,
161
+ });
162
+ }
163
+ let url;
164
+ try {
165
+ url = new URL("/", baseUrl);
166
+ }
167
+ catch {
168
+ throw Object.assign(new Error("CLICKHOUSE_HTTP_URL is not a valid URL"), {
169
+ chStatusCode: 503,
170
+ });
171
+ }
172
+ url.searchParams.set("default_format", "JSON");
173
+ url.searchParams.set("readonly", "1");
174
+ url.searchParams.set("allow_ddl", "0");
175
+ url.searchParams.set("allow_introspection_functions", "0");
176
+ url.searchParams.set("max_execution_time", "5");
177
+ url.searchParams.set("max_result_rows", "10000");
178
+ const user = process.env.CLICKHOUSE_SQL_USER || "readonly";
179
+ const password = process.env.CLICKHOUSE_SQL_PASSWORD || "";
180
+ const auth = Buffer.from(`${user}:${password}`).toString("base64");
181
+ const response = await fetch(url, {
182
+ method: "POST",
183
+ headers: {
184
+ Authorization: `Basic ${auth}`,
185
+ "Content-Type": "text/plain",
186
+ },
187
+ body: sql,
188
+ signal: AbortSignal.timeout(6_000),
189
+ });
190
+ if (!response.ok) {
191
+ const body = await response.text();
192
+ const error = new Error(extractErrorMessage(body));
193
+ error.chStatusCode = response.status;
194
+ throw error;
195
+ }
196
+ const result = (await response.json());
197
+ if (result.exception) {
198
+ const error = new Error(extractErrorMessage(result.exception));
199
+ error.chStatusCode = 400;
200
+ throw error;
201
+ }
202
+ return result;
203
+ }
204
+ function extractQuery(req) {
205
+ return req.body?.query ?? req.query?.query;
206
+ }
207
+ async function handleQuery(req, res, next) {
208
+ try {
209
+ const validation = validateSqlQuery(extractQuery(req));
210
+ if (!validation.valid) {
211
+ res.status(400).json({ error: validation.error });
212
+ return;
213
+ }
214
+ if (!hasSqlAccess(req)) {
215
+ res.status(403).json({
216
+ error: "sql_access_denied",
217
+ message: "SQL query access requires an Enterprise plan",
218
+ });
219
+ return;
220
+ }
221
+ if (!isConfigured()) {
222
+ res.status(503).json({
223
+ error: "service_unavailable",
224
+ message: "SQL query service is not available. Configure CLICKHOUSE_HTTP_URL " +
225
+ "or use the hosted PMXT Enterprise SQL endpoint.",
226
+ });
227
+ return;
228
+ }
229
+ const result = await queryClickHouse(validation.query);
230
+ res.json({
231
+ data: result.data || [],
232
+ meta: {
233
+ columns: result.meta || [],
234
+ rows: result.rows ?? result.data?.length ?? 0,
235
+ statistics: result.statistics || {},
236
+ },
237
+ });
238
+ }
239
+ catch (error) {
240
+ const err = error;
241
+ if (err.chStatusCode === 503) {
242
+ res.status(503).json({
243
+ error: "service_unavailable",
244
+ message: err.message,
245
+ });
246
+ return;
247
+ }
248
+ if (err.chStatusCode === 401 || err.chStatusCode === 403) {
249
+ res.status(502).json({
250
+ error: "database_error",
251
+ message: "Database connection failed",
252
+ });
253
+ return;
254
+ }
255
+ if (err.chStatusCode) {
256
+ res.status(400).json({
257
+ error: "query_error",
258
+ message: err.message,
259
+ });
260
+ return;
261
+ }
262
+ if (err.name === "TimeoutError" || err.name === "AbortError") {
263
+ res.status(408).json({
264
+ error: "query_timeout",
265
+ message: "Query exceeded the maximum execution time (5s)",
266
+ });
267
+ return;
268
+ }
269
+ next(error);
270
+ }
271
+ }
272
+ function createSqlRouter() {
273
+ const router = (0, express_1.Router)();
274
+ router.post("/", handleQuery);
275
+ router.get("/", handleQuery);
276
+ return router;
277
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxt-core",
3
- "version": "2.44.4",
3
+ "version": "2.44.6",
4
4
  "description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,8 +29,8 @@
29
29
  "test": "jest -c jest.config.js",
30
30
  "server": "tsx watch src/server/index.ts",
31
31
  "server:prod": "node dist/server/index.js",
32
- "generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.44.4,library=urllib3",
33
- "generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.44.4,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
32
+ "generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.44.6,library=urllib3",
33
+ "generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.44.6,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
34
34
  "fetch:openapi": "node scripts/fetch-openapi-specs.js",
35
35
  "extract:jsdoc": "node ../scripts/extract-jsdoc.js",
36
36
  "generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",