@lunora/seed 1.0.0-alpha.102 → 1.0.0-alpha.104
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.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/createSeedClient-B6_37xlU.mjs +1 -0
- package/dist/packem_shared/plan-DfieuDm9.mjs +1 -0
- package/dist/packem_shared/seedPlan-CstVYU35.mjs +1 -0
- package/dist/testing.mjs +1 -1
- package/package.json +1 -1
- package/dist/packem_shared/createSeedClient-DCeTN5tl.mjs +0 -1
- package/dist/packem_shared/plan-vnUMmTjD.mjs +0 -1
- package/dist/packem_shared/seedPlan-DJps_-aq.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -44,6 +44,14 @@ type SeedClient<InsertModel> = SeedClientState & { [Table in keyof InsertModel]:
|
|
|
44
44
|
interface SeedClientOptions {
|
|
45
45
|
/** Default row count when a table call passes no spec (default `10`). */
|
|
46
46
|
defaultCount?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Wall-clock reference for time-valued columns (`createdAt`, `expiresAt`, a
|
|
49
|
+
* `.unique()` date, …), in epoch-ms. Defaults to `Date.now()` **per call**,
|
|
50
|
+
* which is the one input that otherwise drifts between runs — pin it and the
|
|
51
|
+
* client is deterministic in the full sense the docs promise, not merely in
|
|
52
|
+
* its ids.
|
|
53
|
+
*/
|
|
54
|
+
now?: number;
|
|
47
55
|
/** Persist each generated batch (e.g. insert through the test harness). Pure when omitted. */
|
|
48
56
|
persist?: (table: string, rows: ReadonlyArray<Record<string, unknown>>) => Promise<void> | void;
|
|
49
57
|
/** Deterministic mapping selector — same seed ⇒ same rows and ids. Default `0`. */
|
package/dist/index.d.ts
CHANGED
|
@@ -44,6 +44,14 @@ type SeedClient<InsertModel> = SeedClientState & { [Table in keyof InsertModel]:
|
|
|
44
44
|
interface SeedClientOptions {
|
|
45
45
|
/** Default row count when a table call passes no spec (default `10`). */
|
|
46
46
|
defaultCount?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Wall-clock reference for time-valued columns (`createdAt`, `expiresAt`, a
|
|
49
|
+
* `.unique()` date, …), in epoch-ms. Defaults to `Date.now()` **per call**,
|
|
50
|
+
* which is the one input that otherwise drifts between runs — pin it and the
|
|
51
|
+
* client is deterministic in the full sense the docs promise, not merely in
|
|
52
|
+
* its ids.
|
|
53
|
+
*/
|
|
54
|
+
now?: number;
|
|
47
55
|
/** Persist each generated batch (e.g. insert through the test harness). Pure when omitted. */
|
|
48
56
|
persist?: (table: string, rows: ReadonlyArray<Record<string, unknown>>) => Promise<void> | void;
|
|
49
57
|
/** Deterministic mapping selector — same seed ⇒ same rows and ids. Default `0`. */
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSeedClient as o}from"./packem_shared/createSeedClient-
|
|
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};
|
|
@@ -0,0 +1 @@
|
|
|
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-
|
|
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 +0,0 @@
|
|
|
1
|
-
import{a as S,s as $,c as C}from"./plan-vnUMmTjD.mjs";const P=e=>Array.isArray(e)&&e.length===2&&typeof e[0]=="number"&&typeof e[1]=="number",T=(e,d,u,r)=>{const o=n=>typeof n=="number"?n:C.int([u,d,"count"],{max:n[1],min:n[0]});return e===void 0?{count:r}:typeof e=="number"?{count:e}:typeof e=="function"?{count:e(o)}:P(e)?{count:o(e)}:{count:e.length,partials:e}},A=(e,d,u)=>{const r={};if(e!==void 0){const o=new Set(e.flatMap(n=>Object.keys(n)));for(const n of o)r[n]=i=>e[i.index-u]?.[n]}for(const[o,n]of Object.entries(d??{}))r[o]=n;return r},B=(e,d={})=>{const{defaultCount:u=10,persist:r,seed:o=0}=d,n={},i={},l={},j=async(t,s,a)=>{S(o);const{count:c,partials:v}=T(s,t,o,u),h=l[t]??0,g=$(e,{counts:{[t]:c},existingIds:i,indexOffset:{[t]:h},only:[t],overrides:{[t]:A(v,a?.overrides,h)},seed:o});let m=[];for(const{rows:y,table:f}of g){const k=y.map(w=>w._id);n[f]??=[],n[f].push(...y),i[f]??=[],i[f].push(...k),l[f]=(l[f]??0)+y.length,f===t&&(m=k),r!==void 0&&await r(f,y)}return{[t]:m}};let b=Promise.resolve();const x=(t,s,a)=>{const c=b.then(()=>j(t,s,a));return b=c.then(()=>{},()=>{}),c},O={$ids:i,$reset:()=>{for(const t of Object.keys(n))delete n[t];for(const t of Object.keys(i))delete i[t];for(const t of Object.keys(l))delete l[t]},$store:n};return new Proxy(O,{get(t,s,a){return typeof s=="string"&&!s.startsWith("$")&&Object.hasOwn(e.tables,s)?(c,v)=>x(s,c,v):Reflect.get(t,s,a)}})};export{B as createSeedClient};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as y}from"@lunora/errors";import{faker as m}from"@faker-js/faker";import{optionalInner as W}from"@lunora/values";let x=0;const oe=(e,t)=>e<t?-1:e>t?1:0,_=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=>_(n)).join(",")}]`:`{${Object.keys(e).toSorted(oe).map(n=>`${JSON.stringify(n)}:${_(e[n])}`).join(",")}}`,H=(e,t)=>{let n=3735928559^t,r=1103547991^t;for(let o=0;o<e.length;o+=1){const i=e.codePointAt(o)??0;n=Math.imul(n^i,2654435761),r=Math.imul(r^i,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)},se="\0",ae=e=>{const t=typeof e=="string"?se+e:_(e);return H(t,x)%4294967296},ie=e=>{if(typeof e=="number"){x=e>>>0;return}if(typeof e=="string"){x=H(e,0)%4294967296;return}let t=0;for(const n of e)t=Math.imul(t^n,2654435761)>>>0;x=t},f=(e,t)=>(m.seed(ae(e)),t()),ce=(e,t)=>{if(typeof t=="number")return t;const[n,r]=t;return f(["__count__",e],()=>m.number.int({max:r,min:n}))},ue=/[a-z]/,le=/[A-Z]/,me=/\d/,u={bool(e){return f(e,()=>m.datatype.boolean())},city(e){return f(e,()=>m.location.city())},country(e){return f(e,()=>m.location.country())},dateString(e,t){const n=t?.min??new Date("1980-01-01T00:00:00.000Z"),r=t?.max??new Date("2020-01-01T00:00:00.000Z");return f(e,()=>m.date.between({from:n,to:r}).toISOString())},email(e){return f(e,()=>m.internet.email().toLowerCase())},firstName(e){return f(e,()=>m.person.firstName())},float(e,t){const{fractionDigits:n=2,max:r=1e3,min:o=0}=t??{};return f(e,()=>m.number.float({fractionDigits:n,max:r,min:o}))},fullName(e){return f(e,()=>m.person.fullName())},int(e,t){const{max:n=1e3,min:r=0}=t??{};return f(e,()=>m.number.int({max:n,min:r}))},lastName(e){return f(e,()=>m.person.lastName())},oneOf(e,t){if(t.length!==0)return f(e,()=>m.helpers.arrayElement(t))},paragraph(e){return f(e,()=>m.lorem.paragraph())},password(e){return f(e,()=>m.internet.password())},phoneNumber(e){return f(e,()=>m.phone.number())},scramble(e,t){const n=new Set(t?.preserve);return Array.from({length:e.length},(r,o)=>{const i=e.charAt(o);return n.has(i)?i:ue.test(i)?f([e,o,"l"],()=>m.string.alpha({casing:"lower",length:1})):le.test(i)?f([e,o,"u"],()=>m.string.alpha({casing:"upper",length:1})):me.test(i)?f([e,o,"d"],()=>String(m.number.int({max:9,min:0}))):i}).join("")},sentence(e,t){return f(e,()=>m.lorem.sentence(t?{max:t.max??8,min:t.min??3}:void 0))},slug(e){return f(e,()=>m.lorem.slug())},streetAddress(e){return f(e,()=>m.location.streetAddress())},times(e,t,n){const r=ce(e,t),o=[];for(let i=0;i<r;i+=1)o.push(n([e,i]));return o},url(e){return f(e,()=>m.internet.url())},username(e){return f(e,()=>m.internet.username())},uuid(e){return f(e,()=>m.string.uuid())},word(e){return f(e,()=>m.lorem.word())}},p=e=>e._meta??{},Z=e=>W(e)??e,z=e=>{const{column:t}=p(e);if(t?.defaultValue!==void 0||t?.defaultFn!==void 0)return!0;const n=W(e);return n===void 0?!1:z(n)},de=(e,t)=>{const n=Z(t),r=p(n);return{fkTable:n.kind==="id"?r.tableName:void 0,hasServerDefault:z(t),kind:n.kind,name:e,nullable:r.column?.notNull===!1,optional:t.kind==="optional",unique:r.column?.unique===!0,validator:n}},fe=e=>{const{tables:t}=e;return Object.entries(t).map(([n,r])=>({fields:Object.entries(r.shape).map(([o,i])=>de(o,i)),name:n}))},he=(e,t)=>{const n=new Map(e.map(s=>[s.name,s])),r=s=>{const c=n.get(s);if(c===void 0)return new Set;const l=new Set;for(const h of c.fields)h.fkTable!==void 0&&h.fkTable!==s&&t.has(h.fkTable)&&l.add(h.fkTable);return l},o=[],i=new Set,a=[...t].filter(s=>n.has(s));for(;a.length>0;){const s=a.findIndex(h=>[...r(h)].every(g=>i.has(g))),c=s===-1?0:s,[l]=a.splice(c,1);if(l===void 0)break;o.push(l),i.add(l)}return o},ge=(e,t,n=new Set)=>{const r=new Map(e.map(a=>[a.name,a])),o=new Set(t),i=[...o];for(;i.length>0;){const a=i.pop();if(a===void 0)break;const s=r.get(a);if(s!==void 0&&!n.has(a))for(const c of s.fields)c.fkTable!==void 0&&c.fkTable!==a&&r.has(c.fkTable)&&!o.has(c.fkTable)&&(o.add(c.fkTable),i.push(c.fkTable))}return o},J=e=>p(e).constraints??{},ve=[{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"]}],pe=new Set(["at","date","deadline","expires","expiry","since","timestamp","until"]),we=/([a-z\d])([A-Z])/gu,be=/[\s_-]+/u,ye=e=>e.replaceAll(we,"$1 $2").split(be).filter(t=>t!=="").map(t=>t.toLowerCase()),$={max:1e3,min:0},E={max:1e6,min:0},Se=4320*60*60*1e3,K=e=>{const n=ye(e).at(-1);return n!==void 0&&pe.has(n)},Ae=(e,t)=>t-u.int(e,{max:Se,min:0}),Te=(e,t,n)=>{const r=e.toLowerCase(),o=ve.find(l=>l.keywords.some(h=>r.includes(h))),i=o===void 0?u.word(t):o.generate(t),{maxLength:a,minLength:s}=n;if(a!==void 0&&s!==void 0&&s>a)throw new y("INTERNAL",`Seed constraint error for field "${e}": minLength (${String(s)}) > maxLength (${String(a)}). Adjust the schema constraints.`);const c=a!==void 0&&i.length>a?i.slice(0,a):i;return s!==void 0&&c.length<s?c.padEnd(s,c.length>0?c:"x"):c},b=(e,t,n,r)=>{const o=Z(e),i=J(o);if(i.enum!==void 0&&i.enum.length>0)return u.oneOf(n,i.enum);switch(o.kind){case"any":return u.word(n);case"array":{const a=p(o).inner;return a===void 0?[]:u.times(n,[1,3],s=>b(a,t,s,r))}case"bigint":return u.int(n,{max:E.max,min:E.min});case"boolean":return u.bool(n);case"bytes":return Array.from({length:8},(a,s)=>u.int([n,s],{max:255,min:0}));case"date":case"timestamp":return new Date(u.dateString(n)).getTime();case"from":throw new y("INTERNAL",`@lunora/seed: column "${t}" is a v.from() validator, whose external Standard Schema the seeder cannot introspect to invent a conforming value. Supply one via \`overrides\` (\`{ <table>: { ${t}: … } }\`), restrict the run with \`only\` so the table is skipped, or give the column a concrete v.* type.`);case"id":return u.uuid(n);case"literal":return p(o).value;case"null":return null;case"number":{const{maximum:a,minimum:s}=i;if(a===void 0&&s===void 0&&K(t))return Ae(n,r);if(a!==void 0&&s!==void 0&&s>a)throw new y("INTERNAL",`Seed constraint error for field "${t}": minimum (${String(s)}) > maximum (${String(a)}). Adjust the schema constraints.`);const c=s??$.min,l=a??$.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 a=p(o).shape??{};return Object.fromEntries(Object.entries(a).map(([s,c])=>[s,b(c,s,[n,s],r)]))}case"record":{const{keyValidator:a,valueValidator:s}=p(o),c=u.times(n,[1,3],l=>{const h=a===void 0?u.word(["k",l]):String(b(a,t,["k",l],r)),g=s===void 0?u.word(["v",l]):b(s,t,["v",l],r);return[h,g]});return Object.fromEntries(c)}case"storage":return`seed/${u.uuid(n)}`;case"string":return Te(t,n,i);case"union":{const a=p(o).members??[],s=u.oneOf(n,a);return s===void 0?u.word(n):b(s,t,[n,"u"],r)}default:return u.word(n)}},O=1e6,Ie=6e4,ke=2**32,xe=(e,t,n)=>{const r=[...e];for(let o=r.length-1;o>0;o-=1){const i=u.int([t,n,"unique-deal",o],{max:o,min:0}),a=r[o];r[o]=r[i],r[i]=a}return r},F="@example.com",Ne=(e,t,n)=>{const{maxLength:r}=n,o=String(t),i=e.indexOf("@");if(i>0){const c=e.slice(0,i),l=e.slice(i),h=r===void 0?c.length:Math.max(0,r-l.length-o.length-1);return`${c.slice(0,h)}+${o}${l}`}if(n.format==="email"){const c=r===void 0?e.length:Math.max(0,r-F.length-o.length);return`${e.slice(0,c)}${o}${F}`}const a=`-${o}`,s=r===void 0?e.length:Math.max(0,r-a.length);return`${e.slice(0,s)}${a}`},B=(e,t,n)=>{const r=xe(e,t,n);return{capacity:r.length,valueAt:o=>r[o%r.length]}},Oe=(e,t)=>{if(Number.isInteger(e)&&Number.isInteger(t)){const n=t-e+1;return{capacity:n,valueAt:r=>e+r%n}}return{capacity:O,valueAt:n=>e+n%O*(t-e)/O}},V=e=>({capacity:Number.POSITIVE_INFINITY,valueAt:t=>e-t*Ie}),_e={capacity:Number.POSITIVE_INFINITY,valueAt:e=>e},U=(e,t)=>{const{maximum:n,minimum:r}=e;return n===void 0&&r===void 0?_e:Oe(r??t.min,n??t.max)},G=(e,t,n)=>{throw new y("INTERNAL",`@lunora/seed: cannot generate unique values for "${e}"."${t}" — ${n}. Supply them via \`overrides\` (\`{ ${e}: { ${t}: … } }\`) or drop \`.unique()\` from the column.`)},$e=e=>e===void 0?Number.POSITIVE_INFINITY:e<=1?0:10**(e-1),Ee=(e,t,n)=>(e.pattern!==void 0&&G(t,n,"the column is pattern-constrained, and an index-tagged value would no longer match it"),e.format!==void 0&&e.format!=="email"&&G(t,n,`the column declares format "${e.format}", which an index-tagged value would no longer satisfy`),{capacity:$e(e.maxLength),valueAt:(r,o)=>Ne(String(o()),r,e)}),Me=(e,t)=>{const{now:n,table:r}=t,o=J(e.validator),i=o.enum;if(Array.isArray(i)&&i.length>0)return B(i,r,e.name);switch(e.kind){case"any":case"string":return Ee(o,r,e.name);case"bigint":return U(o,E);case"boolean":return B([!1,!0],r,e.name);case"bytes":return{capacity:ke,valueAt:a=>[Math.floor(a/16777216)%256,Math.floor(a/65536)%256,Math.floor(a/256)%256,a%256,...Array.from({length:4},(s,c)=>u.int([r,e.name,"unique-bytes",c],{max:255,min:0}))]};case"date":case"timestamp":return V(n);case"literal":return{capacity:1,valueAt:()=>p(e.validator).value};case"number":return o.maximum===void 0&&o.minimum===void 0&&K(e.name)?V(n):U(o,$);default:return{capacity:Number.POSITIVE_INFINITY,valueAt:(a,s)=>s()}}},De=(e,t)=>typeof e=="function"?e(t):e,Le=(e,t)=>{if(!e.optional)return e.nullable?null:u.uuid(t)},Re=(e,t,n,r,o)=>{const i=e.fkTable,a=i===t?(r.get(t)??[]).slice(0,n):r.get(i)??[],s=o[i]??[];return s.length===0?a:[...a,...s]},Y=(e,t,n,r)=>[e,t,n,r],Pe=(e,t)=>{const{existingIds:n,idsByTable:r,index:o,input:i,localIndex:a,now:s,table:c,uniqueDeals:l}=t;if(e.fkTable!==void 0){const g=Re(e,c,a,r,n);return g.length===0?Le(e,i):u.oneOf(i,g)}if(e.hasServerDefault)return;const h=e.unique?l.get(e.name):void 0;return h!==void 0?h.valueAt(o,()=>b(e.validator,e.name,i,s)):b(e.validator,e.name,i,s)},je=(e,t,n,r,o,i)=>{const a=new Map;for(const s of e){if(!s.unique||s.fkTable!==void 0||s.hasServerDefault)continue;const c=Me(s,{now:o,table:t}),l=r+n;if(l>c.capacity&&!Object.hasOwn(i,s.name))throw new y("BAD_REQUEST",`cannot seed ${String(l)} rows into "${t}": unique column "${s.name}" has only ${String(c.capacity)} possible values`);a.set(s.name,c)}return a},Be=(e,t={})=>{const{counts:n={},defaultCount:r=10,existingIds:o={},indexOffset:i={},now:a=Date.now(),only:s,overrides:c={},seed:l=0}=t;ie(l);const h=fe(e);if(s!==void 0){const d=new Set(h.map(w=>w.name));for(const w of s)if(!d.has(w)){const S=h.map(T=>T.name).join(", ");throw new y("BAD_REQUEST",`unknown table "${w}" in seed \`only\` — schema defines: ${S||"(no tables)"}`)}}const g=new Set(s??h.map(d=>d.name)),Q=new Set(Object.keys(o).filter(d=>!g.has(d)&&(o[d]??[]).length>0)),X=new Set([...ge(h,g,Q)].filter(d=>g.has(d)||(o[d]??[]).length===0)),ee=he(h,X),te=new Map(h.map(d=>[d.name,d])),M=new Map,D={},L=[];for(const d of ee){const w=te.get(d);if(w===void 0)continue;const S=c[d]??{},T=n[d]??r,R=i[d]??0,ne=je(w.fields,d,T,R,a,S),P=[];M.set(d,P);const N=[];D[d]=N;for(let I=0;I<T;I+=1){const k=R+I,A={},j=(v,re)=>{if(Object.hasOwn(S,v)){const C=De(S[v],{field:v,index:k,row:A,store:D,table:d});if(C!==void 0){A[v]=C;return}}const q=re();q!==void 0&&(A[v]=q)};j("_id",()=>u.uuid(Y(l,d,k,"_id"))),P.push(A._id);for(const v of w.fields)j(v.name,()=>Pe(v,{existingIds:o,idsByTable:M,index:k,input:Y(l,d,k,v.name),localIndex:I,now:a,table:d,uniqueDeals:ne}));N.push(A)}L.push({rows:N,table:d})}return L};export{ie as a,u as c,fe as i,Be as s};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a}from"./plan-vnUMmTjD.mjs";export{a as seedPlan};
|