ebag 0.0.2 → 0.1.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/README.md +26 -10
- package/dist/cli/format.d.ts +1 -1
- package/dist/cli/format.js +136 -115
- package/dist/cli/index.js +138 -79
- package/dist/lib/auth.d.ts +1 -1
- package/dist/lib/auth.js +5 -5
- package/dist/lib/cart.d.ts +1 -1
- package/dist/lib/cart.js +11 -11
- package/dist/lib/client.d.ts +1 -1
- package/dist/lib/client.js +30 -20
- package/dist/lib/config.d.ts +2 -1
- package/dist/lib/config.js +22 -13
- package/dist/lib/cookies.js +10 -7
- package/dist/lib/index.d.ts +9 -9
- package/dist/lib/lists.d.ts +1 -1
- package/dist/lib/lists.js +4 -4
- package/dist/lib/log.d.ts +8 -0
- package/dist/lib/log.js +115 -0
- package/dist/lib/orders.d.ts +1 -1
- package/dist/lib/orders.js +47 -29
- package/dist/lib/products.d.ts +1 -1
- package/dist/lib/search.d.ts +1 -1
- package/dist/lib/search.js +26 -20
- package/dist/lib/slots.d.ts +1 -1
- package/dist/lib/slots.js +3 -3
- package/dist/lib/types.d.ts +1 -1
- package/package.json +5 -2
package/dist/cli/index.js
CHANGED
|
@@ -16,6 +16,7 @@ const orders_1 = require("../lib/orders");
|
|
|
16
16
|
const products_1 = require("../lib/products");
|
|
17
17
|
const search_1 = require("../lib/search");
|
|
18
18
|
const slots_1 = require("../lib/slots");
|
|
19
|
+
const log_1 = require("../lib/log");
|
|
19
20
|
const format_1 = require("./format");
|
|
20
21
|
function requireSessionCookie() {
|
|
21
22
|
const session = (0, config_1.loadSession)();
|
|
@@ -35,26 +36,60 @@ function formatError(err) {
|
|
|
35
36
|
}
|
|
36
37
|
async function main() {
|
|
37
38
|
const program = new commander_1.Command();
|
|
39
|
+
let lastCommand = "unknown";
|
|
40
|
+
let lastArgs = [];
|
|
41
|
+
let lastStart = Date.now();
|
|
38
42
|
function getPackageVersion() {
|
|
39
43
|
try {
|
|
40
|
-
const packagePath = node_path_1.default.resolve(__dirname,
|
|
41
|
-
const raw = node_fs_1.default.readFileSync(packagePath,
|
|
44
|
+
const packagePath = node_path_1.default.resolve(__dirname, "../../package.json");
|
|
45
|
+
const raw = node_fs_1.default.readFileSync(packagePath, "utf8");
|
|
42
46
|
const parsed = JSON.parse(raw);
|
|
43
|
-
return parsed.version ||
|
|
47
|
+
return parsed.version || "unknown";
|
|
44
48
|
}
|
|
45
49
|
catch {
|
|
46
|
-
return
|
|
50
|
+
return "unknown";
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
program
|
|
50
|
-
.name(
|
|
51
|
-
.description(
|
|
52
|
-
.version(getPackageVersion(),
|
|
53
|
-
.option(
|
|
54
|
+
.name("ebag")
|
|
55
|
+
.description("CLI for interacting with ebag.bg")
|
|
56
|
+
.version(getPackageVersion(), "-v, --version", "Show CLI version")
|
|
57
|
+
.option("--json", "Output JSON");
|
|
58
|
+
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
59
|
+
lastStart = Date.now();
|
|
60
|
+
const commandPath = actionCommand.commandPath?.();
|
|
61
|
+
lastCommand = commandPath || actionCommand.name() || "unknown";
|
|
62
|
+
lastArgs = process.argv.slice(2);
|
|
63
|
+
(0, log_1.appendLog)({
|
|
64
|
+
level: "info",
|
|
65
|
+
event: "command.start",
|
|
66
|
+
command: lastCommand,
|
|
67
|
+
args: lastArgs,
|
|
68
|
+
json: Boolean(program.opts().json),
|
|
69
|
+
pid: process.pid,
|
|
70
|
+
ppid: process.ppid,
|
|
71
|
+
cwd: process.cwd(),
|
|
72
|
+
node: process.version,
|
|
73
|
+
configDir: (0, config_1.getConfigDir)(),
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
program.hook("postAction", () => {
|
|
77
|
+
const durationMs = Date.now() - lastStart;
|
|
78
|
+
(0, log_1.appendLog)({
|
|
79
|
+
level: "info",
|
|
80
|
+
event: "command.finish",
|
|
81
|
+
command: lastCommand,
|
|
82
|
+
args: lastArgs,
|
|
83
|
+
json: Boolean(program.opts().json),
|
|
84
|
+
pid: process.pid,
|
|
85
|
+
durationMs,
|
|
86
|
+
configDir: (0, config_1.getConfigDir)(),
|
|
87
|
+
});
|
|
88
|
+
});
|
|
54
89
|
program
|
|
55
|
-
.command(
|
|
56
|
-
.description(
|
|
57
|
-
.option(
|
|
90
|
+
.command("login")
|
|
91
|
+
.description("Store session cookie and validate it")
|
|
92
|
+
.option("--cookie <cookie>", "Cookie header value from browser")
|
|
58
93
|
.action(async (options) => {
|
|
59
94
|
const config = (0, config_1.loadConfig)();
|
|
60
95
|
const json = program.opts().json;
|
|
@@ -81,20 +116,20 @@ async function main() {
|
|
|
81
116
|
const email = user.email ||
|
|
82
117
|
user.username;
|
|
83
118
|
if (!email) {
|
|
84
|
-
throw new Error(
|
|
119
|
+
throw new Error("Session validated but no user email was returned.");
|
|
85
120
|
}
|
|
86
121
|
(0, config_1.saveSession)(session);
|
|
87
122
|
if (json) {
|
|
88
|
-
(0, format_1.outputJson)({ status:
|
|
123
|
+
(0, format_1.outputJson)({ status: "ok", user, email });
|
|
89
124
|
}
|
|
90
125
|
else {
|
|
91
|
-
process.stdout.write(
|
|
126
|
+
process.stdout.write("Login session validated and saved.\n");
|
|
92
127
|
process.stdout.write(`Logged in as: ${email}\n`);
|
|
93
128
|
}
|
|
94
129
|
}
|
|
95
130
|
catch (err) {
|
|
96
131
|
if (json) {
|
|
97
|
-
(0, format_1.outputJson)({ status:
|
|
132
|
+
(0, format_1.outputJson)({ status: "error", message: err.message });
|
|
98
133
|
}
|
|
99
134
|
else {
|
|
100
135
|
process.stderr.write(`Login failed: ${err.message}\n`);
|
|
@@ -102,29 +137,30 @@ async function main() {
|
|
|
102
137
|
}
|
|
103
138
|
});
|
|
104
139
|
program
|
|
105
|
-
.command(
|
|
106
|
-
.description(
|
|
140
|
+
.command("status")
|
|
141
|
+
.description("Show current login status")
|
|
107
142
|
.action(async () => {
|
|
108
143
|
const config = (0, config_1.loadConfig)();
|
|
109
144
|
const json = program.opts().json;
|
|
110
145
|
const session = (0, config_1.loadSession)();
|
|
111
146
|
if (!session.cookies) {
|
|
112
147
|
if (json) {
|
|
113
|
-
(0, format_1.outputJson)({ status:
|
|
148
|
+
(0, format_1.outputJson)({ status: "logged_out" });
|
|
114
149
|
}
|
|
115
150
|
else {
|
|
116
|
-
process.stdout.write(
|
|
151
|
+
process.stdout.write("Logged out (no session cookie).\n");
|
|
117
152
|
}
|
|
118
153
|
return;
|
|
119
154
|
}
|
|
120
155
|
try {
|
|
121
156
|
const user = await (0, auth_1.validateSession)(config, session);
|
|
122
|
-
const email = user.email ||
|
|
157
|
+
const email = user.email ||
|
|
158
|
+
user.username;
|
|
123
159
|
if (json) {
|
|
124
|
-
(0, format_1.outputJson)({ status:
|
|
160
|
+
(0, format_1.outputJson)({ status: "logged_in", user, email });
|
|
125
161
|
}
|
|
126
162
|
else {
|
|
127
|
-
process.stdout.write(
|
|
163
|
+
process.stdout.write("Logged in.\n");
|
|
128
164
|
if (email) {
|
|
129
165
|
process.stdout.write(`Email: ${email}\n`);
|
|
130
166
|
}
|
|
@@ -134,10 +170,10 @@ async function main() {
|
|
|
134
170
|
const error = err;
|
|
135
171
|
if (error.status && [401, 403].includes(error.status)) {
|
|
136
172
|
if (json) {
|
|
137
|
-
(0, format_1.outputJson)({ status:
|
|
173
|
+
(0, format_1.outputJson)({ status: "logged_out" });
|
|
138
174
|
}
|
|
139
175
|
else {
|
|
140
|
-
process.stdout.write(
|
|
176
|
+
process.stdout.write("Logged out.\n");
|
|
141
177
|
}
|
|
142
178
|
return;
|
|
143
179
|
}
|
|
@@ -145,9 +181,9 @@ async function main() {
|
|
|
145
181
|
}
|
|
146
182
|
});
|
|
147
183
|
program
|
|
148
|
-
.command(
|
|
149
|
-
.description(
|
|
150
|
-
.option(
|
|
184
|
+
.command("slots")
|
|
185
|
+
.description("Show the next available delivery slots")
|
|
186
|
+
.option("--limit <n>", "Limit number of slots", "10")
|
|
151
187
|
.action(async (options) => {
|
|
152
188
|
const config = (0, config_1.loadConfig)();
|
|
153
189
|
const session = requireSessionCookie();
|
|
@@ -162,7 +198,7 @@ async function main() {
|
|
|
162
198
|
return;
|
|
163
199
|
}
|
|
164
200
|
if (!limited.length) {
|
|
165
|
-
process.stdout.write(
|
|
201
|
+
process.stdout.write("No available delivery slots.\n");
|
|
166
202
|
return;
|
|
167
203
|
}
|
|
168
204
|
const today = new Date();
|
|
@@ -170,7 +206,7 @@ async function main() {
|
|
|
170
206
|
const tomorrow = new Date(today);
|
|
171
207
|
tomorrow.setDate(today.getDate() + 1);
|
|
172
208
|
const tomorrowDate = tomorrow.toISOString().slice(0, 10);
|
|
173
|
-
let currentDate =
|
|
209
|
+
let currentDate = "";
|
|
174
210
|
let printedHeader = false;
|
|
175
211
|
for (const slot of limited) {
|
|
176
212
|
if (slot.date !== currentDate) {
|
|
@@ -182,26 +218,30 @@ async function main() {
|
|
|
182
218
|
else if (currentDate === tomorrowDate) {
|
|
183
219
|
label = `Tomorrow (${currentDate})`;
|
|
184
220
|
}
|
|
185
|
-
const headerPrefix = printedHeader ?
|
|
221
|
+
const headerPrefix = printedHeader ? "\n" : "";
|
|
186
222
|
process.stdout.write(`${headerPrefix}${(0, format_1.formatHeading)(`# ${label}`)}\n`);
|
|
187
223
|
printedHeader = true;
|
|
188
224
|
}
|
|
189
225
|
process.stdout.write(`${(0, slots_1.formatSlotRange)(slot.start, slot.end)} (${(0, slots_1.formatLoadPercent)(slot.loadPercent)})\n`);
|
|
190
226
|
}
|
|
191
227
|
});
|
|
192
|
-
program
|
|
193
|
-
|
|
194
|
-
.
|
|
195
|
-
.
|
|
196
|
-
.
|
|
197
|
-
.option(
|
|
228
|
+
const product = program.command("product").description("Product operations");
|
|
229
|
+
product
|
|
230
|
+
.command("search")
|
|
231
|
+
.description("Search for products")
|
|
232
|
+
.argument("<query>", "Search query")
|
|
233
|
+
.option("--limit <n>", "Limit number of results", "20")
|
|
234
|
+
.option("--page <n>", "Algolia page number (0-based)", "0")
|
|
198
235
|
.action(async (query, options) => {
|
|
199
236
|
const config = (0, config_1.loadConfig)();
|
|
200
237
|
const session = (0, config_1.loadSession)();
|
|
201
238
|
const json = program.opts().json;
|
|
202
239
|
const limit = Number(options.limit);
|
|
203
240
|
const page = Number(options.page);
|
|
204
|
-
const result = await (0, search_1.searchProducts)(config, session, query, {
|
|
241
|
+
const result = await (0, search_1.searchProducts)(config, session, query, {
|
|
242
|
+
limit,
|
|
243
|
+
page,
|
|
244
|
+
});
|
|
205
245
|
if (json) {
|
|
206
246
|
(0, format_1.outputJson)(result);
|
|
207
247
|
}
|
|
@@ -209,10 +249,10 @@ async function main() {
|
|
|
209
249
|
(0, format_1.outputProducts)(result.results);
|
|
210
250
|
}
|
|
211
251
|
});
|
|
212
|
-
|
|
213
|
-
.command(
|
|
214
|
-
.description(
|
|
215
|
-
.argument(
|
|
252
|
+
product
|
|
253
|
+
.command("show")
|
|
254
|
+
.description("Get product details by ID")
|
|
255
|
+
.argument("<productId>", "Product ID")
|
|
216
256
|
.action(async (productId) => {
|
|
217
257
|
const config = (0, config_1.loadConfig)();
|
|
218
258
|
const session = (0, config_1.loadSession)();
|
|
@@ -225,14 +265,14 @@ async function main() {
|
|
|
225
265
|
(0, format_1.outputProductDetail)(result);
|
|
226
266
|
}
|
|
227
267
|
});
|
|
228
|
-
const order = program.command(
|
|
268
|
+
const order = program.command("order").description("Order operations");
|
|
229
269
|
order
|
|
230
|
-
.command(
|
|
231
|
-
.description(
|
|
232
|
-
.option(
|
|
233
|
-
.option(
|
|
234
|
-
.option(
|
|
235
|
-
.option(
|
|
270
|
+
.command("list")
|
|
271
|
+
.description("List recent orders")
|
|
272
|
+
.option("--limit <n>", "Limit number of results", "10")
|
|
273
|
+
.option("--page <n>", "Page number")
|
|
274
|
+
.option("--from <date>", "Filter from date (YYYY-MM-DD)")
|
|
275
|
+
.option("--to <date>", "Filter to date (YYYY-MM-DD)")
|
|
236
276
|
.action(async (options) => {
|
|
237
277
|
const config = (0, config_1.loadConfig)();
|
|
238
278
|
const session = requireSessionCookie();
|
|
@@ -251,16 +291,16 @@ async function main() {
|
|
|
251
291
|
(0, format_1.outputJson)(result);
|
|
252
292
|
}
|
|
253
293
|
else if (!result.results.length) {
|
|
254
|
-
process.stdout.write(
|
|
294
|
+
process.stdout.write("No orders found.\n");
|
|
255
295
|
}
|
|
256
296
|
else {
|
|
257
297
|
(0, format_1.outputOrdersList)(result.results);
|
|
258
298
|
}
|
|
259
299
|
});
|
|
260
300
|
order
|
|
261
|
-
.command(
|
|
262
|
-
.description(
|
|
263
|
-
.argument(
|
|
301
|
+
.command("show")
|
|
302
|
+
.description("Show order details")
|
|
303
|
+
.argument("<orderId>", "Order ID")
|
|
264
304
|
.action(async (orderId) => {
|
|
265
305
|
const config = (0, config_1.loadConfig)();
|
|
266
306
|
const session = requireSessionCookie();
|
|
@@ -273,11 +313,11 @@ async function main() {
|
|
|
273
313
|
(0, format_1.outputOrderDetail)(detail);
|
|
274
314
|
}
|
|
275
315
|
});
|
|
276
|
-
const cart = program.command(
|
|
316
|
+
const cart = program.command("cart").description("Cart operations");
|
|
277
317
|
cart
|
|
278
|
-
.command(
|
|
279
|
-
.argument(
|
|
280
|
-
.option(
|
|
318
|
+
.command("add")
|
|
319
|
+
.argument("<productId>", "Product ID")
|
|
320
|
+
.option("--qty <n>", "Quantity", "1")
|
|
281
321
|
.action(async (productId, options) => {
|
|
282
322
|
const config = (0, config_1.loadConfig)();
|
|
283
323
|
const session = requireSessionCookie();
|
|
@@ -288,13 +328,13 @@ async function main() {
|
|
|
288
328
|
(0, format_1.outputJson)(result);
|
|
289
329
|
}
|
|
290
330
|
else {
|
|
291
|
-
process.stdout.write(
|
|
331
|
+
process.stdout.write("Added to cart.\n");
|
|
292
332
|
}
|
|
293
333
|
});
|
|
294
334
|
cart
|
|
295
|
-
.command(
|
|
296
|
-
.argument(
|
|
297
|
-
.option(
|
|
335
|
+
.command("update")
|
|
336
|
+
.argument("<productId>", "Product ID")
|
|
337
|
+
.option("--qty <n>", "Quantity", "1")
|
|
298
338
|
.action(async (productId, options) => {
|
|
299
339
|
const config = (0, config_1.loadConfig)();
|
|
300
340
|
const session = requireSessionCookie();
|
|
@@ -305,12 +345,12 @@ async function main() {
|
|
|
305
345
|
(0, format_1.outputJson)(result);
|
|
306
346
|
}
|
|
307
347
|
else {
|
|
308
|
-
process.stdout.write(
|
|
348
|
+
process.stdout.write("Cart updated.\n");
|
|
309
349
|
}
|
|
310
350
|
});
|
|
311
351
|
cart
|
|
312
|
-
.command(
|
|
313
|
-
.description(
|
|
352
|
+
.command("show")
|
|
353
|
+
.description("Show cart contents")
|
|
314
354
|
.action(async () => {
|
|
315
355
|
const config = (0, config_1.loadConfig)();
|
|
316
356
|
const session = requireSessionCookie();
|
|
@@ -326,8 +366,11 @@ async function main() {
|
|
|
326
366
|
const listItems = items
|
|
327
367
|
.map((item) => {
|
|
328
368
|
const entry = item;
|
|
329
|
-
const id = entry.product?.id ??
|
|
330
|
-
|
|
369
|
+
const id = entry.product?.id ??
|
|
370
|
+
entry.product_id ??
|
|
371
|
+
entry.productId ??
|
|
372
|
+
entry.id;
|
|
373
|
+
const name = entry.product?.name ?? entry.name ?? "Unknown";
|
|
331
374
|
const count = entry.quantity ?? entry.qty;
|
|
332
375
|
if (!id)
|
|
333
376
|
return null;
|
|
@@ -338,14 +381,14 @@ async function main() {
|
|
|
338
381
|
(0, format_1.outputList)(listItems);
|
|
339
382
|
}
|
|
340
383
|
else {
|
|
341
|
-
process.stdout.write(
|
|
384
|
+
process.stdout.write("Cart is empty.\n");
|
|
342
385
|
}
|
|
343
386
|
});
|
|
344
|
-
const list = program.command(
|
|
387
|
+
const list = program.command("list").description("List operations");
|
|
345
388
|
list
|
|
346
|
-
.command(
|
|
347
|
-
.description(
|
|
348
|
-
.argument(
|
|
389
|
+
.command("show")
|
|
390
|
+
.description("Show your lists")
|
|
391
|
+
.argument("[listId]", "List ID")
|
|
349
392
|
.action(async (listId) => {
|
|
350
393
|
const config = (0, config_1.loadConfig)();
|
|
351
394
|
const session = requireSessionCookie();
|
|
@@ -360,7 +403,7 @@ async function main() {
|
|
|
360
403
|
const results = Array.isArray(listItems.results)
|
|
361
404
|
? listItems.results
|
|
362
405
|
: [];
|
|
363
|
-
const count = typeof listItems.count ===
|
|
406
|
+
const count = typeof listItems.count === "number"
|
|
364
407
|
? listItems.count
|
|
365
408
|
: results.length;
|
|
366
409
|
if (json) {
|
|
@@ -375,7 +418,7 @@ async function main() {
|
|
|
375
418
|
else {
|
|
376
419
|
process.stdout.write(`${listEntry.name} (${listEntry.id})`);
|
|
377
420
|
if (!count) {
|
|
378
|
-
process.stdout.write(
|
|
421
|
+
process.stdout.write(" - empty\n");
|
|
379
422
|
return;
|
|
380
423
|
}
|
|
381
424
|
process.stdout.write(` - ${count} items\n`);
|
|
@@ -384,7 +427,7 @@ async function main() {
|
|
|
384
427
|
const entry = item;
|
|
385
428
|
const product = entry.product;
|
|
386
429
|
const id = product?.id ?? entry.product_id ?? entry.productId ?? entry.id;
|
|
387
|
-
const name = product?.name ?? entry.name ??
|
|
430
|
+
const name = product?.name ?? entry.name ?? "Unknown";
|
|
388
431
|
const itemCount = entry.quantity ?? entry.qty;
|
|
389
432
|
if (!id)
|
|
390
433
|
return null;
|
|
@@ -406,10 +449,10 @@ async function main() {
|
|
|
406
449
|
})));
|
|
407
450
|
});
|
|
408
451
|
list
|
|
409
|
-
.command(
|
|
410
|
-
.argument(
|
|
411
|
-
.argument(
|
|
412
|
-
.option(
|
|
452
|
+
.command("add")
|
|
453
|
+
.argument("<listId>", "List ID")
|
|
454
|
+
.argument("<productId>", "Product ID")
|
|
455
|
+
.option("--qty <n>", "Quantity", "1")
|
|
413
456
|
.action(async (listId, productId, options) => {
|
|
414
457
|
const config = (0, config_1.loadConfig)();
|
|
415
458
|
const session = requireSessionCookie();
|
|
@@ -420,7 +463,7 @@ async function main() {
|
|
|
420
463
|
(0, format_1.outputJson)(result);
|
|
421
464
|
}
|
|
422
465
|
else {
|
|
423
|
-
process.stdout.write(
|
|
466
|
+
process.stdout.write("Added to list.\n");
|
|
424
467
|
}
|
|
425
468
|
});
|
|
426
469
|
try {
|
|
@@ -428,8 +471,24 @@ async function main() {
|
|
|
428
471
|
}
|
|
429
472
|
catch (err) {
|
|
430
473
|
const json = program.opts().json;
|
|
474
|
+
const error = err;
|
|
475
|
+
(0, log_1.appendLog)({
|
|
476
|
+
level: "error",
|
|
477
|
+
event: "command.error",
|
|
478
|
+
command: lastCommand,
|
|
479
|
+
args: lastArgs,
|
|
480
|
+
json: Boolean(json),
|
|
481
|
+
pid: process.pid,
|
|
482
|
+
durationMs: Date.now() - lastStart,
|
|
483
|
+
configDir: (0, config_1.getConfigDir)(),
|
|
484
|
+
message: error.message,
|
|
485
|
+
status: error.status,
|
|
486
|
+
body: error.body,
|
|
487
|
+
url: error.url,
|
|
488
|
+
method: error.method,
|
|
489
|
+
});
|
|
431
490
|
if (json) {
|
|
432
|
-
(0, format_1.outputJson)({ status:
|
|
491
|
+
(0, format_1.outputJson)({ status: "error", ...formatError(err) });
|
|
433
492
|
}
|
|
434
493
|
else {
|
|
435
494
|
const details = formatError(err);
|
package/dist/lib/auth.d.ts
CHANGED
package/dist/lib/auth.js
CHANGED
|
@@ -5,13 +5,13 @@ exports.validateSession = validateSession;
|
|
|
5
5
|
const client_1 = require("./client");
|
|
6
6
|
function getLoginInstructions() {
|
|
7
7
|
return [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
"1) Log in to https://www.ebag.bg in your browser.",
|
|
9
|
+
"2) Open DevTools > Network and click any request to https://www.ebag.bg (not a static asset).",
|
|
10
|
+
"3) In the request headers, copy the full Cookie header value (semicolon-separated).",
|
|
11
11
|
'4) Run: ebag login --cookie "<cookie>"',
|
|
12
|
-
].join(
|
|
12
|
+
].join("\n");
|
|
13
13
|
}
|
|
14
14
|
async function validateSession(config, session) {
|
|
15
|
-
const result = await (0, client_1.requestEbag)(config, session,
|
|
15
|
+
const result = await (0, client_1.requestEbag)(config, session, "/user/json");
|
|
16
16
|
return result.data;
|
|
17
17
|
}
|
package/dist/lib/cart.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Config, Session } from
|
|
1
|
+
import type { Config, Session } from "./types";
|
|
2
2
|
export declare function addToCart(config: Config, session: Session, productId: number, quantity: number, unitTypeOverride?: string): Promise<unknown>;
|
|
3
3
|
export declare function updateCart(config: Config, session: Session, productId: number, quantity: number, unitTypeOverride?: string): Promise<unknown>;
|
|
4
4
|
export declare function getCart(config: Config, session: Session): Promise<unknown>;
|
package/dist/lib/cart.js
CHANGED
|
@@ -4,17 +4,17 @@ exports.addToCart = addToCart;
|
|
|
4
4
|
exports.updateCart = updateCart;
|
|
5
5
|
exports.getCart = getCart;
|
|
6
6
|
const client_1 = require("./client");
|
|
7
|
-
async function addToCart(config, session, productId, quantity, unitTypeOverride =
|
|
8
|
-
const baseUrl = config.baseUrl ||
|
|
7
|
+
async function addToCart(config, session, productId, quantity, unitTypeOverride = "false") {
|
|
8
|
+
const baseUrl = config.baseUrl || "https://www.ebag.bg";
|
|
9
9
|
const body = new URLSearchParams({
|
|
10
10
|
product_id: String(productId),
|
|
11
11
|
quantity: String(quantity),
|
|
12
12
|
unit_type_override: unitTypeOverride,
|
|
13
13
|
});
|
|
14
|
-
const result = await (0, client_1.requestEbag)(config, session,
|
|
15
|
-
method:
|
|
14
|
+
const result = await (0, client_1.requestEbag)(config, session, "/cart/add", {
|
|
15
|
+
method: "POST",
|
|
16
16
|
headers: {
|
|
17
|
-
|
|
17
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
18
18
|
origin: baseUrl,
|
|
19
19
|
referer: `${baseUrl}/search/`,
|
|
20
20
|
},
|
|
@@ -22,17 +22,17 @@ async function addToCart(config, session, productId, quantity, unitTypeOverride
|
|
|
22
22
|
});
|
|
23
23
|
return result.data;
|
|
24
24
|
}
|
|
25
|
-
async function updateCart(config, session, productId, quantity, unitTypeOverride =
|
|
26
|
-
const baseUrl = config.baseUrl ||
|
|
25
|
+
async function updateCart(config, session, productId, quantity, unitTypeOverride = "false") {
|
|
26
|
+
const baseUrl = config.baseUrl || "https://www.ebag.bg";
|
|
27
27
|
const body = new URLSearchParams({
|
|
28
28
|
product_id: String(productId),
|
|
29
29
|
quantity: String(quantity),
|
|
30
30
|
unit_type_override: unitTypeOverride,
|
|
31
31
|
});
|
|
32
|
-
const result = await (0, client_1.requestEbag)(config, session,
|
|
33
|
-
method:
|
|
32
|
+
const result = await (0, client_1.requestEbag)(config, session, "/cart/update", {
|
|
33
|
+
method: "POST",
|
|
34
34
|
headers: {
|
|
35
|
-
|
|
35
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
36
36
|
origin: baseUrl,
|
|
37
37
|
referer: `${baseUrl}/search/`,
|
|
38
38
|
},
|
|
@@ -41,6 +41,6 @@ async function updateCart(config, session, productId, quantity, unitTypeOverride
|
|
|
41
41
|
return result.data;
|
|
42
42
|
}
|
|
43
43
|
async function getCart(config, session) {
|
|
44
|
-
const result = await (0, client_1.requestEbag)(config, session,
|
|
44
|
+
const result = await (0, client_1.requestEbag)(config, session, "/cart/json");
|
|
45
45
|
return result.data;
|
|
46
46
|
}
|
package/dist/lib/client.d.ts
CHANGED
package/dist/lib/client.js
CHANGED
|
@@ -12,7 +12,7 @@ function normalizeHeaders(headers) {
|
|
|
12
12
|
function getCookieValue(cookies, name) {
|
|
13
13
|
if (!cookies)
|
|
14
14
|
return undefined;
|
|
15
|
-
const parts = cookies.split(
|
|
15
|
+
const parts = cookies.split(";").map((part) => part.trim());
|
|
16
16
|
for (const part of parts) {
|
|
17
17
|
if (part.startsWith(`${name}=`)) {
|
|
18
18
|
return part.slice(name.length + 1);
|
|
@@ -21,7 +21,7 @@ function getCookieValue(cookies, name) {
|
|
|
21
21
|
return undefined;
|
|
22
22
|
}
|
|
23
23
|
async function requestEbag(config, session, path, options = {}) {
|
|
24
|
-
const baseUrl = config.baseUrl ||
|
|
24
|
+
const baseUrl = config.baseUrl || "https://www.ebag.bg";
|
|
25
25
|
const url = new URL(path, baseUrl);
|
|
26
26
|
if (options.query) {
|
|
27
27
|
for (const [key, value] of Object.entries(options.query)) {
|
|
@@ -31,31 +31,37 @@ async function requestEbag(config, session, path, options = {}) {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
const headers = {
|
|
34
|
-
accept:
|
|
34
|
+
accept: "application/json, text/plain, */*",
|
|
35
35
|
...options.headers,
|
|
36
36
|
};
|
|
37
37
|
if (session.cookies) {
|
|
38
38
|
headers.cookie = session.cookies;
|
|
39
39
|
}
|
|
40
|
-
const method = (options.method ||
|
|
41
|
-
if (!headers[
|
|
42
|
-
const token = getCookieValue(session.cookies,
|
|
40
|
+
const method = (options.method || "GET").toUpperCase();
|
|
41
|
+
if (!headers["x-csrftoken"] && method !== "GET") {
|
|
42
|
+
const token = getCookieValue(session.cookies, "csrftoken");
|
|
43
43
|
if (token) {
|
|
44
|
-
headers[
|
|
44
|
+
headers["x-csrftoken"] = token;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
const response = await fetch(url.toString(), {
|
|
48
48
|
method,
|
|
49
49
|
headers,
|
|
50
|
-
body: options.body instanceof URLSearchParams
|
|
50
|
+
body: options.body instanceof URLSearchParams
|
|
51
|
+
? options.body.toString()
|
|
52
|
+
: options.body,
|
|
51
53
|
});
|
|
52
|
-
const contentType = response.headers.get(
|
|
54
|
+
const contentType = response.headers.get("content-type") || "";
|
|
53
55
|
const raw = await response.text();
|
|
54
|
-
const data = contentType.includes(
|
|
56
|
+
const data = contentType.includes("application/json")
|
|
57
|
+
? JSON.parse(raw)
|
|
58
|
+
: raw;
|
|
55
59
|
if (!response.ok) {
|
|
56
60
|
const err = new Error(`Request failed ${response.status} ${url}`);
|
|
57
61
|
err.status = response.status;
|
|
58
62
|
err.body = raw;
|
|
63
|
+
err.url = url.toString();
|
|
64
|
+
err.method = method;
|
|
59
65
|
throw err;
|
|
60
66
|
}
|
|
61
67
|
return {
|
|
@@ -65,27 +71,31 @@ async function requestEbag(config, session, path, options = {}) {
|
|
|
65
71
|
};
|
|
66
72
|
}
|
|
67
73
|
async function requestAlgolia(config, body) {
|
|
68
|
-
const host = config.algolia?.host ||
|
|
69
|
-
const appId = config.algolia?.appId ||
|
|
70
|
-
const apiKey = config.algolia?.apiKey ||
|
|
74
|
+
const host = config.algolia?.host || "jmjmdq9hhx-dsn.algolia.net";
|
|
75
|
+
const appId = config.algolia?.appId || "JMJMDQ9HHX";
|
|
76
|
+
const apiKey = config.algolia?.apiKey || "42ca9458d9354298c7016ce9155d8481";
|
|
71
77
|
const url = new URL(`/1/indexes/*/queries`, `https://${host}`);
|
|
72
|
-
url.searchParams.set(
|
|
78
|
+
url.searchParams.set("x-algolia-agent", "Algolia for JavaScript (4.24.0); Browser; instantsearch.js (4.80.0)");
|
|
73
79
|
const response = await fetch(url.toString(), {
|
|
74
|
-
method:
|
|
80
|
+
method: "POST",
|
|
75
81
|
headers: {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
"x-algolia-application-id": appId,
|
|
83
|
+
"x-algolia-api-key": apiKey,
|
|
84
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
79
85
|
},
|
|
80
86
|
body: JSON.stringify(body),
|
|
81
87
|
});
|
|
82
|
-
const contentType = response.headers.get(
|
|
88
|
+
const contentType = response.headers.get("content-type") || "";
|
|
83
89
|
const raw = await response.text();
|
|
84
|
-
const data = contentType.includes(
|
|
90
|
+
const data = contentType.includes("application/json")
|
|
91
|
+
? JSON.parse(raw)
|
|
92
|
+
: raw;
|
|
85
93
|
if (!response.ok) {
|
|
86
94
|
const err = new Error(`Algolia request failed ${response.status}`);
|
|
87
95
|
err.status = response.status;
|
|
88
96
|
err.body = raw;
|
|
97
|
+
err.url = url.toString();
|
|
98
|
+
err.method = "POST";
|
|
89
99
|
throw err;
|
|
90
100
|
}
|
|
91
101
|
return {
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { Cache, Config, Session } from
|
|
1
|
+
import type { Cache, Config, Session } from "./types";
|
|
2
2
|
export declare function getConfigDir(): string;
|
|
3
3
|
export declare function getConfigPath(): string;
|
|
4
4
|
export declare function getSessionPath(): string;
|
|
5
5
|
export declare function getCachePath(): string;
|
|
6
|
+
export declare function getLogPath(): string;
|
|
6
7
|
export declare function loadConfig(): Config;
|
|
7
8
|
export declare function saveConfig(config: Config): void;
|
|
8
9
|
export declare function loadSession(): Session;
|