@kyro-cms/core 0.13.1 → 0.13.3
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/api-handler-graphql.cjs +1 -1
- package/dist/api-handler-graphql.js +1 -1
- package/dist/api-handler-trpc.cjs +1 -1
- package/dist/api-handler-trpc.js +1 -1
- package/dist/api-handler.cjs +1 -1
- package/dist/api-handler.js +1 -1
- package/dist/base-A9AJPCG5.d.ts +219 -0
- package/dist/base-C6wyX2nC.d.cts +219 -0
- package/dist/bootstrap-PG2LGDLB.js +1 -0
- package/dist/bootstrap-YD3GLTWX.cjs +1 -0
- package/dist/chunk-22RXJ442.js +57 -0
- package/dist/chunk-2SPWRQ5O.js +122 -0
- package/dist/chunk-32QY56XF.js +122 -0
- package/dist/chunk-4NTIK6DF.cjs +2 -0
- package/dist/chunk-6E44MQQ5.js +115 -0
- package/dist/chunk-6LWF5MPL.js +20 -0
- package/dist/chunk-7KLEANTO.cjs +1 -0
- package/dist/chunk-A7LZ6T42.cjs +1 -0
- package/dist/chunk-DSHKQL3R.cjs +121 -0
- package/dist/chunk-ELFQKQLL.js +2 -0
- package/dist/chunk-EQN3HDES.cjs +123 -0
- package/dist/chunk-EW424IBO.cjs +1 -0
- package/dist/chunk-GTR7JAKP.cjs +3 -0
- package/dist/chunk-HPIJI7TM.js +3 -0
- package/dist/chunk-J6V573PE.cjs +1 -0
- package/dist/chunk-JB4WG2YJ.cjs +121 -0
- package/dist/chunk-K73HOMQY.cjs +56 -0
- package/dist/chunk-LBLFU6KI.js +57 -0
- package/dist/chunk-LP3HRZGK.js +57 -0
- package/dist/chunk-MLCBSEBU.js +2 -0
- package/dist/chunk-NRE6VKL6.cjs +121 -0
- package/dist/chunk-O7CBGP4N.cjs +1 -0
- package/dist/chunk-OJ3H4AQ2.cjs +56 -0
- package/dist/chunk-OOVNTOZC.cjs +56 -0
- package/dist/chunk-PYUWSKKP.js +57 -0
- package/dist/chunk-QYN6C3FZ.cjs +114 -0
- package/dist/chunk-RYXLEFS5.js +2 -0
- package/dist/chunk-SRIXRJHL.js +4 -0
- package/dist/chunk-TEY5LZ26.cjs +56 -0
- package/dist/chunk-UWVBFRCW.js +2 -0
- package/dist/chunk-UZWYFEUN.js +122 -0
- package/dist/chunk-V4FAL7AG.js +2 -0
- package/dist/chunk-VOYPKTID.cjs +1 -0
- package/dist/chunk-WAVGRSE6.js +2 -0
- package/dist/chunk-WNU76M2C.js +124 -0
- package/dist/chunk-XDQVYCIR.cjs +1 -0
- package/dist/chunk-XOR64WUQ.cjs +19 -0
- package/dist/chunk-XP7BXFXT.cjs +121 -0
- package/dist/chunk-YGI5W4RS.js +2 -0
- package/dist/chunk-Z2SN2MYP.js +122 -0
- package/dist/cli/index.cjs +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/client.d.cts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/drizzle/index.cjs +1 -1
- package/dist/drizzle/index.d.cts +1 -1
- package/dist/drizzle/index.d.ts +1 -1
- package/dist/drizzle/index.js +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -4
- package/dist/local-6UUGBZ4M.js +1 -0
- package/dist/local-ZYHV3J2K.cjs +1 -0
- package/dist/mongo-auth-adapter-2H2AXDRH.cjs +1 -0
- package/dist/mongo-auth-adapter-YWMEOC42.js +1 -0
- package/dist/mongodb/index.cjs +1 -1
- package/dist/mongodb/index.d.cts +1 -1
- package/dist/mongodb/index.d.ts +1 -1
- package/dist/mongodb/index.js +1 -1
- package/dist/postgres-auth-adapter-QKBNXVPT.js +1 -0
- package/dist/postgres-auth-adapter-WMLM4UUC.cjs +1 -0
- package/dist/redis-adapter-EVK2SMKH.cjs +1 -0
- package/dist/redis-adapter-LY2NBSAG.js +1 -0
- package/dist/rest/index.cjs +1 -1
- package/dist/rest/index.js +1 -1
- package/dist/sqlite-adapter-KPSISY6E.cjs +1 -0
- package/dist/sqlite-adapter-PI6SIY7O.js +1 -0
- package/dist/templates/index.cjs +1 -1
- package/dist/templates/index.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {g}from'./chunk-Y2YAKDEQ.js';if (typeof window === "undefined") { const { createRequire } = await import(/* @vite-ignore */ 'module'); createRequire(import.meta.url); }
|
|
2
|
+
g();var t={slug:"users",label:"Users",auth:true,fields:[{name:"name",type:"text",label:"Name"},{name:"email",type:"email",required:true},{name:"passwordHash",type:"text",label:"Password Hash",admin:{hidden:true}},{name:"role",type:"select",options:[{label:"Super Admin",value:"super_admin"},{label:"Admin",value:"admin"},{label:"Editor",value:"editor"},{label:"Author",value:"author"},{label:"Customer",value:"customer"},{label:"Guest",value:"guest"}],required:true},{name:"avatar",type:"upload",relationTo:"media",label:"Profile Picture"},{name:"tenantId",type:"text",label:"Tenant"},{name:"emailVerified",type:"checkbox",label:"Email Verified"},{name:"locked",type:"checkbox"},{name:"lastLogin",type:"date",time:true,label:"Last Login",admin:{readOnly:true}},{name:"failedLoginAttempts",type:"number",label:"Failed Login Attempts",admin:{readOnly:true}},{name:"metadata",type:"json",label:"Metadata",admin:{hidden:true}}],timestamps:true,admin:{useAsTitle:"email",defaultColumns:["email","role","tenantId","lastLogin"]}},a={slug:"audit_logs",label:"Audit Logs",access:{create:()=>false,update:()=>false,delete:()=>false},fields:[{name:"action",type:"text",required:true},{name:"userId",type:"text",label:"User ID"},{name:"userEmail",type:"email",label:"User Email"},{name:"role",type:"text"},{name:"resource",type:"text",label:"Resource",required:true},{name:"resourceId",type:"text",label:"Resource ID"},{name:"changes",type:"json",label:"Changes"},{name:"ipAddress",type:"text",label:"IP Address"},{name:"userAgent",type:"text",label:"User Agent"},{name:"success",type:"checkbox"},{name:"error",type:"text",label:"Error"},{name:"metadata",type:"json",label:"Metadata"},{name:"timestamp",type:"date",time:true,required:true,admin:{readOnly:true}}],admin:{defaultColumns:["action","userEmail","resource","success","timestamp"]}},s={users:t,audit_logs:a};export{t as a,s as b};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var chunkK73HOMQY_cjs=require('./chunk-K73HOMQY.cjs'),chunk3O3AVMWM_cjs=require('./chunk-3O3AVMWM.cjs'),chunkXP7BXFXT_cjs=require('./chunk-XP7BXFXT.cjs'),chunkOPTVCCQQ_cjs=require('./chunk-OPTVCCQQ.cjs'),chunkN4FXLQE3_cjs=require('./chunk-N4FXLQE3.cjs'),chunkXBQ6HV3T_cjs=require('./chunk-XBQ6HV3T.cjs'),chunkEYHD7HZE_cjs=require('./chunk-EYHD7HZE.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs'),w=require('kyro:config');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var w__default=/*#__PURE__*/_interopDefault(w);chunkBUNLC3II_cjs.h();exports.a=null;var l=null;async function b(){if(!exports.a){if(globalThis.__KYRO_INSTANCE__)try{await globalThis.__KYRO_INSTANCE__.shutdown();}catch{}try{let e=w__default.default.default||w__default.default,t=e.adapter,o=t&&!t.dialect&&typeof t.connect=="function";if(globalThis.DB&&(!t||o)){let s=globalThis.DB;e.adapter=new chunkN4FXLQE3_cjs.c({type:"sqlite",client:s}),chunkK73HOMQY_cjs.K.info("Hot-swapped to D1 DrizzleAdapter");}exports.a=chunkK73HOMQY_cjs.H(e),await exports.a.init();let a=e.adapter,p=a&&a.dialect&&(a.dialect==="postgres"||a.dialect==="sqlite"),c=a&&a.dialect==="mongodb",n;if(p)a.dialect==="postgres"?n=new chunkXBQ6HV3T_cjs.a({db:a.client}):a.dialect==="sqlite"&&(n=new chunkXP7BXFXT_cjs.hb({db:a.rawClient||a.client}));else if(o&&!globalThis.DB){let s=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";n=new chunkOPTVCCQQ_cjs.a({path:s});}else c&&(n=new chunkEYHD7HZE_cjs.a({adapter:a}));if(n?.connect)try{await n.connect();}catch(s){chunkK73HOMQY_cjs.K.warn("Auth connect warning:",s);}try{await exports.a.loadSettings();}catch(s){chunkK73HOMQY_cjs.K.warn("loadSettings warning:",s);}try{await chunk3O3AVMWM_cjs.e(n);}catch(s){chunkK73HOMQY_cjs.K.warn("autoBootstrap warning:",s);}globalThis.__KYRO_INSTANCE__=exports.a;}catch(e){throw exports.a=null,l=null,chunkK73HOMQY_cjs.K.error("Init failed, will retry:",e),e}}}async function E(e){let t=globalThis.DB?globalThis:null;try{let{env:o}=await import('cloudflare:workers');o&&(t=o);}catch{}if(e)try{t=e.locals?.cfContext?.env||e?.env||t;}catch{}if(!t)try{t=process.env;}catch{}t?.DB&&(globalThis.DB=t.DB),t?.STORAGE_BUCKET&&(globalThis.STORAGE_BUCKET=t.STORAGE_BUCKET),l||(l=b()),await l;}var _={graphqlEnabled:false,trpcEnabled:false,wsEnabled:false,requireAuth:false};function T(e){return exports.a?exports.a.settings?.access?.apiAccess?.[e]??_[e]??true:_[e]??true}var R=async e=>{if(!exports.a)try{await Promise.race([E(e),new Promise((t,o)=>setTimeout(()=>o(new Error("Initialization timeout")),3e4))]);}catch(t){return console.error("[Kyro API] Warm error:",t?.stack||t?.message||t),new Response(JSON.stringify({error:"Service Unavailable",message:"Kyro CMS is still starting up. Please try again in a moment."}),{status:503,headers:{"Content-Type":"application/json","Retry-After":"5"}})}try{let o=new URL(e.request.url).pathname,a=__KYRO_API_PATH__;if(o===`${a}/graphql`&&typeof exports.a.getGraphQL=="function"){if(!T("graphqlEnabled"))return new Response(JSON.stringify({error:"GraphQL is disabled"}),{status:503,headers:{"Content-Type":"application/json"}});let n=await exports.a.getGraphQL().fetch(e.request,e.locals);return new Response(n.body,n)}if(o.startsWith(`${a}/trpc/`)&&typeof exports.a.getTRPC=="function"){if(!T("trpcEnabled"))return new Response(JSON.stringify({error:"tRPC is disabled"}),{status:503,headers:{"Content-Type":"application/json"}});let n=await exports.a.getTRPC().fetch(e.request,e.locals);return new Response(n.body,n)}return await(await exports.a.getREST()).fetch(e.request,e.locals)}catch(t){return console.error("[Kyro API Execution Error]:",t?.stack||t?.message||t),new Response(JSON.stringify({error:"Internal Server Error",message:t?.message||String(t),stack:t?.stack}),{status:500,headers:{"Content-Type":"application/json"}})}},L=R;exports.b=E;exports.c=R;exports.d=L;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {K,H}from'./chunk-PYUWSKKP.js';import {e}from'./chunk-RYXLEFS5.js';import {hb}from'./chunk-2SPWRQ5O.js';import {a as a$1}from'./chunk-WNU76M2C.js';import {c}from'./chunk-6NBZDW53.js';import {a}from'./chunk-6E44MQQ5.js';import {a as a$2}from'./chunk-YGI5W4RS.js';import {g}from'./chunk-Y2YAKDEQ.js';import w from'kyro:config';if (typeof window === "undefined") { const { createRequire } = await import(/* @vite-ignore */ 'module'); createRequire(import.meta.url); }
|
|
2
|
+
g();var r=null,l=null;async function b(){if(!r){if(globalThis.__KYRO_INSTANCE__)try{await globalThis.__KYRO_INSTANCE__.shutdown();}catch{}try{let e$1=w.default||w,t=e$1.adapter,o=t&&!t.dialect&&typeof t.connect=="function";if(globalThis.DB&&(!t||o)){let s=globalThis.DB;e$1.adapter=new c({type:"sqlite",client:s}),K.info("Hot-swapped to D1 DrizzleAdapter");}r=H(e$1),await r.init();let a$3=e$1.adapter,p=a$3&&a$3.dialect&&(a$3.dialect==="postgres"||a$3.dialect==="sqlite"),c$1=a$3&&a$3.dialect==="mongodb",n;if(p)a$3.dialect==="postgres"?n=new a({db:a$3.client}):a$3.dialect==="sqlite"&&(n=new hb({db:a$3.rawClient||a$3.client}));else if(o&&!globalThis.DB){let s=process.env.KYRO_AUTH_DB_PATH||"./data/auth.db";n=new a$1({path:s});}else c$1&&(n=new a$2({adapter:a$3}));if(n?.connect)try{await n.connect();}catch(s){K.warn("Auth connect warning:",s);}try{await r.loadSettings();}catch(s){K.warn("loadSettings warning:",s);}try{await e(n);}catch(s){K.warn("autoBootstrap warning:",s);}globalThis.__KYRO_INSTANCE__=r;}catch(e){throw r=null,l=null,K.error("Init failed, will retry:",e),e}}}async function E(e){let t=globalThis.DB?globalThis:null;try{let{env:o}=await import('cloudflare:workers');o&&(t=o);}catch{}if(e)try{t=e.locals?.cfContext?.env||e?.env||t;}catch{}if(!t)try{t=process.env;}catch{}t?.DB&&(globalThis.DB=t.DB),t?.STORAGE_BUCKET&&(globalThis.STORAGE_BUCKET=t.STORAGE_BUCKET),l||(l=b()),await l;}var _={graphqlEnabled:false,trpcEnabled:false,wsEnabled:false,requireAuth:false};function T(e){return r?r.settings?.access?.apiAccess?.[e]??_[e]??true:_[e]??true}var R=async e=>{if(!r)try{await Promise.race([E(e),new Promise((t,o)=>setTimeout(()=>o(new Error("Initialization timeout")),3e4))]);}catch(t){return console.error("[Kyro API] Warm error:",t?.stack||t?.message||t),new Response(JSON.stringify({error:"Service Unavailable",message:"Kyro CMS is still starting up. Please try again in a moment."}),{status:503,headers:{"Content-Type":"application/json","Retry-After":"5"}})}try{let o=new URL(e.request.url).pathname,a=__KYRO_API_PATH__;if(o===`${a}/graphql`&&typeof r.getGraphQL=="function"){if(!T("graphqlEnabled"))return new Response(JSON.stringify({error:"GraphQL is disabled"}),{status:503,headers:{"Content-Type":"application/json"}});let n=await r.getGraphQL().fetch(e.request,e.locals);return new Response(n.body,n)}if(o.startsWith(`${a}/trpc/`)&&typeof r.getTRPC=="function"){if(!T("trpcEnabled"))return new Response(JSON.stringify({error:"tRPC is disabled"}),{status:503,headers:{"Content-Type":"application/json"}});let n=await r.getTRPC().fetch(e.request,e.locals);return new Response(n.body,n)}return await(await r.getREST()).fetch(e.request,e.locals)}catch(t){return console.error("[Kyro API Execution Error]:",t?.stack||t?.message||t),new Response(JSON.stringify({error:"Internal Server Error",message:t?.message||String(t),stack:t?.stack}),{status:500,headers:{"Content-Type":"application/json"}})}},N=R;export{r as a,E as b,R as c,N as d};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {a}from'./chunk-7NH7H3WA.js';import {g,e}from'./chunk-Y2YAKDEQ.js';import {randomBytes}from'crypto';import {mkdirSync}from'fs';import {dirname}from'path';import {createRequire}from'module';if (typeof window === "undefined") { const { createRequire } = await import(/* @vite-ignore */ 'module'); createRequire(import.meta.url); }
|
|
2
|
+
g();var l=e(a(),1);g();var T=`
|
|
3
|
+
CREATE TABLE IF NOT EXISTS kyro_users (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
name TEXT,
|
|
6
|
+
email TEXT UNIQUE NOT NULL,
|
|
7
|
+
password_hash TEXT NOT NULL,
|
|
8
|
+
role TEXT NOT NULL DEFAULT 'customer',
|
|
9
|
+
tenant_id TEXT,
|
|
10
|
+
email_verified INTEGER DEFAULT 0,
|
|
11
|
+
locked INTEGER DEFAULT 0,
|
|
12
|
+
last_login TEXT,
|
|
13
|
+
failed_login_attempts INTEGER DEFAULT 0,
|
|
14
|
+
locked_until TEXT,
|
|
15
|
+
avatar TEXT,
|
|
16
|
+
metadata TEXT,
|
|
17
|
+
created_at TEXT NOT NULL,
|
|
18
|
+
updated_at TEXT NOT NULL
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS kyro_sessions (
|
|
22
|
+
id TEXT PRIMARY KEY,
|
|
23
|
+
user_id TEXT NOT NULL,
|
|
24
|
+
token TEXT NOT NULL,
|
|
25
|
+
refresh_token TEXT,
|
|
26
|
+
expires_at TEXT NOT NULL,
|
|
27
|
+
created_at TEXT NOT NULL,
|
|
28
|
+
ip_address TEXT,
|
|
29
|
+
user_agent TEXT,
|
|
30
|
+
FOREIGN KEY (user_id) REFERENCES kyro_users(id) ON DELETE CASCADE
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE TABLE IF NOT EXISTS kyro_password_history (
|
|
34
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
35
|
+
user_id TEXT NOT NULL,
|
|
36
|
+
password_hash TEXT NOT NULL,
|
|
37
|
+
created_at TEXT NOT NULL,
|
|
38
|
+
FOREIGN KEY (user_id) REFERENCES kyro_users(id) ON DELETE CASCADE
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE TABLE IF NOT EXISTS kyro_rate_limits (
|
|
42
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
43
|
+
key TEXT NOT NULL,
|
|
44
|
+
window_start INTEGER NOT NULL,
|
|
45
|
+
count INTEGER NOT NULL DEFAULT 1,
|
|
46
|
+
UNIQUE(key, window_start)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
CREATE TABLE IF NOT EXISTS kyro_lockouts (
|
|
50
|
+
user_id TEXT PRIMARY KEY,
|
|
51
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
52
|
+
last_attempt INTEGER,
|
|
53
|
+
locked_at INTEGER,
|
|
54
|
+
locked_until INTEGER
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
CREATE TABLE IF NOT EXISTS kyro_audit_logs (
|
|
58
|
+
id TEXT PRIMARY KEY,
|
|
59
|
+
timestamp TEXT NOT NULL,
|
|
60
|
+
action TEXT NOT NULL,
|
|
61
|
+
user_id TEXT,
|
|
62
|
+
user_email TEXT,
|
|
63
|
+
role TEXT,
|
|
64
|
+
resource TEXT NOT NULL,
|
|
65
|
+
resource_id TEXT,
|
|
66
|
+
ip_address TEXT,
|
|
67
|
+
user_agent TEXT,
|
|
68
|
+
success INTEGER NOT NULL,
|
|
69
|
+
error TEXT,
|
|
70
|
+
metadata TEXT,
|
|
71
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_users_email ON kyro_users(email);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_sessions_user_id ON kyro_sessions(user_id);
|
|
76
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_sessions_token ON kyro_sessions(token);
|
|
77
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_sessions_refresh_token ON kyro_sessions(refresh_token);
|
|
78
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_sessions_expires ON kyro_sessions(expires_at);
|
|
79
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_password_history_user_id ON kyro_password_history(user_id);
|
|
80
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_rate_limits_key ON kyro_rate_limits(key);
|
|
81
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_rate_limits_window ON kyro_rate_limits(window_start);
|
|
82
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_lockouts_locked_until ON kyro_lockouts(locked_until);
|
|
83
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_audit_logs_timestamp ON kyro_audit_logs(timestamp);
|
|
84
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_audit_logs_action ON kyro_audit_logs(action);
|
|
85
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_audit_logs_user_id ON kyro_audit_logs(user_id);
|
|
86
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_audit_logs_resource ON kyro_audit_logs(resource);
|
|
87
|
+
|
|
88
|
+
CREATE TABLE IF NOT EXISTS kyro_email_verifications (
|
|
89
|
+
id TEXT PRIMARY KEY,
|
|
90
|
+
user_id TEXT NOT NULL,
|
|
91
|
+
token TEXT UNIQUE NOT NULL,
|
|
92
|
+
expires_at TEXT NOT NULL,
|
|
93
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
94
|
+
FOREIGN KEY (user_id) REFERENCES kyro_users(id) ON DELETE CASCADE
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
CREATE TABLE IF NOT EXISTS kyro_password_resets (
|
|
98
|
+
id TEXT PRIMARY KEY,
|
|
99
|
+
user_id TEXT NOT NULL,
|
|
100
|
+
token TEXT UNIQUE NOT NULL,
|
|
101
|
+
expires_at TEXT NOT NULL,
|
|
102
|
+
used_at TEXT,
|
|
103
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
104
|
+
FOREIGN KEY (user_id) REFERENCES kyro_users(id) ON DELETE CASCADE
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_email_verifications_token ON kyro_email_verifications(token);
|
|
108
|
+
CREATE INDEX IF NOT EXISTS idx_kyro_password_resets_token ON kyro_password_resets(token);
|
|
109
|
+
`;var E;function L(){return E||(E=createRequire("file:///")("node:sqlite").DatabaseSync,E)}var R=5e3,N=1e3,f=-64e3,I=268435456,p=class{db=null;path;saltRounds;externalDb;busyTimeout;walAutoCheckpoint;cacheSize;mmapSize;preparedStatements=new Map;constructor(e={}){this.path=e.path||"./data/auth.db",this.saltRounds=e.saltRounds||12,this.externalDb=!!e.db,this.busyTimeout=e.busyTimeout??R,this.walAutoCheckpoint=e.walAutoCheckpoint??N,this.cacheSize=e.cacheSize??f,this.mmapSize=e.mmapSize??I,e.db&&(this.db=e.db);}async connect(){if(this.db)return;let e=dirname(this.path);e&&e!=="."&&mkdirSync(e,{recursive:true}),this.db=new(L())(this.path),this.db.exec(`PRAGMA busy_timeout = ${this.busyTimeout}`),this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA cache_size = "+this.cacheSize),this.db.exec("PRAGMA mmap_size = "+this.mmapSize),this.db.exec("PRAGMA wal_autocheckpoint = "+this.walAutoCheckpoint),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA temp_store = MEMORY"),this.ensureTables(),this.prepareStatements();}async disconnect(){this.db&&!this.externalDb&&(this.db.exec("PRAGMA wal_checkpoint(TRUNCATE)"),this.db.close(),this.db=null,this.preparedStatements.clear());}async ensureConnected(){if(this.db||await this.connect(),!this.db)throw new Error("Failed to connect to SQLite database");return this.db}ensureTables(){if(this.db){this.db.exec(T);try{this.db.exec("ALTER TABLE kyro_users ADD COLUMN name TEXT");}catch{}try{this.db.exec("ALTER TABLE kyro_users ADD COLUMN avatar TEXT");}catch{}try{this.db.exec("ALTER TABLE kyro_users ADD COLUMN metadata TEXT");}catch{}try{this.db.exec("ALTER TABLE kyro_audit_logs ADD COLUMN metadata TEXT");}catch{}try{this.db.exec("ALTER TABLE kyro_audit_logs ADD COLUMN resource_id TEXT");}catch{}}}prepareStatements(){this.db&&(this.preparedStatements.set("findUserByEmail",this.db.prepare("SELECT * FROM kyro_users WHERE email = ?")),this.preparedStatements.set("findUserById",this.db.prepare("SELECT * FROM kyro_users WHERE id = ?")),this.preparedStatements.set("findSessionByToken",this.db.prepare("SELECT * FROM kyro_sessions WHERE token = ?")),this.preparedStatements.set("findSessionByRefreshToken",this.db.prepare("SELECT * FROM kyro_sessions WHERE refresh_token = ?")),this.preparedStatements.set("deleteSession",this.db.prepare("DELETE FROM kyro_sessions WHERE id = ? OR token = ?")),this.preparedStatements.set("deleteUserSessions",this.db.prepare("DELETE FROM kyro_sessions WHERE user_id = ?")),this.preparedStatements.set("countUsers",this.db.prepare("SELECT COUNT(*) as count FROM kyro_users")),this.preparedStatements.set("deleteUser",this.db.prepare("DELETE FROM kyro_users WHERE id = ?")),this.preparedStatements.set("findUsersPaginated",this.db.prepare("SELECT * FROM kyro_users ORDER BY created_at DESC LIMIT ? OFFSET ?")),this.preparedStatements.set("findUsersWithSearch",this.db.prepare("SELECT * FROM kyro_users WHERE email LIKE ? ORDER BY created_at DESC LIMIT ? OFFSET ?")),this.preparedStatements.set("countUsersWithSearch",this.db.prepare("SELECT COUNT(*) as count FROM kyro_users WHERE email LIKE ?")),this.preparedStatements.set("getPasswordHistory",this.db.prepare("SELECT password_hash FROM kyro_password_history WHERE user_id = ? ORDER BY created_at DESC LIMIT ?")),this.preparedStatements.set("addPasswordHistory",this.db.prepare("INSERT INTO kyro_password_history (user_id, password_hash, created_at) VALUES (?, ?, ?)")),this.preparedStatements.set("trimPasswordHistory",this.db.prepare(`DELETE FROM kyro_password_history WHERE id IN (
|
|
110
|
+
SELECT id FROM kyro_password_history WHERE user_id = ? ORDER BY created_at DESC LIMIT -1 OFFSET 5
|
|
111
|
+
)`)),this.preparedStatements.set("deleteExpiredSessions",this.db.prepare("DELETE FROM kyro_sessions WHERE expires_at < ?")),this.preparedStatements.set("cleanupOldAuditLogs",this.db.prepare("DELETE FROM kyro_audit_logs WHERE timestamp < ?")),this.preparedStatements.set("cleanupExpiredLockouts",this.db.prepare("UPDATE kyro_lockouts SET attempts = 0, locked_at = NULL, locked_until = NULL WHERE locked_until < ?")),this.preparedStatements.set("getLockout",this.db.prepare("SELECT * FROM kyro_lockouts WHERE user_id = ?")),this.preparedStatements.set("upsertLockout",this.db.prepare(`
|
|
112
|
+
INSERT INTO kyro_lockouts (user_id, attempts, last_attempt, locked_at, locked_until)
|
|
113
|
+
VALUES (?, ?, ?, ?, ?)
|
|
114
|
+
ON CONFLICT(user_id) DO UPDATE SET
|
|
115
|
+
attempts = excluded.attempts,
|
|
116
|
+
last_attempt = excluded.last_attempt,
|
|
117
|
+
locked_at = excluded.locked_at,
|
|
118
|
+
locked_until = excluded.locked_until
|
|
119
|
+
`)),this.preparedStatements.set("resetLockout",this.db.prepare("UPDATE kyro_lockouts SET attempts = 0, locked_at = NULL, locked_until = NULL WHERE user_id = ?")));}stmt(e){let s=this.preparedStatements.get(e);if(!s)throw new Error(`Prepared statement not found: ${e}`);return s}async cleanupExpiredSessions(){return await this.ensureConnected(),this.stmt("deleteExpiredSessions").run(new Date().toISOString()).changes}async cleanupOldAuditLogs(e=30){await this.ensureConnected();let s=new Date(Date.now()-e*24*60*60*1e3).toISOString();return this.stmt("cleanupOldAuditLogs").run(s).changes}async getStats(){await this.ensureConnected();let e=this.stmt("countUsers").get().count,s=this.db.prepare("SELECT COUNT(*) as count FROM kyro_sessions WHERE expires_at > ?").get(new Date().toISOString()).count,t=this.db.prepare("SELECT COUNT(*) as count FROM kyro_audit_logs").get().count;return {userCount:e,activeSessionCount:s,auditLogCount:t}}async createUser(e){await this.ensureConnected();let s=randomBytes(16).toString("hex"),t=new Date().toISOString(),r=await this.hashPassword(e.password),i={id:s,name:e.name,email:e.email.toLowerCase(),passwordHash:r,role:e.role||"customer",avatar:e.avatar,tenantId:e.tenantId,createdAt:t,updatedAt:t};return this.db.prepare(`INSERT INTO kyro_users (id, name, email, password_hash, role, avatar, tenant_id, metadata, created_at, updated_at)
|
|
120
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(s,i.name||null,i.email,i.passwordHash,i.role,i.avatar||null,i.tenantId||null,i.metadata?JSON.stringify(i.metadata):null,t,t),i}async findUserByEmail(e){await this.ensureConnected();let s=this.stmt("findUserByEmail").get(e.toLowerCase());return s?this.rowToUser(s):null}async findUserById(e){await this.ensureConnected();let s=this.stmt("findUserById").get(e);return s?this.rowToUser(s):null}async updateUser(e,s){if(await this.ensureConnected(),!await this.findUserById(e))return null;let r=[],i=[];return s.email!==void 0&&(r.push("email = ?"),i.push(s.email.toLowerCase())),s.name!==void 0&&(r.push("name = ?"),i.push(s.name)),s.passwordHash!==void 0&&(r.push("password_hash = ?"),i.push(s.passwordHash)),s.role!==void 0&&(r.push("role = ?"),i.push(s.role)),s.avatar!==void 0&&(r.push("avatar = ?"),i.push(s.avatar)),s.tenantId!==void 0&&(r.push("tenant_id = ?"),i.push(s.tenantId)),s.metadata!==void 0&&(r.push("metadata = ?"),i.push(s.metadata?JSON.stringify(s.metadata):null)),s.emailVerified!==void 0&&(r.push("email_verified = ?"),i.push(s.emailVerified?1:0)),s.locked!==void 0&&(r.push("locked = ?"),i.push(s.locked?1:0)),s.lastLogin!==void 0&&(r.push("last_login = ?"),i.push(s.lastLogin)),s.failedLoginAttempts!==void 0&&(r.push("failed_login_attempts = ?"),i.push(s.failedLoginAttempts)),r.push("updated_at = ?"),i.push(new Date().toISOString()),i.push(e),this.db.prepare(`UPDATE kyro_users SET ${r.join(", ")} WHERE id = ?`).run(...i),this.findUserById(e)}async deleteUser(e){return await this.ensureConnected(),this.stmt("deleteUser").run(e).changes>0}async hashPassword(e){return l.default.hash(e,this.saltRounds)}async verifyPassword(e,s){await this.ensureConnected();let t=await this.findUserByEmail(e);if(!t)return null;let r=this.db.prepare("SELECT password_hash FROM kyro_users WHERE id = ?").get(t.id);return r?.password_hash&&await l.default.compare(s,r.password_hash)?t:null}async createSession(e,s={}){await this.ensureConnected();let t=randomBytes(32).toString("hex"),r=randomBytes(32).toString("base64url"),i=randomBytes(32).toString("base64url"),d=new Date,u=new Date(d.getTime()+864e5).toISOString(),n={id:t,userId:e,token:r,refreshToken:i,expiresAt:u,createdAt:d.toISOString(),ipAddress:s.ipAddress,userAgent:s.userAgent};return this.db.prepare(`INSERT INTO kyro_sessions (id, user_id, token, refresh_token, expires_at, created_at, ip_address, user_agent)
|
|
121
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(n.id,n.userId,n.token,n.refreshToken??null,n.expiresAt,n.createdAt,n.ipAddress??null,n.userAgent??null),n}async findSessionByToken(e){await this.ensureConnected();let s=this.stmt("findSessionByToken").get(e);return s?this.rowToSession(s):null}async findSessionByRefreshToken(e){await this.ensureConnected();let s=this.stmt("findSessionByRefreshToken").get(e);return s?this.rowToSession(s):null}async deleteSession(e){return await this.ensureConnected(),this.stmt("deleteSession").run(e,e).changes>0}async deleteUserSessions(e){return await this.ensureConnected(),this.stmt("deleteUserSessions").run(e).changes}async hasAnyUsers(){return await this.ensureConnected(),this.stmt("countUsers").get().count>0}async findUsers(e={}){await this.ensureConnected();let s=e.page??1,t=e.limit??10,r=(s-1)*t,i=e.search,d,u;if(i){let n=`%${i}%`;d=this.stmt("countUsersWithSearch").get(n).count,u=this.stmt("findUsersWithSearch").all(n,t,r);}else d=this.stmt("countUsers").get().count,u=this.stmt("findUsersPaginated").all(t,r);return {users:u.map(n=>this.rowToUser(n)),total:d}}async addPasswordToHistory(e,s){await this.ensureConnected(),this.stmt("addPasswordHistory").run(e,s,new Date().toISOString()),this.stmt("trimPasswordHistory").run(e);}async getPasswordHistory(e,s=5){return await this.ensureConnected(),this.stmt("getPasswordHistory").all(e,s).map(r=>r.password_hash)}async isPasswordInHistory(e,s,t=5){let r=await this.getPasswordHistory(s,t);for(let i of r)if(await l.default.compare(e,i))return true;return false}async recordFailedAttempt(e){await this.ensureConnected();let s=Date.now(),t=this.stmt("getLockout").get(e),r=(t?.attempts||0)+1,i=r>=5?s+900*1e3:t?.locked_until||null;this.stmt("upsertLockout").run(e,r,s,i!==null?s:null,i);}async resetAttempts(e){await this.ensureConnected(),this.stmt("resetLockout").run(e);}async checkLockout(e){await this.ensureConnected(),this.stmt("cleanupExpiredLockouts").run(Date.now());let s=this.stmt("getLockout").get(e);return s?s.locked_until!==null&&s.locked_until>Date.now()?{locked:true,attemptsRemaining:0,lockedUntil:new Date(s.locked_until),totalAttempts:s.attempts}:{locked:false,attemptsRemaining:Math.max(0,5-s.attempts),totalAttempts:s.attempts}:{locked:false,attemptsRemaining:5,totalAttempts:0}}async logAudit(e){await this.ensureConnected();let s=randomBytes(16).toString("hex"),t=new Date().toISOString();return this.db.prepare(`INSERT INTO kyro_audit_logs (
|
|
122
|
+
id, timestamp, action, user_id, user_email, role, resource, resource_id,
|
|
123
|
+
ip_address, user_agent, success, error, metadata, created_at
|
|
124
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(s,t,e.action,e.userId||null,e.userEmail||null,e.role||null,e.resource,e.resourceId||null,e.ipAddress||null,e.userAgent||null,e.success?1:0,e.error||null,e.metadata?JSON.stringify(e.metadata):null,new Date().toISOString()),s}async queryAuditLogs(e={}){await this.ensureConnected();let s=[],t=[];e.action&&(s.push("action = ?"),t.push(e.action)),e.userId&&(s.push("user_id = ?"),t.push(e.userId)),e.resource&&(s.push("resource = ?"),t.push(e.resource)),e.success!==void 0&&(s.push("success = ?"),t.push(e.success?1:0)),e.startDate&&(s.push("timestamp >= ?"),t.push(e.startDate.toISOString())),e.endDate&&(s.push("timestamp <= ?"),t.push(e.endDate.toISOString()));let r=s.length>0?"WHERE "+s.join(" AND "):"",i=e.limit||50,d=e.offset||0,u=this.db.prepare(`SELECT COUNT(*) as count FROM kyro_audit_logs ${r}`).get(...t),n=this.db.prepare(`SELECT * FROM kyro_audit_logs ${r} ORDER BY timestamp DESC LIMIT ? OFFSET ?`).all(...t,i,d);return {total:u.count,logs:n.map(a=>({id:a.id,timestamp:new Date(a.timestamp),action:a.action,userId:a.user_id||void 0,userEmail:a.user_email||void 0,resource:a.resource,resourceId:a.resource_id||void 0,ipAddress:a.ip_address||void 0,userAgent:a.user_agent||void 0,success:a.success===1,error:a.error||void 0,metadata:a.metadata?JSON.parse(a.metadata):void 0}))}}rowToUser(e){return {id:e.id,name:e.name||void 0,email:e.email,passwordHash:e.password_hash,role:e.role,tenantId:e.tenant_id,avatar:e.avatar,metadata:e.metadata?typeof e.metadata=="string"?JSON.parse(e.metadata):e.metadata:void 0,emailVerified:e.email_verified===1,locked:e.locked===1,lastLogin:e.last_login,failedLoginAttempts:e.failed_login_attempts||0,createdAt:e.created_at,updatedAt:e.updated_at}}rowToSession(e){return {id:e.id,userId:e.user_id,token:e.token,refreshToken:e.refresh_token,expiresAt:e.expires_at,createdAt:e.created_at,ipAddress:e.ip_address,userAgent:e.user_agent}}async findAuditLogs(e){let s=await this.queryAuditLogs({action:e.action,userId:e.userId,resource:e.resource,success:e.success,startDate:e.startDate,endDate:e.endDate,limit:e.limit,offset:e.offset});return {logs:s.logs.map(t=>({...t,action:t.action})),total:s.total}}async createAuditLog(e){let s=await this.logAudit({action:e.action,userId:e.userId,userEmail:e.userEmail,role:e.role,resource:e.resource,resourceId:e.resourceId,ipAddress:e.ipAddress,userAgent:e.userAgent,success:e.success,error:e.error,metadata:e.metadata}),t=this.db?.prepare("SELECT * FROM kyro_audit_logs WHERE id = ?").get(s);return {...e,id:s,timestamp:t?new Date(t.timestamp):new Date}}async createEmailVerificationToken(e){await this.ensureConnected();let s=randomBytes(16).toString("hex"),t=randomBytes(32).toString("hex"),r=new Date(Date.now()+1440*60*1e3);return this.db.prepare("INSERT INTO kyro_email_verifications (id, user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?, ?)").run(s,e,t,r.toISOString(),new Date().toISOString()),{token:t,expiresAt:r}}async verifyEmailToken(e){await this.ensureConnected();let s=this.db.prepare("SELECT * FROM kyro_email_verifications WHERE token = ?").get(e);return s?new Date(s.expires_at)<new Date?{success:false,error:"Verification token has expired"}:(this.db.prepare("UPDATE kyro_users SET email_verified = 1 WHERE id = ?").run(s.user_id),this.db.prepare("DELETE FROM kyro_email_verifications WHERE id = ?").run(s.id),{success:true,userId:s.user_id}):{success:false,error:"Invalid verification token"}}async createPasswordResetToken(e){await this.ensureConnected();let s=await this.findUserByEmail(e);if(!s)return {token:"",expiresAt:new Date,error:"User not found"};let t=randomBytes(16).toString("hex"),r=randomBytes(32).toString("hex"),i=new Date(Date.now()+3600*1e3);return this.db.prepare("INSERT INTO kyro_password_resets (id, user_id, token, expires_at, created_at) VALUES (?, ?, ?, ?, ?)").run(t,s.id,r,i.toISOString(),new Date().toISOString()),{token:r,expiresAt:i}}async resetPasswordWithToken(e,s){await this.ensureConnected();let t=this.db.prepare("SELECT * FROM kyro_password_resets WHERE token = ?").get(e);if(!t)return {success:false,error:"Invalid reset token"};if(new Date(t.expires_at)<new Date)return {success:false,error:"Reset token has expired"};if(t.used_at)return {success:false,error:"Reset token has already been used"};let r=await this.hashPassword(s);return this.db.prepare("UPDATE kyro_users SET password_hash = ?, updated_at = ? WHERE id = ?").run(r,new Date().toISOString(),t.user_id),this.db.prepare("UPDATE kyro_password_resets SET used_at = ? WHERE id = ?").run(new Date().toISOString(),t.id),this.db.prepare("DELETE FROM kyro_sessions WHERE user_id = ?").run(t.user_id),{success:true}}};export{p as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs');chunkBUNLC3II_cjs.h();var t={slug:"users",label:"Users",auth:true,fields:[{name:"name",type:"text",label:"Name"},{name:"email",type:"email",required:true},{name:"passwordHash",type:"text",label:"Password Hash",admin:{hidden:true}},{name:"role",type:"select",options:[{label:"Super Admin",value:"super_admin"},{label:"Admin",value:"admin"},{label:"Editor",value:"editor"},{label:"Author",value:"author"},{label:"Customer",value:"customer"},{label:"Guest",value:"guest"}],required:true},{name:"avatar",type:"upload",relationTo:"media",label:"Profile Picture"},{name:"tenantId",type:"text",label:"Tenant"},{name:"emailVerified",type:"checkbox",label:"Email Verified"},{name:"locked",type:"checkbox"},{name:"lastLogin",type:"date",time:true,label:"Last Login",admin:{readOnly:true}},{name:"failedLoginAttempts",type:"number",label:"Failed Login Attempts",admin:{readOnly:true}},{name:"metadata",type:"json",label:"Metadata",admin:{hidden:true}}],timestamps:true,admin:{useAsTitle:"email",defaultColumns:["email","role","tenantId","lastLogin"]}},a={slug:"audit_logs",label:"Audit Logs",access:{create:()=>false,update:()=>false,delete:()=>false},fields:[{name:"action",type:"text",required:true},{name:"userId",type:"text",label:"User ID"},{name:"userEmail",type:"email",label:"User Email"},{name:"role",type:"text"},{name:"resource",type:"text",label:"Resource",required:true},{name:"resourceId",type:"text",label:"Resource ID"},{name:"changes",type:"json",label:"Changes"},{name:"ipAddress",type:"text",label:"IP Address"},{name:"userAgent",type:"text",label:"User Agent"},{name:"success",type:"checkbox"},{name:"error",type:"text",label:"Error"},{name:"metadata",type:"json",label:"Metadata"},{name:"timestamp",type:"date",time:true,required:true,admin:{readOnly:true}}],admin:{defaultColumns:["action","userEmail","resource","success","timestamp"]}},r={users:t,audit_logs:a};exports.a=t;exports.b=r;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';var chunkVQ53TFYA_cjs=require('./chunk-VQ53TFYA.cjs'),chunkZUBJ6RLQ_cjs=require('./chunk-ZUBJ6RLQ.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs'),module$1=require('module'),crypto=require('crypto');chunkBUNLC3II_cjs.h();chunkBUNLC3II_cjs.h();chunkBUNLC3II_cjs.h();function E(m){let t=[];for(let a of m)if(a.type==="tabs"&&"tabs"in a)for(let n of a.tabs)t.push(...E(n.fields));else a.type==="row"&&"fields"in a?t.push(...E(a.fields)):a.type==="collapsible"&&"fields"in a?t.push(...E(a.fields)):t.push(a);return t}function w(m,t){let a=t,n=m[a.name];if(a.type==="json"||a.type==="richtext"||a.type==="array"||a.type==="group"||a.type==="blocks"||a.type==="list"||a.type==="relationship-block")try{n=n?JSON.parse(n):null;}catch{n=null;}if(a.type==="checkbox"&&(n=!!n),a.type==="date"&&n)try{let i=new Date(n);isNaN(i.getTime())?n=null:n=i.toISOString();}catch{n=null;}if((a.type==="upload"||a.type==="image")&&n)try{let i=JSON.parse(n);Array.isArray(i)?n=i.map(o=>typeof o=="object"&&o!==null?o:{id:o}):n=typeof i=="object"?i:{id:i};}catch{n=typeof n=="string"?{id:n}:n;}return n}var R;function P(){return R||(R=module$1.createRequire("file:///")("node:sqlite").DatabaseSync,R)}function U(m,t){return Array.isArray(m)?m.map(a=>{if(!a||typeof a!="object")return a;let n=a.data?{...a.data}:void 0;if(!n)return a;let i=t.find(o=>o.slug===a.type||o.slug===a.slug);if(!i||!Array.isArray(i.fields))return a;for(let o of i.fields){if(o.name&&(o.type==="upload"||o.type==="image")&&n[o.name]){let e=n[o.name];Array.isArray(e)?n[o.name]=e.map(s=>typeof s=="string"?{id:s}:s):typeof e=="string"&&(n[o.name]={id:e});}if(o.type==="blocks"&&o.name&&n[o.name]){let e=o.blocks||[];n[o.name]=U(n[o.name],e);}}return {...a,data:n}}):m}function I(m,t){try{return m.prepare(`PRAGMA table_info(${t})`).all().map(n=>n.name)}catch{return []}}var L=class extends chunkVQ53TFYA_cjs.a{db;path;migrations=new Map;versionsTableName="kyro_versions";constructor(t){super(),this.path=t.path,t.db?this.db=t.db:this.db=null;}async connect(){if(!this.db)this.db=new(P())(this.path||":memory:");else try{this.db.exec("SELECT 1");}catch{this.db=new(P())(this.path||":memory:");}if(this.db&&typeof this.db.prepare=="function"&&!this.db.prepare.__wrapped){let t=this.db.prepare.bind(this.db),a=n=>{let i=t(n),o=e=>typeof e=="boolean"?e?1:0:e===void 0?null:e;return new Proxy(i,{get(e,s,r){if(s==="all")return (...c)=>e.all(...c.map(o));if(s==="get")return (...c)=>e.get(...c.map(o));if(s==="run")return (...c)=>e.run(...c.map(o));let l=Reflect.get(e,s,r);return typeof l=="function"?l.bind(e):l}})};a.__wrapped=true,this.db.prepare=a;}this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.connected=true;}async disconnect(){if(this.db){try{this.db.close();}catch{}this.db=null;}this.connected=false;}ensureTable(t,a){let n=a||this.getTableNameFor(t.slug),i=["id TEXT PRIMARY KEY"];for(let s of E(t.fields)){if(!s.name||s.name==="id")continue;let r=this.fieldToSQL(s);r&&i.push(r);}let o=E(t.fields);o.some(s=>s.name==="createdAt")||i.push(`${this.col("createdAt")} TEXT DEFAULT (datetime('now'))`),o.some(s=>s.name==="updatedAt")||i.push(`${this.col("updatedAt")} TEXT DEFAULT (datetime('now'))`),o.some(s=>s.name==="status")||i.push("status TEXT DEFAULT 'draft'"),o.some(s=>s.name==="hasDraft")||i.push("hasDraft INTEGER DEFAULT 0"),t.tenantScoped&&i.push("tenant_id TEXT NOT NULL");let e=I(this.db,n);if(e.length===0){let s=`CREATE TABLE IF NOT EXISTS ${n} (${i.join(", ")})`;this.db.exec(s),this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${n}_status ON ${n}(status)`);for(let r of E(t.fields))r.name&&r.indexed&&this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${n}_${r.name} ON ${n}(${this.col(r.name)})`),r.name&&r.unique&&this.db.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_${n}_${r.name}_unique ON ${n}(${this.col(r.name)})`);}else {let s=new Set(e);for(let r of i){let l=r.split(" ")[0].replace(/^"/,"").replace(/"$/,"");if(!s.has(l)&&l!=="id")try{l==="status"?this.db.exec(`ALTER TABLE ${n} ADD COLUMN ${this.col(l)} TEXT DEFAULT 'published'`):l==="hasDraft"?this.db.exec(`ALTER TABLE ${n} ADD COLUMN ${this.col(l)} INTEGER DEFAULT 0`):this.db.exec(`ALTER TABLE ${n} ADD COLUMN ${this.col(l)} TEXT`);}catch{}}}this.migrations.set(n,true);}ensureVersionsTable(){this.db.exec(`
|
|
2
|
+
CREATE TABLE IF NOT EXISTS ${this.versionsTableName} (
|
|
3
|
+
id TEXT PRIMARY KEY,
|
|
4
|
+
collection_slug TEXT NOT NULL,
|
|
5
|
+
document_id TEXT NOT NULL,
|
|
6
|
+
tenant_id TEXT,
|
|
7
|
+
version INTEGER NOT NULL,
|
|
8
|
+
status TEXT NOT NULL DEFAULT 'draft',
|
|
9
|
+
autosave INTEGER NOT NULL DEFAULT 0,
|
|
10
|
+
data TEXT NOT NULL,
|
|
11
|
+
created_by TEXT,
|
|
12
|
+
change_description TEXT,
|
|
13
|
+
published_at TEXT,
|
|
14
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
15
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
16
|
+
)
|
|
17
|
+
`);try{this.db.exec(`ALTER TABLE ${this.versionsTableName} ADD COLUMN autosave INTEGER NOT NULL DEFAULT 0`);}catch{}this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_doc ON ${this.versionsTableName}(collection_slug, document_id)`),this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_status ON ${this.versionsTableName}(status)`),this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_autosave ON ${this.versionsTableName}(autosave)`);}resolveCol(t,a){let n=a.replace(/^-/,""),i=I(this.db,t);if(!i.includes(n)){if(n==="created_at"&&i.includes("createdAt"))return '"createdAt"';if(n==="createdAt"&&i.includes("created_at"))return '"created_at"';if(n==="updated_at"&&i.includes("updatedAt"))return '"updatedAt"';if(n==="updatedAt"&&i.includes("updated_at"))return '"updated_at"'}return this.col(n)}col(t){return `"${t}"`}fieldToSQL(t){switch(t.type){case "text":case "email":case "password":case "textarea":case "color":case "icon":case "code":case "markdown":case "url":return this.col(t.name)+" TEXT";case "number":return this.col(t.name)+" REAL";case "checkbox":return this.col(t.name)+" INTEGER DEFAULT 0";case "date":return this.col(t.name)+" TEXT";case "select":case "radio":return this.col(t.name)+" TEXT";case "relationship":case "upload":case "image":return this.col(t.name)+" TEXT";case "json":case "richtext":case "array":case "group":case "blocks":return this.col(t.name)+" TEXT";default:return null}}parseGlobalsSlug(t){if(t.startsWith("_globals_")){let a=t.replace("_globals_","");return {isGlobal:true,globalSlug:a,tableName:`global_${a.replace(/-/g,"_")}`}}return {isGlobal:false,globalSlug:"",tableName:this.getTableNameFor(t)}}buildWhere(t,a){let n=[],i=[];for(let[o,e]of Object.entries(t)){let s=o.toUpperCase();if((s==="AND"||s==="OR")&&Array.isArray(e)){let l=[];for(let c of e)if(typeof c=="object"&&c!==null){let d=this.buildWhere(c,a);d.clause&&(l.push(`(${d.clause})`),i.push(...d.params));}l.length>0&&n.push(`(${l.join(` ${s} `)})`);continue}let r=this.resolveCol(a,o);typeof e=="object"&&e!==null&&!Array.isArray(e)?(e.equals!==void 0&&(n.push(`${r} = ?`),i.push(e.equals)),e.not_equals!==void 0&&(n.push(`${r} != ?`),i.push(e.not_equals)),e.in!==void 0&&Array.isArray(e.in)&&(e.in.length===0?n.push("1 = 0"):(n.push(`${r} IN (${e.in.map(()=>"?").join(", ")})`),i.push(...e.in))),e.contains!==void 0&&(n.push(`LOWER(${r}) LIKE LOWER(?)`),i.push(`%${e.contains}%`)),e.like!==void 0&&(n.push(`LOWER(${r}) LIKE LOWER(?)`),i.push(e.like)),e.greater_than!==void 0&&(n.push(`${r} > ?`),i.push(e.greater_than)),e.greater_than_equal!==void 0&&(n.push(`${r} >= ?`),i.push(e.greater_than_equal)),e.less_than!==void 0&&(n.push(`${r} < ?`),i.push(e.less_than)),e.less_than_equal!==void 0&&(n.push(`${r} <= ?`),i.push(e.less_than_equal))):e!==void 0&&(n.push(`${r} = ?`),i.push(e));}return {clause:n.join(" AND "),params:i}}async find(t){let{collection:a,where:n={},sort:i,limit:o=10,page:e=1,tenantId:s,select:r,draft:l=false}=t,c=this.parseGlobalsSlug(a),d=c.isGlobal?this.globals.get(c.globalSlug):this.getCollection(a);this.ensureTable(d,c.tableName);let y=c.tableName,h=`SELECT * FROM ${y}`,f=[],u=[],g={...n};this.tenantContext&&d.tenantScoped&&(g=chunkVQ53TFYA_cjs.c({where:g},a,this.tenantContext,chunkVQ53TFYA_cjs.b).where||{});let b=d.fields.find(p=>p.name==="status"),T=b?.type==="select"&&Array.isArray(b.options)&&b.options.some(p=>p.value==="published");if(!l&&T&&(u.push("status = ?"),f.push("published")),s&&d.tenantScoped&&(u.push("tenant_id = ?"),f.push(s)),g&&Object.keys(g).length>0){let p=this.buildWhere(g,y);p.clause&&(u.push(`(${p.clause})`),f.push(...p.params));}u.length>0&&(h+=` WHERE ${u.join(" AND ")}`);let $=i||"-createdAt",j=this.resolveCol(y,$),M=$.startsWith("-")?"DESC":"ASC";h+=` ORDER BY ${j} ${M}`;let V=h.replace("SELECT *","SELECT COUNT(*) as count"),S=this.db.prepare(V).get(...f)?.count||0;h+=" LIMIT ? OFFSET ?",f.push(o,(e-1)*o);let N=this.db.prepare(h).all(...f).map(p=>this.rowToDoc(p,d));return this.tenantContext&&!this.tenantContext.isSuperAdmin&&(N=N.filter(p=>chunkVQ53TFYA_cjs.d(p,a,this.tenantContext,chunkVQ53TFYA_cjs.b))),l&&(N=await Promise.all(N.map(async p=>{let D=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(a,p.id);if(D){let X=D.data?JSON.parse(D.data):{};return chunkZUBJ6RLQ_cjs.a({...p,...X,status:p.status,_hasUnpublishedChanges:D.status==="draft"})}return p}))),N=N.map(p=>chunkZUBJ6RLQ_cjs.a(p)),{docs:N,totalDocs:S,limit:o,totalPages:Math.ceil(S/o),page:e,pagingCounter:(e-1)*o+1,hasPrevPage:e>1,hasNextPage:e<Math.ceil(S/o),prevPage:e>1?e-1:null,nextPage:e<Math.ceil(S/o)?e+1:null}}async findByID(t){let{collection:a,id:n,tenantId:i,draft:o=false}=t,e=this.parseGlobalsSlug(a),s=e.isGlobal?this.globals.get(e.globalSlug):this.getCollection(a);this.ensureTable(s,e.tableName);let l=`SELECT * FROM ${e.tableName} WHERE id = ?`,c=[n];if(this.tenantContext&&s.tenantScoped){let u={id:n,tenant_id:this.tenantContext.tenantId};if(!chunkVQ53TFYA_cjs.d(u,a,this.tenantContext,chunkVQ53TFYA_cjs.b))return null}let d=s.fields.find(u=>u.name==="status"),y=d?.type==="select"&&Array.isArray(d.options)&&d.options.some(u=>u.value==="published");!o&&y&&(l+=" AND status = ?",c.push("published")),i&&s.tenantScoped&&(l+=" AND tenant_id = ?",c.push(i));let h=this.db.prepare(l).get(...c);if(!h)return null;let f=this.rowToDoc(h,s);if(o){let u=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(a,f.id);if(u){let g=u.data?JSON.parse(u.data):{};f={...f,...g,status:f.status,_hasUnpublishedChanges:u.status==="draft"};}}return chunkZUBJ6RLQ_cjs.a(f)}async create(t){let{collection:a,data:n,tenantId:i}=t,o=this.parseGlobalsSlug(a),e=o.isGlobal?this.globals.get(o.globalSlug):this.getCollection(a);this.ensureTable(e,o.tableName);let s=o.tableName,r=o.isGlobal?o.globalSlug:n.id||this.generateId(),l=this.prepareData(n,e);l.id=r;let c=new Date().toISOString();l.created_at=c,l.updated_at=c,i&&e.tenantScoped&&(l.tenant_id=i);let d=Object.keys(l),y=I(this.db,s),h={};for(let T of d)y.includes(T)&&(h[T]=l[T]);let f=Object.keys(h),u=f.map(T=>this.col(T)),g=f.map(()=>"?").join(", "),b=Object.values(h).map(T=>T!==null&&typeof T=="object"?JSON.stringify(T):T);return this.db.prepare(`INSERT OR REPLACE INTO ${s} (${u.join(", ")}) VALUES (${g})`).run(...b),this.ensureVersionsTable(),this.findByID({collection:a,id:r,tenantId:i,draft:true})}async update(t){let{collection:a,id:n,data:i,tenantId:o}=t,e=this.parseGlobalsSlug(a),s=e.isGlobal?this.globals.get(e.globalSlug):this.getCollection(a);this.ensureTable(s,e.tableName);let r=e.tableName,l=this.prepareData(i,s);l.updated_at=new Date().toISOString();let c=I(this.db,r),d={};for(let b of Object.keys(l))c.includes(b)&&(d[b]=l[b]);let h=Object.keys(d).map(b=>`${this.col(b)} = ?`).join(", "),f=Object.values(d).map(b=>b!==null&&typeof b=="object"?JSON.stringify(b):b),u=`UPDATE ${r} SET ${h} WHERE id = ?`,g=[...f,n];return o&&s.tenantScoped&&(u+=" AND tenant_id = ?",g.push(o)),this.db.prepare(u).run(...g),this.ensureVersionsTable(),this.findByID({collection:a,id:n,tenantId:o,draft:true})}async delete(t){let{collection:a,id:n,tenantId:i}=t,o=this.parseGlobalsSlug(a),e=o.isGlobal?this.globals.get(o.globalSlug):this.getCollection(a);this.ensureTable(e,o.tableName),this.ensureVersionsTable();let s=await this.findByID({collection:a,id:n,tenantId:i,draft:true});if(!s)throw new Error(`Document not found: ${a}/${n}`);let l=`DELETE FROM ${o.tableName} WHERE id = ?`,c=[n];return i&&e.tenantScoped&&(l+=" AND tenant_id = ?",c.push(i)),this.db.prepare(l).run(...c),s}async count(t){let{collection:a,tenantId:n}=t,i=this.parseGlobalsSlug(a),o=i.isGlobal?this.globals.get(i.globalSlug):this.getCollection(a);this.ensureTable(o,i.tableName);let e=i.tableName,s=`SELECT COUNT(*) as count FROM ${e}`,r=[],l=[];if(n&&o.tenantScoped&&(r.push("tenant_id = ?"),l.push(n)),t.where&&Object.keys(t.where).length>0){let d=this.buildWhere(t.where,e);d.clause&&(r.push(`(${d.clause})`),l.push(...d.params));}return r.length>0&&(s+=` WHERE ${r.join(" AND ")}`),this.db.prepare(s).get(...l)?.count||0}async findOne(t){let a=this.parseGlobalsSlug(t.collection);if(a.isGlobal){let i=this.globals.get(a.globalSlug);if(!i)throw new Error(`Global "${a.globalSlug}" not found in adapter`);this.ensureTable(i,a.tableName);let o=`SELECT * FROM ${a.tableName}`,e=[],s=[],r=i.fields.find(d=>d.name==="status"),l=r?.type==="select"&&Array.isArray(r.options)&&r.options.some(d=>d.value==="published");!t.draft&&i.versions&&l&&e.push("status = 'published'"),e.length>0&&(o+=` WHERE ${e.join(" AND ")}`),o+=" LIMIT 1";let c=this.db.prepare(o).get(...s);if(c){let d=this.rowToDoc(c,i);if(t.draft){let y=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(t.collection,a.globalSlug);if(y){let h=y.data?JSON.parse(y.data):{};d={...d,...h,status:d.status,_hasUnpublishedChanges:y.status==="draft"};}}return d}return null}return (await this.find({...t,limit:1})).docs[0]||null}async findVersions(t){this.ensureVersionsTable();let{collection:a,documentId:n,tenantId:i,limit:o=20,page:e=1}=t,s=["collection_slug = ?","document_id = ?","autosave = 0"],r=[a,n];i?(s.push("tenant_id = ?"),r.push(i)):s.push("tenant_id IS NULL");let l=`WHERE ${s.join(" AND ")}`,d=this.db.prepare(`SELECT COUNT(*) as count FROM ${this.versionsTableName} ${l}`).get(...r)?.count||0,y=(e-1)*o;return {docs:this.db.prepare(`SELECT * FROM ${this.versionsTableName} ${l} ORDER BY version DESC LIMIT ? OFFSET ?`).all(...r,o,y).map(u=>this.rowToVersion(u)),totalDocs:d,limit:o,totalPages:Math.ceil(d/o),page:e,pagingCounter:(e-1)*o+1,hasPrevPage:e>1,hasNextPage:e<Math.ceil(d/o),prevPage:e>1?e-1:null,nextPage:e<Math.ceil(d/o)?e+1:null}}async findVersionByID(t){this.ensureVersionsTable();let a=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE id = ? AND collection_slug = ? LIMIT 1`).get(t.versionId,t.collection);return a?this.rowToVersion(a):null}async createVersion(t){this.ensureVersionsTable();let a=new Date().toISOString();if(t.autosave){let s=`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND autosave = 1`,r=[t.collection,t.documentId];t.tenantId?(s+=" AND tenant_id = ?",r.push(t.tenantId)):s+=" AND tenant_id IS NULL",s+=" LIMIT 1";let l=this.db.prepare(s).get(...r);if(l){this.db.prepare(`UPDATE ${this.versionsTableName} SET data = ?, status = ?, updated_at = ? WHERE id = ?`).run(JSON.stringify(t.data),t.status,a,l.id);let c=await this.findVersionByID({collection:t.collection,versionId:l.id});if(c)return c}}let n=this.generateId(),o=(this.db.prepare(`SELECT version FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND autosave = 0 ORDER BY version DESC LIMIT 1`).get(t.collection,t.documentId)?.version??0)+1;if(this.db.prepare(`INSERT INTO ${this.versionsTableName} (
|
|
18
|
+
id, collection_slug, document_id, tenant_id, version, status, autosave, data, created_by, change_description, published_at, created_at, updated_at
|
|
19
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(n,t.collection,t.documentId,t.tenantId??null,o,t.status,t.autosave?1:0,JSON.stringify(t.data),t.createdBy??null,t.changeDescription??null,t.status==="published"?a:null,a,a),!t.autosave){let r=this.collections.get(t.collection)?.versions?.maxPerDoc;r&&r>0&&await this.deleteVersions({collection:t.collection,documentId:t.documentId,keepLatest:r,tenantId:t.tenantId});}return await this.findVersionByID({collection:t.collection,versionId:n})}async updateLatestVersion(t){return this.createVersion({...t,autosave:true})}async deleteVersions(t){this.ensureVersionsTable();let{collection:a,documentId:n,keepLatest:i,tenantId:o}=t;if(i&&i>0){let e=this.db.prepare(`SELECT id, status, autosave FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? ORDER BY version DESC`).all(a,n),s=0,r=[];for(let l of e)l.status==="published"||l.autosave===1||(s++,s>i&&r.push(l.id));for(let l of r)this.db.prepare(`DELETE FROM ${this.versionsTableName} WHERE id = ?`).run(l);}else {let e=`DELETE FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ?`,s=[a,n];o&&(e+=" AND tenant_id = ?",s.push(o)),this.db.prepare(e).run(...s);}}rowToVersion(t){return {id:String(t.id),collection:t.collection_slug,documentId:t.document_id,version:t.version,status:t.status,data:t.data?JSON.parse(t.data):{},createdBy:t.created_by??void 0,changeDescription:t.change_description??void 0,publishedAt:t.published_at??null,createdAt:t.created_at,updatedAt:t.updated_at}}prepareData(t,a){let n={},i=E(a.fields),o=(e,s)=>{let r=e;if(r.type==="json"||r.type==="richtext"||r.type==="array"||r.type==="group"||r.type==="blocks"||r.type==="list"||r.type==="relationship-block")return s!=null?JSON.stringify(s):null;if(r.type==="checkbox")return s?1:0;if(r.type==="number")return s!==null&&s!==""?Number(s):null;if(r.type==="upload"||r.type==="image"){if(s==null)return null;if(Array.isArray(s)){let l=s.map(c=>typeof c=="string"?c:typeof c=="object"?c.id||c._id||c:String(c));return JSON.stringify(l)}return typeof s=="string"?s:typeof s=="object"?JSON.stringify(s):String(s)}else if(e.type==="relationship"){if(s==null)return null;if(Array.isArray(s)){let l=s.map(c=>typeof c=="string"?c:typeof c=="object"?JSON.stringify({relationTo:e.relationTo,value:c.id||c}):String(c));return JSON.stringify(l)}return typeof s=="string"?s:typeof s=="object"?JSON.stringify({relationTo:e.relationTo,value:s.id||s}):String(s)}return s};for(let e of i){if(!e.name||e.name==="id"||a.fields.some(l=>l.type==="tabs"&&l.name&&"tabs"in l&&l.tabs.some(c=>c.fields.some(d=>d.name===e.name))))continue;let r=t[e.name];r!==void 0&&(n[e.name]=o(e,r));}for(let e of a.fields)if(e.type==="tabs"&&"tabs"in e&&e.name){let s=t[e.name];if(s&&typeof s=="object"){for(let r of e.tabs)for(let l of r.fields)if(l.name&&l.name!=="id"){let c=s[l.name];c!==void 0&&(n[l.name]=o(l,c));}}}return n}rowToDoc(t,a){let n={id:t.id};for(let i of E(a.fields)){if(!i.name||i.name==="id")continue;let o=i,e=t[o.name];if(o.type==="json"||o.type==="richtext"||o.type==="array"||o.type==="group"||o.type==="blocks"||o.type==="list"||o.type==="relationship-block")try{e=e?JSON.parse(e):null;}catch{e=null;}if(o.type==="blocks"&&e&&Array.isArray(e)){let s=o.blocks||[];e=U(e,s);}if(i.type==="checkbox"&&(e=!!e),i.type==="date"&&e)try{let s=new Date(e);isNaN(s.getTime())?(console.warn(`[LocalAdapter] Invalid date value for field "${i.name}":`,e),e=null):e=s.toISOString();}catch{e=null;}if((i.type==="upload"||i.type==="image")&&e)try{let s=JSON.parse(e);Array.isArray(s)?e=s.map(r=>typeof r=="object"&&r!==null?r:{id:r}):e=typeof s=="object"?s:{id:s};}catch{e={id:e};}if(i.type==="relationship"&&e)try{let s=JSON.parse(e);Array.isArray(s),e=s;}catch{e={relationTo:Array.isArray(i.relationTo)?i.relationTo[0]:i.relationTo,value:e};}n[i.name]=e;}for(let i of a.fields)if(!(!i.name||i.name==="id"||i.name==="row"||i.name==="collapsible")&&i.type==="tabs"&&"tabs"in i){let o={};for(let e of i.tabs)for(let s of e.fields)s.name&&s.name!=="id"&&(o[s.name]=w(t,s));n[i.name]=o;}if(a.timestamps){let i=t.createdAt||t.created_at,o=t.updatedAt||t.updated_at;if(i)try{let e=new Date(i);isNaN(e.getTime())||(n.createdAt=e.toISOString());}catch{}if(o)try{let e=new Date(o);isNaN(e.getTime())||(n.updatedAt=e.toISOString());}catch{}}a.tenantScoped&&(n.tenantId=t.tenant_id),n.status=t.status??"published",n.hasDraft=t.hasDraft?!!t.hasDraft:false;for(let i of Object.keys(n))/^\d+$/.test(i)&&delete n[i];return n}generateId(){let t=Date.now().toString(16).padStart(12,"0"),a=crypto.randomBytes(6).toString("hex");return t+a}getMediaById(t){try{let a=this.getTableNameFor("media"),n=this.db.prepare(`SELECT id, url, thumbnail_url FROM ${a} WHERE id = ?`).get(t);if(n)return {id:n.id,url:n.url,thumbnailUrl:n.thumbnail_url||n.url}}catch{}return null}getTableNameFor(t){return t.replace(/-/g,"_")}async migrate(){for(let t of this.collections.values())this.ensureTable(t);}async rollback(){}async transaction(t){return new Promise((a,n)=>{let i=this.db.transaction(async()=>t({db:this.db}));try{let o=i();a(o);}catch(o){n(o);}})}getDatabase(){return this.db}exec(t){this.db.exec(t);}prepare(t){return this.db.prepare(t)}};function k(m){return new L(m||{})}exports.a=L;exports.b=k;
|