build: include production build artifacts in repo
This commit is contained in:
+2
-2
@@ -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
@@ -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};
|
||||
@@ -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
@@ -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};
|
||||
@@ -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
@@ -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};
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
+6203
File diff suppressed because one or more lines are too long
@@ -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
@@ -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};
|
||||
+473
File diff suppressed because one or more lines are too long
+2
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
var e=`/logo.png`;export{e as t};
|
||||
+1
@@ -0,0 +1 @@
|
||||
var e=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,80);export{e as t};
|
||||
Vendored
+1
@@ -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 |
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Vendored
+15
@@ -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>
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 279 KiB |
Vendored
+69
@@ -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
|
||||
Vendored
+1
@@ -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
@@ -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
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"auth.controller.js","sourceRoot":"","sources":["../../src/auth/auth.controller.ts"],"names":[],"mappings":"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"}
|
||||
Vendored
+127
@@ -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
|
||||
+1
File diff suppressed because one or more lines are too long
+214
@@ -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
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"catalog.module.js","sourceRoot":"","sources":["../../src/catalog/catalog.module.ts"],"names":[],"mappings":"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"}
|
||||
+133
@@ -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
@@ -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
Vendored
+60
@@ -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
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/common/auth.ts"],"names":[],"mappings":"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"}
|
||||
+70
@@ -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
@@ -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
@@ -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
|
||||
@@ -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"}
|
||||
Vendored
+23
@@ -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
|
||||
Vendored
+1
@@ -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"}
|
||||
Vendored
+43
@@ -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
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"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"}
|
||||
+163
@@ -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
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"contact.module.js","sourceRoot":"","sources":["../../src/contact/contact.module.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EACL,IAAI,EACJ,UAAU,EACV,MAAM,EACN,GAAG,EACH,QAAQ,EACR,UAAU,EACV,MAAM,EACN,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,GAAG,GACJ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAEL,kBAAkB,EAElB,gBAAgB,EAEhB,mBAAmB,GAEpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAiB,WAAW,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE;IAC3C,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC9D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAiB,EAAqB,EAAE,CAAC,CAAC;IACrE,EAAE,EAAE,CAAC,CAAC,EAAE;IACR,IAAI,EAAE,CAAC,CAAC,IAAI;IACZ,GAAG,EAAE,CAAC,CAAC,GAAG;IACV,KAAK,EAAE,CAAC,CAAC,KAAK;IACd,OAAO,EAAE,CAAC,CAAC,OAAO;IAClB,MAAM,EAAE,CAAC,CAAC,MAAM;IAChB,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE;CACrC,CAAC,CAAC;AAGI,IAAM,cAAc,GAApB,MAAM,cAAc;IAEN;IACA;IAFnB,YACmB,MAAqB,EACrB,KAAmB;QADnB,WAAM,GAAN,MAAM,CAAe;QACrB,UAAK,GAAL,KAAK,CAAc;IACnC,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,KAAmB,EAAE,EAAU,EAAE,SAAiB;QAE7D,IAAI,KAAK,CAAC,OAAO;YAAE,OAAO;QAC1B,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC;YACtC,IAAI,EAAE;gBACJ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;gBACnB,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;aACnC;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAA6B;QACtC,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC;gBAClC,KAAK;gBACL,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;gBACvB,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ;gBAC/B,IAAI,EAAE,CAAC,CAAC,QAAQ;aACjB,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;SAC5C,CAAC,CAAC;QACH,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACvF,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,EAAU,EAAE,MAAqB;QAC/C,OAAO,YAAY,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IACpG,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,MAAc;QACrC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;CACF,CAAA;AA3CY,cAAc;IAD1B,UAAU,EAAE;qCAGgB,aAAa;QACd,YAAY;GAH3B,cAAc,CA2C1B;;AAGM,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IACL;IAA7B,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAKlD,AAAN,KAAK,CAAC,MAAM,CAAwC,IAAkB,EAAS,GAAY;QACzF,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;CACF,CAAA;AAJO;IAHL,IAAI,EAAE;IACN,QAAQ,CAAC,GAAG,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;IACxC,WAAA,IAAI,CAAC,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAA;IAAsB,WAAA,GAAG,EAAE,CAAA;;;;qDAG7E;AATU,uBAAuB;IADnC,UAAU,CAAC,gBAAgB,CAAC;qCAEW,cAAc;GADzC,uBAAuB,CAUnC;;AAIM,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IACA;IAA7B,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAGxD,IAAI,CAAgC,CAA6B;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAGD,MAAM,CACiB,EAAU,EACS,IAA0C;QAElF,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAKK,AAAN,KAAK,CAAC,MAAM,CAAsB,EAAU,EAAiB,IAAc;QACzE,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;CACF,CAAA;AAlBC;IADC,GAAG,EAAE;IACA,WAAA,KAAK,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;;;;8CAElC;AAGD;IADC,KAAK,CAAC,KAAK,CAAC;IAEV,WAAA,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACnB,WAAA,IAAI,CAAC,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAA;;;;gDAGxC;AAKK;IAHL,KAAK,CAAC,OAAO,CAAC;IACd,MAAM,CAAC,KAAK,CAAC;IACb,QAAQ,CAAC,GAAG,CAAC;IACA,WAAA,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAAc,WAAA,WAAW,EAAE,CAAA;;;;gDAE3D;AArBU,kBAAkB;IAF9B,SAAS,EAAE;IACX,UAAU,CAAC,gBAAgB,CAAC;qCAEW,cAAc;GADzC,kBAAkB,CAsB9B;;AAMM,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,aAAa;IAJzB,MAAM,CAAC;QACN,WAAW,EAAE,CAAC,uBAAuB,EAAE,kBAAkB,CAAC;QAC1D,SAAS,EAAE,CAAC,cAAc,CAAC;KAC5B,CAAC;GACW,aAAa,CAAG"}
|
||||
+116
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dashboard.module.js","sourceRoot":"","sources":["../../src/dashboard/dashboard.module.ts"],"names":[],"mappings":"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"}
|
||||
+5
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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"}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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":"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"}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=models.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/generated/prisma/models.ts"],"names":[],"mappings":""}
|
||||
@@ -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":""}
|
||||
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=AuditLog.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AuditLog.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/AuditLog.ts"],"names":[],"mappings":""}
|
||||
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=Category.js.map
|
||||
@@ -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":""}
|
||||
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=Media.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Media.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/Media.ts"],"names":[],"mappings":""}
|
||||
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=Product.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Product.js","sourceRoot":"","sources":["../../../../src/generated/prisma/models/Product.ts"],"names":[],"mappings":""}
|
||||
@@ -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":""}
|
||||
@@ -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":""}
|
||||
@@ -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":""}
|
||||
@@ -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":""}
|
||||
Vendored
+21
@@ -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
|
||||
Vendored
+1
@@ -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
@@ -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
Reference in New Issue
Block a user