@awadheshs109/billing 1.0.0

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 ADDED
@@ -0,0 +1,18 @@
1
+
2
+ ```
3
+ zentris-billing
4
+ ├─ examples
5
+ │ ├─ angular
6
+ │ ├─ javascript
7
+ │ ├─ node
8
+ │ └─ react
9
+ ├─ package-lock.json
10
+ ├─ package.json
11
+ ├─ src
12
+ │ ├─ constants
13
+ │ ├─ core
14
+ │ ├─ models
15
+ │ └─ utils
16
+ └─ tests
17
+
18
+ ```
@@ -0,0 +1,94 @@
1
+ declare function calculateGST(amount: number, percent: number): number;
2
+ declare function calculateTax(amount: number, taxRate: number): number;
3
+
4
+ declare function calculateDiscount(amount: number, percent: number): number;
5
+
6
+ type CurrencyType = 'INR' | 'USD' | 'EUR' | 'GBP';
7
+ declare function formatCurrency(amount: number, currency?: CurrencyType): string;
8
+
9
+ interface Customer {
10
+ id?: string;
11
+ name: string;
12
+ email: string;
13
+ phone?: string;
14
+ gstNumber?: string;
15
+ address?: string;
16
+ }
17
+
18
+ interface InvoiceItem {
19
+ name: string;
20
+ quantity: number;
21
+ price: number;
22
+ }
23
+
24
+ interface Invoice {
25
+ customer: Customer;
26
+ items: InvoiceItem[];
27
+ tax: number;
28
+ discount: number;
29
+ invoiceId?: string;
30
+ subtotal?: number;
31
+ taxAmount?: number;
32
+ discountAmount?: number;
33
+ total?: number;
34
+ generatedDate?: string;
35
+ }
36
+
37
+ declare function createInvoice(invoice: Invoice): {
38
+ invoiceId: string;
39
+ subtotal: number;
40
+ taxAmount: number;
41
+ discountAmount: number;
42
+ total: number;
43
+ generatedDate: string;
44
+ customer: Customer;
45
+ items: InvoiceItem[];
46
+ tax: number;
47
+ discount: number;
48
+ };
49
+
50
+ declare class Billing {
51
+ static calculateGST: typeof calculateGST;
52
+ static calculateTax: typeof calculateTax;
53
+ static calculateDiscount: typeof calculateDiscount;
54
+ static formatCurrency: typeof formatCurrency;
55
+ static createInvoice: typeof createInvoice;
56
+ }
57
+
58
+ declare class BillingError extends Error {
59
+ constructor(message: string);
60
+ }
61
+ declare class ValidationError extends Error {
62
+ constructor(message: string);
63
+ }
64
+ declare class InvoiceError extends Error {
65
+ constructor(message: string);
66
+ }
67
+
68
+ interface Tax {
69
+ name?: string;
70
+ rate: number;
71
+ }
72
+
73
+ interface BillingSummary {
74
+ subtotal: number;
75
+ taxAmount: number;
76
+ discountAmount: number;
77
+ total: number;
78
+ }
79
+
80
+ declare function formatDate(date?: Date, locale?: string): string;
81
+ declare function getCurrentTimestamp(): number;
82
+
83
+ declare function isValidEmail(email: string): boolean;
84
+ declare function isValidPhone(phone: string): boolean;
85
+ declare function isValidGST(gst: string): boolean;
86
+
87
+ declare const TAX_RATES: {
88
+ readonly GST_5: 5;
89
+ readonly GST_12: 12;
90
+ readonly GST_18: 18;
91
+ readonly GST_28: 28;
92
+ };
93
+
94
+ export { Billing, BillingError, type BillingSummary, type CurrencyType, type Customer, type Invoice, InvoiceError, type InvoiceItem, TAX_RATES, type Tax, ValidationError, calculateDiscount, calculateGST, calculateTax, createInvoice, formatCurrency, formatDate, getCurrentTimestamp, isValidEmail, isValidGST, isValidPhone };
@@ -0,0 +1,94 @@
1
+ declare function calculateGST(amount: number, percent: number): number;
2
+ declare function calculateTax(amount: number, taxRate: number): number;
3
+
4
+ declare function calculateDiscount(amount: number, percent: number): number;
5
+
6
+ type CurrencyType = 'INR' | 'USD' | 'EUR' | 'GBP';
7
+ declare function formatCurrency(amount: number, currency?: CurrencyType): string;
8
+
9
+ interface Customer {
10
+ id?: string;
11
+ name: string;
12
+ email: string;
13
+ phone?: string;
14
+ gstNumber?: string;
15
+ address?: string;
16
+ }
17
+
18
+ interface InvoiceItem {
19
+ name: string;
20
+ quantity: number;
21
+ price: number;
22
+ }
23
+
24
+ interface Invoice {
25
+ customer: Customer;
26
+ items: InvoiceItem[];
27
+ tax: number;
28
+ discount: number;
29
+ invoiceId?: string;
30
+ subtotal?: number;
31
+ taxAmount?: number;
32
+ discountAmount?: number;
33
+ total?: number;
34
+ generatedDate?: string;
35
+ }
36
+
37
+ declare function createInvoice(invoice: Invoice): {
38
+ invoiceId: string;
39
+ subtotal: number;
40
+ taxAmount: number;
41
+ discountAmount: number;
42
+ total: number;
43
+ generatedDate: string;
44
+ customer: Customer;
45
+ items: InvoiceItem[];
46
+ tax: number;
47
+ discount: number;
48
+ };
49
+
50
+ declare class Billing {
51
+ static calculateGST: typeof calculateGST;
52
+ static calculateTax: typeof calculateTax;
53
+ static calculateDiscount: typeof calculateDiscount;
54
+ static formatCurrency: typeof formatCurrency;
55
+ static createInvoice: typeof createInvoice;
56
+ }
57
+
58
+ declare class BillingError extends Error {
59
+ constructor(message: string);
60
+ }
61
+ declare class ValidationError extends Error {
62
+ constructor(message: string);
63
+ }
64
+ declare class InvoiceError extends Error {
65
+ constructor(message: string);
66
+ }
67
+
68
+ interface Tax {
69
+ name?: string;
70
+ rate: number;
71
+ }
72
+
73
+ interface BillingSummary {
74
+ subtotal: number;
75
+ taxAmount: number;
76
+ discountAmount: number;
77
+ total: number;
78
+ }
79
+
80
+ declare function formatDate(date?: Date, locale?: string): string;
81
+ declare function getCurrentTimestamp(): number;
82
+
83
+ declare function isValidEmail(email: string): boolean;
84
+ declare function isValidPhone(phone: string): boolean;
85
+ declare function isValidGST(gst: string): boolean;
86
+
87
+ declare const TAX_RATES: {
88
+ readonly GST_5: 5;
89
+ readonly GST_12: 12;
90
+ readonly GST_18: 18;
91
+ readonly GST_28: 28;
92
+ };
93
+
94
+ export { Billing, BillingError, type BillingSummary, type CurrencyType, type Customer, type Invoice, InvoiceError, type InvoiceItem, TAX_RATES, type Tax, ValidationError, calculateDiscount, calculateGST, calculateTax, createInvoice, formatCurrency, formatDate, getCurrentTimestamp, isValidEmail, isValidGST, isValidPhone };
package/dist/index.js ADDED
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Billing: () => Billing,
24
+ BillingError: () => BillingError,
25
+ InvoiceError: () => InvoiceError,
26
+ TAX_RATES: () => TAX_RATES,
27
+ ValidationError: () => ValidationError,
28
+ calculateDiscount: () => calculateDiscount,
29
+ calculateGST: () => calculateGST,
30
+ calculateTax: () => calculateTax,
31
+ createInvoice: () => createInvoice,
32
+ formatCurrency: () => formatCurrency,
33
+ formatDate: () => formatDate,
34
+ getCurrentTimestamp: () => getCurrentTimestamp,
35
+ isValidEmail: () => isValidEmail,
36
+ isValidGST: () => isValidGST,
37
+ isValidPhone: () => isValidPhone
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
40
+
41
+ // src/core/errors.ts
42
+ var BillingError = class extends Error {
43
+ constructor(message) {
44
+ super(message);
45
+ this.name = "BillingError";
46
+ }
47
+ };
48
+ var ValidationError = class extends Error {
49
+ constructor(message) {
50
+ super(message);
51
+ this.name = "ValidationError";
52
+ }
53
+ };
54
+ var InvoiceError = class extends Error {
55
+ constructor(message) {
56
+ super(message);
57
+ this.name = "InvoiceError";
58
+ }
59
+ };
60
+
61
+ // src/core/tax.ts
62
+ function calculateGST(amount, percent) {
63
+ if (amount < 0 || percent < 0) {
64
+ throw new BillingError(
65
+ "Amount and GST percentage cannot be negative"
66
+ );
67
+ }
68
+ return Number(
69
+ (amount * percent / 100).toFixed(2)
70
+ );
71
+ }
72
+ function calculateTax(amount, taxRate) {
73
+ if (amount < 0 || taxRate < 0) {
74
+ throw new BillingError(
75
+ "Amount and tax cannot be negative"
76
+ );
77
+ }
78
+ return Number(
79
+ (amount * taxRate / 100).toFixed(2)
80
+ );
81
+ }
82
+
83
+ // src/core/discount.ts
84
+ function calculateDiscount(amount, percent) {
85
+ if (amount < 0 || percent < 0) {
86
+ throw new BillingError(
87
+ "Invalid discount values"
88
+ );
89
+ }
90
+ return Number(
91
+ (amount * percent / 100).toFixed(2)
92
+ );
93
+ }
94
+
95
+ // src/core/currency.ts
96
+ var locales = {
97
+ INR: "en-IN",
98
+ USD: "en-US",
99
+ EUR: "de-DE",
100
+ GBP: "en-GB"
101
+ };
102
+ function formatCurrency(amount, currency = "INR") {
103
+ return new Intl.NumberFormat(
104
+ locales[currency],
105
+ {
106
+ style: "currency",
107
+ currency
108
+ }
109
+ ).format(amount);
110
+ }
111
+
112
+ // src/utils/validators.ts
113
+ function isValidEmail(email) {
114
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
115
+ }
116
+ function isValidPhone(phone) {
117
+ return /^[0-9]{10}$/.test(phone);
118
+ }
119
+ function isValidGST(gst) {
120
+ return /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/i.test(gst);
121
+ }
122
+
123
+ // src/core/invoice.ts
124
+ var invoiceCounter = 1;
125
+ function generateInvoiceId() {
126
+ const date = /* @__PURE__ */ new Date();
127
+ const yyyy = date.getFullYear();
128
+ const mm = String(
129
+ date.getMonth() + 1
130
+ ).padStart(2, "0");
131
+ const dd = String(
132
+ date.getDate()
133
+ ).padStart(2, "0");
134
+ const count = String(
135
+ invoiceCounter++
136
+ ).padStart(6, "0");
137
+ return `INV-${yyyy}${mm}${dd}-${count}`;
138
+ }
139
+ function validateItems(items) {
140
+ for (const item of items) {
141
+ if (item.quantity <= 0) {
142
+ throw new ValidationError(
143
+ `Invalid quantity for ${item.name}`
144
+ );
145
+ }
146
+ if (item.price < 0) {
147
+ throw new ValidationError(
148
+ `Invalid price for ${item.name}`
149
+ );
150
+ }
151
+ }
152
+ }
153
+ function createInvoice(invoice) {
154
+ if (!invoice.customer.name) {
155
+ throw new ValidationError(
156
+ "Customer name required"
157
+ );
158
+ }
159
+ if (!isValidEmail(
160
+ invoice.customer.email
161
+ )) {
162
+ throw new ValidationError(
163
+ "Invalid email"
164
+ );
165
+ }
166
+ if (!invoice.items || invoice.items.length === 0) {
167
+ throw new InvoiceError(
168
+ "Invoice cannot be empty"
169
+ );
170
+ }
171
+ validateItems(
172
+ invoice.items
173
+ );
174
+ const subtotal = invoice.items.reduce(
175
+ (sum, item) => {
176
+ return sum + item.price * item.quantity;
177
+ },
178
+ 0
179
+ );
180
+ const taxAmount = calculateTax(
181
+ subtotal,
182
+ invoice.tax
183
+ );
184
+ const discountAmount = calculateDiscount(
185
+ subtotal,
186
+ invoice.discount
187
+ );
188
+ const total = subtotal + taxAmount - discountAmount;
189
+ return {
190
+ ...invoice,
191
+ invoiceId: generateInvoiceId(),
192
+ subtotal,
193
+ taxAmount,
194
+ discountAmount,
195
+ total: Number(
196
+ total.toFixed(2)
197
+ ),
198
+ generatedDate: (/* @__PURE__ */ new Date()).toISOString()
199
+ };
200
+ }
201
+
202
+ // src/core/billing.ts
203
+ var Billing = class {
204
+ };
205
+ Billing.calculateGST = calculateGST;
206
+ Billing.calculateTax = calculateTax;
207
+ Billing.calculateDiscount = calculateDiscount;
208
+ Billing.formatCurrency = formatCurrency;
209
+ Billing.createInvoice = createInvoice;
210
+
211
+ // src/utils/date.ts
212
+ function formatDate(date = /* @__PURE__ */ new Date(), locale = "en-IN") {
213
+ return new Intl.DateTimeFormat(locale, {
214
+ year: "numeric",
215
+ month: "2-digit",
216
+ day: "2-digit"
217
+ }).format(date);
218
+ }
219
+ function getCurrentTimestamp() {
220
+ return Date.now();
221
+ }
222
+
223
+ // src/constants/tax-rates.ts
224
+ var TAX_RATES = {
225
+ GST_5: 5,
226
+ GST_12: 12,
227
+ GST_18: 18,
228
+ GST_28: 28
229
+ };
230
+ // Annotate the CommonJS export names for ESM import in node:
231
+ 0 && (module.exports = {
232
+ Billing,
233
+ BillingError,
234
+ InvoiceError,
235
+ TAX_RATES,
236
+ ValidationError,
237
+ calculateDiscount,
238
+ calculateGST,
239
+ calculateTax,
240
+ createInvoice,
241
+ formatCurrency,
242
+ formatDate,
243
+ getCurrentTimestamp,
244
+ isValidEmail,
245
+ isValidGST,
246
+ isValidPhone
247
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,206 @@
1
+ // src/core/errors.ts
2
+ var BillingError = class extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "BillingError";
6
+ }
7
+ };
8
+ var ValidationError = class extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "ValidationError";
12
+ }
13
+ };
14
+ var InvoiceError = class extends Error {
15
+ constructor(message) {
16
+ super(message);
17
+ this.name = "InvoiceError";
18
+ }
19
+ };
20
+
21
+ // src/core/tax.ts
22
+ function calculateGST(amount, percent) {
23
+ if (amount < 0 || percent < 0) {
24
+ throw new BillingError(
25
+ "Amount and GST percentage cannot be negative"
26
+ );
27
+ }
28
+ return Number(
29
+ (amount * percent / 100).toFixed(2)
30
+ );
31
+ }
32
+ function calculateTax(amount, taxRate) {
33
+ if (amount < 0 || taxRate < 0) {
34
+ throw new BillingError(
35
+ "Amount and tax cannot be negative"
36
+ );
37
+ }
38
+ return Number(
39
+ (amount * taxRate / 100).toFixed(2)
40
+ );
41
+ }
42
+
43
+ // src/core/discount.ts
44
+ function calculateDiscount(amount, percent) {
45
+ if (amount < 0 || percent < 0) {
46
+ throw new BillingError(
47
+ "Invalid discount values"
48
+ );
49
+ }
50
+ return Number(
51
+ (amount * percent / 100).toFixed(2)
52
+ );
53
+ }
54
+
55
+ // src/core/currency.ts
56
+ var locales = {
57
+ INR: "en-IN",
58
+ USD: "en-US",
59
+ EUR: "de-DE",
60
+ GBP: "en-GB"
61
+ };
62
+ function formatCurrency(amount, currency = "INR") {
63
+ return new Intl.NumberFormat(
64
+ locales[currency],
65
+ {
66
+ style: "currency",
67
+ currency
68
+ }
69
+ ).format(amount);
70
+ }
71
+
72
+ // src/utils/validators.ts
73
+ function isValidEmail(email) {
74
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
75
+ }
76
+ function isValidPhone(phone) {
77
+ return /^[0-9]{10}$/.test(phone);
78
+ }
79
+ function isValidGST(gst) {
80
+ return /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/i.test(gst);
81
+ }
82
+
83
+ // src/core/invoice.ts
84
+ var invoiceCounter = 1;
85
+ function generateInvoiceId() {
86
+ const date = /* @__PURE__ */ new Date();
87
+ const yyyy = date.getFullYear();
88
+ const mm = String(
89
+ date.getMonth() + 1
90
+ ).padStart(2, "0");
91
+ const dd = String(
92
+ date.getDate()
93
+ ).padStart(2, "0");
94
+ const count = String(
95
+ invoiceCounter++
96
+ ).padStart(6, "0");
97
+ return `INV-${yyyy}${mm}${dd}-${count}`;
98
+ }
99
+ function validateItems(items) {
100
+ for (const item of items) {
101
+ if (item.quantity <= 0) {
102
+ throw new ValidationError(
103
+ `Invalid quantity for ${item.name}`
104
+ );
105
+ }
106
+ if (item.price < 0) {
107
+ throw new ValidationError(
108
+ `Invalid price for ${item.name}`
109
+ );
110
+ }
111
+ }
112
+ }
113
+ function createInvoice(invoice) {
114
+ if (!invoice.customer.name) {
115
+ throw new ValidationError(
116
+ "Customer name required"
117
+ );
118
+ }
119
+ if (!isValidEmail(
120
+ invoice.customer.email
121
+ )) {
122
+ throw new ValidationError(
123
+ "Invalid email"
124
+ );
125
+ }
126
+ if (!invoice.items || invoice.items.length === 0) {
127
+ throw new InvoiceError(
128
+ "Invoice cannot be empty"
129
+ );
130
+ }
131
+ validateItems(
132
+ invoice.items
133
+ );
134
+ const subtotal = invoice.items.reduce(
135
+ (sum, item) => {
136
+ return sum + item.price * item.quantity;
137
+ },
138
+ 0
139
+ );
140
+ const taxAmount = calculateTax(
141
+ subtotal,
142
+ invoice.tax
143
+ );
144
+ const discountAmount = calculateDiscount(
145
+ subtotal,
146
+ invoice.discount
147
+ );
148
+ const total = subtotal + taxAmount - discountAmount;
149
+ return {
150
+ ...invoice,
151
+ invoiceId: generateInvoiceId(),
152
+ subtotal,
153
+ taxAmount,
154
+ discountAmount,
155
+ total: Number(
156
+ total.toFixed(2)
157
+ ),
158
+ generatedDate: (/* @__PURE__ */ new Date()).toISOString()
159
+ };
160
+ }
161
+
162
+ // src/core/billing.ts
163
+ var Billing = class {
164
+ };
165
+ Billing.calculateGST = calculateGST;
166
+ Billing.calculateTax = calculateTax;
167
+ Billing.calculateDiscount = calculateDiscount;
168
+ Billing.formatCurrency = formatCurrency;
169
+ Billing.createInvoice = createInvoice;
170
+
171
+ // src/utils/date.ts
172
+ function formatDate(date = /* @__PURE__ */ new Date(), locale = "en-IN") {
173
+ return new Intl.DateTimeFormat(locale, {
174
+ year: "numeric",
175
+ month: "2-digit",
176
+ day: "2-digit"
177
+ }).format(date);
178
+ }
179
+ function getCurrentTimestamp() {
180
+ return Date.now();
181
+ }
182
+
183
+ // src/constants/tax-rates.ts
184
+ var TAX_RATES = {
185
+ GST_5: 5,
186
+ GST_12: 12,
187
+ GST_18: 18,
188
+ GST_28: 28
189
+ };
190
+ export {
191
+ Billing,
192
+ BillingError,
193
+ InvoiceError,
194
+ TAX_RATES,
195
+ ValidationError,
196
+ calculateDiscount,
197
+ calculateGST,
198
+ calculateTax,
199
+ createInvoice,
200
+ formatCurrency,
201
+ formatDate,
202
+ getCurrentTimestamp,
203
+ isValidEmail,
204
+ isValidGST,
205
+ isValidPhone
206
+ };
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@awadheshs109/billing",
3
+ "version": "1.0.0",
4
+ "description": "Framework-independent TypeScript billing library for Angular, React, Vue, Node.js and JavaScript projects",
5
+ "author": "Awadhesh Sharma",
6
+ "license": "MIT",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "sideEffects": false,
21
+ "scripts": {
22
+ "build": "tsup src/index.ts --format cjs,esm --dts",
23
+ "dev": "tsup src/index.ts --watch",
24
+ "test": "vitest",
25
+ "test:run": "vitest run",
26
+ "lint": "eslint ."
27
+ },
28
+ "keywords": [
29
+ "billing",
30
+ "invoice",
31
+ "gst",
32
+ "tax",
33
+ "typescript",
34
+ "javascript",
35
+ "react",
36
+ "angular",
37
+ "vue",
38
+ "nodejs"
39
+ ],
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/Awadheshs109/zentris-billing.git"
43
+ },
44
+ "bugs": {
45
+ "url": "https://github.com/Awadheshs109/zentris-billing/issues"
46
+ },
47
+ "homepage": "https://github.com/Awadheshs109",
48
+ "devDependencies": {
49
+ "@types/node": "^25.9.1",
50
+ "eslint": "^10.4.0",
51
+ "tsup": "^8.5.1",
52
+ "tsx": "^4.22.3",
53
+ "typescript": "^6.0.3",
54
+ "vitest": "^4.1.7"
55
+ }
56
+ }