@discomedia/utils 1.0.39 → 1.0.41
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/index-frontend.cjs +252 -6
- package/dist/index-frontend.cjs.map +1 -1
- package/dist/index-frontend.mjs +252 -6
- package/dist/index-frontend.mjs.map +1 -1
- package/dist/index.cjs +266 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +266 -9
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +2 -2
- package/dist/test.js +297 -85
- package/dist/test.js.map +1 -1
- package/dist/types/alpaca-market-data-api.d.ts +7 -7
- package/dist/types/alpaca-market-data-api.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/market-time.d.ts +29 -0
- package/dist/types/market-time.d.ts.map +1 -1
- package/dist/types/types/alpaca-types.d.ts +16 -0
- package/dist/types/types/alpaca-types.d.ts.map +1 -1
- package/dist/types-frontend/alpaca-market-data-api.d.ts +7 -7
- package/dist/types-frontend/alpaca-market-data-api.d.ts.map +1 -1
- package/dist/types-frontend/index.d.ts +1 -0
- package/dist/types-frontend/index.d.ts.map +1 -1
- package/dist/types-frontend/market-time.d.ts +29 -0
- package/dist/types-frontend/market-time.d.ts.map +1 -1
- package/dist/types-frontend/types/alpaca-types.d.ts +16 -0
- package/dist/types-frontend/types/alpaca-types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.41",
|
|
7
7
|
"author": "Disco Media",
|
|
8
8
|
"description": "Utility functions used in Disco Media apps",
|
|
9
9
|
"always-build-npm": true,
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"dotenv": "^17.2.3",
|
|
36
|
-
"openai": "^6.
|
|
36
|
+
"openai": "^6.2.0",
|
|
37
37
|
"p-limit": "^7.1.1",
|
|
38
38
|
"tslib": "^2.8.1",
|
|
39
39
|
"ws": "^8.18.3"
|
package/dist/test.js
CHANGED
|
@@ -799,7 +799,7 @@ const safeJSON = (text) => {
|
|
|
799
799
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
800
800
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
801
801
|
|
|
802
|
-
const VERSION = '6.
|
|
802
|
+
const VERSION = '6.2.0'; // x-release-please-version
|
|
803
803
|
|
|
804
804
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
805
805
|
const isRunningInBrowser = () => {
|
|
@@ -2200,6 +2200,15 @@ function getName(value) {
|
|
|
2200
2200
|
.pop() || undefined);
|
|
2201
2201
|
}
|
|
2202
2202
|
const isAsyncIterable = (value) => value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function';
|
|
2203
|
+
/**
|
|
2204
|
+
* Returns a multipart/form-data request if any part of the given request body contains a File / Blob value.
|
|
2205
|
+
* Otherwise returns the request as is.
|
|
2206
|
+
*/
|
|
2207
|
+
const maybeMultipartFormRequestOptions = async (opts, fetch) => {
|
|
2208
|
+
if (!hasUploadableValue(opts.body))
|
|
2209
|
+
return opts;
|
|
2210
|
+
return { ...opts, body: await createForm(opts.body, fetch) };
|
|
2211
|
+
};
|
|
2203
2212
|
const multipartFormRequestOptions = async (opts, fetch) => {
|
|
2204
2213
|
return { ...opts, body: await createForm(opts.body, fetch) };
|
|
2205
2214
|
};
|
|
@@ -2245,6 +2254,22 @@ const createForm = async (body, fetch) => {
|
|
|
2245
2254
|
// We check for Blob not File because Bun.File doesn't inherit from File,
|
|
2246
2255
|
// but they both inherit from Blob and have a `name` property at runtime.
|
|
2247
2256
|
const isNamedBlob = (value) => value instanceof Blob && 'name' in value;
|
|
2257
|
+
const isUploadable = (value) => typeof value === 'object' &&
|
|
2258
|
+
value !== null &&
|
|
2259
|
+
(value instanceof Response || isAsyncIterable(value) || isNamedBlob(value));
|
|
2260
|
+
const hasUploadableValue = (value) => {
|
|
2261
|
+
if (isUploadable(value))
|
|
2262
|
+
return true;
|
|
2263
|
+
if (Array.isArray(value))
|
|
2264
|
+
return value.some(hasUploadableValue);
|
|
2265
|
+
if (value && typeof value === 'object') {
|
|
2266
|
+
for (const k in value) {
|
|
2267
|
+
if (hasUploadableValue(value[k]))
|
|
2268
|
+
return true;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
return false;
|
|
2272
|
+
};
|
|
2248
2273
|
const addFormValue = async (form, key, value) => {
|
|
2249
2274
|
if (value === undefined)
|
|
2250
2275
|
return;
|
|
@@ -2299,7 +2324,7 @@ const isResponseLike = (value) => value != null &&
|
|
|
2299
2324
|
typeof value.blob === 'function';
|
|
2300
2325
|
/**
|
|
2301
2326
|
* Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
|
|
2302
|
-
* @param value the raw content of the file.
|
|
2327
|
+
* @param value the raw content of the file. Can be an {@link Uploadable}, BlobLikePart, or AsyncIterable of BlobLikeParts
|
|
2303
2328
|
* @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
|
|
2304
2329
|
* @param {Object=} options additional properties
|
|
2305
2330
|
* @param {string=} options.type the MIME type of the content
|
|
@@ -4150,7 +4175,7 @@ class Assistants extends APIResource {
|
|
|
4150
4175
|
}
|
|
4151
4176
|
|
|
4152
4177
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4153
|
-
class Sessions extends APIResource {
|
|
4178
|
+
let Sessions$1 = class Sessions extends APIResource {
|
|
4154
4179
|
/**
|
|
4155
4180
|
* Create an ephemeral API token for use in client-side applications with the
|
|
4156
4181
|
* Realtime API. Can be configured with the same session parameters as the
|
|
@@ -4173,7 +4198,7 @@ class Sessions extends APIResource {
|
|
|
4173
4198
|
headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
|
|
4174
4199
|
});
|
|
4175
4200
|
}
|
|
4176
|
-
}
|
|
4201
|
+
};
|
|
4177
4202
|
|
|
4178
4203
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4179
4204
|
class TranscriptionSessions extends APIResource {
|
|
@@ -4208,13 +4233,144 @@ class TranscriptionSessions extends APIResource {
|
|
|
4208
4233
|
let Realtime$1 = class Realtime extends APIResource {
|
|
4209
4234
|
constructor() {
|
|
4210
4235
|
super(...arguments);
|
|
4211
|
-
this.sessions = new Sessions(this._client);
|
|
4236
|
+
this.sessions = new Sessions$1(this._client);
|
|
4212
4237
|
this.transcriptionSessions = new TranscriptionSessions(this._client);
|
|
4213
4238
|
}
|
|
4214
4239
|
};
|
|
4215
|
-
Realtime$1.Sessions = Sessions;
|
|
4240
|
+
Realtime$1.Sessions = Sessions$1;
|
|
4216
4241
|
Realtime$1.TranscriptionSessions = TranscriptionSessions;
|
|
4217
4242
|
|
|
4243
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4244
|
+
class Sessions extends APIResource {
|
|
4245
|
+
/**
|
|
4246
|
+
* Create a ChatKit session
|
|
4247
|
+
*
|
|
4248
|
+
* @example
|
|
4249
|
+
* ```ts
|
|
4250
|
+
* const chatSession =
|
|
4251
|
+
* await client.beta.chatkit.sessions.create({
|
|
4252
|
+
* user: 'x',
|
|
4253
|
+
* workflow: { id: 'id' },
|
|
4254
|
+
* });
|
|
4255
|
+
* ```
|
|
4256
|
+
*/
|
|
4257
|
+
create(body, options) {
|
|
4258
|
+
return this._client.post('/chatkit/sessions', {
|
|
4259
|
+
body,
|
|
4260
|
+
...options,
|
|
4261
|
+
headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
|
|
4262
|
+
});
|
|
4263
|
+
}
|
|
4264
|
+
/**
|
|
4265
|
+
* Cancel a ChatKit session
|
|
4266
|
+
*
|
|
4267
|
+
* @example
|
|
4268
|
+
* ```ts
|
|
4269
|
+
* const chatSession =
|
|
4270
|
+
* await client.beta.chatkit.sessions.cancel('cksess_123');
|
|
4271
|
+
* ```
|
|
4272
|
+
*/
|
|
4273
|
+
cancel(sessionID, options) {
|
|
4274
|
+
return this._client.post(path `/chatkit/sessions/${sessionID}/cancel`, {
|
|
4275
|
+
...options,
|
|
4276
|
+
headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
|
|
4277
|
+
});
|
|
4278
|
+
}
|
|
4279
|
+
}
|
|
4280
|
+
|
|
4281
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4282
|
+
let Threads$1 = class Threads extends APIResource {
|
|
4283
|
+
/**
|
|
4284
|
+
* Retrieve a ChatKit thread
|
|
4285
|
+
*
|
|
4286
|
+
* @example
|
|
4287
|
+
* ```ts
|
|
4288
|
+
* const chatkitThread =
|
|
4289
|
+
* await client.beta.chatkit.threads.retrieve('cthr_123');
|
|
4290
|
+
* ```
|
|
4291
|
+
*/
|
|
4292
|
+
retrieve(threadID, options) {
|
|
4293
|
+
return this._client.get(path `/chatkit/threads/${threadID}`, {
|
|
4294
|
+
...options,
|
|
4295
|
+
headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
|
|
4296
|
+
});
|
|
4297
|
+
}
|
|
4298
|
+
/**
|
|
4299
|
+
* List ChatKit threads
|
|
4300
|
+
*
|
|
4301
|
+
* @example
|
|
4302
|
+
* ```ts
|
|
4303
|
+
* // Automatically fetches more pages as needed.
|
|
4304
|
+
* for await (const chatkitThread of client.beta.chatkit.threads.list()) {
|
|
4305
|
+
* // ...
|
|
4306
|
+
* }
|
|
4307
|
+
* ```
|
|
4308
|
+
*/
|
|
4309
|
+
list(query = {}, options) {
|
|
4310
|
+
return this._client.getAPIList('/chatkit/threads', (ConversationCursorPage), {
|
|
4311
|
+
query,
|
|
4312
|
+
...options,
|
|
4313
|
+
headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
|
|
4314
|
+
});
|
|
4315
|
+
}
|
|
4316
|
+
/**
|
|
4317
|
+
* Delete a ChatKit thread
|
|
4318
|
+
*
|
|
4319
|
+
* @example
|
|
4320
|
+
* ```ts
|
|
4321
|
+
* const thread = await client.beta.chatkit.threads.delete(
|
|
4322
|
+
* 'cthr_123',
|
|
4323
|
+
* );
|
|
4324
|
+
* ```
|
|
4325
|
+
*/
|
|
4326
|
+
delete(threadID, options) {
|
|
4327
|
+
return this._client.delete(path `/chatkit/threads/${threadID}`, {
|
|
4328
|
+
...options,
|
|
4329
|
+
headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
|
|
4330
|
+
});
|
|
4331
|
+
}
|
|
4332
|
+
/**
|
|
4333
|
+
* List ChatKit thread items
|
|
4334
|
+
*
|
|
4335
|
+
* @example
|
|
4336
|
+
* ```ts
|
|
4337
|
+
* // Automatically fetches more pages as needed.
|
|
4338
|
+
* for await (const thread of client.beta.chatkit.threads.listItems(
|
|
4339
|
+
* 'cthr_123',
|
|
4340
|
+
* )) {
|
|
4341
|
+
* // ...
|
|
4342
|
+
* }
|
|
4343
|
+
* ```
|
|
4344
|
+
*/
|
|
4345
|
+
listItems(threadID, query = {}, options) {
|
|
4346
|
+
return this._client.getAPIList(path `/chatkit/threads/${threadID}/items`, (ConversationCursorPage), { query, ...options, headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]) });
|
|
4347
|
+
}
|
|
4348
|
+
};
|
|
4349
|
+
|
|
4350
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4351
|
+
class ChatKit extends APIResource {
|
|
4352
|
+
constructor() {
|
|
4353
|
+
super(...arguments);
|
|
4354
|
+
this.sessions = new Sessions(this._client);
|
|
4355
|
+
this.threads = new Threads$1(this._client);
|
|
4356
|
+
}
|
|
4357
|
+
/**
|
|
4358
|
+
* Upload a ChatKit file
|
|
4359
|
+
*
|
|
4360
|
+
* @example
|
|
4361
|
+
* ```ts
|
|
4362
|
+
* const response = await client.beta.chatkit.uploadFile({
|
|
4363
|
+
* file: fs.createReadStream('path/to/file'),
|
|
4364
|
+
* });
|
|
4365
|
+
* ```
|
|
4366
|
+
*/
|
|
4367
|
+
uploadFile(body, options) {
|
|
4368
|
+
return this._client.post('/chatkit/files', maybeMultipartFormRequestOptions({ body, ...options, headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]) }, this._client));
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
4371
|
+
ChatKit.Sessions = Sessions;
|
|
4372
|
+
ChatKit.Threads = Threads$1;
|
|
4373
|
+
|
|
4218
4374
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
4219
4375
|
/**
|
|
4220
4376
|
* @deprecated The Assistants API is deprecated in favor of the Responses API
|
|
@@ -5152,11 +5308,13 @@ class Beta extends APIResource {
|
|
|
5152
5308
|
constructor() {
|
|
5153
5309
|
super(...arguments);
|
|
5154
5310
|
this.realtime = new Realtime$1(this._client);
|
|
5311
|
+
this.chatkit = new ChatKit(this._client);
|
|
5155
5312
|
this.assistants = new Assistants(this._client);
|
|
5156
5313
|
this.threads = new Threads(this._client);
|
|
5157
5314
|
}
|
|
5158
5315
|
}
|
|
5159
5316
|
Beta.Realtime = Realtime$1;
|
|
5317
|
+
Beta.ChatKit = ChatKit;
|
|
5160
5318
|
Beta.Assistants = Assistants;
|
|
5161
5319
|
Beta.Threads = Threads;
|
|
5162
5320
|
|
|
@@ -6909,6 +7067,51 @@ class VectorStores extends APIResource {
|
|
|
6909
7067
|
VectorStores.Files = Files;
|
|
6910
7068
|
VectorStores.FileBatches = FileBatches;
|
|
6911
7069
|
|
|
7070
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
7071
|
+
class Videos extends APIResource {
|
|
7072
|
+
/**
|
|
7073
|
+
* Create a video
|
|
7074
|
+
*/
|
|
7075
|
+
create(body, options) {
|
|
7076
|
+
return this._client.post('/videos', maybeMultipartFormRequestOptions({ body, ...options }, this._client));
|
|
7077
|
+
}
|
|
7078
|
+
/**
|
|
7079
|
+
* Retrieve a video
|
|
7080
|
+
*/
|
|
7081
|
+
retrieve(videoID, options) {
|
|
7082
|
+
return this._client.get(path `/videos/${videoID}`, options);
|
|
7083
|
+
}
|
|
7084
|
+
/**
|
|
7085
|
+
* List videos
|
|
7086
|
+
*/
|
|
7087
|
+
list(query = {}, options) {
|
|
7088
|
+
return this._client.getAPIList('/videos', (ConversationCursorPage), { query, ...options });
|
|
7089
|
+
}
|
|
7090
|
+
/**
|
|
7091
|
+
* Delete a video
|
|
7092
|
+
*/
|
|
7093
|
+
delete(videoID, options) {
|
|
7094
|
+
return this._client.delete(path `/videos/${videoID}`, options);
|
|
7095
|
+
}
|
|
7096
|
+
/**
|
|
7097
|
+
* Download video content
|
|
7098
|
+
*/
|
|
7099
|
+
downloadContent(videoID, query = {}, options) {
|
|
7100
|
+
return this._client.get(path `/videos/${videoID}/content`, {
|
|
7101
|
+
query,
|
|
7102
|
+
...options,
|
|
7103
|
+
headers: buildHeaders([{ Accept: 'application/binary' }, options?.headers]),
|
|
7104
|
+
__binaryResponse: true,
|
|
7105
|
+
});
|
|
7106
|
+
}
|
|
7107
|
+
/**
|
|
7108
|
+
* Create a video remix
|
|
7109
|
+
*/
|
|
7110
|
+
remix(videoID, body, options) {
|
|
7111
|
+
return this._client.post(path `/videos/${videoID}/remix`, maybeMultipartFormRequestOptions({ body, ...options }, this._client));
|
|
7112
|
+
}
|
|
7113
|
+
}
|
|
7114
|
+
|
|
6912
7115
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
6913
7116
|
var _Webhooks_instances, _Webhooks_validateSecret, _Webhooks_getRequiredHeader;
|
|
6914
7117
|
class Webhooks extends APIResource {
|
|
@@ -7047,6 +7250,7 @@ class OpenAI {
|
|
|
7047
7250
|
this.conversations = new Conversations(this);
|
|
7048
7251
|
this.evals = new Evals(this);
|
|
7049
7252
|
this.containers = new Containers(this);
|
|
7253
|
+
this.videos = new Videos(this);
|
|
7050
7254
|
if (apiKey === undefined) {
|
|
7051
7255
|
throw new OpenAIError('Missing credentials. Please pass an `apiKey`, or set the `OPENAI_API_KEY` environment variable.');
|
|
7052
7256
|
}
|
|
@@ -7517,6 +7721,7 @@ OpenAI.Realtime = Realtime;
|
|
|
7517
7721
|
OpenAI.Conversations = Conversations;
|
|
7518
7722
|
OpenAI.Evals = Evals;
|
|
7519
7723
|
OpenAI.Containers = Containers;
|
|
7724
|
+
OpenAI.Videos = Videos;
|
|
7520
7725
|
|
|
7521
7726
|
function getDefaultExportFromCjs (x) {
|
|
7522
7727
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -13526,14 +13731,25 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
13526
13731
|
`Avg Volume: ${avgVolume.toLocaleString()}`);
|
|
13527
13732
|
}
|
|
13528
13733
|
/**
|
|
13529
|
-
* Get
|
|
13530
|
-
* @param params Optional query params
|
|
13734
|
+
* Get assets available for trade and data consumption from Alpaca
|
|
13735
|
+
* @param params Optional query params
|
|
13736
|
+
* - status: 'active' | 'inactive' (default 'active')
|
|
13737
|
+
* - asset_class: 'us_equity' | 'us_option' | 'crypto' (default 'us_equity')
|
|
13738
|
+
* - shortable: if true (default), filters to assets with shortable=true and easy_to_borrow=true
|
|
13531
13739
|
* @returns Array of AlpacaAsset objects
|
|
13532
13740
|
* @see https://docs.alpaca.markets/reference/get-v2-assets-1
|
|
13533
13741
|
*/
|
|
13534
13742
|
async getAssets(params) {
|
|
13535
13743
|
// Endpoint: GET /v2/assets
|
|
13536
|
-
|
|
13744
|
+
const { status = 'active', asset_class = 'us_equity', shortable = true, } = {
|
|
13745
|
+
status: params?.status ?? 'active',
|
|
13746
|
+
asset_class: params?.asset_class ?? 'us_equity',
|
|
13747
|
+
shortable: params?.shortable ?? true,
|
|
13748
|
+
};
|
|
13749
|
+
const assets = await this.makeRequest('/assets', 'GET', { status, asset_class }, 'api');
|
|
13750
|
+
if (!shortable)
|
|
13751
|
+
return assets;
|
|
13752
|
+
return assets.filter((a) => a.shortable === true && a.easy_to_borrow === true);
|
|
13537
13753
|
}
|
|
13538
13754
|
/**
|
|
13539
13755
|
* Get a single asset by symbol or asset_id
|
|
@@ -14177,88 +14393,84 @@ class AlpacaMarketDataAPI extends EventEmitter {
|
|
|
14177
14393
|
}
|
|
14178
14394
|
}
|
|
14179
14395
|
// Export the singleton instance
|
|
14180
|
-
AlpacaMarketDataAPI.getInstance();
|
|
14396
|
+
const marketDataAPI = AlpacaMarketDataAPI.getInstance();
|
|
14397
|
+
|
|
14398
|
+
var alpacaMarketDataApi = /*#__PURE__*/Object.freeze({
|
|
14399
|
+
__proto__: null,
|
|
14400
|
+
AlpacaMarketDataAPI: AlpacaMarketDataAPI,
|
|
14401
|
+
marketDataAPI: marketDataAPI
|
|
14402
|
+
});
|
|
14181
14403
|
|
|
14182
14404
|
// Test file for context functionality
|
|
14183
|
-
|
|
14184
|
-
|
|
14185
|
-
//testCryptoMarketData();
|
|
14186
|
-
//testGetPortfolioDailyHistory();
|
|
14187
|
-
async function testWebSocketConnectAndDisconnect() {
|
|
14188
|
-
console.log('\n--- Testing WebSocket Connect and Disconnect ---');
|
|
14405
|
+
async function testGetAssetsShortableFilter() {
|
|
14406
|
+
console.log('\n--- Testing getAssets params and shortable filter ---');
|
|
14189
14407
|
const log = (message, options = { type: 'info' }) => {
|
|
14190
14408
|
log$1(message, { ...options, source: 'Test' });
|
|
14191
14409
|
};
|
|
14192
|
-
|
|
14193
|
-
|
|
14194
|
-
process.env.ALPACA_API_KEY = process.env.ALPACA_TRADING_API_KEY;
|
|
14195
|
-
}
|
|
14196
|
-
if (!process.env.ALPACA_SECRET_KEY && process.env.ALPACA_TRADING_SECRET_KEY) {
|
|
14197
|
-
process.env.ALPACA_SECRET_KEY = process.env.ALPACA_TRADING_SECRET_KEY;
|
|
14198
|
-
}
|
|
14199
|
-
if (!process.env.ALPACA_ACCOUNT_TYPE && process.env.ALPACA_TRADING_ACCOUNT_TYPE) {
|
|
14200
|
-
process.env.ALPACA_ACCOUNT_TYPE = process.env.ALPACA_TRADING_ACCOUNT_TYPE;
|
|
14201
|
-
}
|
|
14202
|
-
const apiKey = process.env.ALPACA_API_KEY;
|
|
14203
|
-
const secretKey = process.env.ALPACA_SECRET_KEY;
|
|
14204
|
-
if (!apiKey || !secretKey) {
|
|
14205
|
-
console.error('Missing Alpaca API credentials. Check .env ALPACA_TRADING_API_KEY/SECRET or ALPACA_API_KEY/SECRET.');
|
|
14410
|
+
if (!process.env.ALPACA_API_KEY || !process.env.ALPACA_SECRET_KEY) {
|
|
14411
|
+
console.log('Skipping getAssets test: Missing environment variables (ALPACA_API_KEY, ALPACA_SECRET_KEY)');
|
|
14206
14412
|
return;
|
|
14207
14413
|
}
|
|
14208
|
-
|
|
14209
|
-
|
|
14210
|
-
|
|
14211
|
-
|
|
14212
|
-
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
|
|
14217
|
-
const formatNY = (d) => d.toLocaleString('en-US', { timeZone: 'America/New_York' });
|
|
14218
|
-
const onBar = (msg) => {
|
|
14219
|
-
if (!symbols.includes(msg.S))
|
|
14220
|
-
return;
|
|
14221
|
-
barCounts[msg.S] += 1;
|
|
14222
|
-
if (!firstSeenAt[msg.S]) {
|
|
14223
|
-
firstSeenAt[msg.S] = formatNY(new Date(msg.t));
|
|
14414
|
+
try {
|
|
14415
|
+
const { marketDataAPI } = await Promise.resolve().then(function () { return alpacaMarketDataApi; });
|
|
14416
|
+
// 1) Default call: should filter to shortable && easy_to_borrow and default to active us_equity
|
|
14417
|
+
log('Calling getAssets() with defaults');
|
|
14418
|
+
const filtered = await marketDataAPI.getAssets();
|
|
14419
|
+
console.log(`Received ${filtered.length} filtered assets (default params)`);
|
|
14420
|
+
const allFilteredValid = filtered.every((a) => a.shortable === true && a.easy_to_borrow === true);
|
|
14421
|
+
if (!allFilteredValid) {
|
|
14422
|
+
console.error('✗ Default getAssets() included assets that are not shortable and easy_to_borrow');
|
|
14224
14423
|
}
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
|
|
14230
|
-
|
|
14231
|
-
|
|
14232
|
-
|
|
14233
|
-
|
|
14234
|
-
|
|
14235
|
-
|
|
14236
|
-
|
|
14237
|
-
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
|
|
14242
|
-
|
|
14243
|
-
|
|
14244
|
-
|
|
14245
|
-
|
|
14246
|
-
|
|
14247
|
-
|
|
14248
|
-
|
|
14249
|
-
|
|
14250
|
-
|
|
14251
|
-
|
|
14252
|
-
|
|
14253
|
-
|
|
14254
|
-
|
|
14255
|
-
|
|
14256
|
-
|
|
14257
|
-
|
|
14258
|
-
|
|
14259
|
-
|
|
14260
|
-
|
|
14261
|
-
}
|
|
14262
|
-
}
|
|
14263
|
-
|
|
14424
|
+
else {
|
|
14425
|
+
console.log('✓ Default getAssets() correctly filtered shortable and easy_to_borrow assets');
|
|
14426
|
+
}
|
|
14427
|
+
// 2) Unfiltered call: shortable=false
|
|
14428
|
+
log('Calling getAssets({ shortable: false })');
|
|
14429
|
+
const unfiltered = await marketDataAPI.getAssets({ shortable: false });
|
|
14430
|
+
console.log(`Received ${unfiltered.length} unfiltered assets`);
|
|
14431
|
+
if (unfiltered.length < filtered.length) {
|
|
14432
|
+
console.warn('Unfiltered list is smaller than filtered. This is unexpected but not fatal.');
|
|
14433
|
+
}
|
|
14434
|
+
else {
|
|
14435
|
+
console.log('✓ Unfiltered list length is >= filtered list length');
|
|
14436
|
+
}
|
|
14437
|
+
// 3) Specific constraints: inactive crypto, not asserting non-empty
|
|
14438
|
+
log("Calling getAssets({ status: 'inactive', asset_class: 'crypto', shortable: false })");
|
|
14439
|
+
const inactiveCrypto = await marketDataAPI.getAssets({ status: 'inactive', asset_class: 'crypto', shortable: false });
|
|
14440
|
+
console.log(`Received ${inactiveCrypto.length} inactive crypto assets`);
|
|
14441
|
+
if (inactiveCrypto.length > 0) {
|
|
14442
|
+
const valid = inactiveCrypto.every((a) => a.class === 'crypto' && a.status === 'inactive');
|
|
14443
|
+
if (!valid) {
|
|
14444
|
+
console.error('✗ Inactive crypto request returned assets with mismatched class or status');
|
|
14445
|
+
}
|
|
14446
|
+
else {
|
|
14447
|
+
console.log('✓ Inactive crypto request returned only crypto with inactive status');
|
|
14448
|
+
}
|
|
14449
|
+
}
|
|
14450
|
+
else {
|
|
14451
|
+
console.log('No inactive crypto assets returned; skipping class/status assertions.');
|
|
14452
|
+
}
|
|
14453
|
+
}
|
|
14454
|
+
catch (error) {
|
|
14455
|
+
console.error('✗ getAssets test failed:', error);
|
|
14456
|
+
if (error instanceof Error) {
|
|
14457
|
+
console.error('Error message:', error.message);
|
|
14458
|
+
console.error('Stack trace:', error.stack);
|
|
14459
|
+
}
|
|
14460
|
+
}
|
|
14461
|
+
}
|
|
14462
|
+
// testGetTradingDate();
|
|
14463
|
+
// testGetTradingStartAndEndDates();
|
|
14464
|
+
// testGetLastFullTradingDate();
|
|
14465
|
+
// testGetMarketOpenClose();
|
|
14466
|
+
// testGetNYTimeZone();
|
|
14467
|
+
// testGetNextMarketDay();
|
|
14468
|
+
// testCountTradingDays();
|
|
14469
|
+
// testGetPreviousMarketDay();
|
|
14470
|
+
// testOpenRouter();
|
|
14471
|
+
// testGetMarketStatus();
|
|
14472
|
+
// testCryptoMarketData();
|
|
14473
|
+
// testGetPortfolioDailyHistory();
|
|
14474
|
+
// testWebSocketConnectAndDisconnect();
|
|
14475
|
+
testGetAssetsShortableFilter();
|
|
14264
14476
|
//# sourceMappingURL=test.js.map
|