@discomedia/utils 1.0.39 → 1.0.40

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.mjs CHANGED
@@ -772,6 +772,46 @@ function getNYTimeZone(date) {
772
772
  const offset = getNYOffset(date || new Date());
773
773
  return offset === -4 ? '-04:00' : '-05:00';
774
774
  }
775
+ /**
776
+ * Returns the regular market open and close Date objects for a given trading day string in the
777
+ * America/New_York timezone (NYSE/NASDAQ calendar).
778
+ *
779
+ * This helper is convenient when you have a calendar date like '2025-10-03' and want the precise
780
+ * open and close Date values for that day. It internally:
781
+ * - Determines the NY offset for the day using `getNYTimeZone()`.
782
+ * - Anchors a noon-time Date on that day in NY time to avoid DST edge cases.
783
+ * - Verifies the day is a market day via `isMarketDay()`.
784
+ * - Fetches the open/close times via `getMarketOpenClose()`.
785
+ *
786
+ * Throws if the provided day is not a market day or if open/close times are unavailable.
787
+ *
788
+ * See also:
789
+ * - `getNYTimeZone(date?: Date)`
790
+ * - `isMarketDay(date: Date)`
791
+ * - `getMarketOpenClose(options?: { date?: Date })`
792
+ *
793
+ * @param dateStr - Trading day string in 'YYYY-MM-DD' format (Eastern Time date)
794
+ * @returns An object containing `{ open: Date; close: Date }`
795
+ * @example
796
+ * ```ts
797
+ * const { open, close } = disco.time.getOpenCloseForTradingDay('2025-10-03');
798
+ * ```
799
+ */
800
+ function getOpenCloseForTradingDay(dateStr) {
801
+ // Build a UTC midnight anchor for the date, then derive the NY offset for that day.
802
+ const utcAnchor = new Date(`${dateStr}T00:00:00Z`);
803
+ const nyOffset = getNYTimeZone(utcAnchor); // '-04:00' | '-05:00'
804
+ // Create a NY-local noon date to avoid DST midnight transitions.
805
+ const nyNoon = new Date(`${dateStr}T12:00:00${nyOffset}`);
806
+ if (!isMarketDay(nyNoon)) {
807
+ throw new Error(`Not a market day in ET: ${dateStr}`);
808
+ }
809
+ const { open, close } = getMarketOpenClose({ date: nyNoon });
810
+ if (!open || !close) {
811
+ throw new Error(`No market times available for ${dateStr}`);
812
+ }
813
+ return { open, close };
814
+ }
775
815
  /**
776
816
  * Converts any date to the market time zone (America/New_York, Eastern Time).
777
817
  * Returns a new Date object representing the same moment in time but adjusted to NY/Eastern timezone.
@@ -2409,7 +2449,7 @@ const safeJSON = (text) => {
2409
2449
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2410
2450
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2411
2451
 
2412
- const VERSION = '6.1.0'; // x-release-please-version
2452
+ const VERSION = '6.2.0'; // x-release-please-version
2413
2453
 
2414
2454
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2415
2455
  const isRunningInBrowser = () => {
@@ -3810,6 +3850,15 @@ function getName(value) {
3810
3850
  .pop() || undefined);
3811
3851
  }
3812
3852
  const isAsyncIterable = (value) => value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function';
3853
+ /**
3854
+ * Returns a multipart/form-data request if any part of the given request body contains a File / Blob value.
3855
+ * Otherwise returns the request as is.
3856
+ */
3857
+ const maybeMultipartFormRequestOptions = async (opts, fetch) => {
3858
+ if (!hasUploadableValue(opts.body))
3859
+ return opts;
3860
+ return { ...opts, body: await createForm(opts.body, fetch) };
3861
+ };
3813
3862
  const multipartFormRequestOptions = async (opts, fetch) => {
3814
3863
  return { ...opts, body: await createForm(opts.body, fetch) };
3815
3864
  };
