@live-state/sync 0.0.4-beta.7 → 0.0.4-beta.9
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/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { d as Client, c as ClientEvents, C as ClientOptions, b as ConnectionStateChangeEvent, M as MessageReceivedEvent, S as SubscriptionProvider, e as createClient, u as useLiveQuery } from './index-
|
|
1
|
+
export { d as Client, c as ClientEvents, C as ClientOptions, b as ConnectionStateChangeEvent, M as MessageReceivedEvent, S as SubscriptionProvider, e as createClient, u as useLiveQuery } from './index-BgowrRDR.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import 'zod/v3';
|
package/dist/fetch-client.d.ts
CHANGED
|
@@ -339,7 +339,7 @@ interface MutationRequest<TInput = any> extends BaseRequest {
|
|
|
339
339
|
type Request = QueryRequest | MutationRequest;
|
|
340
340
|
type NextFunction<O, R = Request> = (req: R) => Awaitable<O>;
|
|
341
341
|
type Middleware<T = any> = (opts: {
|
|
342
|
-
req:
|
|
342
|
+
req: Request;
|
|
343
343
|
next: NextFunction<T>;
|
|
344
344
|
}) => ReturnType<NextFunction<T>>;
|
|
345
345
|
|
package/dist/server.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var P=require('crypto'),Ye=require('qs'),zod=require('zod');require('js-xxhash');var kysely=require('kysely'),postgres=require('kysely/helpers/postgres');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var P__default=/*#__PURE__*/_interopDefault(P);var Ye__default=/*#__PURE__*/_interopDefault(Ye);var Ie=Object.create;var ie=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var Ae=Object.getPrototypeOf,je=Object.prototype.hasOwnProperty;var Ee=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var $e=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Oe(e))!je.call(r,i)&&i!==t&&ie(r,i,{get:()=>e[i],enumerable:!(n=Le(e,i))||n.enumerable});return r};var ae=(r,e,t)=>(t=r!=null?Ie(Ae(r)):{},$e(ie(t,"default",{value:r,enumerable:true}),r));var U=Ee(V=>{Object.defineProperty(V,"__esModule",{value:true});V.parse=Be;V.serialize=Qe;var Fe=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,Ke=/^[\u0021-\u003A\u003C-\u007E]*$/,De=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,Ue=/^[\u0020-\u003A\u003D-\u007E]*$/,We=Object.prototype.toString,ke=(()=>{let r=function(){};return r.prototype=Object.create(null),r})();function Be(r,e){let t=new ke,n=r.length;if(n<2)return t;let i=(e==null?void 0:e.decode)||Ge,a=0;do{let o=r.indexOf("=",a);if(o===-1)break;let c=r.indexOf(";",a),s=c===-1?n:c;if(o>s){a=r.lastIndexOf(";",o-1)+1;continue}let m=le(r,a,o),y=de(r,o,m),d=r.slice(m,y);if(t[d]===void 0){let l=le(r,o+1,s),p=de(r,s,l),u=i(r.slice(l,p));t[d]=u;}a=s+1;}while(a<n);return t}function le(r,e,t){do{let n=r.charCodeAt(e);if(n!==32&&n!==9)return e}while(++e<t);return t}function de(r,e,t){for(;e>t;){let n=r.charCodeAt(--e);if(n!==32&&n!==9)return e+1}return t}function Qe(r,e,t){let n=(t==null?void 0:t.encode)||encodeURIComponent;if(!Fe.test(r))throw new TypeError(`argument name is invalid: ${r}`);let i=n(e);if(!Ke.test(i))throw new TypeError(`argument val is invalid: ${e}`);let a=r+"="+i;if(!t)return a;if(t.maxAge!==void 0){if(!Number.isInteger(t.maxAge))throw new TypeError(`option maxAge is invalid: ${t.maxAge}`);a+="; Max-Age="+t.maxAge;}if(t.domain){if(!De.test(t.domain))throw new TypeError(`option domain is invalid: ${t.domain}`);a+="; Domain="+t.domain;}if(t.path){if(!Ue.test(t.path))throw new TypeError(`option path is invalid: ${t.path}`);a+="; Path="+t.path;}if(t.expires){if(!Ze(t.expires)||!Number.isFinite(t.expires.valueOf()))throw new TypeError(`option expires is invalid: ${t.expires}`);a+="; Expires="+t.expires.toUTCString();}if(t.httpOnly&&(a+="; HttpOnly"),t.secure&&(a+="; Secure"),t.partitioned&&(a+="; Partitioned"),t.priority)switch(typeof t.priority=="string"?t.priority.toLowerCase():void 0){case "low":a+="; Priority=Low";break;case "medium":a+="; Priority=Medium";break;case "high":a+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${t.priority}`)}if(t.sameSite)switch(typeof t.sameSite=="string"?t.sameSite.toLowerCase():t.sameSite){case true:case "strict":a+="; SameSite=Strict";break;case "lax":a+="; SameSite=Lax";break;case "none":a+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${t.sameSite}`)}return a}function Ge(r){if(r.indexOf("%")===-1)return r;try{return decodeURIComponent(r)}catch{return r}}function Ze(r){return We.call(r)==="[object Date]"}});var se="0123456789ABCDEFGHJKMNPQRSTVWXYZ",O=32;var Ce=16,ce=10,oe=0xffffffffffff;var w;(function(r){r.Base32IncorrectEncoding="B32_ENC_INVALID",r.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",r.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",r.EncodeTimeNegative="ENC_TIME_NEG",r.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",r.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",r.PRNGDetectFailure="PRNG_DETECT",r.ULIDInvalid="ULID_INVALID",r.Unexpected="UNEXPECTED",r.UUIDInvalid="UUID_INVALID";})(w||(w={}));var v=class extends Error{constructor(e,t){super(`${t} (${e})`),this.name="ULIDError",this.code=e;}};function Pe(r){let e=Math.floor(r()*O);return e===O&&(e=O-1),se.charAt(e)}function Ne(r){var n;let e=ze(),t=e&&(e.crypto||e.msCrypto)||(typeof P__default.default<"u"?P__default.default:null);if(typeof(t==null?void 0:t.getRandomValues)=="function")return ()=>{let i=new Uint8Array(1);return t.getRandomValues(i),i[0]/255};if(typeof(t==null?void 0:t.randomBytes)=="function")return ()=>t.randomBytes(1).readUInt8()/255;if((n=P__default.default)!=null&&n.randomBytes)return ()=>P__default.default.randomBytes(1).readUInt8()/255;throw new v(w.PRNGDetectFailure,"Failed to find a reliable PRNG")}function ze(){return qe()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function Ve(r,e){let t="";for(;r>0;r--)t=Pe(e)+t;return t}function _e(r,e=ce){if(isNaN(r))throw new v(w.EncodeTimeValueMalformed,`Time must be a number: ${r}`);if(r>oe)throw new v(w.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${oe}: ${r}`);if(r<0)throw new v(w.EncodeTimeNegative,`Time must be positive: ${r}`);if(Number.isInteger(r)===false)throw new v(w.EncodeTimeValueMalformed,`Time must be an integer: ${r}`);let t,n="";for(let i=e;i>0;i--)t=r%O,n=se.charAt(t)+n,r=(r-t)/O;return n}function qe(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function ue(r,e){let t=Ne(),n=Date.now();return _e(n,ce)+Ve(Ce,t)}var D=()=>ue().toLowerCase();var N=(...r)=>{let e=r.filter(t=>!!t);return e.length===0?{}:e.length===1?e[0]:{$and:e}};var z=class{storage;queue=new Map;scheduled=false;constructor(e){this.storage=e;}async rawFind({resource:e,commonWhere:t,uniqueWhere:n,...i}){return new Promise((a,o)=>{let c=this.getBatchKey({resource:e,commonWhere:t,...i}),s={resource:e,commonWhere:t,uniqueWhere:n,...i,resolve:a,reject:o};this.queue.has(c)||this.queue.set(c,[]);let m=this.queue.get(c);m&&m.push(s),this.scheduled||(this.scheduled=true,setImmediate(()=>{this.processBatch();}));})}getBatchKey(e){let{resource:t,commonWhere:n,...i}=e;return `${t}:${JSON.stringify(n??{})}:${JSON.stringify(i??{})}`}async processBatch(){this.scheduled=false;let e=Array.from(this.queue.entries());this.queue.clear();for(let[,t]of e)try{await this.executeBatchedRequests(t);}catch(n){t.forEach(i=>{i.reject(n);});}}async executeBatchedRequests(e){var l,p;if(e.length===0)return;let t=e[0],{resource:n,commonWhere:i,include:a,sort:o}=t,c=e.length===1?t.limit:void 0,s=e.map(u=>u.uniqueWhere).filter(u=>u!==void 0),m=i,y=(l=Object.entries(s[0]??{})[0])==null?void 0:l[0];if(s.length>0){let u=s.map(f=>f[y]).filter(f=>f!=null);u.length>0&&(m=N(i,{[y]:{$in:u}}));}let d=await this.storage.rawFind({resource:n,where:m,include:a,sort:o,limit:c});for(let u of e){let f={};if(u.uniqueWhere){let[h,R]=Object.entries(u.uniqueWhere)[0];for(let[M,C]of Object.entries(d))((p=C.value[h])==null?void 0:p.value)===R&&(f[M]=C);}else Object.assign(f,d);u.resolve(f);}}};var me=ae(U());var _=zod.z.object({resource:zod.z.string(),where:zod.z.record(zod.z.string(),zod.z.any()).optional(),include:zod.z.record(zod.z.string(),zod.z.any()).optional(),lastSyncedAt:zod.z.string().optional(),limit:zod.z.coerce.number().optional(),sort:zod.z.array(zod.z.object({key:zod.z.string(),direction:zod.z.enum(["asc","desc"])})).optional()}),W=zod.z.record(zod.z.string(),zod.z.object({value:zod.z.string().or(zod.z.number()).or(zod.z.boolean()).or(zod.z.date()).nullable(),_meta:zod.z.object({timestamp:zod.z.string().optional().nullable()}).optional()})),He=W.superRefine((r,e)=>{r.id&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),ye=zod.z.object({id:zod.z.string().optional(),type:zod.z.literal("MUTATE"),resource:zod.z.string(),resourceId:zod.z.string().optional()}),A=ye.extend({procedure:zod.z.string(),payload:zod.z.any().optional()}),j=ye.extend({procedure:zod.z.enum(["INSERT","UPDATE"]),payload:He});zod.z.union([j,A]);var pe=_.omit({resource:true}),k=A.omit({id:true,type:true,resource:true,procedure:true}),B=j.omit({id:true,type:true,resource:true,procedure:true});zod.z.union([B,k]);var fe=r=>async e=>{var t;try{let n=typeof e.headers.getSetCookie=="function"?Object.fromEntries(e.headers):e.headers,i={headers:n,cookies:n.cookie?me.default.parse(n.cookie):{}},a=new URL(e.url),o=a.pathname.split("/"),c=a.searchParams,s=Ye__default.default.parse(c.toString()),m=await((t=r.contextProvider)==null?void 0:t.call(r,{transport:"HTTP",headers:i.headers,cookies:i.cookies,queryParams:s}))??{};if(e.method==="GET"){let y=o[o.length-1],{success:d,data:l,error:p}=pe.safeParse(s);if(!d)return Response.json({message:"Invalid query",code:"INVALID_QUERY",details:p},{status:400});let u=await r.handleQuery({req:{...i,...l,type:"QUERY",resource:y,context:m,queryParams:s}});return !u||!u.data?Response.json({message:"Invalid resource",code:"INVALID_RESOURCE"},{status:400}):Response.json(u.data)}if(e.method==="POST")try{let y=o[o.length-1],d=o[o.length-2],l=e.body?await e.json():{},p;if(y==="insert"||y==="update"){let{success:f,data:h,error:R}=B.safeParse(l);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:R},{status:400});p=h;}else {let{success:f,data:h,error:R}=k.safeParse(l);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:R},{status:400});p=h;}let u=await r.handleMutation({req:{...i,type:"MUTATE",resource:d,input:p.payload,context:m,resourceId:p.resourceId,procedure:y==="insert"||y==="update"?y.toUpperCase():y,queryParams:{}}});return Response.json(u)}catch(y){return console.error("Error parsing mutation from the client:",y),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}return Response.json({message:"Not found",code:"NOT_FOUND"},{status:404})}catch(n){return console.error("Unexpected error:",n),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}};var ge=ae(U());var I=zod.z.string(),Xe=zod.z.object({id:I,type:zod.z.literal("SUBSCRIBE"),resource:zod.z.string()}),et=_.extend({id:I,type:zod.z.literal("QUERY")}),Te=j.extend({id:I}),tt=A.extend({id:I}),nt=zod.z.union([tt,Te]),he=zod.z.union([Xe,et,nt]),rt=zod.z.object({id:I,type:zod.z.literal("REJECT"),resource:zod.z.string(),message:zod.z.string().optional()}),it=zod.z.object({id:I,type:zod.z.literal("REPLY"),data:zod.z.any()});zod.z.union([rt,it,Te]);zod.z.object({resource:zod.z.string(),data:zod.z.record(zod.z.string(),W)});var Re=r=>{let e={},t={};return r.subscribeToMutations(n=>{let i=n;!i.resourceId||!i.payload||(console.log("Mutation propagated:",i),Object.entries(t[i.resource]??{}).forEach(([a,o])=>{var c;(c=e[a])==null||c.send(JSON.stringify({...i,id:i.id??D()}));}));}),(n,i)=>{var y;let a=d=>{n.send(JSON.stringify(d));},o=D(),c={headers:i.headers,cookies:typeof i.headers.cookie=="string"?ge.default.parse(i.headers.cookie):{}},s=Ye.parse(i.url.split("?")[1]),m=(y=r.contextProvider)==null?void 0:y.call(r,{transport:"WEBSOCKET",headers:c.headers,cookies:c.cookies,queryParams:s});e[o]=n,console.log("Client connected:",o),n.on("message",async d=>{try{console.log("Message received from the client:",d);let l=he.parse(JSON.parse(d.toString()));if(l.type==="SUBSCRIBE"){let{resource:p}=l;t[p]||(t[p]={}),t[p][o]={};}else if(l.type==="QUERY"){let{resource:p}=l,u=await r.handleQuery({req:{...c,type:"QUERY",resource:p,context:await m??{},queryParams:s}});if(!u||!u.data)throw new Error("Invalid resource");a({id:l.id,type:"REPLY",data:{resource:p,data:Object.fromEntries(Object.entries(u.data??{}).map(([f,h])=>[f,h.value]))}});}else if(l.type==="MUTATE"){let{resource:p}=l;console.log("Received mutation from client:",l);try{let u=await r.handleMutation({req:{...c,type:"MUTATE",resource:p,input:l.payload,context:{messageId:l.id,...await m??{}},resourceId:l.resourceId,procedure:l.procedure,queryParams:s}});l.procedure&&l.procedure!=="INSERT"&&l.procedure!=="UPDATE"&&a({id:l.id,type:"REPLY",data:u});}catch(u){a({id:l.id,type:"REJECT",resource:p,message:u.message}),console.error("Error parsing mutation from the client:",u);}}}catch(l){console.error("Error handling message from the client:",l);}}),n.on("close",()=>{console.log("Connection closed",o),delete e[o];for(let d of Object.values(t))delete d[o];});}};function xe(r){let e=`${r.protocol}://${r.hostname}${r.url}`,t=new Headers;return Object.entries(r.headers).forEach(([n,i])=>{i&&t.set(n,Array.isArray(i)?i.join(","):i);}),new Request(e,{method:r.method,headers:t,body:r.body&&r.method!=="GET"?JSON.stringify(r.body):void 0})}var Kt=(r,e,t)=>{r.ws(`${(t==null?void 0:t.basePath)??""}/ws`,Re(e)),r.use(`${(t==null?void 0:t.basePath)??""}/`,(n,i)=>{fe(e)(xe(n)).then(o=>o.json().then(c=>i.status(o.status).send(c)));});};var x=r=>{if(r)return Array.isArray(r.value)?r.value.map(e=>x(e)):typeof r.value!="object"||r.value===null||r.value instanceof Date?r.value:Object.fromEntries(Object.entries(r.value).map(([e,t])=>[e,x(t)]))};var b=(r,e,t=false)=>Object.entries(e).every(([n,i])=>{if(n==="$and")return i.every(o=>b(r,o,t));if(n==="$or")return i.some(o=>b(r,o,t));let a=(i==null?void 0:i.$eq)!==void 0?i==null?void 0:i.$eq:i;if(typeof i=="object"&&i!==null&&(i==null?void 0:i.$eq)===void 0){if(i.$in!==void 0){let o=r[n];return o===void 0?false:t?!i.$in.includes(o):i.$in.includes(o)}if(i.$not!==void 0&&!t)return b(r,{[n]:i.$not},true);if(i.$gt!==void 0){let o=r[n];return typeof o!="number"?false:t?o<=i.$gt:o>i.$gt}if(i.$gte!==void 0){let o=r[n];return typeof o!="number"?false:t?o<i.$gte:o>=i.$gte}if(i.$lt!==void 0){let o=r[n];return typeof o!="number"?false:t?o>=i.$lt:o<i.$lt}if(i.$lte!==void 0){let o=r[n];return typeof o!="number"?false:t?o>i.$lte:o<=i.$lte}return !r[n]||typeof r[n]!="object"?false:b(r[n],i,t)}return t?r[n]!==a:r[n]===a});var Y=class r{routes;constructor(e){this.routes=e.routes;}static create(e){return new r(e)}},dn=r=>Y.create({...r}),st=r=>({handler:e=>({inputValidator:r??zod.z.undefined(),handler:e})}),X=class r{resourceSchema;middlewares;customMutations;authorization;constructor(e,t,n){this.resourceSchema=e,this.middlewares=new Set,this.customMutations=t??{},this.authorization=n;}use(...e){for(let t of e)this.middlewares.add(t);return this}withMutations(e){return new r(this.resourceSchema,e({mutation:st}))}handleQuery=async({req:e,batcher:t})=>await this.wrapInMiddlewares(async n=>{var a,o;let i=(o=(a=this.authorization)==null?void 0:a.read)==null?void 0:o.call(a,{ctx:n.context});if(typeof i=="boolean"&&!i)throw new Error("Not authorized");return {data:await t.rawFind({resource:n.resource,commonWhere:N(n.where,typeof i=="object"?i:void 0),uniqueWhere:n.relationalWhere,include:n.include,limit:n.limit,sort:n.sort})}})(e);handleMutation=async({req:e,db:t})=>await this.wrapInMiddlewares(async n=>{if(!n.procedure)throw new Error("Procedure is required for mutations");let i=this.customMutations[n.procedure];if(i){let a=i.inputValidator.parse(n.input);return n.input=a,i.handler({req:n,db:t})}else {if(n.procedure==="INSERT"||n.procedure==="UPDATE")return this.handleSet({req:n,db:t,operation:n.procedure});throw new Error(`Unknown procedure: ${n.procedure}`)}})(e);handleSet=async({req:e,db:t,operation:n})=>{if(!e.input)throw new Error("Payload is required");if(!e.resourceId)throw new Error("ResourceId is required");let i=await t.rawFindById(e.resource,e.resourceId);if(n==="INSERT"&&i)throw new Error("Resource already exists");if(n==="UPDATE"&&!i)throw new Error("Resource not found");return t.transaction(async({trx:a})=>{var m,y,d,l,p;let[o,c]=this.resourceSchema.mergeMutation("set",e.input,i);if(!c)throw new Error("Mutation rejected");if(n==="INSERT"){let u=await a.rawInsert(e.resource,e.resourceId,o);if((m=this.authorization)!=null&&m.insert){let f=x(u);f.id=f.id??e.resourceId;let h=this.authorization.insert({ctx:e.context,value:f});if(!(typeof h=="boolean"?h:b(f,h)))throw new Error("Not authorized")}return {data:u,acceptedValues:c}}if((d=(y=this.authorization)==null?void 0:y.update)!=null&&d.preMutation){let u=x(i);u.id=u.id??e.resourceId;let f=this.authorization.update.preMutation({ctx:e.context,value:u});if(!(typeof f=="boolean"?f:b(u,f)))throw new Error("Not authorized")}let s=await a.rawUpdate(e.resource,e.resourceId,o);if((p=(l=this.authorization)==null?void 0:l.update)!=null&&p.postMutation){let u=x(s);u.id=u.id??e.resourceId;let f=this.authorization.update.postMutation({ctx:e.context,value:u});if(!(typeof f=="boolean"?f:b(u,f)))throw new Error("Not authorized")}return {data:s,acceptedValues:c}})};wrapInMiddlewares(e){return t=>Array.from(this.middlewares.values()).reduceRight((n,i)=>a=>i({req:a,next:n}),e)(t)}},ee=class r{middlewares;constructor(e=[]){this.middlewares=e;}collectionRoute(e,t){return new X(e,void 0,t).use(...this.middlewares)}use(...e){return new r([...this.middlewares,...e])}static create(){return new r}},yn=ee.create;var $=class{async insert(e,t){let n=new Date().toISOString();return x(await this.rawInsert(e.name,t.id,{value:Object.fromEntries(Object.entries(t).map(([i,a])=>[i,{value:a,_meta:{timestamp:n}}]))}))}async update(e,t,n){let i=new Date().toISOString(),{id:a,...o}=n;return x(await this.rawUpdate(e.name,t,{value:Object.fromEntries(Object.entries(o).map(([c,s])=>[c,{value:s,_meta:{timestamp:i}}]))}))}};function q(r,e,t,n){if(!r)throw new Error("Schema not initialized");let i=r[e];if(!i)throw new Error("Resource not found");let a=n.$or,o=n.$and;return (a?t.or:t.and)(a?n.$or.map(c=>q(r,e,t,c)):o?n.$and.map(c=>q(r,e,t,c)):Object.entries(n).map(([c,s])=>{var m,y;if(i.fields[c])return (s==null?void 0:s.$eq)!==void 0?t(`${e}.${c}`,s.$eq===null?"is":"=",s.$eq):(s==null?void 0:s.$in)!==void 0?t(`${e}.${c}`,"in",s.$in):(s==null?void 0:s.$not)!==void 0?((m=s==null?void 0:s.$not)==null?void 0:m.$in)!==void 0?t(`${e}.${c}`,"not in",s.$not.$in):((y=s==null?void 0:s.$not)==null?void 0:y.$eq)!==void 0?t(`${e}.${c}`,s.$not.$eq===null?"is not":"!=",s.$not.$eq):t(`${e}.${c}`,s.$not===null?"is not":"!=",s.$not):(s==null?void 0:s.$gt)!==void 0?t(`${e}.${c}`,">",s.$gt):(s==null?void 0:s.$gte)!==void 0?t(`${e}.${c}`,">=",s.$gte):(s==null?void 0:s.$lt)!==void 0?t(`${e}.${c}`,"<",s.$lt):(s==null?void 0:s.$lte)!==void 0?t(`${e}.${c}`,"<=",s.$lte):t(`${e}.${c}`,s===null?"is":"=",s);if(i.relations[c]){let d=i.relations[c],l=d.entity.name;return d.type==="many"?t.exists(te(r,l,t.selectFrom(l).select("id").whereRef(d.foreignColumn,"=",`${e}.id`),s)):q(r,l,t,s)}return null}).filter(Boolean))}function F(r,e,t,n){let i=r[e];if(!i)throw new Error("Resource not found");if(!n)return t;if(n.$and){for(let a of n.$and)t=F(r,e,t,a);return t}else if(n.$or){for(let a of n.$or)t=F(r,e,t,a);return t}for(let[a,o]of Object.entries(n)){if(!i.relations[a])continue;let c=i.relations[a],s=c.entity.name,m=c.type==="one"?"id":c.foreignColumn,y=c.type==="one"?c.relationalColumn:"id";t=t.leftJoin(s,`${s}.${m}`,`${e}.${y}`),o instanceof Object&&!Array.isArray(o)&&o!==null&&(t=F(r,s,t,o));}return t}function te(r,e,t,n){return !n||Object.keys(n).length===0?t:(t=F(r,e,t,n),t.where(i=>q(r,e,i,n)))}function K(r,e,t,n){if(!n)return t;if(!r)throw new Error("Schema not initialized");let i=r[e];if(!i)throw new Error(`Resource not found: ${e}`);for(let a of Object.keys(n)){if(!i.relations[a])throw new Error(`Relation ${a} not found in resource ${e}`);let o=i.relations[a],c=o.entity.name,s=n[a],m=o.type==="one"?"id":o.foreignColumn,y=o.type==="one"?o.relationalColumn:"id",d=o.type==="one"?postgres.jsonObjectFrom:postgres.jsonArrayFrom,l=typeof s=="object"&&s!==null;t=t.select(p=>{let u=p.selectFrom(c).selectAll(c).whereRef(`${c}.${m}`,"=",`${e}.${y}`).select(f=>postgres.jsonObjectFrom(f.selectFrom(`${c}_meta`).selectAll(`${c}_meta`).whereRef(`${c}_meta.id`,"=",`${c}.id`)).as("_meta"));return l&&(u=K(r,c,u,s)),d(u).as(a)});}return t}var ne=class r extends ${db;schema;constructor(e,t){super(),this.isKyselyLike(e)?this.db=e:this.db=new kysely.Kysely({dialect:new kysely.PostgresDialect({pool:e})}),this.schema=t,this.rawInsert=this.rawInsert.bind(this),this.rawUpdate=this.rawUpdate.bind(this);}async updateSchema(e){this.schema=e;let t=await this.db.introspection.getTables();for(let[n,i]of Object.entries(e)){let a=t.find(s=>s.name===n);a||await this.db.schema.createTable(n).ifNotExists().execute();let o=`${n}_meta`,c=t.find(s=>s.name===o);c||await this.db.schema.createTable(o).ifNotExists().execute();for(let[s,m]of Object.entries(i.fields)){let y=a==null?void 0:a.columns.find(p=>p.name===s),d=m.getStorageFieldType();y?y.dataType!==d.type&&console.error("Column type mismatch:",s,"expected to have type:",d.type,"but has type:",y.dataType):(await this.db.schema.alterTable(n).addColumn(s,d.type,p=>{let u=p;return d.unique&&(u=u.unique()),d.nullable||(u=u.notNull()),d.references&&(u=u.references(d.references)),d.primary&&(u=u.primaryKey()),d.default!==void 0&&(u=u.defaultTo(d.default)),u}).execute().catch(p=>{throw console.error("Error adding column",s,p),p}),d.index&&await this.db.schema.createIndex(`${n}_${s}_index`).on(n).column(s).execute().catch(()=>{})),(c==null?void 0:c.columns.find(p=>p.name===s))||await this.db.schema.alterTable(o).addColumn(s,"varchar",p=>{let u=p;return d.primary&&(u=u.primaryKey().references(`${n}.${s}`)),u}).execute();}}}async rawFindById(e,t,n){if(!this.schema)throw new Error("Schema not initialized");let i=await this.db.selectFrom(e).where("id","=",t).selectAll(e).select(o=>postgres.jsonObjectFrom(o.selectFrom(`${e}_meta`).selectAll(`${e}_meta`).whereRef(`${e}_meta.id`,"=",`${e}.id`)).as("_meta"));i=K(this.schema,e,i,n);let a=await i.executeTakeFirst();if(a)return this.convertToMaterializedLiveType(a)}async findOne(e,t,n){let i=await this.rawFindById(e.name,t,n==null?void 0:n.include);if(i)return x(i)}async rawFind(e){if(!this.schema)throw new Error("Schema not initialized");let{resource:t,where:n,include:i,limit:a,sort:o}=e,c=this.db.selectFrom(t).selectAll(t).select(d=>postgres.jsonObjectFrom(d.selectFrom(`${t}_meta`).selectAll(`${t}_meta`).whereRef(`${t}_meta.id`,"=",`${t}.id`)).as("_meta"));c=te(this.schema,t,c,n),c=K(this.schema,t,c,i),a!==void 0&&(c=c.limit(a)),o!==void 0&&o.forEach(d=>{c=c.orderBy(d.key,d.direction);});let s=await c.execute(),m=Object.fromEntries(s.map(d=>{let{id:l}=d;return [l,d]}));return Object.keys(m).length===0?{}:Object.entries(m).reduce((d,[l,p])=>(d[l]=this.convertToMaterializedLiveType(p),d),{})}async find(e,t){let n=await this.rawFind({resource:e.name,where:t==null?void 0:t.where,include:t==null?void 0:t.include,limit:t==null?void 0:t.limit,sort:t==null?void 0:t.sort});return Object.fromEntries(Object.entries(n).map(([i,a])=>[i,x(a)]))}async rawInsert(e,t,n){var o;let i={},a={};for(let[c,s]of Object.entries(n.value)){let m=(o=s._meta)==null?void 0:o.timestamp;m&&(i[c]=s.value,a[c]=m);}return await this.db.insertInto(e).values({...i,id:t}).execute().then(()=>{this.db.insertInto(`${e}_meta`).values({...a,id:t}).execute();}),n}async rawUpdate(e,t,n){var o;let i={},a={};for(let[c,s]of Object.entries(n.value)){let m=(o=s._meta)==null?void 0:o.timestamp;m&&(i[c]=s.value,a[c]=m);}return await Promise.all([this.db.updateTable(e).set(i).where("id","=",t).execute(),this.db.insertInto(`${e}_meta`).values({...a,id:t}).onConflict(c=>c.column("id").doUpdateSet(a)).execute()]),n}async transaction(e){if(!this.schema)throw new Error("Schema not initialized");if(this.db.isTransaction){let n=Math.random().toString(36).substring(2,15),i=await this.db.savepoint(n).execute();try{return await e({trx:this,commit:()=>i.releaseSavepoint(n).execute().then(()=>{}),rollback:()=>i.rollbackToSavepoint(n).execute().then(()=>{})}).then(a=>i.isCommitted||i.isRolledBack?a:i.releaseSavepoint(n).execute().then(()=>a))}catch(a){throw await i.rollbackToSavepoint(n).execute().catch(()=>{}),a}}let t=await this.db.startTransaction().execute();try{return await e({trx:new r(t,this.schema),commit:()=>t.commit().execute(),rollback:()=>t.rollback().execute()}).then(n=>t.isCommitted||t.isRolledBack?n:t.commit().execute().then(()=>n))}catch(n){throw await t.rollback().execute(),n}}convertToMaterializedLiveType(e){return {value:Object.entries(e).reduce((t,[n,i])=>{var a,o,c;return n==="_meta"||(n==="id"?t[n]={value:i}:Array.isArray(i)?t[n]={value:i.map(s=>this.convertToMaterializedLiveType(s)),_meta:{timestamp:(a=e==null?void 0:e._meta)==null?void 0:a[n]}}:typeof i=="object"&&i!==null&&!(i instanceof Date)?t[n]={...this.convertToMaterializedLiveType(i),_meta:{timestamp:(o=e==null?void 0:e._meta)==null?void 0:o[n]}}:t[n]={value:i,_meta:{timestamp:(c=e==null?void 0:e._meta)==null?void 0:c[n]}}),t},{})}}isKyselyLike(e){if(e instanceof kysely.Kysely)return true;if(!e||typeof e!="object")return false;let t=e,n=typeof t.selectFrom=="function",i=typeof t.startTransaction=="function",a=typeof t.savepoint=="function",o=typeof t.isTransaction=="boolean"||typeof t.isTransaction=="function";return n&&i||a&&o}};var re=class r{router;storage;schema;middlewares=new Set;contextProvider;mutationSubscriptions=new Set;constructor(e){var t;this.router=e.router,this.storage=e.storage,this.schema=e.schema,(t=e.middlewares)==null||t.forEach(n=>{this.middlewares.add(n);}),this.storage.updateSchema(this.schema),this.contextProvider=e.contextProvider;}static create(e){return new r(e)}subscribeToMutations(e){return this.mutationSubscriptions.add(e),()=>{this.mutationSubscriptions.delete(e);}}handleQuery(e){let t=new z(this.storage);return this.wrapInMiddlewares(async n=>{var m;let i=Se(n,this.schema,{stepId:"query",collectionName:n.resource,included:Object.keys(n.include??{})}),a={headers:n.headers,cookies:n.cookies,queryParams:n.queryParams,context:n.context},o={};for(let y=0;y<i.length;y++){let d=i[y],l=this.router.routes[d.resource];if(!l)throw new Error("Invalid resource");let p=d.getWhere&&d.referenceGetter?d.referenceGetter(o).map(d.getWhere):[void 0],u=(m=o[d.prevStepId??""])==null?void 0:m.flatMap(R=>{var M;return Object.keys(((M=R==null?void 0:R.result)==null?void 0:M.data)??{})}),h=(await Promise.allSettled(p.map(async(R,M)=>{let C=u==null?void 0:u[M],Me=await l.handleQuery({req:{type:"QUERY",...d,...a,where:d.where,relationalWhere:R},batcher:t});return {includedBy:C,result:Me}}))).flatMap(R=>R.status==="fulfilled"?[R.value]:[]);o[d.stepId]=h;}let c=Object.fromEntries(Object.entries(o).flatMap(([y,d],l)=>d.flatMap(p=>Object.entries(p.result.data).map(([u,f])=>[`${y}.${u}`,{data:f,includedBy:y!=="query"&&p.includedBy?`${y.split(".").slice(0,-1).join(".")}.${p.includedBy}`:void 0,path:y.split(".").slice(-1)[0],isMany:i[l].isMany,collectionName:i[l].collectionName,included:i[l].included}]))));return Object.keys(c).reduceRight((y,d)=>{var u,f;let l=c[d],p=l.path;if(p==="query"&&(y.data[d]=l.data),l.included.length)for(let h of l.included)l.data.value[h]??=((f=(u=this.schema[l.collectionName])==null?void 0:u.relations[h])==null?void 0:f.type)==="many"?{value:[]}:{value:null};if(l.includedBy){let h=c[l.includedBy];if(!h)return y;l.isMany?(h.data.value[p]??={value:[]},h.data.value[p].value.push(l.data)):h.data.value[p]=l.data;}return y},{data:{}})})(e.req)}async handleMutation(e){let t=await this.wrapInMiddlewares(async n=>{let i=this.router.routes[n.resource];if(!i)throw new Error("Invalid resource");return i.handleMutation({req:n,db:this.storage})})(e.req);if(t&&e.req.type==="MUTATE"&&t.acceptedValues&&(e.req.procedure==="INSERT"||e.req.procedure==="UPDATE")&&e.req.resourceId){let i=t.acceptedValues??{},a=e.req,o=a.resourceId;Object.keys(i).length&&o&&this.mutationSubscriptions.forEach(c=>{c({id:e.req.context.messageId,type:"MUTATE",resource:a.resource,payload:i,resourceId:o,procedure:a.procedure});});}return t}use(e){return this.middlewares.add(e),this}context(e){return this.contextProvider=e,this}wrapInMiddlewares(e){return t=>Array.from(this.middlewares.values()).reduceRight((n,i)=>a=>i({req:a,next:n}),e)(t)}},On=re.create;function Se(r,e,t){let{include:n,...i}=r,{stepId:a}=t,o=[{...i,...t}];if(n&&typeof n=="object"&&Object.keys(n).length>0){let c=e[i.resource];if(!c)throw new Error(`Resource ${i.resource} not found`);o.push(...Object.entries(n).flatMap(([s,m])=>{let y=c.relations[s];if(!y)throw new Error(`Relation ${s} not found for resource ${i.resource}`);let d=y.entity.name;return Se({...i,resource:d,include:m},e,{getWhere:y.type==="one"?l=>({id:l}):l=>({[y.foreignColumn]:l}),referenceGetter:l=>l[a].flatMap(p=>p.result.data?y.type==="one"?Object.values(p.result.data).map(u=>{var f,h;return (h=(f=u.value)==null?void 0:f[y.relationalColumn])==null?void 0:h.value}):Object.keys(p.result.data):[]),stepId:`${a}.${s}`,prevStepId:a,isMany:y.type==="many",collectionName:d,included:typeof m=="object"?Object.keys(m):[]})}));}return o}
|
|
1
|
+
'use strict';var P=require('crypto'),Ye=require('qs'),zod=require('zod');require('js-xxhash');var kysely=require('kysely'),postgres=require('kysely/helpers/postgres');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var P__default=/*#__PURE__*/_interopDefault(P);var Ye__default=/*#__PURE__*/_interopDefault(Ye);var Ie=Object.create;var ie=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var Ae=Object.getPrototypeOf,je=Object.prototype.hasOwnProperty;var Ee=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var $e=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Oe(e))!je.call(r,i)&&i!==t&&ie(r,i,{get:()=>e[i],enumerable:!(n=Le(e,i))||n.enumerable});return r};var ae=(r,e,t)=>(t=r!=null?Ie(Ae(r)):{},$e(ie(t,"default",{value:r,enumerable:true}),r));var U=Ee(V=>{Object.defineProperty(V,"__esModule",{value:true});V.parse=Be;V.serialize=Qe;var Fe=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,Ke=/^[\u0021-\u003A\u003C-\u007E]*$/,De=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,Ue=/^[\u0020-\u003A\u003D-\u007E]*$/,We=Object.prototype.toString,ke=(()=>{let r=function(){};return r.prototype=Object.create(null),r})();function Be(r,e){let t=new ke,n=r.length;if(n<2)return t;let i=(e==null?void 0:e.decode)||Ge,a=0;do{let o=r.indexOf("=",a);if(o===-1)break;let c=r.indexOf(";",a),s=c===-1?n:c;if(o>s){a=r.lastIndexOf(";",o-1)+1;continue}let m=le(r,a,o),y=de(r,o,m),d=r.slice(m,y);if(t[d]===void 0){let l=le(r,o+1,s),p=de(r,s,l),u=i(r.slice(l,p));t[d]=u;}a=s+1;}while(a<n);return t}function le(r,e,t){do{let n=r.charCodeAt(e);if(n!==32&&n!==9)return e}while(++e<t);return t}function de(r,e,t){for(;e>t;){let n=r.charCodeAt(--e);if(n!==32&&n!==9)return e+1}return t}function Qe(r,e,t){let n=(t==null?void 0:t.encode)||encodeURIComponent;if(!Fe.test(r))throw new TypeError(`argument name is invalid: ${r}`);let i=n(e);if(!Ke.test(i))throw new TypeError(`argument val is invalid: ${e}`);let a=r+"="+i;if(!t)return a;if(t.maxAge!==void 0){if(!Number.isInteger(t.maxAge))throw new TypeError(`option maxAge is invalid: ${t.maxAge}`);a+="; Max-Age="+t.maxAge;}if(t.domain){if(!De.test(t.domain))throw new TypeError(`option domain is invalid: ${t.domain}`);a+="; Domain="+t.domain;}if(t.path){if(!Ue.test(t.path))throw new TypeError(`option path is invalid: ${t.path}`);a+="; Path="+t.path;}if(t.expires){if(!Ze(t.expires)||!Number.isFinite(t.expires.valueOf()))throw new TypeError(`option expires is invalid: ${t.expires}`);a+="; Expires="+t.expires.toUTCString();}if(t.httpOnly&&(a+="; HttpOnly"),t.secure&&(a+="; Secure"),t.partitioned&&(a+="; Partitioned"),t.priority)switch(typeof t.priority=="string"?t.priority.toLowerCase():void 0){case "low":a+="; Priority=Low";break;case "medium":a+="; Priority=Medium";break;case "high":a+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${t.priority}`)}if(t.sameSite)switch(typeof t.sameSite=="string"?t.sameSite.toLowerCase():t.sameSite){case true:case "strict":a+="; SameSite=Strict";break;case "lax":a+="; SameSite=Lax";break;case "none":a+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${t.sameSite}`)}return a}function Ge(r){if(r.indexOf("%")===-1)return r;try{return decodeURIComponent(r)}catch{return r}}function Ze(r){return We.call(r)==="[object Date]"}});var se="0123456789ABCDEFGHJKMNPQRSTVWXYZ",O=32;var Ce=16,ce=10,oe=0xffffffffffff;var w;(function(r){r.Base32IncorrectEncoding="B32_ENC_INVALID",r.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",r.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",r.EncodeTimeNegative="ENC_TIME_NEG",r.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",r.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",r.PRNGDetectFailure="PRNG_DETECT",r.ULIDInvalid="ULID_INVALID",r.Unexpected="UNEXPECTED",r.UUIDInvalid="UUID_INVALID";})(w||(w={}));var v=class extends Error{constructor(e,t){super(`${t} (${e})`),this.name="ULIDError",this.code=e;}};function Pe(r){let e=Math.floor(r()*O);return e===O&&(e=O-1),se.charAt(e)}function Ne(r){var n;let e=ze(),t=e&&(e.crypto||e.msCrypto)||(typeof P__default.default<"u"?P__default.default:null);if(typeof(t==null?void 0:t.getRandomValues)=="function")return ()=>{let i=new Uint8Array(1);return t.getRandomValues(i),i[0]/255};if(typeof(t==null?void 0:t.randomBytes)=="function")return ()=>t.randomBytes(1).readUInt8()/255;if((n=P__default.default)!=null&&n.randomBytes)return ()=>P__default.default.randomBytes(1).readUInt8()/255;throw new v(w.PRNGDetectFailure,"Failed to find a reliable PRNG")}function ze(){return qe()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function Ve(r,e){let t="";for(;r>0;r--)t=Pe(e)+t;return t}function _e(r,e=ce){if(isNaN(r))throw new v(w.EncodeTimeValueMalformed,`Time must be a number: ${r}`);if(r>oe)throw new v(w.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${oe}: ${r}`);if(r<0)throw new v(w.EncodeTimeNegative,`Time must be positive: ${r}`);if(Number.isInteger(r)===false)throw new v(w.EncodeTimeValueMalformed,`Time must be an integer: ${r}`);let t,n="";for(let i=e;i>0;i--)t=r%O,n=se.charAt(t)+n,r=(r-t)/O;return n}function qe(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function ue(r,e){let t=Ne(),n=Date.now();return _e(n,ce)+Ve(Ce,t)}var D=()=>ue().toLowerCase();var N=(...r)=>{let e=r.filter(t=>!!t);return e.length===0?{}:e.length===1?e[0]:{$and:e}};var z=class{storage;queue=new Map;scheduled=false;constructor(e){this.storage=e;}async rawFind({resource:e,commonWhere:t,uniqueWhere:n,...i}){return new Promise((a,o)=>{let c=this.getBatchKey({resource:e,commonWhere:t,...i}),s={resource:e,commonWhere:t,uniqueWhere:n,...i,resolve:a,reject:o};this.queue.has(c)||this.queue.set(c,[]);let m=this.queue.get(c);m&&m.push(s),this.scheduled||(this.scheduled=true,setImmediate(()=>{this.processBatch();}));})}getBatchKey(e){let{resource:t,commonWhere:n,...i}=e;return `${t}:${JSON.stringify(n??{})}:${JSON.stringify(i??{})}`}async processBatch(){this.scheduled=false;let e=Array.from(this.queue.entries());this.queue.clear();for(let[,t]of e)try{await this.executeBatchedRequests(t);}catch(n){t.forEach(i=>{i.reject(n);});}}async executeBatchedRequests(e){var l,p;if(e.length===0)return;let t=e[0],{resource:n,commonWhere:i,include:a,sort:o}=t,c=e.length===1?t.limit:void 0,s=e.map(u=>u.uniqueWhere).filter(u=>u!==void 0),m=i,y=(l=Object.entries(s[0]??{})[0])==null?void 0:l[0];if(s.length>0){let u=s.map(f=>f[y]).filter(f=>f!=null);u.length>0&&(m=N(i,{[y]:{$in:u}}));}let d=await this.storage.rawFind({resource:n,where:m,include:a,sort:o,limit:c});for(let u of e){let f={};if(u.uniqueWhere){let[h,R]=Object.entries(u.uniqueWhere)[0];for(let[M,C]of Object.entries(d))((p=C.value[h])==null?void 0:p.value)===R&&(f[M]=C);}else Object.assign(f,d);u.resolve(f);}}};var me=ae(U());var _=zod.z.object({resource:zod.z.string(),where:zod.z.record(zod.z.string(),zod.z.any()).optional(),include:zod.z.record(zod.z.string(),zod.z.any()).optional(),lastSyncedAt:zod.z.string().optional(),limit:zod.z.coerce.number().optional(),sort:zod.z.array(zod.z.object({key:zod.z.string(),direction:zod.z.enum(["asc","desc"])})).optional()}),W=zod.z.record(zod.z.string(),zod.z.object({value:zod.z.string().or(zod.z.number()).or(zod.z.boolean()).or(zod.z.date()).nullable(),_meta:zod.z.object({timestamp:zod.z.string().optional().nullable()}).optional()})),He=W.superRefine((r,e)=>{r.id&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),ye=zod.z.object({id:zod.z.string().optional(),type:zod.z.literal("MUTATE"),resource:zod.z.string(),resourceId:zod.z.string().optional()}),A=ye.extend({procedure:zod.z.string(),payload:zod.z.any().optional()}),j=ye.extend({procedure:zod.z.enum(["INSERT","UPDATE"]),payload:He});zod.z.union([j,A]);var pe=_.omit({resource:true}),k=A.omit({id:true,type:true,resource:true,procedure:true}),B=j.omit({id:true,type:true,resource:true,procedure:true});zod.z.union([B,k]);var fe=r=>async e=>{var t;try{let n=typeof e.headers.getSetCookie=="function"?Object.fromEntries(e.headers):e.headers,i={headers:n,cookies:n.cookie?me.default.parse(n.cookie):{}},a=new URL(e.url),o=a.pathname.split("/"),c=a.searchParams,s=Ye__default.default.parse(c.toString()),m=await((t=r.contextProvider)==null?void 0:t.call(r,{transport:"HTTP",headers:i.headers,cookies:i.cookies,queryParams:s}))??{};if(e.method==="GET"){let y=o[o.length-1],{success:d,data:l,error:p}=pe.safeParse(s);if(!d)return Response.json({message:"Invalid query",code:"INVALID_QUERY",details:p},{status:400});let u=await r.handleQuery({req:{...i,...l,type:"QUERY",resource:y,context:m,queryParams:s}});return !u||!u.data?Response.json({message:"Invalid resource",code:"INVALID_RESOURCE"},{status:400}):Response.json(u.data)}if(e.method==="POST")try{let y=o[o.length-1],d=o[o.length-2],l=e.body?await e.json():{},p;if(y==="insert"||y==="update"){let{success:f,data:h,error:R}=B.safeParse(l);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:R},{status:400});p=h;}else {let{success:f,data:h,error:R}=k.safeParse(l);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:R},{status:400});p=h;}let u=await r.handleMutation({req:{...i,type:"MUTATE",resource:d,input:p.payload,context:m,resourceId:p.resourceId,procedure:y==="insert"||y==="update"?y.toUpperCase():y,queryParams:{}}});return Response.json(u)}catch(y){return console.error("Error parsing mutation from the client:",y),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}return Response.json({message:"Not found",code:"NOT_FOUND"},{status:404})}catch(n){return console.error("Unexpected error:",n),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}};var ge=ae(U());var I=zod.z.string(),Xe=zod.z.object({id:I,type:zod.z.literal("SUBSCRIBE"),resource:zod.z.string()}),et=_.extend({id:I,type:zod.z.literal("QUERY")}),Te=j.extend({id:I}),tt=A.extend({id:I}),nt=zod.z.union([tt,Te]),he=zod.z.union([Xe,et,nt]),rt=zod.z.object({id:I,type:zod.z.literal("REJECT"),resource:zod.z.string(),message:zod.z.string().optional()}),it=zod.z.object({id:I,type:zod.z.literal("REPLY"),data:zod.z.any()});zod.z.union([rt,it,Te]);zod.z.object({resource:zod.z.string(),data:zod.z.record(zod.z.string(),W)});var Re=r=>{let e={},t={};return r.subscribeToMutations(n=>{let i=n;!i.resourceId||!i.payload||(console.log("Mutation propagated:",i),Object.entries(t[i.resource]??{}).forEach(([a,o])=>{var c;(c=e[a])==null||c.send(JSON.stringify({...i,id:i.id??D()}));}));}),(n,i)=>{var y;let a=d=>{n.send(JSON.stringify(d));},o=D(),c={headers:i.headers,cookies:typeof i.headers.cookie=="string"?ge.default.parse(i.headers.cookie):{}},s=Ye.parse(i.url.split("?")[1]),m=(y=r.contextProvider)==null?void 0:y.call(r,{transport:"WEBSOCKET",headers:c.headers,cookies:c.cookies,queryParams:s});e[o]=n,console.log("Client connected:",o),n.on("message",async d=>{try{console.log("Message received from the client:",d);let l=he.parse(JSON.parse(d.toString()));if(l.type==="SUBSCRIBE"){let{resource:p}=l;t[p]||(t[p]={}),t[p][o]={};}else if(l.type==="QUERY"){let{resource:p}=l,u=await r.handleQuery({req:{...c,type:"QUERY",resource:p,context:await m??{},queryParams:s}});if(!u||!u.data)throw new Error("Invalid resource");a({id:l.id,type:"REPLY",data:{resource:p,data:Object.fromEntries(Object.entries(u.data??{}).map(([f,h])=>[f,h.value]))}});}else if(l.type==="MUTATE"){let{resource:p}=l;console.log("Received mutation from client:",l);try{let u=await r.handleMutation({req:{...c,type:"MUTATE",resource:p,input:l.payload,context:{messageId:l.id,...await m??{}},resourceId:l.resourceId,procedure:l.procedure,queryParams:s}});l.procedure&&l.procedure!=="INSERT"&&l.procedure!=="UPDATE"&&a({id:l.id,type:"REPLY",data:u});}catch(u){a({id:l.id,type:"REJECT",resource:p,message:u.message}),console.error("Error parsing mutation from the client:",u);}}}catch(l){console.error("Error handling message from the client:",l);}}),n.on("close",()=>{console.log("Connection closed",o),delete e[o];for(let d of Object.values(t))delete d[o];});}};function xe(r){let e=`${r.protocol}://${r.hostname}${r.url}`,t=new Headers;return Object.entries(r.headers).forEach(([n,i])=>{i&&t.set(n,Array.isArray(i)?i.join(","):i);}),new Request(e,{method:r.method,headers:t,body:r.body&&r.method!=="GET"?JSON.stringify(r.body):void 0})}var Kt=(r,e,t)=>{r.ws(`${(t==null?void 0:t.basePath)??""}/ws`,Re(e)),r.use(`${(t==null?void 0:t.basePath)??""}/`,(n,i)=>{fe(e)(xe(n)).then(o=>o.json().then(c=>i.status(o.status).send(c)));});};var x=r=>{if(r)return Array.isArray(r.value)?r.value.map(e=>x(e)):typeof r.value!="object"||r.value===null||r.value instanceof Date?r.value:Object.fromEntries(Object.entries(r.value).map(([e,t])=>[e,x(t)]))};var b=(r,e,t=false)=>Object.entries(e).every(([n,i])=>{if(n==="$and")return i.every(o=>b(r,o,t));if(n==="$or")return i.some(o=>b(r,o,t));let a=(i==null?void 0:i.$eq)!==void 0?i==null?void 0:i.$eq:i;if(typeof i=="object"&&i!==null&&(i==null?void 0:i.$eq)===void 0){if(i.$in!==void 0){let o=r[n];return o===void 0?false:t?!i.$in.includes(o):i.$in.includes(o)}if(i.$not!==void 0&&!t)return b(r,{[n]:i.$not},true);if(i.$gt!==void 0){let o=r[n];return typeof o!="number"?false:t?o<=i.$gt:o>i.$gt}if(i.$gte!==void 0){let o=r[n];return typeof o!="number"?false:t?o<i.$gte:o>=i.$gte}if(i.$lt!==void 0){let o=r[n];return typeof o!="number"?false:t?o>=i.$lt:o<i.$lt}if(i.$lte!==void 0){let o=r[n];return typeof o!="number"?false:t?o>i.$lte:o<=i.$lte}return !r[n]||typeof r[n]!="object"?false:b(r[n],i,t)}return t?r[n]!==a:r[n]===a});var Y=class r{routes;constructor(e){this.routes=e.routes;}static create(e){return new r(e)}},dn=r=>Y.create({...r}),st=r=>({handler:e=>({inputValidator:r??zod.z.undefined(),handler:e})}),X=class r{resourceSchema;middlewares;customMutations;authorization;constructor(e,t,n){this.resourceSchema=e,this.middlewares=new Set,this.customMutations=t??{},this.authorization=n;}use(...e){for(let t of e)this.middlewares.add(t);return this}withMutations(e){return new r(this.resourceSchema,e({mutation:st}),this.authorization)}handleQuery=async({req:e,batcher:t})=>await this.wrapInMiddlewares(async n=>{var a,o;let i=(o=(a=this.authorization)==null?void 0:a.read)==null?void 0:o.call(a,{ctx:n.context});if(typeof i=="boolean"&&!i)throw new Error("Not authorized");return {data:await t.rawFind({resource:n.resource,commonWhere:N(n.where,typeof i=="object"?i:void 0),uniqueWhere:n.relationalWhere,include:n.include,limit:n.limit,sort:n.sort})}})(e);handleMutation=async({req:e,db:t})=>await this.wrapInMiddlewares(async n=>{if(!n.procedure)throw new Error("Procedure is required for mutations");let i=this.customMutations[n.procedure];if(i){let a=i.inputValidator.parse(n.input);return n.input=a,i.handler({req:n,db:t})}else {if(n.procedure==="INSERT"||n.procedure==="UPDATE")return this.handleSet({req:n,db:t,operation:n.procedure});throw new Error(`Unknown procedure: ${n.procedure}`)}})(e);handleSet=async({req:e,db:t,operation:n})=>{if(!e.input)throw new Error("Payload is required");if(!e.resourceId)throw new Error("ResourceId is required");let i=await t.rawFindById(e.resource,e.resourceId);if(n==="INSERT"&&i)throw new Error("Resource already exists");if(n==="UPDATE"&&!i)throw new Error("Resource not found");return t.transaction(async({trx:a})=>{var m,y,d,l,p;let[o,c]=this.resourceSchema.mergeMutation("set",e.input,i);if(!c)throw new Error("Mutation rejected");if(n==="INSERT"){let u=await a.rawInsert(e.resource,e.resourceId,o);if((m=this.authorization)!=null&&m.insert){let f=x(u);f.id=f.id??e.resourceId;let h=this.authorization.insert({ctx:e.context,value:f});if(!(typeof h=="boolean"?h:b(f,h)))throw new Error("Not authorized")}return {data:u,acceptedValues:c}}if((d=(y=this.authorization)==null?void 0:y.update)!=null&&d.preMutation){let u=x(i);u.id=u.id??e.resourceId;let f=this.authorization.update.preMutation({ctx:e.context,value:u});if(!(typeof f=="boolean"?f:b(u,f)))throw new Error("Not authorized")}let s=await a.rawUpdate(e.resource,e.resourceId,o);if((p=(l=this.authorization)==null?void 0:l.update)!=null&&p.postMutation){let u=x(s);u.id=u.id??e.resourceId;let f=this.authorization.update.postMutation({ctx:e.context,value:u});if(!(typeof f=="boolean"?f:b(u,f)))throw new Error("Not authorized")}return {data:s,acceptedValues:c}})};wrapInMiddlewares(e){return t=>Array.from(this.middlewares.values()).reduceRight((n,i)=>a=>i({req:a,next:n}),e)(t)}},ee=class r{middlewares;constructor(e=[]){this.middlewares=e;}collectionRoute(e,t){return new X(e,void 0,t).use(...this.middlewares)}use(...e){return new r([...this.middlewares,...e])}static create(){return new r}},yn=ee.create;var $=class{async insert(e,t){let n=new Date().toISOString();return x(await this.rawInsert(e.name,t.id,{value:Object.fromEntries(Object.entries(t).map(([i,a])=>[i,{value:a,_meta:{timestamp:n}}]))}))}async update(e,t,n){let i=new Date().toISOString(),{id:a,...o}=n;return x(await this.rawUpdate(e.name,t,{value:Object.fromEntries(Object.entries(o).map(([c,s])=>[c,{value:s,_meta:{timestamp:i}}]))}))}};function q(r,e,t,n){if(!r)throw new Error("Schema not initialized");let i=r[e];if(!i)throw new Error("Resource not found");let a=n.$or,o=n.$and;return (a?t.or:t.and)(a?n.$or.map(c=>q(r,e,t,c)):o?n.$and.map(c=>q(r,e,t,c)):Object.entries(n).map(([c,s])=>{var m,y;if(i.fields[c])return (s==null?void 0:s.$eq)!==void 0?t(`${e}.${c}`,s.$eq===null?"is":"=",s.$eq):(s==null?void 0:s.$in)!==void 0?t(`${e}.${c}`,"in",s.$in):(s==null?void 0:s.$not)!==void 0?((m=s==null?void 0:s.$not)==null?void 0:m.$in)!==void 0?t(`${e}.${c}`,"not in",s.$not.$in):((y=s==null?void 0:s.$not)==null?void 0:y.$eq)!==void 0?t(`${e}.${c}`,s.$not.$eq===null?"is not":"!=",s.$not.$eq):t(`${e}.${c}`,s.$not===null?"is not":"!=",s.$not):(s==null?void 0:s.$gt)!==void 0?t(`${e}.${c}`,">",s.$gt):(s==null?void 0:s.$gte)!==void 0?t(`${e}.${c}`,">=",s.$gte):(s==null?void 0:s.$lt)!==void 0?t(`${e}.${c}`,"<",s.$lt):(s==null?void 0:s.$lte)!==void 0?t(`${e}.${c}`,"<=",s.$lte):t(`${e}.${c}`,s===null?"is":"=",s);if(i.relations[c]){let d=i.relations[c],l=d.entity.name;return d.type==="many"?t.exists(te(r,l,t.selectFrom(l).select("id").whereRef(d.foreignColumn,"=",`${e}.id`),s)):q(r,l,t,s)}return null}).filter(Boolean))}function F(r,e,t,n){let i=r[e];if(!i)throw new Error("Resource not found");if(!n)return t;if(n.$and){for(let a of n.$and)t=F(r,e,t,a);return t}else if(n.$or){for(let a of n.$or)t=F(r,e,t,a);return t}for(let[a,o]of Object.entries(n)){if(!i.relations[a])continue;let c=i.relations[a],s=c.entity.name,m=c.type==="one"?"id":c.foreignColumn,y=c.type==="one"?c.relationalColumn:"id";t=t.leftJoin(s,`${s}.${m}`,`${e}.${y}`),o instanceof Object&&!Array.isArray(o)&&o!==null&&(t=F(r,s,t,o));}return t}function te(r,e,t,n){return !n||Object.keys(n).length===0?t:(t=F(r,e,t,n),t.where(i=>q(r,e,i,n)))}function K(r,e,t,n){if(!n)return t;if(!r)throw new Error("Schema not initialized");let i=r[e];if(!i)throw new Error(`Resource not found: ${e}`);for(let a of Object.keys(n)){if(!i.relations[a])throw new Error(`Relation ${a} not found in resource ${e}`);let o=i.relations[a],c=o.entity.name,s=n[a],m=o.type==="one"?"id":o.foreignColumn,y=o.type==="one"?o.relationalColumn:"id",d=o.type==="one"?postgres.jsonObjectFrom:postgres.jsonArrayFrom,l=typeof s=="object"&&s!==null;t=t.select(p=>{let u=p.selectFrom(c).selectAll(c).whereRef(`${c}.${m}`,"=",`${e}.${y}`).select(f=>postgres.jsonObjectFrom(f.selectFrom(`${c}_meta`).selectAll(`${c}_meta`).whereRef(`${c}_meta.id`,"=",`${c}.id`)).as("_meta"));return l&&(u=K(r,c,u,s)),d(u).as(a)});}return t}var ne=class r extends ${db;schema;constructor(e,t){super(),this.isKyselyLike(e)?this.db=e:this.db=new kysely.Kysely({dialect:new kysely.PostgresDialect({pool:e})}),this.schema=t,this.rawInsert=this.rawInsert.bind(this),this.rawUpdate=this.rawUpdate.bind(this);}async updateSchema(e){this.schema=e;let t=await this.db.introspection.getTables();for(let[n,i]of Object.entries(e)){let a=t.find(s=>s.name===n);a||await this.db.schema.createTable(n).ifNotExists().execute();let o=`${n}_meta`,c=t.find(s=>s.name===o);c||await this.db.schema.createTable(o).ifNotExists().execute();for(let[s,m]of Object.entries(i.fields)){let y=a==null?void 0:a.columns.find(p=>p.name===s),d=m.getStorageFieldType();y?y.dataType!==d.type&&console.error("Column type mismatch:",s,"expected to have type:",d.type,"but has type:",y.dataType):(await this.db.schema.alterTable(n).addColumn(s,d.type,p=>{let u=p;return d.unique&&(u=u.unique()),d.nullable||(u=u.notNull()),d.references&&(u=u.references(d.references)),d.primary&&(u=u.primaryKey()),d.default!==void 0&&(u=u.defaultTo(d.default)),u}).execute().catch(p=>{throw console.error("Error adding column",s,p),p}),d.index&&await this.db.schema.createIndex(`${n}_${s}_index`).on(n).column(s).execute().catch(()=>{})),(c==null?void 0:c.columns.find(p=>p.name===s))||await this.db.schema.alterTable(o).addColumn(s,"varchar",p=>{let u=p;return d.primary&&(u=u.primaryKey().references(`${n}.${s}`)),u}).execute();}}}async rawFindById(e,t,n){if(!this.schema)throw new Error("Schema not initialized");let i=await this.db.selectFrom(e).where("id","=",t).selectAll(e).select(o=>postgres.jsonObjectFrom(o.selectFrom(`${e}_meta`).selectAll(`${e}_meta`).whereRef(`${e}_meta.id`,"=",`${e}.id`)).as("_meta"));i=K(this.schema,e,i,n);let a=await i.executeTakeFirst();if(a)return this.convertToMaterializedLiveType(a)}async findOne(e,t,n){let i=await this.rawFindById(e.name,t,n==null?void 0:n.include);if(i)return x(i)}async rawFind(e){if(!this.schema)throw new Error("Schema not initialized");let{resource:t,where:n,include:i,limit:a,sort:o}=e,c=this.db.selectFrom(t).selectAll(t).select(d=>postgres.jsonObjectFrom(d.selectFrom(`${t}_meta`).selectAll(`${t}_meta`).whereRef(`${t}_meta.id`,"=",`${t}.id`)).as("_meta"));c=te(this.schema,t,c,n),c=K(this.schema,t,c,i),a!==void 0&&(c=c.limit(a)),o!==void 0&&o.forEach(d=>{c=c.orderBy(d.key,d.direction);});let s=await c.execute(),m=Object.fromEntries(s.map(d=>{let{id:l}=d;return [l,d]}));return Object.keys(m).length===0?{}:Object.entries(m).reduce((d,[l,p])=>(d[l]=this.convertToMaterializedLiveType(p),d),{})}async find(e,t){let n=await this.rawFind({resource:e.name,where:t==null?void 0:t.where,include:t==null?void 0:t.include,limit:t==null?void 0:t.limit,sort:t==null?void 0:t.sort});return Object.fromEntries(Object.entries(n).map(([i,a])=>[i,x(a)]))}async rawInsert(e,t,n){var o;let i={},a={};for(let[c,s]of Object.entries(n.value)){let m=(o=s._meta)==null?void 0:o.timestamp;m&&(i[c]=s.value,a[c]=m);}return await this.db.insertInto(e).values({...i,id:t}).execute().then(()=>{this.db.insertInto(`${e}_meta`).values({...a,id:t}).execute();}),n}async rawUpdate(e,t,n){var o;let i={},a={};for(let[c,s]of Object.entries(n.value)){let m=(o=s._meta)==null?void 0:o.timestamp;m&&(i[c]=s.value,a[c]=m);}return await Promise.all([this.db.updateTable(e).set(i).where("id","=",t).execute(),this.db.insertInto(`${e}_meta`).values({...a,id:t}).onConflict(c=>c.column("id").doUpdateSet(a)).execute()]),n}async transaction(e){if(!this.schema)throw new Error("Schema not initialized");if(this.db.isTransaction){let n=Math.random().toString(36).substring(2,15),i=await this.db.savepoint(n).execute();try{return await e({trx:this,commit:()=>i.releaseSavepoint(n).execute().then(()=>{}),rollback:()=>i.rollbackToSavepoint(n).execute().then(()=>{})}).then(a=>i.isCommitted||i.isRolledBack?a:i.releaseSavepoint(n).execute().then(()=>a))}catch(a){throw await i.rollbackToSavepoint(n).execute().catch(()=>{}),a}}let t=await this.db.startTransaction().execute();try{return await e({trx:new r(t,this.schema),commit:()=>t.commit().execute(),rollback:()=>t.rollback().execute()}).then(n=>t.isCommitted||t.isRolledBack?n:t.commit().execute().then(()=>n))}catch(n){throw await t.rollback().execute(),n}}convertToMaterializedLiveType(e){return {value:Object.entries(e).reduce((t,[n,i])=>{var a,o,c;return n==="_meta"||(n==="id"?t[n]={value:i}:Array.isArray(i)?t[n]={value:i.map(s=>this.convertToMaterializedLiveType(s)),_meta:{timestamp:(a=e==null?void 0:e._meta)==null?void 0:a[n]}}:typeof i=="object"&&i!==null&&!(i instanceof Date)?t[n]={...this.convertToMaterializedLiveType(i),_meta:{timestamp:(o=e==null?void 0:e._meta)==null?void 0:o[n]}}:t[n]={value:i,_meta:{timestamp:(c=e==null?void 0:e._meta)==null?void 0:c[n]}}),t},{})}}isKyselyLike(e){if(e instanceof kysely.Kysely)return true;if(!e||typeof e!="object")return false;let t=e,n=typeof t.selectFrom=="function",i=typeof t.startTransaction=="function",a=typeof t.savepoint=="function",o=typeof t.isTransaction=="boolean"||typeof t.isTransaction=="function";return n&&i||a&&o}};var re=class r{router;storage;schema;middlewares=new Set;contextProvider;mutationSubscriptions=new Set;constructor(e){var t;this.router=e.router,this.storage=e.storage,this.schema=e.schema,(t=e.middlewares)==null||t.forEach(n=>{this.middlewares.add(n);}),this.storage.updateSchema(this.schema),this.contextProvider=e.contextProvider;}static create(e){return new r(e)}subscribeToMutations(e){return this.mutationSubscriptions.add(e),()=>{this.mutationSubscriptions.delete(e);}}handleQuery(e){let t=new z(this.storage);return this.wrapInMiddlewares(async n=>{var m;let i=Se(n,this.schema,{stepId:"query",collectionName:n.resource,included:Object.keys(n.include??{})}),a={headers:n.headers,cookies:n.cookies,queryParams:n.queryParams,context:n.context},o={};for(let y=0;y<i.length;y++){let d=i[y],l=this.router.routes[d.resource];if(!l)throw new Error("Invalid resource");let p=d.getWhere&&d.referenceGetter?d.referenceGetter(o).map(d.getWhere):[void 0],u=(m=o[d.prevStepId??""])==null?void 0:m.flatMap(R=>{var M;return Object.keys(((M=R==null?void 0:R.result)==null?void 0:M.data)??{})}),h=(await Promise.allSettled(p.map(async(R,M)=>{let C=u==null?void 0:u[M],Me=await l.handleQuery({req:{type:"QUERY",...d,...a,where:d.where,relationalWhere:R},batcher:t});return {includedBy:C,result:Me}}))).flatMap(R=>R.status==="fulfilled"?[R.value]:[]);o[d.stepId]=h;}let c=Object.fromEntries(Object.entries(o).flatMap(([y,d],l)=>d.flatMap(p=>Object.entries(p.result.data).map(([u,f])=>[`${y}.${u}`,{data:f,includedBy:y!=="query"&&p.includedBy?`${y.split(".").slice(0,-1).join(".")}.${p.includedBy}`:void 0,path:y.split(".").slice(-1)[0],isMany:i[l].isMany,collectionName:i[l].collectionName,included:i[l].included}]))));return Object.keys(c).reduceRight((y,d)=>{var u,f;let l=c[d],p=l.path;if(p==="query"&&(y.data[d.replace("query.","")]=l.data),l.included.length)for(let h of l.included)l.data.value[h]??=((f=(u=this.schema[l.collectionName])==null?void 0:u.relations[h])==null?void 0:f.type)==="many"?{value:[]}:{value:null};if(l.includedBy){let h=c[l.includedBy];if(!h)return y;l.isMany?(h.data.value[p]??={value:[]},h.data.value[p].value.push(l.data)):h.data.value[p]=l.data;}return y},{data:{}})})(e.req)}async handleMutation(e){let t=await this.wrapInMiddlewares(async n=>{let i=this.router.routes[n.resource];if(!i)throw new Error("Invalid resource");return i.handleMutation({req:n,db:this.storage})})(e.req);if(t&&e.req.type==="MUTATE"&&t.acceptedValues&&(e.req.procedure==="INSERT"||e.req.procedure==="UPDATE")&&e.req.resourceId){let i=t.acceptedValues??{},a=e.req,o=a.resourceId;Object.keys(i).length&&o&&this.mutationSubscriptions.forEach(c=>{c({id:e.req.context.messageId,type:"MUTATE",resource:a.resource,payload:i,resourceId:o,procedure:a.procedure});});}return t}use(e){return this.middlewares.add(e),this}context(e){return this.contextProvider=e,this}wrapInMiddlewares(e){return t=>Array.from(this.middlewares.values()).reduceRight((n,i)=>a=>i({req:a,next:n}),e)(t)}},On=re.create;function Se(r,e,t){let{include:n,...i}=r,{stepId:a}=t,o=[{...i,...t}];if(n&&typeof n=="object"&&Object.keys(n).length>0){let c=e[i.resource];if(!c)throw new Error(`Resource ${i.resource} not found`);o.push(...Object.entries(n).flatMap(([s,m])=>{let y=c.relations[s];if(!y)throw new Error(`Relation ${s} not found for resource ${i.resource}`);let d=y.entity.name;return Se({...i,resource:d,include:m},e,{getWhere:y.type==="one"?l=>({id:l}):l=>({[y.foreignColumn]:l}),referenceGetter:l=>l[a].flatMap(p=>p.result.data?y.type==="one"?Object.values(p.result.data).map(u=>{var f,h;return (h=(f=u.value)==null?void 0:f[y.relationalColumn])==null?void 0:h.value}):Object.keys(p.result.data):[]),stepId:`${a}.${s}`,prevStepId:a,isMany:y.type==="many",collectionName:d,included:typeof m=="object"?Object.keys(m):[]})}));}return o}
|
|
2
2
|
exports.Route=X;exports.RouteFactory=ee;exports.Router=Y;exports.SQLStorage=ne;exports.Server=re;exports.Storage=$;exports.expressAdapter=Kt;exports.routeFactory=yn;exports.router=dn;exports.server=On;
|
package/dist/server.d.cts
CHANGED
|
@@ -193,7 +193,7 @@ type ContextProvider = (req: Omit<BaseRequest, "context"> & {
|
|
|
193
193
|
type MutationHandler = (mutation: DefaultMutation) => void;
|
|
194
194
|
type NextFunction<O, R = Request> = (req: R) => Awaitable<O>;
|
|
195
195
|
type Middleware<T = any> = (opts: {
|
|
196
|
-
req:
|
|
196
|
+
req: Request;
|
|
197
197
|
next: NextFunction<T>;
|
|
198
198
|
}) => ReturnType<NextFunction<T>>;
|
|
199
199
|
declare class Server<TRouter extends AnyRouter> {
|
package/dist/server.d.ts
CHANGED
|
@@ -193,7 +193,7 @@ type ContextProvider = (req: Omit<BaseRequest, "context"> & {
|
|
|
193
193
|
type MutationHandler = (mutation: DefaultMutation) => void;
|
|
194
194
|
type NextFunction<O, R = Request> = (req: R) => Awaitable<O>;
|
|
195
195
|
type Middleware<T = any> = (opts: {
|
|
196
|
-
req:
|
|
196
|
+
req: Request;
|
|
197
197
|
next: NextFunction<T>;
|
|
198
198
|
}) => ReturnType<NextFunction<T>>;
|
|
199
199
|
declare class Server<TRouter extends AnyRouter> {
|
package/dist/server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {a,b,t}from'./chunk-XNKBHWSC.js';import v from'node:crypto';import Ue,{parse}from'qs';import {z as z$1}from'zod';import'js-xxhash';import {Kysely,PostgresDialect}from'kysely';import {jsonObjectFrom,jsonArrayFrom}from'kysely/helpers/postgres';var D=a(P=>{Object.defineProperty(P,"__esModule",{value:true});P.parse=ve;P.serialize=Le;var Ie=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,Ee=/^[\u0021-\u003A\u003C-\u007E]*$/,Ae=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,Oe=/^[\u0020-\u003A\u003D-\u007E]*$/,$e=Object.prototype.toString,je=(()=>{let i=function(){};return i.prototype=Object.create(null),i})();function ve(i,t){let e=new je,r=i.length;if(r<2)return e;let n=(t==null?void 0:t.decode)||Ce,a=0;do{let o=i.indexOf("=",a);if(o===-1)break;let c=i.indexOf(";",a),s=c===-1?r:c;if(o>s){a=i.lastIndexOf(";",o-1)+1;continue}let y=te(i,a,o),p=re(i,o,y),l=i.slice(y,p);if(e[l]===void 0){let d=te(i,o+1,s),m=re(i,s,d),u=n(i.slice(d,m));e[l]=u;}a=s+1;}while(a<r);return e}function te(i,t,e){do{let r=i.charCodeAt(t);if(r!==32&&r!==9)return t}while(++t<e);return e}function re(i,t,e){for(;t>e;){let r=i.charCodeAt(--t);if(r!==32&&r!==9)return t+1}return e}function Le(i,t,e){let r=(e==null?void 0:e.encode)||encodeURIComponent;if(!Ie.test(i))throw new TypeError(`argument name is invalid: ${i}`);let n=r(t);if(!Ee.test(n))throw new TypeError(`argument val is invalid: ${t}`);let a=i+"="+n;if(!e)return a;if(e.maxAge!==void 0){if(!Number.isInteger(e.maxAge))throw new TypeError(`option maxAge is invalid: ${e.maxAge}`);a+="; Max-Age="+e.maxAge;}if(e.domain){if(!Ae.test(e.domain))throw new TypeError(`option domain is invalid: ${e.domain}`);a+="; Domain="+e.domain;}if(e.path){if(!Oe.test(e.path))throw new TypeError(`option path is invalid: ${e.path}`);a+="; Path="+e.path;}if(e.expires){if(!Pe(e.expires)||!Number.isFinite(e.expires.valueOf()))throw new TypeError(`option expires is invalid: ${e.expires}`);a+="; Expires="+e.expires.toUTCString();}if(e.httpOnly&&(a+="; HttpOnly"),e.secure&&(a+="; Secure"),e.partitioned&&(a+="; Partitioned"),e.priority)switch(typeof e.priority=="string"?e.priority.toLowerCase():void 0){case "low":a+="; Priority=Low";break;case "medium":a+="; Priority=Medium";break;case "high":a+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${e.priority}`)}if(e.sameSite)switch(typeof e.sameSite=="string"?e.sameSite.toLowerCase():e.sameSite){case true:case "strict":a+="; SameSite=Strict";break;case "lax":a+="; SameSite=Lax";break;case "none":a+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${e.sameSite}`)}return a}function Ce(i){if(i.indexOf("%")===-1)return i;try{return decodeURIComponent(i)}catch{return i}}function Pe(i){return $e.call(i)==="[object Date]"}});var Y="0123456789ABCDEFGHJKMNPQRSTVWXYZ",E=32;var ge=16,X=10,J=0xffffffffffff;var w;(function(i){i.Base32IncorrectEncoding="B32_ENC_INVALID",i.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",i.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",i.EncodeTimeNegative="ENC_TIME_NEG",i.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",i.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",i.PRNGDetectFailure="PRNG_DETECT",i.ULIDInvalid="ULID_INVALID",i.Unexpected="UNEXPECTED",i.UUIDInvalid="UUID_INVALID";})(w||(w={}));var S=class extends Error{constructor(t,e){super(`${e} (${t})`),this.name="ULIDError",this.code=t;}};function Re(i){let t=Math.floor(i()*E);return t===E&&(t=E-1),Y.charAt(t)}function be(i){var r;let t=xe(),e=t&&(t.crypto||t.msCrypto)||(typeof v<"u"?v:null);if(typeof(e==null?void 0:e.getRandomValues)=="function")return ()=>{let n=new Uint8Array(1);return e.getRandomValues(n),n[0]/255};if(typeof(e==null?void 0:e.randomBytes)=="function")return ()=>e.randomBytes(1).readUInt8()/255;if((r=v)!=null&&r.randomBytes)return ()=>v.randomBytes(1).readUInt8()/255;throw new S(w.PRNGDetectFailure,"Failed to find a reliable PRNG")}function xe(){return Me()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function we(i,t){let e="";for(;i>0;i--)e=Re(t)+e;return e}function Se(i,t=X){if(isNaN(i))throw new S(w.EncodeTimeValueMalformed,`Time must be a number: ${i}`);if(i>J)throw new S(w.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${J}: ${i}`);if(i<0)throw new S(w.EncodeTimeNegative,`Time must be positive: ${i}`);if(Number.isInteger(i)===false)throw new S(w.EncodeTimeValueMalformed,`Time must be an integer: ${i}`);let e,r="";for(let n=t;n>0;n--)e=i%E,r=Y.charAt(e)+r,i=(i-e)/E;return r}function Me(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function ee(i,t){let e=be(),r=Date.now();return Se(r,X)+we(ge,e)}var W=()=>ee().toLowerCase();var L=(...i)=>{let t=i.filter(e=>!!e);return t.length===0?{}:t.length===1?t[0]:{$and:t}};var C=class{storage;queue=new Map;scheduled=false;constructor(t){this.storage=t;}async rawFind({resource:t,commonWhere:e,uniqueWhere:r,...n}){return new Promise((a,o)=>{let c=this.getBatchKey({resource:t,commonWhere:e,...n}),s={resource:t,commonWhere:e,uniqueWhere:r,...n,resolve:a,reject:o};this.queue.has(c)||this.queue.set(c,[]);let y=this.queue.get(c);y&&y.push(s),this.scheduled||(this.scheduled=true,setImmediate(()=>{this.processBatch();}));})}getBatchKey(t){let{resource:e,commonWhere:r,...n}=t;return `${e}:${JSON.stringify(r??{})}:${JSON.stringify(n??{})}`}async processBatch(){this.scheduled=false;let t=Array.from(this.queue.entries());this.queue.clear();for(let[,e]of t)try{await this.executeBatchedRequests(e);}catch(r){e.forEach(n=>{n.reject(r);});}}async executeBatchedRequests(t){var d,m;if(t.length===0)return;let e=t[0],{resource:r,commonWhere:n,include:a,sort:o}=e,c=t.length===1?e.limit:void 0,s=t.map(u=>u.uniqueWhere).filter(u=>u!==void 0),y=n,p=(d=Object.entries(s[0]??{})[0])==null?void 0:d[0];if(s.length>0){let u=s.map(f=>f[p]).filter(f=>f!=null);u.length>0&&(y=L(n,{[p]:{$in:u}}));}let l=await this.storage.rawFind({resource:r,where:y,include:a,sort:o,limit:c});for(let u of t){let f={};if(u.uniqueWhere){let[T,R]=Object.entries(u.uniqueWhere)[0];for(let[M,j]of Object.entries(l))((m=j.value[T])==null?void 0:m.value)===R&&(f[M]=j);}else Object.assign(f,l);u.resolve(f);}}};var ae=b(D(),1);var z=z$1.object({resource:z$1.string(),where:z$1.record(z$1.string(),z$1.any()).optional(),include:z$1.record(z$1.string(),z$1.any()).optional(),lastSyncedAt:z$1.string().optional(),limit:z$1.coerce.number().optional(),sort:z$1.array(z$1.object({key:z$1.string(),direction:z$1.enum(["asc","desc"])})).optional()}),k=z$1.record(z$1.string(),z$1.object({value:z$1.string().or(z$1.number()).or(z$1.boolean()).or(z$1.date()).nullable(),_meta:z$1.object({timestamp:z$1.string().optional().nullable()}).optional()})),ze=k.superRefine((i,t)=>{i.id&&t.addIssue({code:z$1.ZodIssueCode.custom,message:"Payload cannot have an id"});}),ne=z$1.object({id:z$1.string().optional(),type:z$1.literal("MUTATE"),resource:z$1.string(),resourceId:z$1.string().optional()}),A=ne.extend({procedure:z$1.string(),payload:z$1.any().optional()}),O=ne.extend({procedure:z$1.enum(["INSERT","UPDATE"]),payload:ze});z$1.union([O,A]);var ie=z.omit({resource:true}),B=A.omit({id:true,type:true,resource:true,procedure:true}),_=O.omit({id:true,type:true,resource:true,procedure:true});z$1.union([_,B]);var oe=i=>async t=>{var e;try{let r=typeof t.headers.getSetCookie=="function"?Object.fromEntries(t.headers):t.headers,n={headers:r,cookies:r.cookie?ae.default.parse(r.cookie):{}},a=new URL(t.url),o=a.pathname.split("/"),c=a.searchParams,s=Ue.parse(c.toString()),y=await((e=i.contextProvider)==null?void 0:e.call(i,{transport:"HTTP",headers:n.headers,cookies:n.cookies,queryParams:s}))??{};if(t.method==="GET"){let p=o[o.length-1],{success:l,data:d,error:m}=ie.safeParse(s);if(!l)return Response.json({message:"Invalid query",code:"INVALID_QUERY",details:m},{status:400});let u=await i.handleQuery({req:{...n,...d,type:"QUERY",resource:p,context:y,queryParams:s}});return !u||!u.data?Response.json({message:"Invalid resource",code:"INVALID_RESOURCE"},{status:400}):Response.json(u.data)}if(t.method==="POST")try{let p=o[o.length-1],l=o[o.length-2],d=t.body?await t.json():{},m;if(p==="insert"||p==="update"){let{success:f,data:T,error:R}=_.safeParse(d);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:R},{status:400});m=T;}else {let{success:f,data:T,error:R}=B.safeParse(d);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:R},{status:400});m=T;}let u=await i.handleMutation({req:{...n,type:"MUTATE",resource:l,input:m.payload,context:y,resourceId:m.resourceId,procedure:p==="insert"||p==="update"?p.toUpperCase():p,queryParams:{}}});return Response.json(u)}catch(p){return console.error("Error parsing mutation from the client:",p),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}return Response.json({message:"Not found",code:"NOT_FOUND"},{status:404})}catch(r){return console.error("Unexpected error:",r),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}};var ue=b(D(),1);var I=z$1.string(),qe=z$1.object({id:I,type:z$1.literal("SUBSCRIBE"),resource:z$1.string()}),We=z.extend({id:I,type:z$1.literal("QUERY")}),se=O.extend({id:I}),De=A.extend({id:I}),ke=z$1.union([De,se]),ce=z$1.union([qe,We,ke]),Be=z$1.object({id:I,type:z$1.literal("REJECT"),resource:z$1.string(),message:z$1.string().optional()}),_e=z$1.object({id:I,type:z$1.literal("REPLY"),data:z$1.any()});z$1.union([Be,_e,se]);z$1.object({resource:z$1.string(),data:z$1.record(z$1.string(),k)});var de=i=>{let t={},e={};return i.subscribeToMutations(r=>{let n=r;!n.resourceId||!n.payload||(console.log("Mutation propagated:",n),Object.entries(e[n.resource]??{}).forEach(([a,o])=>{var c;(c=t[a])==null||c.send(JSON.stringify({...n,id:n.id??W()}));}));}),(r,n)=>{var p;let a=l=>{r.send(JSON.stringify(l));},o=W(),c={headers:n.headers,cookies:typeof n.headers.cookie=="string"?ue.default.parse(n.headers.cookie):{}},s=parse(n.url.split("?")[1]),y=(p=i.contextProvider)==null?void 0:p.call(i,{transport:"WEBSOCKET",headers:c.headers,cookies:c.cookies,queryParams:s});t[o]=r,console.log("Client connected:",o),r.on("message",async l=>{try{console.log("Message received from the client:",l);let d=ce.parse(JSON.parse(l.toString()));if(d.type==="SUBSCRIBE"){let{resource:m}=d;e[m]||(e[m]={}),e[m][o]={};}else if(d.type==="QUERY"){let{resource:m}=d,u=await i.handleQuery({req:{...c,type:"QUERY",resource:m,context:await y??{},queryParams:s}});if(!u||!u.data)throw new Error("Invalid resource");a({id:d.id,type:"REPLY",data:{resource:m,data:Object.fromEntries(Object.entries(u.data??{}).map(([f,T])=>[f,T.value]))}});}else if(d.type==="MUTATE"){let{resource:m}=d;console.log("Received mutation from client:",d);try{let u=await i.handleMutation({req:{...c,type:"MUTATE",resource:m,input:d.payload,context:{messageId:d.id,...await y??{}},resourceId:d.resourceId,procedure:d.procedure,queryParams:s}});d.procedure&&d.procedure!=="INSERT"&&d.procedure!=="UPDATE"&&a({id:d.id,type:"REPLY",data:u});}catch(u){a({id:d.id,type:"REJECT",resource:m,message:u.message}),console.error("Error parsing mutation from the client:",u);}}}catch(d){console.error("Error handling message from the client:",d);}}),r.on("close",()=>{console.log("Connection closed",o),delete t[o];for(let l of Object.values(e))delete l[o];});}};function le(i){let t=`${i.protocol}://${i.hostname}${i.url}`,e=new Headers;return Object.entries(i.headers).forEach(([r,n])=>{n&&e.set(r,Array.isArray(n)?n.join(","):n);}),new Request(t,{method:i.method,headers:e,body:i.body&&i.method!=="GET"?JSON.stringify(i.body):void 0})}var It=(i,t,e)=>{i.ws(`${(e==null?void 0:e.basePath)??""}/ws`,de(t)),i.use(`${(e==null?void 0:e.basePath)??""}/`,(r,n)=>{oe(t)(le(r)).then(o=>o.json().then(c=>n.status(o.status).send(c)));});};var x=(i,t,e=false)=>Object.entries(t).every(([r,n])=>{if(r==="$and")return n.every(o=>x(i,o,e));if(r==="$or")return n.some(o=>x(i,o,e));let a=(n==null?void 0:n.$eq)!==void 0?n==null?void 0:n.$eq:n;if(typeof n=="object"&&n!==null&&(n==null?void 0:n.$eq)===void 0){if(n.$in!==void 0){let o=i[r];return o===void 0?false:e?!n.$in.includes(o):n.$in.includes(o)}if(n.$not!==void 0&&!e)return x(i,{[r]:n.$not},true);if(n.$gt!==void 0){let o=i[r];return typeof o!="number"?false:e?o<=n.$gt:o>n.$gt}if(n.$gte!==void 0){let o=i[r];return typeof o!="number"?false:e?o<n.$gte:o>=n.$gte}if(n.$lt!==void 0){let o=i[r];return typeof o!="number"?false:e?o>=n.$lt:o<n.$lt}if(n.$lte!==void 0){let o=i[r];return typeof o!="number"?false:e?o>n.$lte:o<=n.$lte}return !i[r]||typeof i[r]!="object"?false:x(i[r],n,e)}return e?i[r]!==a:i[r]===a});var V=class i{routes;constructor(t){this.routes=t.routes;}static create(t){return new i(t)}},Pt=i=>V.create({...i}),Fe=i=>({handler:t=>({inputValidator:i??z$1.undefined(),handler:t})}),Q=class i{resourceSchema;middlewares;customMutations;authorization;constructor(t,e,r){this.resourceSchema=t,this.middlewares=new Set,this.customMutations=e??{},this.authorization=r;}use(...t){for(let e of t)this.middlewares.add(e);return this}withMutations(t){return new i(this.resourceSchema,t({mutation:Fe}))}handleQuery=async({req:t,batcher:e})=>await this.wrapInMiddlewares(async r=>{var a,o;let n=(o=(a=this.authorization)==null?void 0:a.read)==null?void 0:o.call(a,{ctx:r.context});if(typeof n=="boolean"&&!n)throw new Error("Not authorized");return {data:await e.rawFind({resource:r.resource,commonWhere:L(r.where,typeof n=="object"?n:void 0),uniqueWhere:r.relationalWhere,include:r.include,limit:r.limit,sort:r.sort})}})(t);handleMutation=async({req:t,db:e})=>await this.wrapInMiddlewares(async r=>{if(!r.procedure)throw new Error("Procedure is required for mutations");let n=this.customMutations[r.procedure];if(n){let a=n.inputValidator.parse(r.input);return r.input=a,n.handler({req:r,db:e})}else {if(r.procedure==="INSERT"||r.procedure==="UPDATE")return this.handleSet({req:r,db:e,operation:r.procedure});throw new Error(`Unknown procedure: ${r.procedure}`)}})(t);handleSet=async({req:t$1,db:e,operation:r})=>{if(!t$1.input)throw new Error("Payload is required");if(!t$1.resourceId)throw new Error("ResourceId is required");let n=await e.rawFindById(t$1.resource,t$1.resourceId);if(r==="INSERT"&&n)throw new Error("Resource already exists");if(r==="UPDATE"&&!n)throw new Error("Resource not found");return e.transaction(async({trx:a})=>{var y,p,l,d,m;let[o,c]=this.resourceSchema.mergeMutation("set",t$1.input,n);if(!c)throw new Error("Mutation rejected");if(r==="INSERT"){let u=await a.rawInsert(t$1.resource,t$1.resourceId,o);if((y=this.authorization)!=null&&y.insert){let f=t(u);f.id=f.id??t$1.resourceId;let T=this.authorization.insert({ctx:t$1.context,value:f});if(!(typeof T=="boolean"?T:x(f,T)))throw new Error("Not authorized")}return {data:u,acceptedValues:c}}if((l=(p=this.authorization)==null?void 0:p.update)!=null&&l.preMutation){let u=t(n);u.id=u.id??t$1.resourceId;let f=this.authorization.update.preMutation({ctx:t$1.context,value:u});if(!(typeof f=="boolean"?f:x(u,f)))throw new Error("Not authorized")}let s=await a.rawUpdate(t$1.resource,t$1.resourceId,o);if((m=(d=this.authorization)==null?void 0:d.update)!=null&&m.postMutation){let u=t(s);u.id=u.id??t$1.resourceId;let f=this.authorization.update.postMutation({ctx:t$1.context,value:u});if(!(typeof f=="boolean"?f:x(u,f)))throw new Error("Not authorized")}return {data:s,acceptedValues:c}})};wrapInMiddlewares(t){return e=>Array.from(this.middlewares.values()).reduceRight((r,n)=>a=>n({req:a,next:r}),t)(e)}},F=class i{middlewares;constructor(t=[]){this.middlewares=t;}collectionRoute(t,e){return new Q(t,void 0,e).use(...this.middlewares)}use(...t){return new i([...this.middlewares,...t])}static create(){return new i}},zt=F.create;var $=class{async insert(t$1,e){let r=new Date().toISOString();return t(await this.rawInsert(t$1.name,e.id,{value:Object.fromEntries(Object.entries(e).map(([n,a])=>[n,{value:a,_meta:{timestamp:r}}]))}))}async update(t$1,e,r){let n=new Date().toISOString(),{id:a,...o}=r;return t(await this.rawUpdate(t$1.name,e,{value:Object.fromEntries(Object.entries(o).map(([c,s])=>[c,{value:s,_meta:{timestamp:n}}]))}))}};function N(i,t,e,r){if(!i)throw new Error("Schema not initialized");let n=i[t];if(!n)throw new Error("Resource not found");let a=r.$or,o=r.$and;return (a?e.or:e.and)(a?r.$or.map(c=>N(i,t,e,c)):o?r.$and.map(c=>N(i,t,e,c)):Object.entries(r).map(([c,s])=>{var y,p;if(n.fields[c])return (s==null?void 0:s.$eq)!==void 0?e(`${t}.${c}`,s.$eq===null?"is":"=",s.$eq):(s==null?void 0:s.$in)!==void 0?e(`${t}.${c}`,"in",s.$in):(s==null?void 0:s.$not)!==void 0?((y=s==null?void 0:s.$not)==null?void 0:y.$in)!==void 0?e(`${t}.${c}`,"not in",s.$not.$in):((p=s==null?void 0:s.$not)==null?void 0:p.$eq)!==void 0?e(`${t}.${c}`,s.$not.$eq===null?"is not":"!=",s.$not.$eq):e(`${t}.${c}`,s.$not===null?"is not":"!=",s.$not):(s==null?void 0:s.$gt)!==void 0?e(`${t}.${c}`,">",s.$gt):(s==null?void 0:s.$gte)!==void 0?e(`${t}.${c}`,">=",s.$gte):(s==null?void 0:s.$lt)!==void 0?e(`${t}.${c}`,"<",s.$lt):(s==null?void 0:s.$lte)!==void 0?e(`${t}.${c}`,"<=",s.$lte):e(`${t}.${c}`,s===null?"is":"=",s);if(n.relations[c]){let l=n.relations[c],d=l.entity.name;return l.type==="many"?e.exists(Z(i,d,e.selectFrom(d).select("id").whereRef(l.foreignColumn,"=",`${t}.id`),s)):N(i,d,e,s)}return null}).filter(Boolean))}function U(i,t,e,r){let n=i[t];if(!n)throw new Error("Resource not found");if(!r)return e;if(r.$and){for(let a of r.$and)e=U(i,t,e,a);return e}else if(r.$or){for(let a of r.$or)e=U(i,t,e,a);return e}for(let[a,o]of Object.entries(r)){if(!n.relations[a])continue;let c=n.relations[a],s=c.entity.name,y=c.type==="one"?"id":c.foreignColumn,p=c.type==="one"?c.relationalColumn:"id";e=e.leftJoin(s,`${s}.${y}`,`${t}.${p}`),o instanceof Object&&!Array.isArray(o)&&o!==null&&(e=U(i,s,e,o));}return e}function Z(i,t,e,r){return !r||Object.keys(r).length===0?e:(e=U(i,t,e,r),e.where(n=>N(i,t,n,r)))}function q(i,t,e,r){if(!r)return e;if(!i)throw new Error("Schema not initialized");let n=i[t];if(!n)throw new Error(`Resource not found: ${t}`);for(let a of Object.keys(r)){if(!n.relations[a])throw new Error(`Relation ${a} not found in resource ${t}`);let o=n.relations[a],c=o.entity.name,s=r[a],y=o.type==="one"?"id":o.foreignColumn,p=o.type==="one"?o.relationalColumn:"id",l=o.type==="one"?jsonObjectFrom:jsonArrayFrom,d=typeof s=="object"&&s!==null;e=e.select(m=>{let u=m.selectFrom(c).selectAll(c).whereRef(`${c}.${y}`,"=",`${t}.${p}`).select(f=>jsonObjectFrom(f.selectFrom(`${c}_meta`).selectAll(`${c}_meta`).whereRef(`${c}_meta.id`,"=",`${c}.id`)).as("_meta"));return d&&(u=q(i,c,u,s)),l(u).as(a)});}return e}var G=class i extends ${db;schema;constructor(t,e){super(),this.isKyselyLike(t)?this.db=t:this.db=new Kysely({dialect:new PostgresDialect({pool:t})}),this.schema=e,this.rawInsert=this.rawInsert.bind(this),this.rawUpdate=this.rawUpdate.bind(this);}async updateSchema(t){this.schema=t;let e=await this.db.introspection.getTables();for(let[r,n]of Object.entries(t)){let a=e.find(s=>s.name===r);a||await this.db.schema.createTable(r).ifNotExists().execute();let o=`${r}_meta`,c=e.find(s=>s.name===o);c||await this.db.schema.createTable(o).ifNotExists().execute();for(let[s,y]of Object.entries(n.fields)){let p=a==null?void 0:a.columns.find(m=>m.name===s),l=y.getStorageFieldType();p?p.dataType!==l.type&&console.error("Column type mismatch:",s,"expected to have type:",l.type,"but has type:",p.dataType):(await this.db.schema.alterTable(r).addColumn(s,l.type,m=>{let u=m;return l.unique&&(u=u.unique()),l.nullable||(u=u.notNull()),l.references&&(u=u.references(l.references)),l.primary&&(u=u.primaryKey()),l.default!==void 0&&(u=u.defaultTo(l.default)),u}).execute().catch(m=>{throw console.error("Error adding column",s,m),m}),l.index&&await this.db.schema.createIndex(`${r}_${s}_index`).on(r).column(s).execute().catch(()=>{})),(c==null?void 0:c.columns.find(m=>m.name===s))||await this.db.schema.alterTable(o).addColumn(s,"varchar",m=>{let u=m;return l.primary&&(u=u.primaryKey().references(`${r}.${s}`)),u}).execute();}}}async rawFindById(t,e,r){if(!this.schema)throw new Error("Schema not initialized");let n=await this.db.selectFrom(t).where("id","=",e).selectAll(t).select(o=>jsonObjectFrom(o.selectFrom(`${t}_meta`).selectAll(`${t}_meta`).whereRef(`${t}_meta.id`,"=",`${t}.id`)).as("_meta"));n=q(this.schema,t,n,r);let a=await n.executeTakeFirst();if(a)return this.convertToMaterializedLiveType(a)}async findOne(t$1,e,r){let n=await this.rawFindById(t$1.name,e,r==null?void 0:r.include);if(n)return t(n)}async rawFind(t){if(!this.schema)throw new Error("Schema not initialized");let{resource:e,where:r,include:n,limit:a,sort:o}=t,c=this.db.selectFrom(e).selectAll(e).select(l=>jsonObjectFrom(l.selectFrom(`${e}_meta`).selectAll(`${e}_meta`).whereRef(`${e}_meta.id`,"=",`${e}.id`)).as("_meta"));c=Z(this.schema,e,c,r),c=q(this.schema,e,c,n),a!==void 0&&(c=c.limit(a)),o!==void 0&&o.forEach(l=>{c=c.orderBy(l.key,l.direction);});let s=await c.execute(),y=Object.fromEntries(s.map(l=>{let{id:d}=l;return [d,l]}));return Object.keys(y).length===0?{}:Object.entries(y).reduce((l,[d,m])=>(l[d]=this.convertToMaterializedLiveType(m),l),{})}async find(t$1,e){let r=await this.rawFind({resource:t$1.name,where:e==null?void 0:e.where,include:e==null?void 0:e.include,limit:e==null?void 0:e.limit,sort:e==null?void 0:e.sort});return Object.fromEntries(Object.entries(r).map(([n,a])=>[n,t(a)]))}async rawInsert(t,e,r){var o;let n={},a={};for(let[c,s]of Object.entries(r.value)){let y=(o=s._meta)==null?void 0:o.timestamp;y&&(n[c]=s.value,a[c]=y);}return await this.db.insertInto(t).values({...n,id:e}).execute().then(()=>{this.db.insertInto(`${t}_meta`).values({...a,id:e}).execute();}),r}async rawUpdate(t,e,r){var o;let n={},a={};for(let[c,s]of Object.entries(r.value)){let y=(o=s._meta)==null?void 0:o.timestamp;y&&(n[c]=s.value,a[c]=y);}return await Promise.all([this.db.updateTable(t).set(n).where("id","=",e).execute(),this.db.insertInto(`${t}_meta`).values({...a,id:e}).onConflict(c=>c.column("id").doUpdateSet(a)).execute()]),r}async transaction(t){if(!this.schema)throw new Error("Schema not initialized");if(this.db.isTransaction){let r=Math.random().toString(36).substring(2,15),n=await this.db.savepoint(r).execute();try{return await t({trx:this,commit:()=>n.releaseSavepoint(r).execute().then(()=>{}),rollback:()=>n.rollbackToSavepoint(r).execute().then(()=>{})}).then(a=>n.isCommitted||n.isRolledBack?a:n.releaseSavepoint(r).execute().then(()=>a))}catch(a){throw await n.rollbackToSavepoint(r).execute().catch(()=>{}),a}}let e=await this.db.startTransaction().execute();try{return await t({trx:new i(e,this.schema),commit:()=>e.commit().execute(),rollback:()=>e.rollback().execute()}).then(r=>e.isCommitted||e.isRolledBack?r:e.commit().execute().then(()=>r))}catch(r){throw await e.rollback().execute(),r}}convertToMaterializedLiveType(t){return {value:Object.entries(t).reduce((e,[r,n])=>{var a,o,c;return r==="_meta"||(r==="id"?e[r]={value:n}:Array.isArray(n)?e[r]={value:n.map(s=>this.convertToMaterializedLiveType(s)),_meta:{timestamp:(a=t==null?void 0:t._meta)==null?void 0:a[r]}}:typeof n=="object"&&n!==null&&!(n instanceof Date)?e[r]={...this.convertToMaterializedLiveType(n),_meta:{timestamp:(o=t==null?void 0:t._meta)==null?void 0:o[r]}}:e[r]={value:n,_meta:{timestamp:(c=t==null?void 0:t._meta)==null?void 0:c[r]}}),e},{})}}isKyselyLike(t){if(t instanceof Kysely)return true;if(!t||typeof t!="object")return false;let e=t,r=typeof e.selectFrom=="function",n=typeof e.startTransaction=="function",a=typeof e.savepoint=="function",o=typeof e.isTransaction=="boolean"||typeof e.isTransaction=="function";return r&&n||a&&o}};var H=class i{router;storage;schema;middlewares=new Set;contextProvider;mutationSubscriptions=new Set;constructor(t){var e;this.router=t.router,this.storage=t.storage,this.schema=t.schema,(e=t.middlewares)==null||e.forEach(r=>{this.middlewares.add(r);}),this.storage.updateSchema(this.schema),this.contextProvider=t.contextProvider;}static create(t){return new i(t)}subscribeToMutations(t){return this.mutationSubscriptions.add(t),()=>{this.mutationSubscriptions.delete(t);}}handleQuery(t){let e=new C(this.storage);return this.wrapInMiddlewares(async r=>{var y;let n=fe(r,this.schema,{stepId:"query",collectionName:r.resource,included:Object.keys(r.include??{})}),a={headers:r.headers,cookies:r.cookies,queryParams:r.queryParams,context:r.context},o={};for(let p=0;p<n.length;p++){let l=n[p],d=this.router.routes[l.resource];if(!d)throw new Error("Invalid resource");let m=l.getWhere&&l.referenceGetter?l.referenceGetter(o).map(l.getWhere):[void 0],u=(y=o[l.prevStepId??""])==null?void 0:y.flatMap(R=>{var M;return Object.keys(((M=R==null?void 0:R.result)==null?void 0:M.data)??{})}),T=(await Promise.allSettled(m.map(async(R,M)=>{let j=u==null?void 0:u[M],he=await d.handleQuery({req:{type:"QUERY",...l,...a,where:l.where,relationalWhere:R},batcher:e});return {includedBy:j,result:he}}))).flatMap(R=>R.status==="fulfilled"?[R.value]:[]);o[l.stepId]=T;}let c=Object.fromEntries(Object.entries(o).flatMap(([p,l],d)=>l.flatMap(m=>Object.entries(m.result.data).map(([u,f])=>[`${p}.${u}`,{data:f,includedBy:p!=="query"&&m.includedBy?`${p.split(".").slice(0,-1).join(".")}.${m.includedBy}`:void 0,path:p.split(".").slice(-1)[0],isMany:n[d].isMany,collectionName:n[d].collectionName,included:n[d].included}]))));return Object.keys(c).reduceRight((p,l)=>{var u,f;let d=c[l],m=d.path;if(m==="query"&&(p.data[l]=d.data),d.included.length)for(let T of d.included)d.data.value[T]??=((f=(u=this.schema[d.collectionName])==null?void 0:u.relations[T])==null?void 0:f.type)==="many"?{value:[]}:{value:null};if(d.includedBy){let T=c[d.includedBy];if(!T)return p;d.isMany?(T.data.value[m]??={value:[]},T.data.value[m].value.push(d.data)):T.data.value[m]=d.data;}return p},{data:{}})})(t.req)}async handleMutation(t){let e=await this.wrapInMiddlewares(async r=>{let n=this.router.routes[r.resource];if(!n)throw new Error("Invalid resource");return n.handleMutation({req:r,db:this.storage})})(t.req);if(e&&t.req.type==="MUTATE"&&e.acceptedValues&&(t.req.procedure==="INSERT"||t.req.procedure==="UPDATE")&&t.req.resourceId){let n=e.acceptedValues??{},a=t.req,o=a.resourceId;Object.keys(n).length&&o&&this.mutationSubscriptions.forEach(c=>{c({id:t.req.context.messageId,type:"MUTATE",resource:a.resource,payload:n,resourceId:o,procedure:a.procedure});});}return e}use(t){return this.middlewares.add(t),this}context(t){return this.contextProvider=t,this}wrapInMiddlewares(t){return e=>Array.from(this.middlewares.values()).reduceRight((r,n)=>a=>n({req:a,next:r}),t)(e)}},Jt=H.create;function fe(i,t,e){let{include:r,...n}=i,{stepId:a}=e,o=[{...n,...e}];if(r&&typeof r=="object"&&Object.keys(r).length>0){let c=t[n.resource];if(!c)throw new Error(`Resource ${n.resource} not found`);o.push(...Object.entries(r).flatMap(([s,y])=>{let p=c.relations[s];if(!p)throw new Error(`Relation ${s} not found for resource ${n.resource}`);let l=p.entity.name;return fe({...n,resource:l,include:y},t,{getWhere:p.type==="one"?d=>({id:d}):d=>({[p.foreignColumn]:d}),referenceGetter:d=>d[a].flatMap(m=>m.result.data?p.type==="one"?Object.values(m.result.data).map(u=>{var f,T;return (T=(f=u.value)==null?void 0:f[p.relationalColumn])==null?void 0:T.value}):Object.keys(m.result.data):[]),stepId:`${a}.${s}`,prevStepId:a,isMany:p.type==="many",collectionName:l,included:typeof y=="object"?Object.keys(y):[]})}));}return o}
|
|
1
|
+
import {a,b,t}from'./chunk-XNKBHWSC.js';import v from'node:crypto';import qe,{parse}from'qs';import {z as z$1}from'zod';import'js-xxhash';import {Kysely,PostgresDialect}from'kysely';import {jsonObjectFrom,jsonArrayFrom}from'kysely/helpers/postgres';var D=a(P=>{Object.defineProperty(P,"__esModule",{value:true});P.parse=ve;P.serialize=Le;var Ie=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,Ee=/^[\u0021-\u003A\u003C-\u007E]*$/,Ae=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,Oe=/^[\u0020-\u003A\u003D-\u007E]*$/,$e=Object.prototype.toString,je=(()=>{let i=function(){};return i.prototype=Object.create(null),i})();function ve(i,t){let e=new je,r=i.length;if(r<2)return e;let n=(t==null?void 0:t.decode)||Ce,a=0;do{let o=i.indexOf("=",a);if(o===-1)break;let c=i.indexOf(";",a),s=c===-1?r:c;if(o>s){a=i.lastIndexOf(";",o-1)+1;continue}let y=te(i,a,o),p=re(i,o,y),l=i.slice(y,p);if(e[l]===void 0){let d=te(i,o+1,s),m=re(i,s,d),u=n(i.slice(d,m));e[l]=u;}a=s+1;}while(a<r);return e}function te(i,t,e){do{let r=i.charCodeAt(t);if(r!==32&&r!==9)return t}while(++t<e);return e}function re(i,t,e){for(;t>e;){let r=i.charCodeAt(--t);if(r!==32&&r!==9)return t+1}return e}function Le(i,t,e){let r=(e==null?void 0:e.encode)||encodeURIComponent;if(!Ie.test(i))throw new TypeError(`argument name is invalid: ${i}`);let n=r(t);if(!Ee.test(n))throw new TypeError(`argument val is invalid: ${t}`);let a=i+"="+n;if(!e)return a;if(e.maxAge!==void 0){if(!Number.isInteger(e.maxAge))throw new TypeError(`option maxAge is invalid: ${e.maxAge}`);a+="; Max-Age="+e.maxAge;}if(e.domain){if(!Ae.test(e.domain))throw new TypeError(`option domain is invalid: ${e.domain}`);a+="; Domain="+e.domain;}if(e.path){if(!Oe.test(e.path))throw new TypeError(`option path is invalid: ${e.path}`);a+="; Path="+e.path;}if(e.expires){if(!Pe(e.expires)||!Number.isFinite(e.expires.valueOf()))throw new TypeError(`option expires is invalid: ${e.expires}`);a+="; Expires="+e.expires.toUTCString();}if(e.httpOnly&&(a+="; HttpOnly"),e.secure&&(a+="; Secure"),e.partitioned&&(a+="; Partitioned"),e.priority)switch(typeof e.priority=="string"?e.priority.toLowerCase():void 0){case "low":a+="; Priority=Low";break;case "medium":a+="; Priority=Medium";break;case "high":a+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${e.priority}`)}if(e.sameSite)switch(typeof e.sameSite=="string"?e.sameSite.toLowerCase():e.sameSite){case true:case "strict":a+="; SameSite=Strict";break;case "lax":a+="; SameSite=Lax";break;case "none":a+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${e.sameSite}`)}return a}function Ce(i){if(i.indexOf("%")===-1)return i;try{return decodeURIComponent(i)}catch{return i}}function Pe(i){return $e.call(i)==="[object Date]"}});var Y="0123456789ABCDEFGHJKMNPQRSTVWXYZ",E=32;var ge=16,X=10,J=0xffffffffffff;var w;(function(i){i.Base32IncorrectEncoding="B32_ENC_INVALID",i.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",i.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",i.EncodeTimeNegative="ENC_TIME_NEG",i.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",i.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",i.PRNGDetectFailure="PRNG_DETECT",i.ULIDInvalid="ULID_INVALID",i.Unexpected="UNEXPECTED",i.UUIDInvalid="UUID_INVALID";})(w||(w={}));var S=class extends Error{constructor(t,e){super(`${e} (${t})`),this.name="ULIDError",this.code=t;}};function Re(i){let t=Math.floor(i()*E);return t===E&&(t=E-1),Y.charAt(t)}function be(i){var r;let t=xe(),e=t&&(t.crypto||t.msCrypto)||(typeof v<"u"?v:null);if(typeof(e==null?void 0:e.getRandomValues)=="function")return ()=>{let n=new Uint8Array(1);return e.getRandomValues(n),n[0]/255};if(typeof(e==null?void 0:e.randomBytes)=="function")return ()=>e.randomBytes(1).readUInt8()/255;if((r=v)!=null&&r.randomBytes)return ()=>v.randomBytes(1).readUInt8()/255;throw new S(w.PRNGDetectFailure,"Failed to find a reliable PRNG")}function xe(){return Me()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function we(i,t){let e="";for(;i>0;i--)e=Re(t)+e;return e}function Se(i,t=X){if(isNaN(i))throw new S(w.EncodeTimeValueMalformed,`Time must be a number: ${i}`);if(i>J)throw new S(w.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${J}: ${i}`);if(i<0)throw new S(w.EncodeTimeNegative,`Time must be positive: ${i}`);if(Number.isInteger(i)===false)throw new S(w.EncodeTimeValueMalformed,`Time must be an integer: ${i}`);let e,r="";for(let n=t;n>0;n--)e=i%E,r=Y.charAt(e)+r,i=(i-e)/E;return r}function Me(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function ee(i,t){let e=be(),r=Date.now();return Se(r,X)+we(ge,e)}var W=()=>ee().toLowerCase();var L=(...i)=>{let t=i.filter(e=>!!e);return t.length===0?{}:t.length===1?t[0]:{$and:t}};var C=class{storage;queue=new Map;scheduled=false;constructor(t){this.storage=t;}async rawFind({resource:t,commonWhere:e,uniqueWhere:r,...n}){return new Promise((a,o)=>{let c=this.getBatchKey({resource:t,commonWhere:e,...n}),s={resource:t,commonWhere:e,uniqueWhere:r,...n,resolve:a,reject:o};this.queue.has(c)||this.queue.set(c,[]);let y=this.queue.get(c);y&&y.push(s),this.scheduled||(this.scheduled=true,setImmediate(()=>{this.processBatch();}));})}getBatchKey(t){let{resource:e,commonWhere:r,...n}=t;return `${e}:${JSON.stringify(r??{})}:${JSON.stringify(n??{})}`}async processBatch(){this.scheduled=false;let t=Array.from(this.queue.entries());this.queue.clear();for(let[,e]of t)try{await this.executeBatchedRequests(e);}catch(r){e.forEach(n=>{n.reject(r);});}}async executeBatchedRequests(t){var d,m;if(t.length===0)return;let e=t[0],{resource:r,commonWhere:n,include:a,sort:o}=e,c=t.length===1?e.limit:void 0,s=t.map(u=>u.uniqueWhere).filter(u=>u!==void 0),y=n,p=(d=Object.entries(s[0]??{})[0])==null?void 0:d[0];if(s.length>0){let u=s.map(f=>f[p]).filter(f=>f!=null);u.length>0&&(y=L(n,{[p]:{$in:u}}));}let l=await this.storage.rawFind({resource:r,where:y,include:a,sort:o,limit:c});for(let u of t){let f={};if(u.uniqueWhere){let[T,R]=Object.entries(u.uniqueWhere)[0];for(let[M,j]of Object.entries(l))((m=j.value[T])==null?void 0:m.value)===R&&(f[M]=j);}else Object.assign(f,l);u.resolve(f);}}};var ae=b(D(),1);var z=z$1.object({resource:z$1.string(),where:z$1.record(z$1.string(),z$1.any()).optional(),include:z$1.record(z$1.string(),z$1.any()).optional(),lastSyncedAt:z$1.string().optional(),limit:z$1.coerce.number().optional(),sort:z$1.array(z$1.object({key:z$1.string(),direction:z$1.enum(["asc","desc"])})).optional()}),k=z$1.record(z$1.string(),z$1.object({value:z$1.string().or(z$1.number()).or(z$1.boolean()).or(z$1.date()).nullable(),_meta:z$1.object({timestamp:z$1.string().optional().nullable()}).optional()})),ze=k.superRefine((i,t)=>{i.id&&t.addIssue({code:z$1.ZodIssueCode.custom,message:"Payload cannot have an id"});}),ne=z$1.object({id:z$1.string().optional(),type:z$1.literal("MUTATE"),resource:z$1.string(),resourceId:z$1.string().optional()}),A=ne.extend({procedure:z$1.string(),payload:z$1.any().optional()}),O=ne.extend({procedure:z$1.enum(["INSERT","UPDATE"]),payload:ze});z$1.union([O,A]);var ie=z.omit({resource:true}),B=A.omit({id:true,type:true,resource:true,procedure:true}),_=O.omit({id:true,type:true,resource:true,procedure:true});z$1.union([_,B]);var oe=i=>async t=>{var e;try{let r=typeof t.headers.getSetCookie=="function"?Object.fromEntries(t.headers):t.headers,n={headers:r,cookies:r.cookie?ae.default.parse(r.cookie):{}},a=new URL(t.url),o=a.pathname.split("/"),c=a.searchParams,s=qe.parse(c.toString()),y=await((e=i.contextProvider)==null?void 0:e.call(i,{transport:"HTTP",headers:n.headers,cookies:n.cookies,queryParams:s}))??{};if(t.method==="GET"){let p=o[o.length-1],{success:l,data:d,error:m}=ie.safeParse(s);if(!l)return Response.json({message:"Invalid query",code:"INVALID_QUERY",details:m},{status:400});let u=await i.handleQuery({req:{...n,...d,type:"QUERY",resource:p,context:y,queryParams:s}});return !u||!u.data?Response.json({message:"Invalid resource",code:"INVALID_RESOURCE"},{status:400}):Response.json(u.data)}if(t.method==="POST")try{let p=o[o.length-1],l=o[o.length-2],d=t.body?await t.json():{},m;if(p==="insert"||p==="update"){let{success:f,data:T,error:R}=_.safeParse(d);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:R},{status:400});m=T;}else {let{success:f,data:T,error:R}=B.safeParse(d);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:R},{status:400});m=T;}let u=await i.handleMutation({req:{...n,type:"MUTATE",resource:l,input:m.payload,context:y,resourceId:m.resourceId,procedure:p==="insert"||p==="update"?p.toUpperCase():p,queryParams:{}}});return Response.json(u)}catch(p){return console.error("Error parsing mutation from the client:",p),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}return Response.json({message:"Not found",code:"NOT_FOUND"},{status:404})}catch(r){return console.error("Unexpected error:",r),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}};var ue=b(D(),1);var I=z$1.string(),Ue=z$1.object({id:I,type:z$1.literal("SUBSCRIBE"),resource:z$1.string()}),We=z.extend({id:I,type:z$1.literal("QUERY")}),se=O.extend({id:I}),De=A.extend({id:I}),ke=z$1.union([De,se]),ce=z$1.union([Ue,We,ke]),Be=z$1.object({id:I,type:z$1.literal("REJECT"),resource:z$1.string(),message:z$1.string().optional()}),_e=z$1.object({id:I,type:z$1.literal("REPLY"),data:z$1.any()});z$1.union([Be,_e,se]);z$1.object({resource:z$1.string(),data:z$1.record(z$1.string(),k)});var de=i=>{let t={},e={};return i.subscribeToMutations(r=>{let n=r;!n.resourceId||!n.payload||(console.log("Mutation propagated:",n),Object.entries(e[n.resource]??{}).forEach(([a,o])=>{var c;(c=t[a])==null||c.send(JSON.stringify({...n,id:n.id??W()}));}));}),(r,n)=>{var p;let a=l=>{r.send(JSON.stringify(l));},o=W(),c={headers:n.headers,cookies:typeof n.headers.cookie=="string"?ue.default.parse(n.headers.cookie):{}},s=parse(n.url.split("?")[1]),y=(p=i.contextProvider)==null?void 0:p.call(i,{transport:"WEBSOCKET",headers:c.headers,cookies:c.cookies,queryParams:s});t[o]=r,console.log("Client connected:",o),r.on("message",async l=>{try{console.log("Message received from the client:",l);let d=ce.parse(JSON.parse(l.toString()));if(d.type==="SUBSCRIBE"){let{resource:m}=d;e[m]||(e[m]={}),e[m][o]={};}else if(d.type==="QUERY"){let{resource:m}=d,u=await i.handleQuery({req:{...c,type:"QUERY",resource:m,context:await y??{},queryParams:s}});if(!u||!u.data)throw new Error("Invalid resource");a({id:d.id,type:"REPLY",data:{resource:m,data:Object.fromEntries(Object.entries(u.data??{}).map(([f,T])=>[f,T.value]))}});}else if(d.type==="MUTATE"){let{resource:m}=d;console.log("Received mutation from client:",d);try{let u=await i.handleMutation({req:{...c,type:"MUTATE",resource:m,input:d.payload,context:{messageId:d.id,...await y??{}},resourceId:d.resourceId,procedure:d.procedure,queryParams:s}});d.procedure&&d.procedure!=="INSERT"&&d.procedure!=="UPDATE"&&a({id:d.id,type:"REPLY",data:u});}catch(u){a({id:d.id,type:"REJECT",resource:m,message:u.message}),console.error("Error parsing mutation from the client:",u);}}}catch(d){console.error("Error handling message from the client:",d);}}),r.on("close",()=>{console.log("Connection closed",o),delete t[o];for(let l of Object.values(e))delete l[o];});}};function le(i){let t=`${i.protocol}://${i.hostname}${i.url}`,e=new Headers;return Object.entries(i.headers).forEach(([r,n])=>{n&&e.set(r,Array.isArray(n)?n.join(","):n);}),new Request(t,{method:i.method,headers:e,body:i.body&&i.method!=="GET"?JSON.stringify(i.body):void 0})}var It=(i,t,e)=>{i.ws(`${(e==null?void 0:e.basePath)??""}/ws`,de(t)),i.use(`${(e==null?void 0:e.basePath)??""}/`,(r,n)=>{oe(t)(le(r)).then(o=>o.json().then(c=>n.status(o.status).send(c)));});};var x=(i,t,e=false)=>Object.entries(t).every(([r,n])=>{if(r==="$and")return n.every(o=>x(i,o,e));if(r==="$or")return n.some(o=>x(i,o,e));let a=(n==null?void 0:n.$eq)!==void 0?n==null?void 0:n.$eq:n;if(typeof n=="object"&&n!==null&&(n==null?void 0:n.$eq)===void 0){if(n.$in!==void 0){let o=i[r];return o===void 0?false:e?!n.$in.includes(o):n.$in.includes(o)}if(n.$not!==void 0&&!e)return x(i,{[r]:n.$not},true);if(n.$gt!==void 0){let o=i[r];return typeof o!="number"?false:e?o<=n.$gt:o>n.$gt}if(n.$gte!==void 0){let o=i[r];return typeof o!="number"?false:e?o<n.$gte:o>=n.$gte}if(n.$lt!==void 0){let o=i[r];return typeof o!="number"?false:e?o>=n.$lt:o<n.$lt}if(n.$lte!==void 0){let o=i[r];return typeof o!="number"?false:e?o>n.$lte:o<=n.$lte}return !i[r]||typeof i[r]!="object"?false:x(i[r],n,e)}return e?i[r]!==a:i[r]===a});var V=class i{routes;constructor(t){this.routes=t.routes;}static create(t){return new i(t)}},Pt=i=>V.create({...i}),Fe=i=>({handler:t=>({inputValidator:i??z$1.undefined(),handler:t})}),Q=class i{resourceSchema;middlewares;customMutations;authorization;constructor(t,e,r){this.resourceSchema=t,this.middlewares=new Set,this.customMutations=e??{},this.authorization=r;}use(...t){for(let e of t)this.middlewares.add(e);return this}withMutations(t){return new i(this.resourceSchema,t({mutation:Fe}),this.authorization)}handleQuery=async({req:t,batcher:e})=>await this.wrapInMiddlewares(async r=>{var a,o;let n=(o=(a=this.authorization)==null?void 0:a.read)==null?void 0:o.call(a,{ctx:r.context});if(typeof n=="boolean"&&!n)throw new Error("Not authorized");return {data:await e.rawFind({resource:r.resource,commonWhere:L(r.where,typeof n=="object"?n:void 0),uniqueWhere:r.relationalWhere,include:r.include,limit:r.limit,sort:r.sort})}})(t);handleMutation=async({req:t,db:e})=>await this.wrapInMiddlewares(async r=>{if(!r.procedure)throw new Error("Procedure is required for mutations");let n=this.customMutations[r.procedure];if(n){let a=n.inputValidator.parse(r.input);return r.input=a,n.handler({req:r,db:e})}else {if(r.procedure==="INSERT"||r.procedure==="UPDATE")return this.handleSet({req:r,db:e,operation:r.procedure});throw new Error(`Unknown procedure: ${r.procedure}`)}})(t);handleSet=async({req:t$1,db:e,operation:r})=>{if(!t$1.input)throw new Error("Payload is required");if(!t$1.resourceId)throw new Error("ResourceId is required");let n=await e.rawFindById(t$1.resource,t$1.resourceId);if(r==="INSERT"&&n)throw new Error("Resource already exists");if(r==="UPDATE"&&!n)throw new Error("Resource not found");return e.transaction(async({trx:a})=>{var y,p,l,d,m;let[o,c]=this.resourceSchema.mergeMutation("set",t$1.input,n);if(!c)throw new Error("Mutation rejected");if(r==="INSERT"){let u=await a.rawInsert(t$1.resource,t$1.resourceId,o);if((y=this.authorization)!=null&&y.insert){let f=t(u);f.id=f.id??t$1.resourceId;let T=this.authorization.insert({ctx:t$1.context,value:f});if(!(typeof T=="boolean"?T:x(f,T)))throw new Error("Not authorized")}return {data:u,acceptedValues:c}}if((l=(p=this.authorization)==null?void 0:p.update)!=null&&l.preMutation){let u=t(n);u.id=u.id??t$1.resourceId;let f=this.authorization.update.preMutation({ctx:t$1.context,value:u});if(!(typeof f=="boolean"?f:x(u,f)))throw new Error("Not authorized")}let s=await a.rawUpdate(t$1.resource,t$1.resourceId,o);if((m=(d=this.authorization)==null?void 0:d.update)!=null&&m.postMutation){let u=t(s);u.id=u.id??t$1.resourceId;let f=this.authorization.update.postMutation({ctx:t$1.context,value:u});if(!(typeof f=="boolean"?f:x(u,f)))throw new Error("Not authorized")}return {data:s,acceptedValues:c}})};wrapInMiddlewares(t){return e=>Array.from(this.middlewares.values()).reduceRight((r,n)=>a=>n({req:a,next:r}),t)(e)}},F=class i{middlewares;constructor(t=[]){this.middlewares=t;}collectionRoute(t,e){return new Q(t,void 0,e).use(...this.middlewares)}use(...t){return new i([...this.middlewares,...t])}static create(){return new i}},zt=F.create;var $=class{async insert(t$1,e){let r=new Date().toISOString();return t(await this.rawInsert(t$1.name,e.id,{value:Object.fromEntries(Object.entries(e).map(([n,a])=>[n,{value:a,_meta:{timestamp:r}}]))}))}async update(t$1,e,r){let n=new Date().toISOString(),{id:a,...o}=r;return t(await this.rawUpdate(t$1.name,e,{value:Object.fromEntries(Object.entries(o).map(([c,s])=>[c,{value:s,_meta:{timestamp:n}}]))}))}};function N(i,t,e,r){if(!i)throw new Error("Schema not initialized");let n=i[t];if(!n)throw new Error("Resource not found");let a=r.$or,o=r.$and;return (a?e.or:e.and)(a?r.$or.map(c=>N(i,t,e,c)):o?r.$and.map(c=>N(i,t,e,c)):Object.entries(r).map(([c,s])=>{var y,p;if(n.fields[c])return (s==null?void 0:s.$eq)!==void 0?e(`${t}.${c}`,s.$eq===null?"is":"=",s.$eq):(s==null?void 0:s.$in)!==void 0?e(`${t}.${c}`,"in",s.$in):(s==null?void 0:s.$not)!==void 0?((y=s==null?void 0:s.$not)==null?void 0:y.$in)!==void 0?e(`${t}.${c}`,"not in",s.$not.$in):((p=s==null?void 0:s.$not)==null?void 0:p.$eq)!==void 0?e(`${t}.${c}`,s.$not.$eq===null?"is not":"!=",s.$not.$eq):e(`${t}.${c}`,s.$not===null?"is not":"!=",s.$not):(s==null?void 0:s.$gt)!==void 0?e(`${t}.${c}`,">",s.$gt):(s==null?void 0:s.$gte)!==void 0?e(`${t}.${c}`,">=",s.$gte):(s==null?void 0:s.$lt)!==void 0?e(`${t}.${c}`,"<",s.$lt):(s==null?void 0:s.$lte)!==void 0?e(`${t}.${c}`,"<=",s.$lte):e(`${t}.${c}`,s===null?"is":"=",s);if(n.relations[c]){let l=n.relations[c],d=l.entity.name;return l.type==="many"?e.exists(Z(i,d,e.selectFrom(d).select("id").whereRef(l.foreignColumn,"=",`${t}.id`),s)):N(i,d,e,s)}return null}).filter(Boolean))}function q(i,t,e,r){let n=i[t];if(!n)throw new Error("Resource not found");if(!r)return e;if(r.$and){for(let a of r.$and)e=q(i,t,e,a);return e}else if(r.$or){for(let a of r.$or)e=q(i,t,e,a);return e}for(let[a,o]of Object.entries(r)){if(!n.relations[a])continue;let c=n.relations[a],s=c.entity.name,y=c.type==="one"?"id":c.foreignColumn,p=c.type==="one"?c.relationalColumn:"id";e=e.leftJoin(s,`${s}.${y}`,`${t}.${p}`),o instanceof Object&&!Array.isArray(o)&&o!==null&&(e=q(i,s,e,o));}return e}function Z(i,t,e,r){return !r||Object.keys(r).length===0?e:(e=q(i,t,e,r),e.where(n=>N(i,t,n,r)))}function U(i,t,e,r){if(!r)return e;if(!i)throw new Error("Schema not initialized");let n=i[t];if(!n)throw new Error(`Resource not found: ${t}`);for(let a of Object.keys(r)){if(!n.relations[a])throw new Error(`Relation ${a} not found in resource ${t}`);let o=n.relations[a],c=o.entity.name,s=r[a],y=o.type==="one"?"id":o.foreignColumn,p=o.type==="one"?o.relationalColumn:"id",l=o.type==="one"?jsonObjectFrom:jsonArrayFrom,d=typeof s=="object"&&s!==null;e=e.select(m=>{let u=m.selectFrom(c).selectAll(c).whereRef(`${c}.${y}`,"=",`${t}.${p}`).select(f=>jsonObjectFrom(f.selectFrom(`${c}_meta`).selectAll(`${c}_meta`).whereRef(`${c}_meta.id`,"=",`${c}.id`)).as("_meta"));return d&&(u=U(i,c,u,s)),l(u).as(a)});}return e}var G=class i extends ${db;schema;constructor(t,e){super(),this.isKyselyLike(t)?this.db=t:this.db=new Kysely({dialect:new PostgresDialect({pool:t})}),this.schema=e,this.rawInsert=this.rawInsert.bind(this),this.rawUpdate=this.rawUpdate.bind(this);}async updateSchema(t){this.schema=t;let e=await this.db.introspection.getTables();for(let[r,n]of Object.entries(t)){let a=e.find(s=>s.name===r);a||await this.db.schema.createTable(r).ifNotExists().execute();let o=`${r}_meta`,c=e.find(s=>s.name===o);c||await this.db.schema.createTable(o).ifNotExists().execute();for(let[s,y]of Object.entries(n.fields)){let p=a==null?void 0:a.columns.find(m=>m.name===s),l=y.getStorageFieldType();p?p.dataType!==l.type&&console.error("Column type mismatch:",s,"expected to have type:",l.type,"but has type:",p.dataType):(await this.db.schema.alterTable(r).addColumn(s,l.type,m=>{let u=m;return l.unique&&(u=u.unique()),l.nullable||(u=u.notNull()),l.references&&(u=u.references(l.references)),l.primary&&(u=u.primaryKey()),l.default!==void 0&&(u=u.defaultTo(l.default)),u}).execute().catch(m=>{throw console.error("Error adding column",s,m),m}),l.index&&await this.db.schema.createIndex(`${r}_${s}_index`).on(r).column(s).execute().catch(()=>{})),(c==null?void 0:c.columns.find(m=>m.name===s))||await this.db.schema.alterTable(o).addColumn(s,"varchar",m=>{let u=m;return l.primary&&(u=u.primaryKey().references(`${r}.${s}`)),u}).execute();}}}async rawFindById(t,e,r){if(!this.schema)throw new Error("Schema not initialized");let n=await this.db.selectFrom(t).where("id","=",e).selectAll(t).select(o=>jsonObjectFrom(o.selectFrom(`${t}_meta`).selectAll(`${t}_meta`).whereRef(`${t}_meta.id`,"=",`${t}.id`)).as("_meta"));n=U(this.schema,t,n,r);let a=await n.executeTakeFirst();if(a)return this.convertToMaterializedLiveType(a)}async findOne(t$1,e,r){let n=await this.rawFindById(t$1.name,e,r==null?void 0:r.include);if(n)return t(n)}async rawFind(t){if(!this.schema)throw new Error("Schema not initialized");let{resource:e,where:r,include:n,limit:a,sort:o}=t,c=this.db.selectFrom(e).selectAll(e).select(l=>jsonObjectFrom(l.selectFrom(`${e}_meta`).selectAll(`${e}_meta`).whereRef(`${e}_meta.id`,"=",`${e}.id`)).as("_meta"));c=Z(this.schema,e,c,r),c=U(this.schema,e,c,n),a!==void 0&&(c=c.limit(a)),o!==void 0&&o.forEach(l=>{c=c.orderBy(l.key,l.direction);});let s=await c.execute(),y=Object.fromEntries(s.map(l=>{let{id:d}=l;return [d,l]}));return Object.keys(y).length===0?{}:Object.entries(y).reduce((l,[d,m])=>(l[d]=this.convertToMaterializedLiveType(m),l),{})}async find(t$1,e){let r=await this.rawFind({resource:t$1.name,where:e==null?void 0:e.where,include:e==null?void 0:e.include,limit:e==null?void 0:e.limit,sort:e==null?void 0:e.sort});return Object.fromEntries(Object.entries(r).map(([n,a])=>[n,t(a)]))}async rawInsert(t,e,r){var o;let n={},a={};for(let[c,s]of Object.entries(r.value)){let y=(o=s._meta)==null?void 0:o.timestamp;y&&(n[c]=s.value,a[c]=y);}return await this.db.insertInto(t).values({...n,id:e}).execute().then(()=>{this.db.insertInto(`${t}_meta`).values({...a,id:e}).execute();}),r}async rawUpdate(t,e,r){var o;let n={},a={};for(let[c,s]of Object.entries(r.value)){let y=(o=s._meta)==null?void 0:o.timestamp;y&&(n[c]=s.value,a[c]=y);}return await Promise.all([this.db.updateTable(t).set(n).where("id","=",e).execute(),this.db.insertInto(`${t}_meta`).values({...a,id:e}).onConflict(c=>c.column("id").doUpdateSet(a)).execute()]),r}async transaction(t){if(!this.schema)throw new Error("Schema not initialized");if(this.db.isTransaction){let r=Math.random().toString(36).substring(2,15),n=await this.db.savepoint(r).execute();try{return await t({trx:this,commit:()=>n.releaseSavepoint(r).execute().then(()=>{}),rollback:()=>n.rollbackToSavepoint(r).execute().then(()=>{})}).then(a=>n.isCommitted||n.isRolledBack?a:n.releaseSavepoint(r).execute().then(()=>a))}catch(a){throw await n.rollbackToSavepoint(r).execute().catch(()=>{}),a}}let e=await this.db.startTransaction().execute();try{return await t({trx:new i(e,this.schema),commit:()=>e.commit().execute(),rollback:()=>e.rollback().execute()}).then(r=>e.isCommitted||e.isRolledBack?r:e.commit().execute().then(()=>r))}catch(r){throw await e.rollback().execute(),r}}convertToMaterializedLiveType(t){return {value:Object.entries(t).reduce((e,[r,n])=>{var a,o,c;return r==="_meta"||(r==="id"?e[r]={value:n}:Array.isArray(n)?e[r]={value:n.map(s=>this.convertToMaterializedLiveType(s)),_meta:{timestamp:(a=t==null?void 0:t._meta)==null?void 0:a[r]}}:typeof n=="object"&&n!==null&&!(n instanceof Date)?e[r]={...this.convertToMaterializedLiveType(n),_meta:{timestamp:(o=t==null?void 0:t._meta)==null?void 0:o[r]}}:e[r]={value:n,_meta:{timestamp:(c=t==null?void 0:t._meta)==null?void 0:c[r]}}),e},{})}}isKyselyLike(t){if(t instanceof Kysely)return true;if(!t||typeof t!="object")return false;let e=t,r=typeof e.selectFrom=="function",n=typeof e.startTransaction=="function",a=typeof e.savepoint=="function",o=typeof e.isTransaction=="boolean"||typeof e.isTransaction=="function";return r&&n||a&&o}};var H=class i{router;storage;schema;middlewares=new Set;contextProvider;mutationSubscriptions=new Set;constructor(t){var e;this.router=t.router,this.storage=t.storage,this.schema=t.schema,(e=t.middlewares)==null||e.forEach(r=>{this.middlewares.add(r);}),this.storage.updateSchema(this.schema),this.contextProvider=t.contextProvider;}static create(t){return new i(t)}subscribeToMutations(t){return this.mutationSubscriptions.add(t),()=>{this.mutationSubscriptions.delete(t);}}handleQuery(t){let e=new C(this.storage);return this.wrapInMiddlewares(async r=>{var y;let n=fe(r,this.schema,{stepId:"query",collectionName:r.resource,included:Object.keys(r.include??{})}),a={headers:r.headers,cookies:r.cookies,queryParams:r.queryParams,context:r.context},o={};for(let p=0;p<n.length;p++){let l=n[p],d=this.router.routes[l.resource];if(!d)throw new Error("Invalid resource");let m=l.getWhere&&l.referenceGetter?l.referenceGetter(o).map(l.getWhere):[void 0],u=(y=o[l.prevStepId??""])==null?void 0:y.flatMap(R=>{var M;return Object.keys(((M=R==null?void 0:R.result)==null?void 0:M.data)??{})}),T=(await Promise.allSettled(m.map(async(R,M)=>{let j=u==null?void 0:u[M],he=await d.handleQuery({req:{type:"QUERY",...l,...a,where:l.where,relationalWhere:R},batcher:e});return {includedBy:j,result:he}}))).flatMap(R=>R.status==="fulfilled"?[R.value]:[]);o[l.stepId]=T;}let c=Object.fromEntries(Object.entries(o).flatMap(([p,l],d)=>l.flatMap(m=>Object.entries(m.result.data).map(([u,f])=>[`${p}.${u}`,{data:f,includedBy:p!=="query"&&m.includedBy?`${p.split(".").slice(0,-1).join(".")}.${m.includedBy}`:void 0,path:p.split(".").slice(-1)[0],isMany:n[d].isMany,collectionName:n[d].collectionName,included:n[d].included}]))));return Object.keys(c).reduceRight((p,l)=>{var u,f;let d=c[l],m=d.path;if(m==="query"&&(p.data[l.replace("query.","")]=d.data),d.included.length)for(let T of d.included)d.data.value[T]??=((f=(u=this.schema[d.collectionName])==null?void 0:u.relations[T])==null?void 0:f.type)==="many"?{value:[]}:{value:null};if(d.includedBy){let T=c[d.includedBy];if(!T)return p;d.isMany?(T.data.value[m]??={value:[]},T.data.value[m].value.push(d.data)):T.data.value[m]=d.data;}return p},{data:{}})})(t.req)}async handleMutation(t){let e=await this.wrapInMiddlewares(async r=>{let n=this.router.routes[r.resource];if(!n)throw new Error("Invalid resource");return n.handleMutation({req:r,db:this.storage})})(t.req);if(e&&t.req.type==="MUTATE"&&e.acceptedValues&&(t.req.procedure==="INSERT"||t.req.procedure==="UPDATE")&&t.req.resourceId){let n=e.acceptedValues??{},a=t.req,o=a.resourceId;Object.keys(n).length&&o&&this.mutationSubscriptions.forEach(c=>{c({id:t.req.context.messageId,type:"MUTATE",resource:a.resource,payload:n,resourceId:o,procedure:a.procedure});});}return e}use(t){return this.middlewares.add(t),this}context(t){return this.contextProvider=t,this}wrapInMiddlewares(t){return e=>Array.from(this.middlewares.values()).reduceRight((r,n)=>a=>n({req:a,next:r}),t)(e)}},Jt=H.create;function fe(i,t,e){let{include:r,...n}=i,{stepId:a}=e,o=[{...n,...e}];if(r&&typeof r=="object"&&Object.keys(r).length>0){let c=t[n.resource];if(!c)throw new Error(`Resource ${n.resource} not found`);o.push(...Object.entries(r).flatMap(([s,y])=>{let p=c.relations[s];if(!p)throw new Error(`Relation ${s} not found for resource ${n.resource}`);let l=p.entity.name;return fe({...n,resource:l,include:y},t,{getWhere:p.type==="one"?d=>({id:d}):d=>({[p.foreignColumn]:d}),referenceGetter:d=>d[a].flatMap(m=>m.result.data?p.type==="one"?Object.values(m.result.data).map(u=>{var f,T;return (T=(f=u.value)==null?void 0:f[p.relationalColumn])==null?void 0:T.value}):Object.keys(m.result.data):[]),stepId:`${a}.${s}`,prevStepId:a,isMany:p.type==="many",collectionName:l,included:typeof y=="object"?Object.keys(y):[]})}));}return o}
|
|
2
2
|
export{Q as Route,F as RouteFactory,V as Router,G as SQLStorage,H as Server,$ as Storage,It as expressAdapter,zt as routeFactory,Pt as router,Jt as server};
|