build: include production build artifacts in repo

This commit is contained in:
S. Esmaeili
2026-10-24 10:11:05 +03:30
parent dfd8a82809
commit 7399812d0e
213 changed files with 65702 additions and 2 deletions
+2 -2
View File
@@ -2,8 +2,8 @@
node_modules/
# build output
dist/
.output/
# dist/
# .output/
.nuxt/
.data/
.turbo/
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{b as e}from"./VuesaxIcon-B4ROVNew.js";import{Et as t,It as n,Nt as r,Ot as i,Tt as a,_t as o,dt as s,i as c,kt as l,lt as u,ot as d,r as f,yt as p}from"./index-BAiPliM2.js";var m=Symbol(`form-errors`),h=e=>Object.fromEntries(e.map(e=>[e.path,e.message]));function g(r,i){let a=n(structuredClone(i)),o=n({});t(m,o);function s(){let t=r.safeParse(a.value);return t.success?(o.value={},t.data):(o.value=h(e(t.error)),d.error(`لطفاً خطاهای فرم را برطرف کنید`),null)}function l(e){let t=f(e).issues;t?.length&&(o.value=h(t)),d.error(c(e))}function u(e){a.value=structuredClone(e),o.value={}}return{model:a,errors:o,validate:s,handleError:l,reset:u}}var _=o({__name:`FormField`,props:{path:{},label:{},hint:{},required:{type:Boolean}},setup(e){let t=e,n=p(m,null),o=u(()=>n?.value[t.path]);return(t,n)=>{let c=l(`a-form-item`);return a(),s(c,{label:e.label,required:e.required,"validate-status":o.value?`error`:void 0,help:o.value||e.hint},{default:r(()=>[i(t.$slots,`default`)]),_:3},8,[`label`,`required`,`validate-status`,`help`])}}});export{g as n,_ as t};
+1
View File
@@ -0,0 +1 @@
import{t as e,y as t}from"./VuesaxIcon-B4ROVNew.js";import{Bt as n,Lt as r,Nt as i,Tt as a,_t as o,bt as s,dt as c,gt as l,jt as u,kt as d,pt as f,ut as p}from"./index-BAiPliM2.js";var m={class:`flex items-center gap-2`},h={class:`flex size-9 shrink-0 items-center justify-center rounded-lg border border-gray-200 bg-gray-50 text-[#ff5a00]`},g={key:1,class:`text-xs text-gray-400`},_={class:`flex items-center gap-2.5 py-0.5`,dir:`ltr`},v={class:`text-xs font-mono`},y=o({__name:`IconSelect`,props:s({allowClear:{type:Boolean}},{modelValue:{required:!0},modelModifiers:{}}),emits:[`update:modelValue`],setup(o){let s=u(o,`modelValue`),y=t.map(e=>({value:e,label:e}));return(t,u)=>{let b=d(`a-select`);return a(),f(`div`,m,[p(`span`,h,[s.value?(a(),c(e,{key:0,name:s.value,size:20},null,8,[`name`])):(a(),f(`span`,g,`---`))]),l(b,{value:s.value,"onUpdate:value":u[0]||=e=>s.value=e,class:`min-w-0 flex-1`,"show-search":``,"allow-clear":o.allowClear,options:r(y),placeholder:`انتخاب آیکون`},{option:i(({value:t})=>[p(`span`,_,[l(e,{name:t,size:18,class:`text-orange-600`},null,8,[`name`]),p(`span`,v,n(t),1)])]),_:1},8,[`value`,`allow-clear`,`options`])])}}});export{y as t};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{c as e,n as t,t as n}from"./VuesaxIcon-B4ROVNew.js";import{It as r,Lt as i,Nt as a,Tt as o,_t as s,a as c,gt as l,ht as u,kt as d,mt as f,o as p,pt as m,st as h,t as g,ut as _}from"./index-BAiPliM2.js";import"./logo-BuUh917n.js";import{n as v,t as y}from"./FormField-CZ_S38rR.js";var b={class:`login-page relative flex min-h-screen overflow-hidden text-[#edede6]`},x={class:`relative z-10 mx-auto grid w-full max-w-[1120px] flex-1 items-center gap-10 px-5 py-12 md:px-8 lg:grid-cols-12 lg:gap-16`},S={class:`login-fade-3 lg:col-span-6`},C={class:`login-panel w-full max-w-md border border-[#2a3d63]/70 bg-[#1a2744]/80 p-7 backdrop-blur-md md:p-8 lg:me-auto`},w=t(s({__name:`LoginPage`,setup(t){let s=g(),w=p(),T=c(),{model:E,validate:D,handleError:O}=v(e,{phone:``,password:``}),k=r(!1);async function A(){let e=D();if(e){k.value=!0;try{await s.login(e);let t=typeof T.query.redirect==`string`?T.query.redirect:`/`;await w.replace(t.startsWith(`/`)?t:`/`)}catch(e){O(e)}finally{k.value=!1}}}return(e,t)=>{let r=d(`a-input`),s=d(`a-input-password`),c=d(`a-button`),p=d(`a-form`);return o(),m(`div`,b,[t[5]||=f(`<div class="pointer-events-none absolute inset-0 bg-[#0b1224]" data-v-2d323d25></div><div class="login-grid pointer-events-none absolute inset-0 opacity-50" data-v-2d323d25></div><div class="pointer-events-none absolute -start-24 top-1/4 size-[420px] rounded-full bg-[#ff5a00]/15 blur-[120px]" data-v-2d323d25></div><div class="pointer-events-none absolute -end-16 bottom-0 size-[360px] rounded-full bg-[#ffb800]/10 blur-[100px]" data-v-2d323d25></div><div class="login-tape pointer-events-none absolute bottom-0 end-0 z-10 h-48 w-1.5 opacity-70" data-v-2d323d25></div><div class="login-noise pointer-events-none absolute inset-0 z-[5]" data-v-2d323d25></div>`,6),_(`div`,x,[_(`div`,S,[_(`div`,C,[t[3]||=_(`div`,{class:`mb-7 text-center`},[_(`div`,{class:`font-mono text-[10px] tracking-[0.28em] text-[#8e9ab0]`},`SIGN IN`),_(`h2`,{class:`mt-2 text-xl font-bold text-[#edede6]`},`ورود به پنل`),_(`p`,{class:`mt-1.5 text-sm text-[#8e9ab0]`},`شماره موبایل و رمز عبور خود را وارد کنید`)],-1),l(p,{class:`login-form`,layout:`vertical`,onSubmit:h(A,[`prevent`])},{default:a(()=>[l(y,{path:`phone`,label:`شماره موبایل`},{default:a(()=>[l(r,{value:i(E).phone,"onUpdate:value":t[0]||=e=>i(E).phone=e,size:`large`,class:`ltr-input`,autocomplete:`tel`,autofocus:``,inputmode:`tel`,placeholder:`09121234567`},{prefix:a(()=>[l(n,{name:`mobile`,size:16,class:`text-[#8e9ab0]`})]),_:1},8,[`value`])]),_:1}),l(y,{path:`password`,label:`رمز عبور`},{default:a(()=>[l(s,{value:i(E).password,"onUpdate:value":t[1]||=e=>i(E).password=e,size:`large`,class:`ltr-input`,autocomplete:`current-password`,placeholder:`••••••••`},{prefix:a(()=>[l(n,{name:`lock`,size:16,class:`text-[#8e9ab0]`})]),_:1},8,[`value`])]),_:1}),l(c,{type:`primary`,"html-type":`submit`,size:`large`,block:``,loading:k.value,class:`!mt-2 !h-12 !rounded-full !font-bold !shadow-[0_8px_32px_rgba(255,90,0,0.35)]`},{default:a(()=>[...t[2]||=[u(` ورود به پنل `,-1)]]),_:1},8,[`loading`])]),_:1})])]),t[4]||=f(`<div class="login-fade-1 lg:col-span-6" data-v-2d323d25><div class="inline-flex items-center gap-2.5 rounded-full border border-[#ff5a00]/30 bg-[#ff5a00]/10 px-4 py-2 backdrop-blur" data-v-2d323d25><span class="size-1.5 animate-pulse rounded-full bg-[#ff5a00]" data-v-2d323d25></span><span class="text-xs font-medium text-[#ff5a00]" data-v-2d323d25>پنل مدیریت ایمن پیشگامان</span></div><div class="mt-8 flex items-center gap-4" data-v-2d323d25><span class="flex size-14 items-center justify-center rounded-xl bg-white shadow-[0_0_28px_rgba(10,30,92,0.45)]" data-v-2d323d25><img src="/logo.png" alt="ایمن پیشگامان" class="size-9 object-contain" data-v-2d323d25></span><div class="leading-tight" data-v-2d323d25><div class="text-2xl font-black tracking-tight md:text-3xl" data-v-2d323d25>ایمن پیشگامان</div><div class="mt-1 font-mono text-[10px] tracking-[0.32em] text-[#8e9ab0]" data-v-2d323d25> IMEN PISHGAMAN CO. </div></div></div><h1 class="mt-8 text-3xl font-black leading-[1.25] md:text-5xl md:leading-[1.2]" data-v-2d323d25> ورود امن <span class="mt-2 inline-block -rotate-1 rounded-lg bg-[#ffb800] px-3 py-1 text-[#0b1224] shadow-[0_10px_40px_rgba(255,184,0,0.22)]" data-v-2d323d25> به سامانه </span></h1><p class="mt-6 max-w-md text-sm leading-8 text-[#edede6]/70 md:text-base md:leading-9" data-v-2d323d25> مدیریت محصولات، محتوا و پیام‌های سایت — فقط برای کاربران مجاز. </p></div>`,1)])])}}}),[[`__scopeId`,`data-v-2d323d25`]]);export{w as default};
+1
View File
@@ -0,0 +1 @@
.login-grid[data-v-2d323d25]{background-image:linear-gradient(270deg,#edede60b 1px,#0000 1px),linear-gradient(#edede60b 1px,#0000 1px);background-size:72px 72px}.login-tape[data-v-2d323d25]{background-image:repeating-linear-gradient(45deg,#ffb800 0 10px,#0b1224 10px 20px)}.login-noise[data-v-2d323d25]{opacity:.045;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}.login-fade-1[data-v-2d323d25],.login-fade-3[data-v-2d323d25]{animation:.9s cubic-bezier(.22,1,.36,1) both login-fade-up-2d323d25}.login-fade-1[data-v-2d323d25]{animation-delay:.12s}.login-fade-3[data-v-2d323d25]{animation-delay:.28s}@keyframes login-fade-up-2d323d25{0%{opacity:0;transform:translateY(36px)}to{opacity:1;transform:translateY(0)}}.login-page[data-v-2d323d25]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}.login-panel[data-v-2d323d25] .ant-form-item-label>label{color:#edede6!important}.login-panel[data-v-2d323d25] .ant-input-affix-wrapper,.login-panel[data-v-2d323d25] .ant-input{color:#edede6!important;background:#152038!important;border-color:#2a3d63!important}.login-panel[data-v-2d323d25] .ant-input-affix-wrapper input.ant-input,.login-panel[data-v-2d323d25] .ant-input-affix-wrapper input{color:#edede6!important;background:0 0!important}.login-panel[data-v-2d323d25] .ant-input-affix-wrapper:hover,.login-panel[data-v-2d323d25] .ant-input-affix-wrapper-focused,.login-panel[data-v-2d323d25] .ant-input-affix-wrapper:focus-within{border-color:#ff5a00!important;box-shadow:0 0 0 2px #ff5a0026!important}.login-panel[data-v-2d323d25] .ant-input::placeholder,.login-panel[data-v-2d323d25] .ant-input-password-icon,.login-panel[data-v-2d323d25] .ant-input-suffix{color:#8e9ab0!important}.login-panel[data-v-2d323d25] input:-webkit-autofill{transition:background-color 99999s ease-in-out;-webkit-text-fill-color:#edede6!important;caret-color:#edede6!important;box-shadow:inset 0 0 0 1000px #152038!important}.login-panel[data-v-2d323d25] input:-webkit-autofill:hover{transition:background-color 99999s ease-in-out;-webkit-text-fill-color:#edede6!important;caret-color:#edede6!important;box-shadow:inset 0 0 0 1000px #152038!important}.login-panel[data-v-2d323d25] input:-webkit-autofill:focus{transition:background-color 99999s ease-in-out;-webkit-text-fill-color:#edede6!important;caret-color:#edede6!important;box-shadow:inset 0 0 0 1000px #152038!important}.login-panel[data-v-2d323d25] input:-webkit-autofill:active{transition:background-color 99999s ease-in-out;-webkit-text-fill-color:#edede6!important;caret-color:#edede6!important;box-shadow:inset 0 0 0 1000px #152038!important}.login-panel[data-v-2d323d25] .ant-form-item-explain-error{color:#ff7a2a}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{n as e,t}from"./VuesaxIcon-B4ROVNew.js";import{Bt as n,Nt as r,Ot as i,Tt as a,_t as o,dt as s,ft as c,gt as l,kt as u,pt as d,ut as f}from"./index-BAiPliM2.js";var p={class:`page-header`},m={class:`page-header__main`},h={class:`min-w-0`},g={class:`page-header__title`},_={key:0,class:`page-header__subtitle`},v={key:0,class:`page-header__actions`},y=e(o({__name:`PageHeader`,props:{title:{},subtitle:{},back:{}},setup(e){return(o,y)=>{let b=u(`RouterLink`);return a(),d(`div`,p,[f(`div`,m,[e.back?(a(),s(b,{key:0,to:e.back,class:`page-header__back`,title:`بازگشت`},{default:r(()=>[l(t,{name:`arrow-right`,size:18})]),_:1},8,[`to`])):c(``,!0),f(`div`,h,[f(`h1`,g,n(e.title),1),e.subtitle?(a(),d(`p`,_,n(e.subtitle),1)):c(``,!0)])]),o.$slots.default?(a(),d(`div`,v,[i(o.$slots,`default`,{},void 0,!0)])):c(``,!0)])}}}),[[`__scopeId`,`data-v-c0b72af8`]]);export{y as t};
+1
View File
@@ -0,0 +1 @@
.page-header[data-v-c0b72af8]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;display:flex;flex:none!important}.page-header__main[data-v-c0b72af8]{align-items:center;gap:8px;min-width:0;display:flex}.page-header__back[data-v-c0b72af8]{color:#475569;background:#f1f5f9;border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;width:34px;height:34px;text-decoration:none;transition:all .15s;display:inline-flex}.page-header__back[data-v-c0b72af8]:hover{color:#0f172a;background:#e2e8f0}.page-header__title[data-v-c0b72af8]{color:#0f172a;margin:0;font-size:16px;font-weight:700;line-height:1.3}@media (width>=640px){.page-header__title[data-v-c0b72af8]{font-size:18px}}.page-header__subtitle[data-v-c0b72af8]{color:#94a3b8;margin:2px 0 0;font-size:12px;line-height:1.4}.page-header__actions[data-v-c0b72af8]{flex-wrap:wrap;align-items:center;gap:8px;display:flex}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
.ap[data-v-7f365815]{flex-direction:column;height:100%;min-height:0;display:flex;overflow:hidden}.ap__head[data-v-7f365815]{background:#fff;border-bottom:1px solid #eef1f6;flex-shrink:0;padding:16px 16px 12px}.ap__body[data-v-7f365815]{flex:1;min-height:0;padding:16px;overflow:auto}.ap__body--locked[data-v-7f365815]{flex-direction:column;display:flex;overflow:hidden}@media (width<=1023px){.ap[data-v-7f365815]{height:auto;min-height:100%;overflow:visible}.ap__head[data-v-7f365815]{z-index:20;background:#fff;padding:10px 12px;position:sticky;top:52px;box-shadow:0 1px 3px #0f172a08}.ap__body[data-v-7f365815]{padding:12px;overflow:visible}.ap__body--locked[data-v-7f365815]{height:auto;overflow:visible}}.table-shell[data-v-a64d8be2],.table-shell[data-v-a64d8be2] .ant-table-wrapper,.table-shell[data-v-a64d8be2] .ant-spin-nested-loading,.table-shell[data-v-a64d8be2] .ant-spin-container{flex-direction:column;flex:1;height:100%;min-height:0;display:flex}.table-shell[data-v-a64d8be2] .ant-table{flex:1;min-height:0}.table-shell[data-v-a64d8be2] .ant-table-pagination{flex-shrink:0;margin:12px 0 0!important}.toolbar[data-v-a64d8be2]{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.toolbar__start[data-v-a64d8be2]{flex:1;align-items:center;gap:16px;min-width:0;display:flex}.toolbar__search[data-v-a64d8be2]{flex:1;min-width:200px;max-width:360px}.toolbar__new[data-v-a64d8be2]{margin-inline-start:auto}.filter-panel[data-v-a64d8be2]{flex-direction:column;gap:10px;display:flex}.filter-panel__hint[data-v-a64d8be2]{color:#94a3b8;margin:0;font-size:12px;line-height:1.6}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{o as e,s as t}from"./VuesaxIcon-B4ROVNew.js";import{Bt as n,It as r,Lt as i,Nt as a,Tt as o,_t as s,ct as c,gt as l,ht as u,kt as d,n as f,ot as p,pt as m,st as h,t as g,ut as _}from"./index-BAiPliM2.js";import{t as v}from"./PageHeader-BzyYFxoY.js";import{n as y,t as b}from"./FormField-CZ_S38rR.js";var x={class:`grid max-w-4xl gap-4 md:gap-6 md:grid-cols-2`},S={class:`flex items-center gap-3.5 mb-4 pb-4 border-b border-gray-100`},C={class:`flex size-14 items-center justify-center rounded-2xl bg-gradient-to-tr from-[#ff5a00] to-amber-500 text-xl font-black text-white shadow-md shadow-orange-500/20`},w={class:`text-base font-bold text-gray-900`},T={class:`mt-0.5 text-xs font-mono text-gray-500`,dir:`ltr`},E={dir:`ltr`,class:`font-mono`},D=s({__name:`ProfilePage`,setup(s){let D=g(),{model:O,validate:k,handleError:A,reset:j}=y(t,{currentPassword:``,newPassword:``}),M=r(!1);async function N(){let e=k();if(e){M.value=!0;try{await f(`/admin/auth/change-password`,{method:`POST`,body:e}),p.success(`رمز عبور تغییر کرد`),j({currentPassword:``,newPassword:``})}catch(e){A(e)}finally{M.value=!1}}}return(t,r)=>{let s=d(`a-descriptions-item`),f=d(`a-tag`),p=d(`a-descriptions`),g=d(`a-card`),y=d(`a-input-password`),k=d(`a-button`),A=d(`a-form`);return o(),m(c,null,[l(v,{title:`حساب کاربری`,subtitle:`مشخصات فردی، نقش دسترسی و تغییر رمز عبور ورود به سامانه`}),_(`div`,x,[l(g,{title:`مشخصات کاربری`},{default:a(()=>[_(`div`,S,[_(`div`,C,n(i(D).user?.name?.slice(0,1)||`U`),1),_(`div`,null,[_(`div`,w,n(i(D).user?.name),1),_(`div`,T,n(i(D).user?.phone),1)])]),l(p,{column:1,size:`small`},{default:a(()=>[l(s,{label:`نام`},{default:a(()=>[u(n(i(D).user?.name),1)]),_:1}),l(s,{label:`موبایل`},{default:a(()=>[_(`span`,E,n(i(D).user?.phone),1)]),_:1}),l(s,{label:`نقش دسترسی`},{default:a(()=>[l(f,{color:i(D).user?.role===`ADMIN`?`orange`:`blue`},{default:a(()=>[u(n(i(D).user&&i(e)[i(D).user.role]),1)]),_:1},8,[`color`])]),_:1})]),_:1})]),_:1}),l(g,{title:`تغییر رمز عبور`},{default:a(()=>[l(A,{layout:`vertical`,onSubmit:h(N,[`prevent`])},{default:a(()=>[l(b,{path:`currentPassword`,label:`رمز فعلی`,required:``},{default:a(()=>[l(y,{value:i(O).currentPassword,"onUpdate:value":r[0]||=e=>i(O).currentPassword=e,class:`ltr-input h-10`,autocomplete:`current-password`},null,8,[`value`])]),_:1}),l(b,{path:`newPassword`,label:`رمز جدید`,hint:`حداقل ۸ کاراکتر`,required:``},{default:a(()=>[l(y,{value:i(O).newPassword,"onUpdate:value":r[1]||=e=>i(O).newPassword=e,class:`ltr-input h-10`,autocomplete:`new-password`},null,8,[`value`])]),_:1}),l(k,{type:`primary`,"html-type":`submit`,loading:M.value,class:`w-full md:w-auto h-10 !font-bold`},{default:a(()=>[...r[2]||=[u(` تغییر رمز ورود `,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1})])],64)}}});export{D as default};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{d as e,f as t}from"./VuesaxIcon-B4ROVNew.js";import{Bt as n,Ct as r,Dt as i,Ft as a,It as o,Lt as s,Nt as c,Rt as l,Tt as u,_t as d,ct as f,dt as p,ft as m,gt as h,ht as g,i as _,kt as v,n as y,o as b,ot as x,pt as S,t as C,ut as w}from"./index-BAiPliM2.js";import{a as T}from"./format-NkL3G1Uq.js";import{t as E}from"./PageHeader-BzyYFxoY.js";var D={class:`grid gap-4 sm:grid-cols-2 xl:grid-cols-3`},O={class:`flex items-center justify-between gap-2`},k=[`onClick`],A={class:`font-bold text-gray-800 group-hover:text-orange-600 transition-colors`},j={key:0,class:`flex items-center flex-shrink-0`},M=[`onClick`],N=[`onClick`],P={key:0},F=d({__name:`SectionsPage`,setup(d){let F=b(),I=C(),L=e.filter(e=>e!==`settings`||I.isAdmin),R=o(!0),z=a({hero:!0,tape:!0,stats:!0,productsIntro:!0,about:!0,services:!0,standards:!0,industries:!0,testimonials:!0,contact:!0,footer:!0}),B=a({}),V=a({});function H(e){return z[e]!==!1}function U(e){return B[e]??null}async function W(){R.value=!0;try{let e=await y(`/admin/sections`);for(let t of e)z[t.key]=t.enabled!==!1,B[t.key]=t.updatedAt}catch(e){x.error(_(e))}finally{R.value=!1}}async function G(e,n){if(e===`settings`)return;let r=z[e]!==!1;z[e]=n,V[e]=!0;try{let r=await y(`/admin/sections/${e}/visibility`,{method:`PATCH`,body:{enabled:n}});z[e]=r.enabled!==!1,B[e]=r.updatedAt,x.success(`وضعیت «${t[e].title}» به ${n?`نمایش`:`عدم نمایش`} تغییر یافت`)}catch(t){z[e]=r,x.error(_(t))}finally{V[e]=!1}}function K(e){F.push({name:`section-edit`,params:{key:e}})}return r(()=>{W()}),(e,r)=>{let a=v(`a-tag`),o=v(`a-switch`),d=v(`a-card`),_=v(`a-spin`);return u(),S(f,null,[h(E,{title:`بخش‌های سایت`,subtitle:`متن‌ها، تصاویر و فهرست‌های صفحه اصلی؛ تنظیم وضعیت نمایش و ویرایش محتوا`}),h(_,{spinning:R.value},{default:c(()=>[w(`div`,D,[(u(!0),S(f,null,i(s(L),e=>(u(),S(`div`,{key:e,class:`block group`},[h(d,{hoverable:``,class:l([`h-full flex flex-col justify-between transition-all`,{"opacity-75 bg-gray-50/60":e!==`settings`&&!H(e)}])},{default:c(()=>[w(`div`,null,[w(`div`,O,[w(`div`,{class:`flex items-center gap-2 cursor-pointer flex-1`,onClick:t=>K(e)},[w(`span`,A,n(s(t)[e].title),1),e===`settings`?(u(),p(a,{key:0,color:`blue`},{default:c(()=>[...r[0]||=[g(`تنظیمات پایه`,-1)]]),_:1})):H(e)?m(``,!0):(u(),p(a,{key:1,color:`error`},{default:c(()=>[...r[1]||=[g(`مخفی`,-1)]]),_:1}))],8,k),e===`settings`?m(``,!0):(u(),S(`div`,j,[h(o,{checked:H(e),loading:V[e],"checked-children":`نمایش`,"un-checked-children":`مخفی`,onChange:t=>G(e,!!t)},null,8,[`checked`,`loading`,`onChange`])]))]),w(`p`,{class:`mt-2 text-sm leading-6 text-gray-500 cursor-pointer`,onClick:t=>K(e)},n(s(t)[e].desc),9,M)]),w(`div`,{class:`mt-4 flex items-center justify-between border-t border-gray-100 pt-3 text-xs text-gray-400 cursor-pointer`,onClick:t=>K(e)},[r[2]||=w(`span`,{class:`text-primary font-medium group-hover:underline`},`ویرایش بخش ←`,-1),U(e)?(u(),S(`span`,P,`آخرین تغییر: `+n(s(T)(U(e))),1)):m(``,!0)],8,N)]),_:2},1032,[`class`])]))),128))])]),_:1},8,[`spinning`])],64)}}});export{F as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
.vx-icon[data-v-9a78c900]{color:inherit;vertical-align:-.15em;flex-shrink:0;justify-content:center;align-items:center;line-height:0;display:inline-flex}.vx-icon[data-v-9a78c900] svg{width:100%;height:100%;display:block}
+1
View File
@@ -0,0 +1 @@
var e=new Intl.DateTimeFormat(`fa-IR-u-ca-persian`,{year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`}),t=t=>t?e.format(new Date(t)):`—`,n=e=>e<1048576?`${(e/1024).toLocaleString(`fa-IR`,{maximumFractionDigits:0})} کیلوبایت`:`${(e/1024/1024).toLocaleString(`fa-IR`,{maximumFractionDigits:1})} مگابایت`,r=e=>e.toLocaleString(`fa-IR`),i=`http://localhost:3000`,a={create:`ایجاد`,update:`ویرایش`,delete:`حذف`,upload:`آپلود`,login:`ورود`,publish:`انتشار`,unpublish:`عدم انتشار`,duplicate:`کپی`,reorder:`مرتب‌سازی`,"change-password":`تغییر رمز`},o={product:`محصول`,category:`دسته`,section:`بخش سایت`,media:`رسانه`,user:`کاربر`,message:`پیام`},s=(e,t)=>`${a[e]??e} ${o[t]??t}`;export{t as a,n as i,s as n,r,i as t};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
var e=`/logo.png`;export{e as t};
+1
View File
@@ -0,0 +1 @@
var e=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,80);export{e as t};
+1
View File
@@ -0,0 +1 @@
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='22' fill='#FF5A00'/><path d='M50 20 L72 28 V48 C72 66 62 76 50 82 C38 76 28 66 28 48 V28 Z' fill='#0A0A0C'/><path d='M40 50 L47 57 L62 42' stroke='#FF5A00' stroke-width='7' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.
Binary file not shown.
Binary file not shown.
+15
View File
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex, nofollow" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>پنل مدیریت ایمن پیشگامان</title>
<script type="module" crossorigin src="/assets/index-BAiPliM2.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-wbnKnB5E.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

+69
View File
@@ -0,0 +1,69 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Controller, Get, Module } from "@nestjs/common";
import { APP_FILTER, APP_GUARD } from "@nestjs/core";
import { ThrottlerGuard, ThrottlerModule } from "@nestjs/throttler";
import { AuthModule } from "./auth/auth.controller.js";
import { CatalogModule } from "./catalog/catalog.module.js";
import { CommonModule } from "./common/common.module.js";
import { PrismaExceptionFilter } from "./common/prisma-exception.filter.js";
import { ContactModule } from "./contact/contact.module.js";
import { DashboardModule } from "./dashboard/dashboard.module.js";
import { MediaModule } from "./media/media.controller.js";
import { PrismaModule, PrismaService } from "./prisma/prisma.service.js";
import { PublicModule } from "./public/public.module.js";
import { SectionsModule } from "./sections/sections.module.js";
import { UsersModule } from "./users/users.controller.js";
let HealthController = class HealthController {
prisma;
constructor(prisma) {
this.prisma = prisma;
}
async health() {
await this.prisma.$queryRaw `SELECT 1`;
return { ok: true };
}
};
__decorate([
Get(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], HealthController.prototype, "health", null);
HealthController = __decorate([
Controller("health"),
__metadata("design:paramtypes", [PrismaService])
], HealthController);
let AppModule = class AppModule {
};
AppModule = __decorate([
Module({
imports: [
ThrottlerModule.forRoot([{ ttl: 60_000, limit: 300 }]),
PrismaModule,
CommonModule,
AuthModule,
UsersModule,
MediaModule,
CatalogModule,
SectionsModule,
ContactModule,
PublicModule,
DashboardModule,
],
controllers: [HealthController],
providers: [
{ provide: APP_GUARD, useClass: ThrottlerGuard },
{ provide: APP_FILTER, useClass: PrismaExceptionFilter },
],
})
], AppModule);
export { AppModule };
//# sourceMappingURL=app.module.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,IACM,gBAAgB,GADtB,MACM,gBAAgB;IACS;IAA7B,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAGhD,AAAN,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAA,UAAU,CAAC;QACtC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;CACF,CAAA;AAJO;IADL,GAAG,EAAE;;;;8CAIL;AAPG,gBAAgB;IADrB,UAAU,CAAC,QAAQ,CAAC;qCAEkB,aAAa;GAD9C,gBAAgB,CAQrB;AAuBM,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,SAAS;IArBrB,MAAM,CAAC;QACN,OAAO,EAAE;YAEP,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACtD,YAAY;YACZ,YAAY;YACZ,UAAU;YACV,WAAW;YACX,WAAW;YACX,aAAa;YACb,cAAc;YACd,aAAa;YACb,YAAY;YACZ,eAAe;SAChB;QACD,WAAW,EAAE,CAAC,gBAAgB,CAAC;QAC/B,SAAS,EAAE;YACT,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE;YAChD,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,qBAAqB,EAAE;SACzD;KACF,CAAC;GACW,SAAS,CAAG"}
+133
View File
@@ -0,0 +1,133 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { Body, Controller, Get, HttpCode, Module, Post, Req, Res } from "@nestjs/common";
import { JwtModule } from "@nestjs/jwt";
import { Throttle } from "@nestjs/throttler";
import { changePasswordSchema, loginSchema, } from "@imen/shared";
import { env, isProd } from "../config/env.js";
import { AdminAuth, CurrentUser } from "../common/auth.js";
import { ZodPipe } from "../common/zod.pipe.js";
import { AuthService } from "./auth.service.js";
const COOKIE = "imen_rt";
const COOKIE_PATH = "/api/admin/auth";
const ua = (req) => req.headers["user-agent"] ?? "";
const readCookie = (req) => req.cookies?.[COOKIE];
let AuthController = class AuthController {
auth;
constructor(auth) {
this.auth = auth;
}
async login(body, req, res) {
return this.respond(res, await this.auth.login(body, ua(req)));
}
async refresh(req, res) {
try {
return this.respond(res, await this.auth.refresh(readCookie(req), ua(req)));
}
catch (e) {
res.clearCookie(COOKIE, { path: COOKIE_PATH });
throw e;
}
}
async logout(req, res) {
await this.auth.logout(readCookie(req));
res.clearCookie(COOKIE, { path: COOKIE_PATH });
}
me(user) {
return this.auth.me(user.id);
}
async changePassword(body, user) {
await this.auth.changePassword(user.id, body);
}
respond(res, t) {
res.cookie(COOKIE, t.refreshToken, {
httpOnly: true,
secure: isProd && env.COOKIE_SECURE,
sameSite: "strict",
path: COOKIE_PATH,
expires: t.refreshExpiresAt,
});
return { accessToken: t.accessToken, user: t.user };
}
};
__decorate([
Post("login"),
HttpCode(200),
Throttle({ default: { limit: 8, ttl: 60_000 } }),
__param(0, Body(new ZodPipe(loginSchema))),
__param(1, Req()),
__param(2, Res({ passthrough: true })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Object]),
__metadata("design:returntype", Promise)
], AuthController.prototype, "login", null);
__decorate([
Post("refresh"),
HttpCode(200),
Throttle({ default: { limit: 30, ttl: 60_000 } }),
__param(0, Req()),
__param(1, Res({ passthrough: true })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], AuthController.prototype, "refresh", null);
__decorate([
Post("logout"),
HttpCode(204),
__param(0, Req()),
__param(1, Res({ passthrough: true })),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], AuthController.prototype, "logout", null);
__decorate([
Get("me"),
AdminAuth(),
__param(0, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], AuthController.prototype, "me", null);
__decorate([
Post("change-password"),
HttpCode(204),
AdminAuth(),
__param(0, Body(new ZodPipe(changePasswordSchema))),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], AuthController.prototype, "changePassword", null);
AuthController = __decorate([
Controller("admin/auth"),
__metadata("design:paramtypes", [AuthService])
], AuthController);
export { AuthController };
let AuthModule = class AuthModule {
};
AuthModule = __decorate([
Module({
imports: [
JwtModule.register({
global: true,
secret: env.JWT_SECRET,
signOptions: { expiresIn: env.JWT_ACCESS_TTL },
}),
],
controllers: [AuthController],
providers: [AuthService],
exports: [AuthService],
})
], AuthModule);
export { AuthModule };
//# sourceMappingURL=auth.controller.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth.controller.js","sourceRoot":"","sources":["../../src/auth/auth.controller.ts"],"names":[],"mappings":"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"}
+127
View File
@@ -0,0 +1,127 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { createHash, randomBytes } from "node:crypto";
import { BadRequestException, Injectable, UnauthorizedException } from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { hash, verify } from "@node-rs/argon2";
import { env } from "../config/env.js";
import { AuditService } from "../common/common.module.js";
import { PrismaService } from "../prisma/prisma.service.js";
export const hashPassword = (password) => hash(password);
const sha256 = (v) => createHash("sha256").update(v).digest("hex");
export const toUserDto = (u) => ({
id: u.id,
phone: u.phone,
name: u.name,
role: u.role,
isActive: u.isActive,
lastLoginAt: u.lastLoginAt?.toISOString() ?? null,
createdAt: u.createdAt.toISOString(),
});
const INVALID_LOGIN = "شماره موبایل یا رمز عبور اشتباه است";
const DUMMY_HASH = hashPassword(randomBytes(16).toString("hex"));
let AuthService = class AuthService {
prisma;
jwt;
audit;
constructor(prisma, jwt, audit) {
this.prisma = prisma;
this.jwt = jwt;
this.audit = audit;
}
async login(input, userAgent) {
const user = await this.prisma.adminUser.findUnique({ where: { phone: input.phone } });
const ok = await verify(user?.passwordHash ?? (await DUMMY_HASH), input.password).catch(() => false);
if (!user || !ok || !user.isActive)
throw new UnauthorizedException(INVALID_LOGIN);
const updated = await this.prisma.adminUser.update({
where: { id: user.id },
data: { lastLoginAt: new Date() },
});
this.audit.log(user.id, "login", "user", user.id, user.phone);
return this.issue(updated, userAgent);
}
async refresh(token, userAgent) {
if (!token)
throw new UnauthorizedException("نشست شما منقضی شده است");
const stored = await this.prisma.refreshToken.findUnique({
where: { tokenHash: sha256(token) },
include: { user: true },
});
if (!stored)
throw new UnauthorizedException("نشست شما منقضی شده است");
if (stored.revokedAt) {
await this.revokeAll(stored.userId);
throw new UnauthorizedException("نشست شما منقضی شده است");
}
if (stored.expiresAt < new Date() || !stored.user.isActive) {
throw new UnauthorizedException("نشست شما منقضی شده است");
}
await this.prisma.refreshToken.update({
where: { id: stored.id },
data: { revokedAt: new Date() },
});
return this.issue(stored.user, userAgent);
}
async logout(token) {
if (!token)
return;
await this.prisma.refreshToken.updateMany({
where: { tokenHash: sha256(token), revokedAt: null },
data: { revokedAt: new Date() },
});
}
async changePassword(userId, input) {
const user = await this.prisma.adminUser.findUniqueOrThrow({ where: { id: userId } });
if (!(await verify(user.passwordHash, input.currentPassword).catch(() => false))) {
throw new BadRequestException("رمز عبور فعلی اشتباه است");
}
await this.prisma.adminUser.update({
where: { id: userId },
data: { passwordHash: await hashPassword(input.newPassword) },
});
this.audit.log(userId, "change-password", "user", userId, user.phone);
}
async me(userId) {
return toUserDto(await this.prisma.adminUser.findUniqueOrThrow({ where: { id: userId } }));
}
revokeAll(userId) {
return this.prisma.refreshToken.updateMany({
where: { userId, revokedAt: null },
data: { revokedAt: new Date() },
});
}
async issue(user, userAgent) {
const payload = { sub: user.id, role: user.role };
const accessToken = await this.jwt.signAsync(payload);
const refreshToken = randomBytes(48).toString("base64url");
const refreshExpiresAt = new Date(Date.now() + env.REFRESH_TTL_DAYS * 86_400_000);
await this.prisma.refreshToken.create({
data: {
userId: user.id,
tokenHash: sha256(refreshToken),
expiresAt: refreshExpiresAt,
userAgent: userAgent.slice(0, 300),
},
});
void this.prisma.refreshToken
.deleteMany({ where: { expiresAt: { lt: new Date(Date.now() - 86_400_000) } } })
.catch(() => undefined);
return { accessToken, refreshToken, refreshExpiresAt, user: toUserDto(user) };
}
};
AuthService = __decorate([
Injectable(),
__metadata("design:paramtypes", [PrismaService,
JwtService,
AuditService])
], AuthService);
export { AuthService };
//# sourceMappingURL=auth.service.js.map
File diff suppressed because one or more lines are too long
+214
View File
@@ -0,0 +1,214 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { Body, Controller, Delete, Get, HttpCode, Module, Param, Patch, Post, Put, Query, } from "@nestjs/common";
import { categoryInputSchema, productInputSchema, productListQuerySchema, reorderSchema, } from "@imen/shared";
import { z } from "zod";
import { AdminAuth, CurrentUser, Roles } from "../common/auth.js";
import { IdPipe, ZodPipe } from "../common/zod.pipe.js";
import { MediaModule } from "../media/media.controller.js";
import { CategoriesService } from "./categories.service.js";
import { ProductsService } from "./products.service.js";
const publishSchema = z.object({ isPublished: z.boolean() });
let CategoriesController = class CategoriesController {
categories;
constructor(categories) {
this.categories = categories;
}
list() {
return this.categories.list();
}
get(id) {
return this.categories.get(id);
}
create(body, user) {
return this.categories.create(body, user.id);
}
async reorder(body, user) {
await this.categories.reorder(body.ids, user.id);
}
update(id, body, user) {
return this.categories.update(id, body, user.id);
}
async remove(id, user) {
await this.categories.remove(id, user.id);
}
};
__decorate([
Get(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], CategoriesController.prototype, "list", null);
__decorate([
Get(":id"),
__param(0, Param("id", IdPipe)),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number]),
__metadata("design:returntype", void 0)
], CategoriesController.prototype, "get", null);
__decorate([
Post(),
__param(0, Body(new ZodPipe(categoryInputSchema))),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", void 0)
], CategoriesController.prototype, "create", null);
__decorate([
Post("reorder"),
HttpCode(204),
__param(0, Body(new ZodPipe(reorderSchema))),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], CategoriesController.prototype, "reorder", null);
__decorate([
Put(":id"),
__param(0, Param("id", IdPipe)),
__param(1, Body(new ZodPipe(categoryInputSchema))),
__param(2, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object, Object]),
__metadata("design:returntype", void 0)
], CategoriesController.prototype, "update", null);
__decorate([
Roles("ADMIN"),
Delete(":id"),
HttpCode(204),
__param(0, Param("id", IdPipe)),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object]),
__metadata("design:returntype", Promise)
], CategoriesController.prototype, "remove", null);
CategoriesController = __decorate([
AdminAuth(),
Controller("admin/categories"),
__metadata("design:paramtypes", [CategoriesService])
], CategoriesController);
export { CategoriesController };
let ProductsController = class ProductsController {
products;
constructor(products) {
this.products = products;
}
list(q) {
return this.products.list(q);
}
get(id) {
return this.products.get(id);
}
create(body, user) {
return this.products.create(body, user.id);
}
async reorder(body, user) {
await this.products.reorder(body.ids, user.id);
}
duplicate(id, user) {
return this.products.duplicate(id, user.id);
}
publish(id, body, user) {
return this.products.setPublished(id, body.isPublished, user.id);
}
update(id, body, user) {
return this.products.update(id, body, user.id);
}
async remove(id, user) {
await this.products.remove(id, user.id);
}
};
__decorate([
Get(),
__param(0, Query(new ZodPipe(productListQuerySchema))),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], ProductsController.prototype, "list", null);
__decorate([
Get(":id"),
__param(0, Param("id", IdPipe)),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number]),
__metadata("design:returntype", void 0)
], ProductsController.prototype, "get", null);
__decorate([
Post(),
__param(0, Body(new ZodPipe(productInputSchema))),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", void 0)
], ProductsController.prototype, "create", null);
__decorate([
Post("reorder"),
HttpCode(204),
__param(0, Body(new ZodPipe(reorderSchema))),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ProductsController.prototype, "reorder", null);
__decorate([
Post(":id/duplicate"),
__param(0, Param("id", IdPipe)),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object]),
__metadata("design:returntype", void 0)
], ProductsController.prototype, "duplicate", null);
__decorate([
Patch(":id/publish"),
__param(0, Param("id", IdPipe)),
__param(1, Body(new ZodPipe(publishSchema))),
__param(2, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object, Object]),
__metadata("design:returntype", void 0)
], ProductsController.prototype, "publish", null);
__decorate([
Put(":id"),
__param(0, Param("id", IdPipe)),
__param(1, Body(new ZodPipe(productInputSchema))),
__param(2, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object, Object]),
__metadata("design:returntype", void 0)
], ProductsController.prototype, "update", null);
__decorate([
Roles("ADMIN"),
Delete(":id"),
HttpCode(204),
__param(0, Param("id", IdPipe)),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object]),
__metadata("design:returntype", Promise)
], ProductsController.prototype, "remove", null);
ProductsController = __decorate([
AdminAuth(),
Controller("admin/products"),
__metadata("design:paramtypes", [ProductsService])
], ProductsController);
export { ProductsController };
let CatalogModule = class CatalogModule {
};
CatalogModule = __decorate([
Module({
imports: [MediaModule],
controllers: [CategoriesController, ProductsController],
providers: [CategoriesService, ProductsService],
})
], CatalogModule);
export { CatalogModule };
//# sourceMappingURL=catalog.module.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"catalog.module.js","sourceRoot":"","sources":["../../src/catalog/catalog.module.ts"],"names":[],"mappings":"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"}
+133
View File
@@ -0,0 +1,133 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { ConflictException, Injectable } from "@nestjs/common";
import { AuditService, RevalidateService } from "../common/common.module.js";
import { MediaService } from "../media/media.service.js";
import { PrismaService } from "../prisma/prisma.service.js";
const withCover = { coverImage: true };
let CategoriesService = class CategoriesService {
prisma;
media;
audit;
revalidate;
constructor(prisma, media, audit, revalidate) {
this.prisma = prisma;
this.media = media;
this.audit = audit;
this.revalidate = revalidate;
}
async list() {
const rows = await this.prisma.category.findMany({
orderBy: [{ sortOrder: "asc" }, { id: "asc" }],
include: { ...withCover, _count: { select: { products: true, groups: true } } },
});
return rows.map(({ coverImage, _count, ...c }) => ({
...c,
coverImage: coverImage && this.media.toDto(coverImage),
productCount: _count.products,
groupCount: _count.groups,
}));
}
async get(id) {
const { coverImage, ...c } = await this.prisma.category.findUniqueOrThrow({
where: { id },
include: {
...withCover,
groups: {
orderBy: { sortOrder: "asc" },
include: { _count: { select: { products: true } } },
},
},
});
return {
...c,
coverImage: coverImage && this.media.toDto(coverImage),
groups: c.groups.map(({ _count, ...g }) => ({ ...g, productCount: _count.products })),
};
}
async create(input, userId) {
this.assertUniqueGroupSlugs(input);
const { groups, ...data } = input;
const last = await this.prisma.category.aggregate({ _max: { sortOrder: true } });
const category = await this.prisma.category.create({
data: {
...data,
sortOrder: (last._max.sortOrder ?? -1) + 1,
groups: {
create: groups.map((g, i) => ({ slug: g.slug, name: g.name, desc: g.desc, sortOrder: i })),
},
},
});
this.audit.log(userId, "create", "category", category.id, category.name);
this.revalidate.trigger();
return this.get(category.id);
}
async update(id, input, userId) {
this.assertUniqueGroupSlugs(input);
const { groups, ...data } = input;
await this.prisma.$transaction(async (tx) => {
const category = await tx.category.update({ where: { id }, data });
const keepIds = groups.flatMap((g) => (g.id ? [g.id] : []));
await tx.productGroup.deleteMany({ where: { categoryId: id, id: { notIn: keepIds } } });
for (const g of groups) {
if (g.id) {
await tx.productGroup.update({
where: { id: g.id, categoryId: id },
data: { slug: `__tmp-${g.id}` },
});
}
}
for (const [i, g] of groups.entries()) {
const fields = { slug: g.slug, name: g.name, desc: g.desc, sortOrder: i };
if (g.id) {
await tx.productGroup.update({ where: { id: g.id, categoryId: id }, data: fields });
}
else {
await tx.productGroup.create({ data: { ...fields, categoryId: id } });
}
}
this.audit.log(userId, "update", "category", id, category.name);
});
this.revalidate.trigger();
return this.get(id);
}
async remove(id, userId) {
const category = await this.prisma.category.findUniqueOrThrow({
where: { id },
include: { _count: { select: { products: true } } },
});
if (category._count.products > 0) {
throw new ConflictException(`این دسته ${category._count.products} محصول دارد؛ ابتدا محصولات را حذف یا جابه‌جا کنید`);
}
await this.prisma.category.delete({ where: { id } });
this.audit.log(userId, "delete", "category", id, category.name);
this.revalidate.trigger();
}
async reorder(ids, userId) {
await this.prisma.$transaction(ids.map((id, i) => this.prisma.category.update({ where: { id }, data: { sortOrder: i } })));
this.audit.log(userId, "reorder", "category", "", `${ids.length} دسته`);
this.revalidate.trigger();
}
assertUniqueGroupSlugs(input) {
const slugs = input.groups.map((g) => g.slug);
if (new Set(slugs).size !== slugs.length) {
throw new ConflictException("اسلاگ زیرگروه‌ها باید یکتا باشد");
}
}
};
CategoriesService = __decorate([
Injectable(),
__metadata("design:paramtypes", [PrismaService,
MediaService,
AuditService,
RevalidateService])
], CategoriesService);
export { CategoriesService };
//# sourceMappingURL=categories.service.js.map
File diff suppressed because one or more lines are too long
+182
View File
@@ -0,0 +1,182 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { BadRequestException, Injectable } from "@nestjs/common";
import { AuditService, RevalidateService } from "../common/common.module.js";
import { MediaService } from "../media/media.service.js";
import { PrismaService } from "../prisma/prisma.service.js";
let ProductsService = class ProductsService {
prisma;
media;
audit;
revalidate;
constructor(prisma, media, audit, revalidate) {
this.prisma = prisma;
this.media = media;
this.audit = audit;
this.revalidate = revalidate;
}
async list(q) {
const where = {
...(q.categoryId && { categoryId: q.categoryId }),
...(q.groupId && { groupId: q.groupId }),
...(q.status && { isPublished: q.status === "published" }),
...(q.q && {
OR: [
{ name: { contains: q.q, mode: "insensitive" } },
{ nameEn: { contains: q.q, mode: "insensitive" } },
{ code: { contains: q.q, mode: "insensitive" } },
],
}),
};
const [rows, total] = await this.prisma.$transaction([
this.prisma.product.findMany({
where,
orderBy: [{ category: { sortOrder: "asc" } }, { sortOrder: "asc" }, { id: "asc" }],
skip: (q.page - 1) * q.pageSize,
take: q.pageSize,
include: {
image: true,
category: { select: { id: true, name: true } },
group: { select: { id: true, name: true } },
},
}),
this.prisma.product.count({ where }),
]);
return {
items: rows.map(({ image, ...p }) => ({ ...p, image: image && this.media.toDto(image) })),
total,
page: q.page,
pageSize: q.pageSize,
};
}
async get(id) {
const { image, gallery, ...p } = await this.prisma.product.findUniqueOrThrow({
where: { id },
include: { image: true, gallery: { orderBy: { sortOrder: "asc" }, include: { media: true } } },
});
return {
...p,
image: image && this.media.toDto(image),
gallery: gallery.map((g) => this.media.toDto(g.media)),
};
}
async create(input, userId) {
await this.assertGroup(input);
const { galleryIds, ...data } = input;
const last = await this.prisma.product.aggregate({
where: { categoryId: input.categoryId },
_max: { sortOrder: true },
});
const product = await this.prisma.product.create({
data: {
...data,
sortOrder: (last._max.sortOrder ?? -1) + 1,
gallery: { create: unique(galleryIds).map((mediaId, i) => ({ mediaId, sortOrder: i })) },
},
});
this.audit.log(userId, "create", "product", product.id, product.name);
this.revalidate.trigger();
return this.get(product.id);
}
async update(id, input, userId) {
await this.assertGroup(input);
const { galleryIds, ...data } = input;
const product = await this.prisma.product.update({
where: { id },
data: {
...data,
gallery: {
deleteMany: {},
create: unique(galleryIds).map((mediaId, i) => ({ mediaId, sortOrder: i })),
},
},
});
this.audit.log(userId, "update", "product", id, product.name);
this.revalidate.trigger();
return this.get(id);
}
async setPublished(id, isPublished, userId) {
const product = await this.prisma.product.update({ where: { id }, data: { isPublished } });
this.audit.log(userId, isPublished ? "publish" : "unpublish", "product", id, product.name);
this.revalidate.trigger();
return { id, isPublished };
}
async duplicate(id, userId) {
const src = await this.prisma.product.findUniqueOrThrow({
where: { id },
include: { gallery: true },
});
let n = 1;
const taken = async (code, slug) => (await this.prisma.product.count({ where: { OR: [{ code }, { slug }] } })) > 0;
while (await taken(`${src.code}-${n}`, `${src.slug}-copy-${n}`))
n++;
const copy = await this.prisma.product.create({
data: {
categoryId: src.categoryId,
groupId: src.groupId,
code: `${src.code}-${n}`,
slug: `${src.slug}-copy-${n}`,
name: `${src.name} (کپی)`,
nameEn: src.nameEn,
desc: src.desc,
specs: src.specs,
variants: src.variants,
details: src.details,
brand: src.brand,
origin: src.origin,
sizes: src.sizes,
standards: src.standards,
features: src.features,
applications: src.applications,
attributes: (src.attributes ?? []),
packaging: src.packaging,
minOrder: src.minOrder,
seoTitle: src.seoTitle,
seoDescription: src.seoDescription,
imageId: src.imageId,
sortOrder: src.sortOrder + 1,
isPublished: false,
gallery: {
create: src.gallery.map((g) => ({ mediaId: g.mediaId, sortOrder: g.sortOrder })),
},
},
});
this.audit.log(userId, "duplicate", "product", copy.id, copy.name);
return this.get(copy.id);
}
async remove(id, userId) {
const product = await this.prisma.product.delete({ where: { id } });
this.audit.log(userId, "delete", "product", id, product.name);
this.revalidate.trigger();
}
async reorder(ids, userId) {
await this.prisma.$transaction(ids.map((id, i) => this.prisma.product.update({ where: { id }, data: { sortOrder: i } })));
this.audit.log(userId, "reorder", "product", "", `${ids.length} محصول`);
this.revalidate.trigger();
}
async assertGroup(input) {
if (!input.groupId)
return;
const group = await this.prisma.productGroup.findUnique({ where: { id: input.groupId } });
if (group?.categoryId !== input.categoryId) {
throw new BadRequestException("زیرگروه انتخاب‌شده متعلق به این دسته نیست");
}
}
};
ProductsService = __decorate([
Injectable(),
__metadata("design:paramtypes", [PrismaService,
MediaService,
AuditService,
RevalidateService])
], ProductsService);
export { ProductsService };
const unique = (ids) => [...new Set(ids)];
//# sourceMappingURL=products.service.js.map
File diff suppressed because one or more lines are too long
+60
View File
@@ -0,0 +1,60 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { createParamDecorator, ForbiddenException, Injectable, SetMetadata, UnauthorizedException, UseGuards, applyDecorators, } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { JwtService } from "@nestjs/jwt";
import { PrismaService } from "../prisma/prisma.service.js";
const ROLES_KEY = "roles";
let JwtAuthGuard = class JwtAuthGuard {
jwt;
reflector;
prisma;
constructor(jwt, reflector, prisma) {
this.jwt = jwt;
this.reflector = reflector;
this.prisma = prisma;
}
async canActivate(ctx) {
const req = ctx.switchToHttp().getRequest();
const [scheme, token] = (req.headers.authorization ?? "").split(" ");
if (scheme !== "Bearer" || !token)
throw new UnauthorizedException("ابتدا وارد شوید");
let payload;
try {
payload = await this.jwt.verifyAsync(token);
}
catch {
throw new UnauthorizedException("نشست شما منقضی شده است");
}
const user = await this.prisma.adminUser.findUnique({ where: { id: payload.sub } });
if (!user?.isActive)
throw new UnauthorizedException("حساب کاربری غیرفعال است");
req.user = { id: user.id, phone: user.phone, name: user.name, role: user.role };
const roles = this.reflector.getAllAndOverride(ROLES_KEY, [
ctx.getHandler(),
ctx.getClass(),
]);
if (roles?.length && !roles.includes(user.role)) {
throw new ForbiddenException("برای این کار دسترسی ندارید");
}
return true;
}
};
JwtAuthGuard = __decorate([
Injectable(),
__metadata("design:paramtypes", [JwtService,
Reflector,
PrismaService])
], JwtAuthGuard);
export { JwtAuthGuard };
export const AdminAuth = (...roles) => applyDecorators(SetMetadata(ROLES_KEY, roles), UseGuards(JwtAuthGuard));
export const Roles = (...roles) => SetMetadata(ROLES_KEY, roles);
export const CurrentUser = createParamDecorator((_, ctx) => ctx.switchToHttp().getRequest().user);
//# sourceMappingURL=auth.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/common/auth.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAEL,oBAAoB,EAEpB,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,qBAAqB,EACrB,SAAS,EACT,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAgB5D,MAAM,SAAS,GAAG,OAAO,CAAC;AAGnB,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEJ;IACA;IACA;IAHnB,YACmB,GAAe,EACf,SAAoB,EACpB,MAAqB;QAFrB,QAAG,GAAH,GAAG,CAAY;QACf,cAAS,GAAT,SAAS,CAAW;QACpB,WAAM,GAAN,MAAM,CAAe;IACrC,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,GAAqB;QACrC,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAiB,CAAC;QAC3D,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrE,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,qBAAqB,CAAC,iBAAiB,CAAC,CAAC;QAEtF,IAAI,OAAmB,CAAC;QACxB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,CAAa,KAAK,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,qBAAqB,CAAC,wBAAwB,CAAC,CAAC;QAC5D,CAAC;QAGD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACpF,IAAI,CAAC,IAAI,EAAE,QAAQ;YAAE,MAAM,IAAI,qBAAqB,CAAC,yBAAyB,CAAC,CAAC;QAChF,GAAG,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAEhF,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAqB,SAAS,EAAE;YAC5E,GAAG,CAAC,UAAU,EAAE;YAChB,GAAG,CAAC,QAAQ,EAAE;SACf,CAAC,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,kBAAkB,CAAC,4BAA4B,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAjCY,YAAY;IADxB,UAAU,EAAE;qCAGa,UAAU;QACJ,SAAS;QACZ,aAAa;GAJ7B,YAAY,CAiCxB;;AAGD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAG,KAAa,EAAE,EAAE,CAC5C,eAAe,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;AAG1E,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,GAAG,KAAa,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAEzE,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAC7C,CAAC,CAAU,EAAE,GAAqB,EAAY,EAAE,CAC9C,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAiB,CAAC,IAAK,CACvD,CAAC"}
+70
View File
@@ -0,0 +1,70 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var AuditService_1, RevalidateService_1;
import { Global, Injectable, Logger, Module } from "@nestjs/common";
import { env } from "../config/env.js";
import { PrismaService } from "../prisma/prisma.service.js";
let AuditService = AuditService_1 = class AuditService {
prisma;
logger = new Logger(AuditService_1.name);
constructor(prisma) {
this.prisma = prisma;
}
log(userId, action, entity, entityId = "", summary = "") {
this.prisma.auditLog
.create({ data: { userId, action, entity, entityId: String(entityId), summary } })
.catch((e) => this.logger.warn(`audit log failed: ${String(e)}`));
}
};
AuditService = AuditService_1 = __decorate([
Injectable(),
__metadata("design:paramtypes", [PrismaService])
], AuditService);
export { AuditService };
let RevalidateService = RevalidateService_1 = class RevalidateService {
logger = new Logger(RevalidateService_1.name);
timer;
trigger() {
if (!env.WEB_REVALIDATE_URL)
return;
clearTimeout(this.timer);
this.timer = setTimeout(() => void this.run(), 1500);
this.timer.unref();
}
async run() {
try {
const res = await fetch(env.WEB_REVALIDATE_URL, {
method: "POST",
headers: { "x-revalidate-secret": env.REVALIDATE_SECRET ?? "" },
signal: AbortSignal.timeout(5000),
});
if (!res.ok)
this.logger.warn(`site revalidation returned ${res.status}`);
}
catch (e) {
this.logger.warn(`site revalidation failed: ${String(e)}`);
}
}
};
RevalidateService = RevalidateService_1 = __decorate([
Injectable()
], RevalidateService);
export { RevalidateService };
let CommonModule = class CommonModule {
};
CommonModule = __decorate([
Global(),
Module({
providers: [AuditService, RevalidateService],
exports: [AuditService, RevalidateService],
})
], CommonModule);
export { CommonModule };
//# sourceMappingURL=common.module.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"common.module.js","sourceRoot":"","sources":["../../src/common/common.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIrD,IAAM,YAAY,oBAAlB,MAAM,YAAY;IAGM;IAFZ,MAAM,GAAG,IAAI,MAAM,CAAC,cAAY,CAAC,IAAI,CAAC,CAAC;IAExD,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAEtD,GAAG,CACD,MAAqB,EACrB,MAAc,EACd,MAAc,EACd,WAA4B,EAAE,EAC9B,OAAO,GAAG,EAAE;QAEZ,IAAI,CAAC,MAAM,CAAC,QAAQ;aACjB,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;aACjF,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;CACF,CAAA;AAhBY,YAAY;IADxB,UAAU,EAAE;qCAI0B,aAAa;GAHvC,YAAY,CAgBxB;;AAOM,IAAM,iBAAiB,yBAAvB,MAAM,iBAAiB;IACX,MAAM,GAAG,IAAI,MAAM,CAAC,mBAAiB,CAAC,IAAI,CAAC,CAAC;IACrD,KAAK,CAA6B;IAE1C,OAAO;QACL,IAAI,CAAC,GAAG,CAAC,kBAAkB;YAAE,OAAO;QACpC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,GAAG;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,kBAAmB,EAAE;gBAC/C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,qBAAqB,EAAE,GAAG,CAAC,iBAAiB,IAAI,EAAE,EAAE;gBAC/D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;aAClC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;CACF,CAAA;AAvBY,iBAAiB;IAD7B,UAAU,EAAE;GACA,iBAAiB,CAuB7B;;AAOM,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,YAAY;IALxB,MAAM,EAAE;IACR,MAAM,CAAC;QACN,SAAS,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;QAC5C,OAAO,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;KAC3C,CAAC;GACW,YAAY,CAAG"}
+59
View File
@@ -0,0 +1,59 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Catch, HttpStatus } from "@nestjs/common";
import { Prisma } from "../generated/prisma/client.js";
const FIELD_LABELS = {
slug: "اسلاگ",
code: "کد",
email: "ایمیل",
phone: "شماره موبایل",
};
function uniqueFields(meta) {
if (meta?.target)
return Array.isArray(meta.target) ? meta.target : [meta.target];
const constraint = meta?.driverAdapterError?.cause?.constraint;
if (constraint?.fields)
return constraint.fields;
const match = constraint?.index?.match(/^[^_]+_(.+)_key$/);
return match ? match[1].split("_") : [];
}
let PrismaExceptionFilter = class PrismaExceptionFilter {
catch(error, host) {
const res = host.switchToHttp().getResponse();
switch (error.code) {
case "P2002": {
const fields = uniqueFields(error.meta)
.filter((f) => !f.endsWith("Id"))
.map((f) => FIELD_LABELS[f] ?? f)
.join("، ");
return res.status(HttpStatus.CONFLICT).json({
statusCode: HttpStatus.CONFLICT,
message: fields ? `مقدار «${fields}» تکراری است` : "مقدار تکراری است",
});
}
case "P2003":
return res.status(HttpStatus.CONFLICT).json({
statusCode: HttpStatus.CONFLICT,
message: "این مورد به داده‌های دیگری وابسته است",
});
case "P2025":
return res
.status(HttpStatus.NOT_FOUND)
.json({ statusCode: HttpStatus.NOT_FOUND, message: "مورد پیدا نشد" });
default:
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
message: "خطای پایگاه داده",
});
}
}
};
PrismaExceptionFilter = __decorate([
Catch(Prisma.PrismaClientKnownRequestError)
], PrismaExceptionFilter);
export { PrismaExceptionFilter };
//# sourceMappingURL=prisma-exception.filter.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"prisma-exception.filter.js","sourceRoot":"","sources":["../../src/common/prisma-exception.filter.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAsB,KAAK,EAAwB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE7F,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAEvD,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,cAAc;CACtB,CAAC;AAQF,SAAS,YAAY,CAAC,IAA4B;IAChD,IAAI,IAAI,EAAE,MAAM;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,UAAU,CAAC;IAC/D,IAAI,UAAU,EAAE,MAAM;QAAE,OAAO,UAAU,CAAC,MAAM,CAAC;IAEjD,MAAM,KAAK,GAAG,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAC3D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC;AAIM,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,KAAK,CAAC,KAA2C,EAAE,IAAmB;QACpE,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,WAAW,EAAY,CAAC;QAExD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,IAA8B,CAAC;qBAC9D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;qBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;qBAChC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;oBAC1C,UAAU,EAAE,UAAU,CAAC,QAAQ;oBAC/B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,cAAc,CAAC,CAAC,CAAC,kBAAkB;iBACtE,CAAC,CAAC;YACL,CAAC;YACD,KAAK,OAAO;gBACV,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;oBAC1C,UAAU,EAAE,UAAU,CAAC,QAAQ;oBAC/B,OAAO,EAAE,uCAAuC;iBACjD,CAAC,CAAC;YACL,KAAK,OAAO;gBACV,OAAO,GAAG;qBACP,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;qBAC5B,IAAI,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;YAC1E;gBACE,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC;oBACvD,UAAU,EAAE,UAAU,CAAC,qBAAqB;oBAC5C,OAAO,EAAE,kBAAkB;iBAC5B,CAAC,CAAC;QACP,CAAC;IACH,CAAC;CACF,CAAA;AA/BY,qBAAqB;IADjC,KAAK,CAAC,MAAM,CAAC,6BAA6B,CAAC;GAC/B,qBAAqB,CA+BjC"}
+23
View File
@@ -0,0 +1,23 @@
import { BadRequestException } from "@nestjs/common";
import { toIssues } from "@imen/shared";
import { z } from "zod";
z.config(z.locales.fa());
export class ZodPipe {
schema;
constructor(schema) {
this.schema = schema;
}
transform(value) {
const result = this.schema.safeParse(value);
if (!result.success) {
throw new BadRequestException({
statusCode: 400,
message: "اطلاعات واردشده معتبر نیست",
issues: toIssues(result.error),
});
}
return result.data;
}
}
export const IdPipe = new ZodPipe(z.coerce.number().int().positive());
//# sourceMappingURL=zod.pipe.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"zod.pipe.js","sourceRoot":"","sources":["../../src/common/zod.pipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAsB,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;AAGzB,MAAM,OAAO,OAAO;IACW;IAA7B,YAA6B,MAAS;QAAT,WAAM,GAAN,MAAM,CAAG;IAAG,CAAC;IAE1C,SAAS,CAAC,KAAc;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,mBAAmB,CAAC;gBAC5B,UAAU,EAAE,GAAG;gBACf,OAAO,EAAE,4BAA4B;gBACrC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;aAC/B,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;CACF;AAGD,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC"}
+43
View File
@@ -0,0 +1,43 @@
import { existsSync } from "node:fs";
import { z } from "zod";
if (existsSync(".env"))
process.loadEnvFile(".env");
const bool = (fallback) => z
.enum(["true", "false", "1", "0"])
.optional()
.transform((v) => (v === undefined ? fallback : v === "true" || v === "1"));
const schema = z.object({
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
PORT: z.coerce.number().int().default(4000),
CORS_ORIGINS: z.string().default(""),
TRUST_PROXY: z.coerce.number().int().min(0).default(1),
DATABASE_URL: z.string().min(1),
JWT_SECRET: z.string().min(32, "JWT_SECRET must be at least 32 characters"),
JWT_ACCESS_TTL: z.string().default("15m"),
REFRESH_TTL_DAYS: z.coerce.number().int().positive().default(30),
COOKIE_SECURE: bool(true),
S3_ENDPOINT: z.string().optional(),
S3_REGION: z.string().default("us-east-1"),
S3_BUCKET: z.string().default("imen-media"),
S3_ACCESS_KEY: z.string().default(""),
S3_SECRET_KEY: z.string().default(""),
S3_FORCE_PATH_STYLE: bool(true),
S3_ENSURE_BUCKET: bool(false),
MEDIA_PUBLIC_URL: z
.string()
.default("/media")
.transform((v) => v.replace(/\/+$/, "")),
WEB_REVALIDATE_URL: z.string().optional(),
REVALIDATE_SECRET: z.string().optional(),
ADMIN_PHONE: z.string().optional(),
ADMIN_PASSWORD: z.string().optional(),
ADMIN_NAME: z.string().default("مدیر سایت"),
});
const parsed = schema.safeParse(process.env);
if (!parsed.success) {
console.error("Invalid environment variables:\n" + z.prettifyError(parsed.error));
process.exit(1);
}
export const env = parsed.data;
export const isProd = env.NODE_ENV === "production";
//# sourceMappingURL=env.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"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"}
+163
View File
@@ -0,0 +1,163 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { Body, Controller, Delete, Get, HttpCode, Injectable, Module, Param, Patch, Post, Query, Req, } from "@nestjs/common";
import { Throttle } from "@nestjs/throttler";
import { contactInputSchema, MESSAGE_STATUSES, messageUpdateSchema, } from "@imen/shared";
import { z } from "zod";
import { AdminAuth, CurrentUser, Roles } from "../common/auth.js";
import { AuditService } from "../common/common.module.js";
import { IdPipe, ZodPipe } from "../common/zod.pipe.js";
import { PrismaService } from "../prisma/prisma.service.js";
const listQuery = z.object({
status: z.enum(MESSAGE_STATUSES).optional(),
page: z.coerce.number().int().min(1).default(1),
pageSize: z.coerce.number().int().min(1).max(100).default(20),
});
export const toMessageDto = (m) => ({
id: m.id,
name: m.name,
org: m.org,
phone: m.phone,
message: m.message,
status: m.status,
createdAt: m.createdAt.toISOString(),
});
let ContactService = class ContactService {
prisma;
audit;
constructor(prisma, audit) {
this.prisma = prisma;
this.audit = audit;
}
async submit(input, ip, userAgent) {
if (input.website)
return;
await this.prisma.contactMessage.create({
data: {
name: input.name,
org: input.org,
phone: input.phone,
message: input.message,
ip: ip.slice(0, 64),
userAgent: userAgent.slice(0, 300),
},
});
}
async list(q) {
const where = q.status ? { status: q.status } : {};
const [items, total] = await this.prisma.$transaction([
this.prisma.contactMessage.findMany({
where,
orderBy: { id: "desc" },
skip: (q.page - 1) * q.pageSize,
take: q.pageSize,
}),
this.prisma.contactMessage.count({ where }),
]);
return { items: items.map(toMessageDto), total, page: q.page, pageSize: q.pageSize };
}
async setStatus(id, status) {
return toMessageDto(await this.prisma.contactMessage.update({ where: { id }, data: { status } }));
}
async remove(id, userId) {
const m = await this.prisma.contactMessage.delete({ where: { id } });
this.audit.log(userId, "delete", "message", id, m.name);
}
};
ContactService = __decorate([
Injectable(),
__metadata("design:paramtypes", [PrismaService,
AuditService])
], ContactService);
export { ContactService };
let PublicContactController = class PublicContactController {
contact;
constructor(contact) {
this.contact = contact;
}
async submit(body, req) {
await this.contact.submit(body, req.ip ?? "", req.headers["user-agent"] ?? "");
return { ok: true };
}
};
__decorate([
Post(),
HttpCode(201),
Throttle({ default: { limit: 5, ttl: 10 * 60_000 } }),
__param(0, Body(new ZodPipe(contactInputSchema))),
__param(1, Req()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], PublicContactController.prototype, "submit", null);
PublicContactController = __decorate([
Controller("public/contact"),
__metadata("design:paramtypes", [ContactService])
], PublicContactController);
export { PublicContactController };
let MessagesController = class MessagesController {
contact;
constructor(contact) {
this.contact = contact;
}
list(q) {
return this.contact.list(q);
}
update(id, body) {
return this.contact.setStatus(id, body.status);
}
async remove(id, user) {
await this.contact.remove(id, user.id);
}
};
__decorate([
Get(),
__param(0, Query(new ZodPipe(listQuery))),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], MessagesController.prototype, "list", null);
__decorate([
Patch(":id"),
__param(0, Param("id", IdPipe)),
__param(1, Body(new ZodPipe(messageUpdateSchema))),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object]),
__metadata("design:returntype", void 0)
], MessagesController.prototype, "update", null);
__decorate([
Roles("ADMIN"),
Delete(":id"),
HttpCode(204),
__param(0, Param("id", IdPipe)),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object]),
__metadata("design:returntype", Promise)
], MessagesController.prototype, "remove", null);
MessagesController = __decorate([
AdminAuth(),
Controller("admin/messages"),
__metadata("design:paramtypes", [ContactService])
], MessagesController);
export { MessagesController };
let ContactModule = class ContactModule {
};
ContactModule = __decorate([
Module({
controllers: [PublicContactController, MessagesController],
providers: [ContactService],
})
], ContactModule);
export { ContactModule };
//# sourceMappingURL=contact.module.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"contact.module.js","sourceRoot":"","sources":["../../src/contact/contact.module.ts"],"names":[],"mappings":"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"}
+116
View File
@@ -0,0 +1,116 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Controller, Get, Module } from "@nestjs/common";
import { SECTION_KEYS } from "@imen/shared";
import { AdminAuth } from "../common/auth.js";
import { toMessageDto } from "../contact/contact.module.js";
import { PrismaService } from "../prisma/prisma.service.js";
const DAY_NAMES = ["یکشنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنج‌شنبه", "جمعه", "شنبه"];
let DashboardController = class DashboardController {
prisma;
constructor(prisma) {
this.prisma = prisma;
}
async get() {
const [categories, products, draftProducts, newMessages, readMessages, archivedMessages, media, messages, activity, categoryRows, sectionRows,] = await Promise.all([
this.prisma.category.count(),
this.prisma.product.count(),
this.prisma.product.count({ where: { isPublished: false } }),
this.prisma.contactMessage.count({ where: { status: "NEW" } }),
this.prisma.contactMessage.count({ where: { status: "READ" } }),
this.prisma.contactMessage.count({ where: { status: "ARCHIVED" } }),
this.prisma.media.count(),
this.prisma.contactMessage.findMany({ orderBy: { id: "desc" }, take: 6 }),
this.prisma.auditLog.findMany({
orderBy: { id: "desc" },
take: 10,
include: { user: { select: { name: true } } },
}),
this.prisma.category.findMany({
select: { id: true, name: true, _count: { select: { products: true } } },
orderBy: { products: { _count: "desc" } },
take: 7,
}),
this.prisma.siteSection.findMany(),
]);
let hiddenCount = 0;
for (const s of sectionRows) {
if (s.data && typeof s.data === "object" && s.data.enabled === false) {
hiddenCount++;
}
}
const now = new Date();
const trend = [];
for (let i = 6; i >= 0; i--) {
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate() - i, 0, 0, 0);
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate() - i, 23, 59, 59, 999);
const count = await this.prisma.contactMessage.count({
where: { createdAt: { gte: start, lte: end } },
});
trend.push({
date: start.toISOString().slice(0, 10),
dayName: DAY_NAMES[start.getDay()],
messages: count,
});
}
return {
categories,
products,
draftProducts,
newMessages,
media,
recentMessages: messages.map(toMessageDto),
recentActivity: activity.map((a) => ({
id: a.id,
action: a.action,
entity: a.entity,
summary: a.summary,
user: a.user?.name ?? null,
createdAt: a.createdAt.toISOString(),
})),
categoryStats: categoryRows.map((c) => ({
id: c.id,
name: c.name,
count: c._count.products,
})),
messageBreakdown: {
new: newMessages,
read: readMessages,
archived: archivedMessages,
total: newMessages + readMessages + archivedMessages,
},
sectionsSummary: {
total: SECTION_KEYS.length,
visible: SECTION_KEYS.length - hiddenCount,
hidden: hiddenCount,
},
trend,
};
}
};
__decorate([
Get(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], DashboardController.prototype, "get", null);
DashboardController = __decorate([
AdminAuth(),
Controller("admin/dashboard"),
__metadata("design:paramtypes", [PrismaService])
], DashboardController);
export { DashboardController };
let DashboardModule = class DashboardModule {
};
DashboardModule = __decorate([
Module({ controllers: [DashboardController] })
], DashboardModule);
export { DashboardModule };
//# sourceMappingURL=dashboard.module.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"dashboard.module.js","sourceRoot":"","sources":["../../src/dashboard/dashboard.module.ts"],"names":[],"mappings":"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"}
+5
View File
@@ -0,0 +1,5 @@
import * as Prisma from './internal/prismaNamespaceBrowser.js';
export { Prisma };
export * as $Enums from './enums.js';
export * from './enums.js';
//# sourceMappingURL=browser.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../src/generated/prisma/browser.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,MAAM,MAAM,sCAAsC,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,CAAA;AACjB,OAAO,KAAK,MAAM,MAAM,YAAY,CAAA;AACpC,cAAc,YAAY,CAAC"}
+10
View File
@@ -0,0 +1,10 @@
import * as path from 'node:path';
import { fileURLToPath } from 'node:url';
globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url));
import * as $Class from "./internal/class.js";
import * as Prisma from "./internal/prismaNamespace.js";
export * as $Enums from './enums.js';
export * from "./enums.js";
export const PrismaClient = $Class.getPrismaClientClass();
export { Prisma };
//# sourceMappingURL=client.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/generated/prisma/client.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAItE,OAAO,KAAK,MAAM,MAAM,qBAAqB,CAAA;AAC7C,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAA;AAEvD,OAAO,KAAK,MAAM,MAAM,YAAY,CAAA;AACpC,cAAc,YAAY,CAAA;AAgB1B,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,oBAAoB,EAAE,CAAA;AAEzD,OAAO,EAAE,MAAM,EAAE,CAAA"}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=commonInputTypes.js.map
@@ -0,0 +1 @@
{"version":3,"file":"commonInputTypes.js","sourceRoot":"","sources":["../../../src/generated/prisma/commonInputTypes.ts"],"names":[],"mappings":""}
+10
View File
@@ -0,0 +1,10 @@
export const Role = {
ADMIN: 'ADMIN',
EDITOR: 'EDITOR'
};
export const MessageStatus = {
NEW: 'NEW',
READ: 'READ',
ARCHIVED: 'ARCHIVED'
};
//# sourceMappingURL=enums.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"enums.js","sourceRoot":"","sources":["../../../src/generated/prisma/enums.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;CACR,CAAA;AAKV,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;CACZ,CAAA"}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"class.js","sourceRoot":"","sources":["../../../../src/generated/prisma/internal/class.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,OAAO,MAAM,+BAA+B,CAAA;AAIxD,MAAM,MAAM,GAAkC;IAC5C,iBAAiB,EAAE,EAAE;IACrB,eAAe,EAAE,QAAQ;IACzB,eAAe,EAAE,0CAA0C;IAC3D,gBAAgB,EAAE,YAAY;IAC9B,cAAc,EAAE,qlMAAqlM;IACrmM,kBAAkB,EAAE;QAClB,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE;KACZ;IACD,wBAAwB,EAAE;QACxB,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,EAAE;KACZ;CACF,CAAA;AAED,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,83QAA83Q,CAAC,CAAA;AACp6Q,MAAM,CAAC,sBAAsB,GAAG;IAC9B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,w0LAAw0L,CAAC;IAC71L,KAAK,EAAE,0psCAA0psC;CAClqsC,CAAA;AAED,KAAK,UAAU,kBAAkB,CAAC,UAAkB;IAClD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;IAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IACnD,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;AAC1C,CAAC;AAED,MAAM,CAAC,YAAY,GAAG;IACpB,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,8DAA8D,CAAC;IAEpG,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,0EAA0E,CAAC,CAAA;QACzG,OAAO,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACvC,CAAC;IAED,UAAU,EAAE,6BAA6B;CAC1C,CAAA;AA4OD,MAAM,UAAU,oBAAoB;IAClC,OAAO,OAAO,CAAC,eAAe,CAAC,MAAM,CAAuC,CAAA;AAC9E,CAAC"}
@@ -0,0 +1,181 @@
import * as runtime from "@prisma/client/runtime/client";
export const PrismaClientKnownRequestError = runtime.PrismaClientKnownRequestError;
export const PrismaClientUnknownRequestError = runtime.PrismaClientUnknownRequestError;
export const PrismaClientRustPanicError = runtime.PrismaClientRustPanicError;
export const PrismaClientInitializationError = runtime.PrismaClientInitializationError;
export const PrismaClientValidationError = runtime.PrismaClientValidationError;
export const sql = runtime.sqltag;
export const empty = runtime.empty;
export const join = runtime.join;
export const raw = runtime.raw;
export const Sql = runtime.Sql;
export const Decimal = runtime.Decimal;
export const getExtensionContext = runtime.Extensions.getExtensionContext;
export const prismaVersion = {
client: "7.10.1",
engine: "d1b3f377ca835d73fd50954a5e22128b9ebdd6b8"
};
export const NullTypes = {
DbNull: runtime.NullTypes.DbNull,
JsonNull: runtime.NullTypes.JsonNull,
AnyNull: runtime.NullTypes.AnyNull,
};
export const DbNull = runtime.DbNull;
export const JsonNull = runtime.JsonNull;
export const AnyNull = runtime.AnyNull;
export const ModelName = {
AdminUser: 'AdminUser',
RefreshToken: 'RefreshToken',
Media: 'Media',
Category: 'Category',
ProductGroup: 'ProductGroup',
Product: 'Product',
ProductImage: 'ProductImage',
SiteSection: 'SiteSection',
ContactMessage: 'ContactMessage',
AuditLog: 'AuditLog'
};
export const TransactionIsolationLevel = runtime.makeStrictEnum({
ReadUncommitted: 'ReadUncommitted',
ReadCommitted: 'ReadCommitted',
RepeatableRead: 'RepeatableRead',
Serializable: 'Serializable'
});
export const AdminUserScalarFieldEnum = {
id: 'id',
phone: 'phone',
name: 'name',
passwordHash: 'passwordHash',
role: 'role',
isActive: 'isActive',
lastLoginAt: 'lastLoginAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
};
export const RefreshTokenScalarFieldEnum = {
id: 'id',
userId: 'userId',
tokenHash: 'tokenHash',
expiresAt: 'expiresAt',
revokedAt: 'revokedAt',
userAgent: 'userAgent',
createdAt: 'createdAt'
};
export const MediaScalarFieldEnum = {
id: 'id',
key: 'key',
mime: 'mime',
size: 'size',
width: 'width',
height: 'height',
alt: 'alt',
originalName: 'originalName',
createdAt: 'createdAt'
};
export const CategoryScalarFieldEnum = {
id: 'id',
slug: 'slug',
code: 'code',
name: 'name',
nameEn: 'nameEn',
shortDesc: 'shortDesc',
fullDesc: 'fullDesc',
icon: 'icon',
coverImageId: 'coverImageId',
sortOrder: 'sortOrder',
isPublished: 'isPublished',
seoTitle: 'seoTitle',
seoDescription: 'seoDescription',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
};
export const ProductGroupScalarFieldEnum = {
id: 'id',
categoryId: 'categoryId',
slug: 'slug',
name: 'name',
desc: 'desc',
sortOrder: 'sortOrder'
};
export const ProductScalarFieldEnum = {
id: 'id',
categoryId: 'categoryId',
groupId: 'groupId',
code: 'code',
slug: 'slug',
name: 'name',
nameEn: 'nameEn',
desc: 'desc',
specs: 'specs',
variants: 'variants',
details: 'details',
brand: 'brand',
origin: 'origin',
sizes: 'sizes',
standards: 'standards',
features: 'features',
applications: 'applications',
attributes: 'attributes',
packaging: 'packaging',
minOrder: 'minOrder',
seoTitle: 'seoTitle',
seoDescription: 'seoDescription',
imageId: 'imageId',
sortOrder: 'sortOrder',
isPublished: 'isPublished',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
};
export const ProductImageScalarFieldEnum = {
productId: 'productId',
mediaId: 'mediaId',
sortOrder: 'sortOrder'
};
export const SiteSectionScalarFieldEnum = {
key: 'key',
data: 'data',
updatedById: 'updatedById',
updatedAt: 'updatedAt'
};
export const ContactMessageScalarFieldEnum = {
id: 'id',
name: 'name',
org: 'org',
phone: 'phone',
message: 'message',
status: 'status',
ip: 'ip',
userAgent: 'userAgent',
createdAt: 'createdAt'
};
export const AuditLogScalarFieldEnum = {
id: 'id',
userId: 'userId',
action: 'action',
entity: 'entity',
entityId: 'entityId',
summary: 'summary',
createdAt: 'createdAt'
};
export const SortOrder = {
asc: 'asc',
desc: 'desc'
};
export const JsonNullValueInput = {
JsonNull: JsonNull
};
export const QueryMode = {
default: 'default',
insensitive: 'insensitive'
};
export const NullsOrder = {
first: 'first',
last: 'last'
};
export const JsonNullValueFilter = {
DbNull: DbNull,
JsonNull: JsonNull,
AnyNull: AnyNull
};
export const defineExtension = runtime.Extensions.defineExtension;
//# sourceMappingURL=prismaNamespace.js.map
@@ -0,0 +1 @@
{"version":3,"file":"prismaNamespace.js","sourceRoot":"","sources":["../../../../src/generated/prisma/internal/prismaNamespace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,165 @@
import * as runtime from "@prisma/client/runtime/index-browser";
export const Decimal = runtime.Decimal;
export const NullTypes = {
DbNull: runtime.NullTypes.DbNull,
JsonNull: runtime.NullTypes.JsonNull,
AnyNull: runtime.NullTypes.AnyNull,
};
export const DbNull = runtime.DbNull;
export const JsonNull = runtime.JsonNull;
export const AnyNull = runtime.AnyNull;
export const ModelName = {
AdminUser: 'AdminUser',
RefreshToken: 'RefreshToken',
Media: 'Media',
Category: 'Category',
ProductGroup: 'ProductGroup',
Product: 'Product',
ProductImage: 'ProductImage',
SiteSection: 'SiteSection',
ContactMessage: 'ContactMessage',
AuditLog: 'AuditLog'
};
export const TransactionIsolationLevel = runtime.makeStrictEnum({
ReadUncommitted: 'ReadUncommitted',
ReadCommitted: 'ReadCommitted',
RepeatableRead: 'RepeatableRead',
Serializable: 'Serializable'
});
export const AdminUserScalarFieldEnum = {
id: 'id',
phone: 'phone',
name: 'name',
passwordHash: 'passwordHash',
role: 'role',
isActive: 'isActive',
lastLoginAt: 'lastLoginAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
};
export const RefreshTokenScalarFieldEnum = {
id: 'id',
userId: 'userId',
tokenHash: 'tokenHash',
expiresAt: 'expiresAt',
revokedAt: 'revokedAt',
userAgent: 'userAgent',
createdAt: 'createdAt'
};
export const MediaScalarFieldEnum = {
id: 'id',
key: 'key',
mime: 'mime',
size: 'size',
width: 'width',
height: 'height',
alt: 'alt',
originalName: 'originalName',
createdAt: 'createdAt'
};
export const CategoryScalarFieldEnum = {
id: 'id',
slug: 'slug',
code: 'code',
name: 'name',
nameEn: 'nameEn',
shortDesc: 'shortDesc',
fullDesc: 'fullDesc',
icon: 'icon',
coverImageId: 'coverImageId',
sortOrder: 'sortOrder',
isPublished: 'isPublished',
seoTitle: 'seoTitle',
seoDescription: 'seoDescription',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
};
export const ProductGroupScalarFieldEnum = {
id: 'id',
categoryId: 'categoryId',
slug: 'slug',
name: 'name',
desc: 'desc',
sortOrder: 'sortOrder'
};
export const ProductScalarFieldEnum = {
id: 'id',
categoryId: 'categoryId',
groupId: 'groupId',
code: 'code',
slug: 'slug',
name: 'name',
nameEn: 'nameEn',
desc: 'desc',
specs: 'specs',
variants: 'variants',
details: 'details',
brand: 'brand',
origin: 'origin',
sizes: 'sizes',
standards: 'standards',
features: 'features',
applications: 'applications',
attributes: 'attributes',
packaging: 'packaging',
minOrder: 'minOrder',
seoTitle: 'seoTitle',
seoDescription: 'seoDescription',
imageId: 'imageId',
sortOrder: 'sortOrder',
isPublished: 'isPublished',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
};
export const ProductImageScalarFieldEnum = {
productId: 'productId',
mediaId: 'mediaId',
sortOrder: 'sortOrder'
};
export const SiteSectionScalarFieldEnum = {
key: 'key',
data: 'data',
updatedById: 'updatedById',
updatedAt: 'updatedAt'
};
export const ContactMessageScalarFieldEnum = {
id: 'id',
name: 'name',
org: 'org',
phone: 'phone',
message: 'message',
status: 'status',
ip: 'ip',
userAgent: 'userAgent',
createdAt: 'createdAt'
};
export const AuditLogScalarFieldEnum = {
id: 'id',
userId: 'userId',
action: 'action',
entity: 'entity',
entityId: 'entityId',
summary: 'summary',
createdAt: 'createdAt'
};
export const SortOrder = {
asc: 'asc',
desc: 'desc'
};
export const JsonNullValueInput = {
JsonNull: JsonNull
};
export const QueryMode = {
default: 'default',
insensitive: 'insensitive'
};
export const NullsOrder = {
first: 'first',
last: 'last'
};
export const JsonNullValueFilter = {
DbNull: DbNull,
JsonNull: JsonNull,
AnyNull: AnyNull
};
//# sourceMappingURL=prismaNamespaceBrowser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"prismaNamespaceBrowser.js","sourceRoot":"","sources":["../../../../src/generated/prisma/internal/prismaNamespaceBrowser.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,OAAO,MAAM,sCAAsC,CAAA;AAK/D,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;AAGtC,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,MAAwD;IAClF,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,QAA4D;IACxF,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,OAA0D;CACtF,CAAA;AAMD,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;AAOpC,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;AAOxC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;AAGtC,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,cAAc;IAC5B,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,cAAc;IAC5B,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,cAAc,EAAE,gBAAgB;IAChC,QAAQ,EAAE,UAAU;CACZ,CAAA;AAQV,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC,cAAc,CAAC;IAC9D,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,gBAAgB;IAChC,YAAY,EAAE,cAAc;CACpB,CAAC,CAAA;AAKX,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,EAAE,EAAE,IAAI;IACR,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,YAAY,EAAE,cAAc;IAC5B,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,EAAE,EAAE,IAAI;IACR,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,KAAK;IACV,YAAY,EAAE,cAAc;IAC5B,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,MAAM;IACZ,YAAY,EAAE,cAAc;IAC5B,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,EAAE,EAAE,IAAI;IACR,UAAU,EAAE,YAAY;IACxB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,EAAE,EAAE,IAAI;IACR,UAAU,EAAE,YAAY;IACxB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,YAAY;IACxB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,gBAAgB;IAChC,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,EAAE,EAAE,IAAI;IACR,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,EAAE,EAAE,IAAI;IACR,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;CACd,CAAA;AAKV,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;CACJ,CAAA;AAKV,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ,EAAE,QAAQ;CACV,CAAA;AAKV,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,aAAa;CAClB,CAAA;AAKV,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;CACJ,CAAA;AAKV,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,OAAO;CACR,CAAA"}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=models.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/generated/prisma/models.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=AdminUser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"AdminUser.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/AdminUser.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=AuditLog.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"AuditLog.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/AuditLog.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=Category.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Category.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/Category.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=ContactMessage.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ContactMessage.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/ContactMessage.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=Media.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Media.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/Media.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=Product.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Product.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/Product.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=ProductGroup.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ProductGroup.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/ProductGroup.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=ProductImage.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ProductImage.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/ProductImage.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=RefreshToken.js.map
@@ -0,0 +1 @@
{"version":3,"file":"RefreshToken.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/RefreshToken.ts"],"names":[],"mappings":""}
+2
View File
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=SiteSection.js.map
@@ -0,0 +1 @@
{"version":3,"file":"SiteSection.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/SiteSection.ts"],"names":[],"mappings":""}
+21
View File
@@ -0,0 +1,21 @@
import { env } from "./config/env.js";
import { NestFactory } from "@nestjs/core";
import cookieParser from "cookie-parser";
import helmet from "helmet";
import { AppModule } from "./app.module.js";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.set("trust proxy", env.TRUST_PROXY);
app.setGlobalPrefix("api");
app.use(helmet());
app.use(cookieParser());
const origins = env.CORS_ORIGINS.split(",")
.map((o) => o.trim())
.filter(Boolean);
if (origins.length)
app.enableCors({ origin: origins, credentials: true });
app.enableShutdownHooks();
await app.listen(env.PORT);
}
await bootstrap();
//# sourceMappingURL=main.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAM,CAAyB,SAAS,CAAC,CAAC;IAGxE,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IACxC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC3B,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAClB,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;IAExB,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;SACxC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,IAAI,OAAO,CAAC,MAAM;QAAE,GAAG,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3E,GAAG,CAAC,mBAAmB,EAAE,CAAC;IAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,SAAS,EAAE,CAAC"}
+95
View File
@@ -0,0 +1,95 @@
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { Body, Controller, Delete, Get, HttpCode, Module, Param, Patch, Post, Query, UploadedFile, UseInterceptors, } from "@nestjs/common";
import { FileInterceptor } from "@nestjs/platform-express";
import { mediaUpdateSchema } from "@imen/shared";
import { z } from "zod";
import { AdminAuth, CurrentUser, Roles } from "../common/auth.js";
import { IdPipe, ZodPipe } from "../common/zod.pipe.js";
import { MediaService } from "./media.service.js";
const listQuery = z.object({
page: z.coerce.number().int().min(1).default(1),
pageSize: z.coerce.number().int().min(1).max(100).default(40),
q: z.string().trim().max(100).optional(),
});
let MediaController = class MediaController {
media;
constructor(media) {
this.media = media;
}
list(q) {
return this.media.list(q.page, q.pageSize, q.q);
}
upload(file, alt, user) {
return this.media.upload(file, typeof alt === "string" ? alt : "", user.id);
}
update(id, body, user) {
return this.media.updateAlt(id, body.alt, user.id);
}
async remove(id, user) {
await this.media.remove(id, user.id);
}
};
__decorate([
Get(),
__param(0, Query(new ZodPipe(listQuery))),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], MediaController.prototype, "list", null);
__decorate([
Post(),
UseInterceptors(FileInterceptor("file", { limits: { fileSize: 15 * 1024 * 1024 } })),
__param(0, UploadedFile()),
__param(1, Body("alt")),
__param(2, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Object]),
__metadata("design:returntype", void 0)
], MediaController.prototype, "upload", null);
__decorate([
Patch(":id"),
__param(0, Param("id", IdPipe)),
__param(1, Body(new ZodPipe(mediaUpdateSchema))),
__param(2, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object, Object]),
__metadata("design:returntype", void 0)
], MediaController.prototype, "update", null);
__decorate([
Roles("ADMIN"),
Delete(":id"),
HttpCode(204),
__param(0, Param("id", IdPipe)),
__param(1, CurrentUser()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Object]),
__metadata("design:returntype", Promise)
], MediaController.prototype, "remove", null);
MediaController = __decorate([
AdminAuth(),
Controller("admin/media"),
__metadata("design:paramtypes", [MediaService])
], MediaController);
export { MediaController };
let MediaModule = class MediaModule {
};
MediaModule = __decorate([
Module({
controllers: [MediaController],
providers: [MediaService],
exports: [MediaService],
})
], MediaModule);
export { MediaModule };
//# sourceMappingURL=media.controller.js.map

Some files were not shown because too many files have changed in this diff Show More