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/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, '../../package.json');
41
- const raw = node_fs_1.default.readFileSync(packagePath, 'utf8');
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 || 'unknown';
47
+ return parsed.version || "unknown";
44
48
  }
45
49
  catch {
46
- return 'unknown';
50
+ return "unknown";
47
51
  }
48
52
  }
49
53
  program
50
- .name('ebag')
51
- .description('CLI for interacting with ebag.bg')
52
- .version(getPackageVersion(), '-v, --version', 'Show CLI version')
53
- .option('--json', 'Output JSON');
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('login')
56
- .description('Store session cookie and validate it')
57
- .option('--cookie <cookie>', 'Cookie header value from browser')
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('Session validated but no user email was returned.');
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: 'ok', user, email });
123
+ (0, format_1.outputJson)({ status: "ok", user, email });
89
124
  }
90
125
  else {
91
- process.stdout.write('Login session validated and saved.\n');
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: 'error', message: err.message });
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('status')
106
- .description('Show current login status')
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: 'logged_out' });
148
+ (0, format_1.outputJson)({ status: "logged_out" });
114
149
  }
115
150
  else {
116
- process.stdout.write('Logged out (no session cookie).\n');
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 || user.username;
157
+ const email = user.email ||
158
+ user.username;
123
159
  if (json) {
124
- (0, format_1.outputJson)({ status: 'logged_in', user, email });
160
+ (0, format_1.outputJson)({ status: "logged_in", user, email });
125
161
  }
126
162
  else {
127
- process.stdout.write('Logged in.\n');
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: 'logged_out' });
173
+ (0, format_1.outputJson)({ status: "logged_out" });
138
174
  }
139
175
  else {
140
- process.stdout.write('Logged out.\n');
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('slots')
149
- .description('Show the next available delivery slots')
150
- .option('--limit <n>', 'Limit number of slots', '10')
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('No available delivery slots.\n');
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 ? '\n' : '';
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
- .command('search')
194
- .description('Search for products')
195
- .argument('<query>', 'Search query')
196
- .option('--limit <n>', 'Limit number of results', '20')
197
- .option('--page <n>', 'Algolia page number (0-based)', '0')
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, { limit, page });
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
- program
213
- .command('product')
214
- .description('Get product details by ID')
215
- .argument('<productId>', 'Product ID')
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('order').description('Order operations');
268
+ const order = program.command("order").description("Order operations");
229
269
  order
230
- .command('list')
231
- .description('List recent orders')
232
- .option('--limit <n>', 'Limit number of results', '10')
233
- .option('--page <n>', 'Page number')
234
- .option('--from <date>', 'Filter from date (YYYY-MM-DD)')
235
- .option('--to <date>', 'Filter to date (YYYY-MM-DD)')
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('No orders found.\n');
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('show')
262
- .description('Show order details')
263
- .argument('<orderId>', 'Order ID')
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('cart').description('Cart operations');
316
+ const cart = program.command("cart").description("Cart operations");
277
317
  cart
278
- .command('add')
279
- .argument('<productId>', 'Product ID')
280
- .option('--qty <n>', 'Quantity', '1')
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('Added to cart.\n');
331
+ process.stdout.write("Added to cart.\n");
292
332
  }
293
333
  });
294
334
  cart
295
- .command('update')
296
- .argument('<productId>', 'Product ID')
297
- .option('--qty <n>', 'Quantity', '1')
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('Cart updated.\n');
348
+ process.stdout.write("Cart updated.\n");
309
349
  }
310
350
  });
311
351
  cart
312
- .command('show')
313
- .description('Show cart contents')
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 ?? entry.product_id ?? entry.productId ?? entry.id;
330
- const name = entry.product?.name ?? entry.name ?? 'Unknown';
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('Cart is empty.\n');
384
+ process.stdout.write("Cart is empty.\n");
342
385
  }
343
386
  });
344
- const list = program.command('list').description('List operations');
387
+ const list = program.command("list").description("List operations");
345
388
  list
