admindb 2.1.1 → 2.2.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/README.md +41 -12
- package/dist/app.js +230 -1
- package/dist/auth/config.js +121 -1
- package/dist/auth/crypto.js +108 -1
- package/dist/auth/index.js +21 -1
- package/dist/auth/middleware.js +85 -1
- package/dist/auth/routes.js +70 -1
- package/dist/auth/types.js +7 -1
- package/dist/cli/args.js +320 -1
- package/dist/cli/config.js +128 -1
- package/dist/cli/index.js +20 -1
- package/dist/cli/runner.js +211 -1
- package/dist/cli.js +4 -1
- package/dist/data/chain.d.ts +1 -0
- package/dist/data/chain.js +707 -0
- package/dist/data/datasets.js +129 -1
- package/dist/data/detector.d.ts +1 -1
- package/dist/data/detector.js +511 -1
- package/dist/data/engine.d.ts +1 -1
- package/dist/data/engine.js +245 -1
- package/dist/data/index.d.ts +1 -1
- package/dist/data/index.js +22 -1
- package/dist/data/strategies.d.ts +1 -1
- package/dist/data/strategies.js +339 -1
- package/dist/data/types.d.ts +1 -1
- package/dist/data/types.js +5 -1
- package/dist/db/database.d.ts +1 -1
- package/dist/db/database.js +477 -1
- package/dist/db/export.d.ts +1 -1
- package/dist/db/export.js +90 -1
- package/dist/db/filters.js +142 -1
- package/dist/db/index.js +24 -1
- package/dist/db/introspection.js +167 -1
- package/dist/db/manager.js +351 -1
- package/dist/db/migrations.js +107 -1
- package/dist/db/postgres.d.ts +1 -1
- package/dist/db/postgres.js +735 -1
- package/dist/db/types.d.ts +1 -1
- package/dist/db/types.js +6 -1
- package/dist/index.js +52 -1
- package/dist/public/css/app.css +1 -1
- package/dist/public/js/api.js +1 -1
- package/dist/public/js/browse.js +1 -1
- package/dist/public/js/common.js +1 -0
- package/dist/public/js/databases.js +1 -1
- package/dist/public/js/designer.js +1 -1
- package/dist/public/js/forms.js +1 -1
- package/dist/public/js/home.js +1 -0
- package/dist/public/js/inspector.js +1 -1
- package/dist/public/js/query.js +1 -1
- package/dist/public/js/schema.js +1 -1
- package/dist/public/js/seed.js +1 -1
- package/dist/routes/api/erd.d.ts +1 -0
- package/dist/routes/api/erd.js +50 -0
- package/dist/routes/api/helpers.d.ts +1 -1
- package/dist/routes/api/helpers.js +163 -1
- package/dist/routes/api/import-export.js +83 -1
- package/dist/routes/api/index.js +48 -1
- package/dist/routes/api/query.js +78 -1
- package/dist/routes/api/rows.js +362 -1
- package/dist/routes/api/seed.js +153 -1
- package/dist/routes/api/tables.js +231 -1
- package/dist/routes/databases.js +228 -1
- package/dist/routes/index.js +19 -1
- package/dist/routes/pages.js +397 -1
- package/dist/serverless.js +174 -1
- package/dist/sql/classifier.js +24 -1
- package/dist/sql/error-analyzer.d.ts +1 -0
- package/dist/sql/error-analyzer.js +550 -0
- package/dist/sql/generator.js +319 -1
- package/dist/sql/index.js +18 -1
- package/dist/types/api.js +2 -1
- package/dist/utils/colors.js +54 -1
- package/dist/utils/common.d.ts +1 -1
- package/dist/utils/common.js +225 -1
- package/dist/utils/csv.js +67 -1
- package/dist/utils/datatype.js +181 -1
- package/dist/utils/icons.js +81 -1
- package/dist/utils/index.js +20 -1
- package/dist/utils/logger.js +36 -1
- package/dist/views/layouts/main.hbs +14 -1
- package/dist/views/pages/erd.hbs +1241 -0
- package/dist/views/pages/home.hbs +98 -2
- package/dist/views/pages/info.hbs +107 -0
- package/dist/views/pages/query.hbs +54 -12
- package/dist/views/pages/seed.hbs +435 -171
- package/dist/views/partials/sidebar.hbs +12 -0
- package/docs/API.md +6 -1
- package/docs/EXAMPLES.md +3 -0
- package/package.json +5 -4
- package/dist/public/js/icons.js +0 -1
package/dist/data/strategies.js
CHANGED
|
@@ -1 +1,339 @@
|
|
|
1
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.randomTime=exports.makeParagraph=exports.makeColor=exports.makeAvatar=exports.makeCreditCard=exports.makeIp=exports.makeAddress=exports.makePhone=exports.makeUsername=exports.makeEmail=exports.makeSlug=exports.pick=exports.randFloat=exports.randInt=void 0,exports.makeMacAddress=makeMacAddress,exports.makeUuid=makeUuid,exports.makeWords=makeWords,exports.makeSentences=makeSentences,exports.formatPattern=formatPattern,exports.randomDate=randomDate,exports.randomUnixTimestamp=randomUnixTimestamp,exports.randomAlnum=randomAlnum,exports.makeJsonObject=makeJsonObject,exports.isTextishType=isTextishType,exports.strategiesFor=function(col,fk){const type=(col.type||"").toUpperCase(),isText=isTextishType(type),isNum=type.startsWith("INTEGER")||"REAL"===type||type.includes("DECIMAL")||type.includes("NUMERIC")||isText,isBlob="BLOB"===type||isText,out=[];fk&&out.push({id:"fk",label:`Foreign Key: Sample from ${fk.table}${fk.to?`.${fk.to}`:""}`,category:"relational"});for(const[id,label,category,target]of STRATEGY_METADATA)("all"===target||"text"===target&&isText||"numeric"===target&&isNum||"blob"===target&&isBlob)&&out.push({id:id,label:label,category:category});return out},exports.fallbackPlanFor=function(col){const type=(col.type||"").toUpperCase();return"BOOLEAN"===type||"BOOL"===type?{strategy:"bool"}:"UUID"===type?{strategy:"uuid"}:"JSON"===type||"JSONB"===type?{strategy:"json"}:type.startsWith("INT")||"BIGINT"===type||"SMALLINT"===type||"SERIAL"===type||"BIGSERIAL"===type?{strategy:"int",min:1,max:1e3}:"REAL"===type||type.includes("DECIMAL")||"NUMERIC"===type||type.includes("FLOAT")||type.includes("DOUBLE")?{strategy:"decimal",min:1,max:1e3,precision:2}:"DATE"===type?{strategy:"date",from:"2020-01-01",to:"2026-12-31"}:type.includes("TIMESTAMP")||"DATETIME"===type?{strategy:"datetime",from:"2024-01-01T00:00:00",to:"2026-12-31T23:59:59"}:"TIME"===type?{strategy:"time"}:"BLOB"===type||"BYTEA"===type?{strategy:"bytes",minLen:8,maxLen:32}:"INET"===type?{strategy:"ip"}:{strategy:"words",minLen:1,maxLen:4}},exports.generateOne=generateOne,exports.generateSampleValue=function(col,plan,fkPool){const v=generateOne(col,plan,fkPool||["[FK sample]"],0);return v===types_1.SKIP?"(omitted / default)":null===v?"NULL":v instanceof Uint8Array||Buffer.isBuffer(v)?`0x${Buffer.from(v).toString("hex").slice(0,16)}...`:v};const node_crypto_1=require("node:crypto"),common_1=require("../utils/common"),datasets_1=require("./datasets"),types_1=require("./types");exports.randInt=(min,max)=>Math.floor(Math.random()*(max-min+1))+min;exports.randFloat=(min,max)=>Math.random()*(max-min)+min;exports.pick=arr=>arr[(0,exports.randInt)(0,arr.length-1)];exports.makeSlug=()=>`${(0,exports.pick)(datasets_1.LOREM_WORDS)}-${(0,exports.pick)(datasets_1.LOREM_WORDS)}-${(0,exports.randInt)(100,999)}`;exports.makeEmail=()=>`${(0,exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}.${(0,exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${(0,exports.randInt)(1,99)}@${(0,exports.pick)(datasets_1.DOMAINS)}`;exports.makeUsername=()=>`${(0,exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}${(0,exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${(0,exports.randInt)(1,9999)}`;exports.makePhone=()=>`+1 (${(0,exports.randInt)(200,999)}) ${(0,exports.randInt)(200,999)}-${String((0,exports.randInt)(0,9999)).padStart(4,"0")}`;exports.makeAddress=()=>`${(0,exports.randInt)(10,9999)} ${(0,exports.pick)(datasets_1.LOREM_WORDS)} ${(0,exports.pick)(["St","Ave","Rd","Blvd","Ln","Dr"])}, ${(0,exports.pick)(datasets_1.CITIES)}`;function makeMacAddress(){const b=()=>(0,exports.randInt)(0,255).toString(16).padStart(2,"0").toUpperCase();return`${b()}:${b()}:${b()}:${b()}:${b()}:${b()}`}exports.makeIp=()=>`${(0,exports.randInt)(1,223)}.${(0,exports.randInt)(0,255)}.${(0,exports.randInt)(0,255)}.${(0,exports.randInt)(1,254)}`;exports.makeCreditCard=()=>`4532-${(0,exports.randInt)(1e3,9999)}-${(0,exports.randInt)(1e3,9999)}-${(0,exports.randInt)(1e3,9999)}`;exports.makeAvatar=seedVal=>`https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(seedVal||(0,exports.makeUsername)())}`;function makeUuid(){const h=n=>(0,exports.randInt)(0,4294967295).toString(16).padStart(n,"0");return`${h(8)}-${h(4).slice(0,4)}-4${h(3).slice(0,3)}-${["8","9","a","b"][(0,exports.randInt)(0,3)]}${h(3).slice(0,3)}-${h(12).slice(0,12)}`}function makeWords(minLen,maxLen){const n=(0,exports.randInt)(minLen,maxLen),parts=[];for(let i=0;i<n;i++)parts.push((0,exports.pick)(datasets_1.LOREM_WORDS));return parts.join(" ")}function makeSentences(minLen,maxLen){const n=(0,exports.randInt)(minLen,maxLen),sentences=[];for(let i=0;i<n;i++){const words=makeWords(6,14).split(" ");words[0]=words[0].charAt(0).toUpperCase()+words[0].slice(1),sentences.push(words.join(" ")+".")}return sentences.join(" ")}exports.makeColor=(format="hex")=>"name"===format?(0,exports.pick)(datasets_1.NAMED_COLORS):(0,exports.pick)(datasets_1.HEX_COLORS);function formatPattern(pattern){if(!pattern)return"";const now=new Date,year=String(now.getFullYear()),s=pattern.replace(/\{YYYY\}/g,year).replace(/\{YY\}/g,year.slice(-2)).replace(/\{MM\}/g,String((0,exports.randInt)(1,12)).padStart(2,"0")).replace(/\{DD\}/g,String((0,exports.randInt)(1,28)).padStart(2,"0"));let res="";for(let i=0;i<s.length;i++){const ch=s[i];res+="#"===ch?(0,exports.randInt)(0,9):"A"===ch||"?"===ch?"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(0,exports.randInt)(0,25)]:"a"===ch?"abcdefghijklmnopqrstuvwxyz"[(0,exports.randInt)(0,25)]:ch}return res}function randomDate(from,to,kind="date"){const now=Date.now(),lo=from?Date.parse(from):now-63072e6,hi=to?Date.parse(to):now,d=new Date((0,exports.randInt)(Number.isFinite(lo)?lo:now-63072e6,Number.isFinite(hi)?hi:now));if("datetime"===kind)return d.toISOString();const p=n=>String(n).padStart(2,"0");return`${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}`}exports.makeParagraph=()=>makeSentences(3,5);function randomUnixTimestamp(format="sec",from,to){const now=Date.now(),lo=from?Date.parse(from):now-63072e6,hi=to?Date.parse(to):now,t=(0,exports.randInt)(Number.isFinite(lo)?lo:now-63072e6,Number.isFinite(hi)?hi:now);return"ms"===format?t:Math.floor(t/1e3)}exports.randomTime=()=>`${String((0,exports.randInt)(0,23)).padStart(2,"0")}:${String((0,exports.randInt)(0,59)).padStart(2,"0")}:${String((0,exports.randInt)(0,59)).padStart(2,"0")}`;const ALNUM="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";function randomAlnum(minLen,maxLen){const len=(0,exports.randInt)(minLen,maxLen);let s="";for(let i=0;i<len;i++)s+=ALNUM[(0,exports.randInt)(0,ALNUM.length-1)];return s}const JSON_ROLES=["admin","editor","viewer","billing","member","owner","guest"],JSON_APPS=["dashboard","api","mobile","cli","webhook","cron","importer"];function jsonValueForKey(key){const lk=key.toLowerCase();if(lk.includes("role"))return(0,exports.pick)(JSON_ROLES);if(lk.includes("app"))return[(0,exports.pick)(JSON_APPS)];const roll=Math.random();return roll<.45?(0,exports.pick)(["alpha","beta","stable","draft","on","off","default","custom"]):roll<.6?(0,exports.randInt)(0,1e3):roll<.75?Math.random()<.5:roll<.9?null:makeUuid()}function makeJsonObject(keys,jsonValues){const k=(keys&&keys.length?keys:["scope","enabled","flags"]).slice(0,16),obj={};for(const key of k){const allowed=jsonValues?jsonValues[key]:void 0;obj[key]=allowed&&allowed.length?(0,exports.pick)(allowed):jsonValueForKey(key)}return JSON.stringify(obj)}function isTextishType(type){const t=(type||"").toUpperCase();return"TEXT"===t||""===t||t.includes("JSON")||t.includes("CHAR")||t.includes("CLOB")||t.includes("VARCHAR")}const STRATEGY_METADATA=[["skip","Skip (DB default or NULL applies)","custom_control","all"],["null","Set NULL explicitly","custom_control","all"],["fixed","Fixed constant value","custom_control","all"],["list","Random item from custom list","custom_control","all"],["pattern","Custom pattern template (e.g. INV-####)","custom_control","all"],["fullname","Full name (e.g. John Smith)","identity","text"],["first","First name","identity","text"],["last","Last name / Surname","identity","text"],["username","Username handle","identity","text"],["job","Job title / Profession","identity","text"],["email","Email address","contact_web","text"],["phone","Phone number","contact_web","text"],["url","Website URL","contact_web","text"],["domain","Domain name","contact_web","text"],["ip","IPv4 address","contact_web","text"],["avatar","Avatar image URL","contact_web","text"],["company","Company / Organization name","commerce","text"],["currency","Currency code (USD, EUR...)","commerce","text"],["status","Status badge (active, pending...)","commerce","text"],["creditCard","Masked test credit card","commerce","text"],["address","Street address","location","text"],["city","City name","location","text"],["state","State / Province","location","text"],["country","Country name","location","text"],["countryCode","Country code (ISO-2 e.g. US)","location","text"],["postal","Postal / Zip code","location","text"],["latitude","Latitude (-90 to 90)","location","all"],["longitude","Longitude (-180 to 180)","location","all"],["int","Random integer in range","numeric","numeric"],["decimal","Random decimal / price","numeric","numeric"],["sequence","Sequential numbering (1, 2, 3...)","numeric","numeric"],["date","Random date (YYYY-MM-DD)","datetime","all"],["datetime","Random datetime (ISO-8601)","datetime","all"],["time","Random time (HH:MM:SS)","datetime","all"],["timestampUnix","Unix timestamp (epoch)","datetime","all"],["words","Short words / Tags","system_crypto","text"],["sentence","Sentences","system_crypto","text"],["paragraph","Paragraph (multi-sentence text)","system_crypto","text"],["slug","URL slug (e.g. tech-news-402)","system_crypto","text"],["bool","Boolean flag (1/0 or true/false)","system_crypto","all"],["bytes","Random hex bytes (BLOB)","system_crypto","blob"],["uuid","UUID v4","system_crypto","text"],["token","Short alphanumeric token","system_crypto","text"],["hash","Hexadecimal hash (MD5/SHA)","system_crypto","text"],["json","Valid JSON object","system_crypto","text"],["color","Color (Hex code or name)","system_crypto","text"],["mac","MAC network address","system_crypto","text"]];const BASIC_STRATEGIES={first:()=>(0,exports.pick)(datasets_1.FIRST_NAMES),last:()=>(0,exports.pick)(datasets_1.LAST_NAMES),fullname:()=>`${(0,exports.pick)(datasets_1.FIRST_NAMES)} ${(0,exports.pick)(datasets_1.LAST_NAMES)}`,email:()=>(0,exports.makeEmail)(),username:()=>(0,exports.makeUsername)(),job:()=>(0,exports.pick)(datasets_1.JOB_TITLES),company:()=>(0,exports.pick)(datasets_1.COMPANIES),currency:()=>(0,exports.pick)(datasets_1.CURRENCIES),status:()=>(0,exports.pick)(datasets_1.STATUSES),creditCard:()=>(0,exports.makeCreditCard)(),avatar:()=>(0,exports.makeAvatar)(),color:p=>(0,exports.makeColor)(p.format),phone:()=>(0,exports.makePhone)(),city:()=>(0,exports.pick)(datasets_1.CITIES),state:()=>(0,exports.pick)(datasets_1.US_STATES),country:()=>(0,exports.pick)(datasets_1.COUNTRIES),countryCode:()=>(0,exports.pick)(datasets_1.COUNTRY_CODES),postal:()=>String((0,exports.randInt)(1e4,99999)),address:()=>(0,exports.makeAddress)(),url:()=>`https://www.${(0,exports.pick)(datasets_1.DOMAINS)}/${(0,exports.makeSlug)()}`,domain:()=>(0,exports.pick)(datasets_1.DOMAINS),ip:()=>(0,exports.makeIp)(),mac:()=>makeMacAddress(),uuid:()=>makeUuid(),slug:()=>(0,exports.makeSlug)(),paragraph:()=>(0,exports.makeParagraph)(),time:()=>(0,exports.randomTime)(),bool:()=>(0,exports.pick)(["1","0"]),json:p=>makeJsonObject(p.jsonKeys,p.jsonValues),words:p=>makeWords(p.minLen??1,p.maxLen??4),sentence:p=>makeSentences(p.minLen??1,p.maxLen??2),date:p=>randomDate(p.from,p.to,"date"),datetime:p=>randomDate(p.from,p.to,"datetime"),timestampUnix:p=>randomUnixTimestamp(p.format,p.from,p.to),latitude:p=>Number((0,exports.randFloat)(p.min??-90,p.max??90).toFixed(6)),longitude:p=>Number((0,exports.randFloat)(p.min??-180,p.max??180).toFixed(6)),sequence:(p,idx)=>(p.start??1)+idx*(p.step??1),int:p=>(0,exports.randInt)(p.min??1,Math.max(p.min??1,p.max??1e3)),decimal:p=>(0,exports.randFloat)(p.min??1,Math.max(p.min??1,p.max??1e3)).toFixed(Math.max(0,Math.min(10,p.precision??2))),pattern:p=>formatPattern(p.pattern||"INV-2026-####"),fixed:p=>p.value??"",token:p=>randomAlnum(Math.max(2,p.minLen??6),Math.max(2,p.maxLen??12)),hash:p=>{const len=(0,exports.randInt)(Math.max(8,p.minLen??32),Math.max(8,p.maxLen??64));return(0,node_crypto_1.randomBytes)(Math.ceil(len/2)).toString("hex").slice(0,len)}};function generateOne(col,p,fkPool,rowIndex=0){const type=(col.type||"").toUpperCase();if(!col.pk&&!col.notnull&&p.nullPct&&p.nullPct>0&&100*Math.random()<p.nullPct)return null;if("skip"===p.strategy)return types_1.SKIP;if("null"===p.strategy)return null;if("list"===p.strategy){const vals=(p.values??[]).filter(v=>""!==String(v).trim());return vals.length?(0,common_1.coerceFormValue)(String((0,exports.pick)(vals)),type||"TEXT"):types_1.SKIP}if("fk"===p.strategy)return fkPool&&fkPool.length?fkPool[(0,exports.randInt)(0,fkPool.length-1)]:null;if("bytes"===p.strategy){const len=(0,exports.randInt)(Math.max(0,p.minLen??8),Math.max(1,p.maxLen??32)),buf=Buffer.alloc(len);for(let i=0;i<len;i++)buf[i]=(0,exports.randInt)(0,255);return(0,common_1.coerceFormValue)(`0x${buf.toString("hex")}`,type||"BLOB")}const gen=BASIC_STRATEGIES[p.strategy];if(!gen)return types_1.SKIP;let rawVal=gen(p,rowIndex);return null!=rawVal&&(p.prefix||p.suffix)&&"string"==typeof rawVal&&(rawVal=`${p.prefix||""}${rawVal}${p.suffix||""}`),(0,common_1.coerceFormValue)(String(rawVal),type||"TEXT")}
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.randomTime = exports.makeParagraph = exports.makeColor = exports.makeAvatar = exports.makeCreditCard = exports.makeIp = exports.makeAddress = exports.makePhone = exports.makeUsername = exports.makeEmail = exports.makeSlug = exports.pick = exports.randFloat = exports.randInt = void 0;
|
|
4
|
+
exports.makeMacAddress = makeMacAddress;
|
|
5
|
+
exports.makeUuid = makeUuid;
|
|
6
|
+
exports.makeWords = makeWords;
|
|
7
|
+
exports.makeSentences = makeSentences;
|
|
8
|
+
exports.formatPattern = formatPattern;
|
|
9
|
+
exports.randomDate = randomDate;
|
|
10
|
+
exports.randomUnixTimestamp = randomUnixTimestamp;
|
|
11
|
+
exports.randomAlnum = randomAlnum;
|
|
12
|
+
exports.makeJsonObject = makeJsonObject;
|
|
13
|
+
exports.isTextishType = isTextishType;
|
|
14
|
+
exports.strategiesFor = strategiesFor;
|
|
15
|
+
exports.fallbackPlanFor = fallbackPlanFor;
|
|
16
|
+
exports.generateOne = generateOne;
|
|
17
|
+
exports.generateSampleValue = generateSampleValue;
|
|
18
|
+
const node_crypto_1 = require("node:crypto");
|
|
19
|
+
const common_1 = require("../utils/common");
|
|
20
|
+
const datasets_1 = require("./datasets");
|
|
21
|
+
const types_1 = require("./types");
|
|
22
|
+
const randInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
|
|
23
|
+
exports.randInt = randInt;
|
|
24
|
+
const randFloat = (min, max) => Math.random() * (max - min) + min;
|
|
25
|
+
exports.randFloat = randFloat;
|
|
26
|
+
const pick = (arr) => arr[(0, exports.randInt)(0, arr.length - 1)];
|
|
27
|
+
exports.pick = pick;
|
|
28
|
+
const makeSlug = () => `${(0, exports.pick)(datasets_1.LOREM_WORDS)}-${(0, exports.pick)(datasets_1.LOREM_WORDS)}-${(0, exports.randInt)(100, 999)}`;
|
|
29
|
+
exports.makeSlug = makeSlug;
|
|
30
|
+
const makeEmail = (idx) => `${(0, exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}.${(0, exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${idx != null ? idx + 1 : ''}${(0, exports.randInt)(10, 9999)}@${(0, exports.pick)(datasets_1.DOMAINS)}`;
|
|
31
|
+
exports.makeEmail = makeEmail;
|
|
32
|
+
const makeUsername = (idx) => `${(0, exports.pick)(datasets_1.FIRST_NAMES).toLowerCase()}${(0, exports.pick)(datasets_1.LAST_NAMES).toLowerCase()}${idx != null ? idx + 1 : ''}${(0, exports.randInt)(10, 9999)}`;
|
|
33
|
+
exports.makeUsername = makeUsername;
|
|
34
|
+
const makePhone = () => `+1 (${(0, exports.randInt)(200, 999)}) ${(0, exports.randInt)(200, 999)}-${String((0, exports.randInt)(0, 9999)).padStart(4, '0')}`;
|
|
35
|
+
exports.makePhone = makePhone;
|
|
36
|
+
const makeAddress = () => `${(0, exports.randInt)(10, 9999)} ${(0, exports.pick)(datasets_1.LOREM_WORDS)} ${(0, exports.pick)(['St', 'Ave', 'Rd', 'Blvd', 'Ln', 'Dr'])}, ${(0, exports.pick)(datasets_1.CITIES)}`;
|
|
37
|
+
exports.makeAddress = makeAddress;
|
|
38
|
+
const makeIp = () => `${(0, exports.randInt)(1, 223)}.${(0, exports.randInt)(0, 255)}.${(0, exports.randInt)(0, 255)}.${(0, exports.randInt)(1, 254)}`;
|
|
39
|
+
exports.makeIp = makeIp;
|
|
40
|
+
function makeMacAddress() {
|
|
41
|
+
const b = () => (0, exports.randInt)(0, 255).toString(16).padStart(2, '0').toUpperCase();
|
|
42
|
+
return `${b()}:${b()}:${b()}:${b()}:${b()}:${b()}`;
|
|
43
|
+
}
|
|
44
|
+
const makeCreditCard = () => `4532-${(0, exports.randInt)(1000, 9999)}-${(0, exports.randInt)(1000, 9999)}-${(0, exports.randInt)(1000, 9999)}`;
|
|
45
|
+
exports.makeCreditCard = makeCreditCard;
|
|
46
|
+
const makeAvatar = (seedVal) => `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(seedVal || (0, exports.makeUsername)())}`;
|
|
47
|
+
exports.makeAvatar = makeAvatar;
|
|
48
|
+
const makeColor = (format = 'hex') => (format === 'name' ? (0, exports.pick)(datasets_1.NAMED_COLORS) : (0, exports.pick)(datasets_1.HEX_COLORS));
|
|
49
|
+
exports.makeColor = makeColor;
|
|
50
|
+
function makeUuid() {
|
|
51
|
+
const h = (n) => (0, exports.randInt)(0, 0xffffffff).toString(16).padStart(n, '0');
|
|
52
|
+
return `${h(8)}-${h(4).slice(0, 4)}-4${h(3).slice(0, 3)}-${['8', '9', 'a', 'b'][(0, exports.randInt)(0, 3)]}${h(3).slice(0, 3)}-${h(12).slice(0, 12)}`;
|
|
53
|
+
}
|
|
54
|
+
function makeWords(minLen, maxLen) {
|
|
55
|
+
const n = (0, exports.randInt)(minLen, maxLen);
|
|
56
|
+
const parts = [];
|
|
57
|
+
for (let i = 0; i < n; i++)
|
|
58
|
+
parts.push((0, exports.pick)(datasets_1.LOREM_WORDS));
|
|
59
|
+
return parts.join(' ');
|
|
60
|
+
}
|
|
61
|
+
function makeSentences(minLen, maxLen) {
|
|
62
|
+
const n = (0, exports.randInt)(minLen, maxLen);
|
|
63
|
+
const sentences = [];
|
|
64
|
+
for (let i = 0; i < n; i++) {
|
|
65
|
+
const words = makeWords(6, 14).split(' ');
|
|
66
|
+
words[0] = words[0].charAt(0).toUpperCase() + words[0].slice(1);
|
|
67
|
+
sentences.push(words.join(' ') + '.');
|
|
68
|
+
}
|
|
69
|
+
return sentences.join(' ');
|
|
70
|
+
}
|
|
71
|
+
const makeParagraph = () => makeSentences(3, 5);
|
|
72
|
+
exports.makeParagraph = makeParagraph;
|
|
73
|
+
function formatPattern(pattern) {
|
|
74
|
+
if (!pattern)
|
|
75
|
+
return '';
|
|
76
|
+
const now = new Date();
|
|
77
|
+
const year = String(now.getFullYear());
|
|
78
|
+
const s = pattern
|
|
79
|
+
.replace(/\{YYYY\}/g, year)
|
|
80
|
+
.replace(/\{YY\}/g, year.slice(-2))
|
|
81
|
+
.replace(/\{MM\}/g, String((0, exports.randInt)(1, 12)).padStart(2, '0'))
|
|
82
|
+
.replace(/\{DD\}/g, String((0, exports.randInt)(1, 28)).padStart(2, '0'));
|
|
83
|
+
const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
84
|
+
const lower = 'abcdefghijklmnopqrstuvwxyz';
|
|
85
|
+
let res = '';
|
|
86
|
+
for (let i = 0; i < s.length; i++) {
|
|
87
|
+
const ch = s[i];
|
|
88
|
+
if (ch === '#')
|
|
89
|
+
res += (0, exports.randInt)(0, 9);
|
|
90
|
+
else if (ch === 'A' || ch === '?')
|
|
91
|
+
res += upper[(0, exports.randInt)(0, 25)];
|
|
92
|
+
else if (ch === 'a')
|
|
93
|
+
res += lower[(0, exports.randInt)(0, 25)];
|
|
94
|
+
else
|
|
95
|
+
res += ch;
|
|
96
|
+
}
|
|
97
|
+
return res;
|
|
98
|
+
}
|
|
99
|
+
function randomDate(from, to, kind = 'date') {
|
|
100
|
+
const now = Date.now();
|
|
101
|
+
const lo = from ? Date.parse(from) : now - 730 * 86400_000;
|
|
102
|
+
const hi = to ? Date.parse(to) : now;
|
|
103
|
+
const d = new Date((0, exports.randInt)(Number.isFinite(lo) ? lo : now - 730 * 86400_000, Number.isFinite(hi) ? hi : now));
|
|
104
|
+
if (kind === 'datetime')
|
|
105
|
+
return d.toISOString();
|
|
106
|
+
const p = (n) => String(n).padStart(2, '0');
|
|
107
|
+
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
|
|
108
|
+
}
|
|
109
|
+
const randomTime = () => `${String((0, exports.randInt)(0, 23)).padStart(2, '0')}:${String((0, exports.randInt)(0, 59)).padStart(2, '0')}:${String((0, exports.randInt)(0, 59)).padStart(2, '0')}`;
|
|
110
|
+
exports.randomTime = randomTime;
|
|
111
|
+
function randomUnixTimestamp(format = 'sec', from, to) {
|
|
112
|
+
const now = Date.now();
|
|
113
|
+
const lo = from ? Date.parse(from) : now - 730 * 86400_000;
|
|
114
|
+
const hi = to ? Date.parse(to) : now;
|
|
115
|
+
const t = (0, exports.randInt)(Number.isFinite(lo) ? lo : now - 730 * 86400_000, Number.isFinite(hi) ? hi : now);
|
|
116
|
+
return format === 'ms' ? t : Math.floor(t / 1000);
|
|
117
|
+
}
|
|
118
|
+
const ALNUM = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
119
|
+
function randomAlnum(minLen, maxLen) {
|
|
120
|
+
const len = (0, exports.randInt)(minLen, maxLen);
|
|
121
|
+
let s = '';
|
|
122
|
+
for (let i = 0; i < len; i++)
|
|
123
|
+
s += ALNUM[(0, exports.randInt)(0, ALNUM.length - 1)];
|
|
124
|
+
return s;
|
|
125
|
+
}
|
|
126
|
+
const JSON_ROLES = ['admin', 'editor', 'viewer', 'billing', 'member', 'owner', 'guest'];
|
|
127
|
+
const JSON_APPS = ['dashboard', 'api', 'mobile', 'cli', 'webhook', 'cron', 'importer'];
|
|
128
|
+
function jsonValueForKey(key) {
|
|
129
|
+
const lk = key.toLowerCase();
|
|
130
|
+
if (lk.includes('role'))
|
|
131
|
+
return (0, exports.pick)(JSON_ROLES);
|
|
132
|
+
if (lk.includes('app'))
|
|
133
|
+
return [(0, exports.pick)(JSON_APPS)];
|
|
134
|
+
const roll = Math.random();
|
|
135
|
+
if (roll < 0.45)
|
|
136
|
+
return (0, exports.pick)(['alpha', 'beta', 'stable', 'draft', 'on', 'off', 'default', 'custom']);
|
|
137
|
+
if (roll < 0.6)
|
|
138
|
+
return (0, exports.randInt)(0, 1000);
|
|
139
|
+
if (roll < 0.75)
|
|
140
|
+
return Math.random() < 0.5;
|
|
141
|
+
if (roll < 0.9)
|
|
142
|
+
return null;
|
|
143
|
+
return makeUuid();
|
|
144
|
+
}
|
|
145
|
+
function makeJsonObject(keys, jsonValues) {
|
|
146
|
+
const k = (keys && keys.length ? keys : ['scope', 'enabled', 'flags']).slice(0, 16);
|
|
147
|
+
const obj = {};
|
|
148
|
+
for (const key of k) {
|
|
149
|
+
const allowed = jsonValues ? jsonValues[key] : undefined;
|
|
150
|
+
obj[key] = allowed && allowed.length ? (0, exports.pick)(allowed) : jsonValueForKey(key);
|
|
151
|
+
}
|
|
152
|
+
return JSON.stringify(obj);
|
|
153
|
+
}
|
|
154
|
+
function isTextishType(type) {
|
|
155
|
+
const t = (type || '').toUpperCase();
|
|
156
|
+
return t === 'TEXT' || t === '' || t.includes('JSON') || t.includes('CHAR') || t.includes('CLOB') || t.includes('VARCHAR');
|
|
157
|
+
}
|
|
158
|
+
const STRATEGY_METADATA = [
|
|
159
|
+
['skip', 'Skip (DB default or NULL applies)', 'custom_control', 'all'],
|
|
160
|
+
['null', 'Set NULL explicitly', 'custom_control', 'all'],
|
|
161
|
+
['fixed', 'Fixed constant value', 'custom_control', 'all'],
|
|
162
|
+
['list', 'Random item from custom list', 'custom_control', 'all'],
|
|
163
|
+
['pattern', 'Custom pattern template (e.g. INV-####)', 'custom_control', 'all'],
|
|
164
|
+
['fullname', 'Full name (e.g. John Smith)', 'identity', 'text'],
|
|
165
|
+
['first', 'First name', 'identity', 'text'],
|
|
166
|
+
['last', 'Last name / Surname', 'identity', 'text'],
|
|
167
|
+
['username', 'Username handle', 'identity', 'text'],
|
|
168
|
+
['job', 'Job title / Profession', 'identity', 'text'],
|
|
169
|
+
['email', 'Email address', 'contact_web', 'text'],
|
|
170
|
+
['phone', 'Phone number', 'contact_web', 'text'],
|
|
171
|
+
['url', 'Website URL', 'contact_web', 'text'],
|
|
172
|
+
['domain', 'Domain name', 'contact_web', 'text'],
|
|
173
|
+
['ip', 'IPv4 address', 'contact_web', 'text'],
|
|
174
|
+
['avatar', 'Avatar image URL', 'contact_web', 'text'],
|
|
175
|
+
['company', 'Company / Organization name', 'commerce', 'text'],
|
|
176
|
+
['currency', 'Currency code (USD, EUR...)', 'commerce', 'text'],
|
|
177
|
+
['status', 'Status badge (active, pending...)', 'commerce', 'text'],
|
|
178
|
+
['creditCard', 'Masked test credit card', 'commerce', 'text'],
|
|
179
|
+
['address', 'Street address', 'location', 'text'],
|
|
180
|
+
['city', 'City name', 'location', 'text'],
|
|
181
|
+
['state', 'State / Province', 'location', 'text'],
|
|
182
|
+
['country', 'Country name', 'location', 'text'],
|
|
183
|
+
['countryCode', 'Country code (ISO-2 e.g. US)', 'location', 'text'],
|
|
184
|
+
['postal', 'Postal / Zip code', 'location', 'text'],
|
|
185
|
+
['latitude', 'Latitude (-90 to 90)', 'location', 'all'],
|
|
186
|
+
['longitude', 'Longitude (-180 to 180)', 'location', 'all'],
|
|
187
|
+
['int', 'Random integer in range', 'numeric', 'numeric'],
|
|
188
|
+
['decimal', 'Random decimal / price', 'numeric', 'numeric'],
|
|
189
|
+
['sequence', 'Sequential numbering (1, 2, 3...)', 'numeric', 'numeric'],
|
|
190
|
+
['date', 'Random date (YYYY-MM-DD)', 'datetime', 'all'],
|
|
191
|
+
['datetime', 'Random datetime (ISO-8601)', 'datetime', 'all'],
|
|
192
|
+
['time', 'Random time (HH:MM:SS)', 'datetime', 'all'],
|
|
193
|
+
['timestampUnix', 'Unix timestamp (epoch)', 'datetime', 'all'],
|
|
194
|
+
['words', 'Short words / Tags', 'system_crypto', 'text'],
|
|
195
|
+
['sentence', 'Sentences', 'system_crypto', 'text'],
|
|
196
|
+
['paragraph', 'Paragraph (multi-sentence text)', 'system_crypto', 'text'],
|
|
197
|
+
['slug', 'URL slug (e.g. tech-news-402)', 'system_crypto', 'text'],
|
|
198
|
+
['bool', 'Boolean flag (1/0 or true/false)', 'system_crypto', 'all'],
|
|
199
|
+
['bytes', 'Random hex bytes (BLOB)', 'system_crypto', 'blob'],
|
|
200
|
+
['uuid', 'UUID v4', 'system_crypto', 'text'],
|
|
201
|
+
['token', 'Short alphanumeric token', 'system_crypto', 'text'],
|
|
202
|
+
['hash', 'Hexadecimal hash (MD5/SHA)', 'system_crypto', 'text'],
|
|
203
|
+
['json', 'Valid JSON object', 'system_crypto', 'text'],
|
|
204
|
+
['color', 'Color (Hex code or name)', 'system_crypto', 'text'],
|
|
205
|
+
['mac', 'MAC network address', 'system_crypto', 'text'],
|
|
206
|
+
];
|
|
207
|
+
function strategiesFor(col, fk) {
|
|
208
|
+
const type = (col.type || '').toUpperCase();
|
|
209
|
+
const isText = isTextishType(type);
|
|
210
|
+
const isNum = type.startsWith('INTEGER') || type === 'REAL' || type.includes('DECIMAL') || type.includes('NUMERIC') || isText;
|
|
211
|
+
const isBlob = type === 'BLOB' || isText;
|
|
212
|
+
const out = [];
|
|
213
|
+
if (fk) {
|
|
214
|
+
out.push({ id: 'fk', label: `Foreign Key: Sample from ${fk.table}${fk.to ? `.${fk.to}` : ''}`, category: 'relational' });
|
|
215
|
+
}
|
|
216
|
+
for (const [id, label, category, target] of STRATEGY_METADATA) {
|
|
217
|
+
if (target === 'all' || (target === 'text' && isText) || (target === 'numeric' && isNum) || (target === 'blob' && isBlob)) {
|
|
218
|
+
out.push({ id, label, category });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
223
|
+
function fallbackPlanFor(col) {
|
|
224
|
+
const type = (col.type || '').toUpperCase();
|
|
225
|
+
if (type === 'BOOLEAN' || type === 'BOOL')
|
|
226
|
+
return { strategy: 'bool' };
|
|
227
|
+
if (type === 'UUID')
|
|
228
|
+
return { strategy: 'uuid' };
|
|
229
|
+
if (type === 'JSON' || type === 'JSONB')
|
|
230
|
+
return { strategy: 'json' };
|
|
231
|
+
if (type.startsWith('INT') || type === 'BIGINT' || type === 'SMALLINT' || type === 'SERIAL' || type === 'BIGSERIAL')
|
|
232
|
+
return { strategy: 'int', min: 1, max: 1000 };
|
|
233
|
+
if (type === 'REAL' || type.includes('DECIMAL') || type === 'NUMERIC' || type.includes('FLOAT') || type.includes('DOUBLE'))
|
|
234
|
+
return { strategy: 'decimal', min: 1, max: 1000, precision: 2 };
|
|
235
|
+
if (type === 'DATE')
|
|
236
|
+
return { strategy: 'date', from: '2020-01-01', to: '2026-12-31' };
|
|
237
|
+
if (type.includes('TIMESTAMP') || type === 'DATETIME')
|
|
238
|
+
return { strategy: 'datetime', from: '2024-01-01T00:00:00', to: '2026-12-31T23:59:59' };
|
|
239
|
+
if (type === 'TIME')
|
|
240
|
+
return { strategy: 'time' };
|
|
241
|
+
if (type === 'BLOB' || type === 'BYTEA')
|
|
242
|
+
return { strategy: 'bytes', minLen: 8, maxLen: 32 };
|
|
243
|
+
if (type === 'INET')
|
|
244
|
+
return { strategy: 'ip' };
|
|
245
|
+
return { strategy: 'words', minLen: 1, maxLen: 4 };
|
|
246
|
+
}
|
|
247
|
+
const BASIC_STRATEGIES = {
|
|
248
|
+
first: () => (0, exports.pick)(datasets_1.FIRST_NAMES),
|
|
249
|
+
last: () => (0, exports.pick)(datasets_1.LAST_NAMES),
|
|
250
|
+
fullname: () => `${(0, exports.pick)(datasets_1.FIRST_NAMES)} ${(0, exports.pick)(datasets_1.LAST_NAMES)}`,
|
|
251
|
+
email: (_, idx) => (0, exports.makeEmail)(idx),
|
|
252
|
+
username: (_, idx) => (0, exports.makeUsername)(idx),
|
|
253
|
+
job: () => (0, exports.pick)(datasets_1.JOB_TITLES),
|
|
254
|
+
company: () => (0, exports.pick)(datasets_1.COMPANIES),
|
|
255
|
+
currency: () => (0, exports.pick)(datasets_1.CURRENCIES),
|
|
256
|
+
status: () => (0, exports.pick)(datasets_1.STATUSES),
|
|
257
|
+
creditCard: () => (0, exports.makeCreditCard)(),
|
|
258
|
+
avatar: () => (0, exports.makeAvatar)(),
|
|
259
|
+
color: (p) => (0, exports.makeColor)(p.format),
|
|
260
|
+
phone: () => (0, exports.makePhone)(),
|
|
261
|
+
city: () => (0, exports.pick)(datasets_1.CITIES),
|
|
262
|
+
state: () => (0, exports.pick)(datasets_1.US_STATES),
|
|
263
|
+
country: () => (0, exports.pick)(datasets_1.COUNTRIES),
|
|
264
|
+
countryCode: () => (0, exports.pick)(datasets_1.COUNTRY_CODES),
|
|
265
|
+
postal: () => String((0, exports.randInt)(10000, 99999)),
|
|
266
|
+
address: () => (0, exports.makeAddress)(),
|
|
267
|
+
url: () => `https://www.${(0, exports.pick)(datasets_1.DOMAINS)}/${(0, exports.makeSlug)()}`,
|
|
268
|
+
domain: () => (0, exports.pick)(datasets_1.DOMAINS),
|
|
269
|
+
ip: () => (0, exports.makeIp)(),
|
|
270
|
+
mac: () => makeMacAddress(),
|
|
271
|
+
uuid: () => makeUuid(),
|
|
272
|
+
slug: () => (0, exports.makeSlug)(),
|
|
273
|
+
paragraph: () => (0, exports.makeParagraph)(),
|
|
274
|
+
time: () => (0, exports.randomTime)(),
|
|
275
|
+
bool: () => (0, exports.pick)(['1', '0']),
|
|
276
|
+
json: (p) => makeJsonObject(p.jsonKeys, p.jsonValues),
|
|
277
|
+
words: (p) => makeWords(p.minLen ?? 1, p.maxLen ?? 4),
|
|
278
|
+
sentence: (p) => makeSentences(p.minLen ?? 1, p.maxLen ?? 2),
|
|
279
|
+
date: (p) => randomDate(p.from, p.to, 'date'),
|
|
280
|
+
datetime: (p) => randomDate(p.from, p.to, 'datetime'),
|
|
281
|
+
timestampUnix: (p) => randomUnixTimestamp(p.format, p.from, p.to),
|
|
282
|
+
latitude: (p) => Number((0, exports.randFloat)(p.min ?? -90, p.max ?? 90).toFixed(6)),
|
|
283
|
+
longitude: (p) => Number((0, exports.randFloat)(p.min ?? -180, p.max ?? 180).toFixed(6)),
|
|
284
|
+
sequence: (p, idx) => (p.start ?? 1) + idx * (p.step ?? 1),
|
|
285
|
+
int: (p) => (0, exports.randInt)(p.min ?? 1, Math.max(p.min ?? 1, p.max ?? 1000)),
|
|
286
|
+
decimal: (p) => (0, exports.randFloat)(p.min ?? 1, Math.max(p.min ?? 1, p.max ?? 1000)).toFixed(Math.max(0, Math.min(10, p.precision ?? 2))),
|
|
287
|
+
pattern: (p) => formatPattern(p.pattern || 'INV-2026-####'),
|
|
288
|
+
fixed: (p) => p.value ?? '',
|
|
289
|
+
token: (p) => randomAlnum(Math.max(2, p.minLen ?? 6), Math.max(2, p.maxLen ?? 12)),
|
|
290
|
+
hash: (p) => {
|
|
291
|
+
const len = (0, exports.randInt)(Math.max(8, p.minLen ?? 32), Math.max(8, p.maxLen ?? 64));
|
|
292
|
+
return (0, node_crypto_1.randomBytes)(Math.ceil(len / 2)).toString('hex').slice(0, len);
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
function generateOne(col, p, fkPool, rowIndex = 0) {
|
|
296
|
+
const type = (col.type || '').toUpperCase();
|
|
297
|
+
if (!col.pk && !col.notnull && p.nullPct && p.nullPct > 0) {
|
|
298
|
+
if (Math.random() * 100 < p.nullPct)
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
if (p.strategy === 'skip')
|
|
302
|
+
return types_1.SKIP;
|
|
303
|
+
if (p.strategy === 'null')
|
|
304
|
+
return null;
|
|
305
|
+
if (p.strategy === 'list') {
|
|
306
|
+
const vals = (p.values ?? []).filter((v) => String(v).trim() !== '');
|
|
307
|
+
if (!vals.length)
|
|
308
|
+
return types_1.SKIP;
|
|
309
|
+
return (0, common_1.coerceFormValue)(String((0, exports.pick)(vals)), type || 'TEXT');
|
|
310
|
+
}
|
|
311
|
+
if (p.strategy === 'fk') {
|
|
312
|
+
return fkPool && fkPool.length ? fkPool[(0, exports.randInt)(0, fkPool.length - 1)] : null;
|
|
313
|
+
}
|
|
314
|
+
if (p.strategy === 'bytes') {
|
|
315
|
+
const len = (0, exports.randInt)(Math.max(0, p.minLen ?? 8), Math.max(1, p.maxLen ?? 32));
|
|
316
|
+
const buf = Buffer.alloc(len);
|
|
317
|
+
for (let i = 0; i < len; i++)
|
|
318
|
+
buf[i] = (0, exports.randInt)(0, 255);
|
|
319
|
+
return (0, common_1.coerceFormValue)(`0x${buf.toString('hex')}`, type || 'BLOB');
|
|
320
|
+
}
|
|
321
|
+
const gen = BASIC_STRATEGIES[p.strategy];
|
|
322
|
+
if (!gen)
|
|
323
|
+
return types_1.SKIP;
|
|
324
|
+
let rawVal = gen(p, rowIndex);
|
|
325
|
+
if (rawVal != null && (p.prefix || p.suffix) && typeof rawVal === 'string') {
|
|
326
|
+
rawVal = `${p.prefix || ''}${rawVal}${p.suffix || ''}`;
|
|
327
|
+
}
|
|
328
|
+
return (0, common_1.coerceFormValue)(String(rawVal), type || 'TEXT');
|
|
329
|
+
}
|
|
330
|
+
function generateSampleValue(col, plan, fkPool) {
|
|
331
|
+
const v = generateOne(col, plan, fkPool || ['[FK sample]'], 0);
|
|
332
|
+
if (v === types_1.SKIP)
|
|
333
|
+
return '(omitted / default)';
|
|
334
|
+
if (v === null)
|
|
335
|
+
return 'NULL';
|
|
336
|
+
if (v instanceof Uint8Array || Buffer.isBuffer(v))
|
|
337
|
+
return `0x${Buffer.from(v).toString('hex').slice(0, 16)}...`;
|
|
338
|
+
return v;
|
|
339
|
+
}
|
package/dist/data/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import type {ForeignKeyInfo,WhereClause} from '../db/database';export declare const MAX_SEED_ROWS=5000;export type StrategyCategory='identity'|'contact_web'|'commerce'|'location'|'numeric'|'datetime'|'system_crypto'|'custom_control'|'relational';export type GeneratorStrategyId='skip'|'null'|'fixed'|'list'|'pattern'|'first'|'last'|'fullname'|'username'|'job'|'email'|'phone'|'url'|'domain'|'ip'|'avatar'|'company'|'currency'|'status'|'creditCard'|'city'|'country'|'state'|'postal'|'address'|'countryCode'|'latitude'|'longitude'|'words'|'sentence'|'paragraph'|'slug'|'int'|'decimal'|'sequence'|'date'|'datetime'|'time'|'timestampUnix'|'bool'|'bytes'|'json'|'hash'|'token'|'uuid'|'color'|'mac'|'fk';export interface ColumnPlan{strategy:GeneratorStrategyId;value?:string;values?:string[];min?:number;max?:number;precision?:number; from ?:string;to?:string;minLen?:number;maxLen?:number;jsonKeys?:string[];jsonValues?:Record<string,string[]>;nullPct?:number;prefix?:string;suffix?:string;start?:number;step?:number;pattern?:string;format?:string;}export interface StrategyDescriptor{id:GeneratorStrategyId;label:string;category:StrategyCategory;description?:string;}export interface ColumnGeneratorConfig{name:string;type:string;pk:boolean;notnull:boolean;hasDefault:boolean;unique:boolean;fk:ForeignKeyInfo|null;strategies:StrategyDescriptor[];defaultPlan:ColumnPlan;}export interface GenerateResult{rows:WhereClause[][];previewRows:Record<string,unknown>[];warnings:string[];}export declare const SKIP:unique symbol;
|
|
1
|
+
import type {ForeignKeyInfo,WhereClause} from '../db/database';export declare const MAX_SEED_ROWS=5000;export type StrategyCategory='identity'|'contact_web'|'commerce'|'location'|'numeric'|'datetime'|'system_crypto'|'custom_control'|'relational';export type GeneratorStrategyId='skip'|'null'|'fixed'|'list'|'pattern'|'first'|'last'|'fullname'|'username'|'job'|'email'|'phone'|'url'|'domain'|'ip'|'avatar'|'company'|'currency'|'status'|'creditCard'|'city'|'country'|'state'|'postal'|'address'|'countryCode'|'latitude'|'longitude'|'words'|'sentence'|'paragraph'|'slug'|'int'|'decimal'|'sequence'|'date'|'datetime'|'time'|'timestampUnix'|'bool'|'bytes'|'json'|'hash'|'token'|'uuid'|'color'|'mac'|'fk';export interface ColumnPlan{strategy:GeneratorStrategyId;value?:string;values?:string[];min?:number;max?:number;precision?:number; from ?:string;to?:string;minLen?:number;maxLen?:number;jsonKeys?:string[];jsonValues?:Record<string,string[]>;nullPct?:number;prefix?:string;suffix?:string;start?:number;step?:number;pattern?:string;format?:string;}export interface StrategyDescriptor{id:GeneratorStrategyId;label:string;category:StrategyCategory;description?:string;}export interface ColumnGeneratorConfig{name:string;type:string;pk:boolean;notnull:boolean;hasDefault:boolean;unique:boolean;fk:ForeignKeyInfo|null;strategies:StrategyDescriptor[];defaultPlan:ColumnPlan;}export interface GenerateResult{rows:WhereClause[][];previewRows:Record<string,unknown>[];warnings:string[];}export type ErChainScope='chain'|'ancestors'|'descendants'|'all'|'single';export interface ErChainTableNode{name:string;order:number;depth:number;parents:{table:string; from :string;to:string;}[];children:{table:string; from :string;to:string;}[];columns:ColumnGeneratorConfig[];suggestedCount:number;rowCount:number;isRoot:boolean;hasSelfRef:boolean;}export interface ErChainConfig{rootTable:string;scope:ErChainScope;tables:ErChainTableNode[];cycleDetected:boolean;cycleTables?:string[];maxTotalRows:number;}export interface ErChainResult{rootTable:string;scope:ErChainScope;executionOrder:string[];tableResults:Record<string,{count:number;rows:WhereClause[][];previewRows:Record<string,unknown>[];warnings:string[];}>;totalRows:number;sql:string;warnings:string[];}export declare const SKIP:unique symbol;
|
package/dist/data/types.js
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SKIP = exports.MAX_SEED_ROWS = void 0;
|
|
4
|
+
exports.MAX_SEED_ROWS = 5000;
|
|
5
|
+
exports.SKIP = Symbol('skip');
|
package/dist/db/database.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import type {Logger} from '../utils/logger';import{type ColumnDef,type IndexDef} from '../sql/generator';import type {DatabaseDialect,DbOpenOptions,IDatabase,ReferencingTableInfo,Result,RowFilters,SavedQuery,SchemaInfo,SQLInputValue,TableInfoData,TableListItem,WhereClause} from './types';export * from './types';export * from './filters';export declare class SqliteDatabase implements IDatabase{private db;private logger;readonly path:string;readonly isReadOnly:boolean;readonly dialect:DatabaseDialect;constructor(dbPath:string,logger:Logger,options?:DbOpenOptions);private readonlyBlocked;close():void;private initSchema;private tryRun;private transaction;private toBind;all(sql:string,params?:SQLInputValue[]):Promise<Result<unknown[]>>;run(sql:string,params?:SQLInputValue[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;execResult(sql:string):Promise<Result<{changes?:number;}>>;hasMultipleStatements(sql:string):boolean;runWrite(sql:string):Promise<Result<{changes?:number;}>>;listTables():Promise<Result<TableListItem[]>>;getTableInfo(table:string):Promise<Result<TableInfoData>>;getRowCount(table:string,filters?:RowFilters):Promise<Result<number>>;getRows(table:string,opts?:{page?:number;limit?:number;orderBy?:string;orderDir?:'asc'|'desc';filters?:RowFilters;}):Promise<Result<Record<string,unknown>[]>>;getAllRows(table:string):Promise<Result<Record<string,unknown>[]>>;getRow(table:string,where:WhereClause[]):Promise<Result<Record<string,unknown>|null>>;insertRow(table:string,fields:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;insertRows(table:string,rows:WhereClause[][]):Promise<Result<{inserted:number;skipped:number;}>>;updateRow(table:string,fields:WhereClause[],where:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;updateRows(table:string,rows:{fields:WhereClause[];where:WhereClause[];}[]):Promise<Result<{updated:number;}>>;deleteRow(table:string,where:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;deleteRows(table:string,rows:WhereClause[][]):Promise<Result<{deleted:number;}>>;getRowsByPks(table:string,pks:WhereClause[][]):Promise<Result<Record<string,unknown>[]>>;getCreateStatement(table:string):Promise<Result<string|null>>;listSavedQueries():Promise<Result<SavedQuery[]>>;saveQuery(name:string,sql:string):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;deleteSavedQuery(id:string|number):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;getSchema(table:string):Promise<Result<SchemaInfo>>;getReferencingTables(table:string):Promise<Result<ReferencingTableInfo[]>>;getRowsByFk(table:string,column:string,value:unknown,limit?:number):Promise<Result<{rows:Record<string,unknown>[];total:number;}>>;renameTable(oldName:string,newName:string):Promise<Result<{changes?:number;}>>;addColumn(table:string,col:ColumnDef):Promise<Result<{changes?:number;}>>;modifyColumn(table:string,oldColName:string,newColDef:ColumnDef):Promise<Result<{changes?:number;}>>;renameColumn(table:string,oldName:string,newName:string):Promise<Result<{changes?:number;}>>;dropColumn(table:string,column:string):Promise<Result<{changes?:number;}>>;dropTable(table:string):Promise<Result<{changes?:number;}>>;createIndex(table:string,index:IndexDef):Promise<Result<{changes?:number;}>>;dropIndex(indexName:string):Promise<Result<{changes?:number;}>>;private getTableInfoSync;}
|
|
1
|
+
import type {Logger} from '../utils/logger';import{type ColumnDef,type IndexDef} from '../sql/generator';import type {DatabaseDialect,DbOpenOptions,IDatabase,ReferencingTableInfo,Result,RowFilters,SavedQuery,SchemaInfo,SQLInputValue,TableInfoData,TableListItem,WhereClause} from './types';export * from './types';export * from './filters';export declare class SqliteDatabase implements IDatabase{private db;private logger;readonly path:string;readonly isReadOnly:boolean;readonly dialect:DatabaseDialect;constructor(dbPath:string,logger:Logger,options?:DbOpenOptions);private readonlyBlocked;close():void;private initSchema;private tryRun;private transaction;private toBind;all(sql:string,params?:SQLInputValue[]):Promise<Result<unknown[]>>;run(sql:string,params?:SQLInputValue[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;execResult(sql:string):Promise<Result<{changes?:number;}>>;hasMultipleStatements(sql:string):boolean;runWrite(sql:string):Promise<Result<{changes?:number;}>>;listTables():Promise<Result<TableListItem[]>>;getTableInfo(table:string):Promise<Result<TableInfoData>>;getRowCount(table:string,filters?:RowFilters):Promise<Result<number>>;getRows(table:string,opts?:{page?:number;limit?:number;orderBy?:string;orderDir?:'asc'|'desc';filters?:RowFilters;}):Promise<Result<Record<string,unknown>[]>>;getAllRows(table:string):Promise<Result<Record<string,unknown>[]>>;getRow(table:string,where:WhereClause[]):Promise<Result<Record<string,unknown>|null>>;insertRow(table:string,fields:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;insertRows(table:string,rows:WhereClause[][]):Promise<Result<{inserted:number;skipped:number;}>>;updateRow(table:string,fields:WhereClause[],where:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;updateRows(table:string,rows:{fields:WhereClause[];where:WhereClause[];}[]):Promise<Result<{updated:number;}>>;deleteRow(table:string,where:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;deleteRows(table:string,rows:WhereClause[][]):Promise<Result<{deleted:number;}>>;getRowsByPks(table:string,pks:WhereClause[][]):Promise<Result<Record<string,unknown>[]>>;getCreateStatement(table:string):Promise<Result<string|null>>;listSavedQueries():Promise<Result<SavedQuery[]>>;saveQuery(name:string,sql:string):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;deleteSavedQuery(id:string|number):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;getSettings():Promise<Result<Record<string,string>>>;getSchema(table:string):Promise<Result<SchemaInfo>>;getReferencingTables(table:string):Promise<Result<ReferencingTableInfo[]>>;getRowsByFk(table:string,column:string,value:unknown,limit?:number):Promise<Result<{rows:Record<string,unknown>[];total:number;}>>;renameTable(oldName:string,newName:string):Promise<Result<{changes?:number;}>>;addColumn(table:string,col:ColumnDef):Promise<Result<{changes?:number;}>>;modifyColumn(table:string,oldColName:string,newColDef:ColumnDef):Promise<Result<{changes?:number;}>>;renameColumn(table:string,oldName:string,newName:string):Promise<Result<{changes?:number;}>>;dropColumn(table:string,column:string):Promise<Result<{changes?:number;}>>;dropTable(table:string):Promise<Result<{changes?:number;}>>;createIndex(table:string,index:IndexDef):Promise<Result<{changes?:number;}>>;dropIndex(indexName:string):Promise<Result<{changes?:number;}>>;private getTableInfoSync;}
|