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