@hasna/invoices 0.1.3 → 0.1.4

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
@@ -2088,6 +2088,11 @@ function normalizePagination(options, defaults) {
2088
2088
  const offset = Number.isFinite(options.offset) ? Math.max(Math.trunc(options.offset), 0) : 0;
2089
2089
  return { limit, offset };
2090
2090
  }
2091
+ function assertInvoiceStatus(status) {
2092
+ if (!INVOICE_STATUSES.has(status)) {
2093
+ throw new RangeError(`Invalid invoice status: ${String(status)}`);
2094
+ }
2095
+ }
2091
2096
  function assertSafeCents(value, field) {
2092
2097
  if (!Number.isSafeInteger(value) || value < 0) {
2093
2098
  throw new RangeError(`${field} must be a safe nonnegative integer`);
@@ -2267,12 +2272,14 @@ function getInvoiceById(db, id) {
2267
2272
  }
2268
2273
  function listInvoices(db, options = {}) {
2269
2274
  const { limit, offset } = normalizePagination(options, { limit: 50 });
2270
- if (options.status) {
2275
+ if (options.status !== undefined) {
2276
+ assertInvoiceStatus(options.status);
2271
2277
  return db.query("SELECT * FROM invoices WHERE status = ?1 ORDER BY issued_at DESC, created_at DESC LIMIT ?2 OFFSET ?3").all(options.status, limit, offset).map(mapInvoiceRow);
2272
2278
  }
2273
2279
  return db.query("SELECT * FROM invoices ORDER BY issued_at DESC, created_at DESC LIMIT ?1 OFFSET ?2").all(limit, offset).map(mapInvoiceRow);
2274
2280
  }
2275
2281
  function updateInvoiceStatus(db, id, status) {
2282
+ assertInvoiceStatus(status);
2276
2283
  db.query("UPDATE invoices SET status = ?2, updated_at = datetime('now') WHERE id = ?1").run(id, status);
2277
2284
  const row = db.query("SELECT * FROM invoices WHERE id = ?1").get(id);
2278
2285
  return row ? mapInvoiceRow(row) : null;
@@ -2280,7 +2287,8 @@ function updateInvoiceStatus(db, id, status) {
2280
2287
  function searchInvoices(db, query, options = {}) {
2281
2288
  const { limit, offset } = normalizePagination(options, { limit: 20 });
2282
2289
  const escapedPhrase = `"${query.replace(/"/g, '""')}"`;
2283
- if (options.status) {
2290
+ if (options.status !== undefined) {
2291
+ assertInvoiceStatus(options.status);
2284
2292
  return db.query(`
2285
2293
  SELECT i.*
2286
2294
  FROM invoices_fts f
@@ -2302,7 +2310,10 @@ LIMIT ?2
2302
2310
  OFFSET ?3
2303
2311
  `).all(escapedPhrase, limit, offset).map(mapInvoiceRow);
2304
2312
  }
2305
- var init_invoices = () => {};
2313
+ var INVOICE_STATUSES;
2314
+ var init_invoices = __esm(() => {
2315
+ INVOICE_STATUSES = new Set(["draft", "sent", "partially_paid", "paid", "void", "overdue"]);
2316
+ });
2306
2317
 
2307
2318
  // src/db/database.ts
2308
2319
  import { mkdirSync } from "fs";
@@ -2471,7 +2482,7 @@ function listAgents(db) {
2471
2482
  }
2472
2483
 
2473
2484
  // src/lib/version.ts
2474
- var VERSION = "0.0.1";
2485
+ var VERSION = "0.1.4";
2475
2486
 
2476
2487
  // src/cli/index.ts
2477
2488
  init_database();
@@ -1 +1 @@
1
- {"version":3,"file":"invoices.d.ts","sourceRoot":"","sources":["../../src/db/invoices.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"invoices.d.ts","sourceRoot":"","sources":["../../src/db/invoices.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // src/lib/version.ts
3
- var VERSION = "0.0.1";
3
+ var VERSION = "0.1.4";
4
4
  // src/db/database.ts
5
5
  import { mkdirSync } from "fs";
6
6
  import { dirname, join } from "path";
@@ -205,11 +205,17 @@ function migrateDatabase(options = {}) {
205
205
  }
206
206
  // src/db/invoices.ts
207
207
  import { randomUUID } from "crypto";
208
+ var INVOICE_STATUSES = new Set(["draft", "sent", "partially_paid", "paid", "void", "overdue"]);
208
209
  function normalizePagination(options, defaults) {
209
210
  const limit = Number.isFinite(options.limit) ? Math.max(Math.trunc(options.limit), 0) : defaults.limit;
210
211
  const offset = Number.isFinite(options.offset) ? Math.max(Math.trunc(options.offset), 0) : 0;
211
212
  return { limit, offset };
212
213
  }
214
+ function assertInvoiceStatus(status) {
215
+ if (!INVOICE_STATUSES.has(status)) {
216
+ throw new RangeError(`Invalid invoice status: ${String(status)}`);
217
+ }
218
+ }
213
219
  function assertSafeCents(value, field) {
214
220
  if (!Number.isSafeInteger(value) || value < 0) {
215
221
  throw new RangeError(`${field} must be a safe nonnegative integer`);
@@ -402,12 +408,14 @@ function getInvoiceById(db, id) {
402
408
  }
403
409
  function listInvoices(db, options = {}) {
404
410
  const { limit, offset } = normalizePagination(options, { limit: 50 });
405
- if (options.status) {
411
+ if (options.status !== undefined) {
412
+ assertInvoiceStatus(options.status);
406
413
  return db.query("SELECT * FROM invoices WHERE status = ?1 ORDER BY issued_at DESC, created_at DESC LIMIT ?2 OFFSET ?3").all(options.status, limit, offset).map(mapInvoiceRow);
407
414
  }
408
415
  return db.query("SELECT * FROM invoices ORDER BY issued_at DESC, created_at DESC LIMIT ?1 OFFSET ?2").all(limit, offset).map(mapInvoiceRow);
409
416
  }
410
417
  function updateInvoiceStatus(db, id, status) {
418
+ assertInvoiceStatus(status);
411
419
  db.query("UPDATE invoices SET status = ?2, updated_at = datetime('now') WHERE id = ?1").run(id, status);
412
420
  const row = db.query("SELECT * FROM invoices WHERE id = ?1").get(id);
413
421
  return row ? mapInvoiceRow(row) : null;
@@ -432,7 +440,8 @@ FROM invoices i;
432
440
  function searchInvoices(db, query, options = {}) {
433
441
  const { limit, offset } = normalizePagination(options, { limit: 20 });
434
442
  const escapedPhrase = `"${query.replace(/"/g, '""')}"`;
435
- if (options.status) {
443
+ if (options.status !== undefined) {
444
+ assertInvoiceStatus(options.status);
436
445
  return db.query(`
437
446
  SELECT i.*
438
447
  FROM invoices_fts f
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.0.1";
1
+ export declare const VERSION = "0.1.4";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/mcp/index.js CHANGED
@@ -4201,11 +4201,17 @@ function migrateDatabase(options = {}) {
4201
4201
 
4202
4202
  // src/db/invoices.ts
4203
4203
  import { randomUUID } from "crypto";
4204
+ var INVOICE_STATUSES = new Set(["draft", "sent", "partially_paid", "paid", "void", "overdue"]);
4204
4205
  function normalizePagination(options, defaults) {
4205
4206
  const limit = Number.isFinite(options.limit) ? Math.max(Math.trunc(options.limit), 0) : defaults.limit;
4206
4207
  const offset = Number.isFinite(options.offset) ? Math.max(Math.trunc(options.offset), 0) : 0;
4207
4208
  return { limit, offset };
4208
4209
  }
4210
+ function assertInvoiceStatus(status) {
4211
+ if (!INVOICE_STATUSES.has(status)) {
4212
+ throw new RangeError(`Invalid invoice status: ${String(status)}`);
4213
+ }
4214
+ }
4209
4215
  function assertSafeCents(value, field) {
4210
4216
  if (!Number.isSafeInteger(value) || value < 0) {
4211
4217
  throw new RangeError(`${field} must be a safe nonnegative integer`);
@@ -4385,12 +4391,14 @@ function getInvoiceById(db, id) {
4385
4391
  }
4386
4392
  function listInvoices(db, options = {}) {
4387
4393
  const { limit, offset } = normalizePagination(options, { limit: 50 });
4388
- if (options.status) {
4394
+ if (options.status !== undefined) {
4395
+ assertInvoiceStatus(options.status);
4389
4396
  return db.query("SELECT * FROM invoices WHERE status = ?1 ORDER BY issued_at DESC, created_at DESC LIMIT ?2 OFFSET ?3").all(options.status, limit, offset).map(mapInvoiceRow);
4390
4397
  }
4391
4398
  return db.query("SELECT * FROM invoices ORDER BY issued_at DESC, created_at DESC LIMIT ?1 OFFSET ?2").all(limit, offset).map(mapInvoiceRow);
4392
4399
  }
4393
4400
  function updateInvoiceStatus(db, id, status) {
4401
+ assertInvoiceStatus(status);
4394
4402
  db.query("UPDATE invoices SET status = ?2, updated_at = datetime('now') WHERE id = ?1").run(id, status);
4395
4403
  const row = db.query("SELECT * FROM invoices WHERE id = ?1").get(id);
4396
4404
  return row ? mapInvoiceRow(row) : null;
@@ -4402,7 +4410,8 @@ function deleteInvoice(db, id) {
4402
4410
  function searchInvoices(db, query, options = {}) {
4403
4411
  const { limit, offset } = normalizePagination(options, { limit: 20 });
4404
4412
  const escapedPhrase = `"${query.replace(/"/g, '""')}"`;
4405
- if (options.status) {
4413
+ if (options.status !== undefined) {
4414
+ assertInvoiceStatus(options.status);
4406
4415
  return db.query(`
4407
4416
  SELECT i.*
4408
4417
  FROM invoices_fts f
@@ -4009,11 +4009,17 @@ function openInvoiceDatabase(options = {}) {
4009
4009
 
4010
4010
  // src/db/invoices.ts
4011
4011
  import { randomUUID } from "crypto";
4012
+ var INVOICE_STATUSES = new Set(["draft", "sent", "partially_paid", "paid", "void", "overdue"]);
4012
4013
  function normalizePagination(options, defaults) {
4013
4014
  const limit = Number.isFinite(options.limit) ? Math.max(Math.trunc(options.limit), 0) : defaults.limit;
4014
4015
  const offset = Number.isFinite(options.offset) ? Math.max(Math.trunc(options.offset), 0) : 0;
4015
4016
  return { limit, offset };
4016
4017
  }
4018
+ function assertInvoiceStatus(status) {
4019
+ if (!INVOICE_STATUSES.has(status)) {
4020
+ throw new RangeError(`Invalid invoice status: ${String(status)}`);
4021
+ }
4022
+ }
4017
4023
  function assertSafeCents(value, field) {
4018
4024
  if (!Number.isSafeInteger(value) || value < 0) {
4019
4025
  throw new RangeError(`${field} must be a safe nonnegative integer`);
@@ -4193,12 +4199,14 @@ function getInvoiceById(db, id) {
4193
4199
  }
4194
4200
  function listInvoices(db, options = {}) {
4195
4201
  const { limit, offset } = normalizePagination(options, { limit: 50 });
4196
- if (options.status) {
4202
+ if (options.status !== undefined) {
4203
+ assertInvoiceStatus(options.status);
4197
4204
  return db.query("SELECT * FROM invoices WHERE status = ?1 ORDER BY issued_at DESC, created_at DESC LIMIT ?2 OFFSET ?3").all(options.status, limit, offset).map(mapInvoiceRow);
4198
4205
  }
4199
4206
  return db.query("SELECT * FROM invoices ORDER BY issued_at DESC, created_at DESC LIMIT ?1 OFFSET ?2").all(limit, offset).map(mapInvoiceRow);
4200
4207
  }
4201
4208
  function updateInvoiceStatus(db, id, status) {
4209
+ assertInvoiceStatus(status);
4202
4210
  db.query("UPDATE invoices SET status = ?2, updated_at = datetime('now') WHERE id = ?1").run(id, status);
4203
4211
  const row = db.query("SELECT * FROM invoices WHERE id = ?1").get(id);
4204
4212
  return row ? mapInvoiceRow(row) : null;
@@ -4206,7 +4214,8 @@ function updateInvoiceStatus(db, id, status) {
4206
4214
  function searchInvoices(db, query, options = {}) {
4207
4215
  const { limit, offset } = normalizePagination(options, { limit: 20 });
4208
4216
  const escapedPhrase = `"${query.replace(/"/g, '""')}"`;
4209
- if (options.status) {
4217
+ if (options.status !== undefined) {
4218
+ assertInvoiceStatus(options.status);
4210
4219
  return db.query(`
4211
4220
  SELECT i.*
4212
4221
  FROM invoices_fts f
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/invoices",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Invoice generation and management for AI agents - CLI + MCP server + REST API + dashboard + SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",