@infuro/cms-core 1.0.4 → 1.0.6

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/index.js CHANGED
@@ -119,6 +119,114 @@ This link expires in 1 hour.`
119
119
  }
120
120
  });
121
121
 
122
+ // src/plugins/payment/stripe.ts
123
+ var stripe_exports = {};
124
+ __export(stripe_exports, {
125
+ StripePaymentService: () => StripePaymentService
126
+ });
127
+ import Stripe from "stripe";
128
+ var StripePaymentService;
129
+ var init_stripe = __esm({
130
+ "src/plugins/payment/stripe.ts"() {
131
+ "use strict";
132
+ StripePaymentService = class {
133
+ stripe;
134
+ webhookSecret;
135
+ constructor(config) {
136
+ this.stripe = new Stripe(config.secretKey, { apiVersion: "2024-06-20" });
137
+ this.webhookSecret = config.webhookSecret;
138
+ }
139
+ async createPaymentIntent(amount, currency, metadata) {
140
+ const intent = await this.stripe.paymentIntents.create({
141
+ amount: Math.round(amount * 100),
142
+ currency: currency.toLowerCase(),
143
+ metadata
144
+ });
145
+ return {
146
+ id: intent.id,
147
+ clientSecret: intent.client_secret || "",
148
+ amount,
149
+ currency,
150
+ status: intent.status
151
+ };
152
+ }
153
+ async capturePayment(paymentId, amount) {
154
+ try {
155
+ await this.stripe.paymentIntents.capture(paymentId, {
156
+ amount_to_capture: amount ? Math.round(amount * 100) : void 0
157
+ });
158
+ return true;
159
+ } catch {
160
+ return false;
161
+ }
162
+ }
163
+ verifyWebhookSignature(payload, signature) {
164
+ if (!this.webhookSecret) return false;
165
+ try {
166
+ this.stripe.webhooks.constructEvent(payload, signature, this.webhookSecret);
167
+ return true;
168
+ } catch {
169
+ return false;
170
+ }
171
+ }
172
+ };
173
+ }
174
+ });
175
+
176
+ // src/plugins/payment/razorpay.ts
177
+ var razorpay_exports = {};
178
+ __export(razorpay_exports, {
179
+ RazorpayPaymentService: () => RazorpayPaymentService
180
+ });
181
+ import Razorpay from "razorpay";
182
+ import crypto from "crypto";
183
+ var RazorpayPaymentService;
184
+ var init_razorpay = __esm({
185
+ "src/plugins/payment/razorpay.ts"() {
186
+ "use strict";
187
+ RazorpayPaymentService = class {
188
+ razorpay;
189
+ keySecret;
190
+ webhookSecret;
191
+ constructor(config) {
192
+ this.razorpay = new Razorpay({
193
+ key_id: config.keyId,
194
+ key_secret: config.keySecret
195
+ });
196
+ this.keySecret = config.keySecret;
197
+ this.webhookSecret = config.webhookSecret;
198
+ }
199
+ async createPaymentIntent(amount, currency, metadata) {
200
+ const order = await this.razorpay.orders.create({
201
+ amount: Math.round(amount * 100),
202
+ currency: currency.toUpperCase(),
203
+ notes: metadata
204
+ });
205
+ return {
206
+ id: order.id,
207
+ clientSecret: order.id,
208
+ amount,
209
+ currency,
210
+ status: order.status
211
+ };
212
+ }
213
+ async capturePayment(paymentId, amount) {
214
+ try {
215
+ await this.razorpay.payments.capture(paymentId, amount ? Math.round(amount * 100) : 0, "INR");
216
+ return true;
217
+ } catch {
218
+ return false;
219
+ }
220
+ }
221
+ verifyWebhookSignature(payload, signature) {
222
+ const secret = this.webhookSecret || this.keySecret;
223
+ const expectedSignature = crypto.createHmac("sha256", secret).update(typeof payload === "string" ? payload : payload.toString("utf8")).digest("hex");
224
+ return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature));
225
+ }
226
+ };
227
+ }
228
+ });
229
+
122
230
  // src/plugins/registry.ts
123
231
  var noopLogger = {
124
232
  info: () => {
@@ -547,12 +655,39 @@ function smsPlugin(_config = {}) {
547
655
  }
548
656
 
549
657
  // src/plugins/payment/index.ts
550
- function paymentPlugin(_config = {}) {
658
+ function paymentPlugin(config) {
551
659
  return {
552
660
  name: "payment",
553
661
  version: "1.0.0",
554
- async init() {
555
- return null;
662
+ async init(context) {
663
+ if (config.provider === "stripe") {
664
+ const { StripePaymentService: StripePaymentService2 } = await Promise.resolve().then(() => (init_stripe(), stripe_exports));
665
+ const secretKey = config.secretKey || context.config.STRIPE_SECRET_KEY;
666
+ if (!secretKey) {
667
+ context.logger.warn("Payment plugin skipped: Stripe secret key not configured");
668
+ return void 0;
669
+ }
670
+ return new StripePaymentService2({
671
+ secretKey,
672
+ webhookSecret: config.webhookSecret || context.config.STRIPE_WEBHOOK_SECRET
673
+ });
674
+ }
675
+ if (config.provider === "razorpay") {
676
+ const { RazorpayPaymentService: RazorpayPaymentService2 } = await Promise.resolve().then(() => (init_razorpay(), razorpay_exports));
677
+ const keyId = config.keyId || context.config.RAZORPAY_KEY_ID;
678
+ const keySecret = config.keySecret || context.config.RAZORPAY_KEY_SECRET;
679
+ if (!keyId || !keySecret) {
680
+ context.logger.warn("Payment plugin skipped: Razorpay credentials not configured");
681
+ return void 0;
682
+ }
683
+ return new RazorpayPaymentService2({
684
+ keyId,
685
+ keySecret,
686
+ webhookSecret: config.webhookSecret || context.config.RAZORPAY_WEBHOOK_SECRET
687
+ });
688
+ }
689
+ context.logger.warn(`Payment plugin skipped: unknown provider "${config.provider}"`);
690
+ return void 0;
556
691
  }
557
692
  };
558
693
  }
@@ -927,7 +1062,7 @@ __decorateClass([
927
1062
  PrimaryGeneratedColumn5()
928
1063
  ], Category.prototype, "id", 2);
929
1064
  __decorateClass([
930
- Column5("varchar")
1065
+ Column5("varchar", { unique: true })
931
1066
  ], Category.prototype, "name", 2);
932
1067
  __decorateClass([
933
1068
  Column5({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
@@ -1239,7 +1374,7 @@ Blog = __decorateClass([
1239
1374
  ], Blog);
1240
1375
 
1241
1376
  // src/entities/contact.entity.ts
1242
- import { Entity as Entity13, PrimaryGeneratedColumn as PrimaryGeneratedColumn13, Column as Column13, OneToMany as OneToMany6 } from "typeorm";
1377
+ import { Entity as Entity16, PrimaryGeneratedColumn as PrimaryGeneratedColumn16, Column as Column16, OneToMany as OneToMany7 } from "typeorm";
1243
1378
 
1244
1379
  // src/entities/form-submission.entity.ts
1245
1380
  import { Entity as Entity12, PrimaryGeneratedColumn as PrimaryGeneratedColumn12, Column as Column12, ManyToOne as ManyToOne6, JoinColumn as JoinColumn6 } from "typeorm";
@@ -1448,12 +1583,266 @@ FormSubmission = __decorateClass([
1448
1583
  Entity12("form_submissions")
1449
1584
  ], FormSubmission);
1450
1585
 
1586
+ // src/entities/address.entity.ts
1587
+ import { Entity as Entity13, PrimaryGeneratedColumn as PrimaryGeneratedColumn13, Column as Column13, ManyToOne as ManyToOne7, JoinColumn as JoinColumn7 } from "typeorm";
1588
+ var Address = class {
1589
+ id;
1590
+ contactId;
1591
+ tag;
1592
+ line1;
1593
+ line2;
1594
+ city;
1595
+ state;
1596
+ postalCode;
1597
+ country;
1598
+ createdAt;
1599
+ updatedAt;
1600
+ contact;
1601
+ };
1602
+ __decorateClass([
1603
+ PrimaryGeneratedColumn13()
1604
+ ], Address.prototype, "id", 2);
1605
+ __decorateClass([
1606
+ Column13("int")
1607
+ ], Address.prototype, "contactId", 2);
1608
+ __decorateClass([
1609
+ Column13("varchar", { nullable: true })
1610
+ ], Address.prototype, "tag", 2);
1611
+ __decorateClass([
1612
+ Column13("varchar", { nullable: true })
1613
+ ], Address.prototype, "line1", 2);
1614
+ __decorateClass([
1615
+ Column13("varchar", { nullable: true })
1616
+ ], Address.prototype, "line2", 2);
1617
+ __decorateClass([
1618
+ Column13("varchar", { nullable: true })
1619
+ ], Address.prototype, "city", 2);
1620
+ __decorateClass([
1621
+ Column13("varchar", { nullable: true })
1622
+ ], Address.prototype, "state", 2);
1623
+ __decorateClass([
1624
+ Column13("varchar", { nullable: true })
1625
+ ], Address.prototype, "postalCode", 2);
1626
+ __decorateClass([
1627
+ Column13("varchar", { nullable: true })
1628
+ ], Address.prototype, "country", 2);
1629
+ __decorateClass([
1630
+ Column13({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1631
+ ], Address.prototype, "createdAt", 2);
1632
+ __decorateClass([
1633
+ Column13({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1634
+ ], Address.prototype, "updatedAt", 2);
1635
+ __decorateClass([
1636
+ ManyToOne7(() => Contact, (c) => c.addresses, { onDelete: "CASCADE" }),
1637
+ JoinColumn7({ name: "contactId" })
1638
+ ], Address.prototype, "contact", 2);
1639
+ Address = __decorateClass([
1640
+ Entity13("addresses")
1641
+ ], Address);
1642
+
1643
+ // src/entities/order.entity.ts
1644
+ import { Entity as Entity14, PrimaryGeneratedColumn as PrimaryGeneratedColumn14, Column as Column14, ManyToOne as ManyToOne8, OneToMany as OneToMany6, JoinColumn as JoinColumn8 } from "typeorm";
1645
+ var Order = class {
1646
+ id;
1647
+ orderNumber;
1648
+ contactId;
1649
+ billingAddressId;
1650
+ shippingAddressId;
1651
+ status;
1652
+ subtotal;
1653
+ tax;
1654
+ discount;
1655
+ total;
1656
+ currency;
1657
+ metadata;
1658
+ createdAt;
1659
+ updatedAt;
1660
+ deletedAt;
1661
+ deleted;
1662
+ createdBy;
1663
+ updatedBy;
1664
+ deletedBy;
1665
+ contact;
1666
+ billingAddress;
1667
+ shippingAddress;
1668
+ items;
1669
+ payments;
1670
+ };
1671
+ __decorateClass([
1672
+ PrimaryGeneratedColumn14()
1673
+ ], Order.prototype, "id", 2);
1674
+ __decorateClass([
1675
+ Column14("varchar", { unique: true })
1676
+ ], Order.prototype, "orderNumber", 2);
1677
+ __decorateClass([
1678
+ Column14("int")
1679
+ ], Order.prototype, "contactId", 2);
1680
+ __decorateClass([
1681
+ Column14("int", { nullable: true })
1682
+ ], Order.prototype, "billingAddressId", 2);
1683
+ __decorateClass([
1684
+ Column14("int", { nullable: true })
1685
+ ], Order.prototype, "shippingAddressId", 2);
1686
+ __decorateClass([
1687
+ Column14("varchar", { default: "pending" })
1688
+ ], Order.prototype, "status", 2);
1689
+ __decorateClass([
1690
+ Column14("decimal", { precision: 12, scale: 2, default: 0 })
1691
+ ], Order.prototype, "subtotal", 2);
1692
+ __decorateClass([
1693
+ Column14("decimal", { precision: 12, scale: 2, default: 0 })
1694
+ ], Order.prototype, "tax", 2);
1695
+ __decorateClass([
1696
+ Column14("decimal", { precision: 12, scale: 2, default: 0 })
1697
+ ], Order.prototype, "discount", 2);
1698
+ __decorateClass([
1699
+ Column14("decimal", { precision: 12, scale: 2, default: 0 })
1700
+ ], Order.prototype, "total", 2);
1701
+ __decorateClass([
1702
+ Column14("varchar", { default: "INR" })
1703
+ ], Order.prototype, "currency", 2);
1704
+ __decorateClass([
1705
+ Column14("jsonb", { nullable: true })
1706
+ ], Order.prototype, "metadata", 2);
1707
+ __decorateClass([
1708
+ Column14({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1709
+ ], Order.prototype, "createdAt", 2);
1710
+ __decorateClass([
1711
+ Column14({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1712
+ ], Order.prototype, "updatedAt", 2);
1713
+ __decorateClass([
1714
+ Column14({ type: "timestamp", nullable: true })
1715
+ ], Order.prototype, "deletedAt", 2);
1716
+ __decorateClass([
1717
+ Column14("boolean", { default: false })
1718
+ ], Order.prototype, "deleted", 2);
1719
+ __decorateClass([
1720
+ Column14("int", { nullable: true })
1721
+ ], Order.prototype, "createdBy", 2);
1722
+ __decorateClass([
1723
+ Column14("int", { nullable: true })
1724
+ ], Order.prototype, "updatedBy", 2);
1725
+ __decorateClass([
1726
+ Column14("int", { nullable: true })
1727
+ ], Order.prototype, "deletedBy", 2);
1728
+ __decorateClass([
1729
+ ManyToOne8(() => Contact, { onDelete: "CASCADE" }),
1730
+ JoinColumn8({ name: "contactId" })
1731
+ ], Order.prototype, "contact", 2);
1732
+ __decorateClass([
1733
+ ManyToOne8(() => Address, { onDelete: "SET NULL" }),
1734
+ JoinColumn8({ name: "billingAddressId" })
1735
+ ], Order.prototype, "billingAddress", 2);
1736
+ __decorateClass([
1737
+ ManyToOne8(() => Address, { onDelete: "SET NULL" }),
1738
+ JoinColumn8({ name: "shippingAddressId" })
1739
+ ], Order.prototype, "shippingAddress", 2);
1740
+ __decorateClass([
1741
+ OneToMany6("OrderItem", "order")
1742
+ ], Order.prototype, "items", 2);
1743
+ __decorateClass([
1744
+ OneToMany6("Payment", "order")
1745
+ ], Order.prototype, "payments", 2);
1746
+ Order = __decorateClass([
1747
+ Entity14("orders")
1748
+ ], Order);
1749
+
1750
+ // src/entities/payment.entity.ts
1751
+ import { Entity as Entity15, PrimaryGeneratedColumn as PrimaryGeneratedColumn15, Column as Column15, ManyToOne as ManyToOne9, JoinColumn as JoinColumn9 } from "typeorm";
1752
+ var Payment = class {
1753
+ id;
1754
+ orderId;
1755
+ contactId;
1756
+ amount;
1757
+ currency;
1758
+ status;
1759
+ method;
1760
+ externalReference;
1761
+ metadata;
1762
+ paidAt;
1763
+ createdAt;
1764
+ updatedAt;
1765
+ deletedAt;
1766
+ deleted;
1767
+ createdBy;
1768
+ updatedBy;
1769
+ deletedBy;
1770
+ order;
1771
+ contact;
1772
+ };
1773
+ __decorateClass([
1774
+ PrimaryGeneratedColumn15()
1775
+ ], Payment.prototype, "id", 2);
1776
+ __decorateClass([
1777
+ Column15("int")
1778
+ ], Payment.prototype, "orderId", 2);
1779
+ __decorateClass([
1780
+ Column15("int", { nullable: true })
1781
+ ], Payment.prototype, "contactId", 2);
1782
+ __decorateClass([
1783
+ Column15("decimal", { precision: 12, scale: 2 })
1784
+ ], Payment.prototype, "amount", 2);
1785
+ __decorateClass([
1786
+ Column15("varchar", { default: "INR" })
1787
+ ], Payment.prototype, "currency", 2);
1788
+ __decorateClass([
1789
+ Column15("varchar", { default: "pending" })
1790
+ ], Payment.prototype, "status", 2);
1791
+ __decorateClass([
1792
+ Column15("varchar", { nullable: true })
1793
+ ], Payment.prototype, "method", 2);
1794
+ __decorateClass([
1795
+ Column15("varchar", { nullable: true })
1796
+ ], Payment.prototype, "externalReference", 2);
1797
+ __decorateClass([
1798
+ Column15("jsonb", { nullable: true })
1799
+ ], Payment.prototype, "metadata", 2);
1800
+ __decorateClass([
1801
+ Column15({ type: "timestamp", nullable: true })
1802
+ ], Payment.prototype, "paidAt", 2);
1803
+ __decorateClass([
1804
+ Column15({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1805
+ ], Payment.prototype, "createdAt", 2);
1806
+ __decorateClass([
1807
+ Column15({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1808
+ ], Payment.prototype, "updatedAt", 2);
1809
+ __decorateClass([
1810
+ Column15({ type: "timestamp", nullable: true })
1811
+ ], Payment.prototype, "deletedAt", 2);
1812
+ __decorateClass([
1813
+ Column15("boolean", { default: false })
1814
+ ], Payment.prototype, "deleted", 2);
1815
+ __decorateClass([
1816
+ Column15("int", { nullable: true })
1817
+ ], Payment.prototype, "createdBy", 2);
1818
+ __decorateClass([
1819
+ Column15("int", { nullable: true })
1820
+ ], Payment.prototype, "updatedBy", 2);
1821
+ __decorateClass([
1822
+ Column15("int", { nullable: true })
1823
+ ], Payment.prototype, "deletedBy", 2);
1824
+ __decorateClass([
1825
+ ManyToOne9(() => Order, (o) => o.payments, { onDelete: "CASCADE" }),
1826
+ JoinColumn9({ name: "orderId" })
1827
+ ], Payment.prototype, "order", 2);
1828
+ __decorateClass([
1829
+ ManyToOne9(() => Contact, { onDelete: "SET NULL" }),
1830
+ JoinColumn9({ name: "contactId" })
1831
+ ], Payment.prototype, "contact", 2);
1832
+ Payment = __decorateClass([
1833
+ Entity15("payments")
1834
+ ], Payment);
1835
+
1451
1836
  // src/entities/contact.entity.ts
1452
1837
  var Contact = class {
1453
1838
  id;
1454
1839
  name;
1455
1840
  email;
1456
1841
  phone;
1842
+ type;
1843
+ company;
1844
+ taxId;
1845
+ notes;
1457
1846
  createdAt;
1458
1847
  updatedAt;
1459
1848
  deletedAt;
@@ -1462,49 +1851,73 @@ var Contact = class {
1462
1851
  updatedBy;
1463
1852
  deletedBy;
1464
1853
  form_submissions;
1854
+ addresses;
1855
+ orders;
1856
+ payments;
1465
1857
  };
1466
1858
  __decorateClass([
1467
- PrimaryGeneratedColumn13()
1859
+ PrimaryGeneratedColumn16()
1468
1860
  ], Contact.prototype, "id", 2);
1469
1861
  __decorateClass([
1470
- Column13("varchar")
1862
+ Column16("varchar")
1471
1863
  ], Contact.prototype, "name", 2);
1472
1864
  __decorateClass([
1473
- Column13("varchar", { unique: true })
1865
+ Column16("varchar", { unique: true })
1474
1866
  ], Contact.prototype, "email", 2);
1475
1867
  __decorateClass([
1476
- Column13("varchar", { nullable: true })
1868
+ Column16("varchar", { nullable: true })
1477
1869
  ], Contact.prototype, "phone", 2);
1478
1870
  __decorateClass([
1479
- Column13({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1871
+ Column16("varchar", { nullable: true })
1872
+ ], Contact.prototype, "type", 2);
1873
+ __decorateClass([
1874
+ Column16("varchar", { nullable: true })
1875
+ ], Contact.prototype, "company", 2);
1876
+ __decorateClass([
1877
+ Column16("varchar", { nullable: true })
1878
+ ], Contact.prototype, "taxId", 2);
1879
+ __decorateClass([
1880
+ Column16("text", { nullable: true })
1881
+ ], Contact.prototype, "notes", 2);
1882
+ __decorateClass([
1883
+ Column16({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1480
1884
  ], Contact.prototype, "createdAt", 2);
1481
1885
  __decorateClass([
1482
- Column13({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1886
+ Column16({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1483
1887
  ], Contact.prototype, "updatedAt", 2);
1484
1888
  __decorateClass([
1485
- Column13({ type: "timestamp", nullable: true })
1889
+ Column16({ type: "timestamp", nullable: true })
1486
1890
  ], Contact.prototype, "deletedAt", 2);
1487
1891
  __decorateClass([
1488
- Column13("boolean", { default: false })
1892
+ Column16("boolean", { default: false })
1489
1893
  ], Contact.prototype, "deleted", 2);
1490
1894
  __decorateClass([
1491
- Column13("int", { nullable: true })
1895
+ Column16("int", { nullable: true })
1492
1896
  ], Contact.prototype, "createdBy", 2);
1493
1897
  __decorateClass([
1494
- Column13("int", { nullable: true })
1898
+ Column16("int", { nullable: true })
1495
1899
  ], Contact.prototype, "updatedBy", 2);
1496
1900
  __decorateClass([
1497
- Column13("int", { nullable: true })
1901
+ Column16("int", { nullable: true })
1498
1902
  ], Contact.prototype, "deletedBy", 2);
1499
1903
  __decorateClass([
1500
- OneToMany6(() => FormSubmission, (fs) => fs.contact)
1904
+ OneToMany7(() => FormSubmission, (fs) => fs.contact)
1501
1905
  ], Contact.prototype, "form_submissions", 2);
1906
+ __decorateClass([
1907
+ OneToMany7(() => Address, (a) => a.contact)
1908
+ ], Contact.prototype, "addresses", 2);
1909
+ __decorateClass([
1910
+ OneToMany7(() => Order, (o) => o.contact)
1911
+ ], Contact.prototype, "orders", 2);
1912
+ __decorateClass([
1913
+ OneToMany7(() => Payment, (p) => p.contact)
1914
+ ], Contact.prototype, "payments", 2);
1502
1915
  Contact = __decorateClass([
1503
- Entity13("contacts")
1916
+ Entity16("contacts")
1504
1917
  ], Contact);
1505
1918
 
1506
1919
  // src/entities/config.entity.ts
1507
- import { Entity as Entity14, PrimaryGeneratedColumn as PrimaryGeneratedColumn14, Column as Column14, Unique } from "typeorm";
1920
+ import { Entity as Entity17, PrimaryGeneratedColumn as PrimaryGeneratedColumn17, Column as Column17, Unique } from "typeorm";
1508
1921
  var Config = class {
1509
1922
  id;
1510
1923
  settings;
@@ -1521,51 +1934,51 @@ var Config = class {
1521
1934
  deletedBy;
1522
1935
  };
1523
1936
  __decorateClass([
1524
- PrimaryGeneratedColumn14()
1937
+ PrimaryGeneratedColumn17()
1525
1938
  ], Config.prototype, "id", 2);
1526
1939
  __decorateClass([
1527
- Column14("varchar")
1940
+ Column17("varchar")
1528
1941
  ], Config.prototype, "settings", 2);
1529
1942
  __decorateClass([
1530
- Column14("varchar")
1943
+ Column17("varchar")
1531
1944
  ], Config.prototype, "key", 2);
1532
1945
  __decorateClass([
1533
- Column14("varchar")
1946
+ Column17("varchar")
1534
1947
  ], Config.prototype, "value", 2);
1535
1948
  __decorateClass([
1536
- Column14("varchar", { default: "private" })
1949
+ Column17("varchar", { default: "private" })
1537
1950
  ], Config.prototype, "type", 2);
1538
1951
  __decorateClass([
1539
- Column14("boolean", { default: false })
1952
+ Column17("boolean", { default: false })
1540
1953
  ], Config.prototype, "encrypted", 2);
1541
1954
  __decorateClass([
1542
- Column14({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1955
+ Column17({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1543
1956
  ], Config.prototype, "createdAt", 2);
1544
1957
  __decorateClass([
1545
- Column14({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1958
+ Column17({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1546
1959
  ], Config.prototype, "updatedAt", 2);
1547
1960
  __decorateClass([
1548
- Column14({ type: "timestamp", nullable: true })
1961
+ Column17({ type: "timestamp", nullable: true })
1549
1962
  ], Config.prototype, "deletedAt", 2);
1550
1963
  __decorateClass([
1551
- Column14("boolean", { default: false })
1964
+ Column17("boolean", { default: false })
1552
1965
  ], Config.prototype, "deleted", 2);
1553
1966
  __decorateClass([
1554
- Column14("int", { nullable: true })
1967
+ Column17("int", { nullable: true })
1555
1968
  ], Config.prototype, "createdBy", 2);
1556
1969
  __decorateClass([
1557
- Column14("int", { nullable: true })
1970
+ Column17("int", { nullable: true })
1558
1971
  ], Config.prototype, "updatedBy", 2);
1559
1972
  __decorateClass([
1560
- Column14("int", { nullable: true })
1973
+ Column17("int", { nullable: true })
1561
1974
  ], Config.prototype, "deletedBy", 2);
1562
1975
  Config = __decorateClass([
1563
- Entity14("configs"),
1976
+ Entity17("configs"),
1564
1977
  Unique(["settings", "key"])
1565
1978
  ], Config);
1566
1979
 
1567
1980
  // src/entities/media.entity.ts
1568
- import { Entity as Entity15, PrimaryGeneratedColumn as PrimaryGeneratedColumn15, Column as Column15 } from "typeorm";
1981
+ import { Entity as Entity18, PrimaryGeneratedColumn as PrimaryGeneratedColumn18, Column as Column18 } from "typeorm";
1569
1982
  var Media = class {
1570
1983
  id;
1571
1984
  filename;
@@ -1580,44 +1993,44 @@ var Media = class {
1580
1993
  deleted;
1581
1994
  };
1582
1995
  __decorateClass([
1583
- PrimaryGeneratedColumn15()
1996
+ PrimaryGeneratedColumn18()
1584
1997
  ], Media.prototype, "id", 2);
1585
1998
  __decorateClass([
1586
- Column15("varchar")
1999
+ Column18("varchar")
1587
2000
  ], Media.prototype, "filename", 2);
1588
2001
  __decorateClass([
1589
- Column15("varchar")
2002
+ Column18("varchar")
1590
2003
  ], Media.prototype, "url", 2);
1591
2004
  __decorateClass([
1592
- Column15("varchar")
2005
+ Column18("varchar")
1593
2006
  ], Media.prototype, "mimeType", 2);
1594
2007
  __decorateClass([
1595
- Column15("int", { default: 0 })
2008
+ Column18("int", { default: 0 })
1596
2009
  ], Media.prototype, "size", 2);
1597
2010
  __decorateClass([
1598
- Column15("varchar", { nullable: true })
2011
+ Column18("varchar", { nullable: true })
1599
2012
  ], Media.prototype, "alt", 2);
1600
2013
  __decorateClass([
1601
- Column15("boolean", { default: false })
2014
+ Column18("boolean", { default: false })
1602
2015
  ], Media.prototype, "isPublic", 2);
1603
2016
  __decorateClass([
1604
- Column15({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2017
+ Column18({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1605
2018
  ], Media.prototype, "createdAt", 2);
1606
2019
  __decorateClass([
1607
- Column15({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2020
+ Column18({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1608
2021
  ], Media.prototype, "updatedAt", 2);
1609
2022
  __decorateClass([
1610
- Column15({ type: "timestamp", nullable: true })
2023
+ Column18({ type: "timestamp", nullable: true })
1611
2024
  ], Media.prototype, "deletedAt", 2);
1612
2025
  __decorateClass([
1613
- Column15("boolean", { default: false })
2026
+ Column18("boolean", { default: false })
1614
2027
  ], Media.prototype, "deleted", 2);
1615
2028
  Media = __decorateClass([
1616
- Entity15("media")
2029
+ Entity18("media")
1617
2030
  ], Media);
1618
2031
 
1619
2032
  // src/entities/page.entity.ts
1620
- import { Entity as Entity16, PrimaryGeneratedColumn as PrimaryGeneratedColumn16, Column as Column16, ManyToOne as ManyToOne7, JoinColumn as JoinColumn7 } from "typeorm";
2033
+ import { Entity as Entity19, PrimaryGeneratedColumn as PrimaryGeneratedColumn19, Column as Column19, ManyToOne as ManyToOne10, JoinColumn as JoinColumn10 } from "typeorm";
1621
2034
  var Page = class {
1622
2035
  id;
1623
2036
  title;
@@ -1638,96 +2051,785 @@ var Page = class {
1638
2051
  deletedBy;
1639
2052
  };
1640
2053
  __decorateClass([
1641
- PrimaryGeneratedColumn16()
2054
+ PrimaryGeneratedColumn19()
1642
2055
  ], Page.prototype, "id", 2);
1643
2056
  __decorateClass([
1644
- Column16("varchar")
2057
+ Column19("varchar")
1645
2058
  ], Page.prototype, "title", 2);
1646
2059
  __decorateClass([
1647
- Column16("varchar", { unique: true })
2060
+ Column19("varchar", { unique: true })
1648
2061
  ], Page.prototype, "slug", 2);
1649
2062
  __decorateClass([
1650
- Column16({ type: "jsonb", default: {} })
2063
+ Column19({ type: "jsonb", default: {} })
1651
2064
  ], Page.prototype, "content", 2);
1652
2065
  __decorateClass([
1653
- Column16("boolean", { default: false })
2066
+ Column19("boolean", { default: false })
1654
2067
  ], Page.prototype, "published", 2);
1655
2068
  __decorateClass([
1656
- Column16("varchar", { default: "default" })
2069
+ Column19("varchar", { default: "default" })
1657
2070
  ], Page.prototype, "theme", 2);
1658
2071
  __decorateClass([
1659
- Column16("int", { nullable: true })
2072
+ Column19("int", { nullable: true })
1660
2073
  ], Page.prototype, "parentId", 2);
1661
2074
  __decorateClass([
1662
- ManyToOne7(() => Page, { onDelete: "SET NULL" }),
1663
- JoinColumn7({ name: "parentId" })
2075
+ ManyToOne10(() => Page, { onDelete: "SET NULL" }),
2076
+ JoinColumn10({ name: "parentId" })
1664
2077
  ], Page.prototype, "parent", 2);
1665
2078
  __decorateClass([
1666
- Column16("int", { nullable: true })
2079
+ Column19("int", { nullable: true })
1667
2080
  ], Page.prototype, "seoId", 2);
1668
2081
  __decorateClass([
1669
- ManyToOne7(() => Seo, { onDelete: "SET NULL" }),
1670
- JoinColumn7({ name: "seoId" })
2082
+ ManyToOne10(() => Seo, { onDelete: "SET NULL" }),
2083
+ JoinColumn10({ name: "seoId" })
1671
2084
  ], Page.prototype, "seo", 2);
1672
2085
  __decorateClass([
1673
- Column16({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2086
+ Column19({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1674
2087
  ], Page.prototype, "createdAt", 2);
1675
2088
  __decorateClass([
1676
- Column16({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2089
+ Column19({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
1677
2090
  ], Page.prototype, "updatedAt", 2);
1678
2091
  __decorateClass([
1679
- Column16({ type: "timestamp", nullable: true })
2092
+ Column19({ type: "timestamp", nullable: true })
1680
2093
  ], Page.prototype, "deletedAt", 2);
1681
2094
  __decorateClass([
1682
- Column16("boolean", { default: false })
2095
+ Column19("boolean", { default: false })
1683
2096
  ], Page.prototype, "deleted", 2);
1684
2097
  __decorateClass([
1685
- Column16("int", { nullable: true })
2098
+ Column19("int", { nullable: true })
1686
2099
  ], Page.prototype, "createdBy", 2);
1687
2100
  __decorateClass([
1688
- Column16("int", { nullable: true })
2101
+ Column19("int", { nullable: true })
1689
2102
  ], Page.prototype, "updatedBy", 2);
1690
2103
  __decorateClass([
1691
- Column16("int", { nullable: true })
2104
+ Column19("int", { nullable: true })
1692
2105
  ], Page.prototype, "deletedBy", 2);
1693
2106
  Page = __decorateClass([
1694
- Entity16("pages")
2107
+ Entity19("pages")
1695
2108
  ], Page);
1696
2109
 
1697
- // src/entities/index.ts
1698
- var CMS_ENTITY_MAP = {
1699
- users: User,
1700
- password_reset_tokens: PasswordResetToken,
1701
- user_groups: UserGroup,
1702
- permissions: Permission,
1703
- blogs: Blog,
1704
- tags: Tag,
1705
- categories: Category,
1706
- comments: Comment,
1707
- contacts: Contact,
1708
- forms: Form,
1709
- form_fields: FormField,
1710
- form_submissions: FormSubmission,
1711
- seos: Seo,
1712
- configs: Config,
1713
- media: Media,
1714
- pages: Page
2110
+ // src/entities/product-category.entity.ts
2111
+ import { Entity as Entity20, PrimaryGeneratedColumn as PrimaryGeneratedColumn20, Column as Column20, ManyToOne as ManyToOne11, OneToMany as OneToMany8, JoinColumn as JoinColumn11 } from "typeorm";
2112
+ var ProductCategory = class {
2113
+ id;
2114
+ name;
2115
+ slug;
2116
+ parentId;
2117
+ image;
2118
+ description;
2119
+ metadata;
2120
+ active;
2121
+ sortOrder;
2122
+ createdAt;
2123
+ updatedAt;
2124
+ deletedAt;
2125
+ deleted;
2126
+ createdBy;
2127
+ updatedBy;
2128
+ deletedBy;
2129
+ parent;
2130
+ children;
2131
+ products;
2132
+ collections;
1715
2133
  };
1716
-
1717
- // src/auth/helpers.ts
1718
- var OPEN_ENDPOINTS = [
1719
- { "/api/contacts": ["POST"] },
1720
- { "/api/form-submissions": ["POST"] },
1721
- { "/api/blogs": ["GET"] }
1722
- ];
1723
- var PERMISSION_REQUIRED_ENDPOINTS = {};
1724
- function isOpenEndpoint(pathname) {
1725
- return OPEN_ENDPOINTS.some((endpoint) => pathname.startsWith(Object.keys(endpoint)[0]));
1726
- }
1727
- function getRequiredPermission(pathname) {
1728
- return null;
1729
- }
1730
- function isPublicMethod(pathname, method) {
2134
+ __decorateClass([
2135
+ PrimaryGeneratedColumn20()
2136
+ ], ProductCategory.prototype, "id", 2);
2137
+ __decorateClass([
2138
+ Column20("varchar")
2139
+ ], ProductCategory.prototype, "name", 2);
2140
+ __decorateClass([
2141
+ Column20("varchar", { unique: true })
2142
+ ], ProductCategory.prototype, "slug", 2);
2143
+ __decorateClass([
2144
+ Column20("int", { nullable: true })
2145
+ ], ProductCategory.prototype, "parentId", 2);
2146
+ __decorateClass([
2147
+ Column20("varchar", { nullable: true })
2148
+ ], ProductCategory.prototype, "image", 2);
2149
+ __decorateClass([
2150
+ Column20("text", { nullable: true })
2151
+ ], ProductCategory.prototype, "description", 2);
2152
+ __decorateClass([
2153
+ Column20("jsonb", { nullable: true })
2154
+ ], ProductCategory.prototype, "metadata", 2);
2155
+ __decorateClass([
2156
+ Column20("boolean", { default: true })
2157
+ ], ProductCategory.prototype, "active", 2);
2158
+ __decorateClass([
2159
+ Column20("int", { default: 0 })
2160
+ ], ProductCategory.prototype, "sortOrder", 2);
2161
+ __decorateClass([
2162
+ Column20({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2163
+ ], ProductCategory.prototype, "createdAt", 2);
2164
+ __decorateClass([
2165
+ Column20({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2166
+ ], ProductCategory.prototype, "updatedAt", 2);
2167
+ __decorateClass([
2168
+ Column20({ type: "timestamp", nullable: true })
2169
+ ], ProductCategory.prototype, "deletedAt", 2);
2170
+ __decorateClass([
2171
+ Column20("boolean", { default: false })
2172
+ ], ProductCategory.prototype, "deleted", 2);
2173
+ __decorateClass([
2174
+ Column20("int", { nullable: true })
2175
+ ], ProductCategory.prototype, "createdBy", 2);
2176
+ __decorateClass([
2177
+ Column20("int", { nullable: true })
2178
+ ], ProductCategory.prototype, "updatedBy", 2);
2179
+ __decorateClass([
2180
+ Column20("int", { nullable: true })
2181
+ ], ProductCategory.prototype, "deletedBy", 2);
2182
+ __decorateClass([
2183
+ ManyToOne11(() => ProductCategory, (c) => c.children, { onDelete: "SET NULL" }),
2184
+ JoinColumn11({ name: "parentId" })
2185
+ ], ProductCategory.prototype, "parent", 2);
2186
+ __decorateClass([
2187
+ OneToMany8(() => ProductCategory, (c) => c.parent)
2188
+ ], ProductCategory.prototype, "children", 2);
2189
+ __decorateClass([
2190
+ OneToMany8("Product", "category")
2191
+ ], ProductCategory.prototype, "products", 2);
2192
+ __decorateClass([
2193
+ OneToMany8("Collection", "category")
2194
+ ], ProductCategory.prototype, "collections", 2);
2195
+ ProductCategory = __decorateClass([
2196
+ Entity20("product_categories")
2197
+ ], ProductCategory);
2198
+
2199
+ // src/entities/collection.entity.ts
2200
+ import { Entity as Entity22, PrimaryGeneratedColumn as PrimaryGeneratedColumn22, Column as Column22, ManyToOne as ManyToOne13, OneToMany as OneToMany10, JoinColumn as JoinColumn13 } from "typeorm";
2201
+
2202
+ // src/entities/brand.entity.ts
2203
+ import { Entity as Entity21, PrimaryGeneratedColumn as PrimaryGeneratedColumn21, Column as Column21, OneToMany as OneToMany9, ManyToOne as ManyToOne12, JoinColumn as JoinColumn12 } from "typeorm";
2204
+ var Brand = class {
2205
+ id;
2206
+ name;
2207
+ slug;
2208
+ logo;
2209
+ metadata;
2210
+ description;
2211
+ active;
2212
+ sortOrder;
2213
+ createdAt;
2214
+ updatedAt;
2215
+ deletedAt;
2216
+ deleted;
2217
+ createdBy;
2218
+ updatedBy;
2219
+ deletedBy;
2220
+ seoId;
2221
+ seo;
2222
+ products;
2223
+ collections;
2224
+ };
2225
+ __decorateClass([
2226
+ PrimaryGeneratedColumn21()
2227
+ ], Brand.prototype, "id", 2);
2228
+ __decorateClass([
2229
+ Column21("varchar")
2230
+ ], Brand.prototype, "name", 2);
2231
+ __decorateClass([
2232
+ Column21("varchar", { unique: true })
2233
+ ], Brand.prototype, "slug", 2);
2234
+ __decorateClass([
2235
+ Column21("varchar", { nullable: true })
2236
+ ], Brand.prototype, "logo", 2);
2237
+ __decorateClass([
2238
+ Column21("jsonb", { nullable: true })
2239
+ ], Brand.prototype, "metadata", 2);
2240
+ __decorateClass([
2241
+ Column21("text", { nullable: true })
2242
+ ], Brand.prototype, "description", 2);
2243
+ __decorateClass([
2244
+ Column21("boolean", { default: true })
2245
+ ], Brand.prototype, "active", 2);
2246
+ __decorateClass([
2247
+ Column21("int", { default: 0 })
2248
+ ], Brand.prototype, "sortOrder", 2);
2249
+ __decorateClass([
2250
+ Column21({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2251
+ ], Brand.prototype, "createdAt", 2);
2252
+ __decorateClass([
2253
+ Column21({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2254
+ ], Brand.prototype, "updatedAt", 2);
2255
+ __decorateClass([
2256
+ Column21({ type: "timestamp", nullable: true })
2257
+ ], Brand.prototype, "deletedAt", 2);
2258
+ __decorateClass([
2259
+ Column21("boolean", { default: false })
2260
+ ], Brand.prototype, "deleted", 2);
2261
+ __decorateClass([
2262
+ Column21("int", { nullable: true })
2263
+ ], Brand.prototype, "createdBy", 2);
2264
+ __decorateClass([
2265
+ Column21("int", { nullable: true })
2266
+ ], Brand.prototype, "updatedBy", 2);
2267
+ __decorateClass([
2268
+ Column21("int", { nullable: true })
2269
+ ], Brand.prototype, "deletedBy", 2);
2270
+ __decorateClass([
2271
+ Column21("int", { nullable: true })
2272
+ ], Brand.prototype, "seoId", 2);
2273
+ __decorateClass([
2274
+ ManyToOne12(() => Seo, { onDelete: "SET NULL" }),
2275
+ JoinColumn12({ name: "seoId" })
2276
+ ], Brand.prototype, "seo", 2);
2277
+ __decorateClass([
2278
+ OneToMany9("Product", "brand")
2279
+ ], Brand.prototype, "products", 2);
2280
+ __decorateClass([
2281
+ OneToMany9("Collection", "brand")
2282
+ ], Brand.prototype, "collections", 2);
2283
+ Brand = __decorateClass([
2284
+ Entity21("brands")
2285
+ ], Brand);
2286
+
2287
+ // src/entities/collection.entity.ts
2288
+ var Collection = class {
2289
+ id;
2290
+ categoryId;
2291
+ brandId;
2292
+ name;
2293
+ slug;
2294
+ description;
2295
+ image;
2296
+ metadata;
2297
+ active;
2298
+ sortOrder;
2299
+ createdAt;
2300
+ updatedAt;
2301
+ deletedAt;
2302
+ deleted;
2303
+ createdBy;
2304
+ updatedBy;
2305
+ deletedBy;
2306
+ seoId;
2307
+ seo;
2308
+ category;
2309
+ brand;
2310
+ products;
2311
+ };
2312
+ __decorateClass([
2313
+ PrimaryGeneratedColumn22()
2314
+ ], Collection.prototype, "id", 2);
2315
+ __decorateClass([
2316
+ Column22("int", { nullable: true })
2317
+ ], Collection.prototype, "categoryId", 2);
2318
+ __decorateClass([
2319
+ Column22("int", { nullable: true })
2320
+ ], Collection.prototype, "brandId", 2);
2321
+ __decorateClass([
2322
+ Column22("varchar")
2323
+ ], Collection.prototype, "name", 2);
2324
+ __decorateClass([
2325
+ Column22("varchar", { unique: true })
2326
+ ], Collection.prototype, "slug", 2);
2327
+ __decorateClass([
2328
+ Column22("text", { nullable: true })
2329
+ ], Collection.prototype, "description", 2);
2330
+ __decorateClass([
2331
+ Column22("varchar", { nullable: true })
2332
+ ], Collection.prototype, "image", 2);
2333
+ __decorateClass([
2334
+ Column22("jsonb", { nullable: true })
2335
+ ], Collection.prototype, "metadata", 2);
2336
+ __decorateClass([
2337
+ Column22("boolean", { default: true })
2338
+ ], Collection.prototype, "active", 2);
2339
+ __decorateClass([
2340
+ Column22("int", { default: 0 })
2341
+ ], Collection.prototype, "sortOrder", 2);
2342
+ __decorateClass([
2343
+ Column22({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2344
+ ], Collection.prototype, "createdAt", 2);
2345
+ __decorateClass([
2346
+ Column22({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2347
+ ], Collection.prototype, "updatedAt", 2);
2348
+ __decorateClass([
2349
+ Column22({ type: "timestamp", nullable: true })
2350
+ ], Collection.prototype, "deletedAt", 2);
2351
+ __decorateClass([
2352
+ Column22("boolean", { default: false })
2353
+ ], Collection.prototype, "deleted", 2);
2354
+ __decorateClass([
2355
+ Column22("int", { nullable: true })
2356
+ ], Collection.prototype, "createdBy", 2);
2357
+ __decorateClass([
2358
+ Column22("int", { nullable: true })
2359
+ ], Collection.prototype, "updatedBy", 2);
2360
+ __decorateClass([
2361
+ Column22("int", { nullable: true })
2362
+ ], Collection.prototype, "deletedBy", 2);
2363
+ __decorateClass([
2364
+ Column22("int", { nullable: true })
2365
+ ], Collection.prototype, "seoId", 2);
2366
+ __decorateClass([
2367
+ ManyToOne13(() => Seo, { onDelete: "SET NULL" }),
2368
+ JoinColumn13({ name: "seoId" })
2369
+ ], Collection.prototype, "seo", 2);
2370
+ __decorateClass([
2371
+ ManyToOne13(() => ProductCategory, (c) => c.collections, { onDelete: "SET NULL" }),
2372
+ JoinColumn13({ name: "categoryId" })
2373
+ ], Collection.prototype, "category", 2);
2374
+ __decorateClass([
2375
+ ManyToOne13(() => Brand, (b) => b.collections, { onDelete: "SET NULL" }),
2376
+ JoinColumn13({ name: "brandId" })
2377
+ ], Collection.prototype, "brand", 2);
2378
+ __decorateClass([
2379
+ OneToMany10("Product", "collection")
2380
+ ], Collection.prototype, "products", 2);
2381
+ Collection = __decorateClass([
2382
+ Entity22("collections")
2383
+ ], Collection);
2384
+
2385
+ // src/entities/product.entity.ts
2386
+ import { Entity as Entity23, PrimaryGeneratedColumn as PrimaryGeneratedColumn23, Column as Column23, ManyToOne as ManyToOne14, OneToMany as OneToMany11, JoinColumn as JoinColumn14 } from "typeorm";
2387
+ var Product = class {
2388
+ id;
2389
+ collectionId;
2390
+ brandId;
2391
+ categoryId;
2392
+ sku;
2393
+ slug;
2394
+ name;
2395
+ price;
2396
+ compareAtPrice;
2397
+ quantity;
2398
+ status;
2399
+ featured;
2400
+ metadata;
2401
+ createdAt;
2402
+ updatedAt;
2403
+ deletedAt;
2404
+ deleted;
2405
+ createdBy;
2406
+ updatedBy;
2407
+ deletedBy;
2408
+ seoId;
2409
+ seo;
2410
+ collection;
2411
+ brand;
2412
+ category;
2413
+ attributes;
2414
+ taxes;
2415
+ };
2416
+ __decorateClass([
2417
+ PrimaryGeneratedColumn23()
2418
+ ], Product.prototype, "id", 2);
2419
+ __decorateClass([
2420
+ Column23("int", { nullable: true })
2421
+ ], Product.prototype, "collectionId", 2);
2422
+ __decorateClass([
2423
+ Column23("int", { nullable: true })
2424
+ ], Product.prototype, "brandId", 2);
2425
+ __decorateClass([
2426
+ Column23("int", { nullable: true })
2427
+ ], Product.prototype, "categoryId", 2);
2428
+ __decorateClass([
2429
+ Column23("varchar", { nullable: true })
2430
+ ], Product.prototype, "sku", 2);
2431
+ __decorateClass([
2432
+ Column23("varchar", { unique: true, nullable: true })
2433
+ ], Product.prototype, "slug", 2);
2434
+ __decorateClass([
2435
+ Column23("varchar", { nullable: true })
2436
+ ], Product.prototype, "name", 2);
2437
+ __decorateClass([
2438
+ Column23("decimal", { precision: 12, scale: 2 })
2439
+ ], Product.prototype, "price", 2);
2440
+ __decorateClass([
2441
+ Column23("decimal", { precision: 12, scale: 2, nullable: true })
2442
+ ], Product.prototype, "compareAtPrice", 2);
2443
+ __decorateClass([
2444
+ Column23("int", { default: 0 })
2445
+ ], Product.prototype, "quantity", 2);
2446
+ __decorateClass([
2447
+ Column23("varchar", { default: "draft" })
2448
+ ], Product.prototype, "status", 2);
2449
+ __decorateClass([
2450
+ Column23("boolean", { default: false })
2451
+ ], Product.prototype, "featured", 2);
2452
+ __decorateClass([
2453
+ Column23("jsonb", { nullable: true })
2454
+ ], Product.prototype, "metadata", 2);
2455
+ __decorateClass([
2456
+ Column23({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2457
+ ], Product.prototype, "createdAt", 2);
2458
+ __decorateClass([
2459
+ Column23({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2460
+ ], Product.prototype, "updatedAt", 2);
2461
+ __decorateClass([
2462
+ Column23({ type: "timestamp", nullable: true })
2463
+ ], Product.prototype, "deletedAt", 2);
2464
+ __decorateClass([
2465
+ Column23("boolean", { default: false })
2466
+ ], Product.prototype, "deleted", 2);
2467
+ __decorateClass([
2468
+ Column23("int", { nullable: true })
2469
+ ], Product.prototype, "createdBy", 2);
2470
+ __decorateClass([
2471
+ Column23("int", { nullable: true })
2472
+ ], Product.prototype, "updatedBy", 2);
2473
+ __decorateClass([
2474
+ Column23("int", { nullable: true })
2475
+ ], Product.prototype, "deletedBy", 2);
2476
+ __decorateClass([
2477
+ Column23("int", { nullable: true })
2478
+ ], Product.prototype, "seoId", 2);
2479
+ __decorateClass([
2480
+ ManyToOne14(() => Seo, { onDelete: "SET NULL" }),
2481
+ JoinColumn14({ name: "seoId" })
2482
+ ], Product.prototype, "seo", 2);
2483
+ __decorateClass([
2484
+ ManyToOne14(() => Collection, (c) => c.products, { onDelete: "SET NULL" }),
2485
+ JoinColumn14({ name: "collectionId" })
2486
+ ], Product.prototype, "collection", 2);
2487
+ __decorateClass([
2488
+ ManyToOne14(() => Brand, (b) => b.products, { onDelete: "SET NULL" }),
2489
+ JoinColumn14({ name: "brandId" })
2490
+ ], Product.prototype, "brand", 2);
2491
+ __decorateClass([
2492
+ ManyToOne14(() => ProductCategory, (c) => c.products, { onDelete: "SET NULL" }),
2493
+ JoinColumn14({ name: "categoryId" })
2494
+ ], Product.prototype, "category", 2);
2495
+ __decorateClass([
2496
+ OneToMany11("ProductAttribute", "product")
2497
+ ], Product.prototype, "attributes", 2);
2498
+ __decorateClass([
2499
+ OneToMany11("ProductTax", "product")
2500
+ ], Product.prototype, "taxes", 2);
2501
+ Product = __decorateClass([
2502
+ Entity23("products")
2503
+ ], Product);
2504
+
2505
+ // src/entities/attribute.entity.ts
2506
+ import { Entity as Entity24, PrimaryGeneratedColumn as PrimaryGeneratedColumn24, Column as Column24 } from "typeorm";
2507
+ var Attribute = class {
2508
+ id;
2509
+ name;
2510
+ slug;
2511
+ type;
2512
+ options;
2513
+ metadata;
2514
+ active;
2515
+ sortOrder;
2516
+ createdAt;
2517
+ updatedAt;
2518
+ deletedAt;
2519
+ deleted;
2520
+ createdBy;
2521
+ updatedBy;
2522
+ deletedBy;
2523
+ };
2524
+ __decorateClass([
2525
+ PrimaryGeneratedColumn24()
2526
+ ], Attribute.prototype, "id", 2);
2527
+ __decorateClass([
2528
+ Column24("varchar")
2529
+ ], Attribute.prototype, "name", 2);
2530
+ __decorateClass([
2531
+ Column24("varchar", { unique: true })
2532
+ ], Attribute.prototype, "slug", 2);
2533
+ __decorateClass([
2534
+ Column24("varchar", { default: "text" })
2535
+ ], Attribute.prototype, "type", 2);
2536
+ __decorateClass([
2537
+ Column24("jsonb", { nullable: true })
2538
+ ], Attribute.prototype, "options", 2);
2539
+ __decorateClass([
2540
+ Column24("jsonb", { nullable: true })
2541
+ ], Attribute.prototype, "metadata", 2);
2542
+ __decorateClass([
2543
+ Column24("boolean", { default: true })
2544
+ ], Attribute.prototype, "active", 2);
2545
+ __decorateClass([
2546
+ Column24("int", { default: 0 })
2547
+ ], Attribute.prototype, "sortOrder", 2);
2548
+ __decorateClass([
2549
+ Column24({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2550
+ ], Attribute.prototype, "createdAt", 2);
2551
+ __decorateClass([
2552
+ Column24({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2553
+ ], Attribute.prototype, "updatedAt", 2);
2554
+ __decorateClass([
2555
+ Column24({ type: "timestamp", nullable: true })
2556
+ ], Attribute.prototype, "deletedAt", 2);
2557
+ __decorateClass([
2558
+ Column24("boolean", { default: false })
2559
+ ], Attribute.prototype, "deleted", 2);
2560
+ __decorateClass([
2561
+ Column24("int", { nullable: true })
2562
+ ], Attribute.prototype, "createdBy", 2);
2563
+ __decorateClass([
2564
+ Column24("int", { nullable: true })
2565
+ ], Attribute.prototype, "updatedBy", 2);
2566
+ __decorateClass([
2567
+ Column24("int", { nullable: true })
2568
+ ], Attribute.prototype, "deletedBy", 2);
2569
+ Attribute = __decorateClass([
2570
+ Entity24("attributes")
2571
+ ], Attribute);
2572
+
2573
+ // src/entities/product-attribute.entity.ts
2574
+ import { Entity as Entity25, PrimaryGeneratedColumn as PrimaryGeneratedColumn25, Column as Column25, ManyToOne as ManyToOne15, JoinColumn as JoinColumn15 } from "typeorm";
2575
+ var ProductAttribute = class {
2576
+ id;
2577
+ productId;
2578
+ attributeId;
2579
+ value;
2580
+ metadata;
2581
+ createdAt;
2582
+ updatedAt;
2583
+ product;
2584
+ attribute;
2585
+ };
2586
+ __decorateClass([
2587
+ PrimaryGeneratedColumn25()
2588
+ ], ProductAttribute.prototype, "id", 2);
2589
+ __decorateClass([
2590
+ Column25("int")
2591
+ ], ProductAttribute.prototype, "productId", 2);
2592
+ __decorateClass([
2593
+ Column25("int")
2594
+ ], ProductAttribute.prototype, "attributeId", 2);
2595
+ __decorateClass([
2596
+ Column25("varchar")
2597
+ ], ProductAttribute.prototype, "value", 2);
2598
+ __decorateClass([
2599
+ Column25("jsonb", { nullable: true })
2600
+ ], ProductAttribute.prototype, "metadata", 2);
2601
+ __decorateClass([
2602
+ Column25({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2603
+ ], ProductAttribute.prototype, "createdAt", 2);
2604
+ __decorateClass([
2605
+ Column25({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2606
+ ], ProductAttribute.prototype, "updatedAt", 2);
2607
+ __decorateClass([
2608
+ ManyToOne15(() => Product, (p) => p.attributes, { onDelete: "CASCADE" }),
2609
+ JoinColumn15({ name: "productId" })
2610
+ ], ProductAttribute.prototype, "product", 2);
2611
+ __decorateClass([
2612
+ ManyToOne15(() => Attribute, { onDelete: "CASCADE" }),
2613
+ JoinColumn15({ name: "attributeId" })
2614
+ ], ProductAttribute.prototype, "attribute", 2);
2615
+ ProductAttribute = __decorateClass([
2616
+ Entity25("product_attributes")
2617
+ ], ProductAttribute);
2618
+
2619
+ // src/entities/tax.entity.ts
2620
+ import { Entity as Entity26, PrimaryGeneratedColumn as PrimaryGeneratedColumn26, Column as Column26 } from "typeorm";
2621
+ var Tax = class {
2622
+ id;
2623
+ name;
2624
+ slug;
2625
+ rate;
2626
+ isDefault;
2627
+ description;
2628
+ active;
2629
+ metadata;
2630
+ createdAt;
2631
+ updatedAt;
2632
+ deletedAt;
2633
+ deleted;
2634
+ createdBy;
2635
+ updatedBy;
2636
+ deletedBy;
2637
+ };
2638
+ __decorateClass([
2639
+ PrimaryGeneratedColumn26()
2640
+ ], Tax.prototype, "id", 2);
2641
+ __decorateClass([
2642
+ Column26("varchar")
2643
+ ], Tax.prototype, "name", 2);
2644
+ __decorateClass([
2645
+ Column26("varchar", { unique: true })
2646
+ ], Tax.prototype, "slug", 2);
2647
+ __decorateClass([
2648
+ Column26("decimal", { precision: 5, scale: 2 })
2649
+ ], Tax.prototype, "rate", 2);
2650
+ __decorateClass([
2651
+ Column26("boolean", { default: false })
2652
+ ], Tax.prototype, "isDefault", 2);
2653
+ __decorateClass([
2654
+ Column26("text", { nullable: true })
2655
+ ], Tax.prototype, "description", 2);
2656
+ __decorateClass([
2657
+ Column26("boolean", { default: true })
2658
+ ], Tax.prototype, "active", 2);
2659
+ __decorateClass([
2660
+ Column26("jsonb", { nullable: true })
2661
+ ], Tax.prototype, "metadata", 2);
2662
+ __decorateClass([
2663
+ Column26({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2664
+ ], Tax.prototype, "createdAt", 2);
2665
+ __decorateClass([
2666
+ Column26({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2667
+ ], Tax.prototype, "updatedAt", 2);
2668
+ __decorateClass([
2669
+ Column26({ type: "timestamp", nullable: true })
2670
+ ], Tax.prototype, "deletedAt", 2);
2671
+ __decorateClass([
2672
+ Column26("boolean", { default: false })
2673
+ ], Tax.prototype, "deleted", 2);
2674
+ __decorateClass([
2675
+ Column26("int", { nullable: true })
2676
+ ], Tax.prototype, "createdBy", 2);
2677
+ __decorateClass([
2678
+ Column26("int", { nullable: true })
2679
+ ], Tax.prototype, "updatedBy", 2);
2680
+ __decorateClass([
2681
+ Column26("int", { nullable: true })
2682
+ ], Tax.prototype, "deletedBy", 2);
2683
+ Tax = __decorateClass([
2684
+ Entity26("taxes")
2685
+ ], Tax);
2686
+
2687
+ // src/entities/product-tax.entity.ts
2688
+ import { Entity as Entity27, PrimaryGeneratedColumn as PrimaryGeneratedColumn27, Column as Column27, ManyToOne as ManyToOne16, JoinColumn as JoinColumn16 } from "typeorm";
2689
+ var ProductTax = class {
2690
+ id;
2691
+ productId;
2692
+ taxId;
2693
+ rate;
2694
+ createdAt;
2695
+ updatedAt;
2696
+ product;
2697
+ tax;
2698
+ };
2699
+ __decorateClass([
2700
+ PrimaryGeneratedColumn27()
2701
+ ], ProductTax.prototype, "id", 2);
2702
+ __decorateClass([
2703
+ Column27("int")
2704
+ ], ProductTax.prototype, "productId", 2);
2705
+ __decorateClass([
2706
+ Column27("int")
2707
+ ], ProductTax.prototype, "taxId", 2);
2708
+ __decorateClass([
2709
+ Column27("decimal", { precision: 5, scale: 2, nullable: true })
2710
+ ], ProductTax.prototype, "rate", 2);
2711
+ __decorateClass([
2712
+ Column27({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2713
+ ], ProductTax.prototype, "createdAt", 2);
2714
+ __decorateClass([
2715
+ Column27({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2716
+ ], ProductTax.prototype, "updatedAt", 2);
2717
+ __decorateClass([
2718
+ ManyToOne16(() => Product, (p) => p.taxes, { onDelete: "CASCADE" }),
2719
+ JoinColumn16({ name: "productId" })
2720
+ ], ProductTax.prototype, "product", 2);
2721
+ __decorateClass([
2722
+ ManyToOne16(() => Tax, { onDelete: "CASCADE" }),
2723
+ JoinColumn16({ name: "taxId" })
2724
+ ], ProductTax.prototype, "tax", 2);
2725
+ ProductTax = __decorateClass([
2726
+ Entity27("product_taxes")
2727
+ ], ProductTax);
2728
+
2729
+ // src/entities/order-item.entity.ts
2730
+ import { Entity as Entity28, PrimaryGeneratedColumn as PrimaryGeneratedColumn28, Column as Column28, ManyToOne as ManyToOne17, JoinColumn as JoinColumn17 } from "typeorm";
2731
+ var OrderItem = class {
2732
+ id;
2733
+ orderId;
2734
+ productId;
2735
+ quantity;
2736
+ unitPrice;
2737
+ tax;
2738
+ total;
2739
+ metadata;
2740
+ createdAt;
2741
+ updatedAt;
2742
+ order;
2743
+ product;
2744
+ };
2745
+ __decorateClass([
2746
+ PrimaryGeneratedColumn28()
2747
+ ], OrderItem.prototype, "id", 2);
2748
+ __decorateClass([
2749
+ Column28("int")
2750
+ ], OrderItem.prototype, "orderId", 2);
2751
+ __decorateClass([
2752
+ Column28("int")
2753
+ ], OrderItem.prototype, "productId", 2);
2754
+ __decorateClass([
2755
+ Column28("int", { default: 1 })
2756
+ ], OrderItem.prototype, "quantity", 2);
2757
+ __decorateClass([
2758
+ Column28("decimal", { precision: 12, scale: 2 })
2759
+ ], OrderItem.prototype, "unitPrice", 2);
2760
+ __decorateClass([
2761
+ Column28("decimal", { precision: 12, scale: 2, default: 0 })
2762
+ ], OrderItem.prototype, "tax", 2);
2763
+ __decorateClass([
2764
+ Column28("decimal", { precision: 12, scale: 2 })
2765
+ ], OrderItem.prototype, "total", 2);
2766
+ __decorateClass([
2767
+ Column28("jsonb", { nullable: true })
2768
+ ], OrderItem.prototype, "metadata", 2);
2769
+ __decorateClass([
2770
+ Column28({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2771
+ ], OrderItem.prototype, "createdAt", 2);
2772
+ __decorateClass([
2773
+ Column28({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
2774
+ ], OrderItem.prototype, "updatedAt", 2);
2775
+ __decorateClass([
2776
+ ManyToOne17(() => Order, (o) => o.items, { onDelete: "CASCADE" }),
2777
+ JoinColumn17({ name: "orderId" })
2778
+ ], OrderItem.prototype, "order", 2);
2779
+ __decorateClass([
2780
+ ManyToOne17(() => Product, { onDelete: "CASCADE" }),
2781
+ JoinColumn17({ name: "productId" })
2782
+ ], OrderItem.prototype, "product", 2);
2783
+ OrderItem = __decorateClass([
2784
+ Entity28("order_items")
2785
+ ], OrderItem);
2786
+
2787
+ // src/entities/index.ts
2788
+ var CMS_ENTITY_MAP = {
2789
+ users: User,
2790
+ password_reset_tokens: PasswordResetToken,
2791
+ user_groups: UserGroup,
2792
+ permissions: Permission,
2793
+ blogs: Blog,
2794
+ tags: Tag,
2795
+ categories: Category,
2796
+ comments: Comment,
2797
+ contacts: Contact,
2798
+ addresses: Address,
2799
+ forms: Form,
2800
+ form_fields: FormField,
2801
+ form_submissions: FormSubmission,
2802
+ seos: Seo,
2803
+ configs: Config,
2804
+ media: Media,
2805
+ pages: Page,
2806
+ product_categories: ProductCategory,
2807
+ collections: Collection,
2808
+ products: Product,
2809
+ attributes: Attribute,
2810
+ product_attributes: ProductAttribute,
2811
+ taxes: Tax,
2812
+ product_taxes: ProductTax,
2813
+ orders: Order,
2814
+ order_items: OrderItem,
2815
+ payments: Payment,
2816
+ brands: Brand
2817
+ };
2818
+
2819
+ // src/auth/helpers.ts
2820
+ var OPEN_ENDPOINTS = [
2821
+ { "/api/contacts": ["POST"] },
2822
+ { "/api/form-submissions": ["POST"] },
2823
+ { "/api/blogs": ["GET"] }
2824
+ ];
2825
+ var PERMISSION_REQUIRED_ENDPOINTS = {};
2826
+ function isOpenEndpoint(pathname) {
2827
+ return OPEN_ENDPOINTS.some((endpoint) => pathname.startsWith(Object.keys(endpoint)[0]));
2828
+ }
2829
+ function getRequiredPermission(pathname) {
2830
+ return null;
2831
+ }
2832
+ function isPublicMethod(pathname, method) {
1731
2833
  for (const endpoint of OPEN_ENDPOINTS) {
1732
2834
  const key = Object.keys(endpoint)[0];
1733
2835
  if (pathname.startsWith(key) && endpoint[key].includes(method)) return true;
@@ -1880,7 +2982,7 @@ function getNextAuthOptions(config) {
1880
2982
  }
1881
2983
 
1882
2984
  // src/api/crud.ts
1883
- import { ILike, Like } from "typeorm";
2985
+ import { ILike, Like, MoreThan } from "typeorm";
1884
2986
  var DATE_COLUMN_TYPES = /* @__PURE__ */ new Set([
1885
2987
  "date",
1886
2988
  "datetime",
@@ -1925,14 +3027,156 @@ function createCrudHandler(dataSource, entityMap, options) {
1925
3027
  if (!resource || !entity) {
1926
3028
  return json({ error: "Invalid resource" }, { status: 400 });
1927
3029
  }
1928
- const repo = dataSource.getRepository(entity);
1929
3030
  const { searchParams } = new URL(req.url);
1930
3031
  const page = Number(searchParams.get("page")) || 1;
1931
- const limit = Number(searchParams.get("limit")) || 10;
3032
+ const limit = Math.min(Number(searchParams.get("limit")) || 10, 100);
1932
3033
  const skip = (page - 1) * limit;
1933
- const sortField = searchParams.get("sortField") || "createdAt";
3034
+ const sortFieldRaw = searchParams.get("sortField") || "createdAt";
1934
3035
  const sortOrder = searchParams.get("sortOrder") === "desc" ? "DESC" : "ASC";
1935
3036
  const search = searchParams.get("search");
3037
+ if (resource === "orders") {
3038
+ const repo2 = dataSource.getRepository(entity);
3039
+ const allowedSort = ["id", "orderNumber", "contactId", "status", "total", "currency", "createdAt", "updatedAt"];
3040
+ const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : "createdAt";
3041
+ const sortOrderOrders = searchParams.get("sortOrder") === "asc" ? "ASC" : "DESC";
3042
+ const statusFilter = searchParams.get("status")?.trim();
3043
+ const dateFrom = searchParams.get("dateFrom")?.trim();
3044
+ const dateTo = searchParams.get("dateTo")?.trim();
3045
+ const paymentRef = searchParams.get("paymentRef")?.trim();
3046
+ let orderIdsFromPayment = null;
3047
+ if (paymentRef && entityMap["payments"]) {
3048
+ const paymentRepo = dataSource.getRepository(entityMap["payments"]);
3049
+ const payments = await paymentRepo.createQueryBuilder("p").select("p.orderId").where("p.externalReference = :ref", { ref: paymentRef }).orWhere("p.metadata->>'razorpayPaymentId' = :ref", { ref: paymentRef }).getRawMany();
3050
+ orderIdsFromPayment = payments.map((r) => r.orderId);
3051
+ if (orderIdsFromPayment.length === 0) {
3052
+ return json({ total: 0, page, limit, totalPages: 0, data: [] });
3053
+ }
3054
+ }
3055
+ const qb = repo2.createQueryBuilder("order").leftJoinAndSelect("order.contact", "contact").leftJoinAndSelect("order.items", "items").leftJoinAndSelect("items.product", "product").leftJoinAndSelect("product.collection", "collection").orderBy(`order.${sortField}`, sortOrderOrders).skip(skip).take(limit);
3056
+ if (search && typeof search === "string" && search.trim()) {
3057
+ const term = `%${search.trim()}%`;
3058
+ qb.andWhere(
3059
+ "(order.orderNumber ILIKE :term OR contact.name ILIKE :term OR contact.email ILIKE :term)",
3060
+ { term }
3061
+ );
3062
+ }
3063
+ if (statusFilter) qb.andWhere("order.status = :status", { status: statusFilter });
3064
+ if (dateFrom) qb.andWhere("order.createdAt >= :dateFrom", { dateFrom: /* @__PURE__ */ new Date(dateFrom + "T00:00:00.000Z") });
3065
+ if (dateTo) qb.andWhere("order.createdAt <= :dateTo", { dateTo: /* @__PURE__ */ new Date(dateTo + "T23:59:59.999Z") });
3066
+ if (orderIdsFromPayment && orderIdsFromPayment.length) qb.andWhere("order.id IN (:...orderIds)", { orderIds: orderIdsFromPayment });
3067
+ const [rows, total2] = await qb.getManyAndCount();
3068
+ const data2 = rows.map((order) => {
3069
+ const contact = order.contact;
3070
+ const items = order.items ?? [];
3071
+ const itemsSummary = items.map((i) => {
3072
+ const label = i.product?.collection?.name ?? i.product?.name ?? "Product";
3073
+ return `${label} \xD7 ${i.quantity}`;
3074
+ }).join(", ") || "\u2014";
3075
+ return {
3076
+ ...order,
3077
+ contact: contact ? { id: contact.id, name: contact.name, email: contact.email, phone: contact.phone } : null,
3078
+ itemsSummary
3079
+ };
3080
+ });
3081
+ return json({ total: total2, page, limit, totalPages: Math.ceil(total2 / limit), data: data2 });
3082
+ }
3083
+ if (resource === "payments") {
3084
+ const repo2 = dataSource.getRepository(entity);
3085
+ const allowedSort = ["id", "orderId", "amount", "currency", "status", "method", "paidAt", "createdAt", "updatedAt"];
3086
+ const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : "createdAt";
3087
+ const sortOrderPayments = searchParams.get("sortOrder") === "asc" ? "ASC" : "DESC";
3088
+ const statusFilter = searchParams.get("status")?.trim();
3089
+ const dateFrom = searchParams.get("dateFrom")?.trim();
3090
+ const dateTo = searchParams.get("dateTo")?.trim();
3091
+ const methodFilter = searchParams.get("method")?.trim();
3092
+ const orderNumberParam = searchParams.get("orderNumber")?.trim();
3093
+ const qb = repo2.createQueryBuilder("payment").leftJoinAndSelect("payment.order", "ord").leftJoinAndSelect("ord.contact", "orderContact").leftJoinAndSelect("payment.contact", "contact").orderBy(`payment.${sortField}`, sortOrderPayments).skip(skip).take(limit);
3094
+ if (search && typeof search === "string" && search.trim()) {
3095
+ const term = `%${search.trim()}%`;
3096
+ qb.andWhere(
3097
+ "(orderContact.name ILIKE :term OR orderContact.email ILIKE :term OR contact.name ILIKE :term OR contact.email ILIKE :term)",
3098
+ { term }
3099
+ );
3100
+ }
3101
+ if (statusFilter) qb.andWhere("payment.status = :status", { status: statusFilter });
3102
+ if (dateFrom) qb.andWhere("payment.createdAt >= :dateFrom", { dateFrom: /* @__PURE__ */ new Date(dateFrom + "T00:00:00.000Z") });
3103
+ if (dateTo) qb.andWhere("payment.createdAt <= :dateTo", { dateTo: /* @__PURE__ */ new Date(dateTo + "T23:59:59.999Z") });
3104
+ if (methodFilter) qb.andWhere("payment.method = :method", { method: methodFilter });
3105
+ if (orderNumberParam) qb.andWhere("ord.orderNumber ILIKE :orderNumber", { orderNumber: `%${orderNumberParam}%` });
3106
+ const [rows, total2] = await qb.getManyAndCount();
3107
+ const data2 = rows.map((payment) => {
3108
+ const order = payment.order;
3109
+ const orderContact = order?.contact;
3110
+ const contact = payment.contact;
3111
+ const customer = orderContact ?? contact;
3112
+ return {
3113
+ ...payment,
3114
+ order: order ? { id: order.id, orderNumber: order.orderNumber, contact: orderContact ? { name: orderContact.name, email: orderContact.email } : null } : null,
3115
+ contact: customer ? { id: customer.id, name: customer.name, email: customer.email } : null
3116
+ };
3117
+ });
3118
+ return json({ total: total2, page, limit, totalPages: Math.ceil(total2 / limit), data: data2 });
3119
+ }
3120
+ if (resource === "products") {
3121
+ const repo2 = dataSource.getRepository(entity);
3122
+ const statusFilter = searchParams.get("status")?.trim();
3123
+ const inventory = searchParams.get("inventory")?.trim();
3124
+ const productWhere = {};
3125
+ if (statusFilter) productWhere.status = statusFilter;
3126
+ if (inventory === "in_stock") productWhere.quantity = MoreThan(0);
3127
+ if (inventory === "out_of_stock") productWhere.quantity = 0;
3128
+ if (search && typeof search === "string" && search.trim()) {
3129
+ productWhere.name = ILike(`%${search.trim()}%`);
3130
+ }
3131
+ const [data2, total2] = await repo2.findAndCount({
3132
+ where: Object.keys(productWhere).length ? productWhere : void 0,
3133
+ skip,
3134
+ take: limit,
3135
+ order: { [sortFieldRaw]: sortOrder }
3136
+ });
3137
+ return json({ total: total2, page, limit, totalPages: Math.ceil(total2 / limit), data: data2 });
3138
+ }
3139
+ if (resource === "contacts") {
3140
+ const repo2 = dataSource.getRepository(entity);
3141
+ const allowedSort = ["id", "name", "email", "createdAt", "type"];
3142
+ const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : "createdAt";
3143
+ const sortOrderContacts = searchParams.get("sortOrder") === "asc" ? "ASC" : "DESC";
3144
+ const typeFilter2 = searchParams.get("type")?.trim();
3145
+ const orderIdParam = searchParams.get("orderId")?.trim();
3146
+ const includeSummary = searchParams.get("includeSummary") === "1";
3147
+ const qb = repo2.createQueryBuilder("contact").orderBy(`contact.${sortField}`, sortOrderContacts).skip(skip).take(limit);
3148
+ if (search && typeof search === "string" && search.trim()) {
3149
+ const term = `%${search.trim()}%`;
3150
+ qb.andWhere("(contact.name ILIKE :term OR contact.email ILIKE :term OR contact.phone ILIKE :term)", { term });
3151
+ }
3152
+ if (typeFilter2) qb.andWhere("contact.type = :type", { type: typeFilter2 });
3153
+ if (orderIdParam) {
3154
+ const orderId = Number(orderIdParam);
3155
+ if (!Number.isNaN(orderId)) {
3156
+ qb.andWhere('contact.id IN (SELECT "contactId" FROM orders WHERE id = :orderId)', { orderId });
3157
+ }
3158
+ }
3159
+ if (includeSummary && entityMap["orders"] && entityMap["payments"]) {
3160
+ qb.loadRelationCountAndMap("contact._orderCount", "contact.orders");
3161
+ const [rows, total3] = await qb.getManyAndCount();
3162
+ const contactIds = rows.map((c) => c.id);
3163
+ const paymentRepo = dataSource.getRepository(entityMap["payments"]);
3164
+ const paidByContact = await paymentRepo.createQueryBuilder("p").select("p.contactId", "contactId").addSelect("COALESCE(SUM(CAST(p.amount AS DECIMAL)), 0)", "total").where("p.contactId IN (:...ids)", { ids: contactIds.length ? contactIds : [0] }).andWhere("p.status = :status", { status: "completed" }).groupBy("p.contactId").getRawMany();
3165
+ const totalPaidMap = new Map(paidByContact.map((r) => [r.contactId, Number(r.total)]));
3166
+ const data3 = rows.map((c) => {
3167
+ const { _orderCount, ...rest } = c;
3168
+ return {
3169
+ ...rest,
3170
+ orderCount: _orderCount ?? 0,
3171
+ totalPaid: totalPaidMap.get(rest.id) ?? 0
3172
+ };
3173
+ });
3174
+ return json({ total: total3, page, limit, totalPages: Math.ceil(total3 / limit), data: data3 });
3175
+ }
3176
+ const [data2, total2] = await qb.getManyAndCount();
3177
+ return json({ total: total2, page, limit, totalPages: Math.ceil(total2 / limit), data: data2 });
3178
+ }
3179
+ const repo = dataSource.getRepository(entity);
1936
3180
  const typeFilter = searchParams.get("type");
1937
3181
  let where = {};
1938
3182
  if (resource === "media") {
@@ -1946,7 +3190,7 @@ function createCrudHandler(dataSource, entityMap, options) {
1946
3190
  const [data, total] = await repo.findAndCount({
1947
3191
  skip,
1948
3192
  take: limit,
1949
- order: { [sortField]: sortOrder },
3193
+ order: { [sortFieldRaw]: sortOrder },
1950
3194
  where
1951
3195
  });
1952
3196
  return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });
@@ -1966,6 +3210,107 @@ function createCrudHandler(dataSource, entityMap, options) {
1966
3210
  sanitizeBodyForEntity(repo, body);
1967
3211
  const created = await repo.save(repo.create(body));
1968
3212
  return json(created, { status: 201 });
3213
+ },
3214
+ async GET_METADATA(req, resource) {
3215
+ const authError = await requireAuth(req);
3216
+ if (authError) return authError;
3217
+ const entity = entityMap[resource];
3218
+ if (!resource || !entity) {
3219
+ return json({ error: "Invalid resource" }, { status: 400 });
3220
+ }
3221
+ const repo = dataSource.getRepository(entity);
3222
+ const meta = repo.metadata;
3223
+ const uniqueFromIndices = /* @__PURE__ */ new Set();
3224
+ for (const idx of meta.indices) {
3225
+ if (idx.isUnique && idx.columns.length === 1) {
3226
+ uniqueFromIndices.add(idx.columns[0].propertyName);
3227
+ }
3228
+ }
3229
+ for (const uniq of meta.uniques) {
3230
+ if (uniq.columns.length === 1) {
3231
+ uniqueFromIndices.add(uniq.columns[0].propertyName);
3232
+ }
3233
+ }
3234
+ const columns = meta.columns.map((col) => ({
3235
+ name: col.propertyName,
3236
+ type: typeof col.type === "string" ? col.type : col.type?.name ?? "unknown",
3237
+ nullable: col.isNullable,
3238
+ isUnique: uniqueFromIndices.has(col.propertyName),
3239
+ isPrimary: col.isPrimary,
3240
+ default: col.default
3241
+ }));
3242
+ const uniqueColumns = [...uniqueFromIndices];
3243
+ return json({ columns, uniqueColumns });
3244
+ },
3245
+ async BULK_POST(req, resource) {
3246
+ const authError = await requireAuth(req);
3247
+ if (authError) return authError;
3248
+ const entity = entityMap[resource];
3249
+ if (!resource || !entity) {
3250
+ return json({ error: "Invalid resource" }, { status: 400 });
3251
+ }
3252
+ const body = await req.json();
3253
+ const { records, upsertKey = "id" } = body;
3254
+ if (!Array.isArray(records) || records.length === 0) {
3255
+ return json({ error: "Records array is required" }, { status: 400 });
3256
+ }
3257
+ const repo = dataSource.getRepository(entity);
3258
+ for (const record of records) {
3259
+ sanitizeBodyForEntity(repo, record);
3260
+ }
3261
+ try {
3262
+ const result = await repo.upsert(records, {
3263
+ conflictPaths: [upsertKey],
3264
+ skipUpdateIfNoValuesChanged: true
3265
+ });
3266
+ return json({
3267
+ success: true,
3268
+ imported: result.identifiers.length,
3269
+ identifiers: result.identifiers
3270
+ });
3271
+ } catch (error) {
3272
+ const message = error instanceof Error ? error.message : "Bulk import failed";
3273
+ return json({ error: message }, { status: 400 });
3274
+ }
3275
+ },
3276
+ async GET_EXPORT(req, resource) {
3277
+ const authError = await requireAuth(req);
3278
+ if (authError) return authError;
3279
+ const entity = entityMap[resource];
3280
+ if (!resource || !entity) {
3281
+ return json({ error: "Invalid resource" }, { status: 400 });
3282
+ }
3283
+ const { searchParams } = new URL(req.url);
3284
+ const format = searchParams.get("format") || "csv";
3285
+ const repo = dataSource.getRepository(entity);
3286
+ const meta = repo.metadata;
3287
+ const hasDeleted = meta.columns.some((c) => c.propertyName === "deleted");
3288
+ const where = hasDeleted ? { deleted: false } : {};
3289
+ const data = await repo.find({ where });
3290
+ const excludeCols = /* @__PURE__ */ new Set(["deletedAt", "deletedBy", "deleted"]);
3291
+ const columns = meta.columns.filter((c) => !excludeCols.has(c.propertyName)).map((c) => c.propertyName);
3292
+ if (format === "json") {
3293
+ return json(data);
3294
+ }
3295
+ const escapeCSV = (val) => {
3296
+ if (val === null || val === void 0) return "";
3297
+ const str = typeof val === "object" ? JSON.stringify(val) : String(val);
3298
+ if (str.includes(",") || str.includes('"') || str.includes("\n")) {
3299
+ return `"${str.replace(/"/g, '""')}"`;
3300
+ }
3301
+ return str;
3302
+ };
3303
+ const header = columns.join(",");
3304
+ const rows = data.map(
3305
+ (row) => columns.map((col) => escapeCSV(row[col])).join(",")
3306
+ );
3307
+ const csv = [header, ...rows].join("\n");
3308
+ return new Response(csv, {
3309
+ headers: {
3310
+ "Content-Type": "text/csv; charset=utf-8",
3311
+ "Content-Disposition": `attachment; filename="${resource}.csv"`
3312
+ }
3313
+ });
1969
3314
  }
