pmxt-core 2.35.0 → 2.35.3
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/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/limitless/utils.js +22 -18
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/opinion/index.d.ts +1 -0
- package/dist/exchanges/opinion/index.js +11 -2
- package/dist/exchanges/opinion/normalizer.d.ts +14 -1
- package/dist/exchanges/opinion/normalizer.js +43 -0
- package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
- package/dist/exchanges/polymarket/api-clob.js +1 -1
- package/dist/exchanges/polymarket/api-data.d.ts +1 -1
- package/dist/exchanges/polymarket/api-data.js +1 -1
- package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
- package/dist/exchanges/polymarket/api-gamma.js +1 -1
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/router/Router.js +2 -1
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-25T12:12:42.204Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const kalshiApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.kalshiApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-25T12:12:42.204Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.kalshiApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-25T12:12:42.253Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const limitlessApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.limitlessApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-25T12:12:42.253Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.limitlessApiSpec = {
|
|
@@ -10,26 +10,30 @@ function mapMarketToUnified(market) {
|
|
|
10
10
|
if (!market)
|
|
11
11
|
return null;
|
|
12
12
|
const outcomes = [];
|
|
13
|
-
// The
|
|
14
|
-
//
|
|
15
|
-
//
|
|
13
|
+
// The Limitless SDK provides:
|
|
14
|
+
// tokens: { yes: "...", no: "..." }
|
|
15
|
+
// prices: [yesPrice, noPrice] (always [yes, no] per SDK docs)
|
|
16
|
+
// Use explicit key lookup — Object.entries order is not guaranteed to
|
|
17
|
+
// match the prices array.
|
|
16
18
|
if (market.tokens) {
|
|
17
|
-
const tokenEntries = Object.entries(market.tokens);
|
|
18
|
-
// Ensure prices array exists, otherwise default to empty
|
|
19
19
|
const prices = Array.isArray(market.prices) ? market.prices : [];
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
const yesPrice = prices[0] || 0;
|
|
21
|
+
const noPrice = prices[1] || 0;
|
|
22
|
+
outcomes.push({
|
|
23
|
+
outcomeId: market.tokens.yes,
|
|
24
|
+
marketId: market.slug,
|
|
25
|
+
label: 'Yes',
|
|
26
|
+
price: yesPrice,
|
|
27
|
+
priceChange24h: 0,
|
|
28
|
+
metadata: { clobTokenId: market.tokens.yes },
|
|
29
|
+
});
|
|
30
|
+
outcomes.push({
|
|
31
|
+
outcomeId: market.tokens.no,
|
|
32
|
+
marketId: market.slug,
|
|
33
|
+
label: 'No',
|
|
34
|
+
price: noPrice,
|
|
35
|
+
priceChange24h: 0,
|
|
36
|
+
metadata: { clobTokenId: market.tokens.no },
|
|
33
37
|
});
|
|
34
38
|
}
|
|
35
39
|
const um = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-25T12:12:42.269Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const myriadApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.myriadApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-25T12:12:42.269Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.myriadApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-25T12:12:42.274Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const opinionApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.opinionApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-25T12:12:42.274Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.opinionApiSpec = {
|
|
@@ -134,6 +134,7 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
134
134
|
return descMatch;
|
|
135
135
|
return titleMatch || descMatch;
|
|
136
136
|
});
|
|
137
|
+
await this.enrichPrices(filtered);
|
|
137
138
|
return filtered.slice(0, params.limit || 250000);
|
|
138
139
|
}
|
|
139
140
|
if (params?.sort === 'volume') {
|
|
@@ -144,7 +145,9 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
144
145
|
}
|
|
145
146
|
const offset = params?.offset || 0;
|
|
146
147
|
const limit = params?.limit || 250000;
|
|
147
|
-
|
|
148
|
+
const sliced = allMarkets.slice(offset, offset + limit);
|
|
149
|
+
await this.enrichPrices(sliced);
|
|
150
|
+
return sliced;
|
|
148
151
|
}
|
|
149
152
|
async fetchEventsImpl(params) {
|
|
150
153
|
const rawEvents = await this.fetcher.fetchRawEvents(params);
|
|
@@ -153,10 +156,13 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
153
156
|
const filtered = query
|
|
154
157
|
? rawEvents.filter((raw) => (raw.marketTitle || '').toLowerCase().includes(query))
|
|
155
158
|
: rawEvents;
|
|
156
|
-
|
|
159
|
+
const events = filtered
|
|
157
160
|
.map((raw) => this.normalizer.normalizeEvent(raw))
|
|
158
161
|
.filter((e) => e !== null)
|
|
159
162
|
.slice(0, limit);
|
|
163
|
+
const allMarkets = events.flatMap((e) => e.markets);
|
|
164
|
+
await this.enrichPrices(allMarkets);
|
|
165
|
+
return events;
|
|
160
166
|
}
|
|
161
167
|
async fetchOHLCV(id, params) {
|
|
162
168
|
const rawPoints = await this.fetcher.fetchRawOHLCV(id, params);
|
|
@@ -380,5 +386,8 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
380
386
|
}
|
|
381
387
|
return this.ws;
|
|
382
388
|
}
|
|
389
|
+
async enrichPrices(markets) {
|
|
390
|
+
await this.normalizer.enrichMarketsWithPrices(markets, (tokenId) => this.fetcher.fetchRawLatestPrice(tokenId));
|
|
391
|
+
}
|
|
383
392
|
}
|
|
384
393
|
exports.OpinionExchange = OpinionExchange;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OHLCVParams } from '../../BaseExchange';
|
|
2
2
|
import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, UserTrade, Position, Order } from '../../types';
|
|
3
3
|
import { IExchangeNormalizer } from '../interfaces';
|
|
4
|
-
import { OpinionRawMarket, OpinionRawOrderBook, OpinionRawPricePoint, OpinionRawUserTrade, OpinionRawPosition, OpinionRawOrder } from './fetcher';
|
|
4
|
+
import { OpinionRawMarket, OpinionRawOrderBook, OpinionRawPricePoint, OpinionRawLatestPrice, OpinionRawUserTrade, OpinionRawPosition, OpinionRawOrder } from './fetcher';
|
|
5
5
|
export declare class OpinionNormalizer implements IExchangeNormalizer<OpinionRawMarket, OpinionRawMarket> {
|
|
6
6
|
normalizeMarket(raw: OpinionRawMarket): UnifiedMarket | null;
|
|
7
7
|
normalizeMarketsFromEvent(raw: OpinionRawMarket): UnifiedMarket[];
|
|
@@ -14,6 +14,19 @@ export declare class OpinionNormalizer implements IExchangeNormalizer<OpinionRaw
|
|
|
14
14
|
normalizeUserTrade(raw: OpinionRawUserTrade, index: number): UserTrade;
|
|
15
15
|
normalizePosition(raw: OpinionRawPosition): Position;
|
|
16
16
|
normalizeOrder(raw: OpinionRawOrder): Order;
|
|
17
|
+
/**
|
|
18
|
+
* Fetch latest prices for all markets in parallel and update outcome prices.
|
|
19
|
+
*
|
|
20
|
+
* Opinion's /market endpoint does not include prices, so outcomes are
|
|
21
|
+
* initially created with a placeholder. This method calls the supplied
|
|
22
|
+
* `fetchLatestPrice` callback (backed by /token/latest-price) for the
|
|
23
|
+
* first outcome of every market, derives the complementary price for
|
|
24
|
+
* binary outcomes, and re-runs addBinaryOutcomes().
|
|
25
|
+
*
|
|
26
|
+
* Uses Promise.allSettled so a single failed price fetch never breaks the
|
|
27
|
+
* whole batch — markets whose price fetch fails simply keep the placeholder.
|
|
28
|
+
*/
|
|
29
|
+
enrichMarketsWithPrices(markets: UnifiedMarket[], fetchLatestPrice: (tokenId: string) => Promise<OpinionRawLatestPrice>): Promise<void>;
|
|
17
30
|
private normalizeBinaryMarket;
|
|
18
31
|
private normalizeChildMarket;
|
|
19
32
|
}
|
|
@@ -171,6 +171,49 @@ class OpinionNormalizer {
|
|
|
171
171
|
timestamp: (0, utils_1.toMillis)(raw.createdAt),
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
|
+
// -- Price enrichment -----------------------------------------------------
|
|
175
|
+
/**
|
|
176
|
+
* Fetch latest prices for all markets in parallel and update outcome prices.
|
|
177
|
+
*
|
|
178
|
+
* Opinion's /market endpoint does not include prices, so outcomes are
|
|
179
|
+
* initially created with a placeholder. This method calls the supplied
|
|
180
|
+
* `fetchLatestPrice` callback (backed by /token/latest-price) for the
|
|
181
|
+
* first outcome of every market, derives the complementary price for
|
|
182
|
+
* binary outcomes, and re-runs addBinaryOutcomes().
|
|
183
|
+
*
|
|
184
|
+
* Uses Promise.allSettled so a single failed price fetch never breaks the
|
|
185
|
+
* whole batch — markets whose price fetch fails simply keep the placeholder.
|
|
186
|
+
*/
|
|
187
|
+
async enrichMarketsWithPrices(markets, fetchLatestPrice) {
|
|
188
|
+
if (markets.length === 0)
|
|
189
|
+
return;
|
|
190
|
+
const results = await Promise.allSettled(markets.map(async (market) => {
|
|
191
|
+
const yesOutcome = market.outcomes[0];
|
|
192
|
+
if (!yesOutcome?.outcomeId)
|
|
193
|
+
return null;
|
|
194
|
+
const raw = await fetchLatestPrice(yesOutcome.outcomeId);
|
|
195
|
+
const yesPrice = parseFloat(raw?.price ?? '');
|
|
196
|
+
if (isNaN(yesPrice))
|
|
197
|
+
return null;
|
|
198
|
+
return { marketId: market.marketId, yesPrice };
|
|
199
|
+
}));
|
|
200
|
+
const priceMap = {};
|
|
201
|
+
for (const result of results) {
|
|
202
|
+
if (result.status === 'fulfilled' && result.value) {
|
|
203
|
+
priceMap[result.value.marketId] = result.value.yesPrice;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
for (const market of markets) {
|
|
207
|
+
const yesPrice = priceMap[market.marketId];
|
|
208
|
+
if (yesPrice === undefined)
|
|
209
|
+
continue;
|
|
210
|
+
if (market.outcomes[0])
|
|
211
|
+
market.outcomes[0].price = yesPrice;
|
|
212
|
+
if (market.outcomes[1])
|
|
213
|
+
market.outcomes[1].price = 1 - yesPrice;
|
|
214
|
+
(0, market_utils_1.addBinaryOutcomes)(market);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
174
217
|
// -- Private helpers ------------------------------------------------------
|
|
175
218
|
normalizeBinaryMarket(raw) {
|
|
176
219
|
if (!raw || raw.marketType !== 0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-25T12:12:42.210Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketClobSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketClobSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-25T12:12:42.210Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketClobSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-25T12:12:42.228Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketDataSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketDataSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-25T12:12:42.228Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketDataSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-25T12:12:42.226Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketGammaSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketGammaSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-25T12:12:42.226Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketGammaSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-25T12:12:42.260Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const probableApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.probableApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-25T12:12:42.260Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.probableApiSpec = {
|
package/dist/router/Router.js
CHANGED
|
@@ -140,7 +140,8 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
|
|
|
140
140
|
if (params?.limit !== undefined)
|
|
141
141
|
query.limit = String(params.limit);
|
|
142
142
|
const res = await this.client.getArbitrage(query);
|
|
143
|
-
|
|
143
|
+
// getArbitrage already unwraps .data — res is the opportunities array.
|
|
144
|
+
const items = Array.isArray(res) ? res : (res?.data ?? []);
|
|
144
145
|
return items.map((r) => ({
|
|
145
146
|
marketA: r.marketA,
|
|
146
147
|
marketB: r.marketB,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "2.35.
|
|
3
|
+
"version": "2.35.3",
|
|
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.35.
|
|
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.35.
|
|
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.35.3,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.35.3,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",
|