elysia-rack 0.1.1

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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/Dashboard-xpstr7fr.js +172 -0
  4. package/dist/Panel-fbp3wrsw.js +738 -0
  5. package/dist/index-37x76zdn.js +4 -0
  6. package/dist/index-zc7rgvmm.js +13 -0
  7. package/dist/panel-app.js +1 -0
  8. package/dist/panel-theme.js +1 -0
  9. package/dist/panel.css +1 -0
  10. package/dist/rack/adapter.d.ts +5 -0
  11. package/dist/rack/adapters/drizzle.d.ts +2 -0
  12. package/dist/rack/adapters/index.d.ts +59 -0
  13. package/dist/rack/adapters/prisma.d.ts +2 -0
  14. package/dist/rack/authorization.d.ts +23 -0
  15. package/dist/rack/idempotency.d.ts +9 -0
  16. package/dist/rack/index.d.ts +40 -0
  17. package/dist/rack/index.js +1362 -0
  18. package/dist/rack/models/drizzle.d.ts +4 -0
  19. package/dist/rack/models/index.d.ts +24 -0
  20. package/dist/rack/models/prisma.d.ts +4 -0
  21. package/dist/rack/openapi.d.ts +6 -0
  22. package/dist/rack/page.d.ts +33 -0
  23. package/dist/rack/query.d.ts +22 -0
  24. package/dist/rack/registry.d.ts +20 -0
  25. package/dist/rack/types/authorization.d.ts +16 -0
  26. package/dist/rack/types/idempotency.d.ts +46 -0
  27. package/dist/rack/types/index.d.ts +89 -0
  28. package/dist/rack/types/metadata.d.ts +36 -0
  29. package/dist/rack/types/openapi.d.ts +22 -0
  30. package/dist/rack/types/operations.d.ts +14 -0
  31. package/dist/rack/types/page.d.ts +41 -0
  32. package/dist/rack/types/query.d.ts +30 -0
  33. package/dist/rack/types/validation.d.ts +19 -0
  34. package/dist/react/index.d.ts +64 -0
  35. package/dist/react/index.js +126 -0
  36. package/dist/react/page/Dashboard.d.ts +7 -0
  37. package/dist/react/page/Panel.d.ts +36 -0
  38. package/dist/react/page/client/panel.d.ts +1 -0
  39. package/dist/react/page/client/theme.d.ts +1 -0
  40. package/dist/react/page/components/Breadcrumb.d.ts +7 -0
  41. package/dist/react/page/components/DataTable.d.ts +10 -0
  42. package/dist/react/page/components/Masthead.d.ts +7 -0
  43. package/dist/react/page/components/Pagination.d.ts +10 -0
  44. package/dist/react/page/components/Sidebar.d.ts +16 -0
  45. package/dist/react/page/components/Toolbar.d.ts +7 -0
  46. package/dist/react/page/components/href.d.ts +10 -0
  47. package/dist/react/page/components/panelForm.d.ts +9 -0
  48. package/dist/react/render.d.ts +2 -0
  49. package/dist/react/types.d.ts +16 -0
  50. package/package.json +89 -0