1970
3315
  };
1971
3316
  }
@@ -1978,6 +3323,44 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
1978
3323
  const entity = entityMap[resource];
1979
3324
  if (!entity) return json({ error: "Invalid resource" }, { status: 400 });
1980
3325
  const repo = dataSource.getRepository(entity);
3326
+ if (resource === "orders") {
3327
+ const order = await repo.findOne({
3328
+ where: { id: Number(id) },
3329
+ relations: ["contact", "billingAddress", "shippingAddress", "items", "items.product", "items.product.collection", "payments"]
3330
+ });
3331
+ if (!order) return json({ message: "Not found" }, { status: 404 });
3332
+ return json(order);
3333
+ }
3334
+ if (resource === "contacts") {
3335
+ const contact = await repo.findOne({
3336
+ where: { id: Number(id) },
3337
+ relations: ["form_submissions", "form_submissions.form", "orders", "payments", "addresses"]
3338
+ });
3339
+ if (!contact) return json({ message: "Not found" }, { status: 404 });
3340
+ const orders = contact.orders ?? [];
3341
+ const payments = contact.payments ?? [];
3342
+ const totalPaid = payments.filter((p) => p.status === "completed").reduce((sum, p) => sum + Number(p.amount ?? 0), 0);
3343
+ const lastOrderAt = orders.length > 0 ? orders.reduce((latest, o) => {
3344
+ const t = o.createdAt ? new Date(o.createdAt).getTime() : 0;
3345
+ return t > latest ? t : latest;
3346
+ }, 0) : null;
3347
+ return json({
3348
+ ...contact,
3349
+ summary: {
3350
+ totalOrders: orders.length,
3351
+ totalPaid,
3352
+ lastOrderAt: lastOrderAt ? new Date(lastOrderAt).toISOString() : null
3353
+ }
3354
+ });
3355
+ }
3356
+ if (resource === "payments") {
3357
+ const payment = await repo.findOne({
3358
+ where: { id: Number(id) },
3359
+ relations: ["order", "order.contact", "contact"]
3360
+ });
3361
+ if (!payment) return json({ message: "Not found" }, { status: 404 });
3362
+ return json(payment);
3363
+ }
1981
3364
  const item = await repo.findOne({ where: { id: Number(id) } });
