pmxtjs 2.1.2 → 2.2.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.
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/pmxt/client.js +2 -1
- package/dist/esm/pmxt/models.d.ts +16 -1
- package/dist/esm/pmxt/models.js +56 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -1
- package/dist/pmxt/client.js +2 -1
- package/dist/pmxt/models.d.ts +16 -1
- package/dist/pmxt/models.js +58 -0
- package/generated/package.json +1 -1
- package/generated/src/apis/DefaultApi.js +812 -0
- package/generated/src/apis/index.js +19 -0
- package/generated/src/index.js +21 -0
- package/generated/src/models/Balance.js +54 -0
- package/generated/src/models/BaseRequest.js +49 -0
- package/generated/src/models/BaseResponse.js +51 -0
- package/generated/src/models/CancelOrderRequest.js +53 -0
- package/generated/src/models/CreateOrder200Response.js +54 -0
- package/generated/src/models/CreateOrderParams.js +85 -0
- package/generated/src/models/CreateOrderRequest.js +54 -0
- package/generated/src/models/ErrorDetail.js +48 -0
- package/generated/src/models/ErrorResponse.js +51 -0
- package/generated/src/models/EventFetchParams.js +63 -0
- package/generated/src/models/ExchangeCredentials.js +59 -0
- package/generated/src/models/ExchangeCredentialsSignatureType.js +49 -0
- package/generated/src/models/ExecutionPriceResult.js +52 -0
- package/generated/src/models/FetchBalance200Response.js +54 -0
- package/generated/src/models/FetchEvents200Response.js +54 -0
- package/generated/src/models/FetchEventsRequest.js +52 -0
- package/generated/src/models/FetchMarkets200Response.js +54 -0
- package/generated/src/models/FetchMarketsRequest.js +52 -0
- package/generated/src/models/FetchOHLCV200Response.js +54 -0
- package/generated/src/models/FetchOHLCVRequest.js +54 -0
- package/generated/src/models/FetchOHLCVRequestArgsInner.js +56 -0
- package/generated/src/models/FetchOpenOrders200Response.js +54 -0
- package/generated/src/models/FetchOpenOrdersRequest.js +51 -0
- package/generated/src/models/FetchOrderBook200Response.js +54 -0
- package/generated/src/models/FetchOrderBookRequest.js +53 -0
- package/generated/src/models/FetchPositions200Response.js +54 -0
- package/generated/src/models/FetchPositionsRequest.js +51 -0
- package/generated/src/models/FetchTrades200Response.js +54 -0
- package/generated/src/models/FetchTradesRequest.js +54 -0
- package/generated/src/models/FilterEventsRequest.js +54 -0
- package/generated/src/models/FilterEventsRequestArgsInner.js +67 -0
- package/generated/src/models/FilterMarketsRequest.js +54 -0
- package/generated/src/models/FilterMarketsRequestArgsInner.js +67 -0
- package/generated/src/models/FilterMarketsRequestArgsInnerOneOf.js +47 -0
- package/generated/src/models/GetExecutionPrice200Response.js +53 -0
- package/generated/src/models/GetExecutionPriceDetailed200Response.js +54 -0
- package/generated/src/models/GetExecutionPriceRequest.js +54 -0
- package/generated/src/models/GetExecutionPriceRequestArgsInner.js +62 -0
- package/generated/src/models/HealthCheck200Response.js +50 -0
- package/generated/src/models/HistoryFilterParams.js +68 -0
- package/generated/src/models/MarketFilterParams.js +79 -0
- package/generated/src/models/MarketOutcome.js +56 -0
- package/generated/src/models/Order.js +95 -0
- package/generated/src/models/OrderBook.js +53 -0
- package/generated/src/models/OrderLevel.js +50 -0
- package/generated/src/models/Position.js +62 -0
- package/generated/src/models/PriceCandle.js +58 -0
- package/generated/src/models/Trade.js +65 -0
- package/generated/src/models/UnifiedEvent.js +65 -0
- package/generated/src/models/UnifiedMarket.js +81 -0
- package/generated/src/models/WatchOrderBookRequest.js +54 -0
- package/generated/src/models/WatchOrderBookRequestArgsInner.js +49 -0
- package/generated/src/models/WatchPricesRequest.js +53 -0
- package/generated/src/models/WatchTradesRequest.js +54 -0
- package/generated/src/models/WatchUserPositionsRequest.js +49 -0
- package/generated/src/models/index.js +73 -0
- package/generated/src/runtime.js +338 -0
- package/index.ts +1 -0
- package/package.json +2 -2
- package/pmxt/client.js +957 -0
- package/pmxt/client.ts +2 -1
- package/pmxt/models.js +60 -0
- package/pmxt/models.ts +60 -1
- package/pmxt/server-manager.js +204 -0
package/pmxt/client.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import {
|
|
23
23
|
UnifiedMarket,
|
|
24
24
|
MarketOutcome,
|
|
25
|
+
MarketList,
|
|
25
26
|
PriceCandle,
|
|
26
27
|
OrderBook,
|
|
27
28
|
OrderLevel,
|
|
@@ -159,7 +160,7 @@ function convertBalance(raw: any): Balance {
|
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
function convertEvent(raw: any): UnifiedEvent {
|
|
162
|
-
const markets = (raw.markets || []).map(convertMarket);
|
|
163
|
+
const markets = MarketList.from((raw.markets || []).map(convertMarket)) as MarketList;
|
|
163
164
|
|
|
164
165
|
return {
|
|
165
166
|
id: raw.id,
|
package/pmxt/models.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Data models for PMXT TypeScript SDK.
|
|
4
|
+
*
|
|
5
|
+
* These are clean TypeScript interfaces that provide a user-friendly API.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.MarketList = void 0;
|
|
9
|
+
/**
|
|
10
|
+
* A list of UnifiedMarket objects with a convenience match() method.
|
|
11
|
+
* Extends Array so all standard array operations work unchanged.
|
|
12
|
+
*/
|
|
13
|
+
class MarketList extends Array {
|
|
14
|
+
/**
|
|
15
|
+
* Find a single market by case-insensitive substring match.
|
|
16
|
+
*
|
|
17
|
+
* @param query - Substring to search for
|
|
18
|
+
* @param searchIn - Fields to search in (default: ['title'])
|
|
19
|
+
* @returns The matching UnifiedMarket
|
|
20
|
+
* @throws Error if zero or multiple markets match
|
|
21
|
+
*/
|
|
22
|
+
match(query, searchIn) {
|
|
23
|
+
const fields = searchIn || ['title'];
|
|
24
|
+
const lowerQuery = query.toLowerCase();
|
|
25
|
+
const matches = [];
|
|
26
|
+
for (const m of this) {
|
|
27
|
+
for (const field of fields) {
|
|
28
|
+
if (field === 'title' && m.title?.toLowerCase().includes(lowerQuery)) {
|
|
29
|
+
matches.push(m);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
if (field === 'description' && m.description?.toLowerCase().includes(lowerQuery)) {
|
|
33
|
+
matches.push(m);
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
if (field === 'category' && m.category?.toLowerCase().includes(lowerQuery)) {
|
|
37
|
+
matches.push(m);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
if (field === 'tags' && m.tags?.some(t => t.toLowerCase().includes(lowerQuery))) {
|
|
41
|
+
matches.push(m);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
if (field === 'outcomes' && m.outcomes?.some(o => o.label.toLowerCase().includes(lowerQuery))) {
|
|
45
|
+
matches.push(m);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (matches.length === 0) {
|
|
51
|
+
throw new Error(`No markets matching '${query}'`);
|
|
52
|
+
}
|
|
53
|
+
if (matches.length > 1) {
|
|
54
|
+
const titles = matches.map(m => m.title);
|
|
55
|
+
throw new Error(`Multiple markets matching '${query}': ${JSON.stringify(titles)}`);
|
|
56
|
+
}
|
|
57
|
+
return matches[0];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.MarketList = MarketList;
|
package/pmxt/models.ts
CHANGED
|
@@ -319,6 +319,65 @@ export interface CreateOrderParams {
|
|
|
319
319
|
/** Optional fee rate (e.g., 1000 for 0.1%) */
|
|
320
320
|
fee?: number;
|
|
321
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* A list of UnifiedMarket objects with a convenience match() method.
|
|
324
|
+
* Extends Array so all standard array operations work unchanged.
|
|
325
|
+
*/
|
|
326
|
+
export class MarketList extends Array<UnifiedMarket> {
|
|
327
|
+
/**
|
|
328
|
+
* Find a single market by case-insensitive substring match.
|
|
329
|
+
*
|
|
330
|
+
* @param query - Substring to search for
|
|
331
|
+
* @param searchIn - Fields to search in (default: ['title'])
|
|
332
|
+
* @returns The matching UnifiedMarket
|
|
333
|
+
* @throws Error if zero or multiple markets match
|
|
334
|
+
*/
|
|
335
|
+
match(query: string, searchIn?: ('title' | 'description' | 'category' | 'tags' | 'outcomes')[]): UnifiedMarket {
|
|
336
|
+
const fields = searchIn || ['title'];
|
|
337
|
+
const lowerQuery = query.toLowerCase();
|
|
338
|
+
const matches: UnifiedMarket[] = [];
|
|
339
|
+
|
|
340
|
+
for (const m of this) {
|
|
341
|
+
for (const field of fields) {
|
|
342
|
+
if (field === 'title' && m.title?.toLowerCase().includes(lowerQuery)) {
|
|
343
|
+
matches.push(m);
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
if (field === 'description' && m.description?.toLowerCase().includes(lowerQuery)) {
|
|
347
|
+
matches.push(m);
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
if (field === 'category' && m.category?.toLowerCase().includes(lowerQuery)) {
|
|
351
|
+
matches.push(m);
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
if (field === 'tags' && m.tags?.some(t => t.toLowerCase().includes(lowerQuery))) {
|
|
355
|
+
matches.push(m);
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
if (field === 'outcomes' && m.outcomes?.some(o => o.label.toLowerCase().includes(lowerQuery))) {
|
|
359
|
+
matches.push(m);
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (matches.length === 0) {
|
|
366
|
+
throw new Error(`No markets matching '${query}'`);
|
|
367
|
+
}
|
|
368
|
+
if (matches.length > 1) {
|
|
369
|
+
const titlesStr = matches
|
|
370
|
+
.map((m, i) => {
|
|
371
|
+
const truncated = m.title.length > 70 ? m.title.substring(0, 70) + '...' : m.title;
|
|
372
|
+
return `${i + 1}. ${truncated}`;
|
|
373
|
+
})
|
|
374
|
+
.join('\n ');
|
|
375
|
+
throw new Error(`Multiple markets matching '${query}' (${matches.length} matches):\n ${titlesStr}\n\nPlease refine your search.`);
|
|
376
|
+
}
|
|
377
|
+
return matches[0];
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
322
381
|
/**
|
|
323
382
|
* A grouped collection of related markets (e.g., "Who will be Fed Chair?" contains multiple candidate markets)
|
|
324
383
|
*/
|
|
@@ -336,7 +395,7 @@ export interface UnifiedEvent {
|
|
|
336
395
|
slug: string;
|
|
337
396
|
|
|
338
397
|
/** Related markets in this event */
|
|
339
|
-
markets:
|
|
398
|
+
markets: MarketList;
|
|
340
399
|
|
|
341
400
|
/** Event URL */
|
|
342
401
|
url: string;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Server manager for PMXT TypeScript SDK.
|
|
4
|
+
*
|
|
5
|
+
* Handles automatic server startup and health checks.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.ServerManager = void 0;
|
|
9
|
+
const index_js_1 = require("../generated/src/index.js");
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const os_1 = require("os");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
class ServerManager {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
this.baseUrl = options.baseUrl || `http://localhost:${ServerManager.DEFAULT_PORT}`;
|
|
16
|
+
this.maxRetries = options.maxRetries || 30;
|
|
17
|
+
this.retryDelayMs = options.retryDelayMs || 1000;
|
|
18
|
+
this.lockPath = (0, path_1.join)((0, os_1.homedir)(), '.pmxt', 'server.lock');
|
|
19
|
+
const config = new index_js_1.Configuration({ basePath: this.baseUrl });
|
|
20
|
+
this.api = new index_js_1.DefaultApi(config);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Read server information from lock file.
|
|
24
|
+
*/
|
|
25
|
+
getServerInfo() {
|
|
26
|
+
try {
|
|
27
|
+
if (!(0, fs_1.existsSync)(this.lockPath)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const content = (0, fs_1.readFileSync)(this.lockPath, 'utf-8');
|
|
31
|
+
return JSON.parse(content);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get the actual port the server is running on.
|
|
39
|
+
*
|
|
40
|
+
* This reads the lock file to determine the actual port,
|
|
41
|
+
* which may differ from the default if the default port was busy.
|
|
42
|
+
*/
|
|
43
|
+
getRunningPort() {
|
|
44
|
+
const info = this.getServerInfo();
|
|
45
|
+
return info?.port || ServerManager.DEFAULT_PORT;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the access token from the lock file.
|
|
49
|
+
*/
|
|
50
|
+
getAccessToken() {
|
|
51
|
+
const info = this.getServerInfo();
|
|
52
|
+
return info?.accessToken;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if the server is running.
|
|
56
|
+
*/
|
|
57
|
+
async isServerRunning() {
|
|
58
|
+
// Read lock file to get current port
|
|
59
|
+
const port = this.getRunningPort();
|
|
60
|
+
try {
|
|
61
|
+
// Use native fetch to check health on the actual running port
|
|
62
|
+
// This avoids issues where this.api is configured with the wrong port
|
|
63
|
+
const response = await fetch(`http://localhost:${port}/health`);
|
|
64
|
+
if (response.ok) {
|
|
65
|
+
const data = await response.json();
|
|
66
|
+
return data.status === "ok";
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Wait for the server to be ready.
|
|
76
|
+
*/
|
|
77
|
+
async waitForServer() {
|
|
78
|
+
for (let i = 0; i < this.maxRetries; i++) {
|
|
79
|
+
if (await this.isServerRunning()) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
await new Promise((resolve) => setTimeout(resolve, this.retryDelayMs));
|
|
83
|
+
}
|
|
84
|
+
throw new Error(`Server did not start within ${(this.maxRetries * this.retryDelayMs) / 1000}s`);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Ensure the server is running, starting it if necessary.
|
|
88
|
+
*/
|
|
89
|
+
async ensureServerRunning() {
|
|
90
|
+
// Check for force restart
|
|
91
|
+
if (process.env.PMXT_ALWAYS_RESTART === '1') {
|
|
92
|
+
await this.killOldServer();
|
|
93
|
+
}
|
|
94
|
+
// Check if already running and version matches
|
|
95
|
+
if (await this.isServerRunning()) {
|
|
96
|
+
if (await this.isVersionMismatch()) {
|
|
97
|
+
await this.killOldServer();
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Locate pmxt-ensure-server
|
|
104
|
+
let launcherPath = 'pmxt-ensure-server'; // Default to PATH
|
|
105
|
+
try {
|
|
106
|
+
// Try to resolve from pmxt-core dependency
|
|
107
|
+
// For CommonJS build (which is primary), we can use require directly
|
|
108
|
+
// For ESM build, this will be transpiled appropriately
|
|
109
|
+
const corePackageJson = require.resolve('pmxt-core/package.json');
|
|
110
|
+
const coreDir = (0, path_1.dirname)(corePackageJson);
|
|
111
|
+
const binPath = (0, path_1.join)(coreDir, 'bin', 'pmxt-ensure-server');
|
|
112
|
+
if ((0, fs_1.existsSync)(binPath)) {
|
|
113
|
+
launcherPath = binPath;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
// If resolution fails, fall back to PATH
|
|
118
|
+
// This could happen in dev environments where pmxt-core is globally installed
|
|
119
|
+
}
|
|
120
|
+
// Try to start the server using pmxt-ensure-server
|
|
121
|
+
const { spawn } = await Promise.resolve().then(() => require("child_process"));
|
|
122
|
+
try {
|
|
123
|
+
const proc = spawn(launcherPath, [], {
|
|
124
|
+
detached: true,
|
|
125
|
+
stdio: "ignore",
|
|
126
|
+
});
|
|
127
|
+
proc.unref();
|
|
128
|
+
// Wait for server to be ready
|
|
129
|
+
await this.waitForServer();
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new Error(`Failed to start PMXT server: ${error}\n\n` +
|
|
133
|
+
`Please ensure 'pmxt-core' is installed: npm install -g pmxt-core\n` +
|
|
134
|
+
`Or start the server manually: pmxt-server`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async isVersionMismatch() {
|
|
138
|
+
const info = this.getServerInfo();
|
|
139
|
+
if (!info || !info.version) {
|
|
140
|
+
return true; // Old server without version
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
// 1. Try to find package.json relative to the installed location (Production)
|
|
144
|
+
let corePackageJsonPath;
|
|
145
|
+
try {
|
|
146
|
+
corePackageJsonPath = require.resolve('pmxt-core/package.json');
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// 2. Try dev path (Monorepo)
|
|
150
|
+
const devPath = (0, path_1.join)((0, path_1.dirname)(__dirname), '../../core/package.json');
|
|
151
|
+
if ((0, fs_1.existsSync)(devPath)) {
|
|
152
|
+
corePackageJsonPath = devPath;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (corePackageJsonPath && (0, fs_1.existsSync)(corePackageJsonPath)) {
|
|
156
|
+
const content = (0, fs_1.readFileSync)(corePackageJsonPath, 'utf-8');
|
|
157
|
+
const pkg = JSON.parse(content);
|
|
158
|
+
// Check if running version starts with package version
|
|
159
|
+
// (Server version might have extra hash in dev mode)
|
|
160
|
+
if (pkg.version && !info.version.startsWith(pkg.version)) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// Ignore errors
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Stop the currently running server.
|
|
172
|
+
*/
|
|
173
|
+
async stop() {
|
|
174
|
+
await this.killOldServer();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Restart the server.
|
|
178
|
+
*/
|
|
179
|
+
async restart() {
|
|
180
|
+
await this.stop();
|
|
181
|
+
await this.ensureServerRunning();
|
|
182
|
+
}
|
|
183
|
+
async killOldServer() {
|
|
184
|
+
const info = this.getServerInfo();
|
|
185
|
+
if (info && info.pid) {
|
|
186
|
+
try {
|
|
187
|
+
process.kill(info.pid, 'SIGTERM');
|
|
188
|
+
// Brief wait
|
|
189
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// Ignore
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Remove lock file (best effort)
|
|
196
|
+
try {
|
|
197
|
+
const { unlinkSync } = await Promise.resolve().then(() => require('fs'));
|
|
198
|
+
unlinkSync(this.lockPath);
|
|
199
|
+
}
|
|
200
|
+
catch { }
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
exports.ServerManager = ServerManager;
|
|
204
|
+
ServerManager.DEFAULT_PORT = 3847;
|