@@ -3855,6 +3904,22 @@ const createForm = async (body, fetch) => {
3855
3904
  // We check for Blob not File because Bun.File doesn't inherit from File,
3856
3905
  // but they both inherit from Blob and have a `name` property at runtime.
3857
3906
  const isNamedBlob = (value) => value instanceof Blob && 'name' in value;
3907
+ const isUploadable = (value) => typeof value === 'object' &&
3908
+ value !== null &&
3909
+ (value instanceof Response || isAsyncIterable(value) || isNamedBlob(value));
3910
+ const hasUploadableValue = (value) => {
3911
+ if (isUploadable(value))
3912
+ return true;
3913
+ if (Array.isArray(value))
3914
+ return value.some(hasUploadableValue);
3915
+ if (value && typeof value === 'object') {
3916
+ for (const k in value) {
3917
+ if (hasUploadableValue(value[k]))
3918
+ return true;
3919
+ }
3920
+ }
3921
+ return false;
3922
+ };
3858
3923
  const addFormValue = async (form, key, value) => {
3859
3924
  if (value === undefined)
3860
3925
  return;
@@ -3909,7 +3974,7 @@ const isResponseLike = (value) => value != null &&
3909
3974
  typeof value.blob === 'function';
3910
3975
  /**
3911
3976
  * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
3912
- * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s
3977
+ * @param value the raw content of the file. Can be an {@link Uploadable}, BlobLikePart, or AsyncIterable of BlobLikeParts
3913
3978
  * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
3914
3979
  * @param {Object=} options additional properties
3915
3980
  * @param {string=} options.type the MIME type of the content
@@ -5760,7 +5825,7 @@ class Assistants extends APIResource {
5760
5825
  }
5761
5826
 
5762
5827
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5763
- class Sessions extends APIResource {
5828
+ let Sessions$1 = class Sessions extends APIResource {
5764
5829
  /**
5765
5830
  * Create an ephemeral API token for use in client-side applications with the
5766
5831
  * Realtime API. Can be configured with the same session parameters as the
@@ -5783,7 +5848,7 @@ class Sessions extends APIResource {
5783
5848
  headers: buildHeaders([{ 'OpenAI-Beta': 'assistants=v2' }, options?.headers]),
5784
5849
  });
5785
5850
  }
5786
- }
5851
+ };
5787
5852
 
5788
5853
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5789
5854
  class TranscriptionSessions extends APIResource {
@@ -5818,13 +5883,144 @@ class TranscriptionSessions extends APIResource {
5818
5883
  let Realtime$1 = class Realtime extends APIResource {
5819
5884
  constructor() {
5820
5885
  super(...arguments);
5821
- this.sessions = new Sessions(this._client);
5886
+ this.sessions = new Sessions$1(this._client);
5822
5887
  this.transcriptionSessions = new TranscriptionSessions(this._client);
5823
5888
  }
5824
5889
  };
5825
- Realtime$1.Sessions = Sessions;
5890
+ Realtime$1.Sessions = Sessions$1;
5826
5891
  Realtime$1.TranscriptionSessions = TranscriptionSessions;
5827
5892
 
5893
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5894
+ class Sessions extends APIResource {
5895
+ /**
5896
+ * Create a ChatKit session
5897
+ *
5898
+ * @example
5899
+ * ```ts
5900
+ * const chatSession =
5901
+ * await client.beta.chatkit.sessions.create({
5902
+ * user: 'x',
5903
+ * workflow: { id: 'id' },
5904
+ * });
5905
+ * ```
5906
+ */
5907
+ create(body, options) {
5908
+ return this._client.post('/chatkit/sessions', {
5909
+ body,
5910
+ ...options,
5911
+ headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
5912
+ });
5913
+ }
5914
+ /**
5915
+ * Cancel a ChatKit session
5916
+ *
5917
+ * @example
5918
+ * ```ts
5919
+ * const chatSession =
5920
+ * await client.beta.chatkit.sessions.cancel('cksess_123');
5921
+ * ```
5922
+ */
5923
+ cancel(sessionID, options) {
5924
+ return this._client.post(path `/chatkit/sessions/${sessionID}/cancel`, {
5925
+ ...options,
5926
+ headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
5927
+ });
5928
+ }
5929
+ }
5930
+
5931
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5932
+ let Threads$1 = class Threads extends APIResource {
5933
+ /**
5934
+ * Retrieve a ChatKit thread
5935
+ *
5936
+ * @example
5937
+ * ```ts
5938
+ * const chatkitThread =
5939
+ * await client.beta.chatkit.threads.retrieve('cthr_123');
5940
+ * ```
5941
+ */
5942
+ retrieve(threadID, options) {
5943
+ return this._client.get(path `/chatkit/threads/${threadID}`, {
5944
+ ...options,
5945
+ headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
5946
+ });
5947
+ }
5948
+ /**
5949
+ * List ChatKit threads
5950
+ *
5951
+ * @example
5952
+ * ```ts
5953
+ * // Automatically fetches more pages as needed.
5954
+ * for await (const chatkitThread of client.beta.chatkit.threads.list()) {
5955
+ * // ...
5956
+ * }
5957
+ * ```
5958
+ */
5959
+ list(query = {}, options) {
5960
+ return this._client.getAPIList('/chatkit/threads', (ConversationCursorPage), {
5961
+ query,
5962
+ ...options,
5963
+ headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
5964
+ });
5965
+ }
5966
+ /**
5967
+ * Delete a ChatKit thread
5968
+ *
5969
+ * @example
5970
+ * ```ts
5971
+ * const thread = await client.beta.chatkit.threads.delete(
5972
+ * 'cthr_123',
5973
+ * );
5974
+ * ```
5975
+ */
5976
+ delete(threadID, options) {
5977
+ return this._client.delete(path `/chatkit/threads/${threadID}`, {
5978
+ ...options,
5979
+ headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]),
5980
+ });
5981
+ }
5982
+ /**
5983
+ * List ChatKit thread items
5984
+ *
5985
+ * @example
5986
+ * ```ts
5987
+ * // Automatically fetches more pages as needed.
5988
+ * for await (const thread of client.beta.chatkit.threads.listItems(
5989
+ * 'cthr_123',
5990
+ * )) {
5991
+ * // ...
5992
+ * }
5993
+ * ```
5994
+ */
5995
+ listItems(threadID, query = {}, options) {
5996
+ return this._client.getAPIList(path `/chatkit/threads/${threadID}/items`, (ConversationCursorPage), { query, ...options, headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]) });
5997
+ }
5998
+ };
5999
+
6000
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6001
+ class ChatKit extends APIResource {
6002
+ constructor() {
6003
+ super(...arguments);
6004
+ this.sessions = new Sessions(this._client);
6005
+ this.threads = new Threads$1(this._client);
6006
+ }
6007
+ /**
6008
+ * Upload a ChatKit file
6009
+ *
6010
+ * @example
6011
+ * ```ts
6012
+ * const response = await client.beta.chatkit.uploadFile({
6013
+ * file: fs.createReadStream('path/to/file'),
6014
+ * });
6015
+ * ```
6016
+ */
6017
+ uploadFile(body, options) {
6018
+ return this._client.post('/chatkit/files', maybeMultipartFormRequestOptions({ body, ...options, headers: buildHeaders([{ 'OpenAI-Beta': 'chatkit_beta=v1' }, options?.headers]) }, this._client));
6019
+ }
6020
+ }
6021
+ ChatKit.Sessions = Sessions;
6022
+ ChatKit.Threads = Threads$1;
6023
+
5828
6024
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5829
6025
  /**
5830
6026
  * @deprecated The Assistants API is deprecated in favor of the Responses API
@@ -6762,11 +6958,13 @@ class Beta extends APIResource {
6762
6958
  constructor() {
6763
6959
  super(...arguments);
6764
6960
  this.realtime = new Realtime$1(this._client);
6961
+ this.chatkit = new ChatKit(this._client);
6765
6962
  this.assistants = new Assistants(this._client);
6766
6963
  this.threads = new Threads(this._client);
6767
6964
  }
6768
6965
  }
6769
6966
  Beta.Realtime = Realtime$1;
6967
+ Beta.ChatKit = ChatKit;
6770
6968
  Beta.Assistants = Assistants;
6771
6969
  Beta.Threads = Threads;
6772
6970
 
@@ -8519,6 +8717,51 @@ class VectorStores extends APIResource {
8519
8717
  VectorStores.Files = Files;
8520
8718
  VectorStores.FileBatches = FileBatches;
8521
8719
 
8720
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
8721
+ class Videos extends APIResource {
8722
+ /**
8723
+ * Create a video
8724
+ */
8725
+ create(body, options) {
8726
+ return this._client.post('/videos', maybeMultipartFormRequestOptions({ body, ...options }, this._client));
8727
+ }
8728
+ /**
8729
+ * Retrieve a video
8730
+ */
8731
+ retrieve(videoID, options) {
8732
+ return this._client.get(path `/videos/${videoID}`, options);
8733
+ }
8734
+ /**
8735
+ * List videos
8736
+ */
8737
+ list(query = {}, options) {
8738
+ return this._client.getAPIList('/videos', (ConversationCursorPage), { query, ...options });
8739
+ }
8740
+ /**
8741
+ * Delete a video
8742
+ */
8743
+ delete(videoID, options) {
8744
+ return this._client.delete(path `/videos/${videoID}`, options);
8745
+ }
8746
+ /**
8747
+ * Download video content
8748
+ */
8749
+ downloadContent(videoID, query = {}, options) {
8750
+ return this._client.get(path `/videos/${videoID}/content`, {
8751
+ query,
8752
+ ...options,
8753
+ headers: buildHeaders([{ Accept: 'application/binary' }, options?.headers]),
8754
+ __binaryResponse: true,
8755
+ });
8756
+ }
8757
+ /**
8758
+ * Create a video remix
8759
+ */
8760
+ remix(videoID, body, options) {
8761
+ return this._client.post(path `/videos/${videoID}/remix`, maybeMultipartFormRequestOptions({ body, ...options }, this._client));
8762
+ }
8763
+ }
8764
+
8522
8765
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
8523
8766
  var _Webhooks_instances, _Webhooks_validateSecret, _Webhooks_getRequiredHeader;
