tempest.games 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/bin/backend.bun.js +1 -1
- package/bin/backend.worker.tribunal.bun.js +38 -0
- package/bin/setup-db.bun.js +3195 -8
- package/drizzle/0000_fine_hardball.sql +33 -0
- package/drizzle/0001_public_greymalkin.sql +101 -0
- package/drizzle/0002_loud_stature.sql +33 -0
- package/drizzle/0003_lyrical_malice.sql +2 -0
- package/drizzle/0004_funny_tana_nile.sql +1 -0
- package/drizzle/0005_reflective_warstar.sql +1 -0
- package/drizzle/0006_mushy_young_avengers.sql +2 -0
- package/drizzle/0007_charming_strong_guy.sql +8 -0
- package/drizzle/meta/0000_snapshot.json +168 -0
- package/drizzle/meta/0001_snapshot.json +471 -0
- package/drizzle/meta/0002_snapshot.json +471 -0
- package/drizzle/meta/0003_snapshot.json +471 -0
- package/drizzle/meta/0004_snapshot.json +465 -0
- package/drizzle/meta/0005_snapshot.json +465 -0
- package/drizzle/meta/0006_snapshot.json +465 -0
- package/drizzle/meta/0007_snapshot.json +465 -0
- package/drizzle/meta/_journal.json +62 -0
- package/package.json +6 -5
- package/__scripts__/destroy-db.bun.ts +0 -29
- package/__scripts__/setup-db.bun.ts +0 -57
- package/__scripts__/setup.vitest.ts +0 -5
package/CHANGELOG.md
CHANGED
package/bin/backend.bun.js
CHANGED
|
@@ -60,4 +60,4 @@ var s4=Object.create;var{getPrototypeOf:j4,defineProperty:pl,getOwnPropertyNames
|
|
|
60
60
|
hash text NOT NULL,
|
|
61
61
|
created_at bigint
|
|
62
62
|
)
|
|
63
|
-
`;await i.execute(F`CREATE SCHEMA IF NOT EXISTS ${F.identifier(p)}`),await i.execute(a);const m=(await i.all(F`select id, hash, created_at from ${F.identifier(p)}.${F.identifier(c)} order by created_at desc limit 1`))[0];await i.transaction(async(l)=>{for await(let f of n)if(!m||Number(m.created_at)<f.folderMillis){for(let $ of f.sql)await l.execute(F.raw($));await l.execute(F`insert into ${F.identifier(p)}.${F.identifier(c)} ("hash", "created_at") values(${f.hash}, ${f.folderMillis})`)}})}escapeName(n){return`"${n}"`}escapeParam(n){return`\$${n+1}`}escapeString(n){return`'${n.replace(/'/g,"''")}'`}buildWithCTE(n){if(!n?.length)return;const i=[F`with `];for(let[o,c]of n.entries())if(i.push(F`${F.identifier(c._.alias)} as (${c._.sql})`),o<n.length-1)i.push(F`, `);return i.push(F` `),F.join(i)}buildDeleteQuery({table:n,where:i,returning:o,withList:c}){const p=this.buildWithCTE(c),a=o?F` returning ${this.buildSelection(o,{isSingleTable:!0})}`:void 0,x=i?F` where ${i}`:void 0;return F`${p}delete from ${n}${x}${a}`}buildUpdateSet(n,i){const o=n[D.Symbol.Columns],c=Object.keys(o).filter((a)=>i[a]!==void 0||o[a]?.onUpdateFn!==void 0),p=c.length;return F.join(c.flatMap((a,x)=>{const m=o[a],l=i[a]??F.param(m.onUpdateFn(),m),f=F`${F.identifier(this.casing.getColumnCasing(m))} = ${l}`;if(x<p-1)return[f,F.raw(", ")];return[f]}))}buildUpdateQuery({table:n,set:i,where:o,returning:c,withList:p}){const a=this.buildWithCTE(p),x=this.buildUpdateSet(n,i),m=c?F` returning ${this.buildSelection(c,{isSingleTable:!0})}`:void 0,l=o?F` where ${o}`:void 0;return F`${a}update ${n} set ${x}${l}${m}`}buildSelection(n,{isSingleTable:i=!1}={}){const o=n.length,c=n.flatMap(({field:p},a)=>{const x=[];if(u(p,t.Aliased)&&p.isSelectionField)x.push(F.identifier(p.fieldAlias));else if(u(p,t.Aliased)||u(p,t)){const m=u(p,t.Aliased)?p.sql:p;if(i)x.push(new t(m.queryChunks.map((l)=>{if(u(l,j))return F.identifier(this.casing.getColumnCasing(l));return l})));else x.push(m);if(u(p,t.Aliased))x.push(F` as ${F.identifier(p.fieldAlias)}`)}else if(u(p,_n))if(i)x.push(F.identifier(this.casing.getColumnCasing(p)));else x.push(p);if(a<o-1)x.push(F`, `);return x});return F.join(c)}buildSelectQuery({withList:n,fields:i,fieldsFlat:o,where:c,having:p,table:a,joins:x,orderBy:m,groupBy:l,limit:f,offset:$,lockingClause:v,distinct:S,setOperators:T}){const R=o??di(i);for(let ln of R)if(u(ln.field,_n)&&gi(ln.field.table)!==(u(a,fi)?a._.alias:u(a,da)?a[hn].name:u(a,t)?void 0:gi(a))&&!(($n)=>x?.some(({alias:Un})=>Un===($n[D.Symbol.IsAlias]?gi($n):$n[D.Symbol.BaseName])))(ln.field.table)){const $n=gi(ln.field.table);throw new Error(`Your "${ln.path.join("->")}" field references a column "${$n}"."${ln.field.name}", but the table "${$n}" is not part of the query! Did you forget to join it?`)}const A=!x||x.length===0,X=this.buildWithCTE(n);let G;if(S)G=S===!0?F` distinct`:F` distinct on (${F.join(S.on,F`, `)})`;const Y=this.buildSelection(R,{isSingleTable:A}),E=(()=>{if(u(a,D)&&a[D.Symbol.OriginalName]!==a[D.Symbol.Name]){let ln=F`${F.identifier(a[D.Symbol.OriginalName])}`;if(a[D.Symbol.Schema])ln=F`${F.identifier(a[D.Symbol.Schema])}.${ln}`;return F`${ln} ${F.identifier(a[D.Symbol.Name])}`}return a})(),s=[];if(x)for(let[ln,$n]of x.entries()){if(ln===0)s.push(F` `);const Un=$n.table,si=$n.lateral?F` lateral`:void 0;if(u(Un,So)){const H=Un[So.Symbol.Name],k=Un[So.Symbol.Schema],Sn=Un[So.Symbol.OriginalName],Gn=H===Sn?void 0:$n.alias;s.push(F`${F.raw($n.joinType)} join${si} ${k?F`${F.identifier(k)}.`:void 0}${F.identifier(Sn)}${Gn&&F` ${F.identifier(Gn)}`} on ${$n.on}`)}else if(u(Un,Ui)){const H=Un[hn].name,k=Un[hn].schema,Sn=Un[hn].originalName,Gn=H===Sn?void 0:$n.alias;s.push(F`${F.raw($n.joinType)} join${si} ${k?F`${F.identifier(k)}.`:void 0}${F.identifier(Sn)}${Gn&&F` ${F.identifier(Gn)}`} on ${$n.on}`)}else s.push(F`${F.raw($n.joinType)} join${si} ${Un} on ${$n.on}`);if(ln<x.length-1)s.push(F` `)}const z=F.join(s),M=c?F` where ${c}`:void 0,O=p?F` having ${p}`:void 0;let U;if(m&&m.length>0)U=F` order by ${F.join(m,F`, `)}`;let V;if(l&&l.length>0)V=F` group by ${F.join(l,F`, `)}`;const K=typeof f==="object"||typeof f==="number"&&f>=0?F` limit ${f}`:void 0,y=$?F` offset ${$}`:void 0,_=F.empty();if(v){const ln=F` for ${F.raw(v.strength)}`;if(v.config.of)ln.append(F` of ${F.join(Array.isArray(v.config.of)?v.config.of:[v.config.of],F`, `)}`);if(v.config.noWait)ln.append(F` no wait`);else if(v.config.skipLocked)ln.append(F` skip locked`);_.append(ln)}const P=F`${X}select${G} ${Y} from ${E}${z}${M}${V}${O}${U}${K}${y}${_}`;if(T.length>0)return this.buildSetOperations(P,T);return P}buildSetOperations(n,i){const[o,...c]=i;if(!o)throw new Error("Cannot pass undefined values to any set operator");if(c.length===0)return this.buildSetOperationQuery({leftSelect:n,setOperator:o});return this.buildSetOperations(this.buildSetOperationQuery({leftSelect:n,setOperator:o}),c)}buildSetOperationQuery({leftSelect:n,setOperator:{type:i,isAll:o,rightSelect:c,limit:p,orderBy:a,offset:x}}){const m=F`(${n.getSQL()}) `,l=F`(${c.getSQL()})`;let f;if(a&&a.length>0){const T=[];for(let R of a)if(u(R,j))T.push(F.identifier(R.name));else if(u(R,t)){for(let A=0;A<R.queryChunks.length;A++){const X=R.queryChunks[A];if(u(X,j))R.queryChunks[A]=F.identifier(X.name)}T.push(F`${R}`)}else T.push(F`${R}`);f=F` order by ${F.join(T,F`, `)} `}const $=typeof p==="object"||typeof p==="number"&&p>=0?F` limit ${p}`:void 0,v=F.raw(`${i} ${o?"all ":""}`),S=x?F` offset ${x}`:void 0;return F`${m}${v}${l}${f}${$}${S}`}buildInsertQuery({table:n,values:i,onConflict:o,returning:c,withList:p}){const a=[],x=n[D.Symbol.Columns],m=Object.entries(x).filter(([T,R])=>!R.shouldDisableInsert()),l=m.map(([,T])=>F.identifier(this.casing.getColumnCasing(T)));for(let[T,R]of i.entries()){const A=[];for(let[X,G]of m){const Y=R[X];if(Y===void 0||u(Y,Li)&&Y.value===void 0)if(G.defaultFn!==void 0){const E=G.defaultFn(),s=u(E,t)?E:F.param(E,G);A.push(s)}else if(!G.default&&G.onUpdateFn!==void 0){const E=G.onUpdateFn(),s=u(E,t)?E:F.param(E,G);A.push(s)}else A.push(F`default`);else A.push(Y)}if(a.push(A),T<i.length-1)a.push(F`, `)}const f=this.buildWithCTE(p),$=F.join(a),v=c?F` returning ${this.buildSelection(c,{isSingleTable:!0})}`:void 0,S=o?F` on conflict ${o}`:void 0;return F`${f}insert into ${n} ${l} values ${$}${S}${v}`}buildRefreshMaterializedViewQuery({view:n,concurrently:i,withNoData:o}){const c=i?F` concurrently`:void 0,p=o?F` with no data`:void 0;return F`refresh materialized view${c} ${n}${p}`}prepareTyping(n){if(u(n,ex)||u(n,Px))return"json";else if(u(n,gx))return"decimal";else if(u(n,dx))return"time";else if(u(n,nm)||u(n,im))return"timestamp";else if(u(n,rx)||u(n,Zx))return"date";else if(u(n,om))return"uuid";else return"none"}sqlToQuery(n,i){return n.toQuery({casing:this.casing,escapeName:this.escapeName,escapeParam:this.escapeParam,escapeString:this.escapeString,prepareTyping:this.prepareTyping,invokeSource:i})}buildRelationalQueryWithoutPK({fullSchema:n,schema:i,tableNamesMap:o,table:c,tableConfig:p,queryConfig:a,tableAlias:x,nestedQueryRelation:m,joinOn:l}){let f=[],$,v,S=[],T;const R=[];if(a===!0)f=Object.entries(p.columns).map(([G,Y])=>({dbKey:Y.name,tsKey:G,field:Oo(Y,x),relationTableTsKey:void 0,isJson:!1,selection:[]}));else{const X=Object.fromEntries(Object.entries(p.columns).map(([M,O])=>[M,Oo(O,x)]));if(a.where){const M=typeof a.where==="function"?a.where(X,kJ()):a.where;T=M&&ua(M,x)}const G=[];let Y=[];if(a.columns){let M=!1;for(let[O,U]of Object.entries(a.columns)){if(U===void 0)continue;if(O in p.columns){if(!M&&U===!0)M=!0;Y.push(O)}}if(Y.length>0)Y=M?Y.filter((O)=>a.columns?.[O]===!0):Object.keys(p.columns).filter((O)=>!Y.includes(O))}else Y=Object.keys(p.columns);for(let M of Y){const O=p.columns[M];G.push({tsKey:M,value:O})}let E=[];if(a.with)E=Object.entries(a.with).filter((M)=>!!M[1]).map(([M,O])=>({tsKey:M,queryConfig:O,relation:p.relations[M]}));let s;if(a.extras){s=typeof a.extras==="function"?a.extras(X,{sql:F}):a.extras;for(let[M,O]of Object.entries(s))G.push({tsKey:M,value:Tf(O,x)})}for(let{tsKey:M,value:O}of G)f.push({dbKey:u(O,t.Aliased)?O.fieldAlias:p.columns[M].name,tsKey:M,field:u(O,_n)?Oo(O,x):O,relationTableTsKey:void 0,isJson:!1,selection:[]});let z=typeof a.orderBy==="function"?a.orderBy(X,rJ()):a.orderBy??[];if(!Array.isArray(z))z=[z];S=z.map((M)=>{if(u(M,_n))return Oo(M,x);return ua(M,x)}),$=a.limit,v=a.offset;for(let{tsKey:M,queryConfig:O,relation:U}of E){const V=qJ(i,o,U),K=Oc(U.referencedTable),y=o[K],_=`${x}_${M}`,P=Hc(...V.fields.map((Un,si)=>Ho(Oo(V.references[si],_),Oo(Un,x)))),ln=this.buildRelationalQueryWithoutPK({fullSchema:n,schema:i,tableNamesMap:o,table:n[y],tableConfig:i[y],queryConfig:u(U,xc)?O===!0?{limit:1}:{...O,limit:1}:O,tableAlias:_,joinOn:P,nestedQueryRelation:U}),$n=F`${F.identifier(_)}.${F.identifier("data")}`.as(M);R.push({on:F`true`,table:new fi(ln.sql,{},_),alias:_,joinType:"left",lateral:!0}),f.push({dbKey:M,tsKey:M,field:$n,relationTableTsKey:y,isJson:!0,selection:ln.selection})}}if(f.length===0)throw new Cx({message:`No fields selected for table "${p.tsName}" ("${x}")`});let A;if(T=Hc(l,T),m){let X=F`json_build_array(${F.join(f.map(({field:E,tsKey:s,isJson:z})=>z?F`${F.identifier(`${x}_${s}`)}.${F.identifier("data")}`:u(E,t.Aliased)?E.sql:E),F`, `)})`;if(u(m,Ea))X=F`coalesce(json_agg(${X}${S.length>0?F` order by ${F.join(S,F`, `)}`:void 0}), '[]'::json)`;const G=[{dbKey:"data",tsKey:"data",field:X.as("data"),isJson:!0,relationTableTsKey:p.tsName,selection:f}];if($!==void 0||v!==void 0||S.length>0)A=this.buildSelectQuery({table:Ix(c,x),fields:{},fieldsFlat:[{path:[],field:F.raw("*")}],where:T,limit:$,offset:v,orderBy:S,setOperators:[]}),T=void 0,$=void 0,v=void 0,S=[];else A=Ix(c,x);A=this.buildSelectQuery({table:u(A,So)?A:new fi(A,{},x),fields:{},fieldsFlat:G.map(({field:E})=>({path:[],field:u(E,_n)?Oo(E,x):E})),joins:R,where:T,limit:$,offset:v,orderBy:S,setOperators:[]})}else A=this.buildSelectQuery({table:Ix(c,x),fields:{},fieldsFlat:f.map(({field:X})=>({path:[],field:u(X,_n)?Oo(X,x):X})),joins:R,where:T,limit:$,offset:v,orderBy:S,setOperators:[]});return{tableTsKey:p.tsName,sql:A,selection:f}}}class _i{static[J]="SelectionProxyHandler";config;constructor(n){this.config={...n}}get(n,i){if(i==="_")return{...n._,selectedFields:new Proxy(n._.selectedFields,this)};if(i===hn)return{...n[hn],selectedFields:new Proxy(n[hn].selectedFields,this)};if(typeof i==="symbol")return n[i];const c=(u(n,fi)?n._.selectedFields:u(n,Ui)?n[hn].selectedFields:n)[i];if(u(c,t.Aliased)){if(this.config.sqlAliasedBehavior==="sql"&&!c.isSelectionField)return c.sql;const p=c.clone();return p.isSelectionField=!0,p}if(u(c,t)){if(this.config.sqlBehavior==="sql")return c;throw new Error(`You tried to reference "${i}" field from a subquery, which is a raw SQL field, but it doesn't have an alias declared. Please add an alias to the field using ".as('alias')" method.`)}if(u(c,_n)){if(this.config.alias)return new Proxy(c,new wp(new Proxy(c.table,new Ya(this.config.alias,this.config.replaceOriginalName??!1))));return c}if(typeof c!=="object"||c===null)return c;return new Proxy(c,new _i(this.config))}}class t${static[J]="TypedQueryBuilder";getSelectedFields(){return this._.selectedFields}}function rp(n,i){return(o,c,...p)=>{const a=[c,...p].map((x)=>({type:n,isAll:i,rightSelect:x}));for(let x of a)if(!Wf(o.getSelectedFields(),x.rightSelect.getSelectedFields()))throw new Error("Set operator error (union / intersect / except): selected fields are not the same or are in a different order");return o.addSetOperators(a)}}class Ei{static[J]="PgSelectBuilder";fields;session;dialect;withList=[];distinct;constructor(n){if(this.fields=n.fields,this.session=n.session,this.dialect=n.dialect,n.withList)this.withList=n.withList;this.distinct=n.distinct}from(n){const i=!!this.fields;let o;if(this.fields)o=this.fields;else if(u(n,fi))o=Object.fromEntries(Object.keys(n._.selectedFields).map((c)=>[c,n[c]]));else if(u(n,da))o=n[hn].selectedFields;else if(u(n,t))o={};else o=gS(n);return new k$({table:n,fields:o,isPartialSelect:i,session:this.session,dialect:this.dialect,withList:this.withList,distinct:this.distinct})}}class MR extends t${static[J]="PgSelectQueryBuilder";_;config;joinsNotNullableMap;tableName;isPartialSelect;session;dialect;constructor({table:n,fields:i,isPartialSelect:o,session:c,dialect:p,withList:a,distinct:x}){super();this.config={withList:a,table:n,fields:{...i},distinct:x,setOperators:[]},this.isPartialSelect=o,this.session=c,this.dialect=p,this._={selectedFields:i},this.tableName=Xf(n),this.joinsNotNullableMap=typeof this.tableName==="string"?{[this.tableName]:!0}:{}}createJoin(n){return(i,o)=>{const c=this.tableName,p=Xf(i);if(typeof p==="string"&&this.config.joins?.some((a)=>a.alias===p))throw new Error(`Alias "${p}" is already used in this query`);if(!this.isPartialSelect){if(Object.keys(this.joinsNotNullableMap).length===1&&typeof c==="string")this.config.fields={[c]:this.config.fields};if(typeof p==="string"&&!u(i,t)){const a=u(i,fi)?i._.selectedFields:u(i,Ui)?i[hn].selectedFields:i[D.Symbol.Columns];this.config.fields[p]=a}}if(typeof o==="function")o=o(new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"sql",sqlBehavior:"sql"})));if(!this.config.joins)this.config.joins=[];if(this.config.joins.push({on:o,table:i,joinType:n,alias:p}),typeof p==="string")switch(n){case"left":{this.joinsNotNullableMap[p]=!1;break}case"right":{this.joinsNotNullableMap=Object.fromEntries(Object.entries(this.joinsNotNullableMap).map(([a])=>[a,!1])),this.joinsNotNullableMap[p]=!0;break}case"inner":{this.joinsNotNullableMap[p]=!0;break}case"full":{this.joinsNotNullableMap=Object.fromEntries(Object.entries(this.joinsNotNullableMap).map(([a])=>[a,!1])),this.joinsNotNullableMap[p]=!1;break}}return this}}leftJoin=this.createJoin("left");rightJoin=this.createJoin("right");innerJoin=this.createJoin("inner");fullJoin=this.createJoin("full");createSetOperator(n,i){return(o)=>{const c=typeof o==="function"?o(ZG()):o;if(!Wf(this.getSelectedFields(),c.getSelectedFields()))throw new Error("Set operator error (union / intersect / except): selected fields are not the same or are in a different order");return this.config.setOperators.push({type:n,isAll:i,rightSelect:c}),this}}union=this.createSetOperator("union",!1);unionAll=this.createSetOperator("union",!0);intersect=this.createSetOperator("intersect",!1);intersectAll=this.createSetOperator("intersect",!0);except=this.createSetOperator("except",!1);exceptAll=this.createSetOperator("except",!0);addSetOperators(n){return this.config.setOperators.push(...n),this}where(n){if(typeof n==="function")n=n(new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"sql",sqlBehavior:"sql"})));return this.config.where=n,this}having(n){if(typeof n==="function")n=n(new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"sql",sqlBehavior:"sql"})));return this.config.having=n,this}groupBy(...n){if(typeof n[0]==="function"){const i=n[0](new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"alias",sqlBehavior:"sql"})));this.config.groupBy=Array.isArray(i)?i:[i]}else this.config.groupBy=n;return this}orderBy(...n){if(typeof n[0]==="function"){const i=n[0](new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"alias",sqlBehavior:"sql"}))),o=Array.isArray(i)?i:[i];if(this.config.setOperators.length>0)this.config.setOperators.at(-1).orderBy=o;else this.config.orderBy=o}else{const i=n;if(this.config.setOperators.length>0)this.config.setOperators.at(-1).orderBy=i;else this.config.orderBy=i}return this}limit(n){if(this.config.setOperators.length>0)this.config.setOperators.at(-1).limit=n;else this.config.limit=n;return this}offset(n){if(this.config.setOperators.length>0)this.config.setOperators.at(-1).offset=n;else this.config.offset=n;return this}for(n,i={}){return this.config.lockingClause={strength:n,config:i},this}getSQL(){return this.dialect.buildSelectQuery(this.config)}toSQL(){const{typings:n,...i}=this.dialect.sqlToQuery(this.getSQL());return i}as(n){return new Proxy(new fi(this.getSQL(),this.config.fields,n),new _i({alias:n,sqlAliasedBehavior:"alias",sqlBehavior:"error"}))}getSelectedFields(){return new Proxy(this.config.fields,new _i({alias:this.tableName,sqlAliasedBehavior:"alias",sqlBehavior:"error"}))}$dynamic(){return this}}class k$ extends MR{static[J]="PgSelect";_prepare(n){const{session:i,config:o,dialect:c,joinsNotNullableMap:p}=this;if(!i)throw new Error("Cannot execute a query on a query builder. Please use a database instance instead.");return En.startActiveSpan("drizzle.prepareQuery",()=>{const a=di(o.fields),x=i.prepareQuery(c.sqlToQuery(this.getSQL()),a,n,!0);return x.joinsNotNullableMap=p,x})}prepare(n){return this._prepare(n)}execute=(n)=>{return En.startActiveSpan("drizzle.operation",()=>{return this._prepare().execute(n)})}}eS(k$,[ui]);var ZG=()=>({union:qG,unionAll:PG,intersect:eG,intersectAll:gG,except:dG,exceptAll:nz}),qG=rp("union",!1),PG=rp("union",!0),eG=rp("intersect",!1),gG=rp("intersect",!0),dG=rp("except",!1),nz=rp("except",!0);class r${static[J]="PgQueryBuilder";dialect;dialectConfig;constructor(n){this.dialect=u(n,kc)?n:void 0,this.dialectConfig=u(n,kc)?void 0:n}$with(n){const i=this;return{as(o){if(typeof o==="function")o=o(i);return new Proxy(new za(o.getSQL(),o.getSelectedFields(),n,!0),new _i({alias:n,sqlAliasedBehavior:"alias",sqlBehavior:"error"}))}}}with(...n){const i=this;function o(a){return new Ei({fields:a??void 0,session:void 0,dialect:i.getDialect(),withList:n})}function c(a){return new Ei({fields:a??void 0,session:void 0,dialect:i.getDialect(),distinct:!0})}function p(a,x){return new Ei({fields:x??void 0,session:void 0,dialect:i.getDialect(),distinct:{on:a}})}return{select:o,selectDistinct:c,selectDistinctOn:p}}select(n){return new Ei({fields:n??void 0,session:void 0,dialect:this.getDialect()})}selectDistinct(n){return new Ei({fields:n??void 0,session:void 0,dialect:this.getDialect(),distinct:!0})}selectDistinctOn(n,i){return new Ei({fields:i??void 0,session:void 0,dialect:this.getDialect(),distinct:{on:n}})}getDialect(){if(!this.dialect)this.dialect=new kc(this.dialectConfig);return this.dialect}}class Z$ extends ui{constructor(n,i,o){super();this.session=i,this.dialect=o,this.config={view:n}}static[J]="PgRefreshMaterializedView";config;concurrently(){if(this.config.withNoData!==void 0)throw new Error("Cannot use concurrently and withNoData together");return this.config.concurrently=!0,this}withNoData(){if(this.config.concurrently!==void 0)throw new Error("Cannot use concurrently and withNoData together");return this.config.withNoData=!0,this}getSQL(){return this.dialect.buildRefreshMaterializedViewQuery(this.config)}toSQL(){const{typings:n,...i}=this.dialect.sqlToQuery(this.getSQL());return i}_prepare(n){return En.startActiveSpan("drizzle.prepareQuery",()=>{return this.session.prepareQuery(this.dialect.sqlToQuery(this.getSQL()),void 0,n,!0)})}prepare(n){return this._prepare(n)}execute=(n)=>{return En.startActiveSpan("drizzle.operation",()=>{return this._prepare().execute(n)})}}class qm{constructor(n,i,o,c){this.table=n,this.session=i,this.dialect=o,this.withList=c}static[J]="PgUpdateBuilder";set(n){return new RR(this.table,kx(this.table,n),this.session,this.dialect,this.withList)}}class RR extends ui{constructor(n,i,o,c,p){super();this.session=o,this.dialect=c,this.config={set:i,table:n,withList:p}}static[J]="PgUpdate";config;where(n){return this.config.where=n,this}returning(n=this.config.table[D.Symbol.Columns]){return this.config.returning=di(n),this}getSQL(){return this.dialect.buildUpdateQuery(this.config)}toSQL(){const{typings:n,...i}=this.dialect.sqlToQuery(this.getSQL());return i}_prepare(n){return this.session.prepareQuery(this.dialect.sqlToQuery(this.getSQL()),this.config.returning,n,!0)}prepare(n){return this._prepare(n)}execute=(n)=>{return this._prepare().execute(n)};$dynamic(){return this}}class nx extends t{constructor(n){super(nx.buildEmbeddedCount(n.source,n.filters).queryChunks);this.params=n,this.mapWith(Number),this.session=n.session,this.sql=nx.buildCount(n.source,n.filters)}sql;static[J]="PgCountBuilder";[Symbol.toStringTag]="PgCountBuilder";session;static buildEmbeddedCount(n,i){return F`(select count(*) from ${n}${F.raw(" where ").if(i)}${i})`}static buildCount(n,i){return F`select count(*) as count from ${n}${F.raw(" where ").if(i)}${i};`}then(n,i){return Promise.resolve(this.session.count(this.sql)).then(n,i)}catch(n){return this.then(void 0,n)}finally(n){return this.then((i)=>{return n?.(),i},(i)=>{throw n?.(),i})}}class P${constructor(n,i,o,c,p,a,x){this.fullSchema=n,this.schema=i,this.tableNamesMap=o,this.table=c,this.tableConfig=p,this.dialect=a,this.session=x}static[J]="PgRelationalQueryBuilder";findMany(n){return new q$(this.fullSchema,this.schema,this.tableNamesMap,this.table,this.tableConfig,this.dialect,this.session,n?n:{},"many")}findFirst(n){return new q$(this.fullSchema,this.schema,this.tableNamesMap,this.table,this.tableConfig,this.dialect,this.session,n?{...n,limit:1}:{limit:1},"first")}}class q$ extends ui{constructor(n,i,o,c,p,a,x,m,l){super();this.fullSchema=n,this.schema=i,this.tableNamesMap=o,this.table=c,this.tableConfig=p,this.dialect=a,this.session=x,this.config=m,this.mode=l}static[J]="PgRelationalQuery";_prepare(n){return En.startActiveSpan("drizzle.prepareQuery",()=>{const{query:i,builtQuery:o}=this._toSQL();return this.session.prepareQuery(o,void 0,n,!0,(c,p)=>{const a=c.map((x)=>cm(this.schema,this.tableConfig,x,i.selection,p));if(this.mode==="first")return a[0];return a})})}prepare(n){return this._prepare(n)}_getQuery(){return this.dialect.buildRelationalQueryWithoutPK({fullSchema:this.fullSchema,schema:this.schema,tableNamesMap:this.tableNamesMap,table:this.table,tableConfig:this.tableConfig,queryConfig:this.config,tableAlias:this.tableConfig.tsName})}getSQL(){return this._getQuery().sql}_toSQL(){const n=this._getQuery(),i=this.dialect.sqlToQuery(n.sql);return{query:n,builtQuery:i}}toSQL(){return this._toSQL().builtQuery}execute(){return En.startActiveSpan("drizzle.operation",()=>{return this._prepare().execute()})}}class e$ extends ui{constructor(n,i,o,c){super();this.execute=n,this.sql=i,this.query=o,this.mapBatchResult=c}static[J]="PgRaw";getSQL(){return this.sql}getQuery(){return this.query}mapResult(n,i){return i?this.mapBatchResult(n):n}_prepare(){return this}isResponseInArrayMode(){return!1}}class ix{constructor(n,i,o){if(this.dialect=n,this.session=i,this._=o?{schema:o.schema,fullSchema:o.fullSchema,tableNamesMap:o.tableNamesMap,session:i}:{schema:void 0,fullSchema:{},tableNamesMap:{},session:i},this.query={},this._.schema)for(let[c,p]of Object.entries(this._.schema))this.query[c]=new P$(o.fullSchema,this._.schema,this._.tableNamesMap,o.fullSchema[c],p,n,i)}static[J]="PgDatabase";query;$with(n){const i=this;return{as(o){if(typeof o==="function")o=o(new r$(i.dialect));return new Proxy(new za(o.getSQL(),o.getSelectedFields(),n,!0),new _i({alias:n,sqlAliasedBehavior:"alias",sqlBehavior:"error"}))}}}$count(n,i){return new nx({source:n,filters:i,session:this.session})}with(...n){const i=this;function o(l){return new Ei({fields:l??void 0,session:i.session,dialect:i.dialect,withList:n})}function c(l){return new Ei({fields:l??void 0,session:i.session,dialect:i.dialect,withList:n,distinct:!0})}function p(l,f){return new Ei({fields:f??void 0,session:i.session,dialect:i.dialect,withList:n,distinct:{on:l}})}function a(l){return new qm(l,i.session,i.dialect,n)}function x(l){return new Zm(l,i.session,i.dialect,n)}function m(l){return new rm(l,i.session,i.dialect,n)}return{select:o,selectDistinct:c,selectDistinctOn:p,update:a,insert:x,delete:m}}select(n){return new Ei({fields:n??void 0,session:this.session,dialect:this.dialect})}selectDistinct(n){return new Ei({fields:n??void 0,session:this.session,dialect:this.dialect,distinct:!0})}selectDistinctOn(n,i){return new Ei({fields:i??void 0,session:this.session,dialect:this.dialect,distinct:{on:n}})}update(n){return new qm(n,this.session,this.dialect)}insert(n){return new Zm(n,this.session,this.dialect)}delete(n){return new rm(n,this.session,this.dialect)}refreshMaterializedView(n){return new Z$(n,this.session,this.dialect)}execute(n){const i=typeof n==="string"?F.raw(n):n.getSQL(),o=this.dialect.sqlToQuery(i),c=this.session.prepareQuery(o,void 0,void 0,!1);return new e$(()=>c.execute(),i,o,(p)=>c.mapResult(p,!0))}transaction(n,i){return this.session.transaction(n,i)}}function g$(n){return new KR(!0,n)}class KR{constructor(n,i){this.unique=n,this.name=i}static[J]="PgIndexBuilderOn";on(...n){return new Pm(n.map((i)=>{if(u(i,t))return i;i=i;const o=new Ga(i.name,!!i.keyAsName,i.columnType,i.indexConfig);return i.indexConfig=JSON.parse(JSON.stringify(i.defaultConfig)),o}),this.unique,!1,this.name)}onOnly(...n){return new Pm(n.map((i)=>{if(u(i,t))return i;i=i;const o=new Ga(i.name,!!i.keyAsName,i.columnType,i.indexConfig);return i.indexConfig=i.defaultConfig,o}),this.unique,!0,this.name)}using(n,...i){return new Pm(i.map((o)=>{if(u(o,t))return o;o=o;const c=new Ga(o.name,!!o.keyAsName,o.columnType,o.indexConfig);return o.indexConfig=JSON.parse(JSON.stringify(o.defaultConfig)),c}),this.unique,!0,this.name,n)}}class Pm{static[J]="PgIndexBuilder";config;constructor(n,i,o,c,p="btree"){this.config={name:c,columns:n,unique:i,only:o,method:p}}concurrently(){return this.config.concurrently=!0,this}with(n){return this.config.with=n,this}where(n){return this.config.where=n,this}build(n){return new WR(this.config,n)}}class WR{static[J]="PgIndex";config;constructor(n,i){this.config={...n,table:i}}}class d${constructor(n){this.query=n}getQuery(){return this.query}mapResult(n,i){return n}static[J]="PgPreparedQuery";joinsNotNullableMap}class nv{constructor(n){this.dialect=n}static[J]="PgSession";execute(n){return En.startActiveSpan("drizzle.operation",()=>{return En.startActiveSpan("drizzle.prepareQuery",()=>{return this.prepareQuery(this.dialect.sqlToQuery(n),void 0,void 0,!1)}).execute()})}all(n){return this.prepareQuery(this.dialect.sqlToQuery(n),void 0,void 0,!1).all()}async count(n){const i=await this.execute(n);return Number(i[0].count)}}class iv extends ix{constructor(n,i,o,c=0){super(n,i,o);this.schema=o,this.nestedIndex=c}static[J]="PgTransaction";rollback(){throw new Mf}getTransactionConfigSQL(n){const i=[];if(n.isolationLevel)i.push(`isolation level ${n.isolationLevel}`);if(n.accessMode)i.push(n.accessMode);if(typeof n.deferrable==="boolean")i.push(n.deferrable?"deferrable":"not deferrable");return F.raw(i.join(" "))}setTransaction(n){return this.session.execute(F`set transaction ${this.getTransactionConfigSQL(n)}`)}}class XR extends d${constructor(n,i,o,c,p,a,x){super({sql:i,params:o});this.client=n,this.queryString=i,this.params=o,this.logger=c,this.fields=p,this._isResponseInArrayMode=a,this.customResultMapper=x}static[J]="PostgresJsPreparedQuery";async execute(n={}){return En.startActiveSpan("drizzle.execute",async(i)=>{const o=Af(this.params,n);i?.setAttributes({"drizzle.query.text":this.queryString,"drizzle.query.params":JSON.stringify(o)}),this.logger.logQuery(this.queryString,o);const{fields:c,queryString:p,client:a,joinsNotNullableMap:x,customResultMapper:m}=this;if(!c&&!m)return En.startActiveSpan("drizzle.driver.execute",()=>{return a.unsafe(p,o)});const l=await En.startActiveSpan("drizzle.driver.execute",()=>{return i?.setAttributes({"drizzle.query.text":p,"drizzle.query.params":JSON.stringify(o)}),a.unsafe(p,o).values()});return En.startActiveSpan("drizzle.mapResponse",()=>{return m?m(l):l.map((f)=>PS(c,f,x))})})}all(n={}){return En.startActiveSpan("drizzle.execute",async(i)=>{const o=Af(this.params,n);return i?.setAttributes({"drizzle.query.text":this.queryString,"drizzle.query.params":JSON.stringify(o)}),this.logger.logQuery(this.queryString,o),En.startActiveSpan("drizzle.driver.execute",()=>{return i?.setAttributes({"drizzle.query.text":this.queryString,"drizzle.query.params":JSON.stringify(o)}),this.client.unsafe(this.queryString,o)})})}isResponseInArrayMode(){return this._isResponseInArrayMode}}class ox extends nv{constructor(n,i,o,c={}){super(i);this.client=n,this.schema=o,this.options=c,this.logger=c.logger??new Kf}static[J]="PostgresJsSession";logger;prepareQuery(n,i,o,c,p){return new XR(this.client,n.sql,n.params,this.logger,i,c,p)}query(n,i){return this.logger.logQuery(n,i),this.client.unsafe(n,i).values()}queryObjects(n,i){return this.client.unsafe(n,i)}transaction(n,i){return this.client.begin(async(o)=>{const c=new ox(o,this.dialect,this.schema,this.options),p=new ov(this.dialect,c,this.schema);if(i)await p.setTransaction(i);return n(p)})}}class ov extends iv{constructor(n,i,o,c=0){super(n,i,o,c);this.session=i}static[J]="PostgresJsTransaction";transaction(n){return this.session.client.savepoint((i)=>{const o=new ox(i,this.dialect,this.schema,this.session.options),c=new ov(this.dialect,o,this.schema);return n(c)})}}function Zp(n,i={}){const o=(l)=>l;for(let l of["1184","1082","1083","1114"])n.options.parsers[l]=o,n.options.serializers[l]=o;n.options.serializers["114"]=o,n.options.serializers["3802"]=o;const c=new kc({casing:i.casing});let p;if(i.logger===!0)p=new Rf;else if(i.logger!==!1)p=i.logger;let a;if(i.schema){const l=ZJ(i.schema,PJ);a={fullSchema:i.schema,schema:l.tables,tableNamesMap:l.tableNamesMap}}const x=new ox(n,c,a,{logger:p}),m=new GR(c,x,a);return m.$client=n,m}function em(...n){if(typeof n[0]==="function")return Zp(n[0],n[1]);if(typeof n[0]==="object"){const{connection:o,client:c,...p}=n[0];if(c)return Zp(c,p);if(typeof o==="object"&&o.url!==void 0){const{url:x,...m}=o,l=kp(x,m);return Zp(l,p)}const a=kp(o);return Zp(a,p)}const i=kp(n[0]);return Zp(i,n[1])}class GR extends ix{static[J]="PostgresJsDatabase"}((n)=>{function i(o){return Zp({},o)}n.mock=i})(em||(em={}));var pv={};y4(pv,{users:()=>Xo,userChanges:()=>oz,untrackedUserColumnNames:()=>iz,twoFactorMethod:()=>OR,trackedUserColumnName:()=>uR,trackableUserColumnNames:()=>YR,role:()=>zR,players:()=>cv,passwordResetAttempts:()=>cz,loginHistory:()=>qp,games:()=>gm,banishedIps:()=>dm});var zR=Bx("role",["admin","user"]),Xo=ac("users",{id:yi().primaryKey().defaultRandom(),username:$i({length:16}).notNull(),email:$i({length:254}).notNull(),hash:$i({length:64}).notNull(),salt:$i({length:36}).notNull(),createdAt:wo({withTimezone:!0}).notNull().defaultNow(),createdIp:$i({length:45}).notNull(),isActive:Oa().notNull().default(!1),verifiedAt:wo({withTimezone:!0}),userRole:zR().default("user")},(n)=>({usersUsernameUnique:g$().on(n.username),usersEmailUnique:g$().on(n.email)})),iz=["id","createdAt","createdIp","isActive","salt","verifiedAt"],YR=["username","email","hash","userRole"],uR=Bx("trackedUserColumnName",YR),oz=ac("userChanges",{id:yi().primaryKey().defaultRandom(),userId:yi().notNull().references(()=>Xo.id),changedAt:wo({withTimezone:!0}).notNull().defaultNow(),changedIp:$i({length:45}).notNull(),changedColumn:uR().notNull(),oldValue:$i({length:255}),newValue:$i({length:255})}),gm=ac("games",{id:yi("id").primaryKey().defaultRandom()}),cv=ac("players",{userId:yi().notNull().references(()=>Xo.id),gameId:yi().notNull().references(()=>gm.id),score:qx().notNull()},(n)=>({pk:IJ({columns:[n.userId,n.gameId]})})),qp=ac("loginHistory",{id:yi().primaryKey().defaultRandom(),userId:yi().references(()=>Xo.id),loginTime:wo({withTimezone:!0}).notNull().defaultNow(),ipAddress:$i({length:45}).notNull(),userAgent:$i({length:1024}),successful:Oa().notNull().default(!1)}),OR=Bx("twoFactorMethod",["email","phone"]),cz=ac("passwordResetAttempts",{id:yi().primaryKey().defaultRandom(),userId:yi().notNull().references(()=>Xo.id),requestedIp:$i({length:45}).notNull(),requestedAt:wo({withTimezone:!0}).notNull().defaultNow(),succeededIp:$i({length:45}),succeededAt:wo({withTimezone:!0}),verificationMethod:OR().notNull()}),dm=ac("banishedIps",{ip:$i({length:45}).primaryKey(),reason:$i({length:2048}).notNull(),banishedAt:wo({withTimezone:!0}).notNull().defaultNow(),banishedUntil:wo({withTimezone:!0})});var __dirname="/home/runner/work/wayforge/wayforge/apps/tempest.games/src/database";class av{options;sql;drizzle;observers=new Map;async setupTriggersAndNotifications(){await this.sql.file(pz.resolve(__dirname,"notify_update.sql"));const n=[gi(Xo),gi(gm),gi(cv)];await this.sql`SELECT create_notify_triggers(${this.sql.array(n)})`,await this.sql.listen("table_update",(i)=>{const o=i.split(","),c=o[0],p=o[1],a=`${c}("${p}")`;if(this.observers.has(a))this.observers.get(a).next(a)})}constructor(n={host:pi.POSTGRES_HOST,port:pi.POSTGRES_PORT,user:pi.POSTGRES_USER,password:pi.POSTGRES_PASSWORD,database:pi.POSTGRES_DATABASE}){this.options=n,this.sql=kp(n),this.drizzle=em(this.sql,{schema:pv})}observe(n,i){if(!this.observers.has(n))this.observers.set(n,new an);this.observers.get(n).subscribe("SINGLETON",i)}}import{createHash as az}from"crypto";function xv(n){const i=az("sha256").update(n).digest("hex");return`${i.substring(0,8)}-${i.substring(8,12)}-${i.substring(12,16)}-${i.substring(16,20)}-${i.substring(20,32)}`}var HR=["123","321","abc","admin","adobe","alexander","amanda","andrea","andrew","angel","apple","asdf","ashley","baby","banana","baseball","batman","bear","biteme","blazer","blonde","boston","buster","butterfly","cameron","charlie","cheese","chelsea","chicken","chocolate","chris","compaq","computer","cookie","corvette","cowboys","dakota","dallas","daniel","david","diamond","dolphin","donald","dragon","eagle","flower","football","frank","freedom","friend","gateway","george","ginger","god","golf","hannah","hardcore","harley","heather","hello","hottie","hunter","internet","jasmine","jennifer","jessica","jesus","johnny","jordan","joshua","justin","justme","killer","knight","lakers","letmein","liverpool","login","london","love","lucky","mackenzie","maggie","master","matrix","matthew","maverick","melissa","mercedes","michael","michelle","mickey","miller","money","monkey","morgan","mother","muffin","mustang","natasha","nathan","nicole","ninja","orange","pass","password","patrick","peanut","pepper","phoenix","photoshop","pokemon","princess","purple","qazwsx","qwerty","rainbow","ranger","root","samantha","samsung","scooter","secret","shadow","simpson","smile","soccer","sparkle","starwars","summer","sunflower","sunshine","superman","taylor","temp","test","thomas","tigers","tigger","tinkerbell","trust","turtle","victoria","welcome","whatever","william","winter","yellow","zaq12wsx","zxcvbn"];function fz(n){let i="";for(let o of n)if(o in QR)i+=QR[o];else i+=o;return i}function $z(n){const i=n.toLocaleLowerCase(),o=fz(i);for(let c of HR){if(o.includes(c))return!0;if(i.includes(c))return!0}return!1}function vz(n){const i=new Set(n).size;return n.length*Math.log2(i)}function wz(n){let i=0;const o=100;if($z(n))i-=o;return i+=vz(n)*0.5,Math.max(i,0)}var xz=3,mz=15,lz=/^[a-zA-Z0-9_-]+$/,UR=Qn.string().min(xz).max(mz).regex(lz),ER=20,QR={"0":"o","1":"l","3":"e","4":"a","5":"s","7":"t","@":"a",$:"s","!":"i"},VR=Qn.string().refine((n)=>{return wz(n)>=ER},{message:`Password does not meet the minimum complexity of ${ER}.`}).brand("password"),bR=Qn.object({username:UR,password:VR}).strict(),Sz=Qn.string().email().brand("email"),_R=Qn.object({username:UR,password:VR,email:Sz}).strict();var nl={100:"Continue",101:"Switching Protocols",102:"Processing",103:"Early Hints",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",208:"Already Reported",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Switch Proxy",307:"Temporary Redirect",308:"Permanent Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Payload Too Large",414:"URI Too Long",415:"Unsupported Media Type",416:"Range Not Satisfiable",417:"Expectation Failed",418:"I'm a teapot",421:"Misdirected Request",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",425:"Too Early",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",451:"Unavailable For Legal Reasons",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",508:"Loop Detected",510:"Not Extended",511:"Network Authentication Required"},mv=Kv(nl).map(([n])=>Qn.literal(Number(n))),Jz=Qn.union([mv[0],mv[1],...mv]),sR=Qn.tuple([Jz,Qn.string()]);var jR=Zo({key:"count",default:0}),Fz=Mc({key:"incrementTX",do:({set:n})=>{n(jR,(i)=>i+1)}}),NR=p0({key:"countContinuity",config:(n)=>n.add(jR).add(Fz)});async function fv(){Xn.info("\uD83E\uDDF9 dispatching SIGINT to workers"),yR.process.kill("SIGINT"),await new Promise((n)=>yR.process.once("exit",n)),Xn.info("\uD83D\uDEEC backend server exiting"),process.exit(0)}var yR=Y$(Dc,"backend.worker.game.bun",Xn),rc=new av,ah=(()=>{let{__tribunalDaily:n}=globalThis;if(!n)n=new DR.CronJob("00 00 03 * * *",()=>{Y$(Dc,"backend.worker.tribunal.bun",Xn)}),n.start(),process.on("exit",()=>{n.stop(),Xn.info("\u231B tribunal daily cronjob stopped")}),Xn.info("\u23F3 tribunal daily cronjob started");return n})(),hR=BR.createServer((n,i)=>{let o;n.on("data",(c)=>(o??=[]).push(c)).on("end",async()=>{const c=n.headers.authorization;try{if(typeof n.url==="undefined")throw[400,"No URL"];const p=n.socket.remoteAddress;if(!p)throw[400,"No IP address"];const a=new Date,x=new URL(n.url,pi.VITE_BACKEND_ORIGIN);Xn.info(a,p,n.method,x.pathname);const m=await rc.drizzle.query.banishedIps.findFirst({columns:{banishedUntil:!0},where:Ho(dm.ip,p)}),l=m?.banishedUntil===null,f=m?.banishedUntil&&m.banishedUntil>a;if(l||f){Xn.info(`\uD83D\uDE45 request from banned ip ${p}`);return}switch(n.method){case"POST":if(!o)throw[400,"No data received"];switch(x.pathname){case`/signup-${xv("signup")}`:{const $=Buffer.concat(o).toString(),v=JSON.parse($);Xn.info("signup json",v);const S=_R.safeParse(v);if(!S.success){Xn.warn("signup parsed",S.error.issues);return}const{username:T,password:R,email:A}=S.data;if(await rc.drizzle.query.users.findFirst({columns:{id:!0},where:Ho(Xo.email,A)}))throw[400,"User already exists"];const G=crypto.randomUUID(),Y=LR("sha256").update(R+G).digest("hex");await rc.drizzle.insert(Xo).values({username:T,email:A,hash:Y,salt:G,createdIp:p}),i.writeHead(201,{"Content-Type":"text/plain","Access-Control-Allow-Origin":`${pi.FRONTEND_ORIGINS[0]}`}),i.end(nl[201])}break;case`/login-${xv("login")}`:{let $=!1,v=null;try{const S=new Date(+a-600000);Xn.info("\uD83D\uDD11 ten minutes ago",{tenMinutesAgo:S,now:a});const T=await rc.drizzle.query.loginHistory.findMany({columns:{userId:!0,successful:!0},where:Hc(Ho(qp.ipAddress,p),Ho(qp.successful,!1),tx(qp.loginTime,S)),limit:10});Xn.info(`\uD83D\uDD11 ${T.length}/10 recent failed logins from ${p}`);const R=10-T.length;if(R<1)throw Xn.info(`\uD83D\uDD11 too many recent failed logins from ${p}`),await rc.drizzle.insert(dm).values({ip:p,reason:"Too many recent login attempts.",banishedAt:a,banishedUntil:new Date(+a+86400000)}),[429,"Too many recent login attempts."];const A=Buffer.concat(o).toString(),X=JSON.parse(A),G=bR.safeParse(X);if(!G.success)throw Xn.warn("login parsed",G.error.issues),[400,`${R} attempts remaining.`];const{username:Y,password:E}=G.data,s=await rc.drizzle.query.users.findFirst({columns:{id:!0,hash:!0,salt:!0},where:Ho(Xo.username,Y)});if(Xn.info("\uD83D\uDD11 login attempt as user",Y),!s)throw Xn.info(`\uD83D\uDD11 user ${Y} does not exist`),[400,`${R} attempts remaining.`];const{hash:z,salt:M}=s;if(v=s.id,LR("sha256").update(E+M).digest("hex")===z){const U=crypto.randomUUID();let V=sm.get(Y);if(!V)V=new Map,sm.set(Y,V);V.set(U,Number(a)),$=!0,Xn.info("\uD83D\uDD11 login successful as",Y),i.writeHead(200,{"Content-Type":"text/plain","Access-Control-Allow-Origin":`${pi.FRONTEND_ORIGINS[0]}`}),i.end(`${Y} ${U}`)}}finally{await rc.drizzle.insert(qp).values({userId:v,successful:$,ipAddress:p,userAgent:n.headers["user-agent"]??"Withheld"}),Xn.info(`\uD83D\uDD11 recorded login attempt from ${p}`)}}}}}catch(p){const a=sR.safeParse(p);if(a.success){const[x,m]=a.data,f=`${nl[x]}. ${m}`;Xn.info(`\u274C ${x}: ${f}`),i.writeHead(x,{"Content-Type":"text/plain","Access-Control-Allow-Origin":`${pi.FRONTEND_ORIGINS[0]}`}),i.end(f)}else Xn.error(p),i.writeHead(500,{"Content-Type":"text/plain","Access-Control-Allow-Origin":`${pi.FRONTEND_ORIGINS[0]}`}),i.end("Internal Server Error")}})}),lv=hR.listen(pi.BACKEND_PORT).address(),Az=typeof lv==="string"?null:lv===null?null:lv.port;if(Az===null)throw new Error("Could not determine port for test server");new jM(hR,{cors:{origin:pi.FRONTEND_ORIGINS,methods:["GET","POST"]}}).use((n,i)=>{const{username:o,sessionKey:c}=n.handshake.auth;if(!(o&&c)){i(new Error("No auth header provided"));return}if(sm.get(o)?.has(c)){const a=An(on.STORE,wa,n.id);zn(on.STORE,a,n),Rc(Kc,(x)=>{x.set(n.id,o)},on.STORE),zn(on.STORE,Ql,(x)=>x.add(o)),zn(on.STORE,El,(x)=>x.add(n.id)),Xn.info(`${o} connected on ${n.id}`),i()}else Xn.info(`${o} couldn't authenticate`),i(new Error("Authentication error"))}).on("connection",(n)=>{const o=m0({socket:n,store:on.STORE})(NR);n.on("disconnect",()=>{const c=np(Kc,n.id,on.STORE).userKeyOfSocket,p=Kn(on.STORE,c);if(Rc(Kc,(a)=>{a.delete(n.id)},on.STORE),p)zn(on.STORE,Ql,(a)=>(a.delete(p),a));zn(on.STORE,El,(a)=>(a.delete(n.id),a)),li(on.STORE,wa,n.id),Xn.info(`${n.id} disconnected`),o()})});Dc.emit("alive");Dc.on("updatesReady",()=>{Dc.emit("readyToUpdate")});process.on("SIGINT",async()=>{Xn.info("\u2757 received SIGINT; exiting gracefully"),await fv()});process.on("SIGTERM",async()=>{Xn.info("\u2757 received SIGTERM; exiting gracefully"),await fv()});process.on("exit",async()=>{Xn.info("\u2757 received exit; exiting gracefully"),await fv()});Xn.info(`\uD83D\uDEEB backend server ready on port ${pi.BACKEND_PORT}`);export{ah as tribunalDaily};
|
|
63
|
+
`;await i.execute(F`CREATE SCHEMA IF NOT EXISTS ${F.identifier(p)}`),await i.execute(a);const m=(await i.all(F`select id, hash, created_at from ${F.identifier(p)}.${F.identifier(c)} order by created_at desc limit 1`))[0];await i.transaction(async(l)=>{for await(let f of n)if(!m||Number(m.created_at)<f.folderMillis){for(let $ of f.sql)await l.execute(F.raw($));await l.execute(F`insert into ${F.identifier(p)}.${F.identifier(c)} ("hash", "created_at") values(${f.hash}, ${f.folderMillis})`)}})}escapeName(n){return`"${n}"`}escapeParam(n){return`\$${n+1}`}escapeString(n){return`'${n.replace(/'/g,"''")}'`}buildWithCTE(n){if(!n?.length)return;const i=[F`with `];for(let[o,c]of n.entries())if(i.push(F`${F.identifier(c._.alias)} as (${c._.sql})`),o<n.length-1)i.push(F`, `);return i.push(F` `),F.join(i)}buildDeleteQuery({table:n,where:i,returning:o,withList:c}){const p=this.buildWithCTE(c),a=o?F` returning ${this.buildSelection(o,{isSingleTable:!0})}`:void 0,x=i?F` where ${i}`:void 0;return F`${p}delete from ${n}${x}${a}`}buildUpdateSet(n,i){const o=n[D.Symbol.Columns],c=Object.keys(o).filter((a)=>i[a]!==void 0||o[a]?.onUpdateFn!==void 0),p=c.length;return F.join(c.flatMap((a,x)=>{const m=o[a],l=i[a]??F.param(m.onUpdateFn(),m),f=F`${F.identifier(this.casing.getColumnCasing(m))} = ${l}`;if(x<p-1)return[f,F.raw(", ")];return[f]}))}buildUpdateQuery({table:n,set:i,where:o,returning:c,withList:p}){const a=this.buildWithCTE(p),x=this.buildUpdateSet(n,i),m=c?F` returning ${this.buildSelection(c,{isSingleTable:!0})}`:void 0,l=o?F` where ${o}`:void 0;return F`${a}update ${n} set ${x}${l}${m}`}buildSelection(n,{isSingleTable:i=!1}={}){const o=n.length,c=n.flatMap(({field:p},a)=>{const x=[];if(u(p,t.Aliased)&&p.isSelectionField)x.push(F.identifier(p.fieldAlias));else if(u(p,t.Aliased)||u(p,t)){const m=u(p,t.Aliased)?p.sql:p;if(i)x.push(new t(m.queryChunks.map((l)=>{if(u(l,j))return F.identifier(this.casing.getColumnCasing(l));return l})));else x.push(m);if(u(p,t.Aliased))x.push(F` as ${F.identifier(p.fieldAlias)}`)}else if(u(p,_n))if(i)x.push(F.identifier(this.casing.getColumnCasing(p)));else x.push(p);if(a<o-1)x.push(F`, `);return x});return F.join(c)}buildSelectQuery({withList:n,fields:i,fieldsFlat:o,where:c,having:p,table:a,joins:x,orderBy:m,groupBy:l,limit:f,offset:$,lockingClause:v,distinct:S,setOperators:T}){const R=o??di(i);for(let ln of R)if(u(ln.field,_n)&&gi(ln.field.table)!==(u(a,fi)?a._.alias:u(a,da)?a[hn].name:u(a,t)?void 0:gi(a))&&!(($n)=>x?.some(({alias:Un})=>Un===($n[D.Symbol.IsAlias]?gi($n):$n[D.Symbol.BaseName])))(ln.field.table)){const $n=gi(ln.field.table);throw new Error(`Your "${ln.path.join("->")}" field references a column "${$n}"."${ln.field.name}", but the table "${$n}" is not part of the query! Did you forget to join it?`)}const A=!x||x.length===0,X=this.buildWithCTE(n);let G;if(S)G=S===!0?F` distinct`:F` distinct on (${F.join(S.on,F`, `)})`;const Y=this.buildSelection(R,{isSingleTable:A}),E=(()=>{if(u(a,D)&&a[D.Symbol.OriginalName]!==a[D.Symbol.Name]){let ln=F`${F.identifier(a[D.Symbol.OriginalName])}`;if(a[D.Symbol.Schema])ln=F`${F.identifier(a[D.Symbol.Schema])}.${ln}`;return F`${ln} ${F.identifier(a[D.Symbol.Name])}`}return a})(),s=[];if(x)for(let[ln,$n]of x.entries()){if(ln===0)s.push(F` `);const Un=$n.table,si=$n.lateral?F` lateral`:void 0;if(u(Un,So)){const H=Un[So.Symbol.Name],k=Un[So.Symbol.Schema],Sn=Un[So.Symbol.OriginalName],Gn=H===Sn?void 0:$n.alias;s.push(F`${F.raw($n.joinType)} join${si} ${k?F`${F.identifier(k)}.`:void 0}${F.identifier(Sn)}${Gn&&F` ${F.identifier(Gn)}`} on ${$n.on}`)}else if(u(Un,Ui)){const H=Un[hn].name,k=Un[hn].schema,Sn=Un[hn].originalName,Gn=H===Sn?void 0:$n.alias;s.push(F`${F.raw($n.joinType)} join${si} ${k?F`${F.identifier(k)}.`:void 0}${F.identifier(Sn)}${Gn&&F` ${F.identifier(Gn)}`} on ${$n.on}`)}else s.push(F`${F.raw($n.joinType)} join${si} ${Un} on ${$n.on}`);if(ln<x.length-1)s.push(F` `)}const z=F.join(s),M=c?F` where ${c}`:void 0,O=p?F` having ${p}`:void 0;let U;if(m&&m.length>0)U=F` order by ${F.join(m,F`, `)}`;let V;if(l&&l.length>0)V=F` group by ${F.join(l,F`, `)}`;const K=typeof f==="object"||typeof f==="number"&&f>=0?F` limit ${f}`:void 0,y=$?F` offset ${$}`:void 0,_=F.empty();if(v){const ln=F` for ${F.raw(v.strength)}`;if(v.config.of)ln.append(F` of ${F.join(Array.isArray(v.config.of)?v.config.of:[v.config.of],F`, `)}`);if(v.config.noWait)ln.append(F` no wait`);else if(v.config.skipLocked)ln.append(F` skip locked`);_.append(ln)}const P=F`${X}select${G} ${Y} from ${E}${z}${M}${V}${O}${U}${K}${y}${_}`;if(T.length>0)return this.buildSetOperations(P,T);return P}buildSetOperations(n,i){const[o,...c]=i;if(!o)throw new Error("Cannot pass undefined values to any set operator");if(c.length===0)return this.buildSetOperationQuery({leftSelect:n,setOperator:o});return this.buildSetOperations(this.buildSetOperationQuery({leftSelect:n,setOperator:o}),c)}buildSetOperationQuery({leftSelect:n,setOperator:{type:i,isAll:o,rightSelect:c,limit:p,orderBy:a,offset:x}}){const m=F`(${n.getSQL()}) `,l=F`(${c.getSQL()})`;let f;if(a&&a.length>0){const T=[];for(let R of a)if(u(R,j))T.push(F.identifier(R.name));else if(u(R,t)){for(let A=0;A<R.queryChunks.length;A++){const X=R.queryChunks[A];if(u(X,j))R.queryChunks[A]=F.identifier(X.name)}T.push(F`${R}`)}else T.push(F`${R}`);f=F` order by ${F.join(T,F`, `)} `}const $=typeof p==="object"||typeof p==="number"&&p>=0?F` limit ${p}`:void 0,v=F.raw(`${i} ${o?"all ":""}`),S=x?F` offset ${x}`:void 0;return F`${m}${v}${l}${f}${$}${S}`}buildInsertQuery({table:n,values:i,onConflict:o,returning:c,withList:p}){const a=[],x=n[D.Symbol.Columns],m=Object.entries(x).filter(([T,R])=>!R.shouldDisableInsert()),l=m.map(([,T])=>F.identifier(this.casing.getColumnCasing(T)));for(let[T,R]of i.entries()){const A=[];for(let[X,G]of m){const Y=R[X];if(Y===void 0||u(Y,Li)&&Y.value===void 0)if(G.defaultFn!==void 0){const E=G.defaultFn(),s=u(E,t)?E:F.param(E,G);A.push(s)}else if(!G.default&&G.onUpdateFn!==void 0){const E=G.onUpdateFn(),s=u(E,t)?E:F.param(E,G);A.push(s)}else A.push(F`default`);else A.push(Y)}if(a.push(A),T<i.length-1)a.push(F`, `)}const f=this.buildWithCTE(p),$=F.join(a),v=c?F` returning ${this.buildSelection(c,{isSingleTable:!0})}`:void 0,S=o?F` on conflict ${o}`:void 0;return F`${f}insert into ${n} ${l} values ${$}${S}${v}`}buildRefreshMaterializedViewQuery({view:n,concurrently:i,withNoData:o}){const c=i?F` concurrently`:void 0,p=o?F` with no data`:void 0;return F`refresh materialized view${c} ${n}${p}`}prepareTyping(n){if(u(n,ex)||u(n,Px))return"json";else if(u(n,gx))return"decimal";else if(u(n,dx))return"time";else if(u(n,nm)||u(n,im))return"timestamp";else if(u(n,rx)||u(n,Zx))return"date";else if(u(n,om))return"uuid";else return"none"}sqlToQuery(n,i){return n.toQuery({casing:this.casing,escapeName:this.escapeName,escapeParam:this.escapeParam,escapeString:this.escapeString,prepareTyping:this.prepareTyping,invokeSource:i})}buildRelationalQueryWithoutPK({fullSchema:n,schema:i,tableNamesMap:o,table:c,tableConfig:p,queryConfig:a,tableAlias:x,nestedQueryRelation:m,joinOn:l}){let f=[],$,v,S=[],T;const R=[];if(a===!0)f=Object.entries(p.columns).map(([G,Y])=>({dbKey:Y.name,tsKey:G,field:Oo(Y,x),relationTableTsKey:void 0,isJson:!1,selection:[]}));else{const X=Object.fromEntries(Object.entries(p.columns).map(([M,O])=>[M,Oo(O,x)]));if(a.where){const M=typeof a.where==="function"?a.where(X,kJ()):a.where;T=M&&ua(M,x)}const G=[];let Y=[];if(a.columns){let M=!1;for(let[O,U]of Object.entries(a.columns)){if(U===void 0)continue;if(O in p.columns){if(!M&&U===!0)M=!0;Y.push(O)}}if(Y.length>0)Y=M?Y.filter((O)=>a.columns?.[O]===!0):Object.keys(p.columns).filter((O)=>!Y.includes(O))}else Y=Object.keys(p.columns);for(let M of Y){const O=p.columns[M];G.push({tsKey:M,value:O})}let E=[];if(a.with)E=Object.entries(a.with).filter((M)=>!!M[1]).map(([M,O])=>({tsKey:M,queryConfig:O,relation:p.relations[M]}));let s;if(a.extras){s=typeof a.extras==="function"?a.extras(X,{sql:F}):a.extras;for(let[M,O]of Object.entries(s))G.push({tsKey:M,value:Tf(O,x)})}for(let{tsKey:M,value:O}of G)f.push({dbKey:u(O,t.Aliased)?O.fieldAlias:p.columns[M].name,tsKey:M,field:u(O,_n)?Oo(O,x):O,relationTableTsKey:void 0,isJson:!1,selection:[]});let z=typeof a.orderBy==="function"?a.orderBy(X,rJ()):a.orderBy??[];if(!Array.isArray(z))z=[z];S=z.map((M)=>{if(u(M,_n))return Oo(M,x);return ua(M,x)}),$=a.limit,v=a.offset;for(let{tsKey:M,queryConfig:O,relation:U}of E){const V=qJ(i,o,U),K=Oc(U.referencedTable),y=o[K],_=`${x}_${M}`,P=Hc(...V.fields.map((Un,si)=>Ho(Oo(V.references[si],_),Oo(Un,x)))),ln=this.buildRelationalQueryWithoutPK({fullSchema:n,schema:i,tableNamesMap:o,table:n[y],tableConfig:i[y],queryConfig:u(U,xc)?O===!0?{limit:1}:{...O,limit:1}:O,tableAlias:_,joinOn:P,nestedQueryRelation:U}),$n=F`${F.identifier(_)}.${F.identifier("data")}`.as(M);R.push({on:F`true`,table:new fi(ln.sql,{},_),alias:_,joinType:"left",lateral:!0}),f.push({dbKey:M,tsKey:M,field:$n,relationTableTsKey:y,isJson:!0,selection:ln.selection})}}if(f.length===0)throw new Cx({message:`No fields selected for table "${p.tsName}" ("${x}")`});let A;if(T=Hc(l,T),m){let X=F`json_build_array(${F.join(f.map(({field:E,tsKey:s,isJson:z})=>z?F`${F.identifier(`${x}_${s}`)}.${F.identifier("data")}`:u(E,t.Aliased)?E.sql:E),F`, `)})`;if(u(m,Ea))X=F`coalesce(json_agg(${X}${S.length>0?F` order by ${F.join(S,F`, `)}`:void 0}), '[]'::json)`;const G=[{dbKey:"data",tsKey:"data",field:X.as("data"),isJson:!0,relationTableTsKey:p.tsName,selection:f}];if($!==void 0||v!==void 0||S.length>0)A=this.buildSelectQuery({table:Ix(c,x),fields:{},fieldsFlat:[{path:[],field:F.raw("*")}],where:T,limit:$,offset:v,orderBy:S,setOperators:[]}),T=void 0,$=void 0,v=void 0,S=[];else A=Ix(c,x);A=this.buildSelectQuery({table:u(A,So)?A:new fi(A,{},x),fields:{},fieldsFlat:G.map(({field:E})=>({path:[],field:u(E,_n)?Oo(E,x):E})),joins:R,where:T,limit:$,offset:v,orderBy:S,setOperators:[]})}else A=this.buildSelectQuery({table:Ix(c,x),fields:{},fieldsFlat:f.map(({field:X})=>({path:[],field:u(X,_n)?Oo(X,x):X})),joins:R,where:T,limit:$,offset:v,orderBy:S,setOperators:[]});return{tableTsKey:p.tsName,sql:A,selection:f}}}class _i{static[J]="SelectionProxyHandler";config;constructor(n){this.config={...n}}get(n,i){if(i==="_")return{...n._,selectedFields:new Proxy(n._.selectedFields,this)};if(i===hn)return{...n[hn],selectedFields:new Proxy(n[hn].selectedFields,this)};if(typeof i==="symbol")return n[i];const c=(u(n,fi)?n._.selectedFields:u(n,Ui)?n[hn].selectedFields:n)[i];if(u(c,t.Aliased)){if(this.config.sqlAliasedBehavior==="sql"&&!c.isSelectionField)return c.sql;const p=c.clone();return p.isSelectionField=!0,p}if(u(c,t)){if(this.config.sqlBehavior==="sql")return c;throw new Error(`You tried to reference "${i}" field from a subquery, which is a raw SQL field, but it doesn't have an alias declared. Please add an alias to the field using ".as('alias')" method.`)}if(u(c,_n)){if(this.config.alias)return new Proxy(c,new wp(new Proxy(c.table,new Ya(this.config.alias,this.config.replaceOriginalName??!1))));return c}if(typeof c!=="object"||c===null)return c;return new Proxy(c,new _i(this.config))}}class t${static[J]="TypedQueryBuilder";getSelectedFields(){return this._.selectedFields}}function rp(n,i){return(o,c,...p)=>{const a=[c,...p].map((x)=>({type:n,isAll:i,rightSelect:x}));for(let x of a)if(!Wf(o.getSelectedFields(),x.rightSelect.getSelectedFields()))throw new Error("Set operator error (union / intersect / except): selected fields are not the same or are in a different order");return o.addSetOperators(a)}}class Ei{static[J]="PgSelectBuilder";fields;session;dialect;withList=[];distinct;constructor(n){if(this.fields=n.fields,this.session=n.session,this.dialect=n.dialect,n.withList)this.withList=n.withList;this.distinct=n.distinct}from(n){const i=!!this.fields;let o;if(this.fields)o=this.fields;else if(u(n,fi))o=Object.fromEntries(Object.keys(n._.selectedFields).map((c)=>[c,n[c]]));else if(u(n,da))o=n[hn].selectedFields;else if(u(n,t))o={};else o=gS(n);return new k$({table:n,fields:o,isPartialSelect:i,session:this.session,dialect:this.dialect,withList:this.withList,distinct:this.distinct})}}class MR extends t${static[J]="PgSelectQueryBuilder";_;config;joinsNotNullableMap;tableName;isPartialSelect;session;dialect;constructor({table:n,fields:i,isPartialSelect:o,session:c,dialect:p,withList:a,distinct:x}){super();this.config={withList:a,table:n,fields:{...i},distinct:x,setOperators:[]},this.isPartialSelect=o,this.session=c,this.dialect=p,this._={selectedFields:i},this.tableName=Xf(n),this.joinsNotNullableMap=typeof this.tableName==="string"?{[this.tableName]:!0}:{}}createJoin(n){return(i,o)=>{const c=this.tableName,p=Xf(i);if(typeof p==="string"&&this.config.joins?.some((a)=>a.alias===p))throw new Error(`Alias "${p}" is already used in this query`);if(!this.isPartialSelect){if(Object.keys(this.joinsNotNullableMap).length===1&&typeof c==="string")this.config.fields={[c]:this.config.fields};if(typeof p==="string"&&!u(i,t)){const a=u(i,fi)?i._.selectedFields:u(i,Ui)?i[hn].selectedFields:i[D.Symbol.Columns];this.config.fields[p]=a}}if(typeof o==="function")o=o(new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"sql",sqlBehavior:"sql"})));if(!this.config.joins)this.config.joins=[];if(this.config.joins.push({on:o,table:i,joinType:n,alias:p}),typeof p==="string")switch(n){case"left":{this.joinsNotNullableMap[p]=!1;break}case"right":{this.joinsNotNullableMap=Object.fromEntries(Object.entries(this.joinsNotNullableMap).map(([a])=>[a,!1])),this.joinsNotNullableMap[p]=!0;break}case"inner":{this.joinsNotNullableMap[p]=!0;break}case"full":{this.joinsNotNullableMap=Object.fromEntries(Object.entries(this.joinsNotNullableMap).map(([a])=>[a,!1])),this.joinsNotNullableMap[p]=!1;break}}return this}}leftJoin=this.createJoin("left");rightJoin=this.createJoin("right");innerJoin=this.createJoin("inner");fullJoin=this.createJoin("full");createSetOperator(n,i){return(o)=>{const c=typeof o==="function"?o(ZG()):o;if(!Wf(this.getSelectedFields(),c.getSelectedFields()))throw new Error("Set operator error (union / intersect / except): selected fields are not the same or are in a different order");return this.config.setOperators.push({type:n,isAll:i,rightSelect:c}),this}}union=this.createSetOperator("union",!1);unionAll=this.createSetOperator("union",!0);intersect=this.createSetOperator("intersect",!1);intersectAll=this.createSetOperator("intersect",!0);except=this.createSetOperator("except",!1);exceptAll=this.createSetOperator("except",!0);addSetOperators(n){return this.config.setOperators.push(...n),this}where(n){if(typeof n==="function")n=n(new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"sql",sqlBehavior:"sql"})));return this.config.where=n,this}having(n){if(typeof n==="function")n=n(new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"sql",sqlBehavior:"sql"})));return this.config.having=n,this}groupBy(...n){if(typeof n[0]==="function"){const i=n[0](new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"alias",sqlBehavior:"sql"})));this.config.groupBy=Array.isArray(i)?i:[i]}else this.config.groupBy=n;return this}orderBy(...n){if(typeof n[0]==="function"){const i=n[0](new Proxy(this.config.fields,new _i({sqlAliasedBehavior:"alias",sqlBehavior:"sql"}))),o=Array.isArray(i)?i:[i];if(this.config.setOperators.length>0)this.config.setOperators.at(-1).orderBy=o;else this.config.orderBy=o}else{const i=n;if(this.config.setOperators.length>0)this.config.setOperators.at(-1).orderBy=i;else this.config.orderBy=i}return this}limit(n){if(this.config.setOperators.length>0)this.config.setOperators.at(-1).limit=n;else this.config.limit=n;return this}offset(n){if(this.config.setOperators.length>0)this.config.setOperators.at(-1).offset=n;else this.config.offset=n;return this}for(n,i={}){return this.config.lockingClause={strength:n,config:i},this}getSQL(){return this.dialect.buildSelectQuery(this.config)}toSQL(){const{typings:n,...i}=this.dialect.sqlToQuery(this.getSQL());return i}as(n){return new Proxy(new fi(this.getSQL(),this.config.fields,n),new _i({alias:n,sqlAliasedBehavior:"alias",sqlBehavior:"error"}))}getSelectedFields(){return new Proxy(this.config.fields,new _i({alias:this.tableName,sqlAliasedBehavior:"alias",sqlBehavior:"error"}))}$dynamic(){return this}}class k$ extends MR{static[J]="PgSelect";_prepare(n){const{session:i,config:o,dialect:c,joinsNotNullableMap:p}=this;if(!i)throw new Error("Cannot execute a query on a query builder. Please use a database instance instead.");return En.startActiveSpan("drizzle.prepareQuery",()=>{const a=di(o.fields),x=i.prepareQuery(c.sqlToQuery(this.getSQL()),a,n,!0);return x.joinsNotNullableMap=p,x})}prepare(n){return this._prepare(n)}execute=(n)=>{return En.startActiveSpan("drizzle.operation",()=>{return this._prepare().execute(n)})}}eS(k$,[ui]);var ZG=()=>({union:qG,unionAll:PG,intersect:eG,intersectAll:gG,except:dG,exceptAll:nz}),qG=rp("union",!1),PG=rp("union",!0),eG=rp("intersect",!1),gG=rp("intersect",!0),dG=rp("except",!1),nz=rp("except",!0);class r${static[J]="PgQueryBuilder";dialect;dialectConfig;constructor(n){this.dialect=u(n,kc)?n:void 0,this.dialectConfig=u(n,kc)?void 0:n}$with(n){const i=this;return{as(o){if(typeof o==="function")o=o(i);return new Proxy(new za(o.getSQL(),o.getSelectedFields(),n,!0),new _i({alias:n,sqlAliasedBehavior:"alias",sqlBehavior:"error"}))}}}with(...n){const i=this;function o(a){return new Ei({fields:a??void 0,session:void 0,dialect:i.getDialect(),withList:n})}function c(a){return new Ei({fields:a??void 0,session:void 0,dialect:i.getDialect(),distinct:!0})}function p(a,x){return new Ei({fields:x??void 0,session:void 0,dialect:i.getDialect(),distinct:{on:a}})}return{select:o,selectDistinct:c,selectDistinctOn:p}}select(n){return new Ei({fields:n??void 0,session:void 0,dialect:this.getDialect()})}selectDistinct(n){return new Ei({fields:n??void 0,session:void 0,dialect:this.getDialect(),distinct:!0})}selectDistinctOn(n,i){return new Ei({fields:i??void 0,session:void 0,dialect:this.getDialect(),distinct:{on:n}})}getDialect(){if(!this.dialect)this.dialect=new kc(this.dialectConfig);return this.dialect}}class Z$ extends ui{constructor(n,i,o){super();this.session=i,this.dialect=o,this.config={view:n}}static[J]="PgRefreshMaterializedView";config;concurrently(){if(this.config.withNoData!==void 0)throw new Error("Cannot use concurrently and withNoData together");return this.config.concurrently=!0,this}withNoData(){if(this.config.concurrently!==void 0)throw new Error("Cannot use concurrently and withNoData together");return this.config.withNoData=!0,this}getSQL(){return this.dialect.buildRefreshMaterializedViewQuery(this.config)}toSQL(){const{typings:n,...i}=this.dialect.sqlToQuery(this.getSQL());return i}_prepare(n){return En.startActiveSpan("drizzle.prepareQuery",()=>{return this.session.prepareQuery(this.dialect.sqlToQuery(this.getSQL()),void 0,n,!0)})}prepare(n){return this._prepare(n)}execute=(n)=>{return En.startActiveSpan("drizzle.operation",()=>{return this._prepare().execute(n)})}}class qm{constructor(n,i,o,c){this.table=n,this.session=i,this.dialect=o,this.withList=c}static[J]="PgUpdateBuilder";set(n){return new RR(this.table,kx(this.table,n),this.session,this.dialect,this.withList)}}class RR extends ui{constructor(n,i,o,c,p){super();this.session=o,this.dialect=c,this.config={set:i,table:n,withList:p}}static[J]="PgUpdate";config;where(n){return this.config.where=n,this}returning(n=this.config.table[D.Symbol.Columns]){return this.config.returning=di(n),this}getSQL(){return this.dialect.buildUpdateQuery(this.config)}toSQL(){const{typings:n,...i}=this.dialect.sqlToQuery(this.getSQL());return i}_prepare(n){return this.session.prepareQuery(this.dialect.sqlToQuery(this.getSQL()),this.config.returning,n,!0)}prepare(n){return this._prepare(n)}execute=(n)=>{return this._prepare().execute(n)};$dynamic(){return this}}class nx extends t{constructor(n){super(nx.buildEmbeddedCount(n.source,n.filters).queryChunks);this.params=n,this.mapWith(Number),this.session=n.session,this.sql=nx.buildCount(n.source,n.filters)}sql;static[J]="PgCountBuilder";[Symbol.toStringTag]="PgCountBuilder";session;static buildEmbeddedCount(n,i){return F`(select count(*) from ${n}${F.raw(" where ").if(i)}${i})`}static buildCount(n,i){return F`select count(*) as count from ${n}${F.raw(" where ").if(i)}${i};`}then(n,i){return Promise.resolve(this.session.count(this.sql)).then(n,i)}catch(n){return this.then(void 0,n)}finally(n){return this.then((i)=>{return n?.(),i},(i)=>{throw n?.(),i})}}class P${constructor(n,i,o,c,p,a,x){this.fullSchema=n,this.schema=i,this.tableNamesMap=o,this.table=c,this.tableConfig=p,this.dialect=a,this.session=x}static[J]="PgRelationalQueryBuilder";findMany(n){return new q$(this.fullSchema,this.schema,this.tableNamesMap,this.table,this.tableConfig,this.dialect,this.session,n?n:{},"many")}findFirst(n){return new q$(this.fullSchema,this.schema,this.tableNamesMap,this.table,this.tableConfig,this.dialect,this.session,n?{...n,limit:1}:{limit:1},"first")}}class q$ extends ui{constructor(n,i,o,c,p,a,x,m,l){super();this.fullSchema=n,this.schema=i,this.tableNamesMap=o,this.table=c,this.tableConfig=p,this.dialect=a,this.session=x,this.config=m,this.mode=l}static[J]="PgRelationalQuery";_prepare(n){return En.startActiveSpan("drizzle.prepareQuery",()=>{const{query:i,builtQuery:o}=this._toSQL();return this.session.prepareQuery(o,void 0,n,!0,(c,p)=>{const a=c.map((x)=>cm(this.schema,this.tableConfig,x,i.selection,p));if(this.mode==="first")return a[0];return a})})}prepare(n){return this._prepare(n)}_getQuery(){return this.dialect.buildRelationalQueryWithoutPK({fullSchema:this.fullSchema,schema:this.schema,tableNamesMap:this.tableNamesMap,table:this.table,tableConfig:this.tableConfig,queryConfig:this.config,tableAlias:this.tableConfig.tsName})}getSQL(){return this._getQuery().sql}_toSQL(){const n=this._getQuery(),i=this.dialect.sqlToQuery(n.sql);return{query:n,builtQuery:i}}toSQL(){return this._toSQL().builtQuery}execute(){return En.startActiveSpan("drizzle.operation",()=>{return this._prepare().execute()})}}class e$ extends ui{constructor(n,i,o,c){super();this.execute=n,this.sql=i,this.query=o,this.mapBatchResult=c}static[J]="PgRaw";getSQL(){return this.sql}getQuery(){return this.query}mapResult(n,i){return i?this.mapBatchResult(n):n}_prepare(){return this}isResponseInArrayMode(){return!1}}class ix{constructor(n,i,o){if(this.dialect=n,this.session=i,this._=o?{schema:o.schema,fullSchema:o.fullSchema,tableNamesMap:o.tableNamesMap,session:i}:{schema:void 0,fullSchema:{},tableNamesMap:{},session:i},this.query={},this._.schema)for(let[c,p]of Object.entries(this._.schema))this.query[c]=new P$(o.fullSchema,this._.schema,this._.tableNamesMap,o.fullSchema[c],p,n,i)}static[J]="PgDatabase";query;$with(n){const i=this;return{as(o){if(typeof o==="function")o=o(new r$(i.dialect));return new Proxy(new za(o.getSQL(),o.getSelectedFields(),n,!0),new _i({alias:n,sqlAliasedBehavior:"alias",sqlBehavior:"error"}))}}}$count(n,i){return new nx({source:n,filters:i,session:this.session})}with(...n){const i=this;function o(l){return new Ei({fields:l??void 0,session:i.session,dialect:i.dialect,withList:n})}function c(l){return new Ei({fields:l??void 0,session:i.session,dialect:i.dialect,withList:n,distinct:!0})}function p(l,f){return new Ei({fields:f??void 0,session:i.session,dialect:i.dialect,withList:n,distinct:{on:l}})}function a(l){return new qm(l,i.session,i.dialect,n)}function x(l){return new Zm(l,i.session,i.dialect,n)}function m(l){return new rm(l,i.session,i.dialect,n)}return{select:o,selectDistinct:c,selectDistinctOn:p,update:a,insert:x,delete:m}}select(n){return new Ei({fields:n??void 0,session:this.session,dialect:this.dialect})}selectDistinct(n){return new Ei({fields:n??void 0,session:this.session,dialect:this.dialect,distinct:!0})}selectDistinctOn(n,i){return new Ei({fields:i??void 0,session:this.session,dialect:this.dialect,distinct:{on:n}})}update(n){return new qm(n,this.session,this.dialect)}insert(n){return new Zm(n,this.session,this.dialect)}delete(n){return new rm(n,this.session,this.dialect)}refreshMaterializedView(n){return new Z$(n,this.session,this.dialect)}execute(n){const i=typeof n==="string"?F.raw(n):n.getSQL(),o=this.dialect.sqlToQuery(i),c=this.session.prepareQuery(o,void 0,void 0,!1);return new e$(()=>c.execute(),i,o,(p)=>c.mapResult(p,!0))}transaction(n,i){return this.session.transaction(n,i)}}function g$(n){return new KR(!0,n)}class KR{constructor(n,i){this.unique=n,this.name=i}static[J]="PgIndexBuilderOn";on(...n){return new Pm(n.map((i)=>{if(u(i,t))return i;i=i;const o=new Ga(i.name,!!i.keyAsName,i.columnType,i.indexConfig);return i.indexConfig=JSON.parse(JSON.stringify(i.defaultConfig)),o}),this.unique,!1,this.name)}onOnly(...n){return new Pm(n.map((i)=>{if(u(i,t))return i;i=i;const o=new Ga(i.name,!!i.keyAsName,i.columnType,i.indexConfig);return i.indexConfig=i.defaultConfig,o}),this.unique,!0,this.name)}using(n,...i){return new Pm(i.map((o)=>{if(u(o,t))return o;o=o;const c=new Ga(o.name,!!o.keyAsName,o.columnType,o.indexConfig);return o.indexConfig=JSON.parse(JSON.stringify(o.defaultConfig)),c}),this.unique,!0,this.name,n)}}class Pm{static[J]="PgIndexBuilder";config;constructor(n,i,o,c,p="btree"){this.config={name:c,columns:n,unique:i,only:o,method:p}}concurrently(){return this.config.concurrently=!0,this}with(n){return this.config.with=n,this}where(n){return this.config.where=n,this}build(n){return new WR(this.config,n)}}class WR{static[J]="PgIndex";config;constructor(n,i){this.config={...n,table:i}}}class d${constructor(n){this.query=n}getQuery(){return this.query}mapResult(n,i){return n}static[J]="PgPreparedQuery";joinsNotNullableMap}class nv{constructor(n){this.dialect=n}static[J]="PgSession";execute(n){return En.startActiveSpan("drizzle.operation",()=>{return En.startActiveSpan("drizzle.prepareQuery",()=>{return this.prepareQuery(this.dialect.sqlToQuery(n),void 0,void 0,!1)}).execute()})}all(n){return this.prepareQuery(this.dialect.sqlToQuery(n),void 0,void 0,!1).all()}async count(n){const i=await this.execute(n);return Number(i[0].count)}}class iv extends ix{constructor(n,i,o,c=0){super(n,i,o);this.schema=o,this.nestedIndex=c}static[J]="PgTransaction";rollback(){throw new Mf}getTransactionConfigSQL(n){const i=[];if(n.isolationLevel)i.push(`isolation level ${n.isolationLevel}`);if(n.accessMode)i.push(n.accessMode);if(typeof n.deferrable==="boolean")i.push(n.deferrable?"deferrable":"not deferrable");return F.raw(i.join(" "))}setTransaction(n){return this.session.execute(F`set transaction ${this.getTransactionConfigSQL(n)}`)}}class XR extends d${constructor(n,i,o,c,p,a,x){super({sql:i,params:o});this.client=n,this.queryString=i,this.params=o,this.logger=c,this.fields=p,this._isResponseInArrayMode=a,this.customResultMapper=x}static[J]="PostgresJsPreparedQuery";async execute(n={}){return En.startActiveSpan("drizzle.execute",async(i)=>{const o=Af(this.params,n);i?.setAttributes({"drizzle.query.text":this.queryString,"drizzle.query.params":JSON.stringify(o)}),this.logger.logQuery(this.queryString,o);const{fields:c,queryString:p,client:a,joinsNotNullableMap:x,customResultMapper:m}=this;if(!c&&!m)return En.startActiveSpan("drizzle.driver.execute",()=>{return a.unsafe(p,o)});const l=await En.startActiveSpan("drizzle.driver.execute",()=>{return i?.setAttributes({"drizzle.query.text":p,"drizzle.query.params":JSON.stringify(o)}),a.unsafe(p,o).values()});return En.startActiveSpan("drizzle.mapResponse",()=>{return m?m(l):l.map((f)=>PS(c,f,x))})})}all(n={}){return En.startActiveSpan("drizzle.execute",async(i)=>{const o=Af(this.params,n);return i?.setAttributes({"drizzle.query.text":this.queryString,"drizzle.query.params":JSON.stringify(o)}),this.logger.logQuery(this.queryString,o),En.startActiveSpan("drizzle.driver.execute",()=>{return i?.setAttributes({"drizzle.query.text":this.queryString,"drizzle.query.params":JSON.stringify(o)}),this.client.unsafe(this.queryString,o)})})}isResponseInArrayMode(){return this._isResponseInArrayMode}}class ox extends nv{constructor(n,i,o,c={}){super(i);this.client=n,this.schema=o,this.options=c,this.logger=c.logger??new Kf}static[J]="PostgresJsSession";logger;prepareQuery(n,i,o,c,p){return new XR(this.client,n.sql,n.params,this.logger,i,c,p)}query(n,i){return this.logger.logQuery(n,i),this.client.unsafe(n,i).values()}queryObjects(n,i){return this.client.unsafe(n,i)}transaction(n,i){return this.client.begin(async(o)=>{const c=new ox(o,this.dialect,this.schema,this.options),p=new ov(this.dialect,c,this.schema);if(i)await p.setTransaction(i);return n(p)})}}class ov extends iv{constructor(n,i,o,c=0){super(n,i,o,c);this.session=i}static[J]="PostgresJsTransaction";transaction(n){return this.session.client.savepoint((i)=>{const o=new ox(i,this.dialect,this.schema,this.session.options),c=new ov(this.dialect,o,this.schema);return n(c)})}}function Zp(n,i={}){const o=(l)=>l;for(let l of["1184","1082","1083","1114"])n.options.parsers[l]=o,n.options.serializers[l]=o;n.options.serializers["114"]=o,n.options.serializers["3802"]=o;const c=new kc({casing:i.casing});let p;if(i.logger===!0)p=new Rf;else if(i.logger!==!1)p=i.logger;let a;if(i.schema){const l=ZJ(i.schema,PJ);a={fullSchema:i.schema,schema:l.tables,tableNamesMap:l.tableNamesMap}}const x=new ox(n,c,a,{logger:p}),m=new GR(c,x,a);return m.$client=n,m}function em(...n){if(typeof n[0]==="function")return Zp(n[0],n[1]);if(typeof n[0]==="object"){const{connection:o,client:c,...p}=n[0];if(c)return Zp(c,p);if(typeof o==="object"&&o.url!==void 0){const{url:x,...m}=o,l=kp(x,m);return Zp(l,p)}const a=kp(o);return Zp(a,p)}const i=kp(n[0]);return Zp(i,n[1])}class GR extends ix{static[J]="PostgresJsDatabase"}((n)=>{function i(o){return Zp({},o)}n.mock=i})(em||(em={}));var pv={};y4(pv,{users:()=>Xo,userChanges:()=>oz,untrackedUserColumnNames:()=>iz,twoFactorMethod:()=>OR,trackedUserColumnName:()=>uR,trackableUserColumnNames:()=>YR,role:()=>zR,players:()=>cv,passwordResetAttempts:()=>cz,loginHistory:()=>qp,games:()=>gm,banishedIps:()=>dm});var zR=Bx("role",["admin","user"]),Xo=ac("users",{id:yi().primaryKey().defaultRandom(),username:$i({length:16}).notNull(),email:$i({length:254}).notNull(),hash:$i({length:64}).notNull(),salt:$i({length:36}).notNull(),createdAt:wo({withTimezone:!0}).notNull().defaultNow(),createdIp:$i({length:45}).notNull(),isActive:Oa().notNull().default(!1),verifiedAt:wo({withTimezone:!0}),userRole:zR().default("user")},(n)=>({usersUsernameUnique:g$().on(n.username),usersEmailUnique:g$().on(n.email)})),iz=["id","createdAt","createdIp","isActive","salt","verifiedAt"],YR=["username","email","hash","userRole"],uR=Bx("trackedUserColumnName",YR),oz=ac("userChanges",{id:yi().primaryKey().defaultRandom(),userId:yi().notNull().references(()=>Xo.id),changedAt:wo({withTimezone:!0}).notNull().defaultNow(),changedIp:$i({length:45}).notNull(),changedColumn:uR().notNull(),oldValue:$i({length:255}),newValue:$i({length:255})}),gm=ac("games",{id:yi("id").primaryKey().defaultRandom()}),cv=ac("players",{userId:yi().notNull().references(()=>Xo.id),gameId:yi().notNull().references(()=>gm.id),score:qx().notNull()},(n)=>({pk:IJ({columns:[n.userId,n.gameId]})})),qp=ac("loginHistory",{id:yi().primaryKey().defaultRandom(),userId:yi().references(()=>Xo.id),loginTime:wo({withTimezone:!0}).notNull().defaultNow(),ipAddress:$i({length:45}).notNull(),userAgent:$i({length:1024}),successful:Oa().notNull().default(!1)}),OR=Bx("twoFactorMethod",["email","phone"]),cz=ac("passwordResetAttempts",{id:yi().primaryKey().defaultRandom(),userId:yi().notNull().references(()=>Xo.id),requestedIp:$i({length:45}).notNull(),requestedAt:wo({withTimezone:!0}).notNull().defaultNow(),succeededIp:$i({length:45}),succeededAt:wo({withTimezone:!0}),verificationMethod:OR().notNull()}),dm=ac("banishedIps",{ip:$i({length:45}).primaryKey(),reason:$i({length:2048}).notNull(),banishedAt:wo({withTimezone:!0}).notNull().defaultNow(),banishedUntil:wo({withTimezone:!0})});var __dirname="/home/runner/work/wayforge/wayforge/apps/tempest.games/src/database";class av{options;sql;drizzle;observers=new Map;async setupTriggersAndNotifications(){await this.sql.file(pz.resolve(__dirname,"notify_update.sql"));const n=[gi(Xo),gi(gm),gi(cv)];await this.sql`SELECT create_notify_triggers(${this.sql.array(n)})`,await this.sql.listen("table_update",(i)=>{const o=i.split(","),c=o[0],p=o[1],a=`${c}("${p}")`;if(this.observers.has(a))this.observers.get(a).next(a)})}constructor(n={host:pi.POSTGRES_HOST,port:pi.POSTGRES_PORT,user:pi.POSTGRES_USER,password:pi.POSTGRES_PASSWORD,database:pi.POSTGRES_DATABASE}){this.options=n,this.sql=kp(n),this.drizzle=em(this.sql,{schema:pv})}observe(n,i){if(!this.observers.has(n))this.observers.set(n,new an);this.observers.get(n).subscribe("SINGLETON",i)}}import{createHash as az}from"crypto";function xv(n){const i=az("sha256").update(n).digest("hex");return`${i.substring(0,8)}-${i.substring(8,12)}-${i.substring(12,16)}-${i.substring(16,20)}-${i.substring(20,32)}`}var HR=["123","321","abc","admin","adobe","alexander","amanda","andrea","andrew","angel","apple","asdf","ashley","baby","banana","baseball","batman","bear","biteme","blazer","blonde","boston","buster","butterfly","cameron","charlie","cheese","chelsea","chicken","chocolate","chris","compaq","computer","cookie","corvette","cowboys","dakota","dallas","daniel","david","diamond","dolphin","donald","dragon","eagle","flower","football","frank","freedom","friend","gateway","george","ginger","god","golf","hannah","hardcore","harley","heather","hello","hottie","hunter","internet","jasmine","jennifer","jessica","jesus","johnny","jordan","joshua","justin","justme","killer","knight","lakers","letmein","liverpool","login","london","love","lucky","mackenzie","maggie","master","matrix","matthew","maverick","melissa","mercedes","michael","michelle","mickey","miller","money","monkey","morgan","mother","muffin","mustang","natasha","nathan","nicole","ninja","orange","pass","password","patrick","peanut","pepper","phoenix","photoshop","pokemon","princess","purple","qazwsx","qwerty","rainbow","ranger","root","samantha","samsung","scooter","secret","shadow","simpson","smile","soccer","sparkle","starwars","summer","sunflower","sunshine","superman","taylor","temp","test","thomas","tigers","tigger","tinkerbell","trust","turtle","victoria","welcome","whatever","william","winter","yellow","zaq12wsx","zxcvbn"];function fz(n){let i="";for(let o of n)if(o in QR)i+=QR[o];else i+=o;return i}function $z(n){const i=n.toLocaleLowerCase(),o=fz(i);for(let c of HR){if(o.includes(c))return!0;if(i.includes(c))return!0}return!1}function vz(n){const i=new Set(n).size;return n.length*Math.log2(i)}function wz(n){let i=0;const o=100;if($z(n))i-=o;return i+=vz(n)*0.5,Math.max(i,0)}var xz=3,mz=15,lz=/^[a-zA-Z0-9_-]+$/,UR=Qn.string().min(xz).max(mz).regex(lz),ER=20,QR={"0":"o","1":"l","3":"e","4":"a","5":"s","7":"t","@":"a",$:"s","!":"i"},VR=Qn.string().refine((n)=>{return wz(n)>=ER},{message:`Password does not meet the minimum complexity of ${ER}.`}).brand("password"),bR=Qn.object({username:UR,password:VR}).strict(),Sz=Qn.string().email().brand("email"),_R=Qn.object({username:UR,password:VR,email:Sz}).strict();var nl={100:"Continue",101:"Switching Protocols",102:"Processing",103:"Early Hints",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",208:"Already Reported",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Switch Proxy",307:"Temporary Redirect",308:"Permanent Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Payload Too Large",414:"URI Too Long",415:"Unsupported Media Type",416:"Range Not Satisfiable",417:"Expectation Failed",418:"I'm a teapot",421:"Misdirected Request",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",425:"Too Early",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",451:"Unavailable For Legal Reasons",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",508:"Loop Detected",510:"Not Extended",511:"Network Authentication Required"},mv=Kv(nl).map(([n])=>Qn.literal(Number(n))),Jz=Qn.union([mv[0],mv[1],...mv]),sR=Qn.tuple([Jz,Qn.string()]);var jR=Zo({key:"count",default:0}),Fz=Mc({key:"incrementTX",do:({set:n})=>{n(jR,(i)=>i+1)}}),NR=p0({key:"countContinuity",config:(n)=>n.add(jR).add(Fz)});async function fv(){Xn.info("\uD83E\uDDF9 dispatching SIGINT to workers"),yR.process.kill("SIGINT"),await new Promise((n)=>yR.process.once("exit",n)),Xn.info("\uD83D\uDEEC backend server exiting"),process.exit(0)}var yR=Y$(Dc,"backend.worker.game.bun",Xn),rc=new av,ah=(()=>{let{__tribunalDaily:n}=globalThis;if(!n)n=new DR.CronJob("00 15 * * * *",()=>{Y$(Dc,"backend.worker.tribunal.bun",Xn)}),n.start(),process.on("exit",()=>{n.stop(),Xn.info("\u231B tribunal daily cronjob stopped")}),Xn.info("\u23F3 tribunal daily cronjob started");return n})(),hR=BR.createServer((n,i)=>{let o;n.on("data",(c)=>(o??=[]).push(c)).on("end",async()=>{const c=n.headers.authorization;try{if(typeof n.url==="undefined")throw[400,"No URL"];const p=n.socket.remoteAddress;if(!p)throw[400,"No IP address"];const a=new Date,x=new URL(n.url,pi.VITE_BACKEND_ORIGIN);Xn.info(a,p,n.method,x.pathname);const m=await rc.drizzle.query.banishedIps.findFirst({columns:{banishedUntil:!0},where:Ho(dm.ip,p)}),l=m?.banishedUntil===null,f=m?.banishedUntil&&m.banishedUntil>a;if(l||f){Xn.info(`\uD83D\uDE45 request from banned ip ${p}`);return}switch(n.method){case"POST":if(!o)throw[400,"No data received"];switch(x.pathname){case`/signup-${xv("signup")}`:{const $=Buffer.concat(o).toString(),v=JSON.parse($);Xn.info("signup json",v);const S=_R.safeParse(v);if(!S.success){Xn.warn("signup parsed",S.error.issues);return}const{username:T,password:R,email:A}=S.data;if(await rc.drizzle.query.users.findFirst({columns:{id:!0},where:Ho(Xo.email,A)}))throw[400,"User already exists"];const G=crypto.randomUUID(),Y=LR("sha256").update(R+G).digest("hex");await rc.drizzle.insert(Xo).values({username:T,email:A,hash:Y,salt:G,createdIp:p}),i.writeHead(201,{"Content-Type":"text/plain","Access-Control-Allow-Origin":`${pi.FRONTEND_ORIGINS[0]}`}),i.end(nl[201])}break;case`/login-${xv("login")}`:{let $=!1,v=null;try{const S=new Date(+a-600000);Xn.info("\uD83D\uDD11 ten minutes ago",{tenMinutesAgo:S,now:a});const T=await rc.drizzle.query.loginHistory.findMany({columns:{userId:!0,successful:!0},where:Hc(Ho(qp.ipAddress,p),Ho(qp.successful,!1),tx(qp.loginTime,S)),limit:10});Xn.info(`\uD83D\uDD11 ${T.length}/10 recent failed logins from ${p}`);const R=10-T.length;if(R<1)throw Xn.info(`\uD83D\uDD11 too many recent failed logins from ${p}`),await rc.drizzle.insert(dm).values({ip:p,reason:"Too many recent login attempts.",banishedAt:a,banishedUntil:new Date(+a+86400000)}),[429,"Too many recent login attempts."];const A=Buffer.concat(o).toString(),X=JSON.parse(A),G=bR.safeParse(X);if(!G.success)throw Xn.warn("login parsed",G.error.issues),[400,`${R} attempts remaining.`];const{username:Y,password:E}=G.data,s=await rc.drizzle.query.users.findFirst({columns:{id:!0,hash:!0,salt:!0},where:Ho(Xo.username,Y)});if(Xn.info("\uD83D\uDD11 login attempt as user",Y),!s)throw Xn.info(`\uD83D\uDD11 user ${Y} does not exist`),[400,`${R} attempts remaining.`];const{hash:z,salt:M}=s;if(v=s.id,LR("sha256").update(E+M).digest("hex")===z){const U=crypto.randomUUID();let V=sm.get(Y);if(!V)V=new Map,sm.set(Y,V);V.set(U,Number(a)),$=!0,Xn.info("\uD83D\uDD11 login successful as",Y),i.writeHead(200,{"Content-Type":"text/plain","Access-Control-Allow-Origin":`${pi.FRONTEND_ORIGINS[0]}`}),i.end(`${Y} ${U}`)}}finally{await rc.drizzle.insert(qp).values({userId:v,successful:$,ipAddress:p,userAgent:n.headers["user-agent"]??"Withheld"}),Xn.info(`\uD83D\uDD11 recorded login attempt from ${p}`)}}}}}catch(p){const a=sR.safeParse(p);if(a.success){const[x,m]=a.data,f=`${nl[x]}. ${m}`;Xn.info(`\u274C ${x}: ${f}`),i.writeHead(x,{"Content-Type":"text/plain","Access-Control-Allow-Origin":`${pi.FRONTEND_ORIGINS[0]}`}),i.end(f)}else Xn.error(p),i.writeHead(500,{"Content-Type":"text/plain","Access-Control-Allow-Origin":`${pi.FRONTEND_ORIGINS[0]}`}),i.end("Internal Server Error")}})}),lv=hR.listen(pi.BACKEND_PORT).address(),Az=typeof lv==="string"?null:lv===null?null:lv.port;if(Az===null)throw new Error("Could not determine port for test server");new jM(hR,{cors:{origin:pi.FRONTEND_ORIGINS,methods:["GET","POST"]}}).use((n,i)=>{const{username:o,sessionKey:c}=n.handshake.auth;if(!(o&&c)){i(new Error("No auth header provided"));return}if(sm.get(o)?.has(c)){const a=An(on.STORE,wa,n.id);zn(on.STORE,a,n),Rc(Kc,(x)=>{x.set(n.id,o)},on.STORE),zn(on.STORE,Ql,(x)=>x.add(o)),zn(on.STORE,El,(x)=>x.add(n.id)),Xn.info(`${o} connected on ${n.id}`),i()}else Xn.info(`${o} couldn't authenticate`),i(new Error("Authentication error"))}).on("connection",(n)=>{const o=m0({socket:n,store:on.STORE})(NR);n.on("disconnect",()=>{const c=np(Kc,n.id,on.STORE).userKeyOfSocket,p=Kn(on.STORE,c);if(Rc(Kc,(a)=>{a.delete(n.id)},on.STORE),p)zn(on.STORE,Ql,(a)=>(a.delete(p),a));zn(on.STORE,El,(a)=>(a.delete(n.id),a)),li(on.STORE,wa,n.id),Xn.info(`${n.id} disconnected`),o()})});Dc.emit("alive");Dc.on("updatesReady",()=>{Dc.emit("readyToUpdate")});process.on("SIGINT",async()=>{Xn.info("\u2757 received SIGINT; exiting gracefully"),await fv()});process.on("SIGTERM",async()=>{Xn.info("\u2757 received SIGTERM; exiting gracefully"),await fv()});process.on("exit",async()=>{Xn.info("\u2757 received exit; exiting gracefully"),await fv()});Xn.info(`\uD83D\uDEEB backend server ready on port ${pi.BACKEND_PORT}`);export{ah as tribunalDaily};
|