@xtandard/webhooks 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +4 -4
- package/dist/cli.mjs +4 -4
- package/dist/{core-CMpnmI5Q.mjs → core-B1JzRitF.mjs} +20 -3
- package/dist/core-B1JzRitF.mjs.map +1 -0
- package/dist/{core-ZGhH6Vs2.cjs → core-DuHD0Rdg.cjs} +20 -3
- package/dist/core-DuHD0Rdg.cjs.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.mjs +1 -1
- package/dist/{create-fetch-handler-jy3hy5nZ.d.mts → create-fetch-handler-BN9vXbgW.d.mts} +7 -3
- package/dist/{create-fetch-handler-CmooujQo.cjs → create-fetch-handler-BNsNcspj.cjs} +6 -5
- package/dist/{create-fetch-handler-CmooujQo.cjs.map → create-fetch-handler-BNsNcspj.cjs.map} +1 -1
- package/dist/{create-fetch-handler-BIdk9P30.mjs → create-fetch-handler-C6BqzdsN.mjs} +6 -5
- package/dist/{create-fetch-handler-BIdk9P30.mjs.map → create-fetch-handler-C6BqzdsN.mjs.map} +1 -1
- package/dist/{create-fetch-handler-Dlkhustu.d.cts → create-fetch-handler-D9ZRfrY6.d.cts} +7 -3
- package/dist/{dispatcher-Coubwrka.mjs → dispatcher-CFfWo-fN.mjs} +3 -3
- package/dist/{dispatcher-Coubwrka.mjs.map → dispatcher-CFfWo-fN.mjs.map} +1 -1
- package/dist/{dispatcher-B0xTEHt1.cjs → dispatcher-COdWV6hM.cjs} +3 -3
- package/dist/{dispatcher-B0xTEHt1.cjs.map → dispatcher-COdWV6hM.cjs.map} +1 -1
- package/dist/entry-bun.cjs +1 -1
- package/dist/entry-bun.d.cts +1 -1
- package/dist/entry-bun.d.mts +1 -1
- package/dist/entry-bun.mjs +1 -1
- package/dist/entry-elysia.cjs +1 -1
- package/dist/entry-elysia.d.cts +1 -1
- package/dist/entry-elysia.d.mts +1 -1
- package/dist/entry-elysia.mjs +1 -1
- package/dist/entry-express.cjs +1 -1
- package/dist/entry-express.d.cts +1 -1
- package/dist/entry-express.d.mts +1 -1
- package/dist/entry-express.mjs +1 -1
- package/dist/entry-hono.cjs +1 -1
- package/dist/entry-hono.d.cts +1 -1
- package/dist/entry-hono.d.mts +1 -1
- package/dist/entry-hono.mjs +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +3 -3
- package/dist/react.css +1 -1
- package/dist/react.js +2522 -2506
- package/dist/testing.cjs +2 -2
- package/dist/testing.mjs +2 -2
- package/dist/types-react/ui/lib/portal-container.d.ts +24 -0
- package/dist/ui/assets/{index-S5t_CLOe.js → index-BgyX_njf.js} +44 -44
- package/dist/ui/assets/index-mJCJq_EB.css +1 -0
- package/dist/ui/index.html +2 -2
- package/package.json +4 -2
- package/dist/core-CMpnmI5Q.mjs.map +0 -1
- package/dist/core-ZGhH6Vs2.cjs.map +0 -1
- package/dist/ui/assets/index-B0eoQX2U.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-ease:initial;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--color-black:#000;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-2xl:42rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-snug:1.375;--leading-relaxed:1.625;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--default-mono-font-family:"JetBrains Mono", "SFMono-Regular", "Cascadia Code", ui-monospace, monospace}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:before,:after{box-sizing:border-box;border-color:var(--border)}html,body,#root{height:100%;margin:0;padding:0}body{background-color:var(--background);color:var(--foreground);font-family:var(--font-sans);letter-spacing:-.006em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:14px;line-height:1.5}:focus-visible{outline:2px solid var(--ring);outline-offset:2px}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-1\/2{top:50%}.right-6{right:calc(var(--spacing) * 6)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.z-40{z-index:40}.z-50{z-index:50}.z-\[9999\]{z-index:9999}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-14{height:calc(var(--spacing) * 14)}.h-screen{height:100vh}.max-h-32{max-height:calc(var(--spacing) * 32)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-\[85vh\]{max-height:85vh}.max-h-\[min\(20rem\,var\(--available-height\)\)\]{max-height:min(20rem,var(--available-height))}.min-h-0{min-height:0}.w-4{width:calc(var(--spacing) * 4)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-28{width:calc(var(--spacing) * 28)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-\[max\(var\(--anchor-width\)\,13rem\)\]{width:max(var(--anchor-width),13rem)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[240px\]{max-width:240px}.max-w-\[320px\]{max-width:320px}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:0}.min-w-\[280px\]{min-width:280px}.min-w-\[var\(--anchor-width\)\]{min-width:var(--anchor-width)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.origin-\[var\(--transform-origin\)\]{transform-origin:var(--transform-origin)}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-x-8{column-gap:calc(var(--spacing) * 8)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--border)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[5px\]{border-radius:5px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-\[3px\]{border-left-style:var(--tw-border-style);border-left-width:3px}.border-accent,.border-accent\/20{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.border-accent\/20{border-color:color-mix(in oklab,var(--accent) 20%,transparent)}}.border-accent\/30{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.border-accent\/30{border-color:color-mix(in oklab,var(--accent) 30%,transparent)}}.border-accent\/40{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.border-accent\/40{border-color:color-mix(in oklab,var(--accent) 40%,transparent)}}.border-border{border-color:var(--border)}.border-card{border-color:var(--card)}.border-chart-2\/30{border-color:var(--chart-2)}@supports (color:color-mix(in lab,red,red)){.border-chart-2\/30{border-color:color-mix(in oklab,var(--chart-2) 30%,transparent)}}.border-destructive\/20{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/20{border-color:color-mix(in oklab,var(--destructive) 20%,transparent)}}.border-destructive\/30{border-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.border-destructive\/30{border-color:color-mix(in oklab,var(--destructive) 30%,transparent)}}.border-input{border-color:var(--input)}.border-success\/20{border-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.border-success\/20{border-color:color-mix(in oklab,var(--success) 20%,transparent)}}.border-success\/30{border-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.border-success\/30{border-color:color-mix(in oklab,var(--success) 30%,transparent)}}.border-transparent{border-color:#0000}.border-warning\/20{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.border-warning\/20{border-color:color-mix(in oklab,var(--warning) 20%,transparent)}}.border-warning\/30{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.border-warning\/30{border-color:color-mix(in oklab,var(--warning) 30%,transparent)}}.border-l-\[var\(--accent\)\]{border-left-color:var(--accent)}.border-l-\[var\(--destructive\)\]{border-left-color:var(--destructive)}.border-l-\[var\(--success\)\]{border-left-color:var(--success)}.border-l-\[var\(--warning\)\]{border-left-color:var(--warning)}.bg-accent,.bg-accent\/10{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-accent\/10{background-color:color-mix(in oklab,var(--accent) 10%,transparent)}}.bg-accent\/\[0\.06\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-accent\/\[0\.06\]{background-color:color-mix(in oklab,var(--accent) 6%,transparent)}}.bg-background,.bg-background\/80{background-color:var(--background)}@supports (color:color-mix(in lab,red,red)){.bg-background\/80{background-color:color-mix(in oklab,var(--background) 80%,transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-card{background-color:var(--card)}.bg-chart-2\/10{background-color:var(--chart-2)}@supports (color:color-mix(in lab,red,red)){.bg-chart-2\/10{background-color:color-mix(in oklab,var(--chart-2) 10%,transparent)}}.bg-destructive,.bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.bg-destructive\/10{background-color:color-mix(in oklab,var(--destructive) 10%,transparent)}}.bg-input{background-color:var(--input)}.bg-muted-foreground\/40{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.bg-muted-foreground\/40{background-color:color-mix(in oklab,var(--muted-foreground) 40%,transparent)}}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-secondary,.bg-secondary\/30{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.bg-secondary\/30{background-color:color-mix(in oklab,var(--secondary) 30%,transparent)}}.bg-secondary\/40{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.bg-secondary\/40{background-color:color-mix(in oklab,var(--secondary) 40%,transparent)}}.bg-secondary\/50{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.bg-secondary\/50{background-color:color-mix(in oklab,var(--secondary) 50%,transparent)}}.bg-secondary\/60{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.bg-secondary\/60{background-color:color-mix(in oklab,var(--secondary) 60%,transparent)}}.bg-success,.bg-success\/10{background-color:var(--success)}@supports (color:color-mix(in lab,red,red)){.bg-success\/10{background-color:color-mix(in oklab,var(--success) 10%,transparent)}}.bg-transparent{background-color:#0000}.bg-warning,.bg-warning\/10{background-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.bg-warning\/10{background-color:color-mix(in oklab,var(--warning) 10%,transparent)}}.object-contain{object-fit:contain}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:JetBrains Mono,SFMono-Regular,Cascadia Code,ui-monospace,monospace}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-all{word-break:break-all}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--accent)}.text-border{color:var(--border)}.text-chart-1{color:var(--chart-1)}.text-chart-2{color:var(--chart-2)}.text-destructive{color:var(--destructive)}.text-foreground{color:var(--foreground)}.text-muted-foreground,.text-muted-foreground\/50{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/50{color:color-mix(in oklab,var(--muted-foreground) 50%,transparent)}}.text-muted-foreground\/60{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/60{color:color-mix(in oklab,var(--muted-foreground) 60%,transparent)}}.text-muted-foreground\/70{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/70{color:color-mix(in oklab,var(--muted-foreground) 70%,transparent)}}.text-popover-foreground{color:var(--popover-foreground)}.text-primary-foreground{color:var(--primary-foreground)}.text-success{color:var(--success)}.text-warning{color:var(--warning)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.accent-\[var\(--accent\)\]{accent-color:var(--accent)}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-border{--tw-ring-color:var(--border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition-\[transform\,opacity\]{transition-property:transform,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:translate-x-0\.5:is(:where(.group):hover *){--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.group-hover\:text-muted-foreground:is(:where(.group):hover *){color:var(--muted-foreground)}}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:top-2:before{content:var(--tw-content);top:calc(var(--spacing) * 2)}.before\:bottom-1:before{content:var(--tw-content);bottom:var(--spacing)}.before\:left-\[13px\]:before{content:var(--tw-content);left:13px}.before\:w-px:before{content:var(--tw-content);width:1px}.before\:bg-border:before{content:var(--tw-content);background-color:var(--border)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:inset-x-3:after{content:var(--tw-content);inset-inline:calc(var(--spacing) * 3)}.after\:-bottom-px:after{content:var(--tw-content);bottom:-1px}.after\:h-0\.5:after{content:var(--tw-content);height:calc(var(--spacing) * .5)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:bg-foreground:after{content:var(--tw-content);background-color:var(--foreground)}@media(hover:hover){.hover\:bg-destructive\/10:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/10:hover{background-color:color-mix(in oklab,var(--destructive) 10%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary) 90%,transparent)}}.hover\:bg-secondary:hover,.hover\:bg-secondary\/30:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/30:hover{background-color:color-mix(in oklab,var(--secondary) 30%,transparent)}}.hover\:bg-secondary\/60:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/60:hover{background-color:color-mix(in oklab,var(--secondary) 60%,transparent)}}.hover\:bg-secondary\/70:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/70:hover{background-color:color-mix(in oklab,var(--secondary) 70%,transparent)}}.hover\:text-destructive:hover{color:var(--destructive)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:ring-offset-background:focus-visible{--tw-ring-offset-color:var(--background)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[checked\]\:translate-x-\[18px\][data-checked]{--tw-translate-x:18px;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[checked\]\:bg-success[data-checked]{background-color:var(--success)}.data-\[ending-style\]\:scale-95[data-ending-style]{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.data-\[ending-style\]\:opacity-0[data-ending-style]{opacity:0}.data-\[highlighted\]\:bg-accent\/15[data-highlighted]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[highlighted\]\:bg-accent\/15[data-highlighted]{background-color:color-mix(in oklab,var(--accent) 15%,transparent)}}.data-\[highlighted\]\:text-foreground[data-highlighted]{color:var(--foreground)}.data-\[popup-open\]\:border-ring[data-popup-open]{border-color:var(--ring)}.data-\[pressed\]\:bg-card[data-pressed]{background-color:var(--card)}.data-\[pressed\]\:text-foreground[data-pressed]{color:var(--foreground)}.data-\[pressed\]\:shadow-sm[data-pressed]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.data-\[starting-style\]\:scale-95[data-starting-style]{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.data-\[starting-style\]\:opacity-0[data-starting-style]{opacity:0}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:px-4{padding-inline:calc(var(--spacing) * 4)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media(min-width:64rem){.lg\:flex{display:flex}}}:root{color-scheme:light;--radius:.625rem;--background:oklch(99% .002 285);--foreground:oklch(21% .01 285);--card:oklch(100% 0 0);--card-foreground:oklch(21% .01 285);--popover:oklch(100% 0 0);--popover-foreground:oklch(21% .01 285);--primary:oklch(24% .01 285);--primary-foreground:oklch(98% 0 0);--secondary:oklch(96.5% .003 285);--secondary-foreground:oklch(24% .01 285);--muted:oklch(96.5% .003 285);--muted-foreground:oklch(50% .012 285);--accent:oklch(55% .2 256);--accent-foreground:oklch(99% 0 0);--success:oklch(60% .15 152);--warning:oklch(70% .15 78);--info:oklch(55% .2 256);--destructive:oklch(58% .21 24);--border:oklch(21% .01 285/.11);--input:oklch(21% .01 285/.14);--ring:oklch(55% .2 256);--chart-1:oklch(55% .2 256);--chart-2:oklch(60% .15 152);--chart-3:oklch(70% .15 78);--chart-4:oklch(60% .2 16);--chart-5:oklch(62% .16 300);--shadow-sm:0 1px 2px oklch(20% .02 285/.06);--shadow-md:0 2px 4px oklch(20% .02 285/.05), 0 8px 20px oklch(20% .02 285/.08);--shadow-lg:0 16px 40px oklch(20% .02 285/.16)}:root[data-theme=dark]{color-scheme:dark;--background:oklch(16% .004 285);--foreground:oklch(97% 0 0);--card:oklch(20.5% .004 285);--card-foreground:oklch(97% 0 0);--popover:oklch(22% .004 285);--popover-foreground:oklch(97% 0 0);--primary:oklch(97% 0 0);--primary-foreground:oklch(20% .01 285);--secondary:oklch(27% .004 285);--secondary-foreground:oklch(97% 0 0);--muted:oklch(27% .004 285);--muted-foreground:oklch(66% .005 285);--accent:oklch(62% .19 256);--accent-foreground:oklch(99% 0 0);--success:oklch(72% .18 152);--warning:oklch(78% .15 78);--info:oklch(62% .19 256);--destructive:oklch(62% .21 24);--border:oklch(100% 0 0/.11);--input:oklch(100% 0 0/.14);--ring:oklch(62% .19 256);--chart-1:oklch(62% .19 256);--chart-2:oklch(72% .18 152);--chart-3:oklch(78% .15 78);--chart-4:oklch(66% .2 16);--chart-5:oklch(70% .16 300);--shadow-sm:0 1px 2px oklch(0% 0 0/.3);--shadow-md:0 2px 4px oklch(0% 0 0/.3), 0 10px 28px oklch(0% 0 0/.45);--shadow-lg:0 18px 48px oklch(0% 0 0/.55)}*{scrollbar-width:thin;scrollbar-color:var(--border) transparent}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){::-webkit-scrollbar-thumb{background:color-mix(in oklab,var(--muted-foreground) 35%,transparent)}}::-webkit-scrollbar-thumb{background-clip:content-box;border:2px solid #0000;border-radius:4px}::-webkit-scrollbar-track{background:0 0}@media(prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}
|
package/dist/ui/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>@xtandard/webhooks</title>
|
|
7
7
|
<meta name="description" content="Admin panel for @xtandard/webhooks outbound webhooks" />
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-BgyX_njf.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-mJCJq_EB.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xtandard/webhooks",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Self-hosted, embeddable, Standard Webhooks-compliant outbound webhook control plane with pluggable storage, an in-process delivery engine, and an embeddable consumer portal.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -373,7 +373,7 @@
|
|
|
373
373
|
"dev:ui": "vite --config vite.ui.config.ts",
|
|
374
374
|
"test:e2e": "playwright test",
|
|
375
375
|
"standalone": "bun run apps/standalone/src/index.ts",
|
|
376
|
-
"build:react": "vite build --config vite.react.config.ts && tsc -p tsconfig.react.json",
|
|
376
|
+
"build:react": "vite build --config vite.react.config.ts && bun scripts/scope-embed-css.ts && tsc -p tsconfig.react.json",
|
|
377
377
|
"demo": "bun scripts/demo.ts",
|
|
378
378
|
"seed:demo": "bun scripts/seed-demo.ts",
|
|
379
379
|
"typecheck:examples": "tsc -p examples/tsconfig.json",
|
|
@@ -422,6 +422,8 @@
|
|
|
422
422
|
"mongodb": "^6.10.0",
|
|
423
423
|
"pg": "^8.13.0",
|
|
424
424
|
"playwright": "^1.49.0",
|
|
425
|
+
"postcss": "^8.5.16",
|
|
426
|
+
"postcss-prefix-selector": "^2.1.1",
|
|
425
427
|
"react": "^19.0.0",
|
|
426
428
|
"react-dom": "^19.0.0",
|
|
427
429
|
"redis": "^5.0.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"core-CMpnmI5Q.mjs","names":[],"sources":["../src/deliver.ts","../src/delivery-sink.ts","../src/duration.ts","../src/id.ts","../src/version.ts","../src/hooks/contract.ts","../src/validation.ts","../src/core.ts"],"sourcesContent":["/**\n * The single-attempt HTTP delivery primitive: build the Standard Webhooks\n * headers, POST the envelope, capture the outcome. Owns no retry/queue logic —\n * the dispatcher schedules attempts and `core.sendExample` fires one-off test\n * sends through the same code path so test deliveries are wire-identical to\n * real ones.\n *\n * @module\n */\n\nimport type { Endpoint } from \"./schema.ts\";\nimport { signatureHeader } from \"./signing.ts\";\n\n/** Default cap on how many response-body characters are kept per attempt. */\nexport const DEFAULT_RESPONSE_BODY_LIMIT = 4096;\n\n/** Default per-attempt timeout. */\nexport const DEFAULT_ATTEMPT_TIMEOUT_MS = 20_000;\n\n/** Input to {@link attemptDelivery}. */\nexport interface AttemptDeliveryInput {\n endpoint: Endpoint;\n /** The `webhook-id` header — the **message** id (stable across retries). */\n messageId: string;\n /** The serialized envelope body, exactly as stored at publish time. */\n body: string;\n /** Per-attempt timeout (AbortController). Default 20s. */\n timeoutMs?: number;\n /** Cap on stored response-body characters. Default 4096. */\n responseBodyLimit?: number;\n /** `user-agent` header value. */\n userAgent?: string;\n /** Injectable fetch (tests, instrumentation). Default: global fetch. */\n fetch?: typeof fetch;\n /** Unix millis of the attempt; defaults to `Date.now()`. */\n nowMs?: number;\n}\n\n/** The observed outcome of one HTTP delivery attempt. */\nexport interface AttemptOutcome {\n ok: boolean;\n httpStatus?: number;\n /** Truncated error message on network error/timeout. */\n error?: string;\n /** Truncated response body. */\n responseBody?: string;\n durationMs: number;\n /** ISO-8601 timestamp of the attempt. */\n at: string;\n}\n\n/** The exact HTTP request a delivery attempt sends — the inspector's view. */\nexport interface SignedRequest {\n method: \"POST\";\n url: string;\n headers: Record<string, string>;\n body: string;\n}\n\n/** Input to {@link buildSignedRequest}. */\nexport interface BuildSignedRequestInput {\n endpoint: Endpoint;\n /** `webhook-id` — the message id (stable across retries). */\n messageId: string;\n /** The serialized envelope body. */\n body: string;\n /** `user-agent` header value. */\n userAgent?: string;\n /** Unix millis; defaults to `Date.now()`. Determines `webhook-timestamp`. */\n nowMs?: number;\n}\n\n/**\n * Build the exact signed request an attempt would POST — Standard Webhooks\n * headers, all unexpired secrets signing — **without sending it**. Shared by\n * {@link attemptDelivery} and the panel's request inspector so what you preview\n * is byte-for-byte what a receiver gets.\n */\nexport async function buildSignedRequest(input: BuildSignedRequestInput): Promise<SignedRequest> {\n const nowMs = input.nowMs ?? Date.now();\n const secrets = activeSecrets(input.endpoint, nowMs);\n if (secrets.length === 0) {\n throw new Error(`Endpoint ${input.endpoint.id} has no unexpired signing secret`);\n }\n // The timestamp is of THIS attempt (receivers check tolerance against it);\n // the id is the message id, stable across retries (receivers dedupe on it).\n const timestamp = Math.floor(nowMs / 1000);\n const signature = await signatureHeader(secrets, input.messageId, timestamp, input.body);\n const headers: Record<string, string> = {\n ...input.endpoint.headers,\n \"content-type\": \"application/json\",\n \"webhook-id\": input.messageId,\n \"webhook-timestamp\": String(timestamp),\n \"webhook-signature\": signature,\n };\n if (input.userAgent) headers[\"user-agent\"] = input.userAgent;\n return { method: \"POST\", url: input.endpoint.url, headers, body: input.body };\n}\n\n/** The endpoint's currently-signing secrets: the active one + unexpired rotation grace. */\nexport function activeSecrets(endpoint: Endpoint, nowMs: number): string[] {\n return endpoint.secrets\n .filter((s) => !s.expiresAt || Date.parse(s.expiresAt) > nowMs)\n .map((s) => s.secret);\n}\n\nconst truncate = (value: string, limit: number): string =>\n value.length > limit ? value.slice(0, limit) : value;\n\n/**\n * Perform one signed POST to `endpoint.url`. Never throws for remote-party\n * failures — network errors, timeouts, and non-2xx responses all come back as\n * a failed {@link AttemptOutcome}. (It does throw on programmer error, e.g. an\n * endpoint with no unexpired secret.)\n */\nexport async function attemptDelivery(input: AttemptDeliveryInput): Promise<AttemptOutcome> {\n const nowMs = input.nowMs ?? Date.now();\n const at = new Date(nowMs).toISOString();\n const timeoutMs = input.timeoutMs ?? DEFAULT_ATTEMPT_TIMEOUT_MS;\n const bodyLimit = input.responseBodyLimit ?? DEFAULT_RESPONSE_BODY_LIMIT;\n const doFetch = input.fetch ?? fetch;\n\n const { headers } = await buildSignedRequest({\n endpoint: input.endpoint,\n messageId: input.messageId,\n body: input.body,\n nowMs,\n ...(input.userAgent !== undefined ? { userAgent: input.userAgent } : {}),\n });\n\n const started = Date.now();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n // Node/Bun timers keep the process alive by default; an in-flight attempt\n // should not.\n (timer as { unref?: () => void }).unref?.();\n\n try {\n const response = await doFetch(input.endpoint.url, {\n method: \"POST\",\n headers,\n body: input.body,\n signal: controller.signal,\n redirect: \"manual\", // a redirect is not a delivery — receivers must answer 2xx directly\n });\n let responseBody = \"\";\n try {\n responseBody = truncate(await response.text(), bodyLimit);\n } catch {\n // Body read failures (aborted stream, etc.) don't change the verdict.\n }\n return {\n ok: response.status >= 200 && response.status < 300,\n httpStatus: response.status,\n responseBody: responseBody || undefined,\n durationMs: Date.now() - started,\n at,\n };\n } catch (error) {\n const aborted = controller.signal.aborted;\n const message = aborted\n ? `Timed out after ${timeoutMs}ms`\n : error instanceof Error\n ? error.message\n : String(error);\n return {\n ok: false,\n error: truncate(message, 512),\n durationMs: Date.now() - started,\n at,\n };\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Delivery sink — a **delivery-plane** observation tap, fired once per attempt.\n * Deliberately separate from the admin-plane {@link ./hooks/contract.WebhooksHooks}\n * (`before`/`after` around control-plane mutations):\n *\n * - **Different plane.** Admin hooks live around rare, human-driven mutations\n * (endpoints, event types, replay). Attempts happen inside the dispatcher,\n * potentially thousands per minute.\n * - **Hot path.** The sink is **fire-and-forget**: invoked *after* the attempt\n * is recorded, never awaited, and its errors never propagate into the\n * delivery loop.\n *\n * It exists to feed metrics/observability pipelines — Prometheus counters,\n * per-endpoint success dashboards, usage-based stale-endpoint detection —\n * without a stats engine. The `after` hooks only see **terminal** transitions\n * (`delivery.succeeded` / `delivery.exhausted`); the sink sees every attempt.\n *\n * @module\n */\n\nimport type { AttemptTrigger } from \"./schema.ts\";\n\n/** One recorded delivery attempt, delivered to a {@link DeliveryListener}. */\nexport interface DeliveryEvent {\n applicationKey: string;\n endpointId: string;\n messageId: string;\n deliveryId: string;\n /** The message's event type name. */\n eventType: string;\n /** 1-based attempt ordinal within the delivery. */\n attemptNumber: number;\n /** True when the receiver answered 2xx. */\n ok: boolean;\n /** True when this attempt drove the delivery to a terminal state. */\n terminal: boolean;\n /** HTTP status code; absent on network error/timeout. */\n httpStatus?: number;\n /** Wall-clock duration of the HTTP round trip. */\n durationMs: number;\n /** What initiated the attempt. */\n trigger: AttemptTrigger;\n /** ISO-8601 timestamp of the attempt. */\n at: string;\n}\n\n/**\n * A fire-and-forget observer of delivery attempts. Return value (including a\n * Promise) is ignored by the caller; throwing / rejecting never affects the\n * delivery — failures are routed to the configured error reporter.\n */\nexport type DeliveryListener = (event: DeliveryEvent) => void | Promise<void>;\n\n/** Reports an error thrown/rejected by a {@link DeliveryListener}. */\nexport type DeliveryErrorReporter = (error: unknown, event: DeliveryEvent) => void;\n\n/**\n * Invoke `listener` safely off the delivery path: synchronous throws are caught\n * and a returned Promise's rejection is handled, so a broken sink can never\n * fail (or slow, since it is not awaited) a delivery.\n */\nexport function emitDelivery(\n listener: DeliveryListener,\n event: DeliveryEvent,\n onError?: DeliveryErrorReporter,\n): void {\n try {\n const result = listener(event);\n if (result && typeof (result as Promise<void>).then === \"function\") {\n (result as Promise<void>).catch((error) => onError?.(error, event));\n }\n } catch (error) {\n onError?.(error, event);\n }\n}\n","/**\n * Duration parsing for {@link ./schema.WebhookDuration} config values. Zero\n * dependencies; shared by the core (rotation grace, retention) and the\n * dispatcher (retry schedule).\n *\n * @module\n */\n\nimport type { WebhookDuration } from \"./schema.ts\";\n\nconst UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n};\n\nconst DURATION_RE = /^(\\d+(?:\\.\\d+)?)(ms|s|m|h|d)$/;\n\n/**\n * Convert a {@link WebhookDuration} (`5000`, `\"5s\"`, `\"30m\"`, `\"2h\"`, `\"5d\"`)\n * to milliseconds. Throws on malformed strings or negative numbers.\n *\n * @example\n * ```ts\n * import { durationToMs } from \"@xtandard/webhooks\";\n *\n * durationToMs(\"5m\"); // 300000\n * durationToMs(250); // 250\n * ```\n */\nexport function durationToMs(duration: WebhookDuration): number {\n if (typeof duration === \"number\") {\n if (!Number.isFinite(duration) || duration < 0) {\n throw new Error(`Invalid duration: ${duration}`);\n }\n return duration;\n }\n const match = DURATION_RE.exec(duration.trim());\n if (!match) throw new Error(`Invalid duration: \"${duration}\" (expected e.g. \"5s\", \"30m\", \"2h\")`);\n const value = Number(match[1]);\n const unit = UNIT_MS[match[2] as keyof typeof UNIT_MS];\n return value * (unit as number);\n}\n\n/**\n * Parse a comma-separated duration list (the `RETRY_SCHEDULE` env var format,\n * e.g. `\"0s,5s,5m,30m,2h,5h,10h\"`) into a {@link WebhookDuration} array.\n */\nexport function parseDurationList(input: string): WebhookDuration[] {\n return input\n .split(\",\")\n .map((part) => part.trim())\n .filter((part) => part.length > 0)\n .map((part) => {\n const asNumber = Number(part);\n const duration = (Number.isFinite(asNumber) ? asNumber : part) as WebhookDuration;\n durationToMs(duration); // validate eagerly so a bad list fails at parse time\n return duration;\n });\n}\n","/**\n * Entity id generation: `{prefix}_{22-char base62}`. Zero dependencies — base62\n * over `crypto.getRandomValues`, no ULID. 22 base62 characters encode ~131 bits;\n * ids are generated from 16 random bytes (128 bits) and left-padded to a fixed\n * length so ids are uniform and lexicographically well-behaved.\n *\n * @module\n */\n\n/** Prefixes for the four generated entity id kinds. */\nexport type IdPrefix = \"msg\" | \"ep\" | \"dlv\" | \"atp\";\n\nconst ALPHABET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\nconst ID_LENGTH = 22;\nconst RANDOM_BYTES = 16;\n\n/** Encode 128 random bits as a fixed-length 22-char base62 string. */\nfunction randomBase62(): string {\n const bytes = new Uint8Array(RANDOM_BYTES);\n crypto.getRandomValues(bytes);\n let value = 0n;\n for (const b of bytes) value = (value << 8n) | BigInt(b);\n let out = \"\";\n while (value > 0n) {\n out = ALPHABET[Number(value % 62n)] + out;\n value /= 62n;\n }\n return out.padStart(ID_LENGTH, \"0\");\n}\n\n/**\n * Generate a new entity id, e.g. `newId(\"msg\")` → `\"msg_0uK9…\"` (22-char base62\n * suffix).\n *\n * @example\n * ```ts\n * import { newId } from \"@xtandard/webhooks\";\n *\n * const id = newId(\"ep\"); // \"ep_…\"\n * ```\n */\nexport function newId(prefix: IdPrefix): string {\n return `${prefix}_${randomBase62()}`;\n}\n\n/** Regex an id of the given prefix must match. */\nexport function idPattern(prefix: IdPrefix): RegExp {\n return new RegExp(`^${prefix}_[0-9A-Za-z]{${ID_LENGTH}}$`);\n}\n","/**\n * Package version, used for the default dispatcher `user-agent`. Bumped by the\n * release flow alongside `package.json`.\n *\n * @module\n */\n\n/** The published package version. */\nexport const VERSION = \"0.1.0\";\n","/**\n * Hook contracts — control-plane extensibility around admin mutations.\n *\n * A hook is plain JavaScript wired in at {@link ../core.createWebhooksCore}\n * time (never authored through the UI — that would be remote code execution).\n * Two phases, deliberately asymmetric:\n *\n * - **`before`** runs *before* a mutation commits. Throwing **denies** the\n * operation (the thrown error's message is the reason). Multiple `before`\n * hooks run **sequentially in declared order**; the first throw aborts and\n * nothing commits. This is the enforcement primitive that governance,\n * quotas, and publish gates build on.\n * - **`after`** runs *after* a mutation commits. It is for side effects\n * (notifications, cache purges, offloading pruned payloads). An `after`\n * hook **must never fail the operation** — the mutation already committed —\n * so errors are isolated and reported via `onHookError`, not rethrown.\n *\n * Delivery *attempts* are deliberately not hook events (they are data-plane\n * traffic and can be very hot); the per-attempt tap is the separate\n * fire-and-forget {@link ../delivery-sink.DeliveryListener}. Only the terminal\n * transitions (`delivery.succeeded`, `delivery.exhausted`) surface here.\n *\n * @module\n */\n\nimport type {\n Actor,\n Application,\n AuditEntry,\n Delivery,\n DeliveryAttempt,\n Endpoint,\n EventType,\n JsonValue,\n Message,\n} from \"../schema.ts\";\n\n/**\n * Event delivered to {@link WebhooksHooks.before} — the *proposed* mutation,\n * before it commits. Throw from the handler to deny it.\n */\nexport type BeforeEvent =\n | {\n type: \"application.create\" | \"application.update\";\n application: Application;\n actor: Actor | null;\n }\n | { type: \"application.delete\"; applicationKey: string; actor: Actor | null }\n | { type: \"event-type.upsert\"; eventType: EventType; actor: Actor | null }\n | { type: \"event-type.delete\"; name: string; actor: Actor | null }\n | {\n type: \"endpoint.create\" | \"endpoint.update\";\n applicationKey: string;\n endpoint: Endpoint;\n actor: Actor | null;\n }\n | {\n type: \"endpoint.delete\" | \"endpoint.rotate-secret\" | \"endpoint.disable\" | \"endpoint.enable\";\n applicationKey: string;\n endpointId: string;\n actor: Actor | null;\n }\n | {\n /** The host's approval/quota gate for the publish hot path. */\n type: \"message.publish\";\n applicationKey: string;\n eventType: string;\n payload: JsonValue;\n idempotencyKey?: string;\n actor: Actor | null;\n }\n | { type: \"delivery.retry\"; applicationKey: string; deliveryId: string; actor: Actor | null }\n | {\n type: \"endpoint.recover\";\n applicationKey: string;\n endpointId: string;\n since: string;\n actor: Actor | null;\n };\n\n/**\n * Event delivered to {@link WebhooksHooks.after} — the *committed* mutation.\n * Carries the resulting state in full: for destructive events this is the last\n * chance to offload the payload before it is gone from storage.\n */\nexport type AfterEvent =\n | { type: \"application.created\" | \"application.updated\"; application: Application; at: string }\n | {\n /** Carries the deleted application — everything under it is already gone. */\n type: \"application.deleted\";\n applicationKey: string;\n application: Application;\n at: string;\n }\n | { type: \"event-type.upserted\"; eventType: EventType; at: string }\n | { type: \"event-type.deleted\"; name: string; eventType: EventType; at: string }\n | {\n type:\n | \"endpoint.created\"\n | \"endpoint.updated\"\n | \"endpoint.deleted\"\n | \"endpoint.secret-rotated\"\n | \"endpoint.disabled\"\n | \"endpoint.enabled\"\n /** Disabled by the failure policy, not an operator (see dispatcher `autoDisable`). */\n | \"endpoint.auto-disabled\";\n applicationKey: string;\n endpoint: Endpoint;\n at: string;\n }\n | {\n type: \"message.published\";\n applicationKey: string;\n message: Message;\n deliveryIds: string[];\n at: string;\n }\n | {\n type: \"delivery.succeeded\";\n applicationKey: string;\n delivery: Delivery;\n attempt: DeliveryAttempt;\n at: string;\n }\n | {\n /** Dead-letter offload point: the retry schedule is exhausted. */\n type: \"delivery.exhausted\";\n applicationKey: string;\n delivery: Delivery;\n attempts: DeliveryAttempt[];\n at: string;\n }\n | {\n /** Messages removed by retention. Carries the **full messages** — offload now or lose them. */\n type: \"message.pruned\";\n applicationKey: string;\n messages: Message[];\n at: string;\n }\n | {\n /** Audit entries removed by retention (oldest-first). */\n type: \"audit.pruned\";\n applicationKey?: string;\n entries: AuditEntry[];\n at: string;\n };\n\n/** The discriminant strings of {@link BeforeEvent} / {@link AfterEvent}. */\nexport type BeforeEventType = BeforeEvent[\"type\"];\nexport type AfterEventType = AfterEvent[\"type\"];\n\n/**\n * Thrown from a {@link WebhooksHooks.before} handler to **deny** a mutation with\n * a clean HTTP status (default `403`). Any thrown error denies the mutation,\n * but a plain `Error` maps to `500` at the API layer (treated as an unexpected\n * bug); throw this to signal a deliberate policy rejection (`403`, or a custom\n * `status` such as `409`/`422`).\n *\n * @example\n * ```ts\n * before(event) {\n * if (event.type === \"message.publish\" && overQuota(event.applicationKey)) {\n * throw new HookDeniedError(\"Monthly webhook quota exceeded.\", { status: 429 });\n * }\n * }\n * ```\n */\nexport class HookDeniedError extends Error {\n /** HTTP status the API layer should respond with. Default `403`. */\n readonly status: number;\n constructor(message: string, options?: { status?: number; cause?: unknown }) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"HookDeniedError\";\n this.status = options?.status ?? 403;\n }\n}\n\n/**\n * A control-plane hook. Implement `before`, `after`, or both. Pass one — or an\n * array — to {@link ../core.createWebhooksCore} via `hooks`.\n */\nexport interface WebhooksHooks {\n /**\n * Runs before a mutation commits. **Throw to deny** (the error propagates to\n * the caller; its message is the reason). Return/resolve to allow. Must not\n * mutate the event payload.\n */\n before?(event: BeforeEvent): void | Promise<void>;\n /**\n * Runs after a mutation commits. For side effects only. Errors are isolated\n * and reported via `onHookError` — they never fail the (already committed)\n * operation.\n */\n after?(event: AfterEvent): void | Promise<void>;\n}\n\n/** Accepts a single hook, an array, or nothing. */\nexport type WebhooksHooksInput = WebhooksHooks | readonly WebhooksHooks[] | undefined;\n\n/** Reports an error thrown by an `after` hook. */\nexport type HookErrorReporter = (error: unknown, event: AfterEvent) => void;\n\n/** Normalize the `hooks` option into a flat array (empty when unset). */\nexport function normalizeHooks(input: WebhooksHooksInput): WebhooksHooks[] {\n if (!input) return [];\n return Array.isArray(input) ? [...input] : [input as WebhooksHooks];\n}\n\n/**\n * Run every `before` hook sequentially, in order. The first hook to throw\n * aborts: the error propagates to the caller (denying the mutation) and no\n * later hook runs. A no-op when there are no `before` hooks.\n */\nexport async function runBefore(hooks: WebhooksHooks[], event: BeforeEvent): Promise<void> {\n for (const hook of hooks) {\n if (hook.before) await hook.before(event);\n }\n}\n\n/**\n * Run every `after` hook, isolating failures. The mutation has already\n * committed, so a throwing hook must not fail the operation — its error is\n * routed to `onError` and swallowed. Remaining hooks still run.\n */\nexport async function runAfter(\n hooks: WebhooksHooks[],\n event: AfterEvent,\n onError: HookErrorReporter,\n): Promise<void> {\n await Promise.all(\n hooks.map(async (hook) => {\n if (!hook.after) return;\n try {\n await hook.after(event);\n } catch (error) {\n onError(error, event);\n }\n }),\n );\n}\n\n/** Default `after`-hook error reporter: warn, but never throw. */\nexport const defaultHookErrorReporter: HookErrorReporter = (error, event) => {\n // eslint-disable-next-line no-console\n console.warn(`[@xtandard/webhooks] after-hook for \"${event.type}\" threw:`, error);\n};\n","/**\n * Runtime validation for control-plane inputs, built on `valibot`.\n *\n * This is the **admin path** only — `publish()` performs its own minimal\n * checks and the wire/receiver path never imports this module, so `valibot`\n * stays off the hot paths. Validation combines structural parsing (valibot)\n * with semantic checks (URL policy, reserved header names, reserved keys).\n *\n * @module\n */\n\nimport * as v from \"valibot\";\nimport { RESERVED_APPLICATION_KEYS } from \"./keys.ts\";\nimport type { Application, Endpoint } from \"./schema.ts\";\n\n/** Allowed characters for application keys and event type names. */\nexport const KEY_REGEX = /^[a-zA-Z0-9._-]+$/;\n\n/**\n * Validate a caller-supplied string that becomes a **storage key segment**\n * (e.g. an idempotency key). Rejects anything that could escape its namespace\n * or traverse the filesystem on the file adapter: characters outside\n * {@link KEY_REGEX}, and the dot-only segments `.` / `..`. Returns the issue\n * list (empty when safe) so callers can fold it into a {@link ValidationError}.\n */\nexport function validateKeySegment(value: string, path: string): ValidationIssue[] {\n if (!KEY_REGEX.test(value)) {\n return [{ path, message: `must match ${KEY_REGEX} (no slashes or path separators)` }];\n }\n if (/^\\.+$/.test(value)) {\n return [{ path, message: `\"${value}\" is not an allowed key` }];\n }\n if (value.length > 256) {\n return [{ path, message: \"must be at most 256 characters\" }];\n }\n return [];\n}\n\n/**\n * Header names owned by the Standard Webhooks wire contract. Endpoints may not\n * override them via static headers.\n */\nexport const RESERVED_HEADERS = [\"webhook-id\", \"webhook-timestamp\", \"webhook-signature\"] as const;\n\nconst jsonValueSchema: v.GenericSchema<unknown> = v.lazy(() =>\n v.union([\n v.string(),\n v.number(),\n v.boolean(),\n v.null(),\n v.array(jsonValueSchema),\n v.record(v.string(), jsonValueSchema),\n ]),\n);\n\nconst keySchema = v.pipe(v.string(), v.minLength(1), v.maxLength(256), v.regex(KEY_REGEX));\n\nconst applicationSchema = v.object({\n key: keySchema,\n name: v.optional(v.string()),\n metadata: v.optional(jsonValueSchema),\n createdAt: v.optional(v.string()),\n updatedAt: v.optional(v.string()),\n});\n\nconst eventTypeSchema = v.object({\n name: keySchema,\n description: v.optional(v.string()),\n groupName: v.optional(v.string()),\n schema: v.optional(jsonValueSchema),\n deprecated: v.optional(v.boolean()),\n createdAt: v.optional(v.string()),\n updatedAt: v.optional(v.string()),\n});\n\nconst endpointSecretSchema = v.object({\n secret: v.pipe(v.string(), v.minLength(1)),\n createdAt: v.string(),\n expiresAt: v.optional(v.string()),\n});\n\nconst endpointSchema = v.object({\n id: v.optional(v.string()),\n url: v.pipe(v.string(), v.minLength(1)),\n description: v.optional(v.string()),\n eventTypes: v.optional(v.array(keySchema)),\n disabled: v.optional(v.boolean()),\n disabledReason: v.optional(v.picklist([\"manual\", \"auto\"])),\n headers: v.optional(v.record(v.string(), v.string())),\n secrets: v.optional(v.array(endpointSecretSchema)),\n metadata: v.optional(jsonValueSchema),\n createdAt: v.optional(v.string()),\n updatedAt: v.optional(v.string()),\n firstFailingAt: v.optional(v.nullable(v.string())),\n});\n\n/** A single validation problem with a dotted path into the offending data. */\nexport interface ValidationIssue {\n path: string;\n message: string;\n}\n\n/** Result of the `validate*` functions. */\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationIssue[];\n}\n\n/** Raised by {@link assertValid} when an input fails validation. Maps to HTTP 422. */\nexport class ValidationError extends Error {\n readonly errors: ValidationIssue[];\n constructor(errors: ValidationIssue[]) {\n super(`Validation failed:\\n${errors.map((e) => ` - ${e.path}: ${e.message}`).join(\"\\n\")}`);\n this.name = \"ValidationError\";\n this.errors = errors;\n }\n}\n\n/** Throw a {@link ValidationError} when `result` is invalid. */\nexport function assertValid(result: ValidationResult): void {\n if (!result.valid) throw new ValidationError(result.errors);\n}\n\nfunction structuralIssues(\n issues: readonly v.BaseIssue<unknown>[],\n basePath: string,\n): ValidationIssue[] {\n return issues.map((issue) => ({\n path: `${basePath}.${(issue.path ?? []).map((p) => String(p.key)).join(\".\")}`,\n message: issue.message,\n }));\n}\n\n/**\n * Validate an {@link Application}: structure + reserved-key check.\n *\n * @example\n * ```ts\n * import { validateApplication } from \"@xtandard/webhooks\";\n *\n * const result = validateApplication({ key: \"acme\" });\n * // result.valid === true\n * ```\n */\nexport function validateApplication(input: unknown, basePath = \"application\"): ValidationResult {\n const parsed = v.safeParse(applicationSchema, input);\n if (!parsed.success) {\n return { valid: false, errors: structuralIssues(parsed.issues, basePath) };\n }\n const application = parsed.output as Application;\n const errors: ValidationIssue[] = [];\n if ((RESERVED_APPLICATION_KEYS as readonly string[]).includes(application.key)) {\n errors.push({\n path: `${basePath}.key`,\n message: `\"${application.key}\" is a reserved application key`,\n });\n }\n return { valid: errors.length === 0, errors };\n}\n\n/** Validate an {@link EventType}: structural only (the name regex carries the semantics). */\nexport function validateEventType(input: unknown, basePath = \"eventType\"): ValidationResult {\n const parsed = v.safeParse(eventTypeSchema, input);\n if (!parsed.success) {\n return { valid: false, errors: structuralIssues(parsed.issues, basePath) };\n }\n return { valid: true, errors: [] };\n}\n\n/** Options that relax/extend the endpoint URL policy. */\nexport interface UrlPolicyOptions {\n /** Allow `http:` for non-localhost hosts (dev only; default `false`). */\n allowInsecureUrls?: boolean;\n /** Extra host-supplied gate; return `false` to reject (e.g. an SSRF denylist). */\n urlPolicy?: (url: string) => boolean;\n}\n\nconst LOCAL_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\", \"::1\"]);\n\n/**\n * Validate an endpoint destination URL: parseable, `https:` (or `http:` for\n * localhost, or anywhere when `allowInsecureUrls`), no embedded credentials,\n * and passing the host's optional `urlPolicy` gate.\n */\nexport function validateEndpointUrl(\n url: string,\n options: UrlPolicyOptions = {},\n basePath = \"endpoint.url\",\n): ValidationResult {\n const errors: ValidationIssue[] = [];\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return { valid: false, errors: [{ path: basePath, message: `invalid URL \"${url}\"` }] };\n }\n if (parsed.username || parsed.password) {\n errors.push({ path: basePath, message: \"URL must not contain credentials\" });\n }\n if (parsed.protocol === \"http:\") {\n if (!options.allowInsecureUrls && !LOCAL_HOSTS.has(parsed.hostname)) {\n errors.push({\n path: basePath,\n message: \"http URLs are only allowed for localhost (set allowInsecureUrls for dev)\",\n });\n }\n } else if (parsed.protocol !== \"https:\") {\n errors.push({ path: basePath, message: `unsupported protocol \"${parsed.protocol}\"` });\n }\n if (errors.length === 0 && options.urlPolicy && !options.urlPolicy(url)) {\n errors.push({ path: basePath, message: \"URL rejected by the configured urlPolicy\" });\n }\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Validate an {@link Endpoint} input: structure, URL policy, and static-header\n * restrictions (the Standard Webhooks headers are reserved).\n *\n * @example\n * ```ts\n * import { validateEndpoint } from \"@xtandard/webhooks\";\n *\n * const result = validateEndpoint({ url: \"https://api.example.com/hooks\" });\n * // result.valid === true\n * ```\n */\nexport function validateEndpoint(\n input: unknown,\n options: UrlPolicyOptions = {},\n basePath = \"endpoint\",\n): ValidationResult {\n const parsed = v.safeParse(endpointSchema, input);\n if (!parsed.success) {\n return { valid: false, errors: structuralIssues(parsed.issues, basePath) };\n }\n const endpoint = parsed.output as unknown as Endpoint;\n const errors: ValidationIssue[] = [];\n errors.push(...validateEndpointUrl(endpoint.url, options, `${basePath}.url`).errors);\n for (const name of Object.keys(endpoint.headers ?? {})) {\n if ((RESERVED_HEADERS as readonly string[]).includes(name.toLowerCase())) {\n errors.push({\n path: `${basePath}.headers.${name}`,\n message: `\"${name}\" is reserved by the Standard Webhooks wire contract`,\n });\n }\n }\n return { valid: errors.length === 0, errors };\n}\n","/**\n * Admin + publish core — the operations layer the API, CLI, and dispatcher sit\n * on top of.\n *\n * Owns the split between the **control plane** (CRUD on applications / event\n * types / endpoints, browsing messages and deliveries, replay — rare,\n * human-driven, hook-guarded, audited) and the **delivery plane** (`publish()`\n * + the dispatcher's claim/record internals — the hot path). `publish()` never\n * performs an HTTP call and never throws because an endpoint is down: it\n * persists one message and fans out one pending delivery per matching enabled\n * endpoint; the dispatcher owns all network I/O.\n *\n * Storage can be split: control data lives in `storage`, while deliveries +\n * the due index live in `queueStorage` (defaults to `storage`) — e.g. control\n * in Postgres, queue in Redis.\n *\n * @module\n */\n\nimport {\n attemptDelivery,\n buildSignedRequest,\n type AttemptOutcome,\n type SignedRequest,\n} from \"./deliver.ts\";\nimport {\n emitDelivery,\n type DeliveryErrorReporter,\n type DeliveryListener,\n} from \"./delivery-sink.ts\";\nimport type { DispatcherOptions } from \"./dispatcher.ts\";\nimport { durationToMs } from \"./duration.ts\";\nimport { newId } from \"./id.ts\";\nimport {\n applicationMetaKey,\n applicationPrefix,\n applicationsKey,\n attemptKey,\n attemptsPrefix,\n auditLogKey,\n byEndpointKey,\n byEndpointPrefix,\n byMessageKey,\n byMessagePrefix,\n deliveriesPrefix,\n deliveryKey,\n dueKey,\n endpointKey,\n endpointsKey,\n eventTypeKey,\n eventTypesKey,\n globalAuditLogKey,\n idempotencyKey,\n lastSegment,\n messageKey,\n messagesPrefix,\n type DueEntry,\n} from \"./keys.ts\";\nimport type {\n Actor,\n Application,\n AuditEntry,\n Delivery,\n DeliveryAttempt,\n Endpoint,\n EventType,\n JsonValue,\n Message,\n WebhookDuration,\n} from \"./schema.ts\";\nimport { isTerminalDeliveryStatus } from \"./schema.ts\";\nimport { generateSecret } from \"./signing.ts\";\nimport { VERSION } from \"./version.ts\";\nimport { hasDeliveryQueue, isCompareAndSwap, type WebhooksStorage } from \"./storage/contract.ts\";\nimport type {\n AfterEvent,\n BeforeEvent,\n HookErrorReporter,\n WebhooksHooks,\n WebhooksHooksInput,\n} from \"./hooks/contract.ts\";\nimport { defaultHookErrorReporter, normalizeHooks, runAfter, runBefore } from \"./hooks/contract.ts\";\nimport {\n assertValid,\n validateApplication,\n validateEndpoint,\n validateEventType,\n validateKeySegment,\n ValidationError,\n} from \"./validation.ts\";\n\n/** Thrown by mutating operations when the core is in readonly mode. */\nexport class ReadonlyError extends Error {\n constructor(operation: string) {\n super(`Cannot ${operation}: @xtandard/webhooks is in readonly mode.`);\n this.name = \"ReadonlyError\";\n }\n}\n\n/** Thrown when a referenced application/event type/endpoint/delivery does not exist. */\nexport class NotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NotFoundError\";\n }\n}\n\n/** Thrown when creating an entity whose key already exists. Maps to HTTP 409. */\nexport class ConflictError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConflictError\";\n }\n}\n\n/** Thrown by {@link WebhooksCore.publish} when the payload exceeds the limit. Maps to 413. */\nexport class PayloadTooLargeError extends Error {\n constructor(size: number, limit: number) {\n super(`Payload is ${size} bytes; the limit is ${limit} bytes.`);\n this.name = \"PayloadTooLargeError\";\n }\n}\n\n/**\n * Thrown by {@link WebhooksCore.publish} when an idempotency key is reused with\n * a **different** payload (same key + same payload returns the original\n * message instead). Maps to HTTP 409.\n */\nexport class IdempotencyConflictError extends Error {\n constructor(key: string) {\n super(`Idempotency key \"${key}\" was already used with a different payload.`);\n this.name = \"IdempotencyConflictError\";\n }\n}\n\n/**\n * One retention rule set. When both fields are set, an item is **kept if either\n * rule keeps it** (union of keeps — the same semantics as backup tools): pruned\n * only when it is outside the `keepLast` most recent AND older than `maxAge`.\n */\nexport interface RetentionRule {\n /** Keep at most the N most recent items. */\n keepLast?: number;\n /** Keep items newer than this age (relative to prune time). */\n maxAge?: WebhookDuration;\n}\n\n/** Retention policy for {@link WebhooksCoreOptions.retention}. */\nexport interface RetentionOptions {\n /**\n * Prune old messages, cascading their deliveries and attempts. Messages with\n * a non-terminal delivery are never pruned (the dispatcher still needs them).\n */\n messages?: RetentionRule;\n /** Prune old audit entries. */\n audit?: RetentionRule;\n}\n\n/** Options for {@link createWebhooksCore}. */\nexport interface WebhooksCoreOptions {\n /** Control-plane store: applications, event types, endpoints, messages, audit. */\n storage: WebhooksStorage;\n /**\n * Store for deliveries, attempts, and the due index. Defaults to `storage`.\n * Splitting lets control data live in Postgres while the queue lives in Redis.\n */\n queueStorage?: WebhooksStorage;\n /** When true, all mutating operations throw {@link ReadonlyError}. */\n readonly?: boolean;\n /**\n * Control-plane hooks fired around admin mutations. Pass one hook or an array.\n * `before` hooks run sequentially and may **throw to deny**; `after` hooks run\n * post-commit for side effects and never fail the operation.\n */\n hooks?: WebhooksHooksInput;\n /** Reporter invoked when an `after` hook throws. Defaults to `console.warn`. */\n onHookError?: HookErrorReporter;\n /** Fire-and-forget sink invoked for **every** delivery attempt (metrics tap). */\n onDelivery?: DeliveryListener;\n /** Reporter invoked when the `onDelivery` sink throws/rejects. */\n onDeliveryError?: DeliveryErrorReporter;\n /**\n * Retention policy. Message pruning cascades deliveries/attempts and is\n * non-vetoable; removed payloads are surfaced to `after` hooks\n * (`message.pruned`, `audit.pruned`) so they can be offloaded first. Pruning\n * runs opportunistically after publishes (off the hot path, fire-and-forget)\n * and on demand via {@link WebhooksCore.prune}.\n */\n retention?: RetentionOptions;\n /**\n * Dispatcher configuration, carried here so panels/CLI construct dispatchers\n * consistently. The core itself never starts one — creation is the\n * panel/CLI's job (or yours, via `createDispatcher(core, core.options.dispatcher)`).\n */\n dispatcher?: DispatcherOptions;\n /** Grace window during which a rotated-out secret keeps signing. Default `\"24h\"`. */\n secretRotationGrace?: WebhookDuration;\n /** Allow `http:` endpoint URLs beyond localhost (dev only; default `false`). */\n allowInsecureUrls?: boolean;\n /** Extra endpoint-URL gate; return `false` to reject (SSRF denylist etc.). */\n urlPolicy?: (url: string) => boolean;\n /** Max serialized payload size accepted by publish. Default `262_144` bytes. */\n payloadLimitBytes?: number;\n /**\n * Whether {@link WebhooksCore.publish} requires the event type to exist in\n * the catalog. Default `true` — a typo'd event type name would otherwise\n * silently deliver to nobody (endpoints subscribe by exact name).\n */\n requireKnownEventTypes?: boolean;\n /** Injectable clock (unix millis) for tests. Default `Date.now`. */\n now?: () => number;\n}\n\n/** Per-call actor attribution for audited mutations. */\nexport interface ActorOptions {\n actor?: Actor | null;\n}\n\n/** Input to {@link WebhooksCore.publish}. */\nexport interface PublishInput {\n eventType: string;\n payload: JsonValue;\n /** ISO-8601 event-occurred time. Defaults to publish time. */\n timestamp?: string;\n /** Dedupe key: same key + same payload within retention returns the existing message. */\n idempotencyKey?: string;\n}\n\n/** Result of {@link WebhooksCore.publish}. */\nexport interface PublishResult {\n message: Message;\n deliveries: Delivery[];\n /** True when an idempotency key matched and the existing message was returned. */\n deduplicated: boolean;\n}\n\n/** Pagination + filters for {@link WebhooksCore.listMessages}. */\nexport interface ListMessagesOptions {\n /** Page size. Default 50, max 200. */\n limit?: number;\n /** Cursor: return items strictly older than the message with this id. */\n before?: string;\n eventType?: string;\n}\n\n/** Pagination + filters for {@link WebhooksCore.listDeliveries}. */\nexport interface ListDeliveriesOptions {\n status?: Delivery[\"status\"];\n endpointId?: string;\n messageId?: string;\n /** Page size. Default 50, max 200. */\n limit?: number;\n /** Cursor: return items strictly older than the delivery with this id. */\n before?: string;\n}\n\n/** Input to the dispatcher-facing {@link WebhooksCore.claimDueDeliveries}. */\nexport interface ClaimInput {\n limit: number;\n leaseMs: number;\n}\n\n/** Input to the dispatcher-facing {@link WebhooksCore.recordAttempt}. */\nexport interface RecordAttemptInput {\n delivery: Delivery;\n outcome: AttemptOutcome;\n trigger: DeliveryAttempt[\"trigger\"];\n /**\n * When the outcome failed: the next attempt time (dispatcher computes the\n * schedule + jitter), or `null` when the schedule is exhausted (dead-letter).\n * Ignored for successful outcomes.\n */\n nextAttemptAt?: string | null;\n /** The message's event type (for the sink event); loaded by the dispatcher anyway. */\n eventType: string;\n}\n\n/** Result of {@link WebhooksCore.sendExample}. */\nexport interface SendExampleResult {\n outcome: AttemptOutcome;\n /** The envelope body that was sent. */\n body: string;\n /** The synthetic message id used as `webhook-id` (not retained). */\n messageId: string;\n}\n\n/** Result of {@link WebhooksCore.recoverEndpoint}. */\nexport interface RecoverResult {\n /** Ids of the failed deliveries that were re-queued. */\n deliveryIds: string[];\n}\n\n/** The admin + publish core surface. */\nexport interface WebhooksCore {\n readonly options: {\n storage: WebhooksStorage;\n queueStorage: WebhooksStorage;\n readonly: boolean;\n /** Normalized hooks (always an array). */\n hooks: WebhooksHooks[];\n retention?: RetentionOptions;\n dispatcher?: DispatcherOptions;\n secretRotationGrace: WebhookDuration;\n allowInsecureUrls: boolean;\n urlPolicy?: (url: string) => boolean;\n payloadLimitBytes: number;\n requireKnownEventTypes: boolean;\n onDelivery?: DeliveryListener;\n onDeliveryError?: DeliveryErrorReporter;\n now: () => number;\n };\n\n // Applications\n listApplications(): Promise<Application[]>;\n createApplication(\n input: { key: string; name?: string; metadata?: JsonValue },\n options?: ActorOptions,\n ): Promise<Application>;\n getApplication(applicationKey: string): Promise<Application | null>;\n updateApplication(\n applicationKey: string,\n patch: { name?: string; metadata?: JsonValue },\n options?: ActorOptions,\n ): Promise<Application>;\n /** Deletes the application and **everything** under it (endpoints, messages, deliveries). */\n deleteApplication(applicationKey: string, options?: ActorOptions): Promise<void>;\n\n // Event types (global catalog)\n listEventTypes(): Promise<EventType[]>;\n getEventType(name: string): Promise<EventType | null>;\n upsertEventType(input: EventType, options?: ActorOptions): Promise<EventType>;\n /**\n * Delete an event type. Endpoints referencing it keep their subscription\n * entry and simply stop matching new publishes of that name.\n */\n deleteEventType(name: string, options?: ActorOptions): Promise<void>;\n\n // Endpoints\n listEndpoints(applicationKey: string): Promise<Endpoint[]>;\n getEndpoint(applicationKey: string, endpointId: string): Promise<Endpoint | null>;\n /** Creates the endpoint and generates its first signing secret. */\n createEndpoint(\n applicationKey: string,\n input: {\n url: string;\n description?: string;\n eventTypes?: string[];\n headers?: Record<string, string>;\n metadata?: JsonValue;\n disabled?: boolean;\n },\n options?: ActorOptions,\n ): Promise<Endpoint>;\n updateEndpoint(\n applicationKey: string,\n endpointId: string,\n patch: {\n url?: string;\n description?: string;\n eventTypes?: string[];\n headers?: Record<string, string>;\n metadata?: JsonValue;\n },\n options?: ActorOptions,\n ): Promise<Endpoint>;\n deleteEndpoint(applicationKey: string, endpointId: string, options?: ActorOptions): Promise<void>;\n /**\n * Mint a new current secret; the previous one keeps verifying until\n * `secretRotationGrace` elapses. Expired grace secrets are pruned lazily.\n */\n rotateSecret(\n applicationKey: string,\n endpointId: string,\n options?: ActorOptions,\n ): Promise<Endpoint>;\n /** The endpoint's secrets (current first). Gate behind `endpoint:read-secret`. */\n getSecrets(applicationKey: string, endpointId: string): Promise<Endpoint[\"secrets\"]>;\n enableEndpoint(\n applicationKey: string,\n endpointId: string,\n options?: ActorOptions,\n ): Promise<Endpoint>;\n disableEndpoint(\n applicationKey: string,\n endpointId: string,\n options?: ActorOptions,\n ): Promise<Endpoint>;\n\n // Publish (the delivery-plane entry point)\n /**\n * Persist a message and fan out one pending delivery per matching enabled\n * endpoint. Never performs HTTP; never throws because an endpoint is down.\n */\n publish(\n applicationKey: string,\n input: PublishInput,\n options?: ActorOptions,\n ): Promise<PublishResult>;\n\n // Messages + deliveries (observability)\n listMessages(applicationKey: string, options?: ListMessagesOptions): Promise<Message[]>;\n getMessage(applicationKey: string, messageId: string): Promise<Message | null>;\n listDeliveries(applicationKey: string, options?: ListDeliveriesOptions): Promise<Delivery[]>;\n getDelivery(\n applicationKey: string,\n deliveryId: string,\n ): Promise<{ delivery: Delivery; attempts: DeliveryAttempt[] } | null>;\n /**\n * The exact signed HTTP request this delivery would send **right now** —\n * method, URL, all headers (including the computed `webhook-signature`), and\n * body. The inspector view: shows what a receiver gets, without sending.\n * Returns `null` if the delivery or its endpoint no longer exists. The\n * `webhook-timestamp`/signature reflect the current time (they change per\n * attempt by design); the id and body are stable.\n */\n previewDeliveryRequest(applicationKey: string, deliveryId: string): Promise<SignedRequest | null>;\n /** Re-queue a dead-lettered delivery (`failed` → `pending`, due immediately). */\n retryDelivery(\n applicationKey: string,\n deliveryId: string,\n options?: ActorOptions,\n ): Promise<Delivery>;\n /** Re-queue every failed delivery for an endpoint created at/after `since`. */\n recoverEndpoint(\n applicationKey: string,\n endpointId: string,\n input: { since: string },\n options?: ActorOptions,\n ): Promise<RecoverResult>;\n /**\n * Fire a one-off signed test delivery at an endpoint, synchronously, through\n * the same wire path as real deliveries (`trigger: \"test\"`). The synthetic\n * message is not retained.\n */\n sendExample(\n applicationKey: string,\n endpointId: string,\n input: { eventType: string; payload?: JsonValue },\n options?: ActorOptions,\n ): Promise<SendExampleResult>;\n\n // Audit\n /** Newest-first. With `applicationKey`: that app's log; without: global + all apps. */\n listAudit(applicationKey?: string): Promise<AuditEntry[]>;\n\n // Retention\n /** Run retention now (also runs opportunistically after publishes). */\n prune(): Promise<void>;\n\n // Dispatcher internals (exported for advanced users / custom dispatchers)\n /**\n * Claim up to `limit` due deliveries for exclusive processing. Uses the\n * storage's native `claimDue` when available; otherwise scans the due index\n * with compare-and-swap claiming (plain read-modify-write when the storage\n * has no CAS — single-dispatcher assumption, see docs/DELIVERY.md).\n */\n claimDueDeliveries(input: ClaimInput): Promise<Delivery[]>;\n /** Record one attempt's outcome and advance the delivery's state machine. */\n recordAttempt(input: RecordAttemptInput): Promise<Delivery>;\n /**\n * Update the endpoint's failure streak after an attempt (any success clears\n * it) and auto-disable once the streak exceeds `failingForDays`. Returns the\n * endpoint when it was auto-disabled by this call.\n */\n noteEndpointOutcome(\n applicationKey: string,\n endpointId: string,\n ok: boolean,\n policy?: { failingForDays?: number } | false,\n ): Promise<Endpoint | null>;\n}\n\nconst DEFAULT_PAYLOAD_LIMIT = 262_144;\nconst DEFAULT_ROTATION_GRACE: WebhookDuration = \"24h\";\nconst MAX_PAGE = 200;\nconst DEFAULT_PAGE = 50;\n\n/**\n * Construct the core over the configured storage.\n *\n * @example\n * ```ts\n * import { createWebhooksCore } from \"@xtandard/webhooks\";\n * import { createMemoryStorage } from \"@xtandard/webhooks/storage/memory\";\n *\n * const core = createWebhooksCore({ storage: createMemoryStorage() });\n *\n * await core.createApplication({ key: \"acme\" });\n * await core.upsertEventType({ name: \"invoice.paid\" });\n * const endpoint = await core.createEndpoint(\"acme\", {\n * url: \"https://api.acme-customer.com/webhooks\",\n * eventTypes: [\"invoice.paid\"],\n * });\n *\n * // The hot path — call this from your app code:\n * await core.publish(\"acme\", {\n * eventType: \"invoice.paid\",\n * payload: { invoiceId: \"inv_1\", amount: 4200 },\n * });\n * ```\n */\nexport function createWebhooksCore(options: WebhooksCoreOptions): WebhooksCore {\n const storage = options.storage;\n const queueStorage = options.queueStorage ?? options.storage;\n const readonly = options.readonly ?? false;\n const hooks = normalizeHooks(options.hooks);\n const onHookError = options.onHookError ?? defaultHookErrorReporter;\n const secretRotationGrace = options.secretRotationGrace ?? DEFAULT_ROTATION_GRACE;\n const payloadLimitBytes = options.payloadLimitBytes ?? DEFAULT_PAYLOAD_LIMIT;\n const requireKnownEventTypes = options.requireKnownEventTypes ?? true;\n const now = options.now ?? Date.now;\n const urlOptions = {\n allowInsecureUrls: options.allowInsecureUrls ?? false,\n ...(options.urlPolicy ? { urlPolicy: options.urlPolicy } : {}),\n };\n\n const guard = (op: string) => {\n if (readonly) throw new ReadonlyError(op);\n };\n\n const before = hooks.length ? (event: BeforeEvent) => runBefore(hooks, event) : null;\n const after = hooks.length ? (event: AfterEvent) => runAfter(hooks, event, onHookError) : null;\n\n const nowIso = () => new Date(now()).toISOString();\n\n // ---------------------------------------------------------------- helpers\n\n async function indexAdd(store: WebhooksStorage, key: string, value: string): Promise<void> {\n const list = (await store.getItem<string[]>(key)) ?? [];\n if (!list.includes(value)) {\n list.push(value);\n await store.setItem(key, list);\n }\n }\n\n async function indexRemove(store: WebhooksStorage, key: string, value: string): Promise<void> {\n const list = (await store.getItem<string[]>(key)) ?? [];\n const next = list.filter((v) => v !== value);\n if (next.length !== list.length) await store.setItem(key, next);\n }\n\n async function appendAudit(\n entry: Omit<AuditEntry, \"at\"> & { at?: string },\n scope: \"app\" | \"global\" = \"app\",\n ): Promise<void> {\n const key =\n scope === \"global\" || !entry.applicationKey\n ? globalAuditLogKey()\n : auditLogKey(entry.applicationKey);\n const log = (await storage.getItem<AuditEntry[]>(key)) ?? [];\n log.push({ at: nowIso(), ...entry });\n await storage.setItem(key, log);\n }\n\n async function requireApplication(applicationKey: string): Promise<Application> {\n const app = await storage.getItem<Application>(applicationMetaKey(applicationKey));\n if (!app) throw new NotFoundError(`Application \"${applicationKey}\" does not exist.`);\n return app;\n }\n\n async function requireEndpoint(applicationKey: string, endpointId: string): Promise<Endpoint> {\n await requireApplication(applicationKey);\n const endpoint = await storage.getItem<Endpoint>(endpointKey(applicationKey, endpointId));\n if (!endpoint) {\n throw new NotFoundError(\n `Endpoint \"${endpointId}\" does not exist in application \"${applicationKey}\".`,\n );\n }\n return endpoint;\n }\n\n /** Write a delivery + its due-index entry (they always move together). */\n async function writeDeliveryWithDue(delivery: Delivery, dueAtMillis: number): Promise<void> {\n await queueStorage.setItem(deliveryKey(delivery.applicationKey, delivery.id), delivery);\n await queueStorage.setItem<DueEntry>(\n dueKey(delivery.applicationKey, dueAtMillis, delivery.id),\n { app: delivery.applicationKey, deliveryId: delivery.id },\n );\n }\n\n /** Remove the due entry a delivery currently occupies, wherever it is. */\n async function removeDueEntry(delivery: Delivery): Promise<void> {\n const candidates: number[] = [];\n if (delivery.nextAttemptAt) candidates.push(Date.parse(delivery.nextAttemptAt));\n if (delivery.leaseUntil) candidates.push(Date.parse(delivery.leaseUntil));\n for (const millis of candidates) {\n if (Number.isFinite(millis)) {\n await queueStorage.removeItem(dueKey(delivery.applicationKey, millis, delivery.id));\n }\n }\n }\n\n async function listAttempts(\n applicationKey: string,\n deliveryId: string,\n ): Promise<DeliveryAttempt[]> {\n const keys = (await queueStorage.getKeys(attemptsPrefix(applicationKey, deliveryId))).sort();\n const attempts = await Promise.all(keys.map((k) => queueStorage.getItem<DeliveryAttempt>(k)));\n return attempts.filter((a): a is DeliveryAttempt => a !== null);\n }\n\n async function deleteDeliveryCascade(delivery: Delivery): Promise<void> {\n const app = delivery.applicationKey;\n await removeDueEntry(delivery);\n for (const k of await queueStorage.getKeys(attemptsPrefix(app, delivery.id))) {\n await queueStorage.removeItem(k);\n }\n await queueStorage.removeItem(byMessageKey(app, delivery.messageId, delivery.id));\n await queueStorage.removeItem(byEndpointKey(app, delivery.endpointId, delivery.id));\n await queueStorage.removeItem(deliveryKey(app, delivery.id));\n }\n\n const pageSize = (limit?: number) => Math.min(Math.max(limit ?? DEFAULT_PAGE, 1), MAX_PAGE);\n\n /** newest-first sort; id tiebreak keeps pagination stable. */\n const byCreatedAtDesc = <T extends { createdAt?: string; id: string }>(a: T, b: T): number => {\n const diff = Date.parse(b.createdAt ?? \"\") - Date.parse(a.createdAt ?? \"\");\n return diff !== 0 ? diff : a.id < b.id ? 1 : -1;\n };\n\n function paginate<T extends { id: string }>(sorted: T[], limit?: number, beforeId?: string): T[] {\n let start = 0;\n if (beforeId) {\n const idx = sorted.findIndex((item) => item.id === beforeId);\n // A cursor that no longer exists (pruned/deleted) means the page it\n // anchored is gone — return an empty page rather than silently\n // restarting from the newest item (which would loop the caller forever).\n if (idx < 0) return [];\n start = idx + 1;\n }\n return sorted.slice(start, start + pageSize(limit));\n }\n\n // ------------------------------------------------------------- retention\n\n let pruneInFlight: Promise<void> | null = null;\n\n async function pruneMessagesForApp(applicationKey: string): Promise<void> {\n const rule = options.retention?.messages;\n if (!rule || (rule.keepLast === undefined && rule.maxAge === undefined)) return;\n const keys = await storage.getKeys(messagesPrefix(applicationKey));\n const messages = (await Promise.all(keys.map((k) => storage.getItem<Message>(k)))).filter(\n (m): m is Message => m !== null,\n );\n messages.sort(byCreatedAtDesc);\n\n const maxAgeMs = rule.maxAge !== undefined ? durationToMs(rule.maxAge) : null;\n const cutoff = maxAgeMs !== null ? now() - maxAgeMs : null;\n const pruned: Message[] = [];\n\n for (const [index, message] of messages.entries()) {\n const keptByCount = rule.keepLast !== undefined && index < rule.keepLast;\n const keptByAge = cutoff !== null && Date.parse(message.createdAt) >= cutoff;\n // Union of keeps: prune only when NO rule keeps it.\n if (keptByCount || keptByAge) continue;\n if (rule.keepLast === undefined && cutoff === null) continue;\n\n // Never prune a message the dispatcher still needs.\n const deliveryIds = (\n await queueStorage.getKeys(byMessagePrefix(applicationKey, message.id))\n ).map(lastSegment);\n const deliveries = (\n await Promise.all(\n deliveryIds.map((id) => queueStorage.getItem<Delivery>(deliveryKey(applicationKey, id))),\n )\n ).filter((d): d is Delivery => d !== null);\n if (deliveries.some((d) => !isTerminalDeliveryStatus(d.status))) continue;\n\n for (const delivery of deliveries) await deleteDeliveryCascade(delivery);\n if (message.idempotencyKey) {\n await storage.removeItem(idempotencyKey(applicationKey, message.idempotencyKey));\n }\n await storage.removeItem(messageKey(applicationKey, message.id));\n pruned.push(message);\n }\n\n if (pruned.length && after) {\n await after({ type: \"message.pruned\", applicationKey, messages: pruned, at: nowIso() });\n }\n }\n\n async function pruneAuditLog(key: string, applicationKey?: string): Promise<void> {\n const rule = options.retention?.audit;\n if (!rule || (rule.keepLast === undefined && rule.maxAge === undefined)) return;\n const log = (await storage.getItem<AuditEntry[]>(key)) ?? [];\n if (!log.length) return;\n const maxAgeMs = rule.maxAge !== undefined ? durationToMs(rule.maxAge) : null;\n const cutoff = maxAgeMs !== null ? now() - maxAgeMs : null;\n // The log is append-ordered (oldest first).\n const kept: AuditEntry[] = [];\n const removed: AuditEntry[] = [];\n for (const [index, entry] of log.entries()) {\n const fromEnd = log.length - index; // 1 = newest\n const keptByCount = rule.keepLast !== undefined && fromEnd <= rule.keepLast;\n const keptByAge = cutoff !== null && Date.parse(entry.at) >= cutoff;\n if (keptByCount || keptByAge) kept.push(entry);\n else removed.push(entry);\n }\n if (removed.length) {\n await storage.setItem(key, kept);\n if (after) {\n await after({\n type: \"audit.pruned\",\n ...(applicationKey ? { applicationKey } : {}),\n entries: removed,\n at: nowIso(),\n });\n }\n }\n }\n\n async function prunePass(): Promise<void> {\n const apps = (await storage.getItem<string[]>(applicationsKey())) ?? [];\n for (const app of apps) {\n await pruneMessagesForApp(app);\n await pruneAuditLog(auditLogKey(app), app);\n }\n await pruneAuditLog(globalAuditLogKey());\n }\n\n /** Serialized: a call always gets a full pass over the state it observed. */\n async function prune(): Promise<void> {\n while (pruneInFlight) await pruneInFlight;\n pruneInFlight = prunePass().finally(() => {\n pruneInFlight = null;\n });\n await pruneInFlight;\n }\n\n function schedulePrune(): void {\n if (!options.retention) return;\n // Off the publish hot path: fire-and-forget on a fresh task.\n const timer = setTimeout(() => {\n prune().catch((error) => {\n // eslint-disable-next-line no-console\n console.warn(\"[@xtandard/webhooks] retention prune failed:\", error);\n });\n }, 0);\n (timer as { unref?: () => void }).unref?.();\n }\n\n // ------------------------------------------------------------------ core\n\n const core: WebhooksCore = {\n options: Object.freeze({\n storage,\n queueStorage,\n readonly,\n hooks,\n ...(options.retention ? { retention: options.retention } : {}),\n ...(options.dispatcher ? { dispatcher: options.dispatcher } : {}),\n secretRotationGrace,\n allowInsecureUrls: urlOptions.allowInsecureUrls,\n ...(options.urlPolicy ? { urlPolicy: options.urlPolicy } : {}),\n payloadLimitBytes,\n requireKnownEventTypes,\n ...(options.onDelivery ? { onDelivery: options.onDelivery } : {}),\n ...(options.onDeliveryError ? { onDeliveryError: options.onDeliveryError } : {}),\n now,\n }),\n\n // ------------------------------------------------------- applications\n\n async listApplications() {\n const keys = (await storage.getItem<string[]>(applicationsKey())) ?? [];\n const apps = await Promise.all(\n keys.map((k) => storage.getItem<Application>(applicationMetaKey(k))),\n );\n return apps.filter((a): a is Application => a !== null);\n },\n\n async createApplication(input, opts) {\n guard(\"create application\");\n assertValid(validateApplication(input));\n const existing = await storage.getItem<Application>(applicationMetaKey(input.key));\n if (existing) throw new ConflictError(`Application \"${input.key}\" already exists.`);\n const application: Application = {\n key: input.key,\n ...(input.name !== undefined ? { name: input.name } : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n createdAt: nowIso(),\n updatedAt: nowIso(),\n };\n if (before)\n await before({ type: \"application.create\", application, actor: opts?.actor ?? null });\n await storage.setItem(applicationMetaKey(application.key), application);\n await indexAdd(storage, applicationsKey(), application.key);\n await appendAudit({\n action: \"application.create\",\n by: opts?.actor ?? null,\n applicationKey: application.key,\n });\n if (after) await after({ type: \"application.created\", application, at: nowIso() });\n return application;\n },\n\n async getApplication(applicationKey) {\n return storage.getItem<Application>(applicationMetaKey(applicationKey));\n },\n\n async updateApplication(applicationKey, patch, opts) {\n guard(\"update application\");\n const current = await requireApplication(applicationKey);\n const application: Application = {\n ...current,\n ...(patch.name !== undefined ? { name: patch.name } : {}),\n ...(patch.metadata !== undefined ? { metadata: patch.metadata } : {}),\n updatedAt: nowIso(),\n };\n assertValid(validateApplication(application));\n if (before)\n await before({ type: \"application.update\", application, actor: opts?.actor ?? null });\n await storage.setItem(applicationMetaKey(applicationKey), application);\n await appendAudit({\n action: \"application.update\",\n by: opts?.actor ?? null,\n applicationKey,\n });\n if (after) await after({ type: \"application.updated\", application, at: nowIso() });\n return application;\n },\n\n async deleteApplication(applicationKey, opts) {\n guard(\"delete application\");\n const application = await requireApplication(applicationKey);\n if (before) {\n await before({ type: \"application.delete\", applicationKey, actor: opts?.actor ?? null });\n }\n for (const key of await storage.getKeys(applicationPrefix(applicationKey))) {\n await storage.removeItem(key);\n }\n if (queueStorage !== storage) {\n for (const key of await queueStorage.getKeys(applicationPrefix(applicationKey))) {\n await queueStorage.removeItem(key);\n }\n }\n await indexRemove(storage, applicationsKey(), applicationKey);\n await appendAudit(\n { action: \"application.delete\", by: opts?.actor ?? null, applicationKey },\n \"global\",\n );\n if (after) {\n await after({ type: \"application.deleted\", applicationKey, application, at: nowIso() });\n }\n },\n\n // -------------------------------------------------------- event types\n\n async listEventTypes() {\n const names = (await storage.getItem<string[]>(eventTypesKey())) ?? [];\n const types = await Promise.all(\n names.map((n) => storage.getItem<EventType>(eventTypeKey(n))),\n );\n return types\n .filter((t): t is EventType => t !== null)\n .sort((a, b) => a.name.localeCompare(b.name));\n },\n\n async getEventType(name) {\n return storage.getItem<EventType>(eventTypeKey(name));\n },\n\n async upsertEventType(input, opts) {\n guard(\"upsert event type\");\n assertValid(validateEventType(input));\n const existing = await storage.getItem<EventType>(eventTypeKey(input.name));\n const eventType: EventType = {\n ...existing,\n ...input,\n createdAt: existing?.createdAt ?? nowIso(),\n updatedAt: nowIso(),\n };\n if (before)\n await before({ type: \"event-type.upsert\", eventType, actor: opts?.actor ?? null });\n await storage.setItem(eventTypeKey(eventType.name), eventType);\n await indexAdd(storage, eventTypesKey(), eventType.name);\n await appendAudit(\n {\n action: existing ? \"event-type.update\" : \"event-type.create\",\n by: opts?.actor ?? null,\n subjectId: eventType.name,\n },\n \"global\",\n );\n if (after) await after({ type: \"event-type.upserted\", eventType, at: nowIso() });\n return eventType;\n },\n\n async deleteEventType(name, opts) {\n guard(\"delete event type\");\n const eventType = await storage.getItem<EventType>(eventTypeKey(name));\n if (!eventType) throw new NotFoundError(`Event type \"${name}\" does not exist.`);\n if (before) await before({ type: \"event-type.delete\", name, actor: opts?.actor ?? null });\n await storage.removeItem(eventTypeKey(name));\n await indexRemove(storage, eventTypesKey(), name);\n await appendAudit(\n { action: \"event-type.delete\", by: opts?.actor ?? null, subjectId: name },\n \"global\",\n );\n if (after) await after({ type: \"event-type.deleted\", name, eventType, at: nowIso() });\n },\n\n // ---------------------------------------------------------- endpoints\n\n async listEndpoints(applicationKey) {\n await requireApplication(applicationKey);\n const ids = (await storage.getItem<string[]>(endpointsKey(applicationKey))) ?? [];\n const endpoints = await Promise.all(\n ids.map((id) => storage.getItem<Endpoint>(endpointKey(applicationKey, id))),\n );\n return endpoints.filter((e): e is Endpoint => e !== null);\n },\n\n async getEndpoint(applicationKey, endpointId) {\n return storage.getItem<Endpoint>(endpointKey(applicationKey, endpointId));\n },\n\n async createEndpoint(applicationKey, input, opts) {\n guard(\"create endpoint\");\n await requireApplication(applicationKey);\n assertValid(validateEndpoint(input, urlOptions));\n const endpoint: Endpoint = {\n id: newId(\"ep\"),\n url: input.url,\n ...(input.description !== undefined ? { description: input.description } : {}),\n ...(input.eventTypes !== undefined ? { eventTypes: input.eventTypes } : {}),\n ...(input.headers !== undefined ? { headers: input.headers } : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.disabled ? { disabled: true, disabledReason: \"manual\" as const } : {}),\n secrets: [{ secret: generateSecret(), createdAt: nowIso() }],\n createdAt: nowIso(),\n updatedAt: nowIso(),\n firstFailingAt: null,\n };\n if (before) {\n await before({\n type: \"endpoint.create\",\n applicationKey,\n endpoint,\n actor: opts?.actor ?? null,\n });\n }\n await storage.setItem(endpointKey(applicationKey, endpoint.id), endpoint);\n await indexAdd(storage, endpointsKey(applicationKey), endpoint.id);\n await appendAudit({\n action: \"endpoint.create\",\n by: opts?.actor ?? null,\n applicationKey,\n subjectId: endpoint.id,\n });\n if (after) {\n await after({ type: \"endpoint.created\", applicationKey, endpoint, at: nowIso() });\n }\n return endpoint;\n },\n\n async updateEndpoint(applicationKey, endpointId, patch, opts) {\n guard(\"update endpoint\");\n const current = await requireEndpoint(applicationKey, endpointId);\n const endpoint: Endpoint = {\n ...current,\n ...(patch.url !== undefined ? { url: patch.url } : {}),\n ...(patch.description !== undefined ? { description: patch.description } : {}),\n ...(patch.eventTypes !== undefined ? { eventTypes: patch.eventTypes } : {}),\n ...(patch.headers !== undefined ? { headers: patch.headers } : {}),\n ...(patch.metadata !== undefined ? { metadata: patch.metadata } : {}),\n updatedAt: nowIso(),\n };\n assertValid(validateEndpoint(endpoint, urlOptions));\n if (before) {\n await before({\n type: \"endpoint.update\",\n applicationKey,\n endpoint,\n actor: opts?.actor ?? null,\n });\n }\n await storage.setItem(endpointKey(applicationKey, endpointId), endpoint);\n await appendAudit({\n action: \"endpoint.update\",\n by: opts?.actor ?? null,\n applicationKey,\n subjectId: endpointId,\n });\n if (after) {\n await after({ type: \"endpoint.updated\", applicationKey, endpoint, at: nowIso() });\n }\n return endpoint;\n },\n\n async deleteEndpoint(applicationKey, endpointId, opts) {\n guard(\"delete endpoint\");\n const endpoint = await requireEndpoint(applicationKey, endpointId);\n if (before) {\n await before({\n type: \"endpoint.delete\",\n applicationKey,\n endpointId,\n actor: opts?.actor ?? null,\n });\n }\n await storage.removeItem(endpointKey(applicationKey, endpointId));\n await indexRemove(storage, endpointsKey(applicationKey), endpointId);\n await appendAudit({\n action: \"endpoint.delete\",\n by: opts?.actor ?? null,\n applicationKey,\n subjectId: endpointId,\n });\n if (after) {\n await after({ type: \"endpoint.deleted\", applicationKey, endpoint, at: nowIso() });\n }\n },\n\n async rotateSecret(applicationKey, endpointId, opts) {\n guard(\"rotate endpoint secret\");\n const current = await requireEndpoint(applicationKey, endpointId);\n if (before) {\n await before({\n type: \"endpoint.rotate-secret\",\n applicationKey,\n endpointId,\n actor: opts?.actor ?? null,\n });\n }\n const graceMs = durationToMs(secretRotationGrace);\n const nowMs = now();\n const [previous, ...rest] = current.secrets;\n const secrets = [\n { secret: generateSecret(), createdAt: nowIso() },\n ...(previous ? [{ ...previous, expiresAt: new Date(nowMs + graceMs).toISOString() }] : []),\n // Lazy pruning: drop grace secrets that have already expired.\n ...rest.filter((s) => s.expiresAt && Date.parse(s.expiresAt) > nowMs),\n ];\n const endpoint: Endpoint = { ...current, secrets, updatedAt: nowIso() };\n await storage.setItem(endpointKey(applicationKey, endpointId), endpoint);\n await appendAudit({\n action: \"endpoint.rotate-secret\",\n by: opts?.actor ?? null,\n applicationKey,\n subjectId: endpointId,\n });\n if (after) {\n await after({ type: \"endpoint.secret-rotated\", applicationKey, endpoint, at: nowIso() });\n }\n return endpoint;\n },\n\n async getSecrets(applicationKey, endpointId) {\n const endpoint = await requireEndpoint(applicationKey, endpointId);\n return endpoint.secrets;\n },\n\n async enableEndpoint(applicationKey, endpointId, opts) {\n guard(\"enable endpoint\");\n const current = await requireEndpoint(applicationKey, endpointId);\n if (before) {\n await before({\n type: \"endpoint.enable\",\n applicationKey,\n endpointId,\n actor: opts?.actor ?? null,\n });\n }\n const endpoint: Endpoint = { ...current, updatedAt: nowIso(), firstFailingAt: null };\n delete endpoint.disabled;\n delete endpoint.disabledReason;\n await storage.setItem(endpointKey(applicationKey, endpointId), endpoint);\n await appendAudit({\n action: \"endpoint.enable\",\n by: opts?.actor ?? null,\n applicationKey,\n subjectId: endpointId,\n });\n if (after) {\n await after({ type: \"endpoint.enabled\", applicationKey, endpoint, at: nowIso() });\n }\n return endpoint;\n },\n\n async disableEndpoint(applicationKey, endpointId, opts) {\n guard(\"disable endpoint\");\n const current = await requireEndpoint(applicationKey, endpointId);\n if (before) {\n await before({\n type: \"endpoint.disable\",\n applicationKey,\n endpointId,\n actor: opts?.actor ?? null,\n });\n }\n const endpoint: Endpoint = {\n ...current,\n disabled: true,\n disabledReason: \"manual\",\n updatedAt: nowIso(),\n };\n await storage.setItem(endpointKey(applicationKey, endpointId), endpoint);\n await appendAudit({\n action: \"endpoint.disable\",\n by: opts?.actor ?? null,\n applicationKey,\n subjectId: endpointId,\n });\n if (after) {\n await after({ type: \"endpoint.disabled\", applicationKey, endpoint, at: nowIso() });\n }\n return endpoint;\n },\n\n // -------------------------------------------------------------- publish\n\n async publish(applicationKey, input, opts) {\n guard(\"publish message\");\n await requireApplication(applicationKey);\n\n if (requireKnownEventTypes) {\n const known = await storage.getItem<EventType>(eventTypeKey(input.eventType));\n if (!known) {\n throw new ValidationError([\n {\n path: \"message.eventType\",\n message: `unknown event type \"${input.eventType}\" (create it first, or set requireKnownEventTypes: false)`,\n },\n ]);\n }\n }\n\n const serializedPayload = JSON.stringify(input.payload);\n if (serializedPayload === undefined) {\n throw new ValidationError([\n { path: \"message.payload\", message: \"payload must be JSON-serializable\" },\n ]);\n }\n const size = new TextEncoder().encode(serializedPayload).length;\n if (size > payloadLimitBytes) throw new PayloadTooLargeError(size, payloadLimitBytes);\n\n // The idempotency key becomes a storage key segment — reject anything that\n // could escape its namespace or traverse the filesystem (file adapter).\n if (input.idempotencyKey !== undefined) {\n const issues = validateKeySegment(input.idempotencyKey, \"message.idempotencyKey\");\n assertValid({ valid: issues.length === 0, errors: issues });\n }\n\n // Idempotency short-circuit: same key + same payload returns the original.\n if (input.idempotencyKey) {\n const existingId = await storage.getItem<string>(\n idempotencyKey(applicationKey, input.idempotencyKey),\n );\n if (existingId) {\n const existing = await storage.getItem<Message>(messageKey(applicationKey, existingId));\n if (existing) {\n if (JSON.stringify(existing.payload) !== serializedPayload) {\n throw new IdempotencyConflictError(input.idempotencyKey);\n }\n const deliveryIds = (\n await queueStorage.getKeys(byMessagePrefix(applicationKey, existing.id))\n ).map(lastSegment);\n const deliveries = (\n await Promise.all(\n deliveryIds.map((id) =>\n queueStorage.getItem<Delivery>(deliveryKey(applicationKey, id)),\n ),\n )\n ).filter((d): d is Delivery => d !== null);\n return { message: existing, deliveries, deduplicated: true };\n }\n }\n }\n\n if (before) {\n await before({\n type: \"message.publish\",\n applicationKey,\n eventType: input.eventType,\n payload: input.payload,\n ...(input.idempotencyKey !== undefined ? { idempotencyKey: input.idempotencyKey } : {}),\n actor: opts?.actor ?? null,\n });\n }\n\n const createdAt = nowIso();\n const timestamp = input.timestamp ?? createdAt;\n const message: Message = {\n id: newId(\"msg\"),\n eventType: input.eventType,\n payload: input.payload,\n timestamp,\n ...(input.idempotencyKey !== undefined ? { idempotencyKey: input.idempotencyKey } : {}),\n // Serialized ONCE so the signed bytes are identical across every retry.\n envelope: JSON.stringify({ type: input.eventType, timestamp, data: input.payload }),\n createdAt,\n };\n\n // Fan out to matching enabled endpoints.\n const ids = (await storage.getItem<string[]>(endpointsKey(applicationKey))) ?? [];\n const endpoints = (\n await Promise.all(\n ids.map((id) => storage.getItem<Endpoint>(endpointKey(applicationKey, id))),\n )\n ).filter((e): e is Endpoint => e !== null);\n const matching = endpoints.filter(\n (e) =>\n !e.disabled &&\n (!e.eventTypes || e.eventTypes.length === 0 || e.eventTypes.includes(input.eventType)),\n );\n\n await storage.setItem(messageKey(applicationKey, message.id), message);\n if (input.idempotencyKey) {\n await storage.setItem(idempotencyKey(applicationKey, input.idempotencyKey), message.id);\n }\n\n const nowMs = now();\n const deliveries: Delivery[] = [];\n for (const endpoint of matching) {\n const delivery: Delivery = {\n id: newId(\"dlv\"),\n applicationKey,\n messageId: message.id,\n endpointId: endpoint.id,\n status: \"pending\",\n attemptCount: 0,\n nextAttemptAt: createdAt,\n leaseUntil: null,\n createdAt,\n updatedAt: createdAt,\n };\n await writeDeliveryWithDue(delivery, nowMs);\n await queueStorage.setItem(byMessageKey(applicationKey, message.id, delivery.id), 1);\n await queueStorage.setItem(byEndpointKey(applicationKey, endpoint.id, delivery.id), 1);\n deliveries.push(delivery);\n }\n\n if (after) {\n await after({\n type: \"message.published\",\n applicationKey,\n message,\n deliveryIds: deliveries.map((d) => d.id),\n at: nowIso(),\n });\n }\n schedulePrune();\n return { message, deliveries, deduplicated: false };\n },\n\n // -------------------------------------------------- messages/deliveries\n\n async listMessages(applicationKey, opts = {}) {\n await requireApplication(applicationKey);\n const keys = await storage.getKeys(messagesPrefix(applicationKey));\n let messages = (await Promise.all(keys.map((k) => storage.getItem<Message>(k)))).filter(\n (m): m is Message => m !== null,\n );\n if (opts.eventType) messages = messages.filter((m) => m.eventType === opts.eventType);\n messages.sort(byCreatedAtDesc);\n return paginate(messages, opts.limit, opts.before);\n },\n\n async getMessage(applicationKey, messageId) {\n return storage.getItem<Message>(messageKey(applicationKey, messageId));\n },\n\n async listDeliveries(applicationKey, opts = {}) {\n await requireApplication(applicationKey);\n let ids: string[];\n if (opts.messageId) {\n ids = (await queueStorage.getKeys(byMessagePrefix(applicationKey, opts.messageId))).map(\n lastSegment,\n );\n } else if (opts.endpointId) {\n ids = (await queueStorage.getKeys(byEndpointPrefix(applicationKey, opts.endpointId))).map(\n lastSegment,\n );\n } else {\n ids = (await queueStorage.getKeys(deliveriesPrefix(applicationKey))).map(lastSegment);\n }\n let deliveries = (\n await Promise.all(\n ids.map((id) => queueStorage.getItem<Delivery>(deliveryKey(applicationKey, id))),\n )\n ).filter((d): d is Delivery => d !== null);\n if (opts.status) deliveries = deliveries.filter((d) => d.status === opts.status);\n if (opts.endpointId) deliveries = deliveries.filter((d) => d.endpointId === opts.endpointId);\n if (opts.messageId) deliveries = deliveries.filter((d) => d.messageId === opts.messageId);\n deliveries.sort(byCreatedAtDesc);\n return paginate(deliveries, opts.limit, opts.before);\n },\n\n async getDelivery(applicationKey, deliveryId) {\n const delivery = await queueStorage.getItem<Delivery>(\n deliveryKey(applicationKey, deliveryId),\n );\n if (!delivery) return null;\n return { delivery, attempts: await listAttempts(applicationKey, deliveryId) };\n },\n\n async previewDeliveryRequest(applicationKey, deliveryId) {\n const delivery = await queueStorage.getItem<Delivery>(\n deliveryKey(applicationKey, deliveryId),\n );\n if (!delivery) return null;\n const [message, endpoint] = await Promise.all([\n storage.getItem<Message>(messageKey(applicationKey, delivery.messageId)),\n storage.getItem<Endpoint>(endpointKey(applicationKey, delivery.endpointId)),\n ]);\n if (!message || !endpoint) return null;\n return buildSignedRequest({\n endpoint,\n messageId: message.id,\n body: message.envelope,\n nowMs: now(),\n userAgent: `xtandard-webhooks/${VERSION}`,\n });\n },\n\n async retryDelivery(applicationKey, deliveryId, opts) {\n guard(\"retry delivery\");\n await requireApplication(applicationKey);\n const current = await queueStorage.getItem<Delivery>(deliveryKey(applicationKey, deliveryId));\n if (!current) throw new NotFoundError(`Delivery \"${deliveryId}\" does not exist.`);\n if (current.status !== \"failed\") {\n throw new ValidationError([\n {\n path: \"delivery.status\",\n message: `only failed (dead-letter) deliveries can be retried; this one is \"${current.status}\"`,\n },\n ]);\n }\n if (before) {\n await before({\n type: \"delivery.retry\",\n applicationKey,\n deliveryId,\n actor: opts?.actor ?? null,\n });\n }\n const nowMs = now();\n const delivery: Delivery = {\n ...current,\n status: \"pending\",\n nextAttemptAt: nowIso(),\n leaseUntil: null,\n pendingTrigger: \"manual\",\n updatedAt: nowIso(),\n };\n await writeDeliveryWithDue(delivery, nowMs);\n await appendAudit({\n action: \"delivery.retry\",\n by: opts?.actor ?? null,\n applicationKey,\n subjectId: deliveryId,\n });\n return delivery;\n },\n\n async recoverEndpoint(applicationKey, endpointId, input, opts) {\n guard(\"recover endpoint\");\n await requireEndpoint(applicationKey, endpointId);\n const sinceMs = Date.parse(input.since);\n if (!Number.isFinite(sinceMs)) {\n throw new ValidationError([\n { path: \"since\", message: `\"${input.since}\" is not a valid timestamp` },\n ]);\n }\n if (before) {\n await before({\n type: \"endpoint.recover\",\n applicationKey,\n endpointId,\n since: input.since,\n actor: opts?.actor ?? null,\n });\n }\n const ids = (await queueStorage.getKeys(byEndpointPrefix(applicationKey, endpointId))).map(\n lastSegment,\n );\n const nowMs = now();\n const recovered: string[] = [];\n for (const id of ids) {\n const delivery = await queueStorage.getItem<Delivery>(deliveryKey(applicationKey, id));\n if (!delivery || delivery.status !== \"failed\") continue;\n if (Date.parse(delivery.createdAt) < sinceMs) continue;\n await writeDeliveryWithDue(\n {\n ...delivery,\n status: \"pending\",\n nextAttemptAt: nowIso(),\n leaseUntil: null,\n pendingTrigger: \"manual\",\n updatedAt: nowIso(),\n },\n nowMs,\n );\n recovered.push(id);\n }\n await appendAudit({\n action: \"endpoint.recover\",\n by: opts?.actor ?? null,\n applicationKey,\n subjectId: endpointId,\n message: `${recovered.length} deliveries re-queued since ${input.since}`,\n });\n return { deliveryIds: recovered };\n },\n\n async sendExample(applicationKey, endpointId, input) {\n guard(\"send example delivery\"); // readonly must emit zero outbound traffic\n const endpoint = await requireEndpoint(applicationKey, endpointId);\n const messageId = newId(\"msg\");\n const timestamp = nowIso();\n const body = JSON.stringify({\n type: input.eventType,\n timestamp,\n data: input.payload ?? { example: true, eventType: input.eventType },\n });\n const dispatcher = options.dispatcher;\n const outcome = await attemptDelivery({\n endpoint,\n messageId,\n body,\n ...(dispatcher?.timeoutMs !== undefined ? { timeoutMs: dispatcher.timeoutMs } : {}),\n ...(dispatcher?.responseBodyLimit !== undefined\n ? { responseBodyLimit: dispatcher.responseBodyLimit }\n : {}),\n ...(dispatcher?.fetch ? { fetch: dispatcher.fetch } : {}),\n ...(dispatcher?.userAgent !== undefined ? { userAgent: dispatcher.userAgent } : {}),\n nowMs: now(),\n });\n if (options.onDelivery) {\n emitDelivery(\n options.onDelivery,\n {\n applicationKey,\n endpointId,\n messageId,\n deliveryId: messageId, // no persisted delivery for a test send\n eventType: input.eventType,\n attemptNumber: 1,\n ok: outcome.ok,\n terminal: true,\n ...(outcome.httpStatus !== undefined ? { httpStatus: outcome.httpStatus } : {}),\n durationMs: outcome.durationMs,\n trigger: \"test\",\n at: outcome.at,\n },\n options.onDeliveryError,\n );\n }\n return { outcome, body, messageId };\n },\n\n // ---------------------------------------------------------------- audit\n\n async listAudit(applicationKey) {\n if (applicationKey) {\n const log = (await storage.getItem<AuditEntry[]>(auditLogKey(applicationKey))) ?? [];\n return [...log].reverse();\n }\n const apps = (await storage.getItem<string[]>(applicationsKey())) ?? [];\n const logs = await Promise.all([\n storage.getItem<AuditEntry[]>(globalAuditLogKey()),\n ...apps.map((app) => storage.getItem<AuditEntry[]>(auditLogKey(app))),\n ]);\n const merged = logs.flatMap((log) => log ?? []);\n merged.sort((a, b) => Date.parse(b.at) - Date.parse(a.at));\n return merged;\n },\n\n prune,\n\n // ------------------------------------------------- dispatcher internals\n\n async claimDueDeliveries(input) {\n const nowMs = now();\n const nowStr = new Date(nowMs).toISOString();\n if (hasDeliveryQueue(queueStorage)) {\n return queueStorage.claimDue({ now: nowStr, limit: input.limit, leaseMs: input.leaseMs });\n }\n\n // Generic fallback: scan each app's due index (13-digit zero-padded keys\n // sort chronologically), claim with CAS when the storage supports it.\n const apps = (await storage.getItem<string[]>(applicationsKey())) ?? [];\n const claimed: Delivery[] = [];\n const cas = isCompareAndSwap(queueStorage) ? queueStorage : null;\n\n for (const app of apps) {\n if (claimed.length >= input.limit) break;\n const dueKeys = (await queueStorage.getKeys(`whk/${app}/due/`)).sort();\n for (const key of dueKeys) {\n if (claimed.length >= input.limit) break;\n const suffix = lastSegment(key);\n const sep = suffix.indexOf(\"~\");\n if (sep === -1) continue;\n const dueAt = Number(suffix.slice(0, sep));\n if (!Number.isFinite(dueAt) || dueAt > nowMs) break; // sorted — the rest are later\n const entry = await queueStorage.getItem<DueEntry>(key);\n if (!entry) continue;\n const dKey = deliveryKey(entry.app, entry.deliveryId);\n const delivery = await queueStorage.getItem<Delivery>(dKey);\n if (!delivery || isTerminalDeliveryStatus(delivery.status)) {\n await queueStorage.removeItem(key); // orphan sweep\n continue;\n }\n const leaseExpired =\n delivery.status === \"delivering\" &&\n (!delivery.leaseUntil || Date.parse(delivery.leaseUntil) <= nowMs);\n if (delivery.status !== \"pending\" && !leaseExpired) continue;\n\n const next: Delivery = {\n ...delivery,\n status: \"delivering\",\n leaseUntil: new Date(nowMs + input.leaseMs).toISOString(),\n updatedAt: nowStr,\n };\n if (cas) {\n const won = await cas.compareAndSwap({ key: dKey, expected: delivery, next });\n if (!won) continue; // another dispatcher claimed it first\n } else {\n await queueStorage.setItem(dKey, next);\n }\n await queueStorage.removeItem(key);\n await queueStorage.setItem<DueEntry>(\n dueKey(entry.app, nowMs + input.leaseMs, entry.deliveryId),\n entry,\n );\n claimed.push(next);\n }\n }\n return claimed;\n },\n\n async recordAttempt(input) {\n const { delivery, outcome } = input;\n const app = delivery.applicationKey;\n const attemptNumber = delivery.attemptCount + 1;\n const attempt: DeliveryAttempt = {\n id: newId(\"atp\"),\n deliveryId: delivery.id,\n attemptNumber,\n at: outcome.at,\n durationMs: outcome.durationMs,\n ok: outcome.ok,\n ...(outcome.httpStatus !== undefined ? { httpStatus: outcome.httpStatus } : {}),\n ...(outcome.error !== undefined ? { error: outcome.error } : {}),\n ...(outcome.responseBody !== undefined ? { responseBody: outcome.responseBody } : {}),\n trigger: input.trigger,\n };\n await queueStorage.setItem(attemptKey(app, delivery.id, attemptNumber), attempt);\n\n await removeDueEntry(delivery);\n\n // The one-shot trigger hint has served its purpose.\n const base: Delivery = { ...delivery };\n delete base.pendingTrigger;\n\n let next: Delivery;\n if (outcome.ok) {\n next = {\n ...base,\n status: \"succeeded\",\n attemptCount: attemptNumber,\n nextAttemptAt: null,\n leaseUntil: null,\n updatedAt: nowIso(),\n };\n await queueStorage.setItem(deliveryKey(app, delivery.id), next);\n if (after) {\n await after({\n type: \"delivery.succeeded\",\n applicationKey: app,\n delivery: next,\n attempt,\n at: nowIso(),\n });\n }\n } else if (input.nextAttemptAt) {\n next = {\n ...base,\n status: \"pending\",\n attemptCount: attemptNumber,\n nextAttemptAt: input.nextAttemptAt,\n leaseUntil: null,\n updatedAt: nowIso(),\n };\n await writeDeliveryWithDue(next, Date.parse(input.nextAttemptAt));\n } else {\n // Exhausted — dead-letter.\n next = {\n ...base,\n status: \"failed\",\n attemptCount: attemptNumber,\n nextAttemptAt: null,\n leaseUntil: null,\n updatedAt: nowIso(),\n };\n await queueStorage.setItem(deliveryKey(app, delivery.id), next);\n if (after) {\n await after({\n type: \"delivery.exhausted\",\n applicationKey: app,\n delivery: next,\n attempts: await listAttempts(app, delivery.id),\n at: nowIso(),\n });\n }\n }\n\n if (options.onDelivery) {\n emitDelivery(\n options.onDelivery,\n {\n applicationKey: app,\n endpointId: delivery.endpointId,\n messageId: delivery.messageId,\n deliveryId: delivery.id,\n eventType: input.eventType,\n attemptNumber,\n ok: outcome.ok,\n terminal: isTerminalDeliveryStatus(next.status),\n ...(outcome.httpStatus !== undefined ? { httpStatus: outcome.httpStatus } : {}),\n durationMs: outcome.durationMs,\n trigger: input.trigger,\n at: outcome.at,\n },\n options.onDeliveryError,\n );\n }\n return next;\n },\n\n async noteEndpointOutcome(applicationKey, endpointId, ok, policy) {\n const key = endpointKey(applicationKey, endpointId);\n const failingForDays = policy === false ? undefined : (policy?.failingForDays ?? 5);\n\n // Compute the failure-accounting delta from the *latest* endpoint record,\n // and commit it without clobbering a concurrent control-plane write\n // (enable/disable/edit runs in the web process while the dispatcher runs\n // here). With CAS storage this is a retry loop; without it we re-read\n // immediately before writing to shrink — not eliminate — the window (the\n // single-dispatcher assumption already applies to non-CAS backends).\n const plan = (current: Endpoint): { next: Endpoint; disabled: boolean } | null => {\n if (ok) {\n if (!current.firstFailingAt) return null; // nothing to clear\n return { next: { ...current, firstFailingAt: null }, disabled: false };\n }\n const firstFailingAt = current.firstFailingAt ?? nowIso();\n let next: Endpoint = { ...current, firstFailingAt };\n const shouldDisable =\n failingForDays !== undefined &&\n !current.disabled &&\n now() - Date.parse(firstFailingAt) > failingForDays * 86_400_000;\n if (shouldDisable) {\n next = { ...next, disabled: true, disabledReason: \"auto\", updatedAt: nowIso() };\n }\n return { next, disabled: shouldDisable };\n };\n\n const cas = isCompareAndSwap(storage) ? storage : null;\n let committed: { next: Endpoint; disabled: boolean } | null = null;\n for (let attempt = 0; attempt < 5; attempt++) {\n const current = await storage.getItem<Endpoint>(key);\n if (!current) return null;\n const planned = plan(current);\n if (!planned) return null;\n if (cas) {\n const won = await cas.compareAndSwap({ key, expected: current, next: planned.next });\n if (!won) continue; // a concurrent write landed — re-read and re-plan\n } else {\n await storage.setItem(key, planned.next);\n }\n committed = planned;\n break;\n }\n if (!committed) return null;\n\n const updated = committed.next;\n const shouldDisable = committed.disabled;\n\n if (shouldDisable) {\n await appendAudit({\n action: \"endpoint.disable\",\n applicationKey,\n subjectId: endpointId,\n message: `auto-disabled: failing since ${updated.firstFailingAt}`,\n });\n if (after) {\n await after({\n type: \"endpoint.auto-disabled\",\n applicationKey,\n endpoint: updated,\n at: nowIso(),\n });\n }\n return updated;\n }\n return null;\n },\n };\n\n return core;\n}\n"],"mappings":"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"}
|