@ganaka/sdk 1.0.1 → 1.0.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/index.mjs CHANGED
@@ -4400,8 +4400,8 @@ const p = object({
4400
4400
  close: number$1()
4401
4401
  })
4402
4402
  ),
4403
- start_time: string(),
4404
- end_time: string(),
4403
+ start_time: string().nullable(),
4404
+ end_time: string().nullable(),
4405
4405
  interval_in_minutes: number$1()
4406
4406
  })
4407
4407
  })
@@ -7922,8 +7922,7 @@ const fetchCandles = ({
7922
7922
  headers["X-Run-Id"] = runId;
7923
7923
  }
7924
7924
  if (currentTimestamp) {
7925
- const timestampStr = dayjs.tz(currentTimestamp, currentTimezone).format("YYYY-MM-DDTHH:mm:ss");
7926
- headers["X-Current-Timestamp"] = timestampStr;
7925
+ headers["X-Current-Timestamp"] = currentTimestamp;
7927
7926
  }
7928
7927
  if (currentTimezone) {
7929
7928
  headers["X-Current-Timezone"] = currentTimezone;
@@ -7967,8 +7966,7 @@ const fetchQuote = ({
7967
7966
  headers["X-Run-Id"] = runId;
7968
7967
  }
7969
7968
  if (currentTimestamp) {
7970
- const timestampStr = dayjs.tz(currentTimestamp, currentTimezone).format("YYYY-MM-DDTHH:mm:ss");
7971
- headers["X-Current-Timestamp"] = timestampStr;
7969
+ headers["X-Current-Timestamp"] = currentTimestamp;
7972
7970
  }
7973
7971
  if (currentTimezone) {
7974
7972
  headers["X-Current-Timezone"] = currentTimezone;
@@ -8000,10 +7998,9 @@ const fetchQuoteTimeline = ({
8000
7998
  throw new Error("Developer token not found. Please set DEVELOPER_KEY environment variable.");
8001
7999
  }
8002
8000
  try {
8003
- const dateStr = dayjs.tz(date2, currentTimezone).format("YYYY-MM-DD");
8004
8001
  const validatedParams = _e.getGrowwQuoteTimeline.query.parse({
8005
8002
  symbol,
8006
- date: dateStr
8003
+ date: date2
8007
8004
  });
8008
8005
  const headers = {
8009
8006
  Authorization: `Bearer ${developerToken}`
@@ -8012,8 +8009,7 @@ const fetchQuoteTimeline = ({
8012
8009
  headers["X-Run-Id"] = runId;
8013
8010
  }
8014
8011
  if (currentTimestamp) {
8015
- const timestampStr = dayjs.tz(currentTimestamp, currentTimezone).format("YYYY-MM-DDTHH:mm:ss");
8016
- headers["X-Current-Timestamp"] = timestampStr;
8012
+ headers["X-Current-Timestamp"] = currentTimestamp;
8017
8013
  }
8018
8014
  if (currentTimezone) {
8019
8015
  headers["X-Current-Timezone"] = currentTimezone;
@@ -8057,8 +8053,7 @@ const fetchShortlist = ({
8057
8053
  headers["X-Run-Id"] = runId;
8058
8054
  }
8059
8055
  if (currentTimestamp) {
8060
- const timestampStr = dayjs.tz(currentTimestamp, currentTimezone).format("YYYY-MM-DDTHH:mm:ss");
8061
- headers["X-Current-Timestamp"] = timestampStr;
8056
+ headers["X-Current-Timestamp"] = currentTimestamp;
8062
8057
  }
8063
8058
  if (currentTimezone) {
8064
8059
  headers["X-Current-Timezone"] = currentTimezone;
@@ -8152,7 +8147,7 @@ async function retryWithBackoff(fn, maxRetries = 3, baseDelayMs = 1e3) {
8152
8147
  throw lastError;
8153
8148
  }
8154
8149
  const placeOrder = ({ runId, apiClient }) => async (data) => {
8155
- console.log(data);
8150
+ logger.debug(`data: ${JSON.stringify(data)}`);
8156
8151
  if (runId) {
8157
8152
  try {
8158
8153
  await retryWithBackoff(
@@ -8268,73 +8263,144 @@ class ApiClient {
8268
8263
  }
8269
8264
  }
8270
8265
  }
8271
- function getNextIntervalBoundary(timestamp, intervalMinutes) {
8272
- const date2 = dayjs(timestamp);
8273
- const currentMinute = date2.minute();
8274
- const currentSecond = date2.second();
8275
- const currentMillisecond = date2.millisecond();
8276
- const minutesIntoHour = currentMinute % intervalMinutes;
8277
- if (minutesIntoHour === 0 && currentSecond === 0 && currentMillisecond === 0) {
8278
- return date2.add(intervalMinutes, "minute").toDate();
8279
- }
8280
- const minutesToAdd = intervalMinutes - minutesIntoHour;
8281
- return date2.add(minutesToAdd, "minute").second(0).millisecond(0).toDate();
8282
- }
8266
+ var calendar$1 = { exports: {} };
8267
+ (function(module, exports$1) {
8268
+ !function(e, t2) {
8269
+ module.exports = t2();
8270
+ }(commonjsGlobal, function() {
8271
+ return function(e, t2, a) {
8272
+ var n2 = "h:mm A", d2 = { lastDay: "[Yesterday at] " + n2, sameDay: "[Today at] " + n2, nextDay: "[Tomorrow at] " + n2, nextWeek: "dddd [at] " + n2, lastWeek: "[Last] dddd [at] " + n2, sameElse: "MM/DD/YYYY" };
8273
+ t2.prototype.calendar = function(e2, t3) {
8274
+ var n3 = t3 || this.$locale().calendar || d2, o2 = a(e2 || void 0).startOf("d"), s = this.diff(o2, "d", true), i2 = "sameElse", f2 = s < -6 ? i2 : s < -1 ? "lastWeek" : s < 0 ? "lastDay" : s < 1 ? "sameDay" : s < 2 ? "nextDay" : s < 7 ? "nextWeek" : i2, l2 = n3[f2] || d2[f2];
8275
+ return "function" == typeof l2 ? l2.call(this, a()) : this.format(l2);
8276
+ };
8277
+ };
8278
+ });
8279
+ })(calendar$1);
8280
+ var calendarExports = calendar$1.exports;
8281
+ const calendar = /* @__PURE__ */ getDefaultExportFromCjs(calendarExports);
8282
+ var relativeTime$1 = { exports: {} };
8283
+ (function(module, exports$1) {
8284
+ !function(r2, e) {
8285
+ module.exports = e();
8286
+ }(commonjsGlobal, function() {
8287
+ return function(r2, e, t2) {
8288
+ r2 = r2 || {};
8289
+ var n2 = e.prototype, o2 = { future: "in %s", past: "%s ago", s: "a few seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" };
8290
+ function i2(r3, e2, t3, o3) {
8291
+ return n2.fromToBase(r3, e2, t3, o3);
8292
+ }
8293
+ t2.en.relativeTime = o2, n2.fromToBase = function(e2, n3, i3, d3, u) {
8294
+ for (var f2, a, s, l2 = i3.$locale().relativeTime || o2, h = r2.thresholds || [{ l: "s", r: 44, d: "second" }, { l: "m", r: 89 }, { l: "mm", r: 44, d: "minute" }, { l: "h", r: 89 }, { l: "hh", r: 21, d: "hour" }, { l: "d", r: 35 }, { l: "dd", r: 25, d: "day" }, { l: "M", r: 45 }, { l: "MM", r: 10, d: "month" }, { l: "y", r: 17 }, { l: "yy", d: "year" }], m2 = h.length, c2 = 0; c2 < m2; c2 += 1) {
8295
+ var y2 = h[c2];
8296
+ y2.d && (f2 = d3 ? t2(e2).diff(i3, y2.d, true) : i3.diff(e2, y2.d, true));
8297
+ var p2 = (r2.rounding || Math.round)(Math.abs(f2));
8298
+ if (s = f2 > 0, p2 <= y2.r || !y2.r) {
8299
+ p2 <= 1 && c2 > 0 && (y2 = h[c2 - 1]);
8300
+ var v2 = l2[y2.l];
8301
+ u && (p2 = u("" + p2)), a = "string" == typeof v2 ? v2.replace("%d", p2) : v2(p2, n3, y2.l, s);
8302
+ break;
8303
+ }
8304
+ }
8305
+ if (n3) return a;
8306
+ var M2 = s ? l2.future : l2.past;
8307
+ return "function" == typeof M2 ? M2(a) : M2.replace("%s", a);
8308
+ }, n2.to = function(r3, e2) {
8309
+ return i2(r3, e2, this, true);
8310
+ }, n2.from = function(r3, e2) {
8311
+ return i2(r3, e2, this);
8312
+ };
8313
+ var d2 = function(r3) {
8314
+ return r3.$u ? t2.utc() : t2();
8315
+ };
8316
+ n2.toNow = function(r3) {
8317
+ return this.to(d2(this), r3);
8318
+ }, n2.fromNow = function(r3) {
8319
+ return this.from(d2(this), r3);
8320
+ };
8321
+ };
8322
+ });
8323
+ })(relativeTime$1);
8324
+ var relativeTimeExports = relativeTime$1.exports;
8325
+ const relativeTime = /* @__PURE__ */ getDefaultExportFromCjs(relativeTimeExports);
8326
+ dayjs.extend(utc);
8327
+ dayjs.extend(timezone);
8328
+ dayjs.extend(calendar);
8329
+ dayjs.extend(relativeTime);
8283
8330
  function sleep(ms) {
8284
8331
  return new Promise((resolve) => setTimeout(resolve, ms));
8285
8332
  }
8286
8333
  async function runMinuteLoop({
8287
- startTime,
8288
- endTime,
8289
- callback,
8290
- intervalMinutes
8334
+ startTimeDayJS,
8335
+ endTimeDayJS,
8336
+ intervalMinutes,
8337
+ callback
8291
8338
  }) {
8292
- const now = /* @__PURE__ */ new Date();
8293
- const isSimulationMode = now < startTime || now > endTime;
8339
+ let currentISTDayJS = dayjs.utc().tz("Asia/Kolkata");
8340
+ logger.debug(`currentIST: ${currentISTDayJS.format("YYYY-MM-DDTHH:mm:ss")}`);
8341
+ logger.debug(`startTime: ${startTimeDayJS.format("YYYY-MM-DDTHH:mm:ss")}`);
8342
+ logger.debug(`endTime: ${endTimeDayJS.format("YYYY-MM-DDTHH:mm:ss")}`);
8343
+ const isSimulationMode = currentISTDayJS.isAfter(endTimeDayJS);
8294
8344
  if (isSimulationMode) {
8295
- console.log("Current time is outside the specified range, simulating loop");
8345
+ logger.info("Current time is after endTime, simulating loop");
8346
+ }
8347
+ if (currentISTDayJS.isBefore(startTimeDayJS)) {
8348
+ const delayUntilStart = startTimeDayJS.diff(currentISTDayJS, "millisecond");
8349
+ logger.info(
8350
+ `Starting loop ${startTimeDayJS.from(currentISTDayJS)} at ${startTimeDayJS.format(
8351
+ "YYYY-MM-DD HH:mm"
8352
+ )}`
8353
+ );
8354
+ await sleep(delayUntilStart);
8355
+ currentISTDayJS = currentISTDayJS.add(delayUntilStart, "millisecond");
8356
+ }
8357
+ if (currentISTDayJS.isAfter(startTimeDayJS) && currentISTDayJS.isBefore(endTimeDayJS)) {
8358
+ startTimeDayJS = currentISTDayJS;
8296
8359
  }
8297
- const startDate = dayjs(startTime);
8298
- const startMinute = startDate.minute();
8360
+ const startMinute = startTimeDayJS.minute();
8299
8361
  const minutesToFirstBoundary = intervalMinutes - startMinute % intervalMinutes;
8300
- const isOnBoundary = startMinute % intervalMinutes === 0 && startDate.second() === 0 && startDate.millisecond() === 0;
8301
- let nextBoundary;
8362
+ const isOnBoundary = startMinute % intervalMinutes === 0 && startTimeDayJS.second() === 0 && startTimeDayJS.millisecond() === 0;
8363
+ let nextBoundaryDayJS;
8302
8364
  if (isOnBoundary) {
8303
- nextBoundary = startTime;
8365
+ nextBoundaryDayJS = startTimeDayJS;
8304
8366
  } else {
8305
- nextBoundary = startDate.add(minutesToFirstBoundary, "minute").second(0).millisecond(0).toDate();
8367
+ nextBoundaryDayJS = startTimeDayJS.add(minutesToFirstBoundary, "minute").second(0).millisecond(0);
8306
8368
  }
8369
+ logger.debug(`nextBoundary: ${nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss")}`);
8307
8370
  if (isSimulationMode) {
8308
- while (nextBoundary <= endTime) {
8371
+ while (nextBoundaryDayJS.isBefore(endTimeDayJS) || nextBoundaryDayJS.isSame(endTimeDayJS)) {
8309
8372
  try {
8310
- await callback(nextBoundary);
8373
+ await callback(nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss"));
8311
8374
  } catch (error) {
8312
8375
  console.error(
8313
- `Error executing callback at ${nextBoundary.toISOString()}:`,
8376
+ `Error executing callback at ${nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss")}:`,
8314
8377
  error
8315
8378
  );
8316
8379
  }
8317
- nextBoundary = dayjs(nextBoundary).add(intervalMinutes, "minute").toDate();
8380
+ nextBoundaryDayJS = nextBoundaryDayJS.add(intervalMinutes, "minute");
8318
8381
  }
8319
8382
  return;
8320
8383
  }
8321
- if (startTime < now && nextBoundary < now) {
8322
- nextBoundary = getNextIntervalBoundary(now, intervalMinutes);
8323
- }
8324
- while (nextBoundary <= endTime) {
8325
- const delay = nextBoundary.getTime() - Date.now();
8384
+ while (nextBoundaryDayJS.isBefore(endTimeDayJS) || nextBoundaryDayJS.isSame(endTimeDayJS)) {
8385
+ const delay = nextBoundaryDayJS.diff(currentISTDayJS, "millisecond");
8326
8386
  if (delay > 0) {
8387
+ logger.info(
8388
+ `Waiting for ${nextBoundaryDayJS.from(
8389
+ currentISTDayJS,
8390
+ true
8391
+ )} to reach next execution time: ${nextBoundaryDayJS.format("YYYY-MM-DD HH:mm:ss")}`
8392
+ );
8327
8393
  await sleep(delay);
8328
8394
  }
8329
8395
  try {
8330
- await callback(nextBoundary);
8396
+ await callback(nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss"));
8331
8397
  } catch (error) {
8332
8398
  console.error(
8333
- `Error executing callback at ${nextBoundary.toISOString()}:`,
8399
+ `Error executing callback at ${nextBoundaryDayJS.format("YYYY-MM-DDTHH:mm:ss")}:`,
8334
8400
  error
8335
8401
  );
8336
8402
  }
8337
- nextBoundary = dayjs(nextBoundary).add(intervalMinutes, "minute").toDate();
8403
+ nextBoundaryDayJS = nextBoundaryDayJS.add(intervalMinutes, "minute");
8338
8404
  }
8339
8405
  }
8340
8406
  dotenv.config();
@@ -8355,10 +8421,15 @@ async function ganaka({
8355
8421
  );
8356
8422
  }
8357
8423
  const apiClient = new ApiClient({ developerToken, apiDomain });
8424
+ const startTimeDayJS = dayjs.tz(startTime, "Asia/Kolkata");
8425
+ const endTimeDayJS = dayjs.tz(endTime, "Asia/Kolkata");
8426
+ if (startTimeDayJS.isAfter(endTimeDayJS)) {
8427
+ throw new Error("Start time cannot be after end time");
8428
+ }
8358
8429
  let runId = null;
8359
8430
  const createRunBody = {
8360
- start_datetime: dayjs.tz(startTime, "Asia/Kolkata").format("YYYY-MM-DDTHH:mm:ss"),
8361
- end_datetime: dayjs.tz(endTime, "Asia/Kolkata").format("YYYY-MM-DDTHH:mm:ss"),
8431
+ start_datetime: startTime,
8432
+ end_datetime: endTime,
8362
8433
  timezone: "Asia/Kolkata"
8363
8434
  };
8364
8435
  try {
@@ -8382,8 +8453,8 @@ async function ganaka({
8382
8453
  }
8383
8454
  try {
8384
8455
  await runMinuteLoop({
8385
- startTime,
8386
- endTime,
8456
+ startTimeDayJS,
8457
+ endTimeDayJS,
8387
8458
  intervalMinutes,
8388
8459
  callback: async (currentTimestamp) => {
8389
8460
  await fn({