Fix for production
This commit is contained in:
+11
-4
@@ -1,11 +1,10 @@
|
||||
node_modules
|
||||
**/node_modules
|
||||
dist
|
||||
**/dist
|
||||
.git
|
||||
.idea
|
||||
.vscode
|
||||
.env
|
||||
.env.local
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
@@ -13,5 +12,13 @@ yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
.npm
|
||||
.pnpm-store
|
||||
Dockerfile*
|
||||
docker-compose*.yml
|
||||
coverage
|
||||
uploads
|
||||
docs
|
||||
iranSans
|
||||
apps/api/src
|
||||
apps/api/dist
|
||||
apps/api/test
|
||||
apps/admin/src
|
||||
apps/client/src
|
||||
packages
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# کپی به env سرویس API در Dokploy (یا فایل .env کنار compose)
|
||||
# دامنهها:
|
||||
# wheel.montzar.ir → سرویس client
|
||||
# api.wheel.montzar.ir → سرویس api
|
||||
# adm.wheel.montzar.ir → سرویس admin
|
||||
|
||||
POSTGRES_DB=lucky_wheel
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD
|
||||
# پورت خارجی برای اتصال از بیرون (مثلاً DBeaver) — داخل شبکه همچنان 5432 است
|
||||
EXPORT_DB_PORT=5432
|
||||
|
||||
# داخل شبکه compose هاست postgres است (نه localhost)
|
||||
DATABASE_URL=postgresql://postgres:CHANGE_ME_STRONG_PASSWORD@postgres:5432/lucky_wheel?schema=public
|
||||
|
||||
REDIS_PASSWORD=
|
||||
|
||||
JWT_USER_SECRET=CHANGE_ME_USER_JWT
|
||||
JWT_USER_EXPIRES_IN=7d
|
||||
JWT_ADMIN_ACCESS_SECRET=CHANGE_ME_ADMIN_ACCESS_JWT
|
||||
JWT_ADMIN_ACCESS_EXPIRES_IN=1h
|
||||
JWT_ADMIN_REFRESH_SECRET=CHANGE_ME_ADMIN_REFRESH_JWT
|
||||
JWT_ADMIN_REFRESH_EXPIRES_IN=7d
|
||||
|
||||
CORS_ADMIN_ORIGIN=https://adm.wheel.montzar.ir
|
||||
CORS_CLIENT_ORIGIN=https://wheel.montzar.ir
|
||||
|
||||
STORAGE_DRIVER=local
|
||||
STORAGE_LOCAL_ROOT=./uploads
|
||||
STORAGE_PUBLIC_URL=https://api.wheel.montzar.ir/uploads
|
||||
|
||||
SMS_DRIVER=mock
|
||||
RAYGAN_SMS_USERNAME=
|
||||
RAYGAN_SMS_PASSWORD=
|
||||
RAYGAN_SMS_LINE_NUMBER=
|
||||
RAYGAN_SMS_API_BASE_URL=https://api.raygansms.com
|
||||
+9
-1
@@ -1,5 +1,8 @@
|
||||
node_modules/
|
||||
dist/
|
||||
# بیلد میانی Nest — فقط release/ روی گیت میرود
|
||||
apps/api/dist/
|
||||
apps/api/release/node_modules/
|
||||
packages/shared-types/dist/
|
||||
build/
|
||||
.env
|
||||
.env.local
|
||||
@@ -8,3 +11,8 @@ uploads/
|
||||
coverage/
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# فرانت و API release برای Dokploy (کپیonly) باید commit شوند:
|
||||
# apps/admin/dist/**
|
||||
# apps/client/dist/**
|
||||
# apps/api/release/** (بدون node_modules)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
VITE_API_BASE_URL=https://api.wheel.montzar.ir/api
|
||||
+5
-25
@@ -1,30 +1,10 @@
|
||||
FROM node:20-alpine AS builder
|
||||
FROM docker.arvancloud.ir/nginx:latest
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable pnpm
|
||||
# بیلد لوکال: pnpm --filter @lucky-wheel/admin build
|
||||
# (با apps/admin/.env.production)
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN pnpm install --frozen-lockfile
|
||||
RUN pnpm --filter @lucky-wheel/admin build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /app/apps/admin/dist /usr/share/nginx/html
|
||||
|
||||
# Configure Nginx for Single Page Application
|
||||
RUN echo 'server { \
|
||||
listen 80; \
|
||||
server_name localhost; \
|
||||
location / { \
|
||||
root /usr/share/nginx/html; \
|
||||
index index.html index.htm; \
|
||||
try_files $uri $uri/ /index.html; \
|
||||
} \
|
||||
}' > /etc/nginx/conf.d/default.conf
|
||||
COPY apps/admin/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY apps/admin/dist /usr/share/nginx/html
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
.page-header-title[data-v-ec85b8e1]{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}.page-header-title .title[data-v-ec85b8e1]{font-size:20px;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.3px}.page-header-title .subtitle[data-v-ec85b8e1]{font-size:13px;color:#64748b;margin:4px 0 0}.main-card[data-v-ec85b8e1]{border-radius:12px;box-shadow:0 1px 3px #0000000a;border:1px solid #f1f5f9}.table-header[data-v-ec85b8e1]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.filters[data-v-ec85b8e1]{display:flex;gap:12px}.admin-name[data-v-ec85b8e1]{font-weight:500;color:#1e293b}.code-badge[data-v-ec85b8e1]{background:#f8fafc;border:1px solid #e2e8f0;padding:2px 6px;border-radius:4px;font-family:monospace;font-size:11px;color:#64748b}.date-cell[data-v-ec85b8e1]{color:#334155;font-size:13px}.text-muted[data-v-ec85b8e1]{color:#94a3b8;font-size:12px}.action-more-btn[data-v-ec85b8e1]{color:#64748b;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;transition:all .2s ease}.action-more-btn[data-v-ec85b8e1]:hover{background-color:#eef2ff!important}.json-box[data-v-ec85b8e1]{background:#0f172a;color:#38bdf8;padding:14px;border-radius:8px;font-family:monospace;font-size:12px;max-height:240px;overflow-y:auto;direction:ltr;text-align:left;border:1px solid #1e293b}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.wheel-picker-grid[data-v-31298959]{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px;margin-top:10px}.design-card[data-v-31298959]{border:2px solid #e2e8f0;border-radius:12px;overflow:hidden;cursor:pointer;transition:all .25s ease;background:#fff;display:flex;flex-direction:column}.design-card[data-v-31298959]:hover{border-color:#1677ff;transform:translateY(-3px);box-shadow:0 8px 20px #0000001a}.design-card.is-selected[data-v-31298959]{border-color:#1677ff;box-shadow:0 0 0 2px #1677ff40}.preview-stage[data-v-31298959]{height:140px;position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden;border-bottom:1px solid rgba(0,0,0,.08)}.theme-tag[data-v-31298959]{position:absolute;top:10px;right:10px;z-index:10;margin:0;font-weight:600}.stage-tools[data-v-31298959]{position:absolute;bottom:8px;left:8px;display:flex;gap:6px;z-index:10}.tool-btn[data-v-31298959]{background:#ffffffd9;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border:none;box-shadow:0 2px 6px #00000026}.tool-btn[data-v-31298959]:hover{background:#fff;color:#1677ff}.wheel-wrapper[data-v-31298959]{position:relative;width:96px;height:96px;display:flex;align-items:center;justify-content:center}.pointer-wrapper[data-v-31298959]{position:absolute;top:-8px;left:50%;transform:translate(-50%);z-index:20;filter:drop-shadow(0 2px 4px rgba(0,0,0,.4))}.mini-wheel-svg[data-v-31298959]{width:100%;height:100%;border-radius:50%;filter:drop-shadow(0 4px 10px rgba(0,0,0,.3))}.card-body[data-v-31298959]{padding:14px 16px;flex:1;display:flex;flex-direction:column}.card-title-row[data-v-31298959]{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}.title-text[data-v-31298959]{font-weight:700;font-size:13.5px;color:#1e293b}.selected-icon[data-v-31298959]{color:#1677ff;font-size:18px}.card-desc[data-v-31298959]{font-size:11.5px;color:#64748b;line-height:1.6;margin:0}.modal-preview-container[data-v-31298959]{padding:30px 20px;border-radius:12px;display:flex;flex-direction:column;align-items:center}.modal-wheel-box[data-v-31298959]{position:relative;width:240px;height:240px}.large-pointer[data-v-31298959]{position:absolute;top:-12px;left:50%;transform:translate(-50%);z-index:20;filter:drop-shadow(0 3px 6px rgba(0,0,0,.5))}.large-wheel-svg[data-v-31298959]{width:100%;height:100%;border-radius:50%;filter:drop-shadow(0 8px 24px rgba(0,0,0,.4))}.submit-btn[data-v-c11ffb22]{font-weight:600;border-radius:8px}
|
||||
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 @@
|
||||
.page-header-title[data-v-d90ae09e]{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}.page-header-title .title[data-v-d90ae09e]{font-size:20px;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.3px}.page-header-title .subtitle[data-v-d90ae09e]{font-size:13px;color:#64748b;margin:4px 0 0}.create-btn[data-v-d90ae09e]{font-weight:600;border-radius:8px;box-shadow:0 2px 4px #4f46e533}.main-card[data-v-d90ae09e]{border-radius:12px;box-shadow:0 1px 3px #0000000a;border:1px solid #f1f5f9}.table-header[data-v-d90ae09e]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;flex-wrap:wrap;gap:12px}.filters[data-v-d90ae09e]{display:flex;gap:12px}.campaign-title[data-v-d90ae09e]{font-weight:600;color:#1e293b;cursor:pointer;transition:color .15s ease}.campaign-title[data-v-d90ae09e]:hover{color:#4f46e5}.slug-badge[data-v-d90ae09e]{background:#f8fafc;border:1px solid #e2e8f0;padding:2px 8px;border-radius:6px;color:#475569;font-size:12px;font-family:monospace}.date-cell[data-v-d90ae09e],.num-cell[data-v-d90ae09e]{color:#334155;font-size:13px}.status-tag[data-v-d90ae09e]{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:20px;font-weight:500}.status-dot[data-v-d90ae09e]{width:6px;height:6px;border-radius:50%;display:inline-block}.action-more-btn[data-v-d90ae09e]{color:#64748b;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;transition:all .2s ease}.action-more-btn[data-v-d90ae09e]:hover{color:#4f46e5!important;background-color:#eef2ff!important}.dropdown-action-item[data-v-d90ae09e]{display:flex;align-items:center;gap:8px;color:#334155;text-decoration:none;font-size:13px}.dropdown-item-icon[data-v-d90ae09e]{font-size:14px}.text-success[data-v-d90ae09e]{color:#10b981}.text-warning[data-v-d90ae09e]{color:#f59e0b}
|
||||
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{c as f,I as u}from"./index-Dx9ODHpC.js";var l={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M880 310H732.4c13.6-21.4 21.6-46.8 21.6-74 0-76.1-61.9-138-138-138-41.4 0-78.7 18.4-104 47.4-25.3-29-62.6-47.4-104-47.4-76.1 0-138 61.9-138 138 0 27.2 7.9 52.6 21.6 74H144c-17.7 0-32 14.3-32 32v200c0 4.4 3.6 8 8 8h40v344c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V550h40c4.4 0 8-3.6 8-8V342c0-17.7-14.3-32-32-32zm-334-74c0-38.6 31.4-70 70-70s70 31.4 70 70-31.4 70-70 70h-70v-70zm-138-70c38.6 0 70 31.4 70 70v70h-70c-38.6 0-70-31.4-70-70s31.4-70 70-70zM180 482V378h298v104H180zm48 68h250v308H228V550zm568 308H546V550h250v308zm48-376H546V378h298v104z"}}]},name:"gift",theme:"outlined"};function a(r){for(var t=1;t<arguments.length;t++){var e=arguments[t]!=null?Object(arguments[t]):{},n=Object.keys(e);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(e).filter(function(c){return Object.getOwnPropertyDescriptor(e,c).enumerable}))),n.forEach(function(c){o(r,c,e[c])})}return r}function o(r,t,e){return t in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e,r}var i=function(t,e){var n=a({},t,e.attrs);return f(u,a({},n,{icon:l}),null)};i.displayName="GiftOutlined";i.inheritAttrs=!1;export{i as G};
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
import{c as i,I as l}from"./index-Dx9ODHpC.js";var u={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 10-56 0z"}}]},name:"lock",theme:"outlined"};function a(r){for(var t=1;t<arguments.length;t++){var e=arguments[t]!=null?Object(arguments[t]):{},n=Object.keys(e);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(e).filter(function(c){return Object.getOwnPropertyDescriptor(e,c).enumerable}))),n.forEach(function(c){f(r,c,e[c])})}return r}function f(r,t,e){return t in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e,r}var o=function(t,e){var n=a({},t,e.attrs);return i(l,a({},n,{icon:u}),null)};o.displayName="LockOutlined";o.inheritAttrs=!1;export{o as L};
|
||||
@@ -0,0 +1 @@
|
||||
.login-container[data-v-20e1793e]{min-height:100vh;display:flex;align-items:center;justify-content:center;background:radial-gradient(circle at 50% 20%,#1e1b4b,#0f172a 70%,#020617);padding:24px;position:relative;overflow:hidden}.login-bg-decorations[data-v-20e1793e]{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;overflow:hidden}.decor-circle[data-v-20e1793e]{position:absolute;border-radius:50%;filter:blur(80px);opacity:.15}.circle-1[data-v-20e1793e]{width:400px;height:400px;background:#6366f1;top:10%;left:20%}.circle-2[data-v-20e1793e]{width:350px;height:350px;background:#a855f7;bottom:10%;right:20%}.login-card[data-v-20e1793e]{width:100%;max-width:420px;background:#fff;border-radius:16px;padding:40px 36px;box-shadow:0 25px 50px -12px #00000073,0 0 0 1px #ffffff1a;position:relative;z-index:1}.header[data-v-20e1793e]{text-align:center;margin-bottom:32px}.logo-wrapper[data-v-20e1793e]{width:68px;height:68px;margin:0 auto 16px;background:#eef2ff;border-radius:16px;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12px #4f46e51f}.logo[data-v-20e1793e]{font-size:34px;line-height:1}h1[data-v-20e1793e]{font-size:20px;font-weight:700;margin:0;color:#0f172a;letter-spacing:-.3px}p[data-v-20e1793e]{font-size:13px;color:#64748b;margin-top:6px;margin-bottom:0}.login-submit-btn[data-v-20e1793e]{height:44px;font-size:15px;font-weight:600;border-radius:8px;background:#4f46e5;box-shadow:0 4px 14px #4f46e559;transition:all .2s ease}.login-submit-btn[data-v-20e1793e]:hover{background:#4338ca!important;box-shadow:0 6px 18px #4f46e573}
|
||||
@@ -0,0 +1 @@
|
||||
import{c as l,I as h,d as O,u as x,a as V,b as n,w as i,r as c,o as S,e as p,f as z,g as L,h as M,i as P,_ as j}from"./index-Dx9ODHpC.js";import{L as B}from"./LockOutlined-ihCI0sD8.js";var N={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"}}]},name:"mail",theme:"outlined"};function f(r){for(var a=1;a<arguments.length;a++){var t=arguments[a]!=null?Object(arguments[a]):{},e=Object.keys(t);typeof Object.getOwnPropertySymbols=="function"&&(e=e.concat(Object.getOwnPropertySymbols(t).filter(function(s){return Object.getOwnPropertyDescriptor(t,s).enumerable}))),e.forEach(function(s){k(r,s,t[s])})}return r}function k(r,a,t){return a in r?Object.defineProperty(r,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[a]=t,r}var m=function(a,t){var e=f({},a,t.attrs);return l(h,f({},e,{icon:N}),null)};m.displayName="MailOutlined";m.inheritAttrs=!1;const A={class:"login-container"},C={class:"login-card"},I=O({__name:"LoginView",setup(r){const a=P(),t=x(),e=L({email:"admin@luckywheel.local",password:"Admin@SecurePass2026"}),s=M(!1);async function _(){s.value=!0;try{await t.login({email:e.email,password:e.password}),a.push("/dashboard")}catch{}finally{s.value=!1}}return(g,o)=>{const v=c("a-input"),u=c("a-form-item"),b=c("a-input-password"),w=c("a-button"),y=c("a-form");return S(),V("div",A,[o[4]||(o[4]=n("div",{class:"login-bg-decorations"},[n("div",{class:"decor-circle circle-1"}),n("div",{class:"decor-circle circle-2"})],-1)),n("div",C,[o[3]||(o[3]=n("div",{class:"header"},[n("div",{class:"logo-wrapper"},[n("span",{class:"logo"},"🎡")]),n("h1",null,"ورود به پنل مدیریت"),n("p",null,"سامانه گردونه شانس و قرعهکشی")],-1)),l(y,{model:e,layout:"vertical",onFinish:_},{default:i(()=>[l(u,{label:"ایمیل مدیریت",name:"email",rules:[{required:!0,message:"لطفاً ایمیل را وارد کنید"},{type:"email",message:"فرمت ایمیل نامعتبر است"}]},{default:i(()=>[l(v,{value:e.email,"onUpdate:value":o[0]||(o[0]=d=>e.email=d),size:"large",placeholder:"admin@example.com"},{prefix:i(()=>[l(p(m),{style:{color:"#6366f1"}})]),_:1},8,["value"])]),_:1}),l(u,{label:"کلمه عبور",name:"password",rules:[{required:!0,message:"لطفاً کلمه عبور را وارد کنید"}]},{default:i(()=>[l(b,{value:e.password,"onUpdate:value":o[1]||(o[1]=d=>e.password=d),size:"large",placeholder:"••••••••"},{prefix:i(()=>[l(p(B),{style:{color:"#6366f1"}})]),_:1},8,["value"])]),_:1}),l(u,{style:{"margin-top":"28px"}},{default:i(()=>[l(w,{type:"primary","html-type":"submit",size:"large",block:"",loading:s.value,class:"login-submit-btn"},{default:i(()=>[...o[2]||(o[2]=[z(" ورود به پنل ",-1)])]),_:1},8,["loading"])]),_:1})]),_:1},8,["model"])])])}}}),H=j(I,[["__scopeId","data-v-20e1793e"]]);export{H as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{c as u,I as l}from"./index-Dx9ODHpC.js";var c={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M456 231a56 56 0 10112 0 56 56 0 10-112 0zm0 280a56 56 0 10112 0 56 56 0 10-112 0zm0 280a56 56 0 10112 0 56 56 0 10-112 0z"}}]},name:"more",theme:"outlined"};function o(r){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?Object(arguments[e]):{},n=Object.keys(t);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(t).filter(function(a){return Object.getOwnPropertyDescriptor(t,a).enumerable}))),n.forEach(function(a){f(r,a,t[a])})}return r}function f(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var i=function(e,t){var n=o({},e,t.attrs);return u(l,o({},n,{icon:c}),null)};i.displayName="MoreOutlined";i.inheritAttrs=!1;export{i as M};
|
||||
@@ -0,0 +1 @@
|
||||
import{c as u,I as l}from"./index-Dx9ODHpC.js";var o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372zm-88-532h-48c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8zm224 0h-48c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8z"}}]},name:"pause-circle",theme:"outlined"};function a(r){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?Object(arguments[e]):{},n=Object.keys(t);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(t).filter(function(c){return Object.getOwnPropertyDescriptor(t,c).enumerable}))),n.forEach(function(c){s(r,c,t[c])})}return r}function s(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var i=function(e,t){var n=a({},e,t.attrs);return u(l,a({},n,{icon:o}),null)};i.displayName="PauseCircleOutlined";i.inheritAttrs=!1;export{i as P};
|
||||
@@ -0,0 +1 @@
|
||||
import{c as i,I as u}from"./index-Dx9ODHpC.js";var s={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M696 480H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8z"}},{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"}}]},name:"plus-circle",theme:"outlined"};function a(r){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?Object(arguments[e]):{},n=Object.keys(t);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(t).filter(function(c){return Object.getOwnPropertyDescriptor(t,c).enumerable}))),n.forEach(function(c){o(r,c,t[c])})}return r}function o(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var l=function(e,t){var n=a({},e,t.attrs);return i(u,a({},n,{icon:s}),null)};l.displayName="PlusCircleOutlined";l.inheritAttrs=!1;export{l as P};
|
||||
@@ -0,0 +1 @@
|
||||
.action-more-btn[data-v-b0ebd2d6]{color:#64748b;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;transition:all .2s ease}.action-more-btn[data-v-b0ebd2d6]:hover{color:#4f46e5!important;background-color:#eef2ff!important}.dropdown-action-item[data-v-b0ebd2d6]{display:flex;align-items:center;gap:8px;color:#334155;text-decoration:none;font-size:13px}.dropdown-item-icon[data-v-b0ebd2d6]{font-size:14px}.text-danger[data-v-b0ebd2d6]{color:#ef4444}.prize-modal-form[data-v-b0ebd2d6] .ant-form-item{margin-bottom:12px}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.page-header-title[data-v-ee1ef293]{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}.page-header-title .title[data-v-ee1ef293]{font-size:20px;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.3px}.page-header-title .subtitle[data-v-ee1ef293]{font-size:13px;color:#64748b;margin:4px 0 0}.main-card[data-v-ee1ef293]{border-radius:12px;box-shadow:0 1px 3px #0000000a;border:1px solid #f1f5f9}.kpi-card[data-v-ee1ef293]{border-radius:12px;box-shadow:0 1px 3px #0000000a;border:1px solid #f1f5f9;transition:all .25s ease}.kpi-card[data-v-ee1ef293]:hover{transform:translateY(-2px);box-shadow:0 6px 16px #00000012}.kpi-flex[data-v-ee1ef293]{display:flex;align-items:center;gap:16px}.kpi-icon-box[data-v-ee1ef293]{width:52px;height:52px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:24px;flex-shrink:0}.icon-indigo[data-v-ee1ef293]{background:#eef2ff;color:#4f46e5}.icon-sky[data-v-ee1ef293]{background:#f0f9ff;color:#0284c7}.icon-emerald[data-v-ee1ef293]{background:#ecfdf5;color:#059669}.icon-purple[data-v-ee1ef293]{background:#faf5ff;color:#9333ea}.icon-amber[data-v-ee1ef293]{background:#fffbeb;color:#d97706}.icon-rose[data-v-ee1ef293]{background:#fff1f2;color:#e11d48}.icon-teal[data-v-ee1ef293]{background:#f0fdfa;color:#0d9488}.kpi-details[data-v-ee1ef293]{display:flex;flex-direction:column}.kpi-label[data-v-ee1ef293]{font-size:13px;color:#64748b;font-weight:500}.kpi-value[data-v-ee1ef293]{font-size:22px;font-weight:700;color:#0f172a;line-height:1.2;margin:2px 0 0}.filters-header[data-v-ee1ef293]{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px}.filters[data-v-ee1ef293]{display:flex;gap:12px}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.page-header-title[data-v-1ae7a208]{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}.page-header-title .title[data-v-1ae7a208]{font-size:20px;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.3px}.page-header-title .subtitle[data-v-1ae7a208]{font-size:13px;color:#64748b;margin:4px 0 0}.main-card[data-v-1ae7a208]{border-radius:12px;box-shadow:0 1px 3px #0000000a;border:1px solid #f1f5f9}.table-header[data-v-1ae7a208]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.filters[data-v-1ae7a208]{display:flex;gap:12px}.code-badge[data-v-1ae7a208]{background:#f8fafc;border:1px solid #e2e8f0;padding:2px 6px;border-radius:4px;font-family:monospace;font-size:11px;color:#64748b}.num-cell[data-v-1ae7a208],.date-cell[data-v-1ae7a208]{color:#334155;font-size:13px}.text-danger[data-v-1ae7a208]{color:#ef4444;font-size:12px}.text-muted[data-v-1ae7a208]{color:#94a3b8}.status-tag[data-v-1ae7a208]{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:20px;font-weight:500}.status-dot[data-v-1ae7a208]{width:6px;height:6px;border-radius:50%;display:inline-block}.action-more-btn[data-v-1ae7a208]{color:#64748b;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;transition:all .2s ease}.action-more-btn[data-v-1ae7a208]:hover{background-color:#eef2ff!important}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.page-header-title[data-v-aaf12675]{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}.page-header-title .title[data-v-aaf12675]{font-size:20px;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.3px}.page-header-title .subtitle[data-v-aaf12675]{font-size:13px;color:#64748b;margin:4px 0 0}.main-card[data-v-aaf12675]{border-radius:12px;box-shadow:0 1px 3px #0000000a;border:1px solid #f1f5f9}.table-header[data-v-aaf12675]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;flex-wrap:wrap;gap:12px}.filters[data-v-aaf12675]{display:flex;gap:12px}.mobile-cell[data-v-aaf12675]{font-weight:600;color:#1e293b}.user-mobile-link[data-v-aaf12675]{cursor:pointer;transition:color .15s ease}.user-mobile-link[data-v-aaf12675]:hover{color:#4f46e5}.user-name[data-v-aaf12675],.prize-text[data-v-aaf12675]{font-weight:500;color:#1e293b}.code-badge[data-v-aaf12675]{background:#f8fafc;border:1px solid #e2e8f0;padding:2px 6px;border-radius:4px;font-family:monospace;font-size:11px;color:#64748b}.num-cell[data-v-aaf12675],.date-cell[data-v-aaf12675]{color:#334155;font-size:13px}.text-muted[data-v-aaf12675]{color:#94a3b8}.status-tag[data-v-aaf12675]{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:20px;font-weight:500}.status-dot[data-v-aaf12675]{width:6px;height:6px;border-radius:50%;display:inline-block}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{c as u,I as l}from"./index-Dx9ODHpC.js";var o={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M824.2 699.9a301.55 301.55 0 00-86.4-60.4C783.1 602.8 812 546.8 812 484c0-110.8-92.4-201.7-203.2-200-109.1 1.7-197 90.6-197 200 0 62.8 29 118.8 74.2 155.5a300.95 300.95 0 00-86.4 60.4C345 754.6 314 826.8 312 903.8a8 8 0 008 8.2h56c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5A226.62 226.62 0 01612 684c60.9 0 118.2 23.7 161.3 66.8C814.5 792 838 846.3 840 904.3c.1 4.3 3.7 7.7 8 7.7h56a8 8 0 008-8.2c-2-77-33-149.2-87.8-203.9zM612 612c-34.2 0-66.4-13.3-90.5-37.5a126.86 126.86 0 01-37.5-91.8c.3-32.8 13.4-64.5 36.3-88 24-24.6 56.1-38.3 90.4-38.7 33.9-.3 66.8 12.9 91 36.6 24.8 24.3 38.4 56.8 38.4 91.4 0 34.2-13.3 66.3-37.5 90.5A127.3 127.3 0 01612 612zM361.5 510.4c-.9-8.7-1.4-17.5-1.4-26.4 0-15.9 1.5-31.4 4.3-46.5.7-3.6-1.2-7.3-4.5-8.8-13.6-6.1-26.1-14.5-36.9-25.1a127.54 127.54 0 01-38.7-95.4c.9-32.1 13.8-62.6 36.3-85.6 24.7-25.3 57.9-39.1 93.2-38.7 31.9.3 62.7 12.6 86 34.4 7.9 7.4 14.7 15.6 20.4 24.4 2 3.1 5.9 4.4 9.3 3.2 17.6-6.1 36.2-10.4 55.3-12.4 5.6-.6 8.8-6.6 6.3-11.6-32.5-64.3-98.9-108.7-175.7-109.9-110.9-1.7-203.3 89.2-203.3 199.9 0 62.8 28.9 118.8 74.2 155.5-31.8 14.7-61.1 35-86.5 60.4-54.8 54.7-85.8 126.9-87.8 204a8 8 0 008 8.2h56.1c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5 29.4-29.4 65.4-49.8 104.7-59.7 3.9-1 6.5-4.7 6-8.7z"}}]},name:"team",theme:"outlined"};function c(r){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?Object(arguments[e]):{},a=Object.keys(t);typeof Object.getOwnPropertySymbols=="function"&&(a=a.concat(Object.getOwnPropertySymbols(t).filter(function(n){return Object.getOwnPropertyDescriptor(t,n).enumerable}))),a.forEach(function(n){f(r,n,t[n])})}return r}function f(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var i=function(e,t){var a=c({},e,t.attrs);return u(l,c({},a,{icon:o}),null)};i.displayName="TeamOutlined";i.inheritAttrs=!1;export{i as T};
|
||||
@@ -0,0 +1 @@
|
||||
import{c as o,I as i}from"./index-Dx9ODHpC.js";var u={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M400 317.7h73.9V656c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V317.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 163a8 8 0 00-12.6 0l-112 141.7c-4.1 5.3-.4 13 6.3 13zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"}}]},name:"upload",theme:"outlined"};function c(r){for(var t=1;t<arguments.length;t++){var e=arguments[t]!=null?Object(arguments[t]):{},n=Object.keys(e);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(e).filter(function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.forEach(function(a){f(r,a,e[a])})}return r}function f(r,t,e){return t in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e,r}var l=function(t,e){var n=c({},t,e.attrs);return o(i,c({},n,{icon:u}),null)};l.displayName="UploadOutlined";l.inheritAttrs=!1;export{l as U};
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.detail-header[data-v-331e5087]{background:#fff;margin-bottom:20px;border-radius:12px;padding:16px 24px;border:1px solid #f1f5f9;box-shadow:0 1px 3px #0000000a}.section-card[data-v-331e5087]{border-radius:12px;border:1px solid #f1f5f9;box-shadow:0 1px 3px #0000000a}.detail-tabs[data-v-331e5087]{background:#fff;padding:16px;border-radius:12px;border:1px solid #f1f5f9;box-shadow:0 1px 3px #0000000a}.code-badge[data-v-331e5087]{background:#f1f5f9;padding:2px 6px;border-radius:4px;font-family:monospace;font-size:12px;color:#334155}.num-cell[data-v-331e5087],.date-cell[data-v-331e5087]{color:#334155;font-size:13px}.action-text-btn[data-v-331e5087]{color:#4f46e5!important;font-size:12px;font-weight:500;border-radius:6px;transition:all .2s ease}.action-text-btn[data-v-331e5087]:hover{background-color:#eef2ff!important}.text-muted[data-v-331e5087]{color:#cbd5e1}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.page-header-title[data-v-fd1c9633]{margin-bottom:20px}.page-header-title .title[data-v-fd1c9633]{font-size:20px;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.3px}.page-header-title .subtitle[data-v-fd1c9633]{font-size:13px;color:#64748b;margin:4px 0 0}.main-card[data-v-fd1c9633]{border-radius:12px;box-shadow:0 1px 3px #0000000a;border:1px solid #f1f5f9}.table-header[data-v-fd1c9633]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.filters[data-v-fd1c9633]{display:flex;gap:12px}.user-mobile-link[data-v-fd1c9633]{font-weight:600;color:#1e293b;cursor:pointer;transition:color .15s ease}.user-mobile-link[data-v-fd1c9633]:hover{color:#4f46e5}.user-name[data-v-fd1c9633]{font-weight:500;color:#334155}.num-cell[data-v-fd1c9633],.date-cell[data-v-fd1c9633]{color:#334155;font-size:13px}.status-tag[data-v-fd1c9633]{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:20px;font-weight:500}.status-dot[data-v-fd1c9633]{width:6px;height:6px;border-radius:50%;display:inline-block}.action-more-btn[data-v-fd1c9633]{color:#64748b;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;transition:all .2s ease}.action-more-btn[data-v-fd1c9633]:hover{color:#4f46e5!important;background-color:#eef2ff!important}.dropdown-action-item[data-v-fd1c9633]{display:flex;align-items:center;gap:8px;color:#334155;text-decoration:none;font-size:13px}.dropdown-item-icon[data-v-fd1c9633]{font-size:14px}.text-success[data-v-fd1c9633]{color:#10b981}.text-danger[data-v-fd1c9633]{color:#ef4444}
|
||||
@@ -0,0 +1 @@
|
||||
.page-header-title[data-v-b623e0ea]{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}.page-header-title .title[data-v-b623e0ea]{font-size:20px;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.3px}.page-header-title .subtitle[data-v-b623e0ea]{font-size:13px;color:#64748b;margin:4px 0 0}.main-card[data-v-b623e0ea]{border-radius:12px;box-shadow:0 1px 3px #0000000a;border:1px solid #f1f5f9}.table-header[data-v-b623e0ea]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;flex-wrap:wrap;gap:12px}.filters[data-v-b623e0ea]{display:flex;gap:12px}.mobile-cell[data-v-b623e0ea]{font-weight:600;color:#1e293b}.user-link[data-v-b623e0ea]{cursor:pointer;transition:color .15s ease}.user-link[data-v-b623e0ea]:hover{color:#4f46e5}.user-name[data-v-b623e0ea]{font-weight:500;color:#334155}.campaign-cell[data-v-b623e0ea]{color:#475569}.prize-text[data-v-b623e0ea]{font-weight:600;color:#1e293b}.code-badge[data-v-b623e0ea]{background:#f8fafc;border:1px solid #e2e8f0;padding:2px 6px;border-radius:4px;font-family:monospace;font-size:12px;color:#475569}.clickable-code[data-v-b623e0ea]{cursor:pointer;transition:all .15s ease}.clickable-code[data-v-b623e0ea]:hover{background:#eef2ff;border-color:#c7d2fe;color:#4f46e5}.date-cell[data-v-b623e0ea]{color:#334155;font-size:13px}.text-muted[data-v-b623e0ea]{color:#94a3b8}.status-tag[data-v-b623e0ea]{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:20px;font-weight:500}.status-dot[data-v-b623e0ea]{width:6px;height:6px;border-radius:50%;display:inline-block}.action-more-btn[data-v-b623e0ea]{color:#64748b;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;transition:all .2s ease}.action-more-btn[data-v-b623e0ea]:hover{color:#4f46e5!important;background-color:#eef2ff!important}.dropdown-action-item[data-v-b623e0ea]{display:flex;align-items:center;gap:8px;color:#334155;text-decoration:none;font-size:13px}.dropdown-item-icon[data-v-b623e0ea]{font-size:14px}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
const i=["۰","۱","۲","۳","۴","۵","۶","۷","۸","۹"];function o(r){return r==null||typeof r=="object"&&r!==null&&"value"in r&&(r=r.value,r==null)||typeof r=="object"?"":String(r).replace(/[0-9]/g,t=>i[+t]).replace(/[٠-٩]/g,t=>i[t.charCodeAt(0)-1632])}function f(r){if(r==null||r===""||typeof r=="object"&&r!==null&&"value"in r&&(r=r.value,r==null||r==="")||typeof r=="object")return"";const t=typeof r=="string"?parseFloat(u(r)):r;if(isNaN(t))return o(r);const e=new Intl.NumberFormat("fa-IR").format(t);return o(e)}function u(r){return r==null?"":String(r).replace(/[۰-۹]/g,t=>String(t.charCodeAt(0)-1776)).replace(/[٠-٩]/g,t=>String(t.charCodeAt(0)-1632))}function s(r,t=0){if(r==null||r==="")return t;if(typeof r=="number")return isNaN(r)?t:r;const e=u(r).replace(/[^0-9.-]/g,""),n=Number(e);return isNaN(n)?t:n}export{u as a,f,s as p,o as t};
|
||||
+1
File diff suppressed because one or more lines are too long
+515
File diff suppressed because one or more lines are too long
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fa" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>پنل مدیریت گردونه شانس و قرعهکشی</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
font-family: 'Vazirmatn', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #f0f2f5;
|
||||
direction: rtl;
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/index-Dx9ODHpC.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-C1RGR6WN.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>␍
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,10 @@ declare module 'axios' {
|
||||
}
|
||||
}
|
||||
|
||||
const apiBaseURL = import.meta.env.VITE_API_BASE_URL || '/api';
|
||||
|
||||
export const apiClient = axios.create({
|
||||
baseURL: '/api',
|
||||
baseURL: apiBaseURL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
@@ -96,7 +98,7 @@ apiClient.interceptors.response.use(
|
||||
}
|
||||
|
||||
try {
|
||||
const { data } = await axios.post('/api/admin/auth/refresh', { refreshToken });
|
||||
const { data } = await axios.post(`${apiBaseURL}/admin/auth/refresh`, { refreshToken });
|
||||
const newToken = data.data?.accessToken || data.accessToken;
|
||||
localStorage.setItem('admin_access_token', newToken);
|
||||
apiClient.defaults.headers.common.Authorization = `Bearer ${newToken}`;
|
||||
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_BASE_URL?: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
+10
-1
@@ -6,6 +6,7 @@ PORT=3000
|
||||
DATABASE_URL="postgresql://postgres:postgrespassword@localhost:5432/lucky_wheel?schema=public"
|
||||
|
||||
# Redis & Queue
|
||||
# اگر از docker-compose لوکال استفاده میکنید و پورت 6380 مپ شده: REDIS_PORT=6380
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
@@ -30,6 +31,14 @@ STORAGE_DRIVER=local
|
||||
STORAGE_LOCAL_ROOT=./uploads
|
||||
STORAGE_PUBLIC_URL=http://localhost:3000/uploads
|
||||
|
||||
# CORS
|
||||
# CORS (لوکال)
|
||||
CORS_ADMIN_ORIGIN=http://localhost:5173
|
||||
CORS_CLIENT_ORIGIN=http://localhost:5174
|
||||
|
||||
# --- Production (Dokploy) نمونه ---
|
||||
# CORS_ADMIN_ORIGIN=https://adm.wheel.montzar.ir
|
||||
# CORS_CLIENT_ORIGIN=https://wheel.montzar.ir
|
||||
# STORAGE_PUBLIC_URL=https://api.wheel.montzar.ir/uploads
|
||||
# DATABASE_URL=postgresql://postgres:PASSWORD@postgres:5432/lucky_wheel?schema=public
|
||||
# REDIS_HOST=redis
|
||||
# REDIS_PORT=6379
|
||||
|
||||
+15
-12
@@ -1,22 +1,25 @@
|
||||
FROM node:20-alpine AS builder
|
||||
FROM docker.arvancloud.ir/node:20-alpine AS production
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable pnpm
|
||||
# تصویر نهایی: release را لوکال بسازید:
|
||||
# pnpm --filter @lucky-wheel/api build:release
|
||||
# سپس فقط کپی میشود (بدون nest build داخل ایمیج).
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN pnpm install --frozen-lockfile
|
||||
RUN pnpm --filter @lucky-wheel/api build
|
||||
RUN pnpm deploy --filter @lucky-wheel/api --prod /prod/api
|
||||
RUN apk add --no-cache openssl libc6-compat python3 make g++
|
||||
|
||||
FROM node:20-alpine AS runner
|
||||
COPY apps/api/release/package.json ./
|
||||
COPY apps/api/release/prisma ./prisma
|
||||
COPY apps/api/release/app.js ./
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /prod/api .
|
||||
RUN npm install --omit=dev \
|
||||
&& npx prisma generate \
|
||||
&& apk del python3 make g++
|
||||
|
||||
RUN mkdir -p uploads
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["node", "dist/src/main"]
|
||||
CMD ["sh", "-c", "npx prisma migrate deploy && node app.js"]
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* باندل تکفایل برای Docker (release/app.js) بعد از nest build.
|
||||
* Prisma و bcrypt بهخاطر باینری native خارجی میمانند و در ایمیج نصب میشوند.
|
||||
*/
|
||||
module.exports = {
|
||||
entryPoints: ['dist/src/main.js'],
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
target: 'node20',
|
||||
format: 'cjs',
|
||||
outfile: 'release/app.js',
|
||||
sourcemap: false,
|
||||
keepNames: true,
|
||||
legalComments: 'none',
|
||||
external: [
|
||||
'@prisma/client',
|
||||
'.prisma/client',
|
||||
'bcrypt',
|
||||
// optional Nest peers — نباید resolve اجباری شوند
|
||||
'@nestjs/microservices',
|
||||
'@nestjs/websockets',
|
||||
'@nestjs/platform-socket.io',
|
||||
'class-transformer/storage',
|
||||
],
|
||||
};
|
||||
@@ -4,6 +4,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nest build",
|
||||
"build:release": "prisma generate && nest build && node scripts/bundle-release.cjs",
|
||||
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||
"start": "nest start",
|
||||
"start:dev": "nest start --watch",
|
||||
@@ -64,7 +65,8 @@
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"typescript": "^5.4.5"
|
||||
"typescript": "^5.4.5",
|
||||
"esbuild": "^0.25.0"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": ["js", "json", "ts"],
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
provider = "prisma-client-js"
|
||||
// native = ماشین بیلد لوکال؛ linux-musl = Alpine داخل Docker/Dokploy
|
||||
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
|
||||
+217327
File diff suppressed because one or more lines are too long
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "lucky-wheel-api-release",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@prisma/client": "5.22.0",
|
||||
"bcrypt": "5.1.1",
|
||||
"prisma": "5.22.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AdminStatus" AS ENUM ('ACTIVE', 'DISABLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AdminRole" AS ENUM ('SUPER_ADMIN', 'OPERATOR', 'SUPPORT');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "UserStatus" AS ENUM ('ACTIVE', 'BLOCKED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CampaignStatus" AS ENUM ('DRAFT', 'ACTIVE', 'PAUSED', 'FINISHED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PrizeType" AS ENUM ('PHYSICAL', 'DISCOUNT_CODE', 'CREDIT', 'CASH', 'NO_PRIZE', 'OTHER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "StockType" AS ENUM ('LIMITED', 'UNLIMITED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PrizeStatus" AS ENUM ('ACTIVE', 'INACTIVE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SpinStatus" AS ENUM ('SUCCESS', 'FAILED', 'DUPLICATE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ChanceTxnType" AS ENUM ('SIGNUP_BONUS', 'ADMIN_ADJUSTMENT', 'SPIN_CONSUME', 'CAMPAIGN_BONUS', 'REFUND');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "UserPrizeStatus" AS ENUM ('NEW', 'CONTACTED', 'DELIVERED', 'ACTIVE_CODE', 'USED', 'EXPIRED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SmsType" AS ENUM ('OTP', 'WINNING', 'NO_PRIZE', 'PRIZE_REMINDER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SmsStatus" AS ENUM ('PENDING', 'SENT', 'FAILED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "WheelDesign" AS ENUM ('CLASSIC_CASINO', 'NEON_CYBER', 'MINIMAL_FLAT', 'LUXURY_GOLD', 'PLAYFUL_CARTOON');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "admins" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"mobile" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"password_hash" TEXT NOT NULL,
|
||||
"role" "AdminRole" NOT NULL DEFAULT 'OPERATOR',
|
||||
"status" "AdminStatus" NOT NULL DEFAULT 'ACTIVE',
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "admins_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "users" (
|
||||
"id" TEXT NOT NULL,
|
||||
"mobile" TEXT NOT NULL,
|
||||
"name" TEXT,
|
||||
"status" "UserStatus" NOT NULL DEFAULT 'ACTIVE',
|
||||
"last_login_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "otp_codes" (
|
||||
"id" TEXT NOT NULL,
|
||||
"mobile" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"user_id" TEXT,
|
||||
"attempts" INTEGER NOT NULL DEFAULT 0,
|
||||
"consumed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"expires_at" TIMESTAMP(3) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "otp_codes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "campaigns" (
|
||||
"id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"image" TEXT,
|
||||
"banner" TEXT,
|
||||
"logo" TEXT,
|
||||
"start_at" TIMESTAMP(3) NOT NULL,
|
||||
"end_at" TIMESTAMP(3) NOT NULL,
|
||||
"status" "CampaignStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"default_chances" INTEGER NOT NULL DEFAULT 0,
|
||||
"rules" TEXT,
|
||||
"cta_text" TEXT,
|
||||
"wheel_design" "WheelDesign" NOT NULL DEFAULT 'CLASSIC_CASINO',
|
||||
"settings" JSONB,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "campaigns_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "prizes" (
|
||||
"id" TEXT NOT NULL,
|
||||
"campaign_id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"image" TEXT,
|
||||
"type" "PrizeType" NOT NULL,
|
||||
"stock_type" "StockType" NOT NULL,
|
||||
"initial_stock" INTEGER,
|
||||
"remaining_stock" INTEGER,
|
||||
"weight" INTEGER NOT NULL,
|
||||
"status" "PrizeStatus" NOT NULL DEFAULT 'ACTIVE',
|
||||
"sort_order" INTEGER NOT NULL DEFAULT 0,
|
||||
"segment_color" TEXT NOT NULL,
|
||||
"expires_at" TIMESTAMP(3),
|
||||
"sms_template" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "prizes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_campaigns" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"campaign_id" TEXT NOT NULL,
|
||||
"total_chances" INTEGER NOT NULL DEFAULT 0,
|
||||
"used_chances" INTEGER NOT NULL DEFAULT 0,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "user_campaigns_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "chance_transactions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"campaign_id" TEXT NOT NULL,
|
||||
"amount" INTEGER NOT NULL,
|
||||
"type" "ChanceTxnType" NOT NULL,
|
||||
"reference_type" TEXT,
|
||||
"reference_id" TEXT,
|
||||
"description" TEXT,
|
||||
"created_by" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "chance_transactions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "spins" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"campaign_id" TEXT NOT NULL,
|
||||
"prize_id" TEXT,
|
||||
"status" "SpinStatus" NOT NULL DEFAULT 'SUCCESS',
|
||||
"idempotency_key" TEXT NOT NULL,
|
||||
"ip" TEXT,
|
||||
"user_agent" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "spins_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_prizes" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"campaign_id" TEXT NOT NULL,
|
||||
"prize_id" TEXT NOT NULL,
|
||||
"spin_id" TEXT NOT NULL,
|
||||
"code" TEXT,
|
||||
"status" "UserPrizeStatus" NOT NULL DEFAULT 'NEW',
|
||||
"won_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"redeemed_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "user_prizes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "sms_logs" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT,
|
||||
"mobile" TEXT NOT NULL,
|
||||
"type" "SmsType" NOT NULL,
|
||||
"message" TEXT NOT NULL,
|
||||
"provider" TEXT NOT NULL DEFAULT 'raygansms',
|
||||
"status" "SmsStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"provider_response" JSONB,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "sms_logs_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "admin_logs" (
|
||||
"id" TEXT NOT NULL,
|
||||
"admin_id" TEXT NOT NULL,
|
||||
"action" TEXT NOT NULL,
|
||||
"entity_type" TEXT NOT NULL,
|
||||
"entity_id" TEXT NOT NULL,
|
||||
"old_value" JSONB,
|
||||
"new_value" JSONB,
|
||||
"ip" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "admin_logs_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "admins_mobile_key" ON "admins"("mobile");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "admins_email_key" ON "admins"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "users_mobile_key" ON "users"("mobile");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "users_mobile_idx" ON "users"("mobile");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "otp_codes_mobile_consumed_idx" ON "otp_codes"("mobile", "consumed");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "campaigns_slug_key" ON "campaigns"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "campaigns_status_start_at_end_at_idx" ON "campaigns"("status", "start_at", "end_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "prizes_campaign_id_status_idx" ON "prizes"("campaign_id", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_campaigns_user_id_campaign_id_key" ON "user_campaigns"("user_id", "campaign_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "chance_transactions_user_id_campaign_id_idx" ON "chance_transactions"("user_id", "campaign_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "spins_idempotency_key_key" ON "spins"("idempotency_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "spins_user_id_campaign_id_idx" ON "spins"("user_id", "campaign_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "spins_campaign_id_created_at_idx" ON "spins"("campaign_id", "created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_prizes_spin_id_key" ON "user_prizes"("spin_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_prizes_code_key" ON "user_prizes"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "user_prizes_user_id_idx" ON "user_prizes"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "user_prizes_status_idx" ON "user_prizes"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "sms_logs_mobile_type_idx" ON "sms_logs"("mobile", "type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "admin_logs_entity_type_entity_id_idx" ON "admin_logs"("entity_type", "entity_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "otp_codes" ADD CONSTRAINT "otp_codes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "prizes" ADD CONSTRAINT "prizes_campaign_id_fkey" FOREIGN KEY ("campaign_id") REFERENCES "campaigns"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_campaigns" ADD CONSTRAINT "user_campaigns_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_campaigns" ADD CONSTRAINT "user_campaigns_campaign_id_fkey" FOREIGN KEY ("campaign_id") REFERENCES "campaigns"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "chance_transactions" ADD CONSTRAINT "chance_transactions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "chance_transactions" ADD CONSTRAINT "chance_transactions_campaign_id_fkey" FOREIGN KEY ("campaign_id") REFERENCES "campaigns"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "chance_transactions" ADD CONSTRAINT "chance_transactions_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "admins"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "spins" ADD CONSTRAINT "spins_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "spins" ADD CONSTRAINT "spins_campaign_id_fkey" FOREIGN KEY ("campaign_id") REFERENCES "campaigns"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "spins" ADD CONSTRAINT "spins_prize_id_fkey" FOREIGN KEY ("prize_id") REFERENCES "prizes"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_prizes" ADD CONSTRAINT "user_prizes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_prizes" ADD CONSTRAINT "user_prizes_campaign_id_fkey" FOREIGN KEY ("campaign_id") REFERENCES "campaigns"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_prizes" ADD CONSTRAINT "user_prizes_prize_id_fkey" FOREIGN KEY ("prize_id") REFERENCES "prizes"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_prizes" ADD CONSTRAINT "user_prizes_spin_id_fkey" FOREIGN KEY ("spin_id") REFERENCES "spins"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "sms_logs" ADD CONSTRAINT "sms_logs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "admin_logs" ADD CONSTRAINT "admin_logs_admin_id_fkey" FOREIGN KEY ("admin_id") REFERENCES "admins"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "postgresql"
|
||||
@@ -0,0 +1,315 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
// native = ماشین بیلد لوکال؛ linux-musl = Alpine داخل Docker/Dokploy
|
||||
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// ==================== ENUMS ====================
|
||||
|
||||
enum AdminStatus {
|
||||
ACTIVE
|
||||
DISABLED
|
||||
}
|
||||
|
||||
enum AdminRole {
|
||||
SUPER_ADMIN
|
||||
OPERATOR
|
||||
SUPPORT
|
||||
}
|
||||
|
||||
enum UserStatus {
|
||||
ACTIVE
|
||||
BLOCKED
|
||||
}
|
||||
|
||||
enum CampaignStatus {
|
||||
DRAFT
|
||||
ACTIVE
|
||||
PAUSED
|
||||
FINISHED
|
||||
}
|
||||
|
||||
enum PrizeType {
|
||||
PHYSICAL
|
||||
DISCOUNT_CODE
|
||||
CREDIT
|
||||
CASH
|
||||
NO_PRIZE
|
||||
OTHER
|
||||
}
|
||||
|
||||
enum StockType {
|
||||
LIMITED
|
||||
UNLIMITED
|
||||
}
|
||||
|
||||
enum PrizeStatus {
|
||||
ACTIVE
|
||||
INACTIVE
|
||||
}
|
||||
|
||||
enum SpinStatus {
|
||||
SUCCESS
|
||||
FAILED
|
||||
DUPLICATE
|
||||
}
|
||||
|
||||
enum ChanceTxnType {
|
||||
SIGNUP_BONUS
|
||||
ADMIN_ADJUSTMENT
|
||||
SPIN_CONSUME
|
||||
CAMPAIGN_BONUS
|
||||
REFUND
|
||||
}
|
||||
|
||||
enum UserPrizeStatus {
|
||||
NEW
|
||||
CONTACTED
|
||||
DELIVERED
|
||||
ACTIVE_CODE
|
||||
USED
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
enum SmsType {
|
||||
OTP
|
||||
WINNING
|
||||
NO_PRIZE
|
||||
PRIZE_REMINDER
|
||||
}
|
||||
|
||||
enum SmsStatus {
|
||||
PENDING
|
||||
SENT
|
||||
FAILED
|
||||
}
|
||||
|
||||
enum WheelDesign {
|
||||
CLASSIC_CASINO
|
||||
NEON_CYBER
|
||||
MINIMAL_FLAT
|
||||
LUXURY_GOLD
|
||||
PLAYFUL_CARTOON
|
||||
}
|
||||
|
||||
// ==================== MODELS ====================
|
||||
|
||||
model Admin {
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
mobile String @unique
|
||||
email String @unique
|
||||
passwordHash String @map("password_hash")
|
||||
role AdminRole @default(OPERATOR)
|
||||
status AdminStatus @default(ACTIVE)
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
auditLogs AdminLog[]
|
||||
chanceTxns ChanceTransaction[] @relation("AdminCreatedTxn")
|
||||
|
||||
@@map("admins")
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
mobile String @unique
|
||||
name String?
|
||||
status UserStatus @default(ACTIVE)
|
||||
lastLoginAt DateTime? @map("last_login_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
userCampaigns UserCampaign[]
|
||||
chanceTransactions ChanceTransaction[]
|
||||
spins Spin[]
|
||||
userPrizes UserPrize[]
|
||||
otpCodes OtpCode[]
|
||||
smsLogs SmsLog[]
|
||||
|
||||
@@index([mobile])
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model OtpCode {
|
||||
id String @id @default(uuid())
|
||||
mobile String
|
||||
code String
|
||||
userId String? @map("user_id")
|
||||
user User? @relation(fields: [userId], references: [id])
|
||||
attempts Int @default(0)
|
||||
consumed Boolean @default(false)
|
||||
expiresAt DateTime @map("expires_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([mobile, consumed])
|
||||
@@map("otp_codes")
|
||||
}
|
||||
|
||||
model Campaign {
|
||||
id String @id @default(uuid())
|
||||
title String
|
||||
slug String @unique
|
||||
description String?
|
||||
image String?
|
||||
banner String?
|
||||
logo String?
|
||||
startAt DateTime @map("start_at")
|
||||
endAt DateTime @map("end_at")
|
||||
status CampaignStatus @default(DRAFT)
|
||||
defaultChances Int @default(0) @map("default_chances")
|
||||
rules String?
|
||||
ctaText String? @map("cta_text")
|
||||
wheelDesign WheelDesign @default(CLASSIC_CASINO) @map("wheel_design")
|
||||
settings Json? // primaryColor, secondaryColor, headerText, buttonText, headerImage, celebrationEffect...
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
prizes Prize[]
|
||||
userCampaigns UserCampaign[]
|
||||
chanceTxns ChanceTransaction[]
|
||||
spins Spin[]
|
||||
userPrizes UserPrize[]
|
||||
|
||||
@@index([status, startAt, endAt])
|
||||
@@map("campaigns")
|
||||
}
|
||||
|
||||
model Prize {
|
||||
id String @id @default(uuid())
|
||||
campaignId String @map("campaign_id")
|
||||
campaign Campaign @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
||||
title String
|
||||
description String?
|
||||
image String?
|
||||
type PrizeType
|
||||
stockType StockType @map("stock_type")
|
||||
initialStock Int? @map("initial_stock")
|
||||
remainingStock Int? @map("remaining_stock")
|
||||
weight Int
|
||||
status PrizeStatus @default(ACTIVE)
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
segmentColor String @map("segment_color")
|
||||
expiresAt DateTime? @map("expires_at")
|
||||
smsTemplate String? @map("sms_template")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
spins Spin[]
|
||||
userPrizes UserPrize[]
|
||||
|
||||
@@index([campaignId, status])
|
||||
@@map("prizes")
|
||||
}
|
||||
|
||||
model UserCampaign {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
campaignId String @map("campaign_id")
|
||||
campaign Campaign @relation(fields: [campaignId], references: [id])
|
||||
totalChances Int @default(0) @map("total_chances")
|
||||
usedChances Int @default(0) @map("used_chances")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@unique([userId, campaignId])
|
||||
@@map("user_campaigns")
|
||||
}
|
||||
|
||||
model ChanceTransaction {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
campaignId String @map("campaign_id")
|
||||
campaign Campaign @relation(fields: [campaignId], references: [id])
|
||||
amount Int // مثبت یا منفی
|
||||
type ChanceTxnType
|
||||
referenceType String? @map("reference_type") // e.g. "spin", "manual"
|
||||
referenceId String? @map("reference_id")
|
||||
description String?
|
||||
createdById String? @map("created_by") // admin id در صورت تغییر دستی
|
||||
createdBy Admin? @relation("AdminCreatedTxn", fields: [createdById], references: [id])
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([userId, campaignId])
|
||||
@@map("chance_transactions")
|
||||
}
|
||||
|
||||
model Spin {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
campaignId String @map("campaign_id")
|
||||
campaign Campaign @relation(fields: [campaignId], references: [id])
|
||||
prizeId String? @map("prize_id")
|
||||
prize Prize? @relation(fields: [prizeId], references: [id])
|
||||
status SpinStatus @default(SUCCESS)
|
||||
idempotencyKey String @unique @map("idempotency_key")
|
||||
ip String?
|
||||
userAgent String? @map("user_agent")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
userPrize UserPrize?
|
||||
|
||||
@@index([userId, campaignId])
|
||||
@@index([campaignId, createdAt])
|
||||
@@map("spins")
|
||||
}
|
||||
|
||||
model UserPrize {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
campaignId String @map("campaign_id")
|
||||
campaign Campaign @relation(fields: [campaignId], references: [id])
|
||||
prizeId String @map("prize_id")
|
||||
prize Prize @relation(fields: [prizeId], references: [id])
|
||||
spinId String @unique @map("spin_id")
|
||||
spin Spin @relation(fields: [spinId], references: [id])
|
||||
code String? @unique
|
||||
status UserPrizeStatus @default(NEW)
|
||||
wonAt DateTime @default(now()) @map("won_at")
|
||||
redeemedAt DateTime? @map("redeemed_at")
|
||||
|
||||
@@index([userId])
|
||||
@@index([status])
|
||||
@@map("user_prizes")
|
||||
}
|
||||
|
||||
model SmsLog {
|
||||
id String @id @default(uuid())
|
||||
userId String? @map("user_id")
|
||||
user User? @relation(fields: [userId], references: [id])
|
||||
mobile String
|
||||
type SmsType
|
||||
message String
|
||||
provider String @default("raygansms")
|
||||
status SmsStatus @default(PENDING)
|
||||
providerResponse Json? @map("provider_response")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([mobile, type])
|
||||
@@map("sms_logs")
|
||||
}
|
||||
|
||||
model AdminLog {
|
||||
id String @id @default(uuid())
|
||||
adminId String @map("admin_id")
|
||||
admin Admin @relation(fields: [adminId], references: [id])
|
||||
action String // e.g. "prize.update", "chance.add"
|
||||
entityType String @map("entity_type")
|
||||
entityId String @map("entity_id")
|
||||
oldValue Json? @map("old_value")
|
||||
newValue Json? @map("new_value")
|
||||
ip String?
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([entityType, entityId])
|
||||
@@map("admin_logs")
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
const user = await prisma.user.upsert({
|
||||
where: { mobile: '09382507041' },
|
||||
create: {
|
||||
mobile: '09382507041',
|
||||
name: 'کاربر ویژه',
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
update: {
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
});
|
||||
|
||||
const campaign = await prisma.campaign.findUnique({
|
||||
where: { slug: 'default-campaign' },
|
||||
});
|
||||
|
||||
if (campaign) {
|
||||
await prisma.userCampaign.upsert({
|
||||
where: {
|
||||
userId_campaignId: {
|
||||
userId: user.id,
|
||||
campaignId: campaign.id,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
userId: user.id,
|
||||
campaignId: campaign.id,
|
||||
totalChances: 10,
|
||||
usedChances: 0,
|
||||
},
|
||||
update: {
|
||||
totalChances: { increment: 10 },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
console.log('SUCCESS: User 09382507041 is authorized and ready with 10 chances!');
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
@@ -0,0 +1,116 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log('Seeding default demo campaign and prizes...');
|
||||
|
||||
const existingCampaign = await prisma.campaign.findUnique({
|
||||
where: { slug: 'default-campaign' },
|
||||
});
|
||||
|
||||
if (existingCampaign) {
|
||||
console.log('Default campaign already exists.');
|
||||
return;
|
||||
}
|
||||
|
||||
const campaign = await prisma.campaign.create({
|
||||
data: {
|
||||
title: 'گردونه شانس جشنواره بزرگ نوروزی',
|
||||
slug: 'default-campaign',
|
||||
description: 'هر روز با چرخاندن گردونه، شانس برنده شدن آیفون، سکه طلا، و کدهای تخفیف شگفتانگیز را داشته باشید!',
|
||||
startAt: new Date(Date.now() - 24 * 3600 * 1000),
|
||||
endAt: new Date(Date.now() + 60 * 24 * 3600 * 1000),
|
||||
status: 'ACTIVE',
|
||||
defaultChances: 3,
|
||||
ctaText: 'بچرخون و برنده شو!',
|
||||
wheelDesign: 'CLASSIC_CASINO',
|
||||
rules: '۱. هر کاربر در بدو ورود ۳ شانس چرخاندن رایگان دریافت میکند.\n۲. جوایز فیزیکی پس از هماهنگی تلفنی توسط پشتیبانی ارسال خواهد شد.\n۳. کدهای تخفیف بلافاصله پیامک شده و تا ۷ روز پس از دریافت معتبر هستند.',
|
||||
prizes: {
|
||||
create: [
|
||||
{
|
||||
title: 'آیفون ۱۵ پرو',
|
||||
type: 'PHYSICAL',
|
||||
stockType: 'LIMITED',
|
||||
initialStock: 3,
|
||||
remainingStock: 3,
|
||||
weight: 1,
|
||||
sortOrder: 1,
|
||||
segmentColor: '#b91c1c',
|
||||
},
|
||||
{
|
||||
title: 'تخفیف ۵۰٪ دیجیکالا',
|
||||
type: 'DISCOUNT_CODE',
|
||||
stockType: 'UNLIMITED',
|
||||
weight: 25,
|
||||
sortOrder: 2,
|
||||
segmentColor: '#1e293b',
|
||||
},
|
||||
{
|
||||
title: 'کارت هدیه ۵۰۰ تومانی',
|
||||
type: 'CREDIT',
|
||||
stockType: 'LIMITED',
|
||||
initialStock: 50,
|
||||
remainingStock: 50,
|
||||
weight: 10,
|
||||
sortOrder: 3,
|
||||
segmentColor: '#b91c1c',
|
||||
},
|
||||
{
|
||||
title: 'پوچ (دفعه بعد)',
|
||||
type: 'NO_PRIZE',
|
||||
stockType: 'UNLIMITED',
|
||||
weight: 20,
|
||||
sortOrder: 4,
|
||||
segmentColor: '#1e293b',
|
||||
},
|
||||
{
|
||||
title: 'تخفیف ۳۰٪ اسنپ',
|
||||
type: 'DISCOUNT_CODE',
|
||||
stockType: 'UNLIMITED',
|
||||
weight: 20,
|
||||
sortOrder: 5,
|
||||
segmentColor: '#b91c1c',
|
||||
},
|
||||
{
|
||||
title: 'ساعت هوشمند',
|
||||
type: 'PHYSICAL',
|
||||
stockType: 'LIMITED',
|
||||
initialStock: 10,
|
||||
remainingStock: 10,
|
||||
weight: 4,
|
||||
sortOrder: 6,
|
||||
segmentColor: '#1e293b',
|
||||
},
|
||||
{
|
||||
title: 'شانس مجدد',
|
||||
type: 'OTHER',
|
||||
stockType: 'UNLIMITED',
|
||||
weight: 15,
|
||||
sortOrder: 7,
|
||||
segmentColor: '#b91c1c',
|
||||
},
|
||||
{
|
||||
title: 'پوچ (بدون جایزه)',
|
||||
type: 'NO_PRIZE',
|
||||
stockType: 'UNLIMITED',
|
||||
weight: 5,
|
||||
sortOrder: 8,
|
||||
segmentColor: '#1e293b',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`Campaign created with ID: ${campaign.id} and 8 prizes.`);
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* باندل تکفایل برای Docker (release/app.js) بعد از nest build.
|
||||
* تنظیمات alias در ../esbuild.release.config.cjs
|
||||
*/
|
||||
const esbuild = require('esbuild');
|
||||
const { existsSync, mkdirSync, cpSync, writeFileSync } = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const root = path.join(__dirname, '..');
|
||||
const config = require(path.join(root, 'esbuild.release.config.cjs'));
|
||||
|
||||
async function main() {
|
||||
const entry = path.join(root, config.entryPoints[0]);
|
||||
if (!existsSync(entry)) {
|
||||
console.error('dist/src/main.js یافت نشد. ابتدا اجرا کنید: pnpm run build');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const outfile = path.join(root, config.outfile);
|
||||
mkdirSync(path.dirname(outfile), { recursive: true });
|
||||
|
||||
await esbuild.build({
|
||||
...config,
|
||||
entryPoints: [entry],
|
||||
outfile,
|
||||
});
|
||||
|
||||
// Prisma schema + migrations برای generate/migrate داخل کانتینر
|
||||
const prismaSrc = path.join(root, 'prisma');
|
||||
const prismaDest = path.join(root, 'release', 'prisma');
|
||||
cpSync(prismaSrc, prismaDest, { recursive: true });
|
||||
|
||||
// فقط native / runtimeهای خارجی باندل
|
||||
const releasePkg = {
|
||||
name: 'lucky-wheel-api-release',
|
||||
private: true,
|
||||
version: '1.0.0',
|
||||
dependencies: {
|
||||
'@prisma/client': '5.22.0',
|
||||
bcrypt: '5.1.1',
|
||||
prisma: '5.22.0',
|
||||
},
|
||||
};
|
||||
writeFileSync(
|
||||
path.join(root, 'release', 'package.json'),
|
||||
`${JSON.stringify(releasePkg, null, 2)}\n`,
|
||||
);
|
||||
|
||||
console.log('نوشت:', outfile);
|
||||
console.log('نوشت: release/prisma + release/package.json');
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
VITE_API_BASE_URL=https://api.wheel.montzar.ir/api
|
||||
+5
-25
@@ -1,30 +1,10 @@
|
||||
FROM node:20-alpine AS builder
|
||||
FROM docker.arvancloud.ir/nginx:latest
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable pnpm
|
||||
# بیلد لوکال: pnpm --filter @lucky-wheel/client build
|
||||
# (با apps/client/.env.production)
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN pnpm install --frozen-lockfile
|
||||
RUN pnpm --filter @lucky-wheel/client build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /app/apps/client/dist /usr/share/nginx/html
|
||||
|
||||
# Configure Nginx for Single Page Application
|
||||
RUN echo 'server { \
|
||||
listen 80; \
|
||||
server_name localhost; \
|
||||
location / { \
|
||||
root /usr/share/nginx/html; \
|
||||
index index.html index.htm; \
|
||||
try_files $uri $uri/ /index.html; \
|
||||
} \
|
||||
}' > /etc/nginx/conf.d/default.conf
|
||||
COPY apps/client/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY apps/client/dist /usr/share/nginx/html
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+39
File diff suppressed because one or more lines are too long
@@ -0,0 +1,46 @@
|
||||
import{C as a}from"./index-ilYp-WvI.js";const s=["۰","۱","۲","۳","۴","۵","۶","۷","۸","۹"];function g(e){return e==null||typeof e=="object"&&e!==null&&"value"in e&&(e=e.value,e==null)||typeof e=="object"?"":String(e).replace(/[0-9]/g,t=>s[+t]).replace(/[٠-٩]/g,t=>s[t.charCodeAt(0)-1632])}/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const p=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/var r={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const y=({size:e,strokeWidth:t=2,absoluteStrokeWidth:c,color:n,iconNode:h,name:d,class:k,...u},{slots:i})=>a("svg",{...r,width:e||r.width,height:e||r.height,stroke:n||r.stroke,"stroke-width":c?Number(t)*24/Number(e):t,class:["lucide",`lucide-${p(d??"icon")}`],...u},[...h.map(l=>a(...l)),...i.default?[i.default()]:[]]);/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const o=(e,t)=>(c,{slots:n})=>a(y,{...c,iconNode:t,name:e},n);/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const f=o("ArrowRightIcon",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]]);/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const C=o("AwardIcon",[["path",{d:"m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526",key:"1yiouv"}],["circle",{cx:"12",cy:"8",r:"6",key:"1vp47v"}]]);/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const m=o("CheckIcon",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const I=o("CopyIcon",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]);/**
|
||||
* @license lucide-vue-next v0.378.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const A=o("LoaderCircleIcon",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);export{f as A,m as C,A as L,C as a,I as b,o as c,g as t};
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fa" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🎡</text></svg>" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>گردونه شانس و قرعهکشی</title>
|
||||
<!-- Google Font Vazirmatn -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<script type="module" crossorigin src="/assets/index-ilYp-WvI.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BqdIdFn_.css">
|
||||
</head>
|
||||
<body class="bg-slate-900 text-slate-100 font-sans antialiased selection:bg-brand-500 selection:text-white overflow-x-hidden min-h-screen">
|
||||
<div id="app"></div>␍
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,10 @@ declare module 'axios' {
|
||||
}
|
||||
}
|
||||
|
||||
const apiBaseURL = import.meta.env.VITE_API_BASE_URL || '/api';
|
||||
|
||||
export const apiClient = axios.create({
|
||||
baseURL: '/api',
|
||||
baseURL: apiBaseURL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_BASE_URL?: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# فقط Postgres + Redis برای توسعه لوکال
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: lucky_wheel_postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: lucky_wheel
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgrespassword
|
||||
ports:
|
||||
- '5432:5432'
|
||||
volumes:
|
||||
- pg_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready -U postgres -d lucky_wheel']
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: lucky_wheel_redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- '6380:6379'
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ['CMD', 'redis-cli', 'ping']
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
volumes:
|
||||
pg_data:
|
||||
redis_data:
|
||||
+46
-20
@@ -1,32 +1,40 @@
|
||||
# Production / Dokploy
|
||||
# دامنهها را در UIی Dokploy به سرویسها ببندید:
|
||||
# client → https://wheel.montzar.ir
|
||||
# api → https://api.wheel.montzar.ir (port 3000)
|
||||
# admin → https://adm.wheel.montzar.ir
|
||||
#
|
||||
# بیلد لوکال قبل از push:
|
||||
# pnpm install && pnpm run build:release
|
||||
#
|
||||
# env: از .env.production.example کپی کنید و در Dokploy ست کنید.
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: lucky_wheel_postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: lucky_wheel
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgrespassword
|
||||
POSTGRES_DB: ${POSTGRES_DB:-lucky_wheel}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgrespassword}
|
||||
ports:
|
||||
- "5432:5432"
|
||||
- '${EXPORT_DB_PORT:-5432}:5432'
|
||||
volumes:
|
||||
- pg_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready -U postgres -d lucky_wheel" ]
|
||||
test: ['CMD-SHELL', 'pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB']
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: lucky_wheel_redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6380:6379"
|
||||
command: ['redis-server', '--appendonly', 'yes']
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: [ "CMD", "redis-cli", "ping" ]
|
||||
test: ['CMD', 'redis-cli', 'ping']
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
@@ -35,15 +43,34 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/api/Dockerfile
|
||||
container_name: lucky_wheel_api
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- '3000:3000'
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://postgres:postgrespassword@postgres:5432/lucky_wheel?schema=public
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- NODE_ENV=production
|
||||
NODE_ENV: production
|
||||
PORT: 3000
|
||||
DATABASE_URL: ${DATABASE_URL:-postgresql://postgres:postgrespassword@postgres:5432/lucky_wheel?schema=public}
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: '6379'
|
||||
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
|
||||
JWT_USER_SECRET: ${JWT_USER_SECRET:-change-me-user-jwt}
|
||||
JWT_USER_EXPIRES_IN: ${JWT_USER_EXPIRES_IN:-7d}
|
||||
JWT_ADMIN_ACCESS_SECRET: ${JWT_ADMIN_ACCESS_SECRET:-change-me-admin-access-jwt}
|
||||
JWT_ADMIN_ACCESS_EXPIRES_IN: ${JWT_ADMIN_ACCESS_EXPIRES_IN:-1h}
|
||||
JWT_ADMIN_REFRESH_SECRET: ${JWT_ADMIN_REFRESH_SECRET:-change-me-admin-refresh-jwt}
|
||||
JWT_ADMIN_REFRESH_EXPIRES_IN: ${JWT_ADMIN_REFRESH_EXPIRES_IN:-7d}
|
||||
CORS_ADMIN_ORIGIN: ${CORS_ADMIN_ORIGIN:-https://adm.wheel.montzar.ir}
|
||||
CORS_CLIENT_ORIGIN: ${CORS_CLIENT_ORIGIN:-https://wheel.montzar.ir}
|
||||
STORAGE_DRIVER: ${STORAGE_DRIVER:-local}
|
||||
STORAGE_LOCAL_ROOT: ${STORAGE_LOCAL_ROOT:-./uploads}
|
||||
STORAGE_PUBLIC_URL: ${STORAGE_PUBLIC_URL:-https://api.wheel.montzar.ir/uploads}
|
||||
SMS_DRIVER: ${SMS_DRIVER:-mock}
|
||||
RAYGAN_SMS_USERNAME: ${RAYGAN_SMS_USERNAME:-}
|
||||
RAYGAN_SMS_PASSWORD: ${RAYGAN_SMS_PASSWORD:-}
|
||||
RAYGAN_SMS_LINE_NUMBER: ${RAYGAN_SMS_LINE_NUMBER:-}
|
||||
RAYGAN_SMS_API_BASE_URL: ${RAYGAN_SMS_API_BASE_URL:-https://api.raygansms.com}
|
||||
volumes:
|
||||
- uploads_data:/app/uploads
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
@@ -54,10 +81,9 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/admin/Dockerfile
|
||||
container_name: lucky_wheel_admin
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:80"
|
||||
- '8080:80'
|
||||
depends_on:
|
||||
- api
|
||||
|
||||
@@ -65,13 +91,13 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/client/Dockerfile
|
||||
container_name: lucky_wheel_client
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- '8081:80'
|
||||
depends_on:
|
||||
- api
|
||||
|
||||
volumes:
|
||||
pg_data:
|
||||
redis_data:
|
||||
uploads_data:
|
||||
|
||||
+6
-2
@@ -9,12 +9,16 @@
|
||||
"dev:client": "pnpm --filter @lucky-wheel/client dev",
|
||||
"build:types": "pnpm --filter @lucky-wheel/shared-types build",
|
||||
"build:api": "pnpm --filter @lucky-wheel/api build",
|
||||
"build:api:release": "pnpm --filter @lucky-wheel/api build:release",
|
||||
"build:admin": "pnpm --filter @lucky-wheel/admin build",
|
||||
"build:client": "pnpm --filter @lucky-wheel/client build",
|
||||
"build": "pnpm run build:types && pnpm --filter @lucky-wheel/api build && pnpm --filter @lucky-wheel/admin build && pnpm --filter @lucky-wheel/client build",
|
||||
"build:release": "pnpm run build:types && pnpm run build:api:release && pnpm run build:admin && pnpm run build:client",
|
||||
"test:api": "pnpm --filter @lucky-wheel/api test",
|
||||
"docker:up": "docker-compose up -d",
|
||||
"docker:down": "docker-compose down"
|
||||
"docker:up": "docker-compose -f docker-compose.dev.yml up -d",
|
||||
"docker:down": "docker-compose -f docker-compose.dev.yml down",
|
||||
"docker:prod:up": "docker-compose up -d --build",
|
||||
"docker:prod:down": "docker-compose down"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.4.5"
|
||||
|
||||
Generated
+289
-15
@@ -138,7 +138,7 @@ importers:
|
||||
devDependencies:
|
||||
'@nestjs/cli':
|
||||
specifier: ^10.3.2
|
||||
version: 10.4.9
|
||||
version: 10.4.9(esbuild@0.25.12)
|
||||
'@nestjs/schematics':
|
||||
specifier: ^10.1.1
|
||||
version: 10.2.3(chokidar@3.6.0)(typescript@5.9.3)
|
||||
@@ -169,6 +169,9 @@ importers:
|
||||
'@types/supertest':
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.3
|
||||
esbuild:
|
||||
specifier: ^0.25.0
|
||||
version: 0.25.12
|
||||
jest:
|
||||
specifier: ^29.7.0
|
||||
version: 29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3))
|
||||
@@ -183,10 +186,10 @@ importers:
|
||||
version: 7.2.2
|
||||
ts-jest:
|
||||
specifier: ^29.1.2
|
||||
version: 29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)))(typescript@5.9.3)
|
||||
version: 29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(esbuild@0.25.12)(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)))(typescript@5.9.3)
|
||||
ts-loader:
|
||||
specifier: ^9.5.1
|
||||
version: 9.6.2(typescript@5.9.3)(webpack@5.97.1)
|
||||
version: 9.6.2(typescript@5.9.3)(webpack@5.97.1(esbuild@0.25.12))
|
||||
ts-node:
|
||||
specifier: ^10.9.2
|
||||
version: 10.9.2(@types/node@20.19.43)(typescript@5.9.3)
|
||||
@@ -486,138 +489,294 @@ packages:
|
||||
cpu: [ppc64]
|
||||
os: [aix]
|
||||
|
||||
'@esbuild/aix-ppc64@0.25.12':
|
||||
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [aix]
|
||||
|
||||
'@esbuild/android-arm64@0.21.5':
|
||||
resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-arm64@0.25.12':
|
||||
resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-arm@0.21.5':
|
||||
resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-arm@0.25.12':
|
||||
resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-x64@0.21.5':
|
||||
resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-x64@0.25.12':
|
||||
resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/darwin-arm64@0.21.5':
|
||||
resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/darwin-arm64@0.25.12':
|
||||
resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/darwin-x64@0.21.5':
|
||||
resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/darwin-x64@0.25.12':
|
||||
resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/freebsd-arm64@0.21.5':
|
||||
resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/freebsd-arm64@0.25.12':
|
||||
resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/freebsd-x64@0.21.5':
|
||||
resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/freebsd-x64@0.25.12':
|
||||
resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/linux-arm64@0.21.5':
|
||||
resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-arm64@0.25.12':
|
||||
resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-arm@0.21.5':
|
||||
resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-arm@0.25.12':
|
||||
resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ia32@0.21.5':
|
||||
resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ia32@0.25.12':
|
||||
resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-loong64@0.21.5':
|
||||
resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-loong64@0.25.12':
|
||||
resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-mips64el@0.21.5':
|
||||
resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-mips64el@0.25.12':
|
||||
resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ppc64@0.21.5':
|
||||
resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ppc64@0.25.12':
|
||||
resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-riscv64@0.21.5':
|
||||
resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-riscv64@0.25.12':
|
||||
resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-s390x@0.21.5':
|
||||
resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-s390x@0.25.12':
|
||||
resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-x64@0.21.5':
|
||||
resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-x64@0.25.12':
|
||||
resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/netbsd-arm64@0.25.12':
|
||||
resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/netbsd-x64@0.21.5':
|
||||
resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/netbsd-x64@0.25.12':
|
||||
resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/openbsd-arm64@0.25.12':
|
||||
resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openbsd-x64@0.21.5':
|
||||
resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openbsd-x64@0.25.12':
|
||||
resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openharmony-arm64@0.25.12':
|
||||
resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@esbuild/sunos-x64@0.21.5':
|
||||
resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
|
||||
'@esbuild/sunos-x64@0.25.12':
|
||||
resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
|
||||
'@esbuild/win32-arm64@0.21.5':
|
||||
resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-arm64@0.25.12':
|
||||
resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-ia32@0.21.5':
|
||||
resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-ia32@0.25.12':
|
||||
resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-x64@0.21.5':
|
||||
resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-x64@0.25.12':
|
||||
resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@fast-csv/format@4.3.5':
|
||||
resolution: {integrity: sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==}
|
||||
|
||||
@@ -2084,6 +2243,11 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
|
||||
esbuild@0.25.12:
|
||||
resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -4358,72 +4522,150 @@ snapshots:
|
||||
'@esbuild/aix-ppc64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/aix-ppc64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-x64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-arm64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-arm64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-x64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-arm64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-arm64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-x64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ia32@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ia32@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-loong64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-loong64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-mips64el@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-mips64el@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ppc64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ppc64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-riscv64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-riscv64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-s390x@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-s390x@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-x64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-arm64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-x64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-arm64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-x64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openharmony-arm64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/sunos-x64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/sunos-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-arm64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-arm64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-ia32@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-ia32@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-x64@0.21.5':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-x64@0.25.12':
|
||||
optional: true
|
||||
|
||||
'@fast-csv/format@4.3.5':
|
||||
dependencies:
|
||||
'@types/node': 14.18.63
|
||||
@@ -4713,7 +4955,7 @@ snapshots:
|
||||
bullmq: 5.81.4
|
||||
tslib: 2.8.1
|
||||
|
||||
'@nestjs/cli@10.4.9':
|
||||
'@nestjs/cli@10.4.9(esbuild@0.25.12)':
|
||||
dependencies:
|
||||
'@angular-devkit/core': 17.3.11(chokidar@3.6.0)
|
||||
'@angular-devkit/schematics': 17.3.11(chokidar@3.6.0)
|
||||
@@ -4723,7 +4965,7 @@ snapshots:
|
||||
chokidar: 3.6.0
|
||||
cli-table3: 0.6.5
|
||||
commander: 4.1.1
|
||||
fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.7.2)(webpack@5.97.1)
|
||||
fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.25.12))
|
||||
glob: 10.4.5
|
||||
inquirer: 8.2.6
|
||||
node-emoji: 1.11.0
|
||||
@@ -4732,7 +4974,7 @@ snapshots:
|
||||
tsconfig-paths: 4.2.0
|
||||
tsconfig-paths-webpack-plugin: 4.2.0
|
||||
typescript: 5.7.2
|
||||
webpack: 5.97.1
|
||||
webpack: 5.97.1(esbuild@0.25.12)
|
||||
webpack-node-externals: 3.0.0
|
||||
transitivePeerDependencies:
|
||||
- '@minify-html/node'
|
||||
@@ -6131,6 +6373,35 @@ snapshots:
|
||||
'@esbuild/win32-ia32': 0.21.5
|
||||
'@esbuild/win32-x64': 0.21.5
|
||||
|
||||
esbuild@0.25.12:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.25.12
|
||||
'@esbuild/android-arm': 0.25.12
|
||||
'@esbuild/android-arm64': 0.25.12
|
||||
'@esbuild/android-x64': 0.25.12
|
||||
'@esbuild/darwin-arm64': 0.25.12
|
||||
'@esbuild/darwin-x64': 0.25.12
|
||||
'@esbuild/freebsd-arm64': 0.25.12
|
||||
'@esbuild/freebsd-x64': 0.25.12
|
||||
'@esbuild/linux-arm': 0.25.12
|
||||
'@esbuild/linux-arm64': 0.25.12
|
||||
'@esbuild/linux-ia32': 0.25.12
|
||||
'@esbuild/linux-loong64': 0.25.12
|
||||
'@esbuild/linux-mips64el': 0.25.12
|
||||
'@esbuild/linux-ppc64': 0.25.12
|
||||
'@esbuild/linux-riscv64': 0.25.12
|
||||
'@esbuild/linux-s390x': 0.25.12
|
||||
'@esbuild/linux-x64': 0.25.12
|
||||
'@esbuild/netbsd-arm64': 0.25.12
|
||||
'@esbuild/netbsd-x64': 0.25.12
|
||||
'@esbuild/openbsd-arm64': 0.25.12
|
||||
'@esbuild/openbsd-x64': 0.25.12
|
||||
'@esbuild/openharmony-arm64': 0.25.12
|
||||
'@esbuild/sunos-x64': 0.25.12
|
||||
'@esbuild/win32-arm64': 0.25.12
|
||||
'@esbuild/win32-ia32': 0.25.12
|
||||
'@esbuild/win32-x64': 0.25.12
|
||||
|
||||
escalade@3.2.0: {}
|
||||
|
||||
escape-html@1.0.3: {}
|
||||
@@ -6312,7 +6583,7 @@ snapshots:
|
||||
cross-spawn: 7.0.6
|
||||
signal-exit: 4.1.0
|
||||
|
||||
fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1):
|
||||
fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.25.12)):
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.29.7
|
||||
chalk: 4.1.2
|
||||
@@ -6327,7 +6598,7 @@ snapshots:
|
||||
semver: 7.8.5
|
||||
tapable: 2.3.3
|
||||
typescript: 5.7.2
|
||||
webpack: 5.97.1
|
||||
webpack: 5.97.1(esbuild@0.25.12)
|
||||
|
||||
form-data@4.0.6:
|
||||
dependencies:
|
||||
@@ -7974,13 +8245,15 @@ snapshots:
|
||||
mkdirp: 1.0.4
|
||||
yallist: 4.0.0
|
||||
|
||||
terser-webpack-plugin@5.6.1(webpack@5.97.1):
|
||||
terser-webpack-plugin@5.6.1(esbuild@0.25.12)(webpack@5.97.1(esbuild@0.25.12)):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
jest-worker: 27.5.1
|
||||
schema-utils: 4.3.3
|
||||
terser: 5.51.2
|
||||
webpack: 5.97.1
|
||||
webpack: 5.97.1(esbuild@0.25.12)
|
||||
optionalDependencies:
|
||||
esbuild: 0.25.12
|
||||
|
||||
terser@5.51.2:
|
||||
dependencies:
|
||||
@@ -8040,7 +8313,7 @@ snapshots:
|
||||
|
||||
ts-interface-checker@0.1.13: {}
|
||||
|
||||
ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)))(typescript@5.9.3):
|
||||
ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.7))(esbuild@0.25.12)(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3)))(typescript@5.9.3):
|
||||
dependencies:
|
||||
bs-logger: 0.2.6
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
@@ -8058,15 +8331,16 @@ snapshots:
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
babel-jest: 29.7.0(@babel/core@7.29.7)
|
||||
esbuild: 0.25.12
|
||||
jest-util: 29.7.0
|
||||
|
||||
ts-loader@9.6.2(typescript@5.9.3)(webpack@5.97.1):
|
||||
ts-loader@9.6.2(typescript@5.9.3)(webpack@5.97.1(esbuild@0.25.12)):
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
picomatch: 4.0.7
|
||||
source-map: 0.7.6
|
||||
typescript: 5.9.3
|
||||
webpack: 5.97.1
|
||||
webpack: 5.97.1(esbuild@0.25.12)
|
||||
|
||||
ts-node@10.9.2(@types/node@20.19.43)(typescript@5.9.3):
|
||||
dependencies:
|
||||
@@ -8242,7 +8516,7 @@ snapshots:
|
||||
|
||||
webpack-sources@3.5.1: {}
|
||||
|
||||
webpack@5.97.1:
|
||||
webpack@5.97.1(esbuild@0.25.12):
|
||||
dependencies:
|
||||
'@types/eslint-scope': 3.7.7
|
||||
'@types/estree': 1.0.9
|
||||
@@ -8264,7 +8538,7 @@ snapshots:
|
||||
neo-async: 2.6.2
|
||||
schema-utils: 3.3.0
|
||||
tapable: 2.3.3
|
||||
terser-webpack-plugin: 5.6.1(webpack@5.97.1)
|
||||
terser-webpack-plugin: 5.6.1(esbuild@0.25.12)(webpack@5.97.1(esbuild@0.25.12))
|
||||
watchpack: 2.5.2
|
||||
webpack-sources: 3.5.1
|
||||
transitivePeerDependencies:
|
||||
|
||||
Reference in New Issue
Block a user