betterauth-dynamodb-adapter 0.1.0
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/LICENSE +21 -0
- package/README.md +233 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +27715 -0
- package/dist/index.d.mts +27716 -0
- package/dist/index.mjs +1 -0
- package/package.json +79 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createAdapterFactory as e}from"better-auth/adapters";import{DeleteItemCommand as t,DynamoDBClient as n,GetItemCommand as r,PutItemCommand as i,QueryCommand as a,UpdateItemCommand as o}from"@aws-sdk/client-dynamodb";var s=((e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports))((e=>{var t=class e{value;constructor(e){typeof e==`object`&&`N`in e?this.value=String(e.N):this.value=String(e);let t=typeof e.valueOf()==`number`?e.valueOf():0;if(t>2**53-1||t<-(2**53-1)||Math.abs(t)===1/0||Number.isNaN(t))throw Error(`NumberValue should not be initialized with an imprecise number=${t}. Use a string instead.`)}static from(t){return new e(t)}toAttributeValue(){return{N:this.toString()}}toBigInt(){let e=this.toString();return BigInt(e)}toString(){return String(this.value)}valueOf(){return this.toString()}};let n=(e,n)=>{if(e===void 0)throw Error(`Pass options.removeUndefinedValues=true to remove undefined values from map/array/set.`);if(e===null&&typeof e==`object`)return s();if(Array.isArray(e))return r(e,n);if(e?.constructor?.name===`Set`)return i(e,n);if(e?.constructor?.name===`Map`)return a(e,n);if(e?.constructor?.name===`Object`||!e.constructor&&typeof e==`object`)return o(e,n);if(p(e))return e.length===0&&n?.convertEmptyValues?s():c(e);if(typeof e==`boolean`||e?.constructor?.name===`Boolean`)return{BOOL:e.valueOf()};if(typeof e==`number`||e?.constructor?.name===`Number`)return f(e,n);if(e instanceof t)return e.toAttributeValue();if(typeof e==`bigint`)return u(e);if(typeof e==`string`||e?.constructor?.name===`String`)return e.length===0&&n?.convertEmptyValues?s():l(e);if(n?.convertClassInstanceToMap&&typeof e==`object`)return o(e,n);throw Error(`Unsupported type passed: ${e}. Pass options.convertClassInstanceToMap=true to marshall typeof object as map attribute.`)},r=(e,t)=>({L:e.filter(e=>typeof e!=`function`&&(!t?.removeUndefinedValues||t?.removeUndefinedValues&&e!==void 0)).map(e=>n(e,t))}),i=(e,n)=>{let r=n?.removeUndefinedValues?new Set([...e].filter(e=>e!==void 0)):e;if(!n?.removeUndefinedValues&&r.has(void 0))throw Error(`Pass options.removeUndefinedValues=true to remove undefined values from map/array/set.`);if(r.size===0){if(n?.convertEmptyValues)return s();throw Error(`Pass a non-empty set, or options.convertEmptyValues=true.`)}let i=r.values().next().value;if(i instanceof t)return{NS:Array.from(r).map(e=>e.toString())};if(typeof i==`number`)return{NS:Array.from(r).map(e=>f(e,n)).map(e=>e.N)};if(typeof i==`bigint`)return{NS:Array.from(r).map(u).map(e=>e.N)};if(typeof i==`string`)return{SS:Array.from(r).map(l).map(e=>e.S)};if(p(i))return{BS:Array.from(r).map(c).map(e=>e.B)};throw Error(`Only Number Set (NS), Binary Set (BS) or String Set (SS) are allowed.`)},a=(e,t)=>({M:(e=>{let r={};for(let[i,a]of e)typeof a!=`function`&&(a!==void 0||!t?.removeUndefinedValues)&&(r[i]=n(a,t));return r})(e)}),o=(e,t)=>({M:(e=>{let r={};for(let i in e){let a=e[i];typeof a!=`function`&&(a!==void 0||!t?.removeUndefinedValues)&&(r[i]=n(a,t))}return r})(e)}),s=()=>({NULL:!0}),c=e=>({B:e}),l=e=>({S:e.toString()}),u=e=>({N:e.toString()}),d=e=>{throw Error(`${e} Use NumberValue from @aws-sdk/lib-dynamodb.`)},f=(e,t)=>{if([NaN,1/0,-1/0].map(e=>e.toString()).includes(e.toString()))throw Error(`Special numeric value ${e.toString()} is not allowed`);return t?.allowImpreciseNumbers||(Number(e)>2**53-1?d(`Number ${e.toString()} is greater than Number.MAX_SAFE_INTEGER.`):Number(e)<-(2**53-1)&&d(`Number ${e.toString()} is lesser than Number.MIN_SAFE_INTEGER.`)),{N:e.toString()}},p=e=>e?.constructor?[`ArrayBuffer`,`Blob`,`Buffer`,`DataView`,`File`,`Int8Array`,`Uint8Array`,`Uint8ClampedArray`,`Int16Array`,`Uint16Array`,`Int32Array`,`Uint32Array`,`Float32Array`,`Float64Array`,`BigInt64Array`,`BigUint64Array`].includes(e.constructor.name):!1,m=(e,t)=>{for(let[n,r]of Object.entries(e))if(r!==void 0)switch(n){case`NULL`:return null;case`BOOL`:return!!r;case`N`:return h(r,t);case`B`:return _(r);case`S`:return g(r);case`L`:return v(r,t);case`M`:return y(r,t);case`NS`:return new Set(r.map(e=>h(e,t)));case`BS`:return new Set(r.map(_));case`SS`:return new Set(r.map(g));default:throw Error(`Unsupported type passed: ${n}`)}throw Error(`No value defined: ${JSON.stringify(e)}`)},h=(e,n)=>{if(typeof n?.wrapNumbers==`function`)return n?.wrapNumbers(e);if(n?.wrapNumbers)return t.from(e);let r=Number(e);if((r>2**53-1||r<-(2**53-1))&&![1/0,-1/0].includes(r))if(typeof BigInt==`function`)try{return BigInt(e)}catch{throw Error(`${e} can't be converted to BigInt. Set options.wrapNumbers to get string value.`)}else throw Error(`${e} is outside SAFE_INTEGER bounds. Set options.wrapNumbers to get string value.`);return r},g=e=>e,_=e=>e,v=(e,t)=>e.map(e=>m(e,t)),y=(e,t)=>Object.entries(e).reduce((e,[n,r])=>(e[n]=m(r,t),e),{});function b(e,t){let r=n(e,t),[i,a]=Object.entries(r)[0];switch(i){case`M`:case`L`:return t?.convertTopLevelContainer?r:a;default:return r}}e.marshall=b,e.unmarshall=(e,t)=>t?.convertWithoutMapWrapper?m(e,t):m({M:e},t)}))();const c=c=>{let{tableName:l,region:u}=c,d=new n({region:u});function f(e){let{_pk:t,_sk:n,_table:r,...i}=e;return i}function p(e){let t=[],n={},r={};return e.forEach((e,i)=>{let a=`#w${i}`,o=`:w${i}`;r[a]=e.field;let s;switch(e.operator){case`ne`:n[o]=e.value,s=`${a} <> ${o}`;break;case`gt`:n[o]=e.value,s=`${a} > ${o}`;break;case`gte`:n[o]=e.value,s=`${a} >= ${o}`;break;case`lt`:n[o]=e.value,s=`${a} < ${o}`;break;case`lte`:n[o]=e.value,s=`${a} <= ${o}`;break;case`in`:case`not_in`:{let t=e.value,r=t.map((e,t)=>`:w${i}_${t}`);t.forEach((e,t)=>{n[`:w${i}_${t}`]=e});let o=`${a} IN (${r.join(`,`)})`;s=e.operator===`not_in`?`NOT ${o}`:o;break}case`contains`:n[o]=e.value,s=`contains(${a}, ${o})`;break;case`starts_with`:n[o]=e.value,s=`begins_with(${a}, ${o})`;break;case`ends_with`:n[o]=e.value,s=`contains(${a}, ${o})`;break;default:n[o]=e.value,s=`${a} = ${o}`;break}i>0&&t.push(e.connector===`OR`?`OR`:`AND`),t.push(s)}),{expression:t.join(` `),vals:n,names:r}}async function m(e,t){let n={"#_table":`_table`},r={":_table":e},i,o=n,c=r;if(t&&t.length>0){let e=p(t);i=e.expression,o={...n,...e.names},c={...r,...e.vals}}return((await d.send(new a({TableName:l,IndexName:`_table-index`,KeyConditionExpression:`#_table = :_table`,FilterExpression:i,ExpressionAttributeNames:o,ExpressionAttributeValues:(0,s.marshall)(c)}))).Items||[]).map(e=>f((0,s.unmarshall)(e)))}return e({config:{adapterId:`dynamodb`,adapterName:`DynamoDB Adapter`,supportsJSON:!1,supportsDates:!1,supportsBooleans:!1,supportsNumericIds:!1},adapter:()=>({create:async({model:e,data:t})=>{let n=t.id||crypto.randomUUID(),r={...t,id:n,_pk:`${e}#${n}`,_sk:`${e}#${n}`,_table:e};return await d.send(new i({TableName:l,Item:(0,s.marshall)(r,{removeUndefinedValues:!0})})),{...t,id:n}},findOne:async({model:e,where:t})=>{if(t.length===1&&t[0].field===`id`&&t[0].operator===`eq`){let n=t[0].value,i=await d.send(new r({TableName:l,Key:(0,s.marshall)({_pk:`${e}#${n}`,_sk:`${e}#${n}`})}));return i.Item?f((0,s.unmarshall)(i.Item)):null}return(await m(e,t))[0]||null},findMany:async({model:e,where:t,limit:n,sortBy:r,offset:i})=>{let a=await m(e,t);if(r){let e=r.direction===`desc`?-1:1;a.sort((t,n)=>t[r.field]<n[r.field]?-1*e:t[r.field]>n[r.field]?1*e:0)}return i&&(a=a.slice(i)),n&&(a=a.slice(0,n)),a},update:async({model:e,where:t,update:n})=>{let r=await m(e,t);if(r.length===0)return null;let i=r[0],a=i.id,c=Object.entries(n),u=[],f={},p={};return c.forEach(([e,t],n)=>{e===`id`||e.startsWith(`_`)||(u.push(`#u${n} = :u${n}`),p[`#u${n}`]=e,f[`:u${n}`]=t)}),u.length===0?i:(await d.send(new o({TableName:l,Key:(0,s.marshall)({_pk:`${e}#${a}`,_sk:`${e}#${a}`}),UpdateExpression:`SET ${u.join(`, `)}`,ExpressionAttributeNames:p,ExpressionAttributeValues:(0,s.marshall)(f,{removeUndefinedValues:!0})})),{...i,...n})},updateMany:async({model:e,where:t,update:n})=>{let r=await m(e,t),i=0;for(let t of r){let r=Object.entries(n),a=[],c={},u={};r.forEach(([e,t],n)=>{e===`id`||e.startsWith(`_`)||(a.push(`#u${n} = :u${n}`),u[`#u${n}`]=e,c[`:u${n}`]=t)}),a.length!==0&&(await d.send(new o({TableName:l,Key:(0,s.marshall)({_pk:`${e}#${t.id}`,_sk:`${e}#${t.id}`}),UpdateExpression:`SET ${a.join(`, `)}`,ExpressionAttributeNames:u,ExpressionAttributeValues:(0,s.marshall)(c,{removeUndefinedValues:!0})})),i++)}return i},delete:async({model:e,where:n})=>{let r=await m(e,n);r.length!==0&&await d.send(new t({TableName:l,Key:(0,s.marshall)({_pk:`${e}#${r[0].id}`,_sk:`${e}#${r[0].id}`})}))},deleteMany:async({model:e,where:n})=>{let r=await m(e,n);for(let n of r)await d.send(new t({TableName:l,Key:(0,s.marshall)({_pk:`${e}#${n.id}`,_sk:`${e}#${n.id}`})}));return r.length},count:async({model:e,where:t})=>(await m(e,t)).length})})};export{c as default};
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "betterauth-dynamodb-adapter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "DynamoDB adapter for Better Auth — single-table design with full CRUD, filtering, and sorting support",
|
|
5
|
+
"author": "rokku-x",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/rokku-x/betterauth-dynamodb-adapter.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/rokku-x/betterauth-dynamodb-adapter/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/rokku-x/betterauth-dynamodb-adapter#readme",
|
|
16
|
+
"main": "dist/index.cjs",
|
|
17
|
+
"module": "dist/index.mjs",
|
|
18
|
+
"types": "dist/index.d.mts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/index.d.mts",
|
|
23
|
+
"default": "./dist/index.mjs"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/index.d.cts",
|
|
27
|
+
"default": "./dist/index.cjs"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"keywords": [
|
|
36
|
+
"better-auth",
|
|
37
|
+
"betterauth",
|
|
38
|
+
"dynamodb",
|
|
39
|
+
"adapter",
|
|
40
|
+
"auth",
|
|
41
|
+
"authentication",
|
|
42
|
+
"aws",
|
|
43
|
+
"serverless",
|
|
44
|
+
"single-table",
|
|
45
|
+
"nosql",
|
|
46
|
+
"database",
|
|
47
|
+
"typescript"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsdown",
|
|
51
|
+
"dev": "tsdown --watch",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"prepublishOnly": "npm run build",
|
|
56
|
+
"changeset": "changeset",
|
|
57
|
+
"version:changeset": "changeset version",
|
|
58
|
+
"publish:changeset": "changeset publish"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@changesets/cli": "^2.30.0",
|
|
62
|
+
"tsdown": "^0.21.7",
|
|
63
|
+
"typescript": "^5.0.0",
|
|
64
|
+
"vitest": "^1.0.0"
|
|
65
|
+
},
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"better-auth": ">=1.0.0",
|
|
68
|
+
"@aws-sdk/client-dynamodb": ">=3.0.0",
|
|
69
|
+
"@aws-sdk/lib-dynamodb": ">=3.0.0"
|
|
70
|
+
},
|
|
71
|
+
"peerDependenciesMeta": {
|
|
72
|
+
"@aws-sdk/client-dynamodb": {
|
|
73
|
+
"optional": false
|
|
74
|
+
},
|
|
75
|
+
"@aws-sdk/lib-dynamodb": {
|
|
76
|
+
"optional": false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|