@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 +15 -4
- package/dist/db/invoices.d.ts.map +1 -1
- package/dist/index.js +12 -3
- package/dist/lib/version.d.ts +1 -1
- package/dist/mcp/index.js +11 -2
- package/dist/server/index.js +11 -2
- package/package.json +1 -1
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
|
|
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.
|
|
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":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;
|
|
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.
|
|
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
|
package/dist/lib/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
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
|
package/dist/server/index.js
CHANGED
|
@@ -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
|