@@ -0,0 +1,4 @@
1
+ import { createRequire } from "node:module";
2
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
+
4
+ export { __require };
@@ -0,0 +1,13 @@
1
+ // src/rack/registry.ts
2
+ var registrations = new Map;
3
+ function registerRack(reg) {
4
+ registrations.set(reg.path, reg);
5
+ }
6
+ function listRacks() {
7
+ return [...registrations.values()];
8
+ }
9
+ function clearRacks() {
10
+ registrations.clear();
11
+ }
12
+
13
+ export { registerRack, listRacks, clearRacks };
@@ -0,0 +1 @@
1
+ function e(e,t={}){let n=new URLSearchParams;for(let[r,i]of Object.entries({...e,...t}))i!=null&&i!==``&&n.set(r,Array.isArray(i)?i.join(`,`):String(i));let r=n.toString();return r?`?${r}`:`?`}function t(e,t){let n=[...new Set([1,t,e-1,e,e+1])].filter(e=>e>=1&&e<=t).sort((e,t)=>e-t),r=[],i=0;for(let e of n)e-i>1&&r.push(`…`),r.push(e),i=e;return r}function n(e){let t={},n=e.elements||[];for(let e=0;e<n.length;e++){let r=n[e];if(r&&r.name&&!r.disabled){if(r.type===`checkbox`){r.checked&&(t[r.name]=!0);continue}if(r.value!==``&&r.value!==void 0&&r.value!==null){if(r.hasAttribute&&r.hasAttribute(`data-json`)){try{t[r.name]=JSON.parse(r.value)}catch{return{error:`Invalid JSON in ${r.name}`}}continue}t[r.name]=r.value}}}return{body:t}}function r(e,t){let n=e.elements||[];for(let e=0;e<n.length;e++){let r=n[e];if(!r||!r.name)continue;let i=t[r.name];if(i!=null){if(r.type===`checkbox`){r.checked=i===!0||i===`true`||i===1;continue}if(r.type===`datetime-local`&&typeof i==`string`){r.value=i.slice(0,16);continue}r.value=typeof i==`object`?JSON.stringify(i):String(i)}}}function i(e){return String(e??``).split(`&`).join(`&amp;`).split(`<`).join(`&lt;`).split(`>`).join(`&gt;`).split(`"`).join(`&quot;`)}function a(e){return e==null?``:typeof e==`object`?JSON.stringify(e):String(e)}function o(e,t){if(e!==`status`||typeof t!=`string`)return null;let n=t.toLowerCase();return n===`active`?`bg-success-muted text-success-muted-foreground`:n===`archived`?`bg-warning-muted text-warning-muted-foreground`:`bg-badge-background text-badge-foreground`}function s(e){let t={};return e.forEach((e,n)=>{t[n]=e}),t}function c(e){let t=e.getAttribute(`data-query-url`)||``;return t.slice(-5)===`/data`?t.slice(0,-5):t||`?`}function l(){try{if(window.crypto?.randomUUID)return window.crypto.randomUUID()}catch{}return`k-${Date.now().toString(36)}-${Math.floor(Math.random()*1e9).toString(36)}`}function u(e,t){let n=e.querySelector(`[data-form-error]`);n&&(n.textContent=t)}function d(e){g(e,new URLSearchParams(window.location.search))}function f(e){return`<td class="border-table-border border-t px-4 py-2 whitespace-nowrap"><div class="border-table-border inline-flex overflow-hidden rounded-md border"><button type="button" data-edit-id="${i(e)}" class="text-link hover:bg-table-row-hover px-2 py-1 text-sm font-semibold">Edit</button><button type="button" data-delete-id="${i(e)}" class="border-table-border text-destructive hover:bg-table-row-hover border-l px-2 py-1 text-sm font-semibold">Delete</button></div></td>`}function p(e,t,n,r,s,c){if(!n.length){e.innerHTML=`<tr><td colspan="${t.length}" class="text-text-muted px-4 py-10 text-center">No records found.</td></tr>`;return}e.innerHTML=n.map(e=>{let n=e[r]==null?``:String(e[r]),l=`<tr class="hover:bg-table-row-hover">`;return s&&(l+=`<td class="border-table-border border-t px-4 py-2"><input type="checkbox" data-select-row value="${i(n)}" aria-label="Select row ${i(n)}"></td>`),l+=t.map(t=>{let n=o(t,e[t]);return`<td class="border-table-border border-t px-4 py-2">${n?`<span class="rounded-full px-2 py-0.5 text-xs font-semibold ${n}">${i(a(e[t]))}</span>`:i(a(e[t]))}</td>`}).join(``),c&&(l+=f(n)),l+`</tr>`}).join(``)}function m(n,r,a,o){let s=`border-border rounded-md border px-3 py-1 text-sm hover:bg-navigation-hover`,c=`border-border text-text-disabled rounded-md border px-3 py-1 text-sm`,l=a>1?`<a class="${s}" data-qlink href="${i(e(r,{page:a-1}))}">← Previous</a>`:`<span class="${c}">← Previous</span>`;for(let n of t(a,o))l+=n===`…`?`<span class="text-text-muted px-1">…</span>`:n===a?`<span class="bg-primary text-primary-foreground rounded-md px-3 py-1 text-sm font-bold">${n}</span>`:`<a class="${s}" data-qlink href="${i(e(r,{page:n}))}">${n}</a>`;l+=a<o?`<a class="${s}" data-qlink href="${i(e(r,{page:a+1}))}">Next →</a>`:`<span class="${c}">Next →</span>`,n.innerHTML=l}function h(t,n,r){let i=s(r),a=[];Array.prototype.forEach.call(t.querySelectorAll(`thead th[data-col]`),e=>{a.push(e.getAttribute(`data-col`))});let o=n.query??{},c=o.page??1,l=o.limit??20,u=n.total??0,d=Math.max(1,Math.ceil(u/l)),f=t.querySelector(`table`),h=!!f?.hasAttribute(`data-selectable`),g=!!f?.hasAttribute(`data-editable`),_=f?.getAttribute(`data-pk`)||`id`,y=t.querySelector(`[data-panel-rows]`);y&&p(y,a,n.data??[],_,h,g);let b=t.querySelector(`[data-panel-count]`);b&&(b.textContent=`Page ${c} of ${d} — ${u===0?0:(c-1)*l+1}–${Math.min(c*l,u)} of ${u} records`);let x=t.querySelector(`[data-panel-pages]`);x&&m(x,i,c,d);let S=o.sort??{};Array.prototype.forEach.call(t.querySelectorAll(`a[data-sort-link]`),t=>{let n=t.getAttribute(`data-sort-link`),r=S.field===n,a=r&&S.direction===`asc`?`desc`:`asc`;t.setAttribute(`href`,e(i,{sort:n,order:a}));let o=t.querySelector(`[data-sort-ind]`);o&&(o.textContent=r?S.direction===`asc`?` ▲`:` ▼`:``)});try{window.history.replaceState(null,``,e(i,{}))}catch{}v(t)}async function g(e,t){let n=e.getAttribute(`data-query-url`)||``,r=t.toString(),i=await fetch(n+(r?`?${r}`:``),{method:`QUERY`,headers:{Accept:`application/json`}});i.ok&&h(e,await i.json(),t)}function _(e){let t=[];return Array.prototype.forEach.call(e.querySelectorAll(`[data-select-row]:checked`),e=>{t.push(e.value)}),t}function v(e){let t=_(e),n=e.querySelector(`[data-bulk-bar]`);n&&(n.style.display=t.length?``:`none`);let r=e.querySelector(`[data-bulk-count]`);r&&(r.textContent=`${t.length} selected`);let i=e.querySelectorAll(`[data-select-row]`),a=e.querySelector(`[data-select-all]`);a&&(a.checked=i.length>0&&t.length===i.length)}async function y(e,t){u(t,``);let r=t.querySelector(`[data-create-json]`);if(r){let n;try{n=JSON.parse(r.value)}catch{u(t,`Invalid JSON body`);return}let i=await fetch(c(e),{method:`POST`,headers:{"Content-Type":`application/json`,"Idempotency-Key":l()},body:JSON.stringify(n)});if(!i.ok){u(t,`Error ${i.status}: ${(await i.text()).slice(0,200)}`);return}}else{let r=n(t);if(r.error){u(t,r.error);return}let i=await fetch(c(e),{method:`POST`,headers:{"Content-Type":`application/json`,"Idempotency-Key":l()},body:JSON.stringify(r.body)});if(!i.ok){u(t,`Error ${i.status}: ${(await i.text()).slice(0,200)}`);return}}let i=t.closest(`dialog`);t.reset(),i&&i.close(),d(e)}async function b(e,t){u(t,``);let r=t.dataset?.id||``;if(!r){u(t,`Missing record id`);return}let i=n(t);if(i.error){u(t,i.error);return}let a=await fetch(`${c(e)}/${encodeURIComponent(r)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i.body)});if(!a.ok){u(t,`Error ${a.status}: ${(await a.text()).slice(0,200)}`);return}let o=t.closest(`dialog`);o&&o.close(),d(e)}async function x(e,t){let n=await fetch(`${c(e)}/data/${encodeURIComponent(t)}`,{method:`QUERY`,headers:{Accept:`application/json`}});if(!n.ok)return;let i=(await n.json()).data??{},a=document.getElementById(`rack-edit`);if(!a)return;let o=a.querySelector(`[data-edit-form]`);if(!o)return;o.dataset.id=t;let s=a.querySelector(`[data-edit-id-label]`);s&&(s.textContent=`#${t}`),r(o,i),u(o,``),a.showModal?.()}async function S(e,t){window.confirm(`Delete record ${t}?`)&&(await fetch(`${c(e)}/${encodeURIComponent(t)}`,{method:`DELETE`})).ok&&d(e)}async function C(e){let t=_(e);if(!t.length||!window.confirm(`Delete ${t.length} records?`))return;let n=c(e);for(let e of t)await fetch(`${n}/${encodeURIComponent(e)}`,{method:`DELETE`});d(e)}async function w(e){let t=e.querySelector(`[data-bulk-field]`),n=e.querySelector(`[data-bulk-value]`),r=_(e);if(!t?.value||!n||!r.length)return;let i=c(e),a=JSON.stringify({[t.value]:n.value});for(let e of r)await fetch(`${i}/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:a});n.value=``,d(e)}document.addEventListener(`click`,e=>{let t=e.target;if(!t?.closest)return;let n=t.closest(`[data-query-url]`);if(!n)return;let r=t.closest(`[data-close]`);if(r){r.closest(`dialog`)?.close();return}if(t.closest(`[data-open-create]`)){let e=document.getElementById(`rack-create`);if(e){let t=e.querySelector(`[data-create-form]`);t&&(t.reset(),u(t,``)),e.showModal?.()}return}let i=t.closest(`[data-edit-id]`);if(i){x(n,i.getAttribute(`data-edit-id`));return}let a=t.closest(`[data-delete-id]`);if(a){S(n,a.getAttribute(`data-delete-id`));return}if(t.closest(`[data-bulk-delete]`)){C(n);return}if(t.closest(`[data-bulk-apply]`)){w(n);return}if(t.closest(`[data-bulk-clear]`)){Array.prototype.forEach.call(n.querySelectorAll(`[data-select-row],[data-select-all]`),e=>{e.checked=!1}),v(n);return}let o=t.closest(`a[data-qlink]`);o&&(e.preventDefault(),g(n,new URLSearchParams(o.getAttribute(`href`).replace(/^\?/,``))))}),document.addEventListener(`submit`,e=>{let t=e.target;if(!t||t.tagName!==`FORM`)return;let n=t.closest?.(`[data-query-url]`);if(!n)return;if(t.hasAttribute(`data-create-form`)){e.preventDefault(),y(n,t);return}if(t.hasAttribute(`data-edit-form`)){e.preventDefault(),b(n,t);return}e.preventDefault();let r=new URLSearchParams,i=t.elements??[];for(let e=0;e<i.length;e++){let t=i[e];t.name&&!t.disabled&&(t.type!==`checkbox`&&t.type!==`radio`||t.checked)&&t.value!==``&&r.append(t.name,t.value)}g(n,r)}),document.addEventListener(`change`,e=>{let t=e.target;if(!t?.closest)return;let n=t.closest(`[data-query-url]`);if(!n)return;let r=t.hasAttribute(`data-select-all`);(r||t.hasAttribute(`data-select-row`))&&(r&&Array.prototype.forEach.call(n.querySelectorAll(`[data-select-row]`),e=>{e.checked=t.checked}),v(n))});
@@ -0,0 +1 @@
1
+ var e=`koran-theme`;function t(){try{let t=localStorage.getItem(e);return t===`dark`||t===`light`?t:null}catch{return null}}function n(){try{return typeof window.matchMedia==`function`&&window.matchMedia(`(prefers-color-scheme: dark)`).matches}catch{return!1}}function r(){let t=document.documentElement,n=t.classList.toggle(`dark`);t.classList.toggle(`light`,!n);try{localStorage.setItem(e,n?`dark`:`light`)}catch{}}function i(){let e=t();e?document.documentElement.classList.add(e):n()&&document.documentElement.classList.add(`dark`),document.getElementById(`koran-theme-toggle`)?.addEventListener(`click`,r),window.__koranToggle=r}i();
package/dist/panel.css ADDED
@@ -0,0 +1 @@
1
+ @import "https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,500;0,700;0,900;1,500&family=Source+Serif+4:ital,opsz,wght@0,8..60,400;0,8..60,600;1,8..60,400&display=swap";@layer components;@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-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--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}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--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);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-normal:400;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-black:900;--tracking-tight:-.025em;--tracking-wider:.05em;--tracking-widest:.1em;--radius-xs:var(--radius-xs);--radius-sm:var(--radius-sm);--radius-md:var(--radius-md);--radius-lg:var(--radius-lg);--radius-xl:var(--radius-xl);--radius-2xl:var(--radius-2xl);--radius-3xl:var(--radius-3xl);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--radius-full:var(--radius-full);--font-koran:"Playfair Display", Georgia, "Times New Roman", serif;--font-koran-body:"Source Serif 4", Georgia, "Times New Roman", serif}}@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%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, 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;-webkit-text-decoration:inherit;-webkit-text-decoration: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:where(:not(iframe)){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]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}body{background-color:var(--background);color:var(--foreground)}::selection{background-color:var(--selection);color:var(--selection-foreground)}:focus-visible{outline:2px solid var(--focus);outline-offset:2px}}@layer utilities{.visible{visibility:visible}.mx-auto{margin-inline:auto}.mt-1{margin-top:var(--spacing)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.contents{display:contents}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-4{height:calc(var(--spacing) * 4)}.h-full{height:100%}.min-h-0{min-height:0}.min-h-screen{min-height:100vh}.w-4{width:calc(var(--spacing) * 4)}.w-64{width:calc(var(--spacing) * 64)}.w-full{width:100%}.max-w-5xl{max-width:var(--container-5xl)}.min-w-0{min-width:0}.min-w-80{min-width:calc(var(--spacing) * 80)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.cursor-pointer{cursor:pointer}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.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-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:var(--radius-full)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.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{border-left-style:var(--tw-border-style);border-left-width:1px}.border-border{border-color:var(--border)}.border-input{border-color:var(--input)}.border-sidebar-border{border-color:var(--sidebar-border)}.border-table-border{border-color:var(--table-border)}.bg-background{background-color:var(--background)}.bg-badge-background{background-color:var(--badge-background)}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-header{background-color:var(--header)}.bg-input-background{background-color:var(--input-background)}.bg-primary{background-color:var(--primary)}.bg-secondary{background-color:var(--secondary)}.bg-sidebar{background-color:var(--sidebar)}.bg-sidebar-primary{background-color:var(--sidebar-primary)}.bg-success-muted{background-color:var(--success-muted)}.bg-table{background-color:var(--table-background)}.bg-table-header{background-color:var(--table-header)}.bg-table-row-hover{background-color:var(--table-row-hover)}.bg-warning-muted{background-color:var(--warning-muted)}.p-0{padding:0}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.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-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pb-1{padding-bottom:var(--spacing)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-10{padding-bottom:calc(var(--spacing) * 10)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.font-koran{font-family:var(--font-koran)}.font-koran-body{font-family:var(--font-koran-body)}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--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))}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.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-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.whitespace-nowrap{white-space:nowrap}.text-badge-foreground{color:var(--badge-foreground)}.text-card-foreground{color:var(--card-foreground)}.text-destructive{color:var(--destructive)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-foreground{color:var(--foreground)}.text-form-error{color:var(--form-error)}.text-form-label{color:var(--form-label)}.text-header-foreground{color:var(--header-foreground)}.text-link{color:var(--link)}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-sidebar-foreground{color:var(--sidebar-foreground)}.text-sidebar-primary-foreground{color:var(--sidebar-primary-foreground)}.text-success-muted-foreground{color:var(--success-muted-foreground)}.text-text-disabled{color:var(--text-disabled)}.text-text-muted{color:var(--text-muted)}.text-warning-muted-foreground{color:var(--warning-muted-foreground)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.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,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.group-open\:rotate-180:is(:where(.group):is([open],:popover-open,:open) *){rotate:180deg}.placeholder\:text-form-placeholder::placeholder{color:var(--form-placeholder)}@media (hover:hover){.hover\:bg-navigation-hover:hover{background-color:var(--navigation-hover)}.hover\:bg-sidebar-accent:hover{background-color:var(--sidebar-accent)}.hover\:bg-table-row-hover:hover{background-color:var(--table-row-hover)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-link-hover:hover{color:var(--link-hover)}.hover\:text-sidebar-accent-foreground:hover{color:var(--sidebar-accent-foreground)}}@media (width>=40rem){.sm\:inline{display:inline}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}}:root{--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--surface:oklch(100% 0 0);--surface-foreground:oklch(14.5% 0 0);--surface-muted:oklch(98.5% 0 0);--surface-muted-foreground:oklch(55.6% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--card-muted:oklch(98.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--overlay:oklch(14.5% 0 0/.5);--overlay-foreground:oklch(100% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(97% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(97% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(97% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--destructive-foreground:oklch(98.5% 0 0);--success:oklch(59.6% .145 163.225);--success-foreground:oklch(98.5% 0 0);--success-muted:oklch(96.2% .044 156.743);--success-muted-foreground:oklch(44.8% .119 151.328);--warning:oklch(68.1% .162 75.834);--warning-foreground:oklch(20.5% 0 0);--warning-muted:oklch(98.7% .026 102.212);--warning-muted-foreground:oklch(47.6% .114 61.907);--info:oklch(62.3% .214 259.815);--info-foreground:oklch(98.5% 0 0);--info-muted:oklch(97% .014 254.604);--info-muted-foreground:oklch(48.8% .217 264.376);--border:oklch(92.2% 0 0);--border-muted:oklch(96% 0 0);--input:oklch(92.2% 0 0);--input-background:oklch(100% 0 0);--ring:oklch(70.8% 0 0);--focus:oklch(62.3% .214 259.815);--text:oklch(14.5% 0 0);--text-muted:oklch(55.6% 0 0);--text-subtle:oklch(70.8% 0 0);--text-disabled:oklch(70.8% 0 0);--text-inverse:oklch(98.5% 0 0);--selection:oklch(20.5% 0 0);--selection-foreground:oklch(98.5% 0 0);--link:oklch(48.8% .243 264.376);--link-hover:oklch(42.4% .199 265.638);--link-visited:oklch(48.8% .243 264.376);--table-background:oklch(100% 0 0);--table-header:oklch(98.5% 0 0);--table-row:oklch(100% 0 0);--table-row-hover:oklch(98.5% 0 0);--table-row-selected:oklch(97% 0 0);--table-border:oklch(92.2% 0 0);--form-label:oklch(20.5% 0 0);--form-description:oklch(55.6% 0 0);--form-placeholder:oklch(70.8% 0 0);--form-error:oklch(57.7% .245 27.325);--form-success:oklch(59.6% .145 163.225);--navigation-background:oklch(100% 0 0);--navigation-foreground:oklch(14.5% 0 0);--navigation-hover:oklch(97% 0 0);--navigation-active:oklch(97% 0 0);--navigation-active-foreground:oklch(20.5% 0 0);--navigation-border:oklch(92.2% 0 0);--sidebar:oklch(98.5% 0 0);--sidebar-foreground:oklch(14.5% 0 0);--sidebar-primary:oklch(20.5% 0 0);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(97% 0 0);--sidebar-accent-foreground:oklch(20.5% 0 0);--sidebar-muted:oklch(55.6% 0 0);--sidebar-border:oklch(92.2% 0 0);--sidebar-ring:oklch(70.8% 0 0);--header:oklch(100% 0 0);--header-foreground:oklch(14.5% 0 0);--header-border:oklch(92.2% 0 0);--breadcrumb-foreground:oklch(55.6% 0 0);--breadcrumb-current:oklch(14.5% 0 0);--breadcrumb-separator:oklch(70.8% 0 0);--badge-background:oklch(97% 0 0);--badge-foreground:oklch(20.5% 0 0);--code-background:oklch(97% 0 0);--code-foreground:oklch(20.5% 0 0);--chart-1:oklch(64.6% .222 41.116);--chart-2:oklch(60% .118 184.704);--chart-3:oklch(39.8% .07 227.392);--chart-4:oklch(82.8% .189 84.429);--chart-5:oklch(76.9% .188 70.08);--radius:.625rem;--radius-xs:calc(var(--radius) - 6px);--radius-sm:calc(var(--radius) - 4px);--radius-md:calc(var(--radius) - 2px);--radius-lg:var(--radius);--radius-xl:calc(var(--radius) + 4px);--radius-2xl:calc(var(--radius) + 8px);--radius-3xl:calc(var(--radius) + 12px);--radius-full:9999px}.dark{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--surface:oklch(20.5% 0 0);--surface-foreground:oklch(98.5% 0 0);--surface-muted:oklch(18% 0 0);--surface-muted-foreground:oklch(70.8% 0 0);--card:oklch(20.5% 0 0);--card-foreground:oklch(98.5% 0 0);--card-muted:oklch(26.9% 0 0);--popover:oklch(20.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--overlay:oklch(0% 0 0/.65);--overlay-foreground:oklch(98.5% 0 0);--primary:oklch(92.2% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--destructive-foreground:oklch(98.5% 0 0);--success:oklch(69.6% .17 162.48);--success-foreground:oklch(14.5% 0 0);--success-muted:oklch(26.9% .07 156.743);--success-muted-foreground:oklch(76.5% .13 152.461);--warning:oklch(76.9% .188 70.08);--warning-foreground:oklch(20.5% 0 0);--warning-muted:oklch(26.9% .06 85);--warning-muted-foreground:oklch(82.8% .15 84);--info:oklch(70.7% .165 254.624);--info-foreground:oklch(14.5% 0 0);--info-muted:oklch(26.9% .06 255);--info-muted-foreground:oklch(70.7% .165 254.624);--border:oklch(100% 0 0/.1);--border-muted:oklch(100% 0 0/.06);--input:oklch(100% 0 0/.15);--input-background:oklch(20.5% 0 0);--ring:oklch(55.6% 0 0);--focus:oklch(70.7% .165 254.624);--text:oklch(98.5% 0 0);--text-muted:oklch(70.8% 0 0);--text-subtle:oklch(55.6% 0 0);--text-disabled:oklch(55.6% 0 0);--text-inverse:oklch(14.5% 0 0);--selection:oklch(92.2% 0 0);--selection-foreground:oklch(20.5% 0 0);--link:oklch(70.7% .165 254.624);--link-hover:oklch(80.9% .105 251.813);--link-visited:oklch(70.7% .165 254.624);--table-background:oklch(20.5% 0 0);--table-header:oklch(18% 0 0);--table-row:oklch(20.5% 0 0);--table-row-hover:oklch(26.9% 0 0);--table-row-selected:oklch(26.9% 0 0);--table-border:oklch(100% 0 0/.1);--form-label:oklch(98.5% 0 0);--form-description:oklch(70.8% 0 0);--form-placeholder:oklch(55.6% 0 0);--form-error:oklch(70.4% .191 22.216);--form-success:oklch(69.6% .17 162.48);--navigation-background:oklch(20.5% 0 0);--navigation-foreground:oklch(98.5% 0 0);--navigation-hover:oklch(26.9% 0 0);--navigation-active:oklch(26.9% 0 0);--navigation-active-foreground:oklch(98.5% 0 0);--navigation-border:oklch(100% 0 0/.1);--sidebar:oklch(20.5% 0 0);--sidebar-foreground:oklch(98.5% 0 0);--sidebar-primary:oklch(48.8% .243 264.376);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(26.9% 0 0);--sidebar-accent-foreground:oklch(98.5% 0 0);--sidebar-muted:oklch(70.8% 0 0);--sidebar-border:oklch(100% 0 0/.1);--sidebar-ring:oklch(55.6% 0 0);--header:oklch(20.5% 0 0);--header-foreground:oklch(98.5% 0 0);--header-border:oklch(100% 0 0/.1);--breadcrumb-foreground:oklch(70.8% 0 0);--breadcrumb-current:oklch(98.5% 0 0);--breadcrumb-separator:oklch(55.6% 0 0);--badge-background:oklch(26.9% 0 0);--badge-foreground:oklch(98.5% 0 0);--code-background:oklch(26.9% 0 0);--code-foreground:oklch(98.5% 0 0);--chart-1:oklch(48.8% .243 264.376);--chart-2:oklch(69.6% .17 162.48);--chart-3:oklch(76.9% .188 70.08);--chart-4:oklch(62.7% .265 303.9);--chart-5:oklch(64.5% .246 16.439)}:root{--background:#f5f0e2;--foreground:#1c1610;--surface:#f5f0e2;--surface-foreground:#1c1610;--surface-muted:#ece4d0;--surface-muted-foreground:#6f6250;--card:#faf6ea;--card-foreground:#1c1610;--card-muted:#ece4d0;--popover:#faf6ea;--popover-foreground:#1c1610;--primary:#1c1610;--primary-foreground:#f5f0e2;--secondary:#e9e0c8;--secondary-foreground:#1c1610;--muted:#e9e0c8;--muted-foreground:#6f6250;--accent:#e9e0c8;--accent-foreground:#1c1610;--border:#d8cdae;--border-muted:#e4dabd;--input:#c9bc9c;--input-background:#faf6ea;--ring:#6f6250;--text:#1c1610;--text-muted:#6f6250;--text-subtle:#a2937a;--text-disabled:#a2937a;--text-inverse:#f5f0e2;--selection:#1c1610;--selection-foreground:#f5f0e2;--link:#9b1c1c;--link-hover:#7c1616;--link-visited:#9b1c1c;--table-background:#faf6ea;--table-header:#ece4d0;--table-row:#faf6ea;--table-row-hover:#f1e9d2;--table-row-selected:#e9e0c8;--table-border:#d8cdae;--form-label:#1c1610;--form-description:#6f6250;--form-placeholder:#a2937a;--navigation-background:#f5f0e2;--navigation-foreground:#1c1610;--navigation-hover:#e9e0c8;--navigation-active:#e9e0c8;--navigation-active-foreground:#1c1610;--navigation-border:#d8cdae;--sidebar:#ece4d0;--sidebar-foreground:#1c1610;--sidebar-primary:#1c1610;--sidebar-primary-foreground:#f5f0e2;--sidebar-accent:#e9e0c8;--sidebar-accent-foreground:#1c1610;--sidebar-muted:#6f6250;--sidebar-border:#d8cdae;--sidebar-ring:#6f6250;--header:#f5f0e2;--header-foreground:#1c1610;--header-border:#1c1610;--breadcrumb-foreground:#6f6250;--breadcrumb-current:#1c1610;--breadcrumb-separator:#a2937a;--badge-background:#e9e0c8;--badge-foreground:#1c1610;--code-background:#ece4d0;--code-foreground:#1c1610}.dark{--background:#181310;--foreground:#ece1c8;--surface:#211a13;--surface-foreground:#ece1c8;--surface-muted:#241d15;--surface-muted-foreground:#a49378;--card:#211a13;--card-foreground:#ece1c8;--card-muted:#2a2118;--popover:#211a13;--popover-foreground:#ece1c8;--primary:#ece1c8;--primary-foreground:#181310;--secondary:#2a2118;--secondary-foreground:#ece1c8;--muted:#2a2118;--muted-foreground:#a49378;--accent:#2a2118;--accent-foreground:#ece1c8;--border:#3a2f22;--border-muted:#2a2118;--input:#4a3d2c;--input-background:#211a13;--ring:#a49378;--text:#ece1c8;--text-muted:#a49378;--text-subtle:#6f6250;--text-disabled:#6f6250;--text-inverse:#181310;--selection:#ece1c8;--selection-foreground:#181310;--link:#e06552;--link-hover:#ef8267;--link-visited:#e06552;--table-background:#211a13;--table-header:#181310;--table-row:#211a13;--table-row-hover:#2a2118;--table-row-selected:#2a2118;--table-border:#3a2f22;--form-label:#ece1c8;--form-description:#a49378;--form-placeholder:#6f6250;--navigation-background:#181310;--navigation-foreground:#ece1c8;--navigation-hover:#2a2118;--navigation-active:#2a2118;--navigation-active-foreground:#ece1c8;--navigation-border:#3a2f22;--sidebar:#211a13;--sidebar-foreground:#ece1c8;--sidebar-primary:#ece1c8;--sidebar-primary-foreground:#181310;--sidebar-accent:#2a2118;--sidebar-accent-foreground:#ece1c8;--sidebar-muted:#a49378;--sidebar-border:#3a2f22;--sidebar-ring:#a49378;--header:#181310;--header-foreground:#ece1c8;--header-border:#ece1c8;--breadcrumb-foreground:#a49378;--breadcrumb-current:#ece1c8;--breadcrumb-separator:#6f6250;--badge-background:#2a2118;--badge-foreground:#ece1c8;--code-background:#2a2118;--code-foreground:#ece1c8}dialog{max-width:min(32rem,100vw - 2rem);max-height:calc(100vh - 2rem);margin:auto}dialog::backdrop{background-color:var(--overlay)}.koran-rule-double{border-top:1px solid var(--header-border);position:relative}.koran-rule-double:after{content:"";border-top:3px solid var(--header-border);margin-top:2px;display:block}.koran-paper{background-color:var(--background);background-image:radial-gradient(at top,#ffffff59,#0000 60%)}.dark .koran-paper{background-image:radial-gradient(at top,#ffffff0d,#0000 60%)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@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}
@@ -0,0 +1,5 @@
1
+ import type { Rack } from "./types";
2
+ /**
3
+ * Resolve which ORM adapter a `CrudModel` targets.
4
+ */
5
+ export declare function resolveAdapter(model: Rack.CrudModel): "drizzle" | "prisma";
@@ -0,0 +1,2 @@
1
+ import { type CrudAdapter } from "./index";
2
+ export declare const drizzleAdapter: CrudAdapter;
@@ -0,0 +1,59 @@
1
+ import type { ParsedListQuery } from "../query";
2
+ import type { Rack } from "../types";
3
+ export { drizzleAdapter } from "./drizzle";
4
+ export { prismaAdapter } from "./prisma";
5
+ export interface AdapterOptions {
6
+ primaryKey: string;
7
+ deletedAtField?: string;
8
+ returning?: boolean;
9
+ softDelete?: boolean;
10
+ }
11
+ export interface ListResult {
12
+ data: unknown[];
13
+ total: number;
14
+ }
15
+ export type FieldKind = "text" | "integer" | "number" | "boolean" | "date" | "enum" | "json";
16
+ export interface FieldDescriptor {
17
+ name: string;
18
+ kind: FieldKind;
19
+ primary: boolean;
20
+ autoIncrement: boolean;
21
+ nullable: boolean;
22
+ enumValues?: readonly string[];
23
+ }
24
+ /**
25
+ * ORM adapter contract. Each method returns `null` when the target
26
+ * row does not exist (handlers map it to 404), or `undefined` data
27
+ * when `returning` is disabled.
28
+ */
29
+ export interface CrudAdapter {
30
+ readonly name: "drizzle" | "prisma";
31
+ /**
32
+ * Introspect writable fields for smart forms.
33
+ * Returns `[]` when the ORM exposes no schema (e.g. Prisma delegates);
34
+ * callers then fall back to text inputs derived from row data.
35
+ */
36
+ describe(model: Rack.CrudModel): FieldDescriptor[];
37
+ list(model: Rack.CrudModel, query: ParsedListQuery, opts: AdapterOptions): Promise<ListResult>;
38
+ detail(model: Rack.CrudModel, id: string, opts: AdapterOptions): Promise<unknown | null>;
39
+ create(model: Rack.CrudModel, body: unknown, opts: AdapterOptions): Promise<unknown>;
40
+ replace(model: Rack.CrudModel, id: string, body: unknown, opts: AdapterOptions): Promise<unknown | null>;
41
+ update(model: Rack.CrudModel, id: string, body: unknown, opts: AdapterOptions): Promise<unknown | null>;
42
+ remove(model: Rack.CrudModel, id: string, opts: AdapterOptions & {
43
+ softDelete?: boolean;
44
+ }): Promise<unknown | null>;
45
+ }
46
+ export declare function getAdapter(model: Rack.CrudModel): CrudAdapter;
47
+ /**
48
+ * Whether a column type holds integers.
49
+ *
50
+ * Unknown columns (e.g. Prisma delegates) are treated as numeric-friendly.
51
+ */
52
+ export declare function isNumericColumn(columnType?: string): boolean;
53
+ /**
54
+ * Coerce a string route id to the column type.
55
+ *
56
+ * Integer-like columns (or unknown columns, e.g. Prisma delegates)
57
+ * turn numeric strings into numbers; everything else passes through.
58
+ */
59
+ export declare function coerceIdValue(id: string, columnType?: string): unknown;
@@ -0,0 +1,2 @@
1
+ import { type CrudAdapter } from "./index";
2
+ export declare const prismaAdapter: CrudAdapter;
@@ -0,0 +1,23 @@
1
+ import type { Rack } from "./types";
2
+ export interface AuthCheck {
3
+ request: Request;
4
+ id?: string;
5
+ resource: unknown;
6
+ permissions?: unknown;
7
+ store?: Record<string, unknown>;
8
+ }
9
+ /**
10
+ * Resolve `true`/`false`/permission-string/function rules.
11
+ *
12
+ * - `undefined` / `true` → allow
13
+ * - `false` → 403
14
+ * - `string` → treated as required permission. Checked against
15
+ * `permissions` decorated on context (e.g. by an auth plugin) or the
16
+ * `x-permissions` header (comma-separated). Allowed when no auth source
17
+ * is wired yet (TODO: strict mode once auth plugin lands).
18
+ * - `function` → awaited, `false` → 403
19
+ */
20
+ export declare function authorize(operation: Rack.CrudOperation, rule: Rack.CrudAuthorizationRule | undefined, ctx: AuthCheck): Promise<import("elysia").ElysiaCustomStatusResponse<403, {
21
+ readonly error: "Forbidden";
22
+ readonly operation: import("./types/authorization").CrudOperation;
23
+ }, 403> | null>;
@@ -0,0 +1,9 @@
1
+ import type { Rack } from "./types";
2
+ /**
3
+ * In-memory idempotency store with lazy expiry and a bounded size
4
+ * (oldest entries are evicted first).
5
+ *
6
+ * Scoped per rack instance. Use a shared store (e.g. Redis) via
7
+ * `idempotency.store` when running multiple instances.
8
+ */
9
+ export declare function createMemoryIdempotencyStore(maxEntries?: number): Rack.CrudIdempotencyStore;
@@ -0,0 +1,40 @@
1
+ import Elysia from "elysia";
2
+ import type { Rack } from "./types";
3
+ export type { Rack } from "./types";
4
+ export type * from "./models";
5
+ export { clearRacks, listRacks, registerRack, type RackRegistration, } from "./registry";
6
+ export { resolveAdapter } from "./adapter";
7
+ export { getAdapter, drizzleAdapter, prismaAdapter, type AdapterOptions, type CrudAdapter, type FieldDescriptor, type FieldKind, type ListResult, } from "./adapters/index";
8
+ export { authorize, type AuthCheck } from "./authorization";
9
+ export { createMemoryIdempotencyStore } from "./idempotency";
10
+ export { detailFor } from "./openapi";
11
+ export { panelPage, PANEL_PAGE_KEY, type PanelPageProps } from "./page";
12
+ export { parseListQuery } from "./query";
13
+ export declare function rack(path: string, options: Rack.RackOptions): Elysia<string, {
14
+ decorator: {};
15
+ store: {};
16
+ derive: {};
17
+ resolve: {};
18
+ }, {
19
+ typebox: {};
20
+ error: {};
21
+ }, {
22
+ schema: {};
23
+ standaloneSchema: {};
24
+ macro: {};
25
+ macroFn: {};
26
+ parser: {};
27
+ response: {};
28
+ }, {}, {
29
+ derive: {};
30
+ resolve: {};
31
+ schema: {};
32
+ standaloneSchema: {};
33
+ response: {};
34
+ }, {
35
+ derive: {};
36
+ resolve: {};
37
+ schema: {};
38
+ standaloneSchema: {};
39
+ response: {};
40
+ }>;