346
- .command('show')
347
- .description('Show your lists')
348
- .argument('[listId]', 'List ID')
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 === 'number'
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(' - empty\n');
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 ?? 'Unknown';
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('add')
410
- .argument('<listId>', 'List ID')
411
- .argument('<productId>', 'Product ID')
412
- .option('--qty <n>', 'Quantity', '1')
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('Added to list.\n');
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: 'error', ...formatError(err) });
491
+ (0, format_1.outputJson)({ status: "error", ...formatError(err) });
433
492
  }
434
493
  else {
435
494
  const details = formatError(err);
@@ -1,3 +1,3 @@
1
- import type { Config, Session } from './types';
1
+ import type { Config, Session } from "./types";
2
2
  export declare function getLoginInstructions(): string;
3
3
  export declare function validateSession(config: Config, session: Session): Promise<unknown>;
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
- '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).',
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('\n');
12
+ ].join("\n");
13
13
  }
14
14
  async function validateSession(config, session) {
15
- const result = await (0, client_1.requestEbag)(config, session, '/user/json');
15
+ const result = await (0, client_1.requestEbag)(config, session, "/user/json");
16
16
  return result.data;
17
17
  }
@@ -1,4 +1,4 @@
1
- import type { Config, Session } from './types';
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 = 'false') {
8
- const baseUrl = config.baseUrl || 'https://www.ebag.bg';
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, '/cart/add', {
15
- method: 'POST',
14
+ const result = await (0, client_1.requestEbag)(config, session, "/cart/add", {
15
+ method: "POST",
16
16
  headers: {
17
- 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
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 = 'false') {
26
- const baseUrl = config.baseUrl || 'https://www.ebag.bg';
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, '/cart/update', {
33
- method: 'POST',
32
+ const result = await (0, client_1.requestEbag)(config, session, "/cart/update", {
33
+ method: "POST",
34
34
  headers: {
35
- 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
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, '/cart/json');
44
+ const result = await (0, client_1.requestEbag)(config, session, "/cart/json");
45
45
  return result.data;
46
46
  }
@@ -1,4 +1,4 @@
1
- import type { Config, Session } from './types';
1
+ import type { Config, Session } from "./types";
2
2
  export type RequestResult<T> = {
3
3
  status: number;
4
4
  data: T;
@@ -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(';').map((part) => part.trim());
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 || 'https://www.ebag.bg';
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: 'application/json, text/plain, */*',
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 || 'GET').toUpperCase();
41
- if (!headers['x-csrftoken'] && method !== 'GET') {
42
- const token = getCookieValue(session.cookies, 'csrftoken');
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['x-csrftoken'] = token;
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 ? options.body.toString() : options.body,
50
+ body: options.body instanceof URLSearchParams
51
+ ? options.body.toString()
52
+ : options.body,
51
53
  });
52
- const contentType = response.headers.get('content-type') || '';
54
+ const contentType = response.headers.get("content-type") || "";
53
55
  const raw = await response.text();
54
- const data = contentType.includes('application/json') ? JSON.parse(raw) : raw;
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 || 'jmjmdq9hhx-dsn.algolia.net';
69
- const appId = config.algolia?.appId || 'JMJMDQ9HHX';
70
- const apiKey = config.algolia?.apiKey || '42ca9458d9354298c7016ce9155d8481';
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('x-algolia-agent', 'Algolia for JavaScript (4.24.0); Browser; instantsearch.js (4.80.0)');
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: 'POST',
80
+ method: "POST",
75
81
  headers: {
76
- 'x-algolia-application-id': appId,
77
- 'x-algolia-api-key': apiKey,
78
- 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
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('content-type') || '';
88
+ const contentType = response.headers.get("content-type") || "";
83
89
  const raw = await response.text();
84
- const data = contentType.includes('application/json') ? JSON.parse(raw) : raw;
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 {
@@ -1,8 +1,9 @@
1
- import type { Cache, Config, Session } from './types';
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;