@lunora/seed 1.0.0-alpha.103 → 1.0.0-alpha.105

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/index.mjs CHANGED
@@ -1 +1 @@
1
- import{createSeedClient as o}from"./packem_shared/createSeedClient-DODhDlgB.mjs";import{s as a}from"./packem_shared/plan-CZy5Xjiw.mjs";export{o as createSeedClient,a as seedPlan};
1
+ import{createSeedClient as o}from"./packem_shared/createSeedClient-B6_37xlU.mjs";import{s as a}from"./packem_shared/plan-DfieuDm9.mjs";export{o as createSeedClient,a as seedPlan};
@@ -1 +1 @@
1
- import{a as $,s as C,c as P}from"./plan-CZy5Xjiw.mjs";const T=e=>Array.isArray(e)&&e.length===2&&typeof e[0]=="number"&&typeof e[1]=="number",A=(e,u,l,i)=>{const o=n=>typeof n=="number"?n:P.int([l,u,"count"],{max:n[1],min:n[0]});return e===void 0?{count:i}:typeof e=="number"?{count:e}:typeof e=="function"?{count:e(o)}:T(e)?{count:o(e)}:{count:e.length,partials:e}},q=(e,u,l)=>{const i={};if(e!==void 0){const o=new Set(e.flatMap(n=>Object.keys(n)));for(const n of o)i[n]=f=>e[f.index-l]?.[n]}for(const[o,n]of Object.entries(u??{}))i[o]=n;return i},H=(e,u={})=>{const{defaultCount:l=10,now:i,persist:o,seed:n=0}=u,f={},c={},a={},w=async(t,s,y)=>{$(n);const{count:d,partials:b}=A(s,t,n,l),m=a[t]??0,g=C(e,{counts:{[t]:d},existingIds:c,indexOffset:{[t]:m},now:i,only:[t],overrides:{[t]:q(b,y?.overrides,m)},seed:n});let k=[];for(const{rows:v,table:r}of g){const j=v.map(S=>S._id);f[r]??=[],f[r].push(...v),c[r]??=[],c[r].push(...j),a[r]=(a[r]??0)+v.length,r===t&&(k=j),o!==void 0&&await o(r,v)}return{[t]:k}};let h=Promise.resolve();const x=(t,s,y)=>{const d=h.then(()=>w(t,s,y));return h=d.then(()=>{},()=>{}),d},O={$ids:c,$reset:()=>{for(const t of Object.keys(f))delete f[t];for(const t of Object.keys(c))delete c[t];for(const t of Object.keys(a))delete a[t]},$store:f};return new Proxy(O,{get(t,s,y){return typeof s=="string"&&!s.startsWith("$")&&Object.hasOwn(e.tables,s)?(d,b)=>x(s,d,b):Reflect.get(t,s,y)}})};export{H as createSeedClient};
1
+ import{a as $,s as C,c as P}from"./plan-DfieuDm9.mjs";const T=e=>Array.isArray(e)&&e.length===2&&typeof e[0]=="number"&&typeof e[1]=="number",A=(e,u,l,i)=>{const o=n=>typeof n=="number"?n:P.int([l,u,"count"],{max:n[1],min:n[0]});return e===void 0?{count:i}:typeof e=="number"?{count:e}:typeof e=="function"?{count:e(o)}:T(e)?{count:o(e)}:{count:e.length,partials:e}},q=(e,u,l)=>{const i={};if(e!==void 0){const o=new Set(e.flatMap(n=>Object.keys(n)));for(const n of o)i[n]=f=>e[f.index-l]?.[n]}for(const[o,n]of Object.entries(u??{}))i[o]=n;return i},H=(e,u={})=>{const{defaultCount:l=10,now:i,persist:o,seed:n=0}=u,f={},c={},a={},w=async(t,s,y)=>{$(n);const{count:d,partials:b}=A(s,t,n,l),m=a[t]??0,g=C(e,{counts:{[t]:d},existingIds:c,indexOffset:{[t]:m},now:i,only:[t],overrides:{[t]:q(b,y?.overrides,m)},seed:n});let k=[];for(const{rows:v,table:r}of g){const j=v.map(S=>S._id);f[r]??=[],f[r].push(...v),c[r]??=[],c[r].push(...j),a[r]=(a[r]??0)+v.length,r===t&&(k=j),o!==void 0&&await o(r,v)}return{[t]:k}};let h=Promise.resolve();const x=(t,s,y)=>{const d=h.then(()=>w(t,s,y));return h=d.then(()=>{},()=>{}),d},O={$ids:c,$reset:()=>{for(const t of Object.keys(f))delete f[t];for(const t of Object.keys(c))delete c[t];for(const t of Object.keys(a))delete a[t]},$store:f};return new Proxy(O,{get(t,s,y){return typeof s=="string"&&!s.startsWith("$")&&Object.hasOwn(e.tables,s)?(d,b)=>x(s,d,b):Reflect.get(t,s,y)}})};export{H as createSeedClient};
@@ -0,0 +1 @@
1
+ import{LunoraError as y}from"@lunora/errors";import{faker as h}from"@faker-js/faker";import{optionalInner as K}from"@lunora/values";let O=0;const me=(e,n)=>e<n?-1:e>n?1:0,R=e=>e===void 0?"undefined":typeof e=="bigint"?`${e.toString()}n`:e===null||typeof e!="object"?JSON.stringify(e)??"null":Array.isArray(e)?`[${e.map(t=>R(t)).join(",")}]`:`{${Object.keys(e).toSorted(me).map(t=>`${JSON.stringify(t)}:${R(e[t])}`).join(",")}}`,Z=(e,n)=>{let t=3735928559^n,r=1103547991^n;for(let o=0;o<e.length;o+=1){const a=e.codePointAt(o)??0;t=Math.imul(t^a,2654435761),r=Math.imul(r^a,1597334677)}return t=Math.imul(t^t>>>16,2246822507),t^=Math.imul(r^r>>>13,3266489909),r=Math.imul(r^r>>>16,2246822507),r^=Math.imul(t^t>>>13,3266489909),4294967296*(2097151&r)+(t>>>0)},de="\0",he=e=>{const n=typeof e=="string"?de+e:R(e);return Z(n,O)%4294967296},fe=e=>{if(typeof e=="number"){O=e>>>0;return}if(typeof e=="string"){O=Z(e,0)%4294967296;return}let n=0;for(const t of e)n=Math.imul(n^t,2654435761)>>>0;O=n},f=(e,n)=>(h.seed(he(e)),n()),ge=(e,n)=>{if(typeof n=="number")return n;const[t,r]=n;return f(["__count__",e],()=>h.number.int({max:r,min:t}))},ve=/[a-z]/,pe=/[A-Z]/,we=/\d/,u={bool(e){return f(e,()=>h.datatype.boolean())},city(e){return f(e,()=>h.location.city())},country(e){return f(e,()=>h.location.country())},email(e){return f(e,()=>h.internet.email().toLowerCase())},firstName(e){return f(e,()=>h.person.firstName())},float(e,n){const{fractionDigits:t=2,max:r=1e3,min:o=0}=n??{};return f(e,()=>h.number.float({fractionDigits:t,max:r,min:o}))},fullName(e){return f(e,()=>h.person.fullName())},int(e,n){const{max:t=1e3,min:r=0}=n??{};return f(e,()=>h.number.int({max:t,min:r}))},lastName(e){return f(e,()=>h.person.lastName())},oneOf(e,n){if(n.length!==0)return f(e,()=>h.helpers.arrayElement(n))},paragraph(e){return f(e,()=>h.lorem.paragraph())},password(e){return f(e,()=>h.internet.password())},phoneNumber(e){return f(e,()=>h.phone.number())},scramble(e,n){const t=new Set(n?.preserve);return Array.from({length:e.length},(r,o)=>{const a=e.charAt(o);return t.has(a)?a:ve.test(a)?f([e,o,"l"],()=>h.string.alpha({casing:"lower",length:1})):pe.test(a)?f([e,o,"u"],()=>h.string.alpha({casing:"upper",length:1})):we.test(a)?f([e,o,"d"],()=>String(h.number.int({max:9,min:0}))):a}).join("")},sentence(e,n){return f(e,()=>h.lorem.sentence(n?{max:n.max??8,min:n.min??3}:void 0))},slug(e){return f(e,()=>h.lorem.slug())},streetAddress(e){return f(e,()=>h.location.streetAddress())},times(e,n,t){const r=ge(e,n),o=[];for(let a=0;a<r;a+=1)o.push(t([e,a]));return o},url(e){return f(e,()=>h.internet.url())},username(e){return f(e,()=>h.internet.username())},uuid(e){return f(e,()=>h.string.uuid())},word(e){return f(e,()=>h.lorem.word())}},v=e=>e._meta??{},X=e=>K(e)??e,ee=e=>{const{column:n}=v(e);if(n?.defaultValue!==void 0||n?.defaultFn!==void 0)return!0;const t=K(e);return t===void 0?!1:ee(t)},be=(e,n)=>{const t=X(n),r=v(t);return{fkTable:t.kind==="id"?r.tableName:void 0,hasServerDefault:ee(n),kind:t.kind,name:e,nullable:r.column?.notNull===!1,optional:n.kind==="optional",unique:r.column?.unique===!0,validator:t}},ye=e=>{const{tables:n}=e;return Object.entries(n).map(([t,r])=>({fields:Object.entries(r.shape).map(([o,a])=>be(o,a)),name:t}))},Se=(e,n)=>{const t=new Map(e.map(s=>[s.name,s])),r=s=>{const c=t.get(s);if(c===void 0)return new Set;const l=new Set;for(const d of c.fields)d.fkTable!==void 0&&d.fkTable!==s&&n.has(d.fkTable)&&l.add(d.fkTable);return l},o=[],a=new Set,i=[...n].filter(s=>t.has(s));for(;i.length>0;){const s=i.findIndex(d=>[...r(d)].every(g=>a.has(g))),c=s===-1?0:s,[l]=i.splice(c,1);if(l===void 0)break;o.push(l),a.add(l)}return o},Ae=(e,n,t=new Set)=>{const r=new Map(e.map(i=>[i.name,i])),o=new Set(n),a=[...o];for(;a.length>0;){const i=a.pop();if(i===void 0)break;const s=r.get(i);if(s!==void 0&&!t.has(i))for(const c of s.fields)c.fkTable!==void 0&&c.fkTable!==i&&r.has(c.fkTable)&&!o.has(c.fkTable)&&(o.add(c.fkTable),a.push(c.fkTable))}return o},ne=e=>v(e).constraints??{},Te=[{generate:e=>u.email(e),keywords:["email"]},{generate:e=>u.firstName(e),keywords:["firstname"]},{generate:e=>u.lastName(e),keywords:["lastname","surname"]},{generate:e=>u.username(e),keywords:["username"]},{generate:e=>u.fullName(e),keywords:["name"]},{generate:e=>u.sentence(e,{max:5,min:2}),keywords:["title"]},{generate:e=>u.url(e),keywords:["url","link","image","avatar"]},{generate:e=>u.phoneNumber(e),keywords:["phone"]},{generate:e=>u.paragraph(e),keywords:["description","bio","body","content","text"]},{generate:e=>u.slug(e),keywords:["slug","key","code"]},{generate:e=>u.city(e),keywords:["city"]},{generate:e=>u.country(e),keywords:["country"]},{generate:e=>u.streetAddress(e),keywords:["address","street"]},{generate:e=>u.password(e),keywords:["password","secret","token"]}],xe=new Set(["at","date","deadline","expires","expiry","since","timestamp","until"]),Ie=/([a-z\d])([A-Z])/gu,ke=/[\s_-]+/u,$e=e=>e.replaceAll(Ie,"$1 $2").split(ke).filter(n=>n!=="").map(n=>n.toLowerCase()),te={max:1e3,min:0},re={max:1e6,min:0},Oe=4320*60*60*1e3,P=(e,n,t)=>{const{maximum:r,minimum:o}=e;if(r!==void 0&&o!==void 0&&o>r)throw new y("INTERNAL",`Seed constraint error for field "${t}": minimum (${String(o)}) > maximum (${String(r)}). Adjust the schema constraints.`);const a=n.max-n.min;return{max:r??(o!==void 0&&o>n.max?o+a:n.max),min:o??(r!==void 0&&r<n.min?r-a:n.min)}},oe=e=>{const t=$e(e).at(-1);return t!==void 0&&xe.has(t)},G=(e,n)=>n-u.int(e,{max:Oe,min:0}),N=(e,n)=>{throw new y("INTERNAL",`@lunora/seed: column "${e}" ${n}. Supply a value via \`overrides\` (\`{ <table>: { ${e}: … } }\`) or restrict the run with \`only\` so the table is skipped.`)},q=(e,n)=>{const t=e===""?"x":e,r=Math.min(Math.max(t.length,n.min),n.max);return t.padEnd(r,t).slice(0,r)},x="@example.com",_="https://",Ne=/[\s@]/gu,_e=/[^a-z\d]/gu,Ee=(e,n)=>{const t=e.lastIndexOf("@"),r=t>0?e.slice(t):"",o=r.length>0&&r.length<n.max?r:x,a=(t>0?e.slice(0,t):e).replaceAll(Ne,"");return`${q(a,{max:n.max-o.length,min:Math.max(1,n.min-o.length)})}${o}`},Me=(e,n)=>{const t=URL.canParse(e)?new URL(e).hostname.replaceAll(_e,""):"";return`${_}${q(t,{max:n.max-_.length,min:Math.max(1,n.min-_.length)})}`},De={email:{fit:Ee,generate:e=>u.email(e),minimum:x.length+1},uri:{fit:Me,generate:e=>u.url(e),minimum:_.length+1}},Le=(e,n)=>{const t=e.toLowerCase(),r=Te.find(o=>o.keywords.some(a=>t.includes(a)));return r===void 0?u.word(n):r.generate(n)},Re=(e,n,t)=>{const{format:r,maxLength:o,minLength:a,pattern:i}=t;if(i!==void 0)return N(e,`is constrained to the pattern /${i}/, and the seeder cannot invent a value matching an arbitrary regular expression`);if(o!==void 0&&a!==void 0&&a>o)throw new y("INTERNAL",`Seed constraint error for field "${e}": minLength (${String(a)}) > maxLength (${String(o)}). Adjust the schema constraints.`);const s={max:o??Number.POSITIVE_INFINITY,min:a??0};if(r===void 0)return q(Le(e,n),s);const c=De[r];if(c===void 0)return N(e,`declares format "${r}", which the seeder has no generator for`);if(s.max<c.minimum)return N(e,`declares format "${r}" with maxLength ${String(o)}, and the shortest ${r} value the seeder can build is ${String(c.minimum)} characters`);const l=c.generate(n);return l.length>=s.min&&l.length<=s.max?l:c.fit(l,s)},b=(e,n,t,r)=>{const o=X(e),a=ne(o);if(a.enum!==void 0&&a.enum.length>0)return u.oneOf(t,a.enum);switch(o.kind){case"any":return u.word(t);case"array":{const i=v(o).inner;return i===void 0?[]:u.times(t,[1,3],s=>b(i,n,s,r))}case"bigint":return u.int(t,P(a,re,n));case"boolean":return u.bool(t);case"bytes":return Array.from({length:8},(i,s)=>u.int([t,s],{max:255,min:0}));case"date":case"timestamp":return G(t,r);case"from":return N(n,"is a v.from() validator, whose external Standard Schema the seeder cannot introspect to invent a conforming value (give the column a concrete v.* type instead)");case"id":return u.uuid(t);case"literal":return v(o).value;case"null":return null;case"number":{if(a.maximum===void 0&&a.minimum===void 0&&oe(n))return G(t,r);const{max:i,min:s}=P(a,te,n);return!Number.isInteger(s)||!Number.isInteger(i)?u.float(t,{max:i,min:s}):u.int(t,{max:i,min:s})}case"object":{const i=v(o).shape??{};return Object.fromEntries(Object.entries(i).map(([s,c])=>[s,b(c,s,[t,s],r)]))}case"record":{const{keyValidator:i,valueValidator:s}=v(o),c=u.times(t,[1,3],l=>{const d=i===void 0?u.word(["k",l]):String(b(i,n,["k",l],r)),g=s===void 0?u.word(["v",l]):b(s,n,["v",l],r);return[d,g]});return Object.fromEntries(c)}case"storage":return`seed/${u.uuid(t)}`;case"string":return Re(n,t,a);case"union":{const i=v(o).members??[],s=u.oneOf(t,i);return s===void 0?u.word(t):b(s,n,[t,"u"],r)}default:return u.word(t)}},L=1e6,Pe=6e4,qe=2**32,je=(e,n,t)=>{const r=[...e];for(let o=r.length-1;o>0;o-=1){const a=u.int([n,t,"unique-deal",o],{max:o,min:0}),i=r[o];r[o]=r[a],r[a]=i}return r},Ce=(e,n,t)=>{const{maxLength:r}=t,o=String(n),a=e.indexOf("@");if(a>0){const c=e.slice(0,a),l=e.slice(a),d=r===void 0?c.length:r-l.length-o.length-1;if(d>=0)return`${c.slice(0,d)}+${o}${l}`}if(t.format==="email"){const c=r===void 0?e.length:Math.max(0,r-x.length-o.length);return`${e.slice(0,c)}${o}${x}`}const i=`-${o}`,s=r===void 0?e.length:Math.max(0,r-i.length);return`${e.slice(0,s)}${i}`},E=(e,n,t)=>{const r=je(e,n,t);return{capacity:r.length,valueAt:o=>r[o%r.length]}},Ue=(e,n)=>{if(Number.isInteger(e)&&Number.isInteger(n)){const t=n-e+1;return{capacity:t,valueAt:r=>e+r%t}}return{capacity:L,valueAt:t=>e+t%L*(n-e)/L}},H=e=>({capacity:Number.POSITIVE_INFINITY,valueAt:n=>e-n*Pe}),Fe={capacity:Number.POSITIVE_INFINITY,valueAt:e=>e},W={capacity:Number.POSITIVE_INFINITY,valueAt:(e,n)=>n()},z=(e,n,t)=>{if(e.maximum===void 0&&e.minimum===void 0)return Fe;const{max:r,min:o}=P(e,n,t);return Ue(o,r)},Q=(e,n,t)=>{throw new y("INTERNAL",`@lunora/seed: cannot generate unique values for "${e}"."${n}" — ${t}. Supply them via \`overrides\` (\`{ ${e}: { ${n}: … } }\`) or drop \`.unique()\` from the column.`)},Be=({format:e,maxLength:n})=>{if(n===void 0)return Number.POSITIVE_INFINITY;const t=e==="email"?x.length:1;return n<=t?0:10**(n-t)},Ve=(e,n,t)=>(e.pattern!==void 0&&Q(n,t,"the column is pattern-constrained, and an index-tagged value would no longer match it"),e.format!==void 0&&e.format!=="email"&&Q(n,t,`the column declares format "${e.format}", which an index-tagged value would no longer satisfy`),{capacity:Be(e),valueAt:(r,o)=>Ce(String(o()),r,e)}),Ye=(e,n,t)=>E(e,n,t),Ge=(e,n)=>{const{now:t,table:r}=n,o=ne(e.validator),a=o.enum;if(Array.isArray(a)&&a.length>0)return E(a,r,e.name);switch(e.kind){case"any":case"string":return Ve(o,r,e.name);case"bigint":return z(o,re,e.name);case"boolean":return E([!1,!0],r,e.name);case"bytes":return{capacity:qe,valueAt:i=>[Math.floor(i/16777216)%256,Math.floor(i/65536)%256,Math.floor(i/256)%256,i%256,...Array.from({length:4},(s,c)=>u.int([r,e.name,"unique-bytes",c],{max:255,min:0}))]};case"date":case"timestamp":return H(t);case"literal":return{capacity:1,valueAt:()=>v(e.validator).value};case"number":return o.maximum===void 0&&o.minimum===void 0&&oe(e.name)?H(t):z(o,te,e.name);case"union":{const i=v(e.validator).members??[],s=i.filter(c=>c.kind==="literal").map(c=>v(c).value);return s.length>0&&s.length===i.length?E(s,r,e.name):W}default:return W}},He=(e,n)=>typeof e=="function"?e(n):e,We=(e,n)=>{if(!e.optional)return e.nullable?null:u.uuid(n)},ae=(e,n,t,r,o)=>{const a=e.fkTable,i=a===n?(r.get(n)??[]).slice(0,t):r.get(a)??[],s=o[a]??[];return s.length===0?i:[...i,...s]},ze=(e,n,t,r)=>{const o=[...r[e]??[],...(t.get(e)??[]).slice(0,n)];return o[n]??o.at(-1)},J=(e,n,t,r)=>[e,n,t,r],Qe=(e,n)=>{const{existingIds:t,idsByTable:r,index:o,input:a,localIndex:i,now:s,table:c,uniqueDeals:l}=n;if(e.fkTable!==void 0){const g=ae(e,c,i,r,t);if(g.length===0)return We(e,a);if(!e.unique)return u.oneOf(a,g);const I=l.get(e.name);return I===void 0?ze(c,i,r,t):I.valueAt(o,()=>u.oneOf(a,g))}if(e.hasServerDefault)return;const d=e.unique?l.get(e.name):void 0;return d!==void 0?d.valueAt(o,()=>b(e.validator,e.name,a,s)):b(e.validator,e.name,a,s)},Je=(e,n,t,r)=>{if(!(t(e).length===0||Object.hasOwn(r,e.name)))throw new y("BAD_REQUEST",`cannot seed into the non-empty table "${n}": unique self-referencing column "${e.name}" cannot be dealt across calls, because the values already stored in it are not knowable from the row ids. Seed the table in one call, or supply "${e.name}" yourself.`)},Ke=(e,n,t,r,o,a,i)=>{const s=new Map;for(const c of e){if(!c.unique||c.hasServerDefault&&c.fkTable===void 0)continue;if(c.fkTable===n){Je(c,n,i,a);continue}const l=c.fkTable===void 0?void 0:i(c);if(l?.length===0)continue;const d=l===void 0?Ge(c,{now:o,table:n}):Ye(l,n,c.name),g=r+t;if(g>d.capacity&&!Object.hasOwn(a,c.name))throw new y("BAD_REQUEST",`cannot seed ${String(g)} rows into "${n}": unique column "${c.name}" has only ${String(d.capacity)} possible values`);s.set(c.name,d)}return s},nn=(e,n={})=>{const{counts:t={},defaultCount:r=10,existingIds:o={},indexOffset:a={},now:i=Date.now(),only:s,overrides:c={},seed:l=0}=n;fe(l);const d=ye(e);if(s!==void 0){const m=new Set(d.map(w=>w.name));for(const w of s)if(!m.has(w)){const A=d.map(k=>k.name).join(", ");throw new y("BAD_REQUEST",`unknown table "${w}" in seed \`only\` — schema defines: ${A||"(no tables)"}`)}}const g=new Set(s??d.map(m=>m.name)),I=new Set(Object.keys(o).filter(m=>!g.has(m)&&(o[m]??[]).length>0)),se=new Set([...Ae(d,g,I)].filter(m=>g.has(m)||(o[m]??[]).length===0)),ie=Se(d,se),ce=new Map(d.map(m=>[m.name,m])),M=new Map,j={},C=[];for(const m of ie){const w=ce.get(m);if(w===void 0)continue;const A=c[m]??{},k=t[m]??r,U=a[m]??0,ue=Ke(w.fields,m,k,U,i,A,S=>ae(S,m,0,M,o)),F=[];M.set(m,F);const D=[];j[m]=D;for(let S=0;S<k;S+=1){const $=U+S,T={},B=(p,le)=>{if(Object.hasOwn(A,p)){const Y=He(A[p],{field:p,index:$,row:T,store:j,table:m});if(Y!==void 0){T[p]=Y;return}}const V=le();V!==void 0&&(T[p]=V)};B("_id",()=>u.uuid(J(l,m,$,"_id"))),F.push(T._id);for(const p of w.fields)B(p.name,()=>Qe(p,{existingIds:o,idsByTable:M,index:$,input:J(l,m,$,p.name),localIndex:S,now:i,table:m,uniqueDeals:ue}));D.push(T)}C.push({rows:D,table:m})}return C};export{fe as a,u as c,ye as i,nn as s};
@@ -0,0 +1 @@
1
+ import{s as a}from"./plan-DfieuDm9.mjs";export{a as seedPlan};
package/dist/testing.mjs CHANGED
@@ -1 +1 @@
1
- import{s as m,i as u}from"./packem_shared/plan-CZy5Xjiw.mjs";const g=(r,o,a)=>{if(o.size===0&&a.size===0)return r;const s={...r};for(const n of o){const t=s[n];typeof t=="number"&&(s[n]=BigInt(t))}for(const n of a){const t=s[n];Array.isArray(t)&&(s[n]=Uint8Array.from(t).buffer)}return s},S=async(r,o,a={})=>{const s=m(o,a),n=u(o),t=new Map,l=new Map;for(const i of n){const c=new Set(i.fields.filter(e=>e.kind==="bigint").map(e=>e.name)),f=new Set(i.fields.filter(e=>e.kind==="bytes").map(e=>e.name));c.size>0&&t.set(i.name,c),f.size>0&&l.set(i.name,f)}const d={};return await r.run(async i=>{const c=i.db.insert;for(const{rows:f,table:e}of s){const b=[],p=t.get(e)??new Set,w=l.get(e)??new Set;for(const y of f)b.push(await c(e,g(y,p,w),{allowExplicitId:!0}));d[e]=b}}),d};export{S as seed};
1
+ import{s as m,i as u}from"./packem_shared/plan-DfieuDm9.mjs";const g=(r,o,a)=>{if(o.size===0&&a.size===0)return r;const s={...r};for(const n of o){const t=s[n];typeof t=="number"&&(s[n]=BigInt(t))}for(const n of a){const t=s[n];Array.isArray(t)&&(s[n]=Uint8Array.from(t).buffer)}return s},S=async(r,o,a={})=>{const s=m(o,a),n=u(o),t=new Map,l=new Map;for(const i of n){const c=new Set(i.fields.filter(e=>e.kind==="bigint").map(e=>e.name)),f=new Set(i.fields.filter(e=>e.kind==="bytes").map(e=>e.name));c.size>0&&t.set(i.name,c),f.size>0&&l.set(i.name,f)}const d={};return await r.run(async i=>{const c=i.db.insert;for(const{rows:f,table:e}of s){const b=[],p=t.get(e)??new Set,w=l.get(e)??new Set;for(const y of f)b.push(await c(e,g(y,p,w),{allowExplicitId:!0}));d[e]=b}}),d};export{S as seed};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/seed",
3
- "version": "1.0.0-alpha.103",
3
+ "version": "1.0.0-alpha.105",
4
4
  "description": "Schema-driven, deterministic database seeding for Lunora: realistic fake data from defineSchema",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@faker-js/faker": "^10.5.0",