8524
8767
  class Webhooks extends APIResource {
@@ -8657,6 +8900,7 @@ class OpenAI {
8657
8900
  this.conversations = new Conversations(this);
8658
8901
  this.evals = new Evals(this);
8659
8902
  this.containers = new Containers(this);
8903
+ this.videos = new Videos(this);
8660
8904
  if (apiKey === undefined) {
8661
8905
  throw new OpenAIError('Missing credentials. Please pass an `apiKey`, or set the `OPENAI_API_KEY` environment variable.');
8662
8906
  }
@@ -9127,6 +9371,7 @@ OpenAI.Realtime = Realtime;
9127
9371
  OpenAI.Conversations = Conversations;
9128
9372
  OpenAI.Evals = Evals;
9129
9373
  OpenAI.Containers = Containers;
9374
+ OpenAI.Videos = Videos;
9130
9375
 
9131
9376
  // llm-openai-config.ts
9132
9377
  const DEFAULT_MODEL = 'gpt-4.1-mini';
@@ -19119,6 +19364,7 @@ const disco = {
19119
19364
  convertDateToMarketTimeZone: convertDateToMarketTimeZone,
19120
19365
  getStartAndEndDates: getStartAndEndDates,
19121
19366
  getMarketOpenClose: getMarketOpenClose,
19367
+ getOpenCloseForTradingDay: getOpenCloseForTradingDay,
19122
19368
  getLastFullTradingDate: getLastFullTradingDate,
19123
19369
  getNextMarketDay: getNextMarketDay,
19124
19370
  getPreviousMarketDay: getPreviousMarketDay,