1982
3365
  return item ? json(item) : json({ message: "Not found" }, { status: 404 });
1983
3366
  },
@@ -2018,8 +3401,8 @@ function createForgotPasswordHandler(config) {
2018
3401
  const user = await userRepo.findOne({ where: { email }, select: ["email"] });
2019
3402
  const msg = "If an account exists with this email, you will receive a reset link shortly.";
2020
3403
  if (!user) return json({ message: msg }, { status: 200 });
2021
- const crypto = await import("crypto");
2022
- const token = crypto.randomBytes(32).toString("hex");
3404
+ const crypto2 = await import("crypto");
3405
+ const token = crypto2.randomBytes(32).toString("hex");
2023
3406
  const expiresAt = new Date(Date.now() + resetExpiryHours * 60 * 60 * 1e3);
2024
3407
  const tokenRepo = dataSource.getRepository(entityMap.password_reset_tokens);
2025
3408
  await tokenRepo.save(tokenRepo.create({ email: user.email, token, expiresAt }));
@@ -2843,6 +4226,17 @@ function createCmsApiHandler(config) {
2843
4226
  if (path.length === 0) return config.json({ error: "Not found" }, { status: 404 });
2844
4227
  const resource = resolveResource(path[0]);
2845
4228
  if (!crudResources.includes(resource)) return config.json({ error: "Invalid resource" }, { status: 400 });
4229
+ if (path.length === 2) {
4230
+ if (path[1] === "metadata" && method === "GET") {
4231
+ return crud.GET_METADATA(req, resource);
4232
+ }
4233
+ if (path[1] === "bulk" && method === "POST") {
4234
+ return crud.BULK_POST(req, resource);
4235
+ }
4236
+ if (path[1] === "export" && method === "GET") {
4237
+ return crud.GET_EXPORT(req, resource);
4238
+ }
4239
+ }
2846
4240
  if (path.length === 1) {
2847
4241
  if (method === "GET") return crud.GET(req, resource);
2848
4242
  if (method === "POST") return crud.POST(req, resource);
@@ -2871,9 +4265,12 @@ var DEFAULT_ADMIN_NAV = [
2871
4265
  { href: "/admin/pages", label: "Pages" }
2872
4266
  ];
2873
4267
  export {
4268
+ Attribute,
2874
4269
  Blog,
4270
+ Brand,
2875
4271
  CMS_ENTITY_MAP,
2876
4272
  Category,
4273
+ Collection,
2877
4274
  Comment,
2878
4275
  Config,
2879
4276
  Contact,
@@ -2884,12 +4281,20 @@ export {
2884
4281
  FormSubmission,
2885
4282
  Media,
2886
4283
  OPEN_ENDPOINTS,
4284
+ Order,
4285
+ OrderItem,
2887
4286
  PERMISSION_REQUIRED_ENDPOINTS,
2888
4287
  Page,
2889
4288
  PasswordResetToken,
4289
+ Payment,
2890
4290
  Permission,
4291
+ Product,
4292
+ ProductAttribute,
4293
+ ProductCategory,
4294
+ ProductTax,
2891
4295
  Seo,
2892
4296
  Tag,
4297
+ Tax,
2893
4298
  User,
2894
4299
  UserGroup,
2895
4300
  analyticsPlugin,