51
- "@lunora/errors": "1.0.0-alpha.30"
51
+ "@lunora/errors": "1.0.0-alpha.31"
52
52
  },
53
53
  "peerDependencies": {
54
54
  "@lunora/server": ">=1.0.0-alpha.24 <2.0.0-0",
@@ -1 +0,0 @@
1
- import{LunoraError as S}from"@lunora/errors";import{faker as f}from"@faker-js/faker";import{optionalInner as Z}from"@lunora/values";let $=0;const le=(e,t)=>e<t?-1:e>t?1:0,R=e=>e===void 0?"undefined":typeof e=="bigint"?`${e.toString()}n`:e===null||typeof e!="object"?JSON.stringify(e)??"null":Array.isArray(e)?`[${e.map(n=>R(n)).join(",")}]`:`{${Object.keys(e).toSorted(le).map(n=>`${JSON.stringify(n)}:${R(e[n])}`).join(",")}}`,X=(e,t)=>{let n=3735928559^t,r=1103547991^t;for(let o=0;o<e.length;o+=1){const s=e.codePointAt(o)??0;n=Math.imul(n^s,2654435761),r=Math.imul(r^s,1597334677)}return n=Math.imul(n^n>>>16,2246822507),n^=Math.imul(r^r>>>13,3266489909),r=Math.imul(r^r>>>16,2246822507),r^=Math.imul(n^n>>>13,3266489909),4294967296*(2097151&r)+(n>>>0)},me="\0",de=e=>{const t=typeof e=="string"?me+e:R(e);return X(t,$)%4294967296},fe=e=>{if(typeof e=="number"){$=e>>>0;return}if(typeof e=="string"){$=X(e,0)%4294967296;return}let t=0;for(const n of e)t=Math.imul(t^n,2654435761)>>>0;$=t},h=(e,t)=>(f.seed(de(e)),t()),he=(e,t)=>{if(typeof t=="number")return t;const[n,r]=t;return h(["__count__",e],()=>f.number.int({max:r,min:n}))},ge=/[a-z]/,pe=/[A-Z]/,ve=/\d/,u={bool(e){return h(e,()=>f.datatype.boolean())},city(e){return h(e,()=>f.location.city())},country(e){return h(e,()=>f.location.country())},email(e){return h(e,()=>f.internet.email().toLowerCase())},firstName(e){return h(e,()=>f.person.firstName())},float(e,t){const{fractionDigits:n=2,max:r=1e3,min:o=0}=t??{};return h(e,()=>f.number.float({fractionDigits:n,max:r,min:o}))},fullName(e){return h(e,()=>f.person.fullName())},int(e,t){const{max:n=1e3,min:r=0}=t??{};return h(e,()=>f.number.int({max:n,min:r}))},lastName(e){return h(e,()=>f.person.lastName())},oneOf(e,t){if(t.length!==0)return h(e,()=>f.helpers.arrayElement(t))},paragraph(e){return h(e,()=>f.lorem.paragraph())},password(e){return h(e,()=>f.internet.password())},phoneNumber(e){return h(e,()=>f.phone.number())},scramble(e,t){const n=new Set(t?.preserve);return Array.from({length:e.length},(r,o)=>{const s=e.charAt(o);return n.has(s)?s:ge.test(s)?h([e,o,"l"],()=>f.string.alpha({casing:"lower",length:1})):pe.test(s)?h([e,o,"u"],()=>f.string.alpha({casing:"upper",length:1})):ve.test(s)?h([e,o,"d"],()=>String(f.number.int({max:9,min:0}))):s}).join("")},sentence(e,t){return h(e,()=>f.lorem.sentence(t?{max:t.max??8,min:t.min??3}:void 0))},slug(e){return h(e,()=>f.lorem.slug())},streetAddress(e){return h(e,()=>f.location.streetAddress())},times(e,t,n){const r=he(e,t),o=[];for(let s=0;s<r;s+=1)o.push(n([e,s]));return o},url(e){return h(e,()=>f.internet.url())},username(e){return h(e,()=>f.internet.username())},uuid(e){return h(e,()=>f.string.uuid())},word(e){return h(e,()=>f.lorem.word())}},p=e=>e._meta??{},ee=e=>Z(e)??e,te=e=>{const{column:t}=p(e);if(t?.defaultValue!==void 0||t?.defaultFn!==void 0)return!0;const n=Z(e);return n===void 0?!1:te(n)},we=(e,t)=>{const n=ee(t),r=p(n);return{fkTable:n.kind==="id"?r.tableName:void 0,hasServerDefault:te(t),kind:n.kind,name:e,nullable:r.column?.notNull===!1,optional:t.kind==="optional",unique:r.column?.unique===!0,validator:n}},be=e=>{const{tables:t}=e;return Object.entries(t).map(([n,r])=>({fields:Object.entries(r.shape).map(([o,s])=>we(o,s)),name:n}))},ye=(e,t)=>{const n=new Map(e.map(a=>[a.name,a])),r=a=>{const c=n.get(a);if(c===void 0)return new Set;const l=new Set;for(const d of c.fields)d.fkTable!==void 0&&d.fkTable!==a&&t.has(d.fkTable)&&l.add(d.fkTable);return l},o=[],s=new Set,i=[...t].filter(a=>n.has(a));for(;i.length>0;){const a=i.findIndex(d=>[...r(d)].every(g=>s.has(g))),c=a===-1?0:a,[l]=i.splice(c,1);if(l===void 0)break;o.push(l),s.add(l)}return o},Se=(e,t,n=new Set)=>{const r=new Map(e.map(i=>[i.name,i])),o=new Set(t),s=[...o];for(;s.length>0;){const i=s.pop();if(i===void 0)break;const a=r.get(i);if(a!==void 0&&!n.has(i))for(const c of a.fields)c.fkTable!==void 0&&c.fkTable!==i&&r.has(c.fkTable)&&!o.has(c.fkTable)&&(o.add(c.fkTable),s.push(c.fkTable))}return o},ne=e=>p(e).constraints??{},Ae=[{generate:e=>u.email(e),keywords:["email"]},{generate:e=>u.firstName(e),keywords:["firstname"]},{generate:e=>u.lastName(e),keywords:["lastname","surname"]},{generate:e=>u.username(e),keywords:["username"]},{generate:e=>u.fullName(e),keywords:["name"]},{generate:e=>u.sentence(e,{max:5,min:2}),keywords:["title"]},{generate:e=>u.url(e),keywords:["url","link","image","avatar"]},{generate:e=>u.phoneNumber(e),keywords:["phone"]},{generate:e=>u.paragraph(e),keywords:["description","bio","body","content","text"]},{generate:e=>u.slug(e),keywords:["slug","key","code"]},{generate:e=>u.city(e),keywords:["city"]},{generate:e=>u.country(e),keywords:["country"]},{generate:e=>u.streetAddress(e),keywords:["address","street"]},{generate:e=>u.password(e),keywords:["password","secret","token"]}],xe=new Set(["at","date","deadline","expires","expiry","since","timestamp","until"]),Te=/([a-z\d])([A-Z])/gu,Ie=/[\s_-]+/u,ke=e=>e.replaceAll(Te,"$1 $2").split(Ie).filter(t=>t!=="").map(t=>t.toLowerCase()),P={max:1e3,min:0},q={max:1e6,min:0},Oe=4320*60*60*1e3,re=e=>{const n=ke(e).at(-1);return n!==void 0&&xe.has(n)},H=(e,t)=>t-u.int(e,{max:Oe,min:0}),N=(e,t)=>{throw new S("INTERNAL",`@lunora/seed: column "${e}" ${t}. Supply a value via \`overrides\` (\`{ <table>: { ${e}: … } }\`) or restrict the run with \`only\` so the table is skipped.`)},j=(e,t)=>{const n=e===""?"x":e,r=Math.min(Math.max(n.length,t.min),t.max);return n.padEnd(r,n).slice(0,r)},T="@example.com",_="https://",$e=/[\s@]/gu,Ne=/[^a-z\d]/gu,_e=(e,t)=>{const n=e.lastIndexOf("@"),r=n>0?e.slice(n):"",o=r.length>0&&r.length<t.max?r:T,s=(n>0?e.slice(0,n):e).replaceAll($e,"");return`${j(s,{max:t.max-o.length,min:Math.max(1,t.min-o.length)})}${o}`},Me=(e,t)=>{const n=URL.canParse(e)?new URL(e).hostname.replaceAll(Ne,""):"";return`${_}${j(n,{max:t.max-_.length,min:Math.max(1,t.min-_.length)})}`},Ee={email:{fit:_e,generate:e=>u.email(e),minimum:T.length+1},uri:{fit:Me,generate:e=>u.url(e),minimum:_.length+1}},De=(e,t)=>{const n=e.toLowerCase(),r=Ae.find(o=>o.keywords.some(s=>n.includes(s)));return r===void 0?u.word(t):r.generate(t)},Le=(e,t,n)=>{const{format:r,maxLength:o,minLength:s,pattern:i}=n;if(i!==void 0)return N(e,`is constrained to the pattern /${i}/, and the seeder cannot invent a value matching an arbitrary regular expression`);if(o!==void 0&&s!==void 0&&s>o)throw new S("INTERNAL",`Seed constraint error for field "${e}": minLength (${String(s)}) > maxLength (${String(o)}). Adjust the schema constraints.`);const a={max:o??Number.POSITIVE_INFINITY,min:s??0};if(r===void 0)return j(De(e,t),a);const c=Ee[r];if(c===void 0)return N(e,`declares format "${r}", which the seeder has no generator for`);if(a.max<c.minimum)return N(e,`declares format "${r}" with maxLength ${String(o)}, and the shortest ${r} value the seeder can build is ${String(c.minimum)} characters`);const l=c.generate(t);return l.length>=a.min&&l.length<=a.max?l:c.fit(l,a)},b=(e,t,n,r)=>{const o=ee(e),s=ne(o);if(s.enum!==void 0&&s.enum.length>0)return u.oneOf(n,s.enum);switch(o.kind){case"any":return u.word(n);case"array":{const i=p(o).inner;return i===void 0?[]:u.times(n,[1,3],a=>b(i,t,a,r))}case"bigint":return u.int(n,{max:s.maximum??q.max,min:s.minimum??q.min});case"boolean":return u.bool(n);case"bytes":return Array.from({length:8},(i,a)=>u.int([n,a],{max:255,min:0}));case"date":case"timestamp":return H(n,r);case"from":return N(t,"is a v.from() validator, whose external Standard Schema the seeder cannot introspect to invent a conforming value (give the column a concrete v.* type instead)");case"id":return u.uuid(n);case"literal":return p(o).value;case"null":return null;case"number":{const{maximum:i,minimum:a}=s;if(i===void 0&&a===void 0&&re(t))return H(n,r);if(i!==void 0&&a!==void 0&&a>i)throw new S("INTERNAL",`Seed constraint error for field "${t}": minimum (${String(a)}) > maximum (${String(i)}). Adjust the schema constraints.`);const c=a??P.min,l=i??P.max;return!Number.isInteger(c)||!Number.isInteger(l)?u.float(n,{max:l,min:c}):u.int(n,{max:l,min:c})}case"object":{const i=p(o).shape??{};return Object.fromEntries(Object.entries(i).map(([a,c])=>[a,b(c,a,[n,a],r)]))}case"record":{const{keyValidator:i,valueValidator:a}=p(o),c=u.times(n,[1,3],l=>{const d=i===void 0?u.word(["k",l]):String(b(i,t,["k",l],r)),g=a===void 0?u.word(["v",l]):b(a,t,["v",l],r);return[d,g]});return Object.fromEntries(c)}case"storage":return`seed/${u.uuid(n)}`;case"string":return Le(t,n,s);case"union":{const i=p(o).members??[],a=u.oneOf(n,i);return a===void 0?u.word(n):b(a,t,[n,"u"],r)}default:return u.word(n)}},L=1e6,Re=6e4,Pe=2**32,qe=(e,t,n)=>{const r=[...e];for(let o=r.length-1;o>0;o-=1){const s=u.int([t,n,"unique-deal",o],{max:o,min:0}),i=r[o];r[o]=r[s],r[s]=i}return r},je=(e,t,n)=>{const{maxLength:r}=n,o=String(t),s=e.indexOf("@");if(s>0){const c=e.slice(0,s),l=e.slice(s),d=r===void 0?c.length:r-l.length-o.length-1;if(d>=0)return`${c.slice(0,d)}+${o}${l}`}if(n.format==="email"){const c=r===void 0?e.length:Math.max(0,r-T.length-o.length);return`${e.slice(0,c)}${o}${T}`}const i=`-${o}`,a=r===void 0?e.length:Math.max(0,r-i.length);return`${e.slice(0,a)}${i}`},M=(e,t,n)=>{const r=qe(e,t,n);return{capacity:r.length,valueAt:o=>r[o%r.length]}},Ce=(e,t)=>{if(Number.isInteger(e)&&Number.isInteger(t)){const n=t-e+1;return{capacity:n,valueAt:r=>e+r%n}}return{capacity:L,valueAt:n=>e+n%L*(t-e)/L}},W=e=>({capacity:Number.POSITIVE_INFINITY,valueAt:t=>e-t*Re}),Fe={capacity:Number.POSITIVE_INFINITY,valueAt:e=>e},z={capacity:Number.POSITIVE_INFINITY,valueAt:(e,t)=>t()},J=(e,t)=>{const{maximum:n,minimum:r}=e;return n===void 0&&r===void 0?Fe:Ce(r??t.min,n??t.max)},K=(e,t,n)=>{throw new S("INTERNAL",`@lunora/seed: cannot generate unique values for "${e}"."${t}" — ${n}. Supply them via \`overrides\` (\`{ ${e}: { ${t}: … } }\`) or drop \`.unique()\` from the column.`)},Ue=({format:e,maxLength:t})=>{if(t===void 0)return Number.POSITIVE_INFINITY;const n=e==="email"?T.length:1;return t<=n?0:10**(t-n)},Ve=(e,t,n)=>(e.pattern!==void 0&&K(t,n,"the column is pattern-constrained, and an index-tagged value would no longer match it"),e.format!==void 0&&e.format!=="email"&&K(t,n,`the column declares format "${e.format}", which an index-tagged value would no longer satisfy`),{capacity:Ue(e),valueAt:(r,o)=>je(String(o()),r,e)}),Be=(e,t,n)=>M(e,t,n),Ye=(e,t)=>{const{now:n,table:r}=t,o=ne(e.validator),s=o.enum;if(Array.isArray(s)&&s.length>0)return M(s,r,e.name);switch(e.kind){case"any":case"string":return Ve(o,r,e.name);case"bigint":return J(o,q);case"boolean":return M([!1,!0],r,e.name);case"bytes":return{capacity:Pe,valueAt:i=>[Math.floor(i/16777216)%256,Math.floor(i/65536)%256,Math.floor(i/256)%256,i%256,...Array.from({length:4},(a,c)=>u.int([r,e.name,"unique-bytes",c],{max:255,min:0}))]};case"date":case"timestamp":return W(n);case"literal":return{capacity:1,valueAt:()=>p(e.validator).value};case"number":return o.maximum===void 0&&o.minimum===void 0&&re(e.name)?W(n):J(o,P);case"union":{const i=p(e.validator).members??[],a=i.filter(c=>c.kind==="literal").map(c=>p(c).value);return a.length>0&&a.length===i.length?M(a,r,e.name):z}default:return z}},Ge=(e,t)=>typeof e=="function"?e(t):e,He=(e,t)=>{if(!e.optional)return e.nullable?null:u.uuid(t)},oe=(e,t,n,r,o)=>{const s=e.fkTable,i=s===t?(r.get(t)??[]).slice(0,n):r.get(s)??[],a=o[s]??[];return a.length===0?i:[...i,...a]},Q=(e,t,n,r)=>[e,t,n,r],We=(e,t)=>{const{existingIds:n,idsByTable:r,index:o,input:s,localIndex:i,now:a,table:c,uniqueDeals:l}=t;if(e.fkTable!==void 0){const g=oe(e,c,i,r,n);if(g.length===0)return He(e,s);if(!e.unique)return u.oneOf(s,g);const I=l.get(e.name);return I===void 0?g.at(-1):I.valueAt(o,()=>u.oneOf(s,g))}if(e.hasServerDefault)return;const d=e.unique?l.get(e.name):void 0;return d!==void 0?d.valueAt(o,()=>b(e.validator,e.name,s,a)):b(e.validator,e.name,s,a)},ze=(e,t,n,r,o,s,i)=>{const a=new Map;for(const c of e){if(!c.unique||c.hasServerDefault&&c.fkTable===void 0||c.fkTable===t)continue;const l=c.fkTable===void 0?void 0:i(c);if(l?.length===0)continue;const d=l===void 0?Ye(c,{now:o,table:t}):Be(l,t,c.name),g=r+n;if(g>d.capacity&&!Object.hasOwn(s,c.name))throw new S("BAD_REQUEST",`cannot seed ${String(g)} rows into "${t}": unique column "${c.name}" has only ${String(d.capacity)} possible values`);a.set(c.name,d)}return a},Ze=(e,t={})=>{const{counts:n={},defaultCount:r=10,existingIds:o={},indexOffset:s={},now:i=Date.now(),only:a,overrides:c={},seed:l=0}=t;fe(l);const d=be(e);if(a!==void 0){const m=new Set(d.map(w=>w.name));for(const w of a)if(!m.has(w)){const A=d.map(k=>k.name).join(", ");throw new S("BAD_REQUEST",`unknown table "${w}" in seed \`only\` — schema defines: ${A||"(no tables)"}`)}}const g=new Set(a??d.map(m=>m.name)),I=new Set(Object.keys(o).filter(m=>!g.has(m)&&(o[m]??[]).length>0)),se=new Set([...Se(d,g,I)].filter(m=>g.has(m)||(o[m]??[]).length===0)),ae=ye(d,se),ie=new Map(d.map(m=>[m.name,m])),E=new Map,C={},F=[];for(const m of ae){const w=ie.get(m);if(w===void 0)continue;const A=c[m]??{},k=n[m]??r,U=s[m]??0,ce=ze(w.fields,m,k,U,i,A,y=>oe(y,m,0,E,o)),V=[];E.set(m,V);const D=[];C[m]=D;for(let y=0;y<k;y+=1){const O=U+y,x={},B=(v,ue)=>{if(Object.hasOwn(A,v)){const G=Ge(A[v],{field:v,index:O,row:x,store:C,table:m});if(G!==void 0){x[v]=G;return}}const Y=ue();Y!==void 0&&(x[v]=Y)};B("_id",()=>u.uuid(Q(l,m,O,"_id"))),V.push(x._id);for(const v of w.fields)B(v.name,()=>We(v,{existingIds:o,idsByTable:E,index:O,input:Q(l,m,O,v.name),localIndex:y,now:i,table:m,uniqueDeals:ce}));D.push(x)}F.push({rows:D,table:m})}return F};export{fe as a,u as c,be as i,Ze as s};
@@ -1 +0,0 @@
1
- import{s as a}from"./plan-CZy5Xjiw.mjs";export{a as seedPlan};