@ganaka/sdk 1.9.0 → 1.10.1
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.d.ts +46 -1
- package/dist/index.js +225 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +225 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -66,6 +66,16 @@ declare const createRun: {
|
|
|
66
66
|
}, z.core.$strip>;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
+
declare const deleteGrowwCredentials: {
|
|
70
|
+
response: z.ZodObject<{
|
|
71
|
+
statusCode: z.ZodNumber;
|
|
72
|
+
message: z.ZodString;
|
|
73
|
+
data: z.ZodObject<{
|
|
74
|
+
success: z.ZodBoolean;
|
|
75
|
+
}, z.core.$strip>;
|
|
76
|
+
}, z.core.$strip>;
|
|
77
|
+
};
|
|
78
|
+
|
|
69
79
|
declare const deleteRun: {
|
|
70
80
|
params: z.ZodObject<{
|
|
71
81
|
runId: z.ZodUUID;
|
|
@@ -452,6 +462,18 @@ declare const getDailyUniqueCompanies: {
|
|
|
452
462
|
}, z.core.$strip>;
|
|
453
463
|
};
|
|
454
464
|
|
|
465
|
+
declare const getGrowwCredentials: {
|
|
466
|
+
response: z.ZodObject<{
|
|
467
|
+
statusCode: z.ZodNumber;
|
|
468
|
+
message: z.ZodString;
|
|
469
|
+
data: z.ZodObject<{
|
|
470
|
+
hasGrowwApiKey: z.ZodBoolean;
|
|
471
|
+
hasGrowwApiSecret: z.ZodBoolean;
|
|
472
|
+
growwApiKeyMasked: z.ZodNullable<z.ZodString>;
|
|
473
|
+
}, z.core.$strip>;
|
|
474
|
+
}, z.core.$strip>;
|
|
475
|
+
};
|
|
476
|
+
|
|
455
477
|
declare const getGrowwHistoricalCandles: {
|
|
456
478
|
query: z.ZodObject<{
|
|
457
479
|
symbol: z.ZodString;
|
|
@@ -1301,6 +1323,20 @@ declare const signIn: {
|
|
|
1301
1323
|
}, z.core.$strip>;
|
|
1302
1324
|
};
|
|
1303
1325
|
|
|
1326
|
+
declare const updateGrowwCredentials: {
|
|
1327
|
+
body: z.ZodObject<{
|
|
1328
|
+
growwApiKey: z.ZodString;
|
|
1329
|
+
growwApiSecret: z.ZodString;
|
|
1330
|
+
}, z.core.$strip>;
|
|
1331
|
+
response: z.ZodObject<{
|
|
1332
|
+
statusCode: z.ZodNumber;
|
|
1333
|
+
message: z.ZodString;
|
|
1334
|
+
data: z.ZodObject<{
|
|
1335
|
+
success: z.ZodBoolean;
|
|
1336
|
+
}, z.core.$strip>;
|
|
1337
|
+
}, z.core.$strip>;
|
|
1338
|
+
};
|
|
1339
|
+
|
|
1304
1340
|
declare const updateRun: {
|
|
1305
1341
|
params: z.ZodObject<{
|
|
1306
1342
|
runId: z.ZodUUID;
|
|
@@ -1381,7 +1417,16 @@ declare namespace v1_dashboard_schemas {
|
|
|
1381
1417
|
v1_dashboard_auth_schemas,
|
|
1382
1418
|
v1_dashboard_quote_timeline_schemas,
|
|
1383
1419
|
v1_dashboard_runs_schemas,
|
|
1384
|
-
v1_dashboard_shortlists_schemas
|
|
1420
|
+
v1_dashboard_shortlists_schemas,
|
|
1421
|
+
v1_dashboard_settings_schemas
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
declare namespace v1_dashboard_settings_schemas {
|
|
1426
|
+
export {
|
|
1427
|
+
getGrowwCredentials,
|
|
1428
|
+
updateGrowwCredentials,
|
|
1429
|
+
deleteGrowwCredentials
|
|
1385
1430
|
}
|
|
1386
1431
|
}
|
|
1387
1432
|
|
package/dist/index.js
CHANGED
|
@@ -4321,7 +4321,7 @@ const y = object({
|
|
|
4321
4321
|
end_time: string(),
|
|
4322
4322
|
interval_in_minutes: number$1()
|
|
4323
4323
|
})
|
|
4324
|
-
}),
|
|
4324
|
+
}), P = {
|
|
4325
4325
|
query: object({
|
|
4326
4326
|
symbol: string(),
|
|
4327
4327
|
interval: _enum(b),
|
|
@@ -4332,7 +4332,7 @@ const y = object({
|
|
|
4332
4332
|
response: t.extend({
|
|
4333
4333
|
data: y
|
|
4334
4334
|
})
|
|
4335
|
-
},
|
|
4335
|
+
}, O = {
|
|
4336
4336
|
query: object({
|
|
4337
4337
|
symbol: string(),
|
|
4338
4338
|
exchange: _enum(["NSE", "BSE"]).optional(),
|
|
@@ -4343,11 +4343,11 @@ const y = object({
|
|
|
4343
4343
|
response: t.extend({
|
|
4344
4344
|
data: r.nullable()
|
|
4345
4345
|
})
|
|
4346
|
-
},
|
|
4346
|
+
}, q = {
|
|
4347
4347
|
response: t.extend({
|
|
4348
4348
|
data: string()
|
|
4349
4349
|
})
|
|
4350
|
-
},
|
|
4350
|
+
}, z = {
|
|
4351
4351
|
query: object({
|
|
4352
4352
|
symbol: string(),
|
|
4353
4353
|
end_datetime: o,
|
|
@@ -4391,7 +4391,7 @@ const y = object({
|
|
|
4391
4391
|
)
|
|
4392
4392
|
})
|
|
4393
4393
|
})
|
|
4394
|
-
},
|
|
4394
|
+
}, M = {
|
|
4395
4395
|
query: object({
|
|
4396
4396
|
datetime: o.optional(),
|
|
4397
4397
|
timezone: a.optional()
|
|
@@ -4399,20 +4399,20 @@ const y = object({
|
|
|
4399
4399
|
response: t.extend({
|
|
4400
4400
|
data: r.nullable()
|
|
4401
4401
|
})
|
|
4402
|
-
},
|
|
4402
|
+
}, Ee = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4403
4403
|
__proto__: null,
|
|
4404
|
-
getGrowwHistoricalCandles:
|
|
4405
|
-
getGrowwNiftyQuote:
|
|
4404
|
+
getGrowwHistoricalCandles: P,
|
|
4405
|
+
getGrowwNiftyQuote: M,
|
|
4406
4406
|
getGrowwNiftyQuoteTimeline: A,
|
|
4407
|
-
getGrowwQuote:
|
|
4408
|
-
getGrowwQuoteTimeline:
|
|
4409
|
-
getGrowwToken:
|
|
4407
|
+
getGrowwQuote: O,
|
|
4408
|
+
getGrowwQuoteTimeline: z,
|
|
4409
|
+
getGrowwToken: q,
|
|
4410
4410
|
growwHistoricalCandlesSchema: y
|
|
4411
4411
|
}, Symbol.toStringTag, { value: "Module" })), j = object({
|
|
4412
4412
|
name: string(),
|
|
4413
4413
|
price: number$1(),
|
|
4414
4414
|
nseSymbol: string()
|
|
4415
|
-
}),
|
|
4415
|
+
}), D = {
|
|
4416
4416
|
query: object({
|
|
4417
4417
|
type: _enum(["top-gainers", "volume-shockers"]),
|
|
4418
4418
|
datetime: o.optional(),
|
|
@@ -4422,9 +4422,9 @@ const y = object({
|
|
|
4422
4422
|
response: t.extend({
|
|
4423
4423
|
data: array(j).nullable()
|
|
4424
4424
|
})
|
|
4425
|
-
},
|
|
4425
|
+
}, Ie = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4426
4426
|
__proto__: null,
|
|
4427
|
-
getLists:
|
|
4427
|
+
getLists: D,
|
|
4428
4428
|
listSchema: j
|
|
4429
4429
|
}, Symbol.toStringTag, { value: "Module" })), C = {
|
|
4430
4430
|
query: object({
|
|
@@ -4451,7 +4451,7 @@ const y = object({
|
|
|
4451
4451
|
)
|
|
4452
4452
|
})
|
|
4453
4453
|
})
|
|
4454
|
-
},
|
|
4454
|
+
}, He = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4455
4455
|
__proto__: null,
|
|
4456
4456
|
getShortlistPersistence: C
|
|
4457
4457
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -4484,7 +4484,7 @@ const y = object({
|
|
|
4484
4484
|
})
|
|
4485
4485
|
})
|
|
4486
4486
|
});
|
|
4487
|
-
const
|
|
4487
|
+
const G = {
|
|
4488
4488
|
query: object({}),
|
|
4489
4489
|
response: t.extend({
|
|
4490
4490
|
data: object({
|
|
@@ -4498,10 +4498,10 @@ const E = {
|
|
|
4498
4498
|
)
|
|
4499
4499
|
})
|
|
4500
4500
|
})
|
|
4501
|
-
},
|
|
4501
|
+
}, E = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4502
4502
|
__proto__: null,
|
|
4503
|
-
getAvailableDatetimes:
|
|
4504
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
4503
|
+
getAvailableDatetimes: G
|
|
4504
|
+
}, Symbol.toStringTag, { value: "Module" })), I = {
|
|
4505
4505
|
query: object({
|
|
4506
4506
|
symbol: string(),
|
|
4507
4507
|
date: n,
|
|
@@ -4523,10 +4523,10 @@ const E = {
|
|
|
4523
4523
|
interval_in_minutes: number$1()
|
|
4524
4524
|
})
|
|
4525
4525
|
})
|
|
4526
|
-
},
|
|
4526
|
+
}, H = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4527
4527
|
__proto__: null,
|
|
4528
|
-
getCandles:
|
|
4529
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
4528
|
+
getCandles: I
|
|
4529
|
+
}, Symbol.toStringTag, { value: "Module" })), L = {
|
|
4530
4530
|
query: object({
|
|
4531
4531
|
date: n,
|
|
4532
4532
|
type: _enum(t$1)
|
|
@@ -4546,10 +4546,10 @@ const E = {
|
|
|
4546
4546
|
)
|
|
4547
4547
|
})
|
|
4548
4548
|
})
|
|
4549
|
-
},
|
|
4549
|
+
}, N = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4550
4550
|
__proto__: null,
|
|
4551
|
-
getDailyPersistentCompanies:
|
|
4552
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
4551
|
+
getDailyPersistentCompanies: L
|
|
4552
|
+
}, Symbol.toStringTag, { value: "Module" })), $ = {
|
|
4553
4553
|
query: object({
|
|
4554
4554
|
date: n,
|
|
4555
4555
|
type: _enum(t$1)
|
|
@@ -4563,7 +4563,7 @@ const E = {
|
|
|
4563
4563
|
})
|
|
4564
4564
|
}, Q = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4565
4565
|
__proto__: null,
|
|
4566
|
-
getDailyUniqueCompanies:
|
|
4566
|
+
getDailyUniqueCompanies: $
|
|
4567
4567
|
}, Symbol.toStringTag, { value: "Module" })), U = object({
|
|
4568
4568
|
id: uuid(),
|
|
4569
4569
|
username: string()
|
|
@@ -4574,10 +4574,10 @@ const E = {
|
|
|
4574
4574
|
response: t.extend({
|
|
4575
4575
|
data: U
|
|
4576
4576
|
})
|
|
4577
|
-
},
|
|
4577
|
+
}, K = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4578
4578
|
__proto__: null,
|
|
4579
4579
|
signIn: Y
|
|
4580
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
4580
|
+
}, Symbol.toStringTag, { value: "Module" })), F = {
|
|
4581
4581
|
query: object({
|
|
4582
4582
|
symbol: string(),
|
|
4583
4583
|
date: n
|
|
@@ -4599,9 +4599,9 @@ const E = {
|
|
|
4599
4599
|
)
|
|
4600
4600
|
})
|
|
4601
4601
|
})
|
|
4602
|
-
},
|
|
4602
|
+
}, B = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4603
4603
|
__proto__: null,
|
|
4604
|
-
getQuoteTimeline:
|
|
4604
|
+
getQuoteTimeline: F
|
|
4605
4605
|
}, Symbol.toStringTag, { value: "Module" })), Z = object({
|
|
4606
4606
|
id: uuid(),
|
|
4607
4607
|
start_datetime: string(),
|
|
@@ -4765,15 +4765,45 @@ const E = {
|
|
|
4765
4765
|
__proto__: null,
|
|
4766
4766
|
getShortlists: me,
|
|
4767
4767
|
shortlistEntryWithMetricsSchema: h
|
|
4768
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
4768
|
+
}, Symbol.toStringTag, { value: "Module" })), pe = {
|
|
4769
|
+
response: t.extend({
|
|
4770
|
+
data: object({
|
|
4771
|
+
hasGrowwApiKey: boolean(),
|
|
4772
|
+
hasGrowwApiSecret: boolean(),
|
|
4773
|
+
growwApiKeyMasked: string().nullable()
|
|
4774
|
+
})
|
|
4775
|
+
})
|
|
4776
|
+
}, ge = {
|
|
4777
|
+
body: object({
|
|
4778
|
+
growwApiKey: string().min(1, "Groww API key is required"),
|
|
4779
|
+
growwApiSecret: string().min(1, "Groww API secret is required")
|
|
4780
|
+
}),
|
|
4781
|
+
response: t.extend({
|
|
4782
|
+
data: object({
|
|
4783
|
+
success: boolean()
|
|
4784
|
+
})
|
|
4785
|
+
})
|
|
4786
|
+
}, _e = {
|
|
4787
|
+
response: t.extend({
|
|
4788
|
+
data: object({
|
|
4789
|
+
success: boolean()
|
|
4790
|
+
})
|
|
4791
|
+
})
|
|
4792
|
+
}, ye = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4769
4793
|
__proto__: null,
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4794
|
+
deleteGrowwCredentials: _e,
|
|
4795
|
+
getGrowwCredentials: pe,
|
|
4796
|
+
updateGrowwCredentials: ge
|
|
4797
|
+
}, Symbol.toStringTag, { value: "Module" })), $e = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4798
|
+
__proto__: null,
|
|
4799
|
+
v1_dashboard_auth_schemas: K,
|
|
4800
|
+
v1_dashboard_available_datetimes_schemas: E,
|
|
4801
|
+
v1_dashboard_candles_schemas: H,
|
|
4802
|
+
v1_dashboard_daily_persistent_companies_schemas: N,
|
|
4774
4803
|
v1_dashboard_daily_unique_companies_schemas: Q,
|
|
4775
|
-
v1_dashboard_quote_timeline_schemas:
|
|
4804
|
+
v1_dashboard_quote_timeline_schemas: B,
|
|
4776
4805
|
v1_dashboard_runs_schemas: ue,
|
|
4806
|
+
v1_dashboard_settings_schemas: ye,
|
|
4777
4807
|
v1_dashboard_shortlists_schemas: be
|
|
4778
4808
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
4779
4809
|
({
|
|
@@ -6060,7 +6090,7 @@ function matchHeaderValue(context, value, header, filter2, isHeaderNameFilter) {
|
|
|
6060
6090
|
}
|
|
6061
6091
|
}
|
|
6062
6092
|
function formatHeader(header) {
|
|
6063
|
-
return header.trim().toLowerCase().replace(/([a-z\d])(\w*)/g, (
|
|
6093
|
+
return header.trim().toLowerCase().replace(/([a-z\d])(\w*)/g, (w, char, str) => {
|
|
6064
6094
|
return char.toUpperCase() + str;
|
|
6065
6095
|
});
|
|
6066
6096
|
}
|
|
@@ -8121,6 +8151,147 @@ const logger = pino({
|
|
|
8121
8151
|
target: "pino-pretty"
|
|
8122
8152
|
}
|
|
8123
8153
|
});
|
|
8154
|
+
class RateLimiter {
|
|
8155
|
+
constructor(config2) {
|
|
8156
|
+
this.queue = [];
|
|
8157
|
+
this.secondTimestamps = [];
|
|
8158
|
+
this.minuteTimestamps = [];
|
|
8159
|
+
this.processing = false;
|
|
8160
|
+
this.inFlight = 0;
|
|
8161
|
+
this.maxPerSecond = config2.maxPerSecond;
|
|
8162
|
+
this.maxPerMinute = config2.maxPerMinute;
|
|
8163
|
+
this.maxConcurrency = config2.maxConcurrency ?? 10;
|
|
8164
|
+
this.requestTimeoutMs = config2.requestTimeoutMs ?? 3e4;
|
|
8165
|
+
}
|
|
8166
|
+
/**
|
|
8167
|
+
* Execute a function with rate limiting.
|
|
8168
|
+
* The function will be queued and executed when rate limits allow.
|
|
8169
|
+
*/
|
|
8170
|
+
async execute(fn) {
|
|
8171
|
+
return new Promise((resolve, reject) => {
|
|
8172
|
+
this.queue.push({ execute: fn, resolve, reject });
|
|
8173
|
+
this.processQueue();
|
|
8174
|
+
});
|
|
8175
|
+
}
|
|
8176
|
+
/**
|
|
8177
|
+
* Process the queue of pending requests.
|
|
8178
|
+
* Dispatches requests concurrently up to maxConcurrency while respecting rate limits.
|
|
8179
|
+
*/
|
|
8180
|
+
async processQueue() {
|
|
8181
|
+
if (this.processing) {
|
|
8182
|
+
return;
|
|
8183
|
+
}
|
|
8184
|
+
this.processing = true;
|
|
8185
|
+
while (this.queue.length > 0) {
|
|
8186
|
+
this.cleanupTimestamps();
|
|
8187
|
+
if (this.inFlight < this.maxConcurrency && this.canMakeRequest()) {
|
|
8188
|
+
const request = this.queue.shift();
|
|
8189
|
+
if (!request) {
|
|
8190
|
+
break;
|
|
8191
|
+
}
|
|
8192
|
+
const now = Date.now();
|
|
8193
|
+
this.secondTimestamps.push(now);
|
|
8194
|
+
this.minuteTimestamps.push(now);
|
|
8195
|
+
this.inFlight++;
|
|
8196
|
+
this.executeWithTimeout(request.execute, this.requestTimeoutMs).then((result) => {
|
|
8197
|
+
request.resolve(result);
|
|
8198
|
+
}).catch((error) => {
|
|
8199
|
+
request.reject(error instanceof Error ? error : new Error(String(error)));
|
|
8200
|
+
}).finally(() => {
|
|
8201
|
+
this.inFlight--;
|
|
8202
|
+
this.processQueue();
|
|
8203
|
+
});
|
|
8204
|
+
} else {
|
|
8205
|
+
if (this.inFlight >= this.maxConcurrency) {
|
|
8206
|
+
break;
|
|
8207
|
+
} else {
|
|
8208
|
+
const waitTime = this.getWaitTime();
|
|
8209
|
+
if (waitTime > 0) {
|
|
8210
|
+
await this.sleep(waitTime);
|
|
8211
|
+
} else {
|
|
8212
|
+
await this.sleep(10);
|
|
8213
|
+
}
|
|
8214
|
+
}
|
|
8215
|
+
}
|
|
8216
|
+
}
|
|
8217
|
+
this.processing = false;
|
|
8218
|
+
}
|
|
8219
|
+
/**
|
|
8220
|
+
* Check if a new request can be made based on current rate limits.
|
|
8221
|
+
*/
|
|
8222
|
+
canMakeRequest() {
|
|
8223
|
+
const now = Date.now();
|
|
8224
|
+
const oneSecondAgo = now - 1e3;
|
|
8225
|
+
const oneMinuteAgo = now - 6e4;
|
|
8226
|
+
const recentSecondCount = this.secondTimestamps.filter((ts) => ts > oneSecondAgo).length;
|
|
8227
|
+
const recentMinuteCount = this.minuteTimestamps.filter((ts) => ts > oneMinuteAgo).length;
|
|
8228
|
+
return recentSecondCount < this.maxPerSecond && recentMinuteCount < this.maxPerMinute;
|
|
8229
|
+
}
|
|
8230
|
+
/**
|
|
8231
|
+
* Remove timestamps that are outside the tracking windows.
|
|
8232
|
+
*/
|
|
8233
|
+
cleanupTimestamps() {
|
|
8234
|
+
const now = Date.now();
|
|
8235
|
+
const oneSecondAgo = now - 1e3;
|
|
8236
|
+
const oneMinuteAgo = now - 6e4;
|
|
8237
|
+
this.secondTimestamps = this.secondTimestamps.filter((ts) => ts > oneSecondAgo);
|
|
8238
|
+
this.minuteTimestamps = this.minuteTimestamps.filter((ts) => ts > oneMinuteAgo);
|
|
8239
|
+
}
|
|
8240
|
+
/**
|
|
8241
|
+
* Calculate the minimum wait time needed before the next request can be made.
|
|
8242
|
+
*/
|
|
8243
|
+
getWaitTime() {
|
|
8244
|
+
const now = Date.now();
|
|
8245
|
+
const oneSecondAgo = now - 1e3;
|
|
8246
|
+
const oneMinuteAgo = now - 6e4;
|
|
8247
|
+
let waitTime = 0;
|
|
8248
|
+
const recentSecondCount = this.secondTimestamps.filter((ts) => ts > oneSecondAgo).length;
|
|
8249
|
+
if (recentSecondCount >= this.maxPerSecond) {
|
|
8250
|
+
const oldestInSecond = Math.min(...this.secondTimestamps.filter((ts) => ts > oneSecondAgo));
|
|
8251
|
+
const waitForSecond = oldestInSecond + 1e3 - now;
|
|
8252
|
+
waitTime = Math.max(waitTime, waitForSecond);
|
|
8253
|
+
}
|
|
8254
|
+
const recentMinuteCount = this.minuteTimestamps.filter((ts) => ts > oneMinuteAgo).length;
|
|
8255
|
+
if (recentMinuteCount >= this.maxPerMinute) {
|
|
8256
|
+
const oldestInMinute = Math.min(...this.minuteTimestamps.filter((ts) => ts > oneMinuteAgo));
|
|
8257
|
+
const waitForMinute = oldestInMinute + 6e4 - now;
|
|
8258
|
+
waitTime = Math.max(waitTime, waitForMinute);
|
|
8259
|
+
}
|
|
8260
|
+
return Math.max(waitTime, 0);
|
|
8261
|
+
}
|
|
8262
|
+
/**
|
|
8263
|
+
* Execute a function with a timeout.
|
|
8264
|
+
* If the function doesn't complete within the timeout, it will be rejected.
|
|
8265
|
+
*/
|
|
8266
|
+
async executeWithTimeout(fn, timeoutMs) {
|
|
8267
|
+
return Promise.race([
|
|
8268
|
+
fn(),
|
|
8269
|
+
new Promise(
|
|
8270
|
+
(_2, reject) => setTimeout(
|
|
8271
|
+
() => reject(new Error(`Request timed out after ${timeoutMs}ms`)),
|
|
8272
|
+
timeoutMs
|
|
8273
|
+
)
|
|
8274
|
+
)
|
|
8275
|
+
]);
|
|
8276
|
+
}
|
|
8277
|
+
/**
|
|
8278
|
+
* Sleep for a given number of milliseconds.
|
|
8279
|
+
*/
|
|
8280
|
+
sleep(ms) {
|
|
8281
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8282
|
+
}
|
|
8283
|
+
}
|
|
8284
|
+
const limiters = /* @__PURE__ */ new Map();
|
|
8285
|
+
limiters.set(
|
|
8286
|
+
"groww",
|
|
8287
|
+
new RateLimiter({
|
|
8288
|
+
maxPerSecond: 10,
|
|
8289
|
+
maxPerMinute: 300,
|
|
8290
|
+
maxConcurrency: 7,
|
|
8291
|
+
requestTimeoutMs: 3e4
|
|
8292
|
+
})
|
|
8293
|
+
);
|
|
8294
|
+
const growwRateLimiter = limiters.get("groww");
|
|
8124
8295
|
dayjs.extend(utc);
|
|
8125
8296
|
dayjs.extend(timezone);
|
|
8126
8297
|
const fetchCandles = ({
|
|
@@ -8136,7 +8307,7 @@ const fetchCandles = ({
|
|
|
8136
8307
|
);
|
|
8137
8308
|
}
|
|
8138
8309
|
try {
|
|
8139
|
-
const validatedParams =
|
|
8310
|
+
const validatedParams = Ee.getGrowwHistoricalCandles.query.parse(params);
|
|
8140
8311
|
const headers = {
|
|
8141
8312
|
Authorization: `Bearer ${developerToken}`
|
|
8142
8313
|
};
|
|
@@ -8149,10 +8320,15 @@ const fetchCandles = ({
|
|
|
8149
8320
|
if (currentTimezone) {
|
|
8150
8321
|
headers["X-Current-Timezone"] = currentTimezone;
|
|
8151
8322
|
}
|
|
8152
|
-
const response = await
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8323
|
+
const response = await growwRateLimiter.execute(
|
|
8324
|
+
() => axios.get(
|
|
8325
|
+
`${apiDomain}/v1/developer/historical-candles`,
|
|
8326
|
+
{
|
|
8327
|
+
params: validatedParams,
|
|
8328
|
+
headers
|
|
8329
|
+
}
|
|
8330
|
+
)
|
|
8331
|
+
);
|
|
8156
8332
|
return response.data.data;
|
|
8157
8333
|
} catch (error) {
|
|
8158
8334
|
if (axios.isAxiosError(error)) {
|
|
@@ -8180,7 +8356,7 @@ const fetchQuote = ({
|
|
|
8180
8356
|
);
|
|
8181
8357
|
}
|
|
8182
8358
|
try {
|
|
8183
|
-
const validatedParams =
|
|
8359
|
+
const validatedParams = Ee.getGrowwQuote.query.parse(params);
|
|
8184
8360
|
const headers = {
|
|
8185
8361
|
Authorization: `Bearer ${developerToken}`
|
|
8186
8362
|
};
|
|
@@ -8220,7 +8396,7 @@ const fetchQuoteTimeline = ({
|
|
|
8220
8396
|
throw new Error("Developer token not found. Please set DEVELOPER_KEY environment variable.");
|
|
8221
8397
|
}
|
|
8222
8398
|
try {
|
|
8223
|
-
const validatedParams =
|
|
8399
|
+
const validatedParams = Ee.getGrowwQuoteTimeline.query.parse({
|
|
8224
8400
|
symbol,
|
|
8225
8401
|
end_datetime
|
|
8226
8402
|
});
|
|
@@ -8267,7 +8443,7 @@ const fetchShortlist = ({
|
|
|
8267
8443
|
);
|
|
8268
8444
|
}
|
|
8269
8445
|
try {
|
|
8270
|
-
const validatedParams =
|
|
8446
|
+
const validatedParams = Ie.getLists.query.parse(queryParams);
|
|
8271
8447
|
const headers = {
|
|
8272
8448
|
Authorization: `Bearer ${developerToken}`
|
|
8273
8449
|
};
|
|
@@ -8311,7 +8487,7 @@ const fetchShortlistPersistence = ({
|
|
|
8311
8487
|
);
|
|
8312
8488
|
}
|
|
8313
8489
|
try {
|
|
8314
|
-
const validatedParams =
|
|
8490
|
+
const validatedParams = He.getShortlistPersistence.query.parse(queryParams);
|
|
8315
8491
|
const headers = {
|
|
8316
8492
|
Authorization: `Bearer ${developerToken}`
|
|
8317
8493
|
};
|
|
@@ -8355,7 +8531,7 @@ const fetchNiftyQuote = ({
|
|
|
8355
8531
|
throw new Error("Developer token not found. Please set DEVELOPER_KEY environment variable.");
|
|
8356
8532
|
}
|
|
8357
8533
|
try {
|
|
8358
|
-
const validatedParams =
|
|
8534
|
+
const validatedParams = Ee.getGrowwNiftyQuote.query.parse(params);
|
|
8359
8535
|
const headers = {
|
|
8360
8536
|
Authorization: `Bearer ${developerToken}`
|
|
8361
8537
|
};
|
|
@@ -8397,7 +8573,7 @@ const fetchNiftyQuoteTimeline = ({
|
|
|
8397
8573
|
throw new Error("Developer token not found. Please set DEVELOPER_KEY environment variable.");
|
|
8398
8574
|
}
|
|
8399
8575
|
try {
|
|
8400
|
-
const validatedParams =
|
|
8576
|
+
const validatedParams = Ee.getGrowwNiftyQuoteTimeline.query.parse({
|
|
8401
8577
|
end_datetime
|
|
8402
8578
|
});
|
|
8403
8579
|
const headers = {
|
|
@@ -8586,7 +8762,7 @@ const placeOrder = ({ runId, apiClient }) => async (data) => {
|
|
|
8586
8762
|
try {
|
|
8587
8763
|
await retryWithBackoff(
|
|
8588
8764
|
async () => {
|
|
8589
|
-
const validatedData =
|
|
8765
|
+
const validatedData = $e.v1_dashboard_runs_schemas.createOrder.body.parse(data);
|
|
8590
8766
|
await apiClient.post(`/v1/dashboard/runs/${runId}/orders`, validatedData);
|
|
8591
8767
|
logger.debug(`Order persisted for ${data.nseSymbol} in runId: ${runId}`);
|
|
8592
8768
|
},
|