palgres 0.7.0 → 0.8.1
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/chunks/{RCTMMWP5.js → 2LZ4FCGH.js} +2 -2
- package/dist/chunks/ERGV4DGD.js +5 -0
- package/dist/chunks/LOZM3WFO.js +2 -0
- package/dist/dsl.js +2 -2
- package/dist/index.js +141 -124
- package/dist/testing.js +2 -2
- package/package.json +1 -1
- package/types/palgres/src/dsl/columns.d.ts +13 -0
- package/types/palgres/src/dsl/foreign-key.d.ts +11 -1
- package/types/palgres/src/migrate.d.ts +7 -0
- package/types/palgres/src/model.d.ts +22 -0
- package/types/palgres/src/plan.d.ts +15 -0
- package/types/palgres/src/query/catalog.d.ts +19 -0
- package/types/palgres/src/query/env-gen.d.ts +9 -0
- package/types/palgres/src/query/index.d.ts +1 -1
- package/types/palgres/src/query/typed.d.ts +6 -2
- package/dist/chunks/4WIUQCVC.js +0 -5
- package/dist/chunks/YYA7H4M5.js +0 -2
package/dist/testing.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palgres 0.
|
|
2
|
-
import{$ as wn,D as U,E as fn,F as Y,J as Z,K as V,L as z,M as dn,O as P,W as _,aa as $n,e as cn,g as ln}from"./chunks/RCTMMWP5.js";import"./chunks/4WIUQCVC.js";import{randomUUID as Rn}from"node:crypto";var On=/^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?)?(Z|[+-]\d{2}(:?\d{2})?)?$/,bn=/^([+-]?)(\d*)(?:\.(\d*))?$/;function q(e){if(e instanceof Date)return e.getTime();if(typeof e=="string"&&On.test(e)){let t=Date.parse(e);return Number.isNaN(t)?null:t}return null}function B(e){if(typeof e=="number")return Number.isFinite(e)?B(String(e)):null;if(typeof e!="string"||/e/i.test(e))return null;let t=bn.exec(e.trim());if(t===null||t[2]===""&&(t[3]??"")==="")return null;let a=t[3]??"";return{unit:BigInt(`${t[1]==="-"?"-":""}${t[2]===""?"0":t[2]}${a}`),scale:a.length}}function K(e,t){return e.unit*10n**BigInt(t-e.scale)}function tn(e,t){if(e==null||t===null||t===void 0)return null;let a=q(e),c=q(t);if(a!==null&&c!==null)return Math.sign(a-c);let w=B(e),f=B(t);if(w!==null&&f!==null){let d=Math.max(w.scale,f.scale),h=K(w,d)-K(f,d);return h===0n?0:h<0n?-1:1}return typeof e==typeof t&&(typeof e=="string"||typeof e=="boolean"||typeof e=="number")?e<t?-1:e>t?1:0:null}function N(e,t){return e==null||t===null||t===void 0?!1:e instanceof Date||t instanceof Date?q(e)!==null&&q(e)===q(t):Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((a,c)=>N(a,t[c])):e===t}function H(e){let t=((e?.days??0)*86400+(e?.hours??0)*3600+(e?.minutes??0)*60+(e?.seconds??0))*1e3;return new Date(Date.now()-t).toISOString()}function v(e,t,a){if(e==null)return null;if(typeof e=="number"&&typeof t=="number")return e+a*t;let c=B(e),w=B(t);if(c===null||w===null)throw new Error(`increment()/decrement() on a value that is not a number (${JSON.stringify(e)}): Postgres refuses it ("operator does not exist")`);let f=Math.max(c.scale,w.scale),d=K(c,f)+BigInt(a)*K(w,f);if(f===0)return typeof e=="number"?Number(d):d.toString();let h=d<0n,R=(h?-d:d).toString().padStart(f+1,"0"),k=`${h?"-":""}${R.slice(0,-f)}.${R.slice(-f)}`;return typeof e=="number"?Number(k):k}function kn(e,t){let a=A=>{let C=(A.unit<0n?-A.unit:A.unit).toString().padStart(A.scale+1,"0"),J=C.slice(0,C.length-A.scale),n=C.slice(C.length-A.scale),r=J.padStart(Math.ceil(J.length/4)*4,"0").match(/.{4}/g)??[],s=n.padEnd(Math.ceil(n.length/4)*4,"0").match(/.{4}/g)??[],i=[...r.map((u,l)=>[r.length-1-l,Number(u)]),...s.map((u,l)=>[-1-l,Number(u)])].find(([,u])=>u!==0);return i?[i[0],i[1]]:[0,0]},[c,w]=a(e),[f,d]=a(t),h=c-f-(w<=d?1:0),R=Math.min(Math.max(16-h*4,e.scale,t.scale,0),1e3),k=e.unit*10n**BigInt(R+t.scale),E=t.unit*10n**BigInt(e.scale),T=k/E,x=k%E;2n*(x<0n?-x:x)>=(E<0n?-E:E)&&(T+=k<0n!=E<0n?-1n:1n);let I=T<0n,W=(I?-T:T).toString().padStart(R+1,"0");return`${I?"-":""}${R===0?W:`${W.slice(0,-R)}.${W.slice(-R)}`}`}var $=e=>structuredClone(e);function rn(e,t,a){if(fn(a))throw new Error(`${e}(${t}): the fake database runs no SQL, so a sqlFragment cannot be evaluated \u2014 write the filter in the filter language (gt, gte, lt, lte, neq, in, contains, isNull, OR, AND, NOT), or test this against Postgres`);if(!(a===null||typeof a!="object"))for(let[c,w]of Object.entries(a))if(c==="OR"||c==="AND")for(let f of Array.isArray(w)?w:[])rn(e,t,f);else c==="NOT"&&rn(e,t,w)}function D(e,t,a){return cn(new ln({fields:[{field:t,message:a}]},`${e}: ${t} ${a}`))}function on(e,t,a="where"){for(let[c,w]of Object.entries(t))if(c==="OR"||c==="AND"){let f=w;if(c==="AND"&&f.length===0)throw D(e,`${a}.AND`,"is an empty list \u2014 no condition at all. Leave it out, or name a condition in it.");f.forEach((d,h)=>{if(Object.keys(d).length===0)throw D(e,`${a}.${c}[${h}]`,"holds no condition \u2014 a branch that matches every row. Name a condition in it, or leave it out.");on(e,d,`${a}.${c}[${h}]`)})}else if(c==="NOT"){if(Array.isArray(w))throw D(e,`${a}.NOT`,"is a list \u2014 NOT takes one filter object. For several conditions, NOT: { AND: [...] } or NOT: { OR: [...] }.");if(Object.keys(w).length===0)throw D(e,`${a}.NOT`,"holds no condition \u2014 NOT of nothing is not a filter. Name the condition to exclude.");on(e,w,`${a}.NOT`)}else if(c==="has"&&Object.keys(w??{}).length===0)throw D(e,`${a}.has`,"names no relation \u2014 no condition. Name one: has: { <relation>: { \u2026 } }.")}function F(e,t){if(Object.keys(t).length===0)throw D(e,"where",`holds no condition, so ${e} would reach EVERY row of the table. Name a condition.`)}function sn(e){let t=!1;for(let a of e){if(a===!1)return!1;a===null&&(t=!0)}return t?null:!0}function mn(e){let t=!1;for(let a of e){if(a===!0)return!0;a===null&&(t=!0)}return t?null:!1}var j=e=>e==null;function L(e,t,a,c){return sn(Object.entries(c).map(([w,f])=>{if(w==="OR")return mn(f.map(d=>L(e,t,a,d)));if(w==="AND")return sn(f.map(d=>L(e,t,a,d)));if(w==="NOT"){let d=L(e,t,a,f);return d===null?null:!d}if(w==="has")throw new Error(`${e}(${t}): the fake database has no relations, so a \`has\` filter cannot be decided for a row \u2014 read the related table first and filter by its ids ({ id: { in: [\u2026] } }), or test this against Postgres`);return xn(e,t,a,w,f)}))}var gn=["neq","gt","gte","lt","lte"];function Q(e,t){return j(e)||j(t)?null:N(e,t)}function xn(e,t,a,c,w){let f=a[c];return w===null?j(f):U(w)?Q(f,a[w.$col]):V(w)?Q(f,H(_(w)?.minus)):typeof w=="object"&&!Array.isArray(w)&&!(w instanceof Date)?sn(Object.entries(w).map(([d,h])=>{if(V(h)){if(!gn.includes(d))throw new Error(`${e}(${t}): where.${c}.${d} cannot take now()`);return G(d,f,H(_(h)?.minus))}if(Z(h))throw new Error(`${e}(${t}): where.${c}.${d} was given increment()/decrement() \u2014 a write, not a value to compare with`);if(U(h)){if(!gn.includes(d))throw new Error(`${e}(${t}): where.${c}.${d} cannot take col()`);return G(d,f,a[h.$col])}switch(d){case"in":{if(!Array.isArray(h))throw new Error(`${e}(${t}): where.${c}.in is a list`);return mn(h.map(R=>Q(f,R)))}case"neq":return h===null?!j(f):G(d,f,h);case"gt":case"gte":case"lt":case"lte":return G(d,f,h);case"isNull":if(typeof h!="boolean")throw new Error(`${e}(${t}): where.${c}.isNull is true or false`);return h?j(f):!j(f);case"overlaps":if(!Array.isArray(h))throw new Error(`${e}(${t}): where.${c}.overlaps is a list`);if(f!=null&&!Array.isArray(f))throw new Error(`${e}(${t}): where.${c}: "overlaps" is an array column's operator`);return j(f)?null:h.some(R=>f.some(k=>N(R,k)));case"contains":case"icontains":case"startsWith":case"endsWith":{if(d==="contains"&&Array.isArray(h))return j(f)?null:Array.isArray(f)&&h.every(R=>f.some(k=>N(R,k)));if(typeof h!="string")throw new Error(`${e}(${t}): where.${c}.${d} is text`);return j(f)?null:typeof f!="string"?!1:d==="contains"?f.includes(h):d==="icontains"?f.toLowerCase().includes(h.toLowerCase()):d==="startsWith"?f.startsWith(h):f.endsWith(h)}default:throw new Error(`${e}(${t}): where.${c} has no operator "${d}"`)}})):Q(f,w)}function G(e,t,a){if(j(t)||j(a))return null;if(e==="neq")return!N(t,a);let c=tn(t,a);return c===null?!1:e==="gt"?c>0:e==="gte"?c>=0:e==="lt"?c<0:c<=0}function En(){let e=new Map,t=new Map,a=new Map,c=new Map,w=[],f=n=>{let r=e.get(n);return r||e.set(n,r=[]),r},d=(n,r,s)=>{let o=n.get(r);o?o.push(s):n.set(r,[s])},h=n=>n.id===void 0?{id:Rn(),...n}:{...n},R=()=>{let n={store:new Map([...e].map(([r,s])=>[r,s.map($)])),inserted:hn(t),updated:hn(a),deleted:new Map([...c].map(([r,s])=>[r,[...s]]))};return()=>{e=n.store,t=n.inserted,a=n.updated,c=n.deleted}};function k(n,r,s){let o={};for(let[i,u]of Object.entries(s)){let l=_(u);if(l!==null&&l.fn==="now")o[i]=H(l.minus);else{if(l!==null)throw new Error(`${n}(${r}): "${i}" was given ${l.fn==="inc"?"increment()":"decrement()"} \u2014 the row does not exist yet, so there is no current value to change`);o[i]=u}}return P(n,r,Object.keys(o),o),z(n,r,Object.keys(o),o),o}function E(n,r,s,o){P(n,r,Object.keys(o),o);let i={};for(let[u,l]of Object.entries(o)){let g=_(l);g!==null&&g.fn==="now"?i[u]=H(g.minus):g!==null?i[u]=v(s[u],g.by,g.fn==="inc"?1:-1):i[u]=l}return z(n,r,Object.keys(i),i),i}function T(n,r,s){let o=h(k(n,r,s));return f(r).push(o),d(t,r,$(o)),$(o)}function x(n,r,s){return dn(n,r,s),rn(n,r,s),s!==void 0&&on(n,s),(e.get(r)??[]).filter(o=>s===void 0||L(n,r,o,s)===!0)}let I={diagnostics:()=>null,async query(n,r=[]){return w.push({sql:n,params:r}),[]},async findUnique(){throw new Error("the fake database knows no table's declared unique keys \u2014 find the row with findMany, or test this against Postgres")},async page(){throw new Error("the fake database cannot reproduce Postgres' cursor ordering, collation or row-level security \u2014 test pagination against Postgres")},async search(n){throw new Error(`search(${n}): the fake database has neither embeddings nor full text \u2014 test search against Postgres`)},async findById(n,r){let s=(e.get(n)??[]).find(o=>o.id===r);return s?$(s):null},async findMany(n,r,s){let{limit:o,offset:i}=s??{};if(o!==void 0&&(!Number.isInteger(o)||o<0))throw new Error(`findMany(${n}): limit is a whole number, 0 or more (got ${String(o)})`);if(i!==void 0){if(!Number.isInteger(i)||i<0)throw new Error(`findMany(${n}): offset is a whole number, 0 or more (got ${String(i)})`);if(o===void 0)throw new Error(`findMany(${n}): offset comes with limit \u2014 an offset into an unbounded result is not a page`)}if(s?.with!==void 0&&Object.keys(s.with).length>0)throw new Error(`findMany(${n}): the fake database has no relations, so \`with\` cannot be read \u2014 seed and query the related table on its own, or test this against Postgres`);let u=x("findMany",n,r),l=s?.orderBy===void 0?[]:Array.isArray(s.orderBy)?s.orderBy:[s.orderBy];l.length>0&&(u=[...u].sort((y,p)=>{for(let O of l){let b=O.direction==="desc"?-1:1,M=y[O.column],S=p[O.column],X=M==null,an=S==null;if(X||an){if(X&&an)continue;let pn=O.nulls===void 0?b===-1:O.nulls==="first";return(X?1:-1)*(pn?-1:1)}let un=tn(M,S)??(String(M)<String(S)?-1:String(M)>String(S)?1:0);if(un!==0)return un*b}return 0}));let g=o===void 0?u:u.slice(i??0,(i??0)+o),m=s?.select;return g.map(y=>m===void 0||m.length===0?$(y):Object.fromEntries(m.map(p=>[p,structuredClone(y[p])])))},async count(n,r={}){return x("count",n,r).length},async aggregate(n,r){let s=x("aggregate",n,r.where),o=r.groupBy??[],i=l=>{let g={},m=y=>l.map(p=>p[y]).filter(p=>p!=null);for(let y of r.sum??[]){let p=m(y);(g.sum??={})[y]=p.length===0?null:String(p.reduce((O,b)=>v(O,b,1),"0"))}for(let y of r.avg??[]){let p=m(y),O=p.some(b=>typeof b=="number"&&!Number.isInteger(b));(g.avg??={})[y]=p.length===0?null:O?p.reduce((b,M)=>b+M,0)/p.length:kn(B(p.reduce((b,M)=>v(b,M,1),"0")),{unit:BigInt(p.length),scale:0})}for(let[y,p]of[["min",-1],["max",1]])for(let O of r[y]??[]){let b=m(O);(g[y]??={})[O]=b.length===0?null:b.reduce((M,S)=>(tn(S,M)??0)*p>0?S:M)}return r.count===!0?g.count=l.length:r.count!==void 0&&r.count!==!1&&(g.count=Object.fromEntries(Object.entries(r.count).map(([y,p])=>[y,l.filter(O=>L("aggregate",n,O,p)===!0).length]))),g};if(o.length===0)return i(s);let u=new Map;for(let l of s){let g=JSON.stringify(o.map(m=>l[m]));u.set(g,[...u.get(g)??[],l])}return[...u.values()].map(l=>({...i(l),...Object.fromEntries(o.map(g=>[g,l[0][g]]))}))},async insert(n,r){return T("insert",n,r)},insertMany:(async(n,r,s)=>{if(wn(s),s?.onConflict?.length||s?.action!==void 0)throw new Error(`insertMany(${n}): the fake database knows no unique constraint to collide with \u2014 test onConflict against Postgres`);if(r.length===0)return s?.returning===!1?0:[];let o=Object.keys(r[0]);r.forEach((u,l)=>{let g=o.filter(y=>!(y in u)),m=Object.keys(u).filter(y=>!o.includes(y));if(g.length>0||m.length>0)throw new Error(`insertMany(${n}): row ${l} has not the first row's columns${g.length?` (missing ${g.join(", ")})`:""}${m.length?` (extra ${m.join(", ")})`:""} \u2014 write null for an empty one, or insert rows of another shape in a call of their own`)});let i=r.map(u=>T("insertMany",n,u));return s?.returning===!1?i.length:i}),async put(n,r,s){if(!s?.onConflict?.length)throw new Error(`put(${n}): onConflict names at least one column`);let o=k("put",n,r),i=f(n).find(u=>s.onConflict.every(l=>N(u[l],o[l])));if(!i)return T("put",n,r);for(let[u,l]of Object.entries(o))s.onConflict.includes(u)||(i[u]=l);return d(a,n,$(i)),$(i)},async update(n,r,s){let o=e.get(n)??[],i=o.findIndex(u=>u.id===r);return i<0?(P("update",n,Object.keys(s),s),null):(o[i]={...o[i],...E("update",n,o[i],s)},d(a,n,$(o[i])),$(o[i]))},async updateMany(n,r,s,o){F("updateMany",r);let i=x("updateMany",n,r),u=f(n),l=[];for(let g of i){let m=u.indexOf(g);u[m]={...g,...E("updateMany",n,g,s)},d(a,n,$(u[m])),l.push($(u[m]))}return i.length===0&&P("updateMany",n,Object.keys(s),s),o?.returning===!1?l.length:l},async delete(n,r){let s=e.get(n)??[],o=s.findIndex(i=>i.id===r);o<0||(s.splice(o,1),d(c,n,r))},async deleteMany(n,r){F("deleteMany",r);let s=x("deleteMany",n,r);e.set(n,(e.get(n)??[]).filter(o=>!s.includes(o)));for(let o of s)d(c,n,String(o.id));return s.length},async claim(n,r,s={}){let o=Object.keys(r);if(o.length===0)throw new Error(`claim(${n}): no unique field \u2014 claim takes a key; without one, insert(${n}, \u2026)`);P("claim",n,o,r);let i=(e.get(n)??[]).find(u=>o.every(l=>N(u[l],r[l])));return i?{inserted:!1,row:$(i)}:{inserted:!0,row:T("claim",n,{...r,...s})}},async lockRows(n,r){if(r.length===0)return;let s=e.get(n)??[],o=[...new Set(r)].filter(i=>!s.some(u=>u.id===i));if(o.length>0&&s.length>0)throw new Error(`lockRows(${n}): no row with id ${o.join(", ")}`)},async lockRowsWhere(n,r,s){let o=s?.mode??"update";if(!["update","share","noKeyUpdate"].includes(o))throw new Error(`lockRowsWhere(${n}): mode is "update", "share" or "noKeyUpdate" (got "${String(o)}")`);F("lockRowsWhere",r),x("lockRowsWhere",n,r)},async advisoryXactLock(){}};function W(n){let r=R(),s=[];try{for(let o of n.ops){let i=A(o,s);s.push(i);let u=Tn(o.guard,i.rows.length);if(u)throw u}}catch(o){throw r(),o}return{results:s}}function A(n,r){let s=i=>Object.fromEntries(Object.entries(i??{}).map(([u,l])=>[u,yn(l,r)])),o=`transaction plan ${n.op}`;switch(n.op){case"insert":return nn(T(o,n.table,s(n.values)));case"insertMany":{let i=(n.rows??[]).map(g=>s(g)),u=n.onConflict??[];if(n.action!==void 0&&u.length===0)throw new Error(`${o}(${n.table}): the fake database knows no unique key to collide with \u2014 name onConflict columns, or test this against Postgres`);let l=[];for(let g of i){let m=u.length>0?f(n.table).find(y=>u.every(p=>N(y[p],g[p]))):void 0;if(!(m&&n.action==="ignore")){if(m&&n.action==="update"){Object.assign(m,E(o,n.table,m,Object.fromEntries(Object.entries(g).filter(([y])=>!u.includes(y))))),d(a,n.table,$(m)),l.push($(m));continue}l.push(T(o,n.table,g))}}return{rows:l,rows_affected:l.length}}case"upsert":{let i=s(n.values),u=n.onConflict??[];if(Object.keys(i).length===0||u.length===0)throw Object.assign(new Error(`put on ${n.table} needs columns and onConflict`),{error_code:"tx_bad_upsert"});let l=f(n.table).find(g=>u.every(m=>N(g[m],i[m])));return l?(Object.assign(l,E(o,n.table,l,Object.fromEntries(Object.entries(i).filter(([g])=>!u.includes(g))))),d(a,n.table,$(l)),nn($(l))):nn(T(o,n.table,i))}case"update":{let i=s(n.set);if(Object.keys(i).length===0)throw new Error(`update ${n.table}: nothing to set`);let u=en(n.where,r);F(o,u);let l=f(n.table),g=[];for(let m of x(o,n.table,u)){let y=l.indexOf(m);l[y]={...m,...E(o,n.table,m,i)},d(a,n.table,$(l[y])),g.push($(l[y]))}return{rows:g,rows_affected:g.length}}case"delete":{let i=en(n.where,r);F(o,i);let u=x(o,n.table,i);e.set(n.table,f(n.table).filter(l=>!u.includes(l)));for(let l of u)d(c,n.table,String(l.id));return{rows:u.map($),rows_affected:u.length}}case"select":{let i=x(o,n.table,en(n.where,r));return n.limit!==void 0&&(i=i.slice(0,n.limit)),{rows:i.map($),rows_affected:i.length}}default:throw new Error(`unknown operation "${String(n.op)}" in a transaction plan`)}}let C={...I,async txPlan(n){return W(n)},async attempt(n){let r=R();try{return await n(I)}catch(s){throw r(),s}},async atomic(){throw new Error("the fake database cannot reproduce a transaction's isolation, COMMIT or retry \u2014 test $atomic against Postgres")}};return{...C,asService:()=>C,inserted:n=>(t.get(n)??[]).map($),updated:n=>(a.get(n)??[]).map($),deleted:n=>[...c.get(n)??[]],seed(n,r){e.set(n,r.map($))},queries:w}}function hn(e){return new Map([...e].map(([t,a])=>[t,a.map($)]))}function nn(e){return{rows:[e],rows_affected:1}}function yn(e,t){if(!Y(e))return e;let a=t[e.$ref.op]?.rows[0];if(!a)throw Object.assign(new Error(`transaction plan: operation ${e.$ref.op} produced no row to reference`),{error_code:"tx_ref_unresolved"});return a[e.$ref.field]}function en(e,t){let a=c=>{if(Y(c)){let w=yn(c,t);if(w==null)throw Object.assign(new Error(`transaction plan: a filter's reference to operation ${c.$ref.op}'s "${c.$ref.field}" is NULL`),{error_code:"tx_ref_null"});return w}return Array.isArray(c)?c.map(a):c!==null&&typeof c=="object"&&!U(c)&&!Z(c)&&!V(c)&&!(c instanceof Date)?Object.fromEntries(Object.entries(c).map(([w,f])=>[w,a(f)])):c};return a(e??{})}function Tn(e,t){return e?(e.kind==="one"?t===1:e.kind==="none"?t===0:e.kind==="atLeast"?t>=e.n:t<=e.n)?null:Object.assign(new Error(`transaction expectation failed: ${e.kind} (${t} row(s))`),{error_code:"tx_guard_failed",slot:e.slot}):null}export{En as createFakeClient,$n as typedDatabase};
|
|
1
|
+
/*! palgres 0.8.1 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{$ as wn,D as U,E as fn,F as Y,J as Z,K as V,L as z,M as dn,O as P,W as _,aa as $n,e as cn,g as ln}from"./chunks/2LZ4FCGH.js";import"./chunks/ERGV4DGD.js";import{randomUUID as Rn}from"node:crypto";var On=/^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?)?(Z|[+-]\d{2}(:?\d{2})?)?$/,bn=/^([+-]?)(\d*)(?:\.(\d*))?$/;function q(e){if(e instanceof Date)return e.getTime();if(typeof e=="string"&&On.test(e)){let t=Date.parse(e);return Number.isNaN(t)?null:t}return null}function B(e){if(typeof e=="number")return Number.isFinite(e)?B(String(e)):null;if(typeof e!="string"||/e/i.test(e))return null;let t=bn.exec(e.trim());if(t===null||t[2]===""&&(t[3]??"")==="")return null;let a=t[3]??"";return{unit:BigInt(`${t[1]==="-"?"-":""}${t[2]===""?"0":t[2]}${a}`),scale:a.length}}function K(e,t){return e.unit*10n**BigInt(t-e.scale)}function tn(e,t){if(e==null||t===null||t===void 0)return null;let a=q(e),c=q(t);if(a!==null&&c!==null)return Math.sign(a-c);let w=B(e),f=B(t);if(w!==null&&f!==null){let d=Math.max(w.scale,f.scale),h=K(w,d)-K(f,d);return h===0n?0:h<0n?-1:1}return typeof e==typeof t&&(typeof e=="string"||typeof e=="boolean"||typeof e=="number")?e<t?-1:e>t?1:0:null}function N(e,t){return e==null||t===null||t===void 0?!1:e instanceof Date||t instanceof Date?q(e)!==null&&q(e)===q(t):Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((a,c)=>N(a,t[c])):e===t}function H(e){let t=((e?.days??0)*86400+(e?.hours??0)*3600+(e?.minutes??0)*60+(e?.seconds??0))*1e3;return new Date(Date.now()-t).toISOString()}function v(e,t,a){if(e==null)return null;if(typeof e=="number"&&typeof t=="number")return e+a*t;let c=B(e),w=B(t);if(c===null||w===null)throw new Error(`increment()/decrement() on a value that is not a number (${JSON.stringify(e)}): Postgres refuses it ("operator does not exist")`);let f=Math.max(c.scale,w.scale),d=K(c,f)+BigInt(a)*K(w,f);if(f===0)return typeof e=="number"?Number(d):d.toString();let h=d<0n,R=(h?-d:d).toString().padStart(f+1,"0"),k=`${h?"-":""}${R.slice(0,-f)}.${R.slice(-f)}`;return typeof e=="number"?Number(k):k}function kn(e,t){let a=A=>{let C=(A.unit<0n?-A.unit:A.unit).toString().padStart(A.scale+1,"0"),J=C.slice(0,C.length-A.scale),n=C.slice(C.length-A.scale),r=J.padStart(Math.ceil(J.length/4)*4,"0").match(/.{4}/g)??[],s=n.padEnd(Math.ceil(n.length/4)*4,"0").match(/.{4}/g)??[],i=[...r.map((u,l)=>[r.length-1-l,Number(u)]),...s.map((u,l)=>[-1-l,Number(u)])].find(([,u])=>u!==0);return i?[i[0],i[1]]:[0,0]},[c,w]=a(e),[f,d]=a(t),h=c-f-(w<=d?1:0),R=Math.min(Math.max(16-h*4,e.scale,t.scale,0),1e3),k=e.unit*10n**BigInt(R+t.scale),E=t.unit*10n**BigInt(e.scale),T=k/E,x=k%E;2n*(x<0n?-x:x)>=(E<0n?-E:E)&&(T+=k<0n!=E<0n?-1n:1n);let I=T<0n,W=(I?-T:T).toString().padStart(R+1,"0");return`${I?"-":""}${R===0?W:`${W.slice(0,-R)}.${W.slice(-R)}`}`}var $=e=>structuredClone(e);function rn(e,t,a){if(fn(a))throw new Error(`${e}(${t}): the fake database runs no SQL, so a sqlFragment cannot be evaluated \u2014 write the filter in the filter language (gt, gte, lt, lte, neq, in, contains, isNull, OR, AND, NOT), or test this against Postgres`);if(!(a===null||typeof a!="object"))for(let[c,w]of Object.entries(a))if(c==="OR"||c==="AND")for(let f of Array.isArray(w)?w:[])rn(e,t,f);else c==="NOT"&&rn(e,t,w)}function D(e,t,a){return cn(new ln({fields:[{field:t,message:a}]},`${e}: ${t} ${a}`))}function on(e,t,a="where"){for(let[c,w]of Object.entries(t))if(c==="OR"||c==="AND"){let f=w;if(c==="AND"&&f.length===0)throw D(e,`${a}.AND`,"is an empty list \u2014 no condition at all. Leave it out, or name a condition in it.");f.forEach((d,h)=>{if(Object.keys(d).length===0)throw D(e,`${a}.${c}[${h}]`,"holds no condition \u2014 a branch that matches every row. Name a condition in it, or leave it out.");on(e,d,`${a}.${c}[${h}]`)})}else if(c==="NOT"){if(Array.isArray(w))throw D(e,`${a}.NOT`,"is a list \u2014 NOT takes one filter object. For several conditions, NOT: { AND: [...] } or NOT: { OR: [...] }.");if(Object.keys(w).length===0)throw D(e,`${a}.NOT`,"holds no condition \u2014 NOT of nothing is not a filter. Name the condition to exclude.");on(e,w,`${a}.NOT`)}else if(c==="has"&&Object.keys(w??{}).length===0)throw D(e,`${a}.has`,"names no relation \u2014 no condition. Name one: has: { <relation>: { \u2026 } }.")}function F(e,t){if(Object.keys(t).length===0)throw D(e,"where",`holds no condition, so ${e} would reach EVERY row of the table. Name a condition.`)}function sn(e){let t=!1;for(let a of e){if(a===!1)return!1;a===null&&(t=!0)}return t?null:!0}function mn(e){let t=!1;for(let a of e){if(a===!0)return!0;a===null&&(t=!0)}return t?null:!1}var j=e=>e==null;function L(e,t,a,c){return sn(Object.entries(c).map(([w,f])=>{if(w==="OR")return mn(f.map(d=>L(e,t,a,d)));if(w==="AND")return sn(f.map(d=>L(e,t,a,d)));if(w==="NOT"){let d=L(e,t,a,f);return d===null?null:!d}if(w==="has")throw new Error(`${e}(${t}): the fake database has no relations, so a \`has\` filter cannot be decided for a row \u2014 read the related table first and filter by its ids ({ id: { in: [\u2026] } }), or test this against Postgres`);return xn(e,t,a,w,f)}))}var gn=["neq","gt","gte","lt","lte"];function Q(e,t){return j(e)||j(t)?null:N(e,t)}function xn(e,t,a,c,w){let f=a[c];return w===null?j(f):U(w)?Q(f,a[w.$col]):V(w)?Q(f,H(_(w)?.minus)):typeof w=="object"&&!Array.isArray(w)&&!(w instanceof Date)?sn(Object.entries(w).map(([d,h])=>{if(V(h)){if(!gn.includes(d))throw new Error(`${e}(${t}): where.${c}.${d} cannot take now()`);return G(d,f,H(_(h)?.minus))}if(Z(h))throw new Error(`${e}(${t}): where.${c}.${d} was given increment()/decrement() \u2014 a write, not a value to compare with`);if(U(h)){if(!gn.includes(d))throw new Error(`${e}(${t}): where.${c}.${d} cannot take col()`);return G(d,f,a[h.$col])}switch(d){case"in":{if(!Array.isArray(h))throw new Error(`${e}(${t}): where.${c}.in is a list`);return mn(h.map(R=>Q(f,R)))}case"neq":return h===null?!j(f):G(d,f,h);case"gt":case"gte":case"lt":case"lte":return G(d,f,h);case"isNull":if(typeof h!="boolean")throw new Error(`${e}(${t}): where.${c}.isNull is true or false`);return h?j(f):!j(f);case"overlaps":if(!Array.isArray(h))throw new Error(`${e}(${t}): where.${c}.overlaps is a list`);if(f!=null&&!Array.isArray(f))throw new Error(`${e}(${t}): where.${c}: "overlaps" is an array column's operator`);return j(f)?null:h.some(R=>f.some(k=>N(R,k)));case"contains":case"icontains":case"startsWith":case"endsWith":{if(d==="contains"&&Array.isArray(h))return j(f)?null:Array.isArray(f)&&h.every(R=>f.some(k=>N(R,k)));if(typeof h!="string")throw new Error(`${e}(${t}): where.${c}.${d} is text`);return j(f)?null:typeof f!="string"?!1:d==="contains"?f.includes(h):d==="icontains"?f.toLowerCase().includes(h.toLowerCase()):d==="startsWith"?f.startsWith(h):f.endsWith(h)}default:throw new Error(`${e}(${t}): where.${c} has no operator "${d}"`)}})):Q(f,w)}function G(e,t,a){if(j(t)||j(a))return null;if(e==="neq")return!N(t,a);let c=tn(t,a);return c===null?!1:e==="gt"?c>0:e==="gte"?c>=0:e==="lt"?c<0:c<=0}function En(){let e=new Map,t=new Map,a=new Map,c=new Map,w=[],f=n=>{let r=e.get(n);return r||e.set(n,r=[]),r},d=(n,r,s)=>{let o=n.get(r);o?o.push(s):n.set(r,[s])},h=n=>n.id===void 0?{id:Rn(),...n}:{...n},R=()=>{let n={store:new Map([...e].map(([r,s])=>[r,s.map($)])),inserted:hn(t),updated:hn(a),deleted:new Map([...c].map(([r,s])=>[r,[...s]]))};return()=>{e=n.store,t=n.inserted,a=n.updated,c=n.deleted}};function k(n,r,s){let o={};for(let[i,u]of Object.entries(s)){let l=_(u);if(l!==null&&l.fn==="now")o[i]=H(l.minus);else{if(l!==null)throw new Error(`${n}(${r}): "${i}" was given ${l.fn==="inc"?"increment()":"decrement()"} \u2014 the row does not exist yet, so there is no current value to change`);o[i]=u}}return P(n,r,Object.keys(o),o),z(n,r,Object.keys(o),o),o}function E(n,r,s,o){P(n,r,Object.keys(o),o);let i={};for(let[u,l]of Object.entries(o)){let g=_(l);g!==null&&g.fn==="now"?i[u]=H(g.minus):g!==null?i[u]=v(s[u],g.by,g.fn==="inc"?1:-1):i[u]=l}return z(n,r,Object.keys(i),i),i}function T(n,r,s){let o=h(k(n,r,s));return f(r).push(o),d(t,r,$(o)),$(o)}function x(n,r,s){return dn(n,r,s),rn(n,r,s),s!==void 0&&on(n,s),(e.get(r)??[]).filter(o=>s===void 0||L(n,r,o,s)===!0)}let I={diagnostics:()=>null,async query(n,r=[]){return w.push({sql:n,params:r}),[]},async findUnique(){throw new Error("the fake database knows no table's declared unique keys \u2014 find the row with findMany, or test this against Postgres")},async page(){throw new Error("the fake database cannot reproduce Postgres' cursor ordering, collation or row-level security \u2014 test pagination against Postgres")},async search(n){throw new Error(`search(${n}): the fake database has neither embeddings nor full text \u2014 test search against Postgres`)},async findById(n,r){let s=(e.get(n)??[]).find(o=>o.id===r);return s?$(s):null},async findMany(n,r,s){let{limit:o,offset:i}=s??{};if(o!==void 0&&(!Number.isInteger(o)||o<0))throw new Error(`findMany(${n}): limit is a whole number, 0 or more (got ${String(o)})`);if(i!==void 0){if(!Number.isInteger(i)||i<0)throw new Error(`findMany(${n}): offset is a whole number, 0 or more (got ${String(i)})`);if(o===void 0)throw new Error(`findMany(${n}): offset comes with limit \u2014 an offset into an unbounded result is not a page`)}if(s?.with!==void 0&&Object.keys(s.with).length>0)throw new Error(`findMany(${n}): the fake database has no relations, so \`with\` cannot be read \u2014 seed and query the related table on its own, or test this against Postgres`);let u=x("findMany",n,r),l=s?.orderBy===void 0?[]:Array.isArray(s.orderBy)?s.orderBy:[s.orderBy];l.length>0&&(u=[...u].sort((y,p)=>{for(let O of l){let b=O.direction==="desc"?-1:1,M=y[O.column],S=p[O.column],X=M==null,an=S==null;if(X||an){if(X&&an)continue;let pn=O.nulls===void 0?b===-1:O.nulls==="first";return(X?1:-1)*(pn?-1:1)}let un=tn(M,S)??(String(M)<String(S)?-1:String(M)>String(S)?1:0);if(un!==0)return un*b}return 0}));let g=o===void 0?u:u.slice(i??0,(i??0)+o),m=s?.select;return g.map(y=>m===void 0||m.length===0?$(y):Object.fromEntries(m.map(p=>[p,structuredClone(y[p])])))},async count(n,r={}){return x("count",n,r).length},async aggregate(n,r){let s=x("aggregate",n,r.where),o=r.groupBy??[],i=l=>{let g={},m=y=>l.map(p=>p[y]).filter(p=>p!=null);for(let y of r.sum??[]){let p=m(y);(g.sum??={})[y]=p.length===0?null:String(p.reduce((O,b)=>v(O,b,1),"0"))}for(let y of r.avg??[]){let p=m(y),O=p.some(b=>typeof b=="number"&&!Number.isInteger(b));(g.avg??={})[y]=p.length===0?null:O?p.reduce((b,M)=>b+M,0)/p.length:kn(B(p.reduce((b,M)=>v(b,M,1),"0")),{unit:BigInt(p.length),scale:0})}for(let[y,p]of[["min",-1],["max",1]])for(let O of r[y]??[]){let b=m(O);(g[y]??={})[O]=b.length===0?null:b.reduce((M,S)=>(tn(S,M)??0)*p>0?S:M)}return r.count===!0?g.count=l.length:r.count!==void 0&&r.count!==!1&&(g.count=Object.fromEntries(Object.entries(r.count).map(([y,p])=>[y,l.filter(O=>L("aggregate",n,O,p)===!0).length]))),g};if(o.length===0)return i(s);let u=new Map;for(let l of s){let g=JSON.stringify(o.map(m=>l[m]));u.set(g,[...u.get(g)??[],l])}return[...u.values()].map(l=>({...i(l),...Object.fromEntries(o.map(g=>[g,l[0][g]]))}))},async insert(n,r){return T("insert",n,r)},insertMany:(async(n,r,s)=>{if(wn(s),s?.onConflict?.length||s?.action!==void 0)throw new Error(`insertMany(${n}): the fake database knows no unique constraint to collide with \u2014 test onConflict against Postgres`);if(r.length===0)return s?.returning===!1?0:[];let o=Object.keys(r[0]);r.forEach((u,l)=>{let g=o.filter(y=>!(y in u)),m=Object.keys(u).filter(y=>!o.includes(y));if(g.length>0||m.length>0)throw new Error(`insertMany(${n}): row ${l} has not the first row's columns${g.length?` (missing ${g.join(", ")})`:""}${m.length?` (extra ${m.join(", ")})`:""} \u2014 write null for an empty one, or insert rows of another shape in a call of their own`)});let i=r.map(u=>T("insertMany",n,u));return s?.returning===!1?i.length:i}),async put(n,r,s){if(!s?.onConflict?.length)throw new Error(`put(${n}): onConflict names at least one column`);let o=k("put",n,r),i=f(n).find(u=>s.onConflict.every(l=>N(u[l],o[l])));if(!i)return T("put",n,r);for(let[u,l]of Object.entries(o))s.onConflict.includes(u)||(i[u]=l);return d(a,n,$(i)),$(i)},async update(n,r,s){let o=e.get(n)??[],i=o.findIndex(u=>u.id===r);return i<0?(P("update",n,Object.keys(s),s),null):(o[i]={...o[i],...E("update",n,o[i],s)},d(a,n,$(o[i])),$(o[i]))},async updateMany(n,r,s,o){F("updateMany",r);let i=x("updateMany",n,r),u=f(n),l=[];for(let g of i){let m=u.indexOf(g);u[m]={...g,...E("updateMany",n,g,s)},d(a,n,$(u[m])),l.push($(u[m]))}return i.length===0&&P("updateMany",n,Object.keys(s),s),o?.returning===!1?l.length:l},async delete(n,r){let s=e.get(n)??[],o=s.findIndex(i=>i.id===r);o<0||(s.splice(o,1),d(c,n,r))},async deleteMany(n,r){F("deleteMany",r);let s=x("deleteMany",n,r);e.set(n,(e.get(n)??[]).filter(o=>!s.includes(o)));for(let o of s)d(c,n,String(o.id));return s.length},async claim(n,r,s={}){let o=Object.keys(r);if(o.length===0)throw new Error(`claim(${n}): no unique field \u2014 claim takes a key; without one, insert(${n}, \u2026)`);P("claim",n,o,r);let i=(e.get(n)??[]).find(u=>o.every(l=>N(u[l],r[l])));return i?{inserted:!1,row:$(i)}:{inserted:!0,row:T("claim",n,{...r,...s})}},async lockRows(n,r){if(r.length===0)return;let s=e.get(n)??[],o=[...new Set(r)].filter(i=>!s.some(u=>u.id===i));if(o.length>0&&s.length>0)throw new Error(`lockRows(${n}): no row with id ${o.join(", ")}`)},async lockRowsWhere(n,r,s){let o=s?.mode??"update";if(!["update","share","noKeyUpdate"].includes(o))throw new Error(`lockRowsWhere(${n}): mode is "update", "share" or "noKeyUpdate" (got "${String(o)}")`);F("lockRowsWhere",r),x("lockRowsWhere",n,r)},async advisoryXactLock(){}};function W(n){let r=R(),s=[];try{for(let o of n.ops){let i=A(o,s);s.push(i);let u=Tn(o.guard,i.rows.length);if(u)throw u}}catch(o){throw r(),o}return{results:s}}function A(n,r){let s=i=>Object.fromEntries(Object.entries(i??{}).map(([u,l])=>[u,yn(l,r)])),o=`transaction plan ${n.op}`;switch(n.op){case"insert":return nn(T(o,n.table,s(n.values)));case"insertMany":{let i=(n.rows??[]).map(g=>s(g)),u=n.onConflict??[];if(n.action!==void 0&&u.length===0)throw new Error(`${o}(${n.table}): the fake database knows no unique key to collide with \u2014 name onConflict columns, or test this against Postgres`);let l=[];for(let g of i){let m=u.length>0?f(n.table).find(y=>u.every(p=>N(y[p],g[p]))):void 0;if(!(m&&n.action==="ignore")){if(m&&n.action==="update"){Object.assign(m,E(o,n.table,m,Object.fromEntries(Object.entries(g).filter(([y])=>!u.includes(y))))),d(a,n.table,$(m)),l.push($(m));continue}l.push(T(o,n.table,g))}}return{rows:l,rows_affected:l.length}}case"upsert":{let i=s(n.values),u=n.onConflict??[];if(Object.keys(i).length===0||u.length===0)throw Object.assign(new Error(`put on ${n.table} needs columns and onConflict`),{error_code:"tx_bad_upsert"});let l=f(n.table).find(g=>u.every(m=>N(g[m],i[m])));return l?(Object.assign(l,E(o,n.table,l,Object.fromEntries(Object.entries(i).filter(([g])=>!u.includes(g))))),d(a,n.table,$(l)),nn($(l))):nn(T(o,n.table,i))}case"update":{let i=s(n.set);if(Object.keys(i).length===0)throw new Error(`update ${n.table}: nothing to set`);let u=en(n.where,r);F(o,u);let l=f(n.table),g=[];for(let m of x(o,n.table,u)){let y=l.indexOf(m);l[y]={...m,...E(o,n.table,m,i)},d(a,n.table,$(l[y])),g.push($(l[y]))}return{rows:g,rows_affected:g.length}}case"delete":{let i=en(n.where,r);F(o,i);let u=x(o,n.table,i);e.set(n.table,f(n.table).filter(l=>!u.includes(l)));for(let l of u)d(c,n.table,String(l.id));return{rows:u.map($),rows_affected:u.length}}case"select":{let i=x(o,n.table,en(n.where,r));return n.limit!==void 0&&(i=i.slice(0,n.limit)),{rows:i.map($),rows_affected:i.length}}default:throw new Error(`unknown operation "${String(n.op)}" in a transaction plan`)}}let C={...I,async txPlan(n){return W(n)},async attempt(n){let r=R();try{return await n(I)}catch(s){throw r(),s}},async atomic(){throw new Error("the fake database cannot reproduce a transaction's isolation, COMMIT or retry \u2014 test $atomic against Postgres")}};return{...C,asService:()=>C,inserted:n=>(t.get(n)??[]).map($),updated:n=>(a.get(n)??[]).map($),deleted:n=>[...c.get(n)??[]],seed(n,r){e.set(n,r.map($))},queries:w}}function hn(e){return new Map([...e].map(([t,a])=>[t,a.map($)]))}function nn(e){return{rows:[e],rows_affected:1}}function yn(e,t){if(!Y(e))return e;let a=t[e.$ref.op]?.rows[0];if(!a)throw Object.assign(new Error(`transaction plan: operation ${e.$ref.op} produced no row to reference`),{error_code:"tx_ref_unresolved"});return a[e.$ref.field]}function en(e,t){let a=c=>{if(Y(c)){let w=yn(c,t);if(w==null)throw Object.assign(new Error(`transaction plan: a filter's reference to operation ${c.$ref.op}'s "${c.$ref.field}" is NULL`),{error_code:"tx_ref_null"});return w}return Array.isArray(c)?c.map(a):c!==null&&typeof c=="object"&&!U(c)&&!Z(c)&&!V(c)&&!(c instanceof Date)?Object.fromEntries(Object.entries(c).map(([w,f])=>[w,a(f)])):c};return a(e??{})}function Tn(e,t){return e?(e.kind==="one"?t===1:e.kind==="none"?t===0:e.kind==="atLeast"?t>=e.n:t<=e.n)?null:Object.assign(new Error(`transaction expectation failed: ${e.kind} (${t} row(s))`),{error_code:"tx_guard_failed",slot:e.slot}):null}export{En as createFakeClient,$n as typedDatabase};
|
package/package.json
CHANGED
|
@@ -109,6 +109,8 @@ export interface ColumnDef {
|
|
|
109
109
|
* the index created for this foreign key column by default.
|
|
110
110
|
*/
|
|
111
111
|
index?: boolean;
|
|
112
|
+
/** Set only when a foreign key explicitly says `deferrable: false`: see references(). */
|
|
113
|
+
deferrable?: false;
|
|
112
114
|
enumName?: string;
|
|
113
115
|
enumValues?: string[];
|
|
114
116
|
unique?: boolean;
|
|
@@ -397,6 +399,17 @@ export declare class ColumnBuilder<K extends ColumnType = ColumnType, N extends
|
|
|
397
399
|
* column that CHANGES is indexed, not because the table has indexes.
|
|
398
400
|
*/
|
|
399
401
|
index?: boolean;
|
|
402
|
+
/**
|
|
403
|
+
* Only `false`. A foreign key with an action (`onDelete` or `onUpdate`
|
|
404
|
+
* other than no action and restrict) is made DEFERRABLE unasked —
|
|
405
|
+
* still checked at each statement, until a transaction defers it — so
|
|
406
|
+
* forgetting a user, whose rows cascade, holds the checks to its commit:
|
|
407
|
+
* Postgres can otherwise fail a cascade that sets two keys of one row
|
|
408
|
+
* null in turn. `false` keeps it checked at once whatever the
|
|
409
|
+
* transaction says: what a database taken over had (`palbase db:pull`
|
|
410
|
+
* writes it), not something to choose.
|
|
411
|
+
*/
|
|
412
|
+
deferrable?: false;
|
|
400
413
|
}): ColumnBuilder<K, N, D, E, P, T, W, Q>;
|
|
401
414
|
/**
|
|
402
415
|
* Foreign key onto THIS table (`parent_id → id`) — category trees, comment
|
|
@@ -38,6 +38,8 @@ export interface ForeignKeyDef {
|
|
|
38
38
|
match?: FkMatch;
|
|
39
39
|
/** Only `false`: no index derived for a one-column key (the column's references() has the same option). */
|
|
40
40
|
index?: false;
|
|
41
|
+
/** Only `false`: checked at once whatever a transaction says, though the key has an action (the column's references() has the same option). */
|
|
42
|
+
deferrable?: false;
|
|
41
43
|
}
|
|
42
44
|
/**
|
|
43
45
|
* Builds one table-level FOREIGN KEY, which can span several columns. Start it
|
|
@@ -99,13 +101,21 @@ export declare class ForeignKeyBuilder {
|
|
|
99
101
|
* over had: its key unindexed, or indexed by an index of its own.
|
|
100
102
|
*/
|
|
101
103
|
index(on: false): this;
|
|
104
|
+
/**
|
|
105
|
+
* `.deferrable(false)`: a key with an action is made DEFERRABLE unasked
|
|
106
|
+
* (still checked at each statement, until a transaction defers it — what
|
|
107
|
+
* forgetting a user needs, see a column's references()); this one stays
|
|
108
|
+
* checked at once whatever the transaction says. What a database taken
|
|
109
|
+
* over had.
|
|
110
|
+
*/
|
|
111
|
+
deferrable(on: false): this;
|
|
102
112
|
}
|
|
103
113
|
/**
|
|
104
114
|
* Starts a table-level foreign key named `name`, for a table's `foreignKeys`
|
|
105
115
|
* callback. Constraints are matched by name across deploys.
|
|
106
116
|
*
|
|
107
117
|
* @param name The constraint name. It must not be empty.
|
|
108
|
-
* @returns A {@link ForeignKeyBuilder}: chain `.on()` and `.references()`, and optionally `.onDelete()`, `.onUpdate()`, `.match()`, `.index(false)`.
|
|
118
|
+
* @returns A {@link ForeignKeyBuilder}: chain `.on()` and `.references()`, and optionally `.onDelete()`, `.onUpdate()`, `.match()`, `.index(false)`, `.deferrable(false)`.
|
|
109
119
|
*/
|
|
110
120
|
export declare function foreignKey(name: string): ForeignKeyBuilder;
|
|
111
121
|
/**
|
|
@@ -179,6 +179,13 @@ export declare class Migrator {
|
|
|
179
179
|
private authRefusals;
|
|
180
180
|
private ensure;
|
|
181
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* The open migration's plan, if this Palgres can run it: one written by a
|
|
184
|
+
* newer Palgres — a format after PLAN_FORMAT, or a step of a kind it does
|
|
185
|
+
* not know — is refused, saying what to run instead, and run as nothing
|
|
186
|
+
* else (an older release pushed back over a migration a newer one opened).
|
|
187
|
+
*/
|
|
188
|
+
export declare function runnable(plan: Plan, to: number): Plan;
|
|
182
189
|
/** The search_path of version n through its views: its views first, then the schema for the types and functions, pg_temp last (connect.ts). */
|
|
183
190
|
export declare function searchPath(n: number, schema?: string): string;
|
|
184
191
|
/**
|
|
@@ -108,7 +108,29 @@ export interface ForeignKey {
|
|
|
108
108
|
onDelete: FkAction;
|
|
109
109
|
onUpdate: FkAction;
|
|
110
110
|
match?: 'simple' | 'full';
|
|
111
|
+
/**
|
|
112
|
+
* DEFERRABLE, INITIALLY IMMEDIATE: checked at each statement as any foreign
|
|
113
|
+
* key is, until a transaction says SET CONSTRAINTS … DEFERRED. What the
|
|
114
|
+
* schema language makes of a foreign key with a referential action
|
|
115
|
+
* (deferrableByRule).
|
|
116
|
+
*/
|
|
117
|
+
deferrable?: true;
|
|
111
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Whether a foreign key with these actions is made DEFERRABLE. Postgres checks
|
|
121
|
+
* every key of a row again — the unchanged ones too — when a row this
|
|
122
|
+
* transaction already wrote is updated (ri_triggers.c,
|
|
123
|
+
* RI_FKey_fk_upd_check_required). One delete that cascades can set two keys
|
|
124
|
+
* of a row null in turn while a third key's row is gone and its own SET NULL
|
|
125
|
+
* still waits in the queue: the check of the second update fails on a key
|
|
126
|
+
* about to be null (pgsql-bugs #17223, #17945). Whether it does is the order
|
|
127
|
+
* the actions run in, the constraints' OIDs compared as text — a database
|
|
128
|
+
* made anew and one migrated for months differ. Deferrable, a transaction
|
|
129
|
+
* that deletes what cascades (forgetUser) holds the checks to its commit,
|
|
130
|
+
* when only each row's last version is checked; the actions themselves never
|
|
131
|
+
* defer.
|
|
132
|
+
*/
|
|
133
|
+
export declare function deferrableByRule(onDelete: FkAction, onUpdate: FkAction): boolean;
|
|
112
134
|
export interface Policy {
|
|
113
135
|
name: string;
|
|
114
136
|
for: 'all' | 'select' | 'insert' | 'update' | 'delete';
|
|
@@ -34,7 +34,22 @@ export type Step =
|
|
|
34
34
|
where: string;
|
|
35
35
|
why: string;
|
|
36
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* The kinds of step this Palgres runs. A plan is kept in the database while
|
|
39
|
+
* it runs, and the version that runs it next may be another — an older one
|
|
40
|
+
* pushed back (a revert): a kind it does not know is not run as some other.
|
|
41
|
+
* A new kind is a new PLAN_FORMAT.
|
|
42
|
+
*/
|
|
43
|
+
export declare const STEP_KINDS: ReadonlySet<Step['kind']>;
|
|
44
|
+
/**
|
|
45
|
+
* The plan's format, written with each plan: a Palgres runs a plan of its
|
|
46
|
+
* format or before it, and refuses a newer one by name. A plan written
|
|
47
|
+
* before plans named theirs is of format 1.
|
|
48
|
+
*/
|
|
49
|
+
export declare const PLAN_FORMAT = 1;
|
|
37
50
|
export interface Plan {
|
|
51
|
+
/** Its format (PLAN_FORMAT as it was written); absent: 1. */
|
|
52
|
+
format?: number;
|
|
38
53
|
from: number | null;
|
|
39
54
|
to: number;
|
|
40
55
|
/** What changes, a line each, for people. */
|
|
@@ -36,13 +36,32 @@ export interface TableInfo {
|
|
|
36
36
|
export declare const quoteIdent: (name: string) => string;
|
|
37
37
|
/** A column's type as the engine reads it: the DSL's, an sqlType() as "sql:<type>". */
|
|
38
38
|
export declare function engineType(def: ColumnDef): string;
|
|
39
|
+
/** What a delete from a table sends around itself: its deferrable keys' checks held, then run. */
|
|
40
|
+
export interface Deferral {
|
|
41
|
+
defer: string;
|
|
42
|
+
check: string;
|
|
43
|
+
}
|
|
39
44
|
export declare class Catalog {
|
|
40
45
|
readonly version: number;
|
|
41
46
|
private readonly tables;
|
|
42
47
|
private readonly ignoredTables;
|
|
48
|
+
private readonly schemas;
|
|
49
|
+
private deferrals?;
|
|
43
50
|
constructor(schemas: readonly SchemaDef[], binding: Binding);
|
|
44
51
|
/** A table of this version, or a refusal that names why it is not one. */
|
|
45
52
|
table(key: string, caller: string): TableInfo;
|
|
53
|
+
/**
|
|
54
|
+
* What a delete from `t` sends before and after itself, or null: the
|
|
55
|
+
* deferrable foreign keys onto every table the delete cascades to (`t`
|
|
56
|
+
* too) held DEFERRED for the delete, then IMMEDIATE — their checks run
|
|
57
|
+
* there, before the next statement, as they would have at the delete's
|
|
58
|
+
* end. Postgres checks every key of a row an action writes a second time,
|
|
59
|
+
* one whose own SET NULL is still to come among them (deferrableByRule):
|
|
60
|
+
* held to after the cascade, that check finds the row's version it was
|
|
61
|
+
* queued for gone and passes over it. Only these keys, by name: a
|
|
62
|
+
* transaction's own deferred constraints are left as it set them.
|
|
63
|
+
*/
|
|
64
|
+
deferral(t: TableInfo): Deferral | null;
|
|
46
65
|
}
|
|
47
66
|
/** The expression that reads a column as its row type promises, or null when the driver's value already is that. */
|
|
48
67
|
export declare function typedResult(type: string | null, expr: string): string | null;
|
|
@@ -12,3 +12,12 @@ export declare const ENV_BLOCK_END = "// palbase:env:end";
|
|
|
12
12
|
export declare function makeEnvDts(schemas: readonly SchemaDef[], options?: {
|
|
13
13
|
module?: string;
|
|
14
14
|
}): string;
|
|
15
|
+
/**
|
|
16
|
+
* The same types as a block of their own, between the markers and holding the
|
|
17
|
+
* helper types it names: what a tool writes into a file that holds more
|
|
18
|
+
* (palbase db:types, into palbase/palbase-env.d.ts beside the stack block),
|
|
19
|
+
* replacing only what is between them.
|
|
20
|
+
*/
|
|
21
|
+
export declare function envBlock(schemas: readonly SchemaDef[], options?: {
|
|
22
|
+
module?: string;
|
|
23
|
+
}): string;
|
|
@@ -59,7 +59,7 @@ export type { Embed } from './search.js';
|
|
|
59
59
|
export type { DatabaseBudget, DatabaseDiagnostics, DatabaseDiagnosticsOptions, DatabaseQueryEvent } from './diagnostics.js';
|
|
60
60
|
export { BUN_CLOSE_GRACE_MS, bunDriver, cancelBackendThrough, cancelOpeningThrough, closeBunPool, DriverRefused, encodeParam, encodePgArray, inlineParams, POSTGRES_JS_TYPES, postgresJsDriver, renewingBunPool, verifyDriver, type PostgresJs } from './driver.js';
|
|
61
61
|
export type { BunPool, BunReserved, BunSqlPool, Opening, RenewingBunPool, Statement, StatementHint, SqlDriver, SqlTx } from './driver.js';
|
|
62
|
-
export { makeEnvDts, ENV_BLOCK_END, ENV_BLOCK_START } from './env-gen.js';
|
|
62
|
+
export { envBlock, makeEnvDts, ENV_BLOCK_END, ENV_BLOCK_START } from './env-gen.js';
|
|
63
63
|
export { BadRequest, Conflict, connectionFailure, constraintOf, DeadlockDetected, ENGINE_RAISED, HTTP_ERROR_BRAND, HttpError, isEngineRaised, isRetryable, markEngineRaised, NotFound, SerializationFailure, SQLSTATE, sqlstateOf, TooManyRequests, TransactionAborted, UniqueViolation, } from './errors.js';
|
|
64
64
|
export type { BadRequestData, FieldError, RetryableError, TooManyRequestsData } from './errors.js';
|
|
65
65
|
export type { AtomicOptions, InsertConflict, InsertManyOptions, Page, PageInfo, PageNavigation, RawPageOptions, TransactionIsolation } from './options.js';
|
|
@@ -42,8 +42,12 @@ export interface Env<T = unknown, S = unknown> {
|
|
|
42
42
|
* declare module "palbase/backend/env" { interface Tables extends TablesOf<typeof schema> {} }
|
|
43
43
|
*
|
|
44
44
|
* Its unique keys are the ones the file declares, so findUnique takes them.
|
|
45
|
-
* Relations
|
|
46
|
-
*
|
|
45
|
+
* Relations are not read this way: a foreign key's target is a thunk, its type
|
|
46
|
+
* the bare column's (so that tables can name each other), and it may be
|
|
47
|
+
* another file's table, which this file's type never sees — `with` and `has`
|
|
48
|
+
* take none. `palbase db:types` writes the app's tables with their relations,
|
|
49
|
+
* both ways and across files, into palbase-env.d.ts (envBlock): an app that
|
|
50
|
+
* queries a relation declares its Tables there, not with TablesOf.
|
|
47
51
|
*/
|
|
48
52
|
export type TablesOf<S extends SchemaDef> = {
|
|
49
53
|
[K in keyof S['tables']]: {
|
package/dist/chunks/4WIUQCVC.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/*! palgres 0.7.0 — Palbase SDK License (see LICENSE) */
|
|
2
|
-
import{createHash as z}from"node:crypto";var L=class extends Error{problems;constructor(e){super(`the schema is not valid:
|
|
3
|
-
- ${e.join(`
|
|
4
|
-
- `)}`),this.name="SchemaError",this.problems=e}},fe=()=>({tables:[],enums:[],extensions:[],raw:[]}),b=n=>`${n.schema}.${n.name}`,Q={int:"integer",int4:"integer",int2:"smallint",int8:"bigint",float4:"real",float8:"double precision",bool:"boolean",timestamptz:"timestamp with time zone",timestamp:"timestamp without time zone","timestamp without time zone":"timestamp without time zone",timetz:"time with time zone",time:"time without time zone",varchar:"character varying",char:"character",decimal:"numeric"};function D(n){let e=n.trim().replace(/\s+/g," "),t="";for(;e.endsWith("[]");)t+="[]",e=e.slice(0,-2).trim();let s=/^((?:"(?:[^"]|"")+"|[A-Za-z_][A-Za-z0-9_ ]*?)(?:\.(?:"(?:[^"]|"")+"|[A-Za-z_][A-Za-z0-9_]*))?)\s*(\(.*\))?$/.exec(e);if(!s)return n.trim()+t;let c=s[2]?s[2].replace(/\s+/g,""):"",o=W(s[1]);return o===void 0?n.trim()+t:o.length===1&&o[0].quoted?`"${o[0].name.replace(/"/g,'""')}"${c}${t}`:o.length===1?`${Q[o[0].name]??o[0].name}${c}${t}`:`${o.map(l=>N(l.name)).join(".")}${c}${t}`}var N=n=>/^[a-z_][a-z0-9_$]*$/.test(n)?n:`"${n.replace(/"/g,'""')}"`,ue=(n,e)=>`${N(n)}.${N(e)}`;function W(n){let e=[],t=0;for(;t<n.length;){if(n[t]==='"'){let s=t+1,c="";for(;;){if(s>=n.length)return;if(n[s]==='"'){if(n[s+1]==='"'){c+='"',s+=2;continue}break}c+=n[s++]}e.push({name:c,quoted:!0}),t=s+1}else{let s=/^[A-Za-z_][A-Za-z0-9_ ]*/.exec(n.slice(t));if(!s)return;e.push({name:s[0].trim().toLowerCase(),quoted:!1}),t+=s[0].length}if(t<n.length){if(n[t]!==".")return;t++}}return e}var J=/^[A-Za-z_][A-Za-z0-9_$]*$/,Z=63;function y(n,e,t=!1){if(typeof e!="string"||e==="")return`${n} has no name`;if(t?e.includes("\0"):!J.test(e))return`${n} "${e}": a name is letters, digits and _ (starting with a letter or _)`;if(Buffer.byteLength(e)>Z)return`${n} "${e}": longer than Postgres' 63 bytes, it would be cut`;if(e.startsWith("palgres_")||e.startsWith("_palgres"))return`${n} "${e}": names starting with palgres_ are Palgres' own`}var G="vector",F=["cosine","euclidean","inner_product"],A=1536,X=2e3,R=4e3,Y=/^(text|citext|public\.citext|character varying(\(\d+\))?)$/;function q(n,e,t){let s=[];e.primaryKey.length!==1&&s.push(`${n} declares search and has ${e.primaryKey.length===0?"no primary key":`a primary key of ${e.primaryKey.length} columns`}: a row's vector is kept by its key \u2014 give the table a single-column primary key (uuid().primaryKey())`),(!Array.isArray(t.from)||t.from.length===0)&&s.push(`${n}: search.from is empty \u2014 name the text columns a row is found by (search: { from: ['title', 'body'], model })`);let c=new Set;for(let o of Array.isArray(t.from)?t.from:[]){c.has(o)&&s.push(`${n}: search.from names "${o}" twice \u2014 name each column once`),c.add(o);let l=e.columns.find(r=>r.name===o);l?l.ignored?s.push(`${n}: search.from names "${o}", which is ignored \u2014 take it out of search.from, or keep the column`):Y.test(D(l.type))?l.generated&&s.push(`${n}: search.from names "${o}", a generated column \u2014 no write names it, so nothing would say when to embed the row again: name the columns it is computed from`):s.push(`${n}: search.from names "${o}", which is ${l.type} \u2014 search reads text (text, varchar, citext): name a text column, or keep the text in one`):s.push(`${n}: search.from names "${o}", which the table does not have \u2014 name its text columns`)}return(typeof t.model!="string"||t.model.trim()==="")&&s.push(`${n}: search.model is empty \u2014 name the embedding model (search: { from, model: 'embedding' })`),F.includes(t.metric)||s.push(`${n}: search.metric is ${JSON.stringify(t.metric)} \u2014 it is ${F.map(o=>`'${o}'`).join(", ")}`),(!Number.isInteger(t.dimensions)||t.dimensions<1||t.dimensions>R)&&s.push(`${n}: search.dimensions is ${String(t.dimensions)} \u2014 it is 1 to ${R}: pgvector indexes a vector of at most ${X} dimensions and a half-precision one of at most ${R}; ask the model for fewer (search: { dimensions: ${A} })`),t.staleness!=="null"&&t.staleness!=="keep"&&s.push(`${n}: search.staleness is ${JSON.stringify(t.staleness)} \u2014 it is 'null' (a changed row is not found by its old meaning) or 'keep' (it is, until embedded again)`),e.columns.some(o=>o.name==="_score"&&!o.ignored)&&s.push(`${n} declares search and has a column "_score": search() answers each row with its _score \u2014 rename the column`),s}function de(n){let e=[],t=r=>r&&e.push(r),s=new Map,c=new Map,o=(r,a,u)=>{let f=`${r}.${a}`,d=c.get(f);d?e.push(`${u} "${a}" has the name of ${d} in schema ${r}`):c.set(f,u)};for(let r of n.enums)t(y("an enum",r.name)),r.values.length===0&&e.push(`enum ${r.schema}.${r.name} has no values`),new Set(r.values).size!==r.values.length&&e.push(`enum ${r.schema}.${r.name} names a value twice`);for(let r of n.tables){let a=b(r);t(y("a schema",r.schema)),t(y("a table",r.name)),s.has(a)&&e.push(`table ${a} is declared twice`),s.set(a,r),o(r.schema,r.name,`table ${a}`);let u=new Map,f=(i,m)=>{let k=u.get(i);k?e.push(`${m} "${i}" has the name of a ${k} of table ${a}`):u.set(i,m)},d=new Map;for(let i of r.columns)t(y(`column ${a}.${i.name}`,i.name)),d.has(i.name)&&e.push(`column ${a}.${i.name} is declared twice`),d.set(i.name,i),i.fill!==void 0&&i.nullable&&e.push(`column ${a}.${i.name}: fillWith is for a column that is NOT NULL`),i.identity&&i.default!==void 0&&e.push(`column ${a}.${i.name}: an identity column has no default`),i.generated&&(i.default!==void 0||i.identity||i.fill!==void 0)&&e.push(`column ${a}.${i.name}: a generated column has no default, identity or fill`),i.generated&&!i.generated.expr.trim()&&e.push(`column ${a}.${i.name}: a generated column's expression is empty`),i.identity&&!["smallint","integer","bigint"].includes(D(i.type))&&e.push(`column ${a}.${i.name}: an identity column is smallint, integer or bigint`),i.identity&&i.nullable&&e.push(`column ${a}.${i.name}: an identity column is NOT NULL`);let g=(i,m)=>{let k=d.get(i);k?k.ignored&&e.push(`${m} names column "${i}", which is ignored`):e.push(`${m} names column "${i}", which ${a} does not have`)};for(let i of r.primaryKey)g(i,`the primary key of ${a}`);for(let i of r.primaryKey)d.get(i)?.nullable&&e.push(`column ${a}.${i} is in the primary key, so it is not nullable`);for(let i of r.uniques){t(y(`a unique constraint of ${a}`,i.name,!0)),o(r.schema,i.name,`unique constraint ${a}.${i.name}`),f(i.name,"unique constraint"),i.columns.length===0&&e.push(`unique constraint ${i.name} names no column`);for(let m of i.columns)g(m,`unique constraint ${i.name}`)}for(let i of r.indexes){t(y(`an index of ${a}`,i.name,!0)),o(r.schema,i.name,`index ${a}.${i.name}`),i.keys.length===0&&e.push(`index ${i.name} has no key`);for(let m of i.keys)"column"in m&&g(m.column,`index ${i.name}`);for(let m of i.include??[])g(m,`index ${i.name}`)}for(let i of r.checks)t(y(`a check of ${a}`,i.name,!0)),f(i.name,"check"),i.expr.trim()||e.push(`check ${i.name} has no expression`);for(let i of r.foreignKeys){t(y(`a foreign key of ${a}`,i.name,!0)),f(i.name,"foreign key"),(i.columns.length===0||i.columns.length!==i.refColumns.length)&&e.push(`foreign key ${i.name} names ${i.columns.length} column(s) and references ${i.refColumns.length}`);for(let m of i.columns)g(m,`foreign key ${i.name}`)}let C=new Set;for(let i of r.policies)t(y(`a policy of ${a}`,i.name,!0)),C.has(i.name)&&e.push(`policy ${a}.${i.name} is declared twice`),C.add(i.name),i.to.length===0&&e.push(`policy ${a}.${i.name} names no role`),i.for==="insert"&&i.using!==void 0&&e.push(`policy ${a}.${i.name}: an insert policy has only withCheck`),(i.for==="select"||i.for==="delete")&&i.withCheck!==void 0&&e.push(`policy ${a}.${i.name}: a ${i.for} policy has only using`);r.policies.length>0&&!r.rls&&e.push(`table ${a} has policies but row-level security off: they would do nothing`),r.search!==void 0&&e.push(...q(`table ${a}`,r,r.search))}for(let r of n.tables)for(let a of r.foreignKeys){let u=s.get(`${a.refSchema}.${a.refTable}`);if(!u){e.push(`foreign key ${a.name} of ${b(r)} references ${a.refSchema}.${a.refTable}, which is not declared`);continue}u.ignored&&e.push(`foreign key ${a.name} of ${b(r)} references ${b(u)}, which is ignored`);for(let f of a.refColumns)u.columns.some(d=>d.name===f&&!d.ignored)||e.push(`foreign key ${a.name} references ${b(u)}.${f}, which it does not have`)}let l=new Set;for(let r of n.raw)t(y("a raw unit",r.name)),l.has(r.name)&&e.push(`raw unit ${r.name} is declared twice`),l.add(r.name),r.sql.trim()||e.push(`raw unit ${r.name} has no SQL`),r.before&&r.table!==void 0&&e.push(`raw unit ${r.name}: before is for a schema's unit, not a table's \u2014 a table's is made after its table`);return e}function j(n){let e=t=>[...t].sort((s,c)=>s.name<c.name?-1:s.name>c.name?1:0);return{tables:[...n.tables].map(t=>({...t,schema:t.schema||"public",columns:t.columns.map(s=>({...s,type:D(s.type)})),uniques:e(t.uniques),indexes:e(t.indexes),checks:e(t.checks),foreignKeys:e(t.foreignKeys),policies:e(t.policies).map(s=>({...s,to:[...s.to].sort()}))})).sort((t,s)=>b(t)<b(s)?-1:b(t)>b(s)?1:0),enums:[...n.enums].sort((t,s)=>`${t.schema}.${t.name}`<`${s.schema}.${s.name}`?-1:1),extensions:[...new Set([...n.extensions,...n.tables.some(t=>t.search!==void 0)?[G]:[]])].sort(),raw:e(n.raw)}}function me(n){let e=j(n),t=new Map(n.raw.map((s,c)=>[s.name,c]));return e.raw.sort((s,c)=>(t.get(s.name)??0)-(t.get(c.name)??0)),e}function O(n){return Array.isArray(n)?`[${n.map(O).join(",")}]`:n&&typeof n=="object"?`{${Object.entries(n).filter(([,t])=>t!==void 0).sort(([t],[s])=>t<s?-1:1).map(([t,s])=>`${JSON.stringify(t)}:${O(s)}`).join(",")}}`:JSON.stringify(n)}function pe(n){return z("sha256").update(O(j(n))).digest("hex").slice(0,32)}var M=Symbol.for("palbase.table.meta"),x=Symbol.for("palbase.ref.target"),S=class{_def;constructor(e){if(e.trim()==="")throw new Error("foreignKey(name): a foreign key's name cannot be empty \u2014 Palbase reconciles constraints by name.");this._def={name:e,columns:[],refTable:"",refColumns:[]}}on(...e){return this._def.columns=e.map(t=>{let s=t.expr;if(s.kind!=="col")throw new Error(`foreignKey(${this._def.name}).on(): takes column references only \u2014 an expression cannot be part of a foreign key.`);return s.name}),this}references(e,...t){if(t.length===0)throw new Error(`foreignKey(${this._def.name}).references(): needs at least one target column.`);return this._def.refColumns=[...t],typeof e=="function"?(Object.defineProperty(this._def,x,{value:()=>e()[M],enumerable:!1,configurable:!0}),this):(this._def.refTable=e[M].name,Object.defineProperty(this._def,x,{value:e[M],enumerable:!1,configurable:!0}),this)}onUpdate(e){return this._def.onUpdate=e,this}onDelete(e){return this._def.onDelete=e,this}match(e){return this._def.match=e,this}index(e){if(e!==!1)throw new Error(`foreignKey(${this._def.name}).index(): only index(false) \u2014 an index is made unasked`);return this._def.index=!1,this}};function V(n){return new S(n)}function B(n){let e=n instanceof S?n._def:n;if(e.columns.length===0)throw new Error(`foreignKey(${e.name}): needs at least one local column \u2014 call .on(...).`);let t=typeof e[x]=="function";if(e.refColumns.length===0||e.refTable===""&&!t)throw new Error(`foreignKey(${e.name}): needs the target table and its columns \u2014 call .references(...).`);if(e.columns.length!==e.refColumns.length)throw new Error(`foreignKey(${e.name}): ${e.columns.length} local column(s) (${e.columns.join(", ")}) but ${e.refColumns.length} target column(s) (${e.refColumns.join(", ")}) \u2014 the two lists must be the same length.`);return e}var h=class n{expr;constructor(e){this.expr=e}bin(e,t){return new n({kind:"binop",op:e,left:this.expr,right:ee(t)})}eq(e){return this.bin("eq",e)}neq(e){return this.bin("neq",e)}gt(e){return this.bin("gt",e)}gte(e){return this.bin("gte",e)}lt(e){return this.bin("lt",e)}lte(e){return this.bin("lte",e)}isNull(e=!1){return new n({kind:"isNull",expr:this.expr,negated:e})}and(...e){return new n({kind:"and",parts:[this.expr,...e.map(t=>t.expr)]})}or(...e){return new n({kind:"or",parts:[this.expr,...e.map(t=>t.expr)]})}not(){return new n({kind:"not",expr:this.expr})}};function ee(n){return n instanceof h?n.expr:{kind:"lit",value:n}}function E(n,e=0,t=""){let s=`pb_e${e}`;return{col:c=>new h(e===0?{kind:"col",name:c}:{kind:"col",name:c,alias:s}),auth:{uid:()=>new h({kind:"authUid"})},lit:c=>new h({kind:"lit",value:c}),and:(...c)=>new h({kind:"and",parts:c.map(o=>o.expr)}),or:(...c)=>new h({kind:"or",parts:c.map(o=>o.expr)}),not:c=>new h({kind:"not",expr:c.expr}),existsIn:(c,o)=>{let l=c[_],r=E(Object.keys(l.columns),e+1,t),a={kind:"exists",table:l.name,alias:`pb_e${e+1}`,outer:t,predicate:o(r).expr};return Object.defineProperty(a,x,{value:l,enumerable:!1,configurable:!0}),new h(a)}}}function p(n){return`"${n.replace(/"/g,'""')}"`}var P=class{_def;constructor(e){this._def={name:e,command:"all",roles:["authenticated"],using:null,withCheck:null,permissive:!0}}for(e){return this._def.command=e,this}to(...e){return this._def.roles=e,this}using(e){return this._def.using=e instanceof h?e.expr:e,this}memberOf(e,t,s={}){if(this._def.using!==null)throw new Error(`policy(${this._def.name}).memberOf(): this policy already has a using() expression. Write one or the other \u2014 memberOf IS the using expression.`);let c=s.column??"id",o=s.userColumn??"user_id";return this._def.using=`${p(c)} IN (SELECT ${p(t)} FROM ${p(e)} WHERE ${p(o)} = (select auth.uid()))`,this}withCheck(e){return this._def.withCheck=e instanceof h?e.expr:e,this}withoutIndexes(){return this._def.indexes=!1,this}as(e){return this._def.permissive=e==="permissive",this}};function xe(n){return new P(n)}function T(n,e){switch(n.kind){case"exists":throw new Error(`check(${e}): \`existsIn(...)\` is a subquery and PostgreSQL forbids subqueries in a CHECK constraint \u2014 express a cross-table rule as a composite FOREIGN KEY (foreignKeys), or as a guard.`);case"authUid":throw new Error(`check(${e}): \`auth.uid()\` renders as a subquery \`(SELECT auth.uid())\` and PostgreSQL forbids subqueries in a CHECK constraint \u2014 a caller-dependent rule belongs in an RLS policy, not a CHECK.`);case"binop":T(n.left,e),T(n.right,e);return;case"and":case"or":for(let t of n.parts)T(t,e);return;case"not":case"isNull":T(n.expr,e);return;default:return}}var ne={eq:"=",neq:"<>",gt:">",gte:">=",lt:"<",lte:"<="};function U(n){if(n===null)return"NULL";if(typeof n=="boolean")return n?"true":"false";if(typeof n=="number"){if(!Number.isFinite(n))throw new Error(`check(): ${n} is not an SQL number literal.`);return String(n)}return`'${n.replace(/'/g,"''")}'`}function w(n,e){switch(n.kind){case"col":return p(n.name);case"lit":return U(n.value);case"binop":{let t=ne[n.op];if(t===void 0)throw new Error(`check(${e}): \`${n.op}\` is not supported in a CHECK expression.`);return`(${w(n.left,e)} ${t} ${w(n.right,e)})`}case"and":case"or":{if(n.parts.length===0)return n.kind==="and"?"(true)":"(false)";let t=n.kind==="and"?" AND ":" OR ";return`(${n.parts.map(s=>w(s,e)).join(t)})`}case"not":return`(NOT ${w(n.expr,e)})`;case"isNull":return`(${w(n.expr,e)} IS ${n.negated?"NOT NULL":"NULL"})`;default:{let t=n.kind;throw new Error(`check(${e}): a \`${t}\` node is not one a CHECK expression takes.`)}}}function te(n,e){if(n.trim()==="")throw new Error("check(): the constraint's name cannot be empty \u2014 Palbase reconciles CHECKs by name.");return T(e.expr,n),{name:n,expr:w(e.expr,n)}}function $e(n){if(n!==null)return typeof n=="string"?n:$(n,"")}var re={eq:"=",neq:"<>",gt:">",gte:">=",lt:"<",lte:"<="};function H(n){let e=n.indexOf(".");return e<0?`${p("public")}.${p(n)}`:`${p(n.slice(0,e))}.${p(n.slice(e+1))}`}function $(n,e){switch(n.kind){case"col":return n.alias!==void 0?`${p(n.alias)}.${p(n.name)}`:e===""?p(n.name):`${H(e)}.${p(n.name)}`;case"authUid":return"(SELECT auth.uid())";case"lit":return U(n.value);case"binop":{let t=re[n.op];if(t===void 0)throw new Error(`policy expression: \`${n.op}\` is not an operator a policy can use`);return`(${$(n.left,e)} ${t} ${$(n.right,e)})`}case"and":case"or":return n.parts.length===0?n.kind==="and"?"(true)":"(false)":`(${n.parts.map(t=>$(t,e)).join(n.kind==="and"?" AND ":" OR ")})`;case"not":return`(NOT ${$(n.expr,e)})`;case"isNull":return`(${$(n.expr,e)} IS ${n.negated?"NOT NULL":"NULL"})`;case"exists":if(n.outer==="")throw new Error("policy expression: an existsIn carries no outer table \u2014 its correlation would collapse to x = x and filter nothing");return`EXISTS (SELECT 1 FROM ${H(n.table)} ${p(n.alias)} WHERE (${$(n.predicate,n.outer)}))`}}function v(n,e){return n===""||n==="public"?e:`${n}.${e}`}var K=class{_def;constructor(e){if(e.trim()==="")throw new Error("index(name): an index's name cannot be empty \u2014 Palbase reconciles indexes by name.");this._def={name:e}}unique(){return this._def.unique=!0,this}on(...e){return this._def.columns=e.map(t=>{let s=t.expr;if(s.kind!=="col")throw new Error(`index(${this._def.name}).on(): takes column references only \u2014 for an expression, use onExpression("\u2026").`);return s.name}),this}onExpression(e){return this._def.expression=e,this}where(e){return this._def.where=e.expr,this}desc(){return this._def.sort="desc",this}asc(){return this._def.sort="asc",this}nulls(e){return this._def.nulls=e,this}include(e){return this._def.include=e,this}};function Pe(n){return new K(n)}function ie(n){return n instanceof P?n._def:n}var _=Symbol.for("palbase.table.meta");function Se(n,e){if(n.trim()==="")throw new Error("defineTable(name, \u2026): name must not be empty");let t=(e.policies?.(E(Object.keys(e.columns),0,n))??[]).map(ie),s=t.length>0||e.rls!==!1,c={};for(let[f,d]of Object.entries(e.columns)){let g=d;ae(n,f,g._def);let C=Object.create(Object.getPrototypeOf(g));Object.defineProperty(C,"_def",{value:{...g._def},enumerable:!0,writable:!0}),c[f]=C}let o={name:n,columns:c,rls:s,policies:t};if(e.primaryKey!==void 0&&(o.primaryKey=[...e.primaryKey]),e.search!==void 0&&(o.search=se(n,e.search,c,o.primaryKey)),e.unique!==void 0&&(o.unique=e.unique.map(f=>({name:f.name,columns:[...f.columns]}))),e.raw!==void 0&&e.raw.length>0){for(let f of e.raw)if(f.drop!==void 0)throw new Error(`defineTable(${JSON.stringify(n)}): raw ${JSON.stringify(f.name)} carries a drop, but a table-level raw() has no teardown \u2014 a drop is run only for a schema-level unit: defineSchema(name, { tables, raw: [raw(name, up, { drop })] })`);o.raw=e.raw.slice()}let l=typeof e.checks=="function"?e.checks(E(Object.keys(e.columns),0,n)):e.checks?.slice()??[];l.length>0&&(o.checks=l);let r=(e.indexes?.(E(Object.keys(e.columns),0,n))??[]).map(f=>f instanceof K?f._def:f);r.length>0&&(o.indexes=r);let a=(e.foreignKeys?.(E(Object.keys(e.columns),0,n))??[]).map(B);a.length>0&&(o.foreignKeys=a),e.ignored===!0&&(o.ignored=!0);for(let f of Object.values(c))f._def.ownerTable=o;let u={...c};return Object.defineProperty(u,_,{value:o,enumerable:!1}),u}function se(n,e,t,s){if(e===null||typeof e!="object")throw new Error(`defineTable(${JSON.stringify(n)}): search is { from: [...columns], model } \u2014 got ${e===null?"null":typeof e}`);let c={from:Array.isArray(e.from)?[...e.from]:e.from,model:e.model,dimensions:e.dimensions??A,metric:e.metric??"cosine",staleness:e.staleness??"null"},o=Object.entries(t).map(([r,a])=>({name:r,def:a._def})),l=q(`defineTable(${JSON.stringify(n)})`,{columns:o.map(({name:r,def:a})=>({name:r,type:a.type==="sql"?a.sqlType??"sql":a.type,...a.ignored?{ignored:!0}:{},...a.generated?{generated:a.generated}:{}})),primaryKey:s??o.filter(({def:r})=>r.primaryKey===!0).map(({name:r})=>r)},c);if(l.length>0)throw new Error(l.join(`
|
|
5
|
-
`));return c}var I=new WeakMap;function oe(n,e){for(let t of Object.values(n))le(t,`table "${t.name}"`,e);for(let t of Object.values(n))for(let[s,c]of Object.entries(t.columns)){let o=c._def;if(o.selfRefColumn!==void 0){if(!(o.selfRefColumn in t.columns))throw new Error(`table "${t.name}" column "${s}": selfReferences("${o.selfRefColumn}") \u2014 no such column on this table`);o.references={table:v(e,t.name),column:o.selfRefColumn};continue}if(o.referencesThunk===void 0)continue;let l=o.referencesThunk(),r=l?._def?.ownerTable;if(r===void 0)throw new Error(`table "${t.name}" column "${s}": references(() => \u2026) must point at a column of a table declared with defineTable(...)`);let a=Object.entries(r.columns).find(([,f])=>f._def===l._def)?.[0];if(a===void 0)throw new Error(`table "${t.name}" column "${s}": the referenced column was not found on table "${r.name}"`);let u=I.get(r);if(u===void 0)throw new Error(`table "${t.name}" column "${s}": references(() => \u2026) points at table "${r.name}", which no defineSchema(...) has claimed yet \u2014 a foreign key cannot be written without its target's schema. Declare that table's schema first (one file per schema: db/public.ts, db/billing.ts \u2026, imported by this one).`);o.references={table:v(u,r.name),column:a}}}function ae(n,e,t){if(t.fill===void 0)return;let s=t.nullable===!0?"the column is .nullable() \u2014 .fillWith() fills a NOT NULL column; keep one of the two":t.ignored===!0?"the column is .ignored() \u2014 this release never writes it, so there is nothing to fill for it":t.defaultValue!==void 0||t.defaultRandom===!0||t.defaultNow===!0||t.defaultSql!==void 0?"the column has a default \u2014 the default already fills every row; keep one of the two":null;if(s!==null)throw new Error(`defineTable(${JSON.stringify(n)}): column "${e}" \u2014 .fillWith(): ${s}`)}function _e(n,e){if(typeof n!="string")throw new Error(`defineSchema(...) takes the schema NAME first: defineSchema("public", { tables: [todos, lists] }). The one-argument form defineSchema({ tables: { \u2026 } }) is gone \u2014 a schema that does not say its own name cannot be told apart from another schema's table of the same name, which is what a cross-schema foreign key has to do. Migrate db/public.ts (one file per schema: db/public.ts, db/billing.ts \u2026): name the schema, and lift each table key onto the table itself with defineTable("todos", { columns: { \u2026 } }), then list the tables in the array.`);if(n.trim()==="")throw new Error("defineSchema(name, \u2026): name must not be empty");let t={};for(let l of e.tables){let r=l[_];if(t[r.name]!==void 0)throw new Error(`defineSchema("${n}"): two tables declare the name "${r.name}" \u2014 table names must be unique within a schema`);t[r.name]=r,I.set(r,n)}oe(t,n);let s=[...new Set(e.extensions??[])],c=(e.raw??[]).slice(),o=new Set;for(let l of c){if(typeof l.name!="string"||l.name.trim()==="")throw new Error(`defineSchema("${n}"): a raw unit needs a name`);if(o.has(l.name))throw new Error(`defineSchema("${n}"): two raw units are named "${l.name}" \u2014 a unit's name identifies it`);o.add(l.name)}return{name:n,tables:t,extensions:s,exposed:e.exposed??n==="public",raw:c}}function le(n,e,t){let s=(l,r)=>{let a=l[x];if(a===void 0)return;let u;try{u=typeof a=="function"?a():a}catch(g){throw new Error(`${e}: ${r} names its target through a callback that failed: ${g.message}`)}if(u==null||typeof u.name!="string")throw new Error(`${e}: ${r}'s callback does not answer a table \u2014 write references(() => otherTable, \u2026)`);let f=I.get(u);if(f===void 0)throw new Error(`${e}: ${r} points at table "${u.name}", which no defineSchema(...) has claimed yet \u2014 a cross-table reference cannot be written without its target's schema. Declare that table's schema first (one file per schema: db/public.ts, db/billing.ts \u2026, imported by this one).`);let d=v(f,u.name);l.refTable!==void 0&&(l.refTable=d),l.table!==void 0&&(l.table=d)};for(let l of n.foreignKeys??[])s(l,`foreignKey("${l.name}")`);let c=`${t}.${n.name}`,o=(l,r)=>{if(!(l==null||typeof l=="string"))switch(l.kind){case"exists":s(l,r),l.table.includes(".")||(l.table=`public.${l.table}`),l.outer=c,o(l.predicate,r);return;case"binop":o(l.left,r),o(l.right,r);return;case"and":case"or":for(let a of l.parts)o(a,r);return;case"not":case"isNull":o(l.expr,r);return;default:return}};for(let l of n.policies)o(l.using,`policy("${l.name}")`),o(l.withCheck,`policy("${l.name}")`);for(let l of n.indexes??[])o(l.where,`index("${l.name}")`)}export{L as a,fe as b,b as c,D as d,ue as e,X as f,q as g,de as h,j as i,me as j,pe as k,S as l,V as m,v as n,K as o,Pe as p,_ as q,Se as r,_e as s,h as t,E as u,P as v,xe as w,te as x,$e as y};
|
package/dist/chunks/YYA7H4M5.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! palgres 0.7.0 — Palbase SDK License (see LICENSE) */
|
|
2
|
-
import{d as b,e as p,y as c}from"./4WIUQCVC.js";var g={uuid:"uuid",text:"text",integer:"integer",bigint:"bigint",numeric:"numeric",boolean:"boolean",timestamp:"timestamp with time zone",date:"date",jsonb:"jsonb"};function $(e){let n=Array.isArray(e)?e:[e],t={tables:[],enums:[],extensions:[],raw:[]},i=new Map;for(let l of n){for(let o of Object.values(l.tables))t.tables.push(E(l.name,o,i));t.extensions.push(...l.extensions);for(let o of l.raw??[])t.raw.push({name:o.name,schema:l.name,sql:o.up,...o.drop!==void 0?{drop:o.drop}:{},...o.before===!0?{before:!0}:{}})}t.enums=[...i.values()];for(let l of n)for(let o of Object.values(l.tables))for(let f of o.raw??[])t.raw.push({name:f.name,table:`${l.name}.${o.name}`,sql:f.up});return t}function T(e){return e._def}function E(e,n,t){let i=[],l=(n.unique??[]).map(r=>({name:r.name,columns:[...r.columns]})),o=[],f=[],s=new Set;for(let[r,y]of Object.entries(n.columns)){let u=T(y),m={name:r,type:K(e,r,n.name,u,t),nullable:u.nullable},h=D(u);if(h!==void 0&&(m.default=h),u.renamedFrom!==void 0&&(m.renamedFrom=u.renamedFrom),u.ignored&&(m.ignored=!0),u.fill!==void 0&&(m.fill=u.fill),u.identity!==void 0&&(m.identity=u.identity==="always"?"always":"by default"),u.generated!==void 0&&(m.generated={...u.generated}),u.user!==void 0&&(m.user={...u.user}),u.primaryKey&&f.push(r),u.unique&&l.push({name:`${n.name}_${r}_key`,columns:[r]}),u.references!==void 0){let[C,x]=w(u.references.table);o.push({name:`${q(e,n.name)}_${r}_fkey`,columns:[r],refSchema:C,refTable:x,refColumns:[u.references.column],onDelete:u.onDeleteAction??"no action",onUpdate:u.onUpdateAction??"no action"}),u.index===!1&&s.add(r)}i.push(m)}for(let r of n.foreignKeys??[]){r.index===!1&&r.columns.length===1&&s.add(r.columns[0]);let[y,u]=w(r.refTable);o.push({name:r.name,columns:[...r.columns],refSchema:y,refTable:u,refColumns:[...r.refColumns],onDelete:r.onDelete??"no action",onUpdate:r.onUpdate??"no action",...r.match==="full"?{match:"full"}:{}})}let a={schema:e,name:n.name,columns:i,primaryKey:n.primaryKey!==void 0?[...n.primaryKey]:f,uniques:l,indexes:(n.indexes??[]).map(N),checks:(n.checks??[]).map(r=>({name:r.name,expr:r.expr})),foreignKeys:o,rls:n.rls,policies:n.policies.map(P)};return n.ignored&&(a.ignored=!0),n.search!==void 0&&(a.search={...n.search,from:[...n.search.from]}),a.uniques=B(a.uniques),S(a,s,new Set((n.raw??[]).map(r=>r.name)),new Set(n.policies.filter(r=>r.indexes===!1).map(r=>r.name))),a}function K(e,n,t,i,l){let o=i.type;if(o==="enum"||o==="enum[]"){let f=i.enumName,s=`${e}.${f}`,a=i.enumValues??[],r=l.get(s);if(r&&r.values.join()!==a.join())throw new Error(`enum ${s} is declared with different values by ${t}.${n}: (${r.values.join(", ")}) and (${a.join(", ")}) \u2014 one type has one list`);return l.set(s,{schema:e,name:f,values:[...a]}),o==="enum[]"?`${p(e,f)}[]`:p(e,f)}return o==="sql"?b(i.sqlType):o==="numeric"&&i.precision!==void 0?`numeric(${i.precision},${i.scale??0})`:o.endsWith("[]")?`${g[o.slice(0,-2)]??o.slice(0,-2)}[]`:g[o]??o}function D(e){if(e.defaultSql!==void 0)return e.defaultSql;if(e.defaultRandom)return"gen_random_uuid()";if(e.defaultNow)return e.type==="date"?"CURRENT_DATE":"now()";let n=e.defaultValue;if(n!==void 0){if(Array.isArray(n)&&n.length===0&&e.type.endsWith("[]"))return"'{}'";if(typeof n=="string")return`'${n.replace(/'/g,"''")}'`;if(typeof n=="boolean")return n?"true":"false";if(typeof n=="number"){if(!Number.isFinite(n))throw new Error(`default ${n} is not a number Postgres can store`);return String(n)}return n===null?"NULL":`'${JSON.stringify(n).replace(/'/g,"''")}'::jsonb`}}function N(e){let n=e.expression!==void 0?[{expr:e.expression}]:(e.columns??[]).map(l=>({column:l}));for(let l of n)e.sort==="desc"&&(l.desc=!0),e.nulls!==void 0&&(l.nulls=e.nulls);let t={name:e.name,keys:n,unique:e.unique===!0},i=e.where===void 0?void 0:c(e.where);return i!==void 0&&(t.where=i),e.include?.length&&(t.include=[...e.include]),t}function P(e){let n={name:e.name,for:e.command,to:e.roles.length===0?["public"]:[...e.roles]},t=c(e.using),i=c(e.withCheck);return t!==void 0&&(n.using=t),i!==void 0&&(n.withCheck=i),e.permissive||(n.restrictive=!0),n}function S(e,n,t,i){let l=new Set,o=s=>s[0]!==void 0&&l.add(s[0]);o(e.primaryKey);for(let s of e.uniques)o(s.columns);for(let s of e.indexes){let a=s.keys[0];a&&"column"in a&&s.where===void 0&&l.add(a.column)}let f=s=>{if(l.has(s)||e.columns.find(r=>r.name===s)?.ignored)return;let a=`${e.name}_${s}_idx`;Buffer.byteLength(a)>63||e.indexes.some(r=>r.name===a)||t.has(a)||(e.indexes.push({name:a,keys:[{column:s}],unique:!1}),l.add(s))};for(let s of e.foreignKeys)s.columns.length===1&&!n.has(s.columns[0])&&f(s.columns[0]);for(let s of e.policies)if(!i.has(s.name))for(let a of A(e,s))f(a)}function A(e,n){let t=[];for(let i of[n.using,n.withCheck])if(i!==void 0)for(let l of i.matchAll(/(?<![.\w"])"((?:[^"]|"")+)"(?!\s*\.)/g)){let o=l[1].replace(/""/g,'"');e.columns.some(f=>f.name===o)&&!t.includes(o)&&t.push(o)}return t}function w(e){let n=e.indexOf(".");return n<0?["public",e]:[e.slice(0,n),e.slice(n+1)]}function q(e,n){return e==="public"?n:`${e}_${n}`}function B(e){let n=new Map;return e.filter(t=>{let i=n.get(t.name);if(i===void 0)return n.set(t.name,t),!0;if(i.columns.join()!==t.columns.join())throw new Error(`palgres: unique ${t.name} is declared over (${i.columns.join(", ")}) and over (${t.columns.join(", ")}): give one of them another name`);return!1})}var _=new Set(["uuid","text","integer","bigint","numeric","boolean","timestamp","date","enum"]),O={number:{fromDb:e=>e==null?e:Number(e),toDb:e=>{if(e==null||typeof e!="number")return e==null?e:String(e);if(!Number.isFinite(e))throw new Error(`asNumber() cannot write ${e}: it is not a finite number, and the column holds one.`);if(Number.isInteger(e)&&!Number.isSafeInteger(e))throw new Error(`asNumber() cannot write ${e}: it is outside the safe integer range and would be stored as a different number. Declare .asDecimal() and hand this column a string.`);return String(e)},tsType:"number"},decimal:{fromDb:e=>e==null?e:String(e),toDb:e=>e==null?e:String(e),tsType:"string"}},d=class e{_def;constructor(n,t){this._def=t??{type:n,nullable:!1,primaryKey:!1}}primaryKey(){return this._def.primaryKey=!0,new e(this._def.type,this._def)}notNull(){return this._def.nullable=!1,new e(this._def.type,this._def)}nullable(){if(this._def.identity!==void 0)throw new Error(".nullable() on an identity column: an identity is always NOT NULL");return this._def.nullable=!0,new e(this._def.type,this._def)}default(n){return this._def.defaultValue=n,new e(this._def.type,this._def)}defaultRandom(){return this._def.defaultRandom=!0,new e(this._def.type,this._def)}defaultNow(){return this._def.defaultNow=!0,new e(this._def.type,this._def)}defaultSql(n){if(typeof n!="string"||n.trim()==="")throw new Error("defaultSql() takes the SQL of the default");return this._def.defaultSql=n,new e(this._def.type,this._def)}dbAssigned(){return this._def.dbAssigned=!0,new e(this._def.type,this._def)}array(){let n=this._def.type;if(!_.has(n))throw new Error(`${n} column: .array() is available on uuid(), text(), integer(), bigint(), numeric(), boolean(), timestamp(), date() and enumType()`);if(this._def.defaultValue!==void 0||this._def.defaultNow||this._def.defaultRandom||this._def.defaultSql!==void 0)throw new Error(`.array() comes before the default \u2014 write ${n}().array().default([])`);if(this._def.codec!==void 0||this._def.transform!==void 0)throw new Error(".array() cannot follow a codec or a transform \u2014 they convert one value, not a list of them");let t=`${n}[]`;return new e(t,{...this._def,type:t})}identity(n){if(this._def.type!=="integer"&&this._def.type!=="bigint"&&!(this._def.type==="sql"&&this._def.sqlType==="smallint"))throw new Error(`${this._def.type} column: .identity() is for integer(), bigint() and sqlType('smallint') columns`);if(this._def.defaultValue!==void 0||this._def.defaultNow||this._def.defaultRandom||this._def.defaultSql!==void 0||this._def.fill!==void 0)throw new Error(".identity() is the column's value \u2014 it cannot also have a default or a fill");let t=n?.always===!1?"byDefault":"always";return new e(this._def.type,{...this._def,nullable:!1,identity:t})}generated(n,t={}){if(typeof n!="string"||n.trim()==="")throw new Error(".generated() takes the SQL expression the column is");if(this._def.defaultValue!==void 0||this._def.defaultNow||this._def.defaultRandom||this._def.defaultSql!==void 0||this._def.fill!==void 0||this._def.identity!==void 0)throw new Error(".generated() is the column's value \u2014 it cannot also have a default, a fill or an identity");return new e(this._def.type,{...this._def,generated:{expr:n,stored:t.stored===!0}})}fillWith(n){return new e(this._def.type,{...this._def,fill:n})}renamedFrom(n){return this._def.renamedFrom=n,this}ignored(){return new e(this._def.type,{...this._def,ignored:!0})}references(n,t){if(typeof n!="function")throw new Error('references(...) takes a callback: write references(() => otherTable.column). The two-string form references("table", "column") is gone \u2014 a string cannot be type-checked and cannot point at a table that does not exist yet.');return this._def.referencesThunk=n,t?.as!==void 0&&(this._def.refAs=t.as),t?.reverseAs!==void 0&&(this._def.reverseAs=t.reverseAs),t?.onDelete!==void 0&&(this._def.onDeleteAction=t.onDelete),t?.onUpdate!==void 0&&(this._def.onUpdateAction=t.onUpdate),t?.index===!1&&(this._def.index=!1),new e(this._def.type,this._def)}selfReferences(n,t){return this._def.selfRefColumn=n,t?.as!==void 0&&(this._def.refAs=t.as),t?.onDelete!==void 0&&(this._def.onDeleteAction=t.onDelete),new e(this._def.type,this._def)}onDelete(n){return this._def.onDeleteAction=n,new e(this._def.type,this._def)}unique(){return this._def.unique=!0,new e(this._def.type,this._def)}asNumber(){return this.withCodec("number","asNumber")}asDecimal(){return this.withCodec("decimal","asDecimal")}withCodec(n,t){if(this._def.type!=="bigint"&&this._def.type!=="numeric")throw new Error(`${this._def.type} column: .${t}() is only available on bigint()/numeric() \u2014 those are the exact-precision types that surface as string.`);if(this._def.transform!==void 0)throw new Error(`.${t}() and .transform() are two ways to say the same thing on one column \u2014 keep .${t}().`);if(this._def.codec!==void 0)throw new Error(`column already declares .as${this._def.codec==="number"?"Number":"Decimal"}(); a column has ONE codec.`);return new e(this._def.type,{...this._def,codec:n})}transform(n){if(this._def.codec!==void 0)throw new Error("column already declares a named codec; .transform() and .as*() are two ways to say the same thing \u2014 keep the codec.");return new e(this._def.type,{...this._def,transform:n})}};function R(){return new d("uuid")}function U(){return new d("text")}function V(){return new d("integer")}function j(){return new d("bigint")}function L(e){if(e===void 0)return new d("numeric");let{precision:n,scale:t=0}=e;if(!Number.isInteger(n)||n<1||n>1e3)throw new Error(`numeric({ precision: ${n} }): precision is a whole number from 1 to 1000`);if(!Number.isInteger(t)||t<0||t>n)throw new Error(`numeric({ precision: ${n}, scale: ${t} }): scale is a whole number from 0 to the precision`);return new d("numeric",{type:"numeric",nullable:!1,primaryKey:!1,precision:n,scale:t})}function F(){return new d("date")}var Q={uuid:"uuid()",text:"text()",integer:"integer()",int:"integer()",int4:"integer()",bigint:"bigint()",int8:"bigint()",numeric:"numeric()",decimal:"numeric()",boolean:"boolean()",bool:"boolean()",timestamptz:"timestamp()","timestamp with time zone":"timestamp()",date:"date()",jsonb:"jsonb()"};function I(e){let n=typeof e=="string"?e.trim():"";if(n==="")throw new Error('sqlType() takes the Postgres type, e.g. sqlType("inet")');let t=n.toLowerCase().replace(/\[\]$/,""),i=Q[t];if(i!==void 0&&!(n.endsWith("[]")&&!_.has(i.slice(0,-2))))throw new Error(`sqlType(${JSON.stringify(n)}): the DSL has this type \u2014 declare it as ${i}${n.endsWith("[]")?".array()":""}`);return new d("sql",{type:"sql",nullable:!1,primaryKey:!1,sqlType:n})}var M=new Set(["smallint","real","double precision"]),Y=new Set(["json"]);function H(){return new d("boolean")}function z(){return new d("timestamp")}function J(){return new d("jsonb")}function G(e,n){let t=new d("enum");return t._def.enumName=e,t._def.enumValues=[...n],t}function X(){let e=new d("text");return e._def.nullable=!1,e._def.user={onDelete:"cascade",owns:!0},e}function Z(e){let n=new d("text");return n._def.user={onDelete:e.onDelete,owns:!1},e.as!==void 0&&(n._def.refAs=e.as),n}export{$ as a,A as b,O as c,d,R as e,U as f,V as g,j as h,L as i,F as j,I as k,M as l,Y as m,H as n,z as o,J as p,G as q,X as r,Z as s};
|