recur-tw 0.3.3 → 0.3.5
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.cjs +192 -83
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +192 -83
- package/dist/recur.umd.js +165 -78
- package/package.json +12 -12
package/dist/recur.umd.js
CHANGED
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
<p class="recur-sdk__success-message">${this.successMessage}</p>
|
|
122
122
|
<slot></slot>
|
|
123
123
|
</div>
|
|
124
|
-
`}};typeof window<"u"&&!customElements.get("recur-success-message")&&customElements.define("recur-success-message",w)});var B={};d(B,{RecurErrorDisplay:()=>E});var E,
|
|
124
|
+
`}};typeof window<"u"&&!customElements.get("recur-success-message")&&customElements.define("recur-success-message",w)});var B={};d(B,{RecurErrorDisplay:()=>E});var E,N=m(()=>{"use strict";E=class extends HTMLElement{static get observedAttributes(){return["error","dismissible"]}constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){this.render()}attributeChangedCallback(e,t,r){t!==r&&this.render()}get error(){return this.getAttribute("error")||""}get isDismissible(){return this.getAttribute("dismissible")==="true"}handleDismiss(){this.dispatchEvent(new CustomEvent("dismiss",{bubbles:!0,composed:!0})),this.remove()}render(){if(!this.error){this.shadowRoot.innerHTML="";return}this.shadowRoot.innerHTML=`
|
|
125
125
|
<style>
|
|
126
126
|
:host {
|
|
127
127
|
display: block;
|
|
@@ -211,7 +211,7 @@
|
|
|
211
211
|
</button>
|
|
212
212
|
`:""}
|
|
213
213
|
</div>
|
|
214
|
-
`,this.isDismissible&&this.shadowRoot.querySelector(".recur-sdk__error-dismiss")?.addEventListener("click",()=>this.handleDismiss())}};typeof window<"u"&&!customElements.get("recur-error-display")&&customElements.define("recur-error-display",E)});var
|
|
214
|
+
`,this.isDismissible&&this.shadowRoot.querySelector(".recur-sdk__error-dismiss")?.addEventListener("click",()=>this.handleDismiss())}};typeof window<"u"&&!customElements.get("recur-error-display")&&customElements.define("recur-error-display",E)});var D={};d(D,{RecurSkeletonLoader:()=>C});var C,O=m(()=>{"use strict";C=class extends HTMLElement{static get observedAttributes(){return["type"]}constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){this.render()}attributeChangedCallback(e,t,r){t!==r&&this.render()}get type(){let e=this.getAttribute("type");return e==="list"||e==="card"?e:"payment-form"}renderPaymentFormSkeleton(){return`
|
|
215
215
|
<div class="skeleton-field">
|
|
216
216
|
<div class="skeleton-label"></div>
|
|
217
217
|
<div class="skeleton-input"></div>
|
|
@@ -397,21 +397,36 @@
|
|
|
397
397
|
margin-bottom: 24px;
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
+
.form-title {
|
|
401
|
+
font-size: 20px;
|
|
402
|
+
font-weight: 600;
|
|
403
|
+
color: #1a202c;
|
|
404
|
+
margin: 0 0 4px 0;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.form-subtitle {
|
|
408
|
+
font-size: 14px;
|
|
409
|
+
color: #718096;
|
|
410
|
+
margin: 0;
|
|
411
|
+
}
|
|
412
|
+
|
|
400
413
|
.form-section {
|
|
401
414
|
margin-bottom: 24px;
|
|
402
415
|
}
|
|
403
416
|
|
|
404
417
|
.section-title {
|
|
405
|
-
|
|
406
|
-
font-size: 16px;
|
|
418
|
+
font-size: 14px;
|
|
407
419
|
font-weight: 600;
|
|
408
420
|
color: #2d3748;
|
|
421
|
+
margin: 0 0 12px 0;
|
|
409
422
|
}
|
|
410
423
|
|
|
411
424
|
.label {
|
|
425
|
+
display: block;
|
|
412
426
|
font-size: 14px;
|
|
413
|
-
|
|
414
|
-
|
|
427
|
+
font-weight: 500;
|
|
428
|
+
color: #2d3748;
|
|
429
|
+
margin-bottom: 6px;
|
|
415
430
|
}
|
|
416
431
|
|
|
417
432
|
/* Skeleton base styles */
|
|
@@ -419,7 +434,7 @@
|
|
|
419
434
|
background: linear-gradient(
|
|
420
435
|
90deg,
|
|
421
436
|
#f0f0f0 0%,
|
|
422
|
-
#
|
|
437
|
+
#e8e8e8 50%,
|
|
423
438
|
#f0f0f0 100%
|
|
424
439
|
);
|
|
425
440
|
background-size: 200% 100%;
|
|
@@ -436,68 +451,109 @@
|
|
|
436
451
|
}
|
|
437
452
|
}
|
|
438
453
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
454
|
+
/* Order Summary */
|
|
455
|
+
.order-summary {
|
|
456
|
+
background: #f7fafc;
|
|
457
|
+
border: 1px solid #e2e8f0;
|
|
458
|
+
border-radius: 8px;
|
|
459
|
+
padding: 16px;
|
|
460
|
+
margin-bottom: 24px;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.order-summary-title {
|
|
464
|
+
font-size: 14px;
|
|
465
|
+
font-weight: 600;
|
|
466
|
+
color: #2d3748;
|
|
467
|
+
margin: 0 0 12px 0;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.order-row {
|
|
471
|
+
display: flex;
|
|
472
|
+
justify-content: space-between;
|
|
473
|
+
align-items: center;
|
|
442
474
|
margin-bottom: 8px;
|
|
443
475
|
}
|
|
444
476
|
|
|
445
|
-
.
|
|
446
|
-
|
|
447
|
-
|
|
477
|
+
.order-row:last-child {
|
|
478
|
+
margin-bottom: 0;
|
|
479
|
+
padding-top: 12px;
|
|
480
|
+
border-top: 1px solid #e2e8f0;
|
|
448
481
|
}
|
|
449
482
|
|
|
450
|
-
.
|
|
451
|
-
|
|
483
|
+
.order-label {
|
|
484
|
+
font-size: 14px;
|
|
485
|
+
color: #4a5568;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.skeleton-order-value {
|
|
489
|
+
height: 20px;
|
|
490
|
+
width: 80px;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
.skeleton-order-total {
|
|
494
|
+
height: 26px;
|
|
495
|
+
width: 100px;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/* Customer Info Display */
|
|
499
|
+
.customer-info-display {
|
|
452
500
|
background: #f7fafc;
|
|
501
|
+
border: 1px solid #e2e8f0;
|
|
453
502
|
border-radius: 6px;
|
|
454
|
-
|
|
503
|
+
padding: 12px;
|
|
504
|
+
margin-bottom: 8px;
|
|
455
505
|
}
|
|
456
506
|
|
|
457
|
-
.
|
|
507
|
+
.info-row {
|
|
458
508
|
display: flex;
|
|
459
|
-
justify-content: space-between;
|
|
460
509
|
align-items: center;
|
|
461
|
-
margin-bottom:
|
|
510
|
+
margin-bottom: 6px;
|
|
462
511
|
}
|
|
463
512
|
|
|
464
|
-
.
|
|
513
|
+
.info-row:last-child {
|
|
465
514
|
margin-bottom: 0;
|
|
466
|
-
padding-top: 12px;
|
|
467
|
-
border-top: 1px solid #e2e8f0;
|
|
468
|
-
font-weight: 600;
|
|
469
515
|
}
|
|
470
516
|
|
|
471
|
-
.
|
|
517
|
+
.info-label {
|
|
518
|
+
font-size: 13px;
|
|
519
|
+
color: #718096;
|
|
520
|
+
min-width: 80px;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
.skeleton-info-value {
|
|
472
524
|
height: 20px;
|
|
473
525
|
width: 120px;
|
|
474
526
|
}
|
|
475
527
|
|
|
476
|
-
|
|
528
|
+
/* Card Fields */
|
|
529
|
+
.card-field {
|
|
477
530
|
margin-bottom: 16px;
|
|
478
531
|
}
|
|
479
532
|
|
|
480
|
-
.
|
|
533
|
+
.card-field:last-child {
|
|
481
534
|
margin-bottom: 0;
|
|
482
535
|
}
|
|
483
536
|
|
|
484
537
|
.skeleton-input {
|
|
485
|
-
height:
|
|
538
|
+
height: 36px;
|
|
486
539
|
width: 100%;
|
|
540
|
+
border-radius: 6px;
|
|
487
541
|
}
|
|
488
542
|
|
|
489
|
-
.card-
|
|
543
|
+
.card-row {
|
|
490
544
|
display: grid;
|
|
491
545
|
grid-template-columns: 1fr 1fr;
|
|
492
546
|
gap: 12px;
|
|
493
547
|
}
|
|
494
548
|
|
|
549
|
+
/* Submit Button - matches .recur-submit-button: padding 14px*2 + font 16px * line-height ~1.5 */
|
|
495
550
|
.skeleton-button {
|
|
496
|
-
height:
|
|
551
|
+
height: 52px;
|
|
497
552
|
width: 100%;
|
|
498
553
|
border-radius: 6px;
|
|
499
554
|
}
|
|
500
555
|
|
|
556
|
+
/* Security Note */
|
|
501
557
|
.security-note {
|
|
502
558
|
display: flex;
|
|
503
559
|
align-items: center;
|
|
@@ -520,73 +576,67 @@
|
|
|
520
576
|
</style>
|
|
521
577
|
|
|
522
578
|
<div class="payment-form-wrapper">
|
|
523
|
-
<!-- Header
|
|
579
|
+
<!-- Header (matches payment-form.ts) -->
|
|
524
580
|
<div class="form-header">
|
|
525
|
-
<
|
|
526
|
-
<
|
|
581
|
+
<h2 class="form-title">\u8A02\u95B1\u4ED8\u6B3E</h2>
|
|
582
|
+
<p class="form-subtitle">\u8ACB\u586B\u5BEB\u4FE1\u7528\u5361\u8CC7\u8A0A\u5B8C\u6210\u8A02\u95B1</p>
|
|
527
583
|
</div>
|
|
528
584
|
|
|
529
|
-
<!-- Order Summary
|
|
530
|
-
<div class="
|
|
531
|
-
<h3 class="
|
|
532
|
-
<div class="
|
|
533
|
-
<span class="label">\u65B9\u6848</span>
|
|
585
|
+
<!-- Order Summary (matches createOrderSummarySection) -->
|
|
586
|
+
<div class="order-summary">
|
|
587
|
+
<h3 class="order-summary-title">\u8A02\u55AE\u6458\u8981</h3>
|
|
588
|
+
<div class="order-row">
|
|
589
|
+
<span class="order-label">\u8A02\u95B1\u65B9\u6848</span>
|
|
534
590
|
<div class="skeleton skeleton-order-value"></div>
|
|
535
591
|
</div>
|
|
536
|
-
<div class="
|
|
537
|
-
<span class="label">\
|
|
592
|
+
<div class="order-row">
|
|
593
|
+
<span class="order-label">\u8A08\u8CBB\u9031\u671F</span>
|
|
538
594
|
<div class="skeleton skeleton-order-value"></div>
|
|
539
595
|
</div>
|
|
540
|
-
<div class="
|
|
541
|
-
<span class="label">\
|
|
542
|
-
<div class="skeleton skeleton-order-
|
|
543
|
-
</div>
|
|
544
|
-
<div class="skeleton-order-row">
|
|
545
|
-
<span class="label">\u7E3D\u8A08</span>
|
|
546
|
-
<div class="skeleton skeleton-order-value"></div>
|
|
596
|
+
<div class="order-row">
|
|
597
|
+
<span class="order-label">\u7E3D\u8A08</span>
|
|
598
|
+
<div class="skeleton skeleton-order-total"></div>
|
|
547
599
|
</div>
|
|
548
600
|
</div>
|
|
549
601
|
|
|
550
|
-
<!-- Customer Info Section
|
|
602
|
+
<!-- Customer Info Section (matches createCustomerInfoSection read-only display) -->
|
|
551
603
|
<div class="form-section">
|
|
552
604
|
<h3 class="section-title">\u5BA2\u6236\u8CC7\u8A0A</h3>
|
|
553
|
-
<div class="
|
|
554
|
-
<div class="
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
<div class="
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
<div class="label">\u96FB\u8A71\uFF08\u9078\u586B\uFF09</div>
|
|
563
|
-
<div class="skeleton skeleton-input"></div>
|
|
605
|
+
<div class="customer-info-display">
|
|
606
|
+
<div class="info-row">
|
|
607
|
+
<span class="info-label">\u5BA2\u6236\u59D3\u540D\uFF1A</span>
|
|
608
|
+
<div class="skeleton skeleton-info-value"></div>
|
|
609
|
+
</div>
|
|
610
|
+
<div class="info-row">
|
|
611
|
+
<span class="info-label">\u96FB\u5B50\u90F5\u4EF6\uFF1A</span>
|
|
612
|
+
<div class="skeleton skeleton-info-value" style="width: 160px;"></div>
|
|
613
|
+
</div>
|
|
564
614
|
</div>
|
|
565
615
|
</div>
|
|
566
616
|
|
|
567
|
-
<!-- Card Fields Section
|
|
617
|
+
<!-- Card Fields Section (matches createCardFieldsSection) -->
|
|
568
618
|
<div class="form-section">
|
|
569
619
|
<h3 class="section-title">\u4FE1\u7528\u5361\u8CC7\u8A0A</h3>
|
|
570
|
-
<div class="
|
|
571
|
-
<
|
|
620
|
+
<div class="card-field">
|
|
621
|
+
<label class="label">\u5361\u865F</label>
|
|
572
622
|
<div class="skeleton skeleton-input"></div>
|
|
573
623
|
</div>
|
|
574
|
-
<div class="card-
|
|
575
|
-
<div class="
|
|
576
|
-
<
|
|
624
|
+
<div class="card-row">
|
|
625
|
+
<div class="card-field">
|
|
626
|
+
<label class="label">\u6709\u6548\u671F\u9650</label>
|
|
577
627
|
<div class="skeleton skeleton-input"></div>
|
|
578
628
|
</div>
|
|
579
|
-
<div class="
|
|
580
|
-
<
|
|
629
|
+
<div class="card-field">
|
|
630
|
+
<label class="label">\u5B89\u5168\u78BC</label>
|
|
581
631
|
<div class="skeleton skeleton-input"></div>
|
|
582
632
|
</div>
|
|
583
633
|
</div>
|
|
584
634
|
</div>
|
|
585
635
|
|
|
586
|
-
<!-- Submit Button
|
|
636
|
+
<!-- Submit Button -->
|
|
587
637
|
<div class="skeleton skeleton-button"></div>
|
|
588
638
|
|
|
589
|
-
<!-- Security Note -->
|
|
639
|
+
<!-- Security Note (matches payment-form.ts) -->
|
|
590
640
|
<div class="security-note">
|
|
591
641
|
<svg class="security-icon" width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
592
642
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
|
@@ -594,7 +644,7 @@
|
|
|
594
644
|
<p class="security-text">\u60A8\u7684\u4ED8\u6B3E\u8CC7\u8A0A\u7D93\u904E\u52A0\u5BC6\u4FDD\u8B77</p>
|
|
595
645
|
</div>
|
|
596
646
|
</div>
|
|
597
|
-
`}};typeof window<"u"&&!customElements.get("recur-payment-form-skeleton")&&customElements.define("recur-payment-form-skeleton",T)});var b={};d(b,{RecurToast:()=>
|
|
647
|
+
`}};typeof window<"u"&&!customElements.get("recur-payment-form-skeleton")&&customElements.define("recur-payment-form-skeleton",T)});var b={};d(b,{RecurToast:()=>I,RecurToastContainer:()=>f});var I,u,f,g=m(()=>{"use strict";I=class extends HTMLElement{static get observedAttributes(){return["message","type","duration"]}constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){this.render(),this.setupAutoDismiss()}get message(){return this.getAttribute("message")||"Notification"}get type(){let e=this.getAttribute("type");return e==="success"||e==="error"?e:"info"}get duration(){let e=this.getAttribute("duration");return e?parseInt(e,10):5e3}setupAutoDismiss(){let e=this.duration;e>0&&setTimeout(()=>this.dismiss(),e)}dismiss(){this.style.animation="recur-toast-slide-out 0.3s ease-in-out",setTimeout(()=>this.remove(),300)}getTypeIcon(){switch(this.type){case"success":return`<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
598
648
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
|
599
649
|
</svg>`;case"error":return`<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
600
650
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
@@ -741,7 +791,7 @@
|
|
|
741
791
|
</style>
|
|
742
792
|
|
|
743
793
|
<slot></slot>
|
|
744
|
-
`}static getInstance(){return u.instance||(u.instance=document.querySelector("recur-toast-container"),u.instance||(u.instance=document.createElement("recur-toast-container"),document.body.appendChild(u.instance))),u.instance}};n(u,"instance",null);f=u;typeof window<"u"&&!customElements.get("recur-toast")&&customElements.define("recur-toast",
|
|
794
|
+
`}static getInstance(){return u.instance||(u.instance=document.querySelector("recur-toast-container"),u.instance||(u.instance=document.createElement("recur-toast-container"),document.body.appendChild(u.instance))),u.instance}};n(u,"instance",null);f=u;typeof window<"u"&&!customElements.get("recur-toast")&&customElements.define("recur-toast",I);typeof window<"u"&&!customElements.get("recur-toast-container")&&customElements.define("recur-toast-container",f)});var K={};d(K,{RecurPaymentForm:()=>M});var M,q=m(()=>{"use strict";M=class extends HTMLElement{constructor(){super();n(this,"containerId");n(this,"customStyles");n(this,"_isInitializing",!1);n(this,"_initializationAborted",!1);this.containerId=this.getAttribute("container-id")||`recur-${Date.now()}`,this.customStyles=this.getAttribute("custom-styles")||"",this.attachShadow({mode:"open"})}connectedCallback(){this.render()}disconnectedCallback(){console.log("[PaymentForm] Component disconnected, cleaning up..."),this._initializationAborted=!0,this._paymentSession=null;let t=document.getElementById(`${this.containerId}-submit-btn`);if(t){let r=t.cloneNode(!0);t.parentNode?.replaceChild(r,t)}}static get observedAttributes(){return["custom-styles","customer-name","customer-email","plan-name","amount","billing-period"]}attributeChangedCallback(t,r,i){t==="custom-styles"&&r!==i?(this.customStyles=i||"",this.updateCustomStyles()):r!==i&&this.updateCustomerInfoSection()}render(){this.shadowRoot.innerHTML=`
|
|
745
795
|
<style>
|
|
746
796
|
/* \u9019\u4E9B\u6A23\u5F0F\u88AB\u9694\u96E2\u5728 Shadow DOM \u5167\uFF0C\u4E0D\u6703\u5F71\u97FF\u5916\u90E8 */
|
|
747
797
|
:host {
|
|
@@ -763,10 +813,10 @@
|
|
|
763
813
|
}
|
|
764
814
|
|
|
765
815
|
.form-title {
|
|
766
|
-
font-size:
|
|
816
|
+
font-size: 20px;
|
|
767
817
|
font-weight: 600;
|
|
768
818
|
color: #1a202c;
|
|
769
|
-
margin: 0 0
|
|
819
|
+
margin: 0 0 4px 0;
|
|
770
820
|
}
|
|
771
821
|
|
|
772
822
|
.form-subtitle {
|
|
@@ -814,8 +864,8 @@
|
|
|
814
864
|
|
|
815
865
|
<div class="payment-form-wrapper">
|
|
816
866
|
<div class="form-header">
|
|
817
|
-
<h2 class="form-title">\u4ED8\u6B3E
|
|
818
|
-
<p class="form-subtitle">\u8ACB\u586B\u5BEB\
|
|
867
|
+
<h2 class="form-title">\u8A02\u95B1\u4ED8\u6B3E</h2>
|
|
868
|
+
<p class="form-subtitle">\u8ACB\u586B\u5BEB\u4FE1\u7528\u5361\u8CC7\u8A0A\u5B8C\u6210\u8A02\u95B1</p>
|
|
819
869
|
</div>
|
|
820
870
|
|
|
821
871
|
<!-- Slot for order summary (Light DOM) -->
|
|
@@ -896,12 +946,14 @@
|
|
|
896
946
|
|
|
897
947
|
.order-summary-value {
|
|
898
948
|
font-size: 14px;
|
|
949
|
+
line-height: 20px;
|
|
899
950
|
font-weight: 500;
|
|
900
951
|
color: #2d3748;
|
|
901
952
|
}
|
|
902
953
|
|
|
903
954
|
.order-summary-total {
|
|
904
955
|
font-size: 18px;
|
|
956
|
+
line-height: 26px;
|
|
905
957
|
font-weight: 700;
|
|
906
958
|
color: #1a202c;
|
|
907
959
|
}
|
|
@@ -950,6 +1002,7 @@
|
|
|
950
1002
|
|
|
951
1003
|
.recur-info-value {
|
|
952
1004
|
font-size: 14px;
|
|
1005
|
+
line-height: 20px;
|
|
953
1006
|
color: #2d3748;
|
|
954
1007
|
font-weight: 500;
|
|
955
1008
|
}
|
|
@@ -1059,11 +1112,43 @@
|
|
|
1059
1112
|
grid-template-columns: 1fr 1fr;
|
|
1060
1113
|
gap: 12px;
|
|
1061
1114
|
}
|
|
1115
|
+
|
|
1116
|
+
/* Container needs relative positioning for skeleton overlay */
|
|
1117
|
+
.recur-card-field-container {
|
|
1118
|
+
position: relative;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
/* Loading skeleton for card fields - shown until PAYUNi iframe loads */
|
|
1122
|
+
.recur-card-skeleton {
|
|
1123
|
+
position: absolute;
|
|
1124
|
+
top: 0;
|
|
1125
|
+
left: 0;
|
|
1126
|
+
height: 36px;
|
|
1127
|
+
width: 100%;
|
|
1128
|
+
background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);
|
|
1129
|
+
background-size: 200% 100%;
|
|
1130
|
+
animation: recur-skeleton-loading 1.5s ease-in-out infinite;
|
|
1131
|
+
border-radius: 4px;
|
|
1132
|
+
z-index: 1;
|
|
1133
|
+
pointer-events: none;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
/* Hide skeleton when PAYUNi iframe is ready (has content) */
|
|
1137
|
+
.recur-card-skeleton.hidden {
|
|
1138
|
+
display: none;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
@keyframes recur-skeleton-loading {
|
|
1142
|
+
0% { background-position: 200% 0; }
|
|
1143
|
+
100% { background-position: -200% 0; }
|
|
1144
|
+
}
|
|
1062
1145
|
</style>
|
|
1063
1146
|
|
|
1064
1147
|
<div class="recur-card-field">
|
|
1065
1148
|
<label class="recur-card-field-label">\u5361\u865F</label>
|
|
1066
1149
|
<div class="recur-card-field-container" id="${this.containerId}-card-no-wrapper">
|
|
1150
|
+
<!-- Skeleton shown until PAYUNi iframe loads -->
|
|
1151
|
+
<div class="recur-card-skeleton" id="${this.containerId}-card-no-skeleton"></div>
|
|
1067
1152
|
<!-- PAYUNi \u6703\u5728\u9019\u88E1\u6CE8\u5165 iframe -->
|
|
1068
1153
|
<div id="${this.containerId}-card-no" class="recur-payuni-iframe"></div>
|
|
1069
1154
|
</div>
|
|
@@ -1073,6 +1158,7 @@
|
|
|
1073
1158
|
<div class="recur-card-field">
|
|
1074
1159
|
<label class="recur-card-field-label">\u6709\u6548\u671F\u9650</label>
|
|
1075
1160
|
<div class="recur-card-field-container" id="${this.containerId}-card-exp-wrapper">
|
|
1161
|
+
<div class="recur-card-skeleton" id="${this.containerId}-card-exp-skeleton"></div>
|
|
1076
1162
|
<div id="${this.containerId}-card-exp" class="recur-payuni-iframe"></div>
|
|
1077
1163
|
</div>
|
|
1078
1164
|
</div>
|
|
@@ -1080,11 +1166,12 @@
|
|
|
1080
1166
|
<div class="recur-card-field">
|
|
1081
1167
|
<label class="recur-card-field-label">\u5B89\u5168\u78BC</label>
|
|
1082
1168
|
<div class="recur-card-field-container" id="${this.containerId}-card-cvc-wrapper">
|
|
1169
|
+
<div class="recur-card-skeleton" id="${this.containerId}-card-cvc-skeleton"></div>
|
|
1083
1170
|
<div id="${this.containerId}-card-cvc" class="recur-payuni-iframe"></div>
|
|
1084
1171
|
</div>
|
|
1085
1172
|
</div>
|
|
1086
1173
|
</div>
|
|
1087
|
-
`,t}createActionsSection(){let t=document.createElement("div");return t.className="actions-section",t.innerHTML=`
|
|
1174
|
+
`,t}hideCardSkeletons(){[`${this.containerId}-card-no-skeleton`,`${this.containerId}-card-exp-skeleton`,`${this.containerId}-card-cvc-skeleton`].forEach(r=>{let i=document.getElementById(r);i&&i.classList.add("hidden")})}createActionsSection(){let t=document.createElement("div");return t.className="actions-section",t.innerHTML=`
|
|
1088
1175
|
<style>
|
|
1089
1176
|
.recur-submit-button {
|
|
1090
1177
|
width: 100%;
|
|
@@ -1138,10 +1225,10 @@
|
|
|
1138
1225
|
>
|
|
1139
1226
|
<span id="${this.containerId}-submit-text">\u78BA\u8A8D\u4ED8\u6B3E</span>
|
|
1140
1227
|
</button>
|
|
1141
|
-
`,t}async initializePayment(t,r){if(this._initializationAborted)return console.log("[PaymentForm] Initialization aborted before start"),null;if(this._isInitializing=!0,await this.updateComplete(),this._initializationAborted)return console.log("[PaymentForm] Initialization aborted after updateComplete"),this._isInitializing=!1,null;if(!window.UniPayment)throw this._isInitializing=!1,new Error("PAYUNi SDK not loaded");try{let i=document.getElementById(`${this.containerId}-card-no`),s=document.getElementById(`${this.containerId}-card-exp`),a=document.getElementById(`${this.containerId}-card-cvc`);if(!i||!s||!a)return console.log("[PaymentForm] DOM elements not found, likely disconnected"),this._isInitializing=!1,null;if(this._initializationAborted)return console.log("[PaymentForm] Initialization aborted before createSession"),this._isInitializing=!1,null;let o=window.UniPayment.createSession(t,{env:r==="SANDBOX"?"S":"P",elements:{CardNo:`${this.containerId}-card-no`,CardExp:`${this.containerId}-card-exp`,CardCvc:`${this.containerId}-card-cvc`}});if(this._initializationAborted)return console.log("[PaymentForm] Initialization aborted before paymentSession.start()"),this._isInitializing=!1,null;try{await o.start()}catch(c){if((c?.message?.includes("1008")||c?.message?.includes("timeout")||c?.code===1008)&&this._initializationAborted)return console.log("[PaymentForm] Caught 1008 timeout error after component disconnect - ignoring"),this._isInitializing=!1,null;throw c}return this._initializationAborted?(console.log("[PaymentForm] Initialization aborted after paymentSession.start()"),this._isInitializing=!1,null):(o.onUpdate?.(c=>{if(this._initializationAborted){console.log("[PaymentForm] Ignoring onUpdate event - component disconnected");return}console.log("[PaymentForm] PAYUNi update:",c);let p=c.status&&c.status.CardNo===!0&&c.status.CardExp===!0&&c.status.CardCvc===!0,v=document.getElementById(`${this.containerId}-submit-btn`);v&&(v.disabled=!p,console.log("[PaymentForm] Submit button disabled:",!p))}),this._initializationAborted?(console.log("[PaymentForm] Initialization aborted before saving session"),this._isInitializing=!1,null):(this._paymentSession=o,this.setupFormSubmission(),this._isInitializing=!1,o))}catch(i){throw this._isInitializing=!1,console.error("[PaymentForm] Failed to initialize payment:",i),i}}setupFormSubmission(){let t=document.getElementById(`${this.containerId}-submit-btn`);t&&t.addEventListener("click",async r=>{if(r.preventDefault(),t.classList.contains("loading"))return;let i,s,a,o=document.getElementById(`${this.containerId}-email`),c=document.getElementById(`${this.containerId}-name`),p=document.getElementById(`${this.containerId}-phone`);if(o&&c){if(i=o.value,s=c.value,a=p?.value,!i||!s){this.showError("\u8ACB\u586B\u5BEB\u59D3\u540D\u548C\u96FB\u5B50\u90F5\u4EF6");return}}else if(i=this.getAttribute("customer-email")||void 0,s=this.getAttribute("customer-name")||void 0,!i||!s){this.showError("\u5BA2\u6236\u8CC7\u8A0A\u4E0D\u5B8C\u6574");return}this.clearError(),this.setButtonLoading(!0),this.dispatchEvent(new CustomEvent("submit",{detail:{customerEmail:i,customerName:s,customerPhone:a,paymentSession:this._paymentSession},bubbles:!0,composed:!0}))})}setButtonLoading(t){let r=document.getElementById(`${this.containerId}-submit-btn`);r&&(t?(r.classList.add("loading"),r.disabled=!0,r.innerHTML=`
|
|
1228
|
+
`,t}async initializePayment(t,r){if(this._initializationAborted)return console.log("[PaymentForm] Initialization aborted before start"),null;if(this._isInitializing=!0,await this.updateComplete(),this._initializationAborted)return console.log("[PaymentForm] Initialization aborted after updateComplete"),this._isInitializing=!1,null;if(!window.UniPayment)throw this._isInitializing=!1,new Error("PAYUNi SDK not loaded");try{let i=document.getElementById(`${this.containerId}-card-no`),s=document.getElementById(`${this.containerId}-card-exp`),a=document.getElementById(`${this.containerId}-card-cvc`);if(!i||!s||!a)return console.log("[PaymentForm] DOM elements not found, likely disconnected"),this._isInitializing=!1,null;if(this._initializationAborted)return console.log("[PaymentForm] Initialization aborted before createSession"),this._isInitializing=!1,null;let o=window.UniPayment.createSession(t,{env:r==="SANDBOX"?"S":"P",elements:{CardNo:`${this.containerId}-card-no`,CardExp:`${this.containerId}-card-exp`,CardCvc:`${this.containerId}-card-cvc`}});if(this._initializationAborted)return console.log("[PaymentForm] Initialization aborted before paymentSession.start()"),this._isInitializing=!1,null;try{await o.start()}catch(c){if((c?.message?.includes("1008")||c?.message?.includes("timeout")||c?.code===1008)&&this._initializationAborted)return console.log("[PaymentForm] Caught 1008 timeout error after component disconnect - ignoring"),this._isInitializing=!1,null;throw c}return this._initializationAborted?(console.log("[PaymentForm] Initialization aborted after paymentSession.start()"),this._isInitializing=!1,null):(this.hideCardSkeletons(),o.onUpdate?.(c=>{if(this._initializationAborted){console.log("[PaymentForm] Ignoring onUpdate event - component disconnected");return}console.log("[PaymentForm] PAYUNi update:",c);let p=c.status&&c.status.CardNo===!0&&c.status.CardExp===!0&&c.status.CardCvc===!0,v=document.getElementById(`${this.containerId}-submit-btn`);v&&(v.disabled=!p,console.log("[PaymentForm] Submit button disabled:",!p))}),this._initializationAborted?(console.log("[PaymentForm] Initialization aborted before saving session"),this._isInitializing=!1,null):(this._paymentSession=o,this.setupFormSubmission(),this._isInitializing=!1,o))}catch(i){throw this._isInitializing=!1,console.error("[PaymentForm] Failed to initialize payment:",i),i}}setupFormSubmission(){let t=document.getElementById(`${this.containerId}-submit-btn`);t&&t.addEventListener("click",async r=>{if(r.preventDefault(),t.classList.contains("loading"))return;let i,s,a,o=document.getElementById(`${this.containerId}-email`),c=document.getElementById(`${this.containerId}-name`),p=document.getElementById(`${this.containerId}-phone`);if(o&&c){if(i=o.value,s=c.value,a=p?.value,!i||!s){this.showError("\u8ACB\u586B\u5BEB\u59D3\u540D\u548C\u96FB\u5B50\u90F5\u4EF6");return}}else if(i=this.getAttribute("customer-email")||void 0,s=this.getAttribute("customer-name")||void 0,!i||!s){this.showError("\u5BA2\u6236\u8CC7\u8A0A\u4E0D\u5B8C\u6574");return}this.clearError(),this.setButtonLoading(!0),this.dispatchEvent(new CustomEvent("submit",{detail:{customerEmail:i,customerName:s,customerPhone:a,paymentSession:this._paymentSession},bubbles:!0,composed:!0}))})}setButtonLoading(t){let r=document.getElementById(`${this.containerId}-submit-btn`);r&&(t?(r.classList.add("loading"),r.disabled=!0,r.innerHTML=`
|
|
1142
1229
|
<span class="recur-loading-spinner"></span>
|
|
1143
1230
|
<span>\u8655\u7406\u4E2D...</span>
|
|
1144
|
-
`):(r.classList.remove("loading"),r.disabled=!1,r.innerHTML='<span id="'+this.containerId+'-submit-text">\u78BA\u8A8D\u4ED8\u6B3E</span>'))}resetButton(){this.setButtonLoading(!1)}showError(t){let r=this.querySelector(".recur-sdk__error-container");r||(r=document.createElement("div"),r.className="recur-sdk__error-container",r.style.cssText="margin-bottom: 16px;",this.insertBefore(r,this.firstChild));let i=document.createElement("recur-error-display");i.setAttribute("error",t),i.setAttribute("dismissible","true"),r.innerHTML="",r.appendChild(i),i.scrollIntoView({behavior:"smooth",block:"center"})}clearError(){let t=this.querySelector(".recur-sdk__error-container");t&&(t.innerHTML="")}updateComplete(){return new Promise(t=>{if(this.isConnected)setTimeout(t,0);else{let r=new MutationObserver(()=>{this.isConnected&&(r.disconnect(),setTimeout(t,0))});r.observe(document.body,{childList:!0,subtree:!0})}})}getFormData(){return{email:document.getElementById(`${this.containerId}-email`)?.value,name:document.getElementById(`${this.containerId}-name`)?.value,phone:document.getElementById(`${this.containerId}-phone`)?.value}}setFormData(t){if(t.email){let r=document.getElementById(`${this.containerId}-email`);r&&(r.value=t.email)}if(t.name){let r=document.getElementById(`${this.containerId}-name`);r&&(r.value=t.name)}if(t.phone){let r=document.getElementById(`${this.containerId}-phone`);r&&(r.value=t.phone)}}};customElements.get("recur-payment-form")||customElements.define("recur-payment-form",
|
|
1231
|
+
`):(r.classList.remove("loading"),r.disabled=!1,r.innerHTML='<span id="'+this.containerId+'-submit-text">\u78BA\u8A8D\u4ED8\u6B3E</span>'))}resetButton(){this.setButtonLoading(!1)}showError(t){let r=this.querySelector(".recur-sdk__error-container");r||(r=document.createElement("div"),r.className="recur-sdk__error-container",r.style.cssText="margin-bottom: 16px;",this.insertBefore(r,this.firstChild));let i=document.createElement("recur-error-display");i.setAttribute("error",t),i.setAttribute("dismissible","true"),r.innerHTML="",r.appendChild(i),i.scrollIntoView({behavior:"smooth",block:"center"})}clearError(){let t=this.querySelector(".recur-sdk__error-container");t&&(t.innerHTML="")}updateComplete(){return new Promise(t=>{if(this.isConnected)setTimeout(t,0);else{let r=new MutationObserver(()=>{this.isConnected&&(r.disconnect(),setTimeout(t,0))});r.observe(document.body,{childList:!0,subtree:!0})}})}getFormData(){return{email:document.getElementById(`${this.containerId}-email`)?.value,name:document.getElementById(`${this.containerId}-name`)?.value,phone:document.getElementById(`${this.containerId}-phone`)?.value}}setFormData(t){if(t.email){let r=document.getElementById(`${this.containerId}-email`);r&&(r.value=t.email)}if(t.name){let r=document.getElementById(`${this.containerId}-name`);r&&(r.value=t.name)}if(t.phone){let r=document.getElementById(`${this.containerId}-phone`);r&&(r.value=t.phone)}}};customElements.get("recur-payment-form")||customElements.define("recur-payment-form",M)});var Y={};d(Y,{RecurCheckoutButton:()=>S});var S,V=m(()=>{"use strict";S=class extends HTMLElement{constructor(){super();n(this,"_isLoading",!1);n(this,"handleClick",async t=>{if(t.preventDefault(),this._isLoading||this.hasAttribute("disabled"))return;let r=this.getAttribute("publishable-key"),i=this.getAttribute("product-id"),s=this.getAttribute("success-url"),a=this.getAttribute("cancel-url");if(!r){this.dispatchError("Missing required attribute: publishable-key");return}if(!i){this.dispatchError("Missing required attribute: product-id");return}if(!s){this.dispatchError("Missing required attribute: success-url");return}if(!a){this.dispatchError("Missing required attribute: cancel-url");return}this._isLoading=!0,this.render(),this.setupEventListeners();try{let o=await this.createCheckoutSession({publishableKey:r,productId:i,successUrl:this.resolveUrl(s),cancelUrl:this.resolveUrl(a),customerEmail:this.getAttribute("customer-email")||void 0,mode:this.getAttribute("mode")});this.dispatchEvent(new CustomEvent("checkout-started",{detail:{sessionId:o.id,url:o.url},bubbles:!0,composed:!0})),window.location.href=o.url}catch(o){this._isLoading=!1,this.render(),this.setupEventListeners(),this.dispatchError(o.message||"Failed to create checkout session")}});this.attachShadow({mode:"open"})}static get observedAttributes(){return["publishable-key","product-id","success-url","cancel-url","customer-email","mode","button-text","button-style","disabled"]}connectedCallback(){this.render(),this.setupEventListeners()}disconnectedCallback(){let t=this.shadowRoot?.querySelector("button");t&&t.removeEventListener("click",this.handleClick)}attributeChangedCallback(t,r,i){r!==i&&this.render()}render(){let t=this.getAttribute("button-text")||this.textContent?.trim()||"\u8A02\u95B1",r=this.getAttribute("button-style")||"primary",i=this.hasAttribute("disabled")||this._isLoading;this.shadowRoot.innerHTML=`
|
|
1145
1232
|
<style>
|
|
1146
1233
|
:host {
|
|
1147
1234
|
display: inline-block;
|
|
@@ -1240,7 +1327,7 @@
|
|
|
1240
1327
|
${this._isLoading?'<span class="spinner"></span>':""}
|
|
1241
1328
|
<span>${this._isLoading?"\u8655\u7406\u4E2D...":t}</span>
|
|
1242
1329
|
</button>
|
|
1243
|
-
`}setupEventListeners(){let t=this.shadowRoot?.querySelector("button");t&&t.addEventListener("click",this.handleClick)}async createCheckoutSession(t){let r=this.getApiBaseUrl(),i={productId:t.productId,successUrl:t.successUrl,cancelUrl:t.cancelUrl};t.mode&&(i.mode=t.mode),t.customerEmail&&(i.customerEmail=t.customerEmail);let s=await fetch(`${r}/v1/checkout/sessions`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":t.publishableKey},body:JSON.stringify(i)});if(!s.ok){let a=await s.json().catch(()=>({}));throw new Error(a.error?.message||`HTTP ${s.status}: Failed to create checkout session`)}return s.json()}getApiBaseUrl(){let t=this.getAttribute("api-base-url");if(t)return t;if(typeof window<"u"){let r=window.location.hostname;if(r==="localhost"||r.includes(".test")||r.includes(".local")||r==="127.0.0.1")return`${window.location.protocol}//${window.location.host}/api`}return"https://api.recur.tw"}resolveUrl(t){return t.startsWith("/")?`${window.location.origin}${t}`:t}dispatchError(t){console.error("[recur-checkout]",t),this.dispatchEvent(new CustomEvent("checkout-error",{detail:{message:t},bubbles:!0,composed:!0}))}};typeof window<"u"&&!customElements.get("recur-checkout")&&customElements.define("recur-checkout",S)});var ie={};d(ie,{RecurCheckout:()=>y,RecurElements:()=>h,createElements:()=>_,default:()=>re,init:()=>X});async function te(){if(typeof window>"u"){console.warn("[Recur SDK] Cannot register Web Components: window is not defined");return}await Promise.all([Promise.resolve().then(()=>(H(),U)),Promise.resolve().then(()=>(A(),$)),Promise.resolve().then(()=>(
|
|
1330
|
+
`}setupEventListeners(){let t=this.shadowRoot?.querySelector("button");t&&t.addEventListener("click",this.handleClick)}async createCheckoutSession(t){let r=this.getApiBaseUrl(),i={productId:t.productId,successUrl:t.successUrl,cancelUrl:t.cancelUrl};t.mode&&(i.mode=t.mode),t.customerEmail&&(i.customerEmail=t.customerEmail);let s=await fetch(`${r}/v1/checkout/sessions`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":t.publishableKey},body:JSON.stringify(i)});if(!s.ok){let a=await s.json().catch(()=>({}));throw new Error(a.error?.message||`HTTP ${s.status}: Failed to create checkout session`)}return s.json()}getApiBaseUrl(){let t=this.getAttribute("api-base-url");if(t)return t;if(typeof window<"u"){let r=window.location.hostname;if(r==="localhost"||r.includes(".test")||r.includes(".local")||r==="127.0.0.1")return`${window.location.protocol}//${window.location.host}/api`}return"https://api.recur.tw"}resolveUrl(t){return t.startsWith("/")?`${window.location.origin}${t}`:t}dispatchError(t){console.error("[recur-checkout]",t),this.dispatchEvent(new CustomEvent("checkout-error",{detail:{message:t},bubbles:!0,composed:!0}))}};typeof window<"u"&&!customElements.get("recur-checkout")&&customElements.define("recur-checkout",S)});var ie={};d(ie,{RecurCheckout:()=>y,RecurElements:()=>h,createElements:()=>_,default:()=>re,init:()=>X});async function te(){if(typeof window>"u"){console.warn("[Recur SDK] Cannot register Web Components: window is not defined");return}await Promise.all([Promise.resolve().then(()=>(H(),U)),Promise.resolve().then(()=>(A(),$)),Promise.resolve().then(()=>(N(),B)),Promise.resolve().then(()=>(O(),D)),Promise.resolve().then(()=>(j(),F)),Promise.resolve().then(()=>(g(),b)),Promise.resolve().then(()=>(q(),K)),Promise.resolve().then(()=>(V(),Y))]);let e=["recur-loading-spinner","recur-success-message","recur-error-display","recur-skeleton-loader","recur-payment-form-skeleton","recur-toast","recur-toast-container","recur-payment-form","recur-checkout"].filter(t=>!customElements.get(t));e.length>0&&console.warn("[Recur SDK] The following components are not registered:",e)}typeof window<"u"&&te();var L=class{constructor(e){n(this,"config");if(!e.publishableKey)throw new Error("publishableKey is required");this.config={baseUrl:"https://api.recur.tw",...e}}async createSubscription(e){let{planId:t,customerName:r,customerEmail:i,customerPhone:s}=e;if(!t)throw new Error("planId is required");let a=await fetch(`${this.config.baseUrl}/v1/subscriptions`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":this.config.publishableKey},body:JSON.stringify({planId:t,customerName:r,customerEmail:i,customerPhone:s})});if(!a.ok){let o=await a.json().catch(()=>({}));throw{code:o.error||"CHECKOUT_FAILED",message:o.message||"Failed to initiate checkout",details:o}}return await a.json()}async fetchPlans(){let e=await fetch(`${this.config.baseUrl}/v1/plans`,{method:"GET",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":this.config.publishableKey}});if(!e.ok){let t=await e.json().catch(()=>({}));throw{code:t.error||"FETCH_PLANS_FAILED",message:t.message||"Failed to fetch plans",details:t}}return await e.json()}getConfig(){return{...this.config}}};var R=class{constructor(e){n(this,"overlay",null);n(this,"modal",null);n(this,"iframe",null);n(this,"onClose");n(this,"handleMessage",e=>{e.origin===window.location.origin&&(e.data?.type==="RECUR_PAYMENT_COMPLETE"?this.close():e.data?.type==="RECUR_PAYMENT_CANCEL"&&this.close())});this.onClose=e}open(e){this.overlay=document.createElement("div"),this.overlay.style.cssText=`
|
|
1244
1331
|
position: fixed;
|
|
1245
1332
|
top: 0;
|
|
1246
1333
|
left: 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "recur-tw",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "React & Vanilla JS SDK for embedding subscription checkout flows (Taiwan / PAYUNi)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -28,6 +28,14 @@
|
|
|
28
28
|
"url": "https://github.com/kaikhq/recur.tw/issues"
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/kaikhq/recur.tw/tree/main/packages/recur-sdk#readme",
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"dev": "tsup --watch",
|
|
34
|
+
"lint": "eslint .",
|
|
35
|
+
"lint:fix": "eslint . --fix",
|
|
36
|
+
"type-check": "tsc --noEmit",
|
|
37
|
+
"examples": "npx http-server examples -p 8080 -o"
|
|
38
|
+
},
|
|
31
39
|
"main": "./dist/index.js",
|
|
32
40
|
"module": "./dist/index.js",
|
|
33
41
|
"types": "./dist/index.d.ts",
|
|
@@ -68,6 +76,7 @@
|
|
|
68
76
|
"@types/node": "^20.19.9",
|
|
69
77
|
"@types/react": "^19.1.9",
|
|
70
78
|
"@types/react-dom": "^19.1.7",
|
|
79
|
+
"@workspace/typescript-config": "workspace:*",
|
|
71
80
|
"autoprefixer": "^10.4.22",
|
|
72
81
|
"eslint": "^9",
|
|
73
82
|
"eslint-plugin-react": "^7.37.5",
|
|
@@ -78,15 +87,6 @@
|
|
|
78
87
|
"tailwindcss": "^4.1.11",
|
|
79
88
|
"tsup": "^8.3.5",
|
|
80
89
|
"typescript": "^5.9.2",
|
|
81
|
-
"typescript-eslint": "^8.47.0"
|
|
82
|
-
"@workspace/typescript-config": "0.0.0"
|
|
83
|
-
},
|
|
84
|
-
"scripts": {
|
|
85
|
-
"build": "tsup",
|
|
86
|
-
"dev": "tsup --watch",
|
|
87
|
-
"lint": "eslint .",
|
|
88
|
-
"lint:fix": "eslint . --fix",
|
|
89
|
-
"type-check": "tsc --noEmit",
|
|
90
|
-
"examples": "npx http-server examples -p 8080 -o"
|
|
90
|
+
"typescript-eslint": "^8.47.0"
|
|
91
91
|
}
|
|
92
|
-
}
|
|
92
|
+
}
|