authored 0.0.3 → 0.0.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Mark Joseph Yalung
3
+ Copyright (c) 2025 Mark Yalung
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/index.d.ts CHANGED
@@ -1,48 +1,23 @@
1
1
  import { Client } from 'pg';
2
+ import { obj } from '@coff-r/x';
2
3
 
3
- declare function decodeSID(str: string): string;
4
- interface obj<T> {
5
- [Key: string]: T;
6
- }
7
- interface fs {
8
- [key: string]: string | undefined | boolean | number;
9
- }
10
- interface bs {
11
- f_timed?: number;
12
- [key: string]: string | undefined | boolean | number;
4
+ declare class Signator {
5
+ salt: string;
6
+ constructor(salt: string);
7
+ getSignature(val: string): string;
8
+ deriveKey(): Buffer<ArrayBufferLike>;
9
+ sign(val: string): string;
10
+ unsign(signedVal: string): boolean;
11
+ loadUnsign(vals: string): string | undefined;
12
+ verifySignature(val: string, sig: string): boolean;
13
13
  }
14
- type authConfig = {
15
- COOKIE_NAME: string;
16
- COOKIE_DOMAIN: string;
17
- COOKIE_PATH: string;
18
- COOKIE_HTTPONLY: boolean;
19
- COOKIE_SECURE: boolean;
20
- REFRESH_EACH_REQUEST: boolean;
21
- COOKIE_SAMESITE: string;
22
- KEY_PREFIX: string;
23
- PERMANENT: boolean;
24
- USE_SIGNER: boolean;
25
- ID_LENGTH: number;
26
- FILE_THRESHOLD: number;
27
- LIFETIME: number;
28
- MAX_COOKIE_SIZE: number;
29
- INTERFACE: dbs;
30
- STORAGE: string;
31
- JWT_STORAGE: string;
32
- JWT_LIFETIME: number;
33
- };
34
- type dbs = "fs" | "postgres";
35
- declare class Auth {
36
- postgresClient?: Client;
37
- config: authConfig;
38
- constructor({ type, dir }?: {
39
- type?: dbs;
40
- dir?: string;
41
- });
42
- initStorage(path: string): this;
43
- get session(): AuthInterface;
44
- get jwt(): FSInterface;
14
+
15
+ declare class sidGenerator {
16
+ signer: Signator;
17
+ constructor(salt: string);
18
+ generate(len?: number): string;
45
19
  }
20
+
46
21
  declare class callBack {
47
22
  [Key: string]: any;
48
23
  data: obj<string>;
@@ -63,21 +38,7 @@ declare class ServerSide extends callBack {
63
38
  constructor(sid?: string, initial?: obj<string>, readonly?: boolean);
64
39
  get session(): ServerSide;
65
40
  }
66
- declare class Signator {
67
- salt: string;
68
- constructor(salt: string);
69
- getSignature(val: string): string;
70
- deriveKey(): Buffer;
71
- sign(val: string): string;
72
- unsign(signedVal: string): boolean;
73
- loadUnsign(vals: string): string | undefined;
74
- verifySignature(val: string, sig: string): boolean;
75
- }
76
- declare class sidGenerator {
77
- signer: Signator;
78
- constructor(salt: string);
79
- generate(len?: number): string;
80
- }
41
+
81
42
  declare class AuthInterface extends sidGenerator {
82
43
  config: authConfig;
83
44
  constructor(config: authConfig, salt?: string);
@@ -90,7 +51,10 @@ declare class AuthInterface extends sidGenerator {
90
51
  setCookie(xsesh: ServerSide, life: Date | number, _sameSite?: string): string;
91
52
  loadHeader(req: any, readonly?: boolean): Promise<ServerSide>;
92
53
  }
93
- declare class FSession extends ServerSide {
54
+
55
+ interface bs$1 {
56
+ f_timed?: number;
57
+ [key: string]: string | undefined | boolean | number;
94
58
  }
95
59
  interface ffcache {
96
60
  [key: string]: string | undefined | boolean | number;
@@ -98,7 +62,7 @@ interface ffcache {
98
62
  data: string;
99
63
  life: number;
100
64
  }
101
- declare class FSCached<T extends bs> {
65
+ declare class FSCached<T extends bs$1> {
102
66
  path: string;
103
67
  data: Map<any, T>;
104
68
  constructor(folderpath: string);
@@ -108,6 +72,9 @@ declare class FSCached<T extends bs> {
108
72
  set(val: string, data: T): Promise<void>;
109
73
  delete(key: string): Promise<void>;
110
74
  }
75
+
76
+ declare class FSession extends ServerSide {
77
+ }
111
78
  declare class FSInterface extends AuthInterface {
112
79
  isJWT: boolean;
113
80
  cacher: FSCached<ffcache>;
@@ -117,6 +84,11 @@ declare class FSInterface extends AuthInterface {
117
84
  fetchSession(sid: string, readonly?: boolean): Promise<ServerSide>;
118
85
  saveSession(sesh: ServerSide, X?: Headers, deleteMe?: boolean): Promise<void>;
119
86
  }
87
+
88
+ interface bs {
89
+ f_timed?: number;
90
+ [key: string]: string | undefined | boolean | number;
91
+ }
120
92
  declare class PGCache<T extends bs> {
121
93
  client: Client;
122
94
  query: string;
@@ -130,7 +102,26 @@ declare class PGCache<T extends bs> {
130
102
  set(data: T): Promise<void>;
131
103
  delete(key: string): Promise<void>;
132
104
  }
133
- declare class JWTInterface extends sidGenerator {
105
+
106
+ declare class PostgreSession extends ServerSide {
107
+ }
108
+ interface sesh_db {
109
+ sid: string;
110
+ data: string;
111
+ expiration: string;
112
+ f_timed?: number;
113
+ [key: string]: string | undefined | boolean | number;
114
+ }
115
+ declare class PGInterface extends AuthInterface {
116
+ sclass: typeof ServerSide;
117
+ client: Client;
118
+ pgc: PGCache<sesh_db>;
119
+ constructor(client: Client, config: authConfig);
120
+ fetchSession(sid: string): Promise<ServerSide>;
121
+ saveSession(xsesh: ServerSide, rsx?: any, deleteMe?: boolean, sameSite?: string): Promise<void>;
122
+ }
123
+
124
+ declare class JWTSession extends sidGenerator {
134
125
  salt: string;
135
126
  constructor();
136
127
  sign(payload: obj<any>): string;
@@ -151,22 +142,45 @@ declare class JWTInterface extends sidGenerator {
151
142
  save(xjwts: ServerSide): string;
152
143
  new(payload: obj<any>): string;
153
144
  }
154
- declare class Fjson<T extends fs> {
155
- fs: string;
156
- f_timed: number;
157
- data: Map<any, T>;
158
- key: string;
159
- dir: string;
160
- constructor({ dir, fs, key }: {
161
- dir: string;
162
- fs: string;
163
- key: string;
145
+
146
+ type dbs = "fs" | "postgres";
147
+ interface authConfig {
148
+ COOKIE_NAME: string;
149
+ COOKIE_DOMAIN: string;
150
+ COOKIE_PATH: string;
151
+ COOKIE_HTTPONLY: boolean;
152
+ COOKIE_SECURE: boolean;
153
+ REFRESH_EACH_REQUEST: boolean;
154
+ COOKIE_SAMESITE: string;
155
+ KEY_PREFIX: string;
156
+ PERMANENT: boolean;
157
+ USE_SIGNER: boolean;
158
+ ID_LENGTH: number;
159
+ FILE_THRESHOLD: number;
160
+ LIFETIME: number;
161
+ MAX_COOKIE_SIZE: number;
162
+ INTERFACE: dbs;
163
+ STORAGE: string;
164
+ JWT_STORAGE: string;
165
+ JWT_LIFETIME: number;
166
+ }
167
+ declare class Auth {
168
+ postgresClient?: Client;
169
+ config: authConfig;
170
+ constructor({ type, dir }?: {
171
+ type?: dbs;
172
+ dir?: string;
164
173
  });
165
- init(): Promise<void>;
166
- get(val: string | undefined): Promise<T | null>;
167
- set(data: T): Promise<void>;
168
- delete(key: string): Promise<void>;
169
- json(): Promise<unknown[]>;
174
+ initStorage(path: string): this;
175
+ get session(): AuthInterface;
176
+ get jwt(): FSInterface;
177
+ }
178
+ declare class Session {
179
+ session: AuthInterface;
180
+ jwt: AuthInterface;
181
+ jwtInt: JWTSession;
182
+ init(sh: Auth): void;
170
183
  }
171
184
 
172
- export { Auth, AuthInterface, FSession, Fjson, JWTInterface, PGCache, ServerSide, decodeSID };
185
+ export { Auth, AuthInterface, FSCached, FSInterface, FSession, PGCache, PGInterface, PostgreSession, ServerSide, Session };
186
+ export type { authConfig };
package/dist/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  // @bun
2
- import{randomBytes as _}from"crypto";var{CryptoHasher:b,file:R,gunzipSync:y,gzipSync:g,write:N}=globalThis.Bun;import{promises as m,mkdirSync as c,writeFileSync as v}from"fs";import{sign as T,verify as o}from"jsonwebtoken";var f=(Y)=>Array.from({length:Y},(Z,$)=>$);var r=f(10).join(""),t=new RegExp(/(\d+)(\d*)/,"m");var M=Object.values;var{entries:I,hasOwn:a}=Object;var D=Object.assign,F=(Y)=>{return Object.keys(Y).length};var V=(Y)=>{return Buffer.from(Y)},j=(...Y)=>{let Z=new Bun.CryptoHasher("sha256",G());return Y.forEach(($)=>{Z.update($)}),Z.digest()};var G=()=>{let Y=process.env.SECRET_KEY;if(!Y)throw new Error("'SECRET_KEY' not found in .env file");return Y};class H{date;constructor(Y){this.date=Y?new Date(Y):new Date}delta(Y=null,Z=!1){let $=H.delta(this.date.getTime(),Y);return Z?new Date($):$}timed(Y){if(!Y)return this.date;return[["year","FullYear"],["month","Month"],["day","Date"],["hour","Hours"],["minute","Minutes"],["second","Seconds"]].reduce(($,[U,W])=>{let Q=Y[U];return Q?new Date($[`set${W}`]($[`get${W}`]()+Q)):$},new Date(this.date))}static delta(Y,Z=null){return Z?Z-Y:Y-Date.now()}static get now(){return Date.now()}}function K(Y){let Z=new b("md5");return Z.update(Y),Z.digest("hex")}var h=new TextDecoder,n={cookie:(Y,Z="",{maxAge:$,expires:U,path:W,domain:Q,secure:q,httpOnly:L,sameSite:E})=>{if($ instanceof Date)$=$.getSeconds();if(U instanceof Date)U=U.toUTCString();else if(U===0)U=new Date().toUTCString();return[["Domain",Q],["Expires",U],["Max-Age",$],["Secure",q],["HttpOnly",L],["Path",W],["SameSite",E]].reduce((B,[X,A])=>{if(A!==void 0)B.push(`${X}=${A}`);return B},[`${Y}=${Z}`]).join("; ")}},O={file:(Y,Z)=>{try{v(Y,Z??"",{flag:"wx"})}catch($){}return!0},dir:(Y)=>{return c(Y,{recursive:!0}),!0},decode(Y){return h.decode(Y)}};function p(Y=64){return new b("sha256").update(_(Y)).digest("hex")}class l{postgresClient;config={COOKIE_NAME:"session",COOKIE_DOMAIN:"127.0.0.1",COOKIE_PATH:"/",COOKIE_HTTPONLY:!0,COOKIE_SECURE:!0,REFRESH_EACH_REQUEST:!1,COOKIE_SAMESITE:"Strict",KEY_PREFIX:"session:",PERMANENT:!0,USE_SIGNER:!1,ID_LENGTH:32,FILE_THRESHOLD:500,LIFETIME:31,MAX_COOKIE_SIZE:4093,INTERFACE:"fs",STORAGE:".sessions",JWT_STORAGE:".jwt",JWT_LIFETIME:5};constructor({type:Y="fs",dir:Z}={}){Y&&(this.config.INTERFACE=Y),Z&&this.initStorage(Z)}initStorage(Y){return this.config.STORAGE=Y+"/"+this.config.STORAGE,this.config.JWT_STORAGE=Y+"/"+this.config.JWT_STORAGE,this}get session(){return new C(this.config,this.config.STORAGE)}get jwt(){return new C(this.config,this.config.JWT_STORAGE)}}class w{data;modified;new=!0;length=0;constructor(Y={}){if(this.modified=!0,this.data={},this.length=F(Y),this.length)this.new=!1;D(this.data,Y)}set(Y,Z,$){if(!this.readonly&&Y.data[Z]!=$){if(this.modified=!0,!(Z in Y.data))this.length++;return Y.data[Z]=$,!0}return!1}get(Y,Z){if(Z in Y)return Y[Z];return Y.data[Z]}has(Y,Z){if(Z in Y.data)return!0;return!1}deleteProperty(Y,Z){if(!this.readonly&&Z in Y.data)this.modified=!0,delete Y.data[Z],this.length--;return!0}}class J extends w{sid;modified;readOnly;constructor(Y="",Z={},$=!1){super(Z);this.sid=Y;this.modified=!1,this.readOnly=$}get session(){return new Proxy(this,this)}}class u{salt;constructor(Y){this.salt=Y}getSignature(Y){let Z=this.deriveKey().toString();return j(Z,Y).toString("base64")}deriveKey(){return j(this.salt)}sign(Y){let Z=this.getSignature(Y),$=V(Y+"."+Z);return O.decode($)}unsign(Y){if(!(Y.indexOf(".")>-1))throw Error("No sep found");let Z=Y.indexOf("."),$=Y.slice(0,Z),U=Y.slice(Z+1);return this.verifySignature($,U)}loadUnsign(Y){if(this.unsign(Y)){let Z=V(Y),$=V(".").toString()[0];if(!($ in Z))throw Error("No sep found");let U=Z.indexOf($),W=Z.subarray(0,U);return Buffer.from(W.toString(),"base64").toString("utf-8")}}verifySignature(Y,Z){return this.getSignature(Y)==Z?!0:!1}}class P{signer;constructor(Y){this.signer=new u(Y)}generate(Y=21){let $=_(Y).toString("base64");if($.endsWith("="))$=$.slice(0,-1);return this.signer.sign($)}}class x extends P{config;constructor(Y,Z){super(Z??"salty");this.config=Y}async openSession(Y,Z){if(Y&&this.signer.unsign(Y))return await this.fetchSession(Y,Z);return this.new}async fetchSession(Y,Z){return this.new}async saveSession(Y,Z,$=!1){return}get new(){return new J(this.generate(),{}).session}get readonly(){return new J(this.generate(),{},!0).session}get getExpiration(){let Y=new Date,Z=this.config.LIFETIME;return Y.setDate(Y.getDate()+Z).toString()}setCookie(Y,Z,$=""){let U=null,W={};if(this.config.COOKIE_SAMESITE)U=this.config.COOKIE_SAMESITE;if($)U=$;if(Z===0)W.maxAge=Z.toString();else W.expires=Z;return n.cookie(this.config.COOKIE_NAME,Y.sid,{domain:"",path:this.config.COOKIE_PATH,httpOnly:this.config.COOKIE_HTTPONLY,secure:this.config.COOKIE_SECURE,sameSite:U,...W})}async loadHeader(Y,Z){let $=async(W)=>{let Q="";if(W)Q=W.split(";").reduce((E,z)=>{let[B,X]=z.trim().split(/=(.*)/s);return E[B]=X,E},{}).session;let q=Q;return await this.openSession(q,Z)},U=Y.headers;if(U){if("get"in U)return await $(U.get("cookie"));else if("cookie"in U)return await $(U.cookie)}return this.new}}class k extends J{}class S{path;data;constructor(Y){this.data=new Map,this.path=Y+"/"}async init(Y){let Z=K(Y),$=this.path+Z,U=R($);if(await U.exists()){let W=await U.arrayBuffer();try{let Q=JSON.parse(O.decode(y(W)));return Q.f_timed=Date.now(),this.data.set(Z,Q),Q}catch(Q){}}return null}async checkLast(Y){let Z=new Date(Y);if(Z.setMinutes(Z.getMinutes()+60),Z.getTime()<Date.now())return!0;return!1}async get(Y){if(Y){let Z=this.data.get(Y);if(Z==null)return await this.init(Y);else{if(Z&&"f_timed"in Z){if(await this.checkLast(Z.f_timed))return await this.init(Y)}return Z}}return null}async set(Y,Z){let $=K(Y),U=this.path+$;O.file(U,""),await N(U,g(JSON.stringify(Z))),Z.f_timed=Date.now(),this.data.set(Y,Z)}async delete(Y){let Z=K(Y);this.data.delete(Z);let $=this.path+Z;R($).exists().then(async(U)=>{await m.unlink($)}).catch()}}class C extends x{isJWT;cacher;side=k;constructor(Y,Z=".sessions",$=!1){super(Y);this.isJWT=$;this.cacher=new S(Z)}life(Y,Z){let{LIFETIME:$,JWT_LIFETIME:U}=this.config;if(new H(Z).timed({day:this.isJWT?U:$}).getTime()-new Date().getTime()>0)return!0;else return this.cacher.delete(Y),!1}async fetchSession(Y,Z){let $=this.config.KEY_PREFIX+Y,U=await this.cacher.get($),W={};if(U){let Q=!0;if("life"in U)Q=this.life($,U.life);W=Q?JSON.parse(U.data):{}}return new this.side(Y,W,Z).session}async saveSession(Y,Z,$=!1){let U=(Q)=>{if(Z){let q=this.setCookie(Y,Q);if(Z)Z.set("Set-Cookie",q)}},W=this.config.KEY_PREFIX+Y.sid;if(!Y.length){if(!Y.new&&(Y.modified||$))this.cacher.delete(W),U(0);return}if(Y.new&&Y.modified){let Q=new H().timed({day:this.config.LIFETIME}),q=JSON.stringify(Y.data);await this.cacher.set(W,{data:q,life:H.now}),U(Q)}return}}class d{client;query;f_timed;data;key;constructor(Y,Z,$){this.query=$,this.key=Z,this.f_timed=Date.now(),this.data=new Map,this.client=Y}async init(Y){let Z=await this.client.query({text:this.query+` where ${this.key} = $1`,values:[Y]});for(let[$,U]of this.data)if(!U)this.data.delete($);if(Z.rowCount){let $=Z.rows[0];return $.f_timed=Date.now(),this.data.set(Y,$),$}else return this.data.set(Y,null),null}async checkLast(Y){let Z=new Date(Y);if(Z.setMinutes(Z.getMinutes()+15),Z.getTime()<Date.now())return!0;return!1}async get(Y){if(Y){let Z=this.data.get(Y);if(Z==null)return await this.init(Y);else{if(Z&&"f_timed"in Z){if(await this.checkLast(Z.f_timed))return await this.init(Y)}return Z}}return null}async set(Y){if(this.key in Y)Y.f_timed=Date.now(),this.data.set(Y[this.key],Y)}async delete(Y){this.data.delete(Y)}}class i extends P{salt;constructor(){super("salty_jwt");this.salt="salty_jwt"}sign(Y){let Z={issuer:this.salt};return T({data:Y},G(),Z)}get random(){let Y={issuer:this.salt},Z={data:p()};return T(Z,G(),Y)}jwt(){let Y=this.generate();return new J(Y).session}verify(Y,Z){try{let $=o(Y,G());if($){let{data:U,iat:W,iss:Q}=$;if(Q==this.salt)if(Z){let{days:q,hours:L,minutes:E,seconds:z}=Z,B=new Date(W*1000);if(q)B=new Date(B.setDate(B.getDate()+q));else if(L)B=new Date(B.setHours(B.getHours()+L));else if(E)B=new Date(B.setMinutes(B.getMinutes()+E));else if(z)B=new Date(B.setSeconds(B.getSeconds()+z));if(B.getTime()-Date.now()>0)return U}else return U}}catch($){}return null}open(Y,Z){if(Y){let $=this.verify(Y,Z);if($)return new J(Y,$,!0).session}return this.jwt()}save(Y){let Z=Y.data;if("access_token"in Z)delete Z.access_token;return this.sign(Z)}new(Y){return this.sign(Y)}}class s{fs;f_timed;data;key;dir;constructor({dir:Y,fs:Z,key:$}){this.dir=Y+"/ffs",this.key=$,this.f_timed=Date.now(),this.data=new Map,this.fs=this.dir+`/${Z}.json`}async init(){if(O.dir(this.dir)&&O.file(this.fs,"{}"))R(this.fs).text().then((Y)=>{let Z=JSON.parse(Y);this.data=new Map(I(Z))}).catch((Y)=>{})}async get(Y){let Z=this.data.get(Y);if(Z)return Z;return null}async set(Y){if(this.key in Y){let Z=await R(this.fs).text();if(Z){let $=JSON.parse(Z),U=Y[this.key];$[U]=Y,await N(this.fs,JSON.stringify($))}this.data.set(Y[this.key],Y)}}async delete(Y){if(await this.get(Y)){let Z=await R(this.fs).text();if(Z){let $=JSON.parse(Z.toString());if(Y in $)delete $[Y],await N(this.fs,JSON.stringify($));this.data.delete(Y)}}}async json(){let Y=await R(this.fs).text(),Z=JSON.parse(Y);return M(Z)}}export{K as decodeSID,J as ServerSide,d as PGCache,i as JWTInterface,s as Fjson,k as FSession,x as AuthInterface,l as Auth};
2
+ var ot=Object.create;var{getPrototypeOf:lt,defineProperty:ee,getOwnPropertyNames:ct}=Object;var ut=Object.prototype.hasOwnProperty;var ft=(e,t,s)=>{s=e!=null?ot(lt(e)):{};let r=t||!e||!e.__esModule?ee(s,"default",{value:e,enumerable:!0}):s;for(let i of ct(e))if(!ut.call(r,i))ee(r,i,{get:()=>e[i],enumerable:!0});return r};var te=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var j=import.meta.require;var Xe=te((ks,bt)=>{bt.exports={name:"dotenv",version:"17.2.3",description:"Loads environment variables from .env file",main:"lib/main.js",types:"lib/main.d.ts",exports:{".":{types:"./lib/main.d.ts",require:"./lib/main.js",default:"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},scripts:{"dts-check":"tsc --project tests/types/tsconfig.json",lint:"standard",pretest:"npm run lint && npm run dts-check",test:"tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000","test:coverage":"tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",prerelease:"npm test",release:"standard-version"},repository:{type:"git",url:"git://github.com/motdotla/dotenv.git"},homepage:"https://github.com/motdotla/dotenv#readme",funding:"https://dotenvx.com",keywords:["dotenv","env",".env","environment","variables","config","settings"],readmeFilename:"README.md",license:"BSD-2-Clause",devDependencies:{"@types/node":"^18.11.3",decache:"^4.6.2",sinon:"^14.0.1",standard:"^17.0.0","standard-version":"^9.5.0",tap:"^19.2.0",typescript:"^4.8.4"},engines:{node:">=12"},browser:{fs:!1}}});var et=te((Hs,y)=>{var U=j("fs"),$=j("path"),wt=j("os"),Et=j("crypto"),Ot=Xe(),G=Ot.version,qe=["\uD83D\uDD10 encrypt with Dotenvx: https://dotenvx.com","\uD83D\uDD10 prevent committing .env to code: https://dotenvx.com/precommit","\uD83D\uDD10 prevent building .env in docker: https://dotenvx.com/prebuild","\uD83D\uDCE1 add observability to secrets: https://dotenvx.com/ops","\uD83D\uDC65 sync secrets across teammates & machines: https://dotenvx.com/ops","\uD83D\uDDC2\uFE0F backup and recover secrets: https://dotenvx.com/ops","\u2705 audit secrets and track compliance: https://dotenvx.com/ops","\uD83D\uDD04 add secrets lifecycle management: https://dotenvx.com/ops","\uD83D\uDD11 add access controls to secrets: https://dotenvx.com/ops","\uD83D\uDEE0\uFE0F run anywhere with `dotenvx run -- yourcommand`","\u2699\uFE0F specify custom .env file path with { path: '/custom/path/.env' }","\u2699\uFE0F enable debug logging with { debug: true }","\u2699\uFE0F override existing env vars with { override: true }","\u2699\uFE0F suppress all logs with { quiet: true }","\u2699\uFE0F write to custom object with { processEnv: myObject }","\u2699\uFE0F load multiple .env files with { path: ['.env.local', '.env'] }"];function Mt(){return qe[Math.floor(Math.random()*qe.length)]}function O(e){if(typeof e==="string")return!["false","0","no","off",""].includes(e.toLowerCase());return Boolean(e)}function Tt(){return process.stdout.isTTY}function xt(e){return Tt()?`\x1B[2m${e}\x1B[0m`:e}var At=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function It(e){let t={},s=e.toString();s=s.replace(/\r\n?/mg,`
3
+ `);let r;while((r=At.exec(s))!=null){let i=r[1],n=r[2]||"";n=n.trim();let a=n[0];if(n=n.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),a==='"')n=n.replace(/\\n/g,`
4
+ `),n=n.replace(/\\r/g,"\r");t[i]=n}return t}function Ct(e){e=e||{};let t=ze(e);e.path=t;let s=f.configDotenv(e);if(!s.parsed){let a=Error(`MISSING_DATA: Cannot parse ${t} for an unknown reason`);throw a.code="MISSING_DATA",a}let r=Ve(e).split(","),i=r.length,n;for(let a=0;a<i;a++)try{let o=r[a].trim(),c=Nt(s,o);n=f.decrypt(c.ciphertext,c.key);break}catch(o){if(a+1>=i)throw o}return f.parse(n)}function jt(e){console.error(`[dotenv@${G}][WARN] ${e}`)}function I(e){console.log(`[dotenv@${G}][DEBUG] ${e}`)}function Qe(e){console.log(`[dotenv@${G}] ${e}`)}function Ve(e){if(e&&e.DOTENV_KEY&&e.DOTENV_KEY.length>0)return e.DOTENV_KEY;if(process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0)return process.env.DOTENV_KEY;return""}function Nt(e,t){let s;try{s=new URL(t)}catch(o){if(o.code==="ERR_INVALID_URL"){let c=Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");throw c.code="INVALID_DOTENV_KEY",c}throw o}let r=s.password;if(!r){let o=Error("INVALID_DOTENV_KEY: Missing key part");throw o.code="INVALID_DOTENV_KEY",o}let i=s.searchParams.get("environment");if(!i){let o=Error("INVALID_DOTENV_KEY: Missing environment part");throw o.code="INVALID_DOTENV_KEY",o}let n=`DOTENV_VAULT_${i.toUpperCase()}`,a=e.parsed[n];if(!a){let o=Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${n} in your .env.vault file.`);throw o.code="NOT_FOUND_DOTENV_ENVIRONMENT",o}return{ciphertext:a,key:r}}function ze(e){let t=null;if(e&&e.path&&e.path.length>0)if(Array.isArray(e.path)){for(let s of e.path)if(U.existsSync(s))t=s.endsWith(".vault")?s:`${s}.vault`}else t=e.path.endsWith(".vault")?e.path:`${e.path}.vault`;else t=$.resolve(process.cwd(),".env.vault");if(U.existsSync(t))return t;return null}function Ze(e){return e[0]==="~"?$.join(wt.homedir(),e.slice(1)):e}function _t(e){let t=O(process.env.DOTENV_CONFIG_DEBUG||e&&e.debug),s=O(process.env.DOTENV_CONFIG_QUIET||e&&e.quiet);if(t||!s)Qe("Loading env from encrypted .env.vault");let r=f._parseVault(e),i=process.env;if(e&&e.processEnv!=null)i=e.processEnv;return f.populate(i,r,e),{parsed:r}}function Rt(e){let t=$.resolve(process.cwd(),".env"),s="utf8",r=process.env;if(e&&e.processEnv!=null)r=e.processEnv;let i=O(r.DOTENV_CONFIG_DEBUG||e&&e.debug),n=O(r.DOTENV_CONFIG_QUIET||e&&e.quiet);if(e&&e.encoding)s=e.encoding;else if(i)I("No encoding is specified. UTF-8 is used by default");let a=[t];if(e&&e.path)if(!Array.isArray(e.path))a=[Ze(e.path)];else{a=[];for(let l of e.path)a.push(Ze(l))}let o,c={};for(let l of a)try{let u=f.parse(U.readFileSync(l,{encoding:s}));f.populate(c,u,e)}catch(u){if(i)I(`Failed to load ${l} ${u.message}`);o=u}let h=f.populate(r,c,e);if(i=O(r.DOTENV_CONFIG_DEBUG||i),n=O(r.DOTENV_CONFIG_QUIET||n),i||!n){let l=Object.keys(h).length,u=[];for(let g of a)try{let m=$.relative(process.cwd(),g);u.push(m)}catch(m){if(i)I(`Failed to load ${g} ${m.message}`);o=m}Qe(`injecting env (${l}) from ${u.join(",")} ${xt(`-- tip: ${Mt()}`)}`)}if(o)return{parsed:c,error:o};else return{parsed:c}}function Dt(e){if(Ve(e).length===0)return f.configDotenv(e);let t=ze(e);if(!t)return jt(`You set DOTENV_KEY but you are missing a .env.vault file at ${t}. Did you forget to build it?`),f.configDotenv(e);return f._configVault(e)}function $t(e,t){let s=Buffer.from(t.slice(-64),"hex"),r=Buffer.from(e,"base64"),i=r.subarray(0,12),n=r.subarray(-16);r=r.subarray(12,-16);try{let a=Et.createDecipheriv("aes-256-gcm",s,i);return a.setAuthTag(n),`${a.update(r)}${a.final()}`}catch(a){let o=a instanceof RangeError,c=a.message==="Invalid key length",h=a.message==="Unsupported state or unable to authenticate data";if(o||c){let l=Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");throw l.code="INVALID_DOTENV_KEY",l}else if(h){let l=Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");throw l.code="DECRYPTION_FAILED",l}else throw a}}function kt(e,t,s={}){let r=Boolean(s&&s.debug),i=Boolean(s&&s.override),n={};if(typeof t!=="object"){let a=Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");throw a.code="OBJECT_REQUIRED",a}for(let a of Object.keys(t))if(Object.prototype.hasOwnProperty.call(e,a)){if(i===!0)e[a]=t[a],n[a]=t[a];if(r)if(i===!0)I(`"${a}" is already defined and WAS overwritten`);else I(`"${a}" is already defined and was NOT overwritten`)}else e[a]=t[a],n[a]=t[a];return n}var f={configDotenv:Rt,_configVault:_t,_parseVault:Ct,config:Dt,decrypt:$t,parse:It,populate:kt};Hs.configDotenv=f.configDotenv;Hs._configVault=f._configVault;Hs._parseVault=f._parseVault;Hs.config=f.config;Hs.decrypt=f.decrypt;Hs.parse=f.parse;Hs.populate=f.populate;y.exports=f});import{randomBytes as Bt}from"crypto";var{getPrototypeOf:is,defineProperty:ht,getOwnPropertyNames:as}=Object;var gt=(e,t)=>{for(var s in t)ht(e,s,{get:t[s],enumerable:!0,configurable:!0,set:(r)=>t[s]=()=>r})};var se={};gt(se,{isWhitespace:()=>Ie,isWeakSet:()=>Se,isWeakMap:()=>ye,isUndefined:()=>P,isUint8Array:()=>ce,isSymbol:()=>ie,isSubclassOf:()=>Je,isString:()=>N,isSet:()=>pe,isRegExp:()=>De,isRecord:()=>he,isReadonlyArray:()=>ne,isPromise:()=>ke,isPrimitive:()=>Fe,isPositiveNumber:()=>Ne,isPlainObject:()=>T,isObjectLike:()=>be,isObject:()=>R,isNumberLike:()=>ae,isNumber:()=>b,isNullish:()=>Me,isNull:()=>Ee,isNotNullish:()=>Te,isNotNull:()=>w,isNonNegativeNumber:()=>_e,isNonFunctionObject:()=>we,isNonEmptyString:()=>Ae,isNonEmptyObject:()=>fe,isModule:()=>ve,isMap:()=>me,isIterable:()=>ge,isInteger:()=>Ce,isInstanceOf:()=>Pe,isFunction:()=>W,isFiniteNumber:()=>je,isError:()=>$e,isEmptyString:()=>xe,isEmpty:()=>He,isDefined:()=>Oe,isDate:()=>Re,isClass:()=>We,isBoolean:()=>L,isBinaryLike:()=>ue,isBigInt:()=>re,isAsyncIterable:()=>de,isAsyncFunction:()=>Le,isArrayBufferView:()=>le,isArrayBuffer:()=>oe,isArray:()=>_,IS_NOT_BROWSER:()=>J,IS_BROWSER:()=>Ye});var L=(e)=>typeof e==="boolean",N=(e)=>typeof e==="string",b=(e)=>typeof e==="number"&&!Number.isNaN(e),re=(e)=>typeof e==="bigint",ie=(e)=>typeof e==="symbol",W=(e)=>typeof e==="function",ae=(e)=>{let t=typeof e==="number"?e:parseFloat(String(e));return!Number.isNaN(t)&&Number.isFinite(t)},_=(e)=>Array.isArray(e),ne=(e)=>Array.isArray(e),oe=(e)=>e instanceof ArrayBuffer,le=(e)=>typeof ArrayBuffer<"u"&&ArrayBuffer.isView(e),ce=(e)=>e instanceof Uint8Array,ue=(e)=>e instanceof Uint8Array||e instanceof ArrayBuffer||typeof e==="string",R=(e)=>w(e)&&typeof e==="object",T=(e)=>w(e)&&R(e)&&(Object.getPrototypeOf(e)===Object.prototype||Object.getPrototypeOf(e)===null),fe=(e)=>T(e)&&Object.keys(e).length>0,he=(e)=>T(e),ge=(e)=>e!=null&&typeof e[Symbol.iterator]==="function",de=(e)=>e!=null&&typeof e[Symbol.asyncIterator]==="function",me=(e)=>e instanceof Map,pe=(e)=>e instanceof Set,ye=(e)=>e instanceof WeakMap,Se=(e)=>e instanceof WeakSet,be=(e)=>e!==null&&(typeof e==="object"||typeof e==="function"),we=(e)=>e!==null&&typeof e==="object",Ee=(e)=>e===null,P=(e)=>e===void 0,Oe=(e)=>!P(e),Me=(e)=>e==null,w=(e)=>e!==null,Te=(e)=>e!=null,xe=(e)=>typeof e==="string"&&e.length===0,Ae=(e)=>typeof e==="string"&&e.length>0,Ie=(e)=>typeof e==="string"&&e.length>0&&e.trim().length===0,Ce=(e)=>b(e)&&Number.isInteger(e),je=(e)=>b(e)&&Number.isFinite(e),Ne=(e)=>b(e)&&Number.isFinite(e)&&e>0,_e=(e)=>b(e)&&Number.isFinite(e)&&e>=0,Re=(e)=>e instanceof Date&&!Number.isNaN(e.getTime()),De=(e)=>e instanceof RegExp,$e=(e)=>e instanceof Error,ke=(e)=>!!e&&typeof e.then==="function",He=(e)=>e==null||typeof e==="string"&&e.length===0||Array.isArray(e)&&e.length===0||(e instanceof Map||e instanceof Set)&&e.size===0||T(e)&&Object.keys(e).length===0,Fe=(e)=>e===null||typeof e!=="object"&&typeof e!=="function",ve=(e)=>w(e)&&R(e)&&e[Symbol.toStringTag]==="Module",Ye=typeof window<"u",J=typeof window>"u",Le=(e)=>W(e)&&w(e.constructor)&&e.constructor.name==="AsyncFunction",We=(e)=>typeof e==="function"&&/^class\s/.test(Function.prototype.toString.call(e)),Pe=(e,t)=>e instanceof t,Je=(e,t)=>typeof e==="function"&&typeof t==="function"&&e.prototype.isPrototypeOf(t.prototype);var x=(e)=>{return new TextEncoder().encode(e)};var A=(e)=>{return new TextDecoder().decode(e)};var D=Object.assign;var K=(e)=>Object.keys(e).length;var S=(e,t=2)=>String(e).padStart(t,"0"),Ke=new Map;function E(e,t){let s=JSON.stringify({locale:t,...e}),r=Ke.get(s);if(!r)r=new Intl.DateTimeFormat(t,e),Ke.set(s,r);return r}var B={YYYY:(e)=>String(e.getFullYear()),YY:(e)=>S(e.getFullYear()%100),MMMM:(e,t)=>E({month:"long"},t).format(e),MMM:(e,t)=>E({month:"short"},t).format(e),MM:(e)=>S(e.getMonth()+1),M:(e)=>String(e.getMonth()+1),dddd:(e,t)=>E({weekday:"long"},t).format(e),ddd:(e,t)=>E({weekday:"short"},t).format(e),DD:(e)=>S(e.getDate()),D:(e)=>String(e.getDate()),HH:(e)=>S(e.getHours()),H:(e)=>String(e.getHours()),hh:(e)=>{let t=e.getHours()%12||12;return S(t)},h:(e)=>String(e.getHours()%12||12),A:(e,t)=>{return(E({hour:"numeric",hour12:!0},t).formatToParts(e).find((s)=>s.type==="dayPeriod")?.value??(e.getHours()<12?"AM":"PM")).toUpperCase()},a:(e,t)=>{return(E({hour:"numeric",hour12:!0},t).formatToParts(e).find((s)=>s.type==="dayPeriod")?.value??(e.getHours()<12?"AM":"PM")).toLowerCase()},mm:(e)=>S(e.getMinutes()),m:(e)=>String(e.getMinutes()),ss:(e)=>S(e.getSeconds()),s:(e)=>String(e.getSeconds()),SSS:(e)=>S(e.getMilliseconds(),3),Q:(e)=>String(Math.floor(e.getMonth()/3)+1),DoY:(e)=>{let t=new Date(e.getFullYear(),0,1),s=Math.floor((+e-+t)/86400000)+1;return String(s)}};function St(){if(globalThis.__dateTokenRegex)return globalThis.__dateTokenRegex;let e=new RegExp(Object.keys(B).sort((t,s)=>s.length-t.length).map((t)=>t.replace(/([.*+?^${}()|[\]\\])/g,"\\$1")).join("|"),"g");return globalThis.__dateTokenRegex=e,e}function Ge(e,t="YYYY-MM-DD HH:mm:ss",s){let r=typeof e==="number"?new Date(e):typeof e==="string"?new Date(e):e,i=St(),n=new Map;return t.replace(i,(a)=>{if(n.has(a))return n.get(a);let o=B[a],c=o?o(r,s):a;return n.set(a,c),c})}Date.prototype.format=function(e,t){return Ge(this,e,t)};Date.registerFormat=function(e,t){B[e]=t,globalThis.__dateTokenRegex=null};Date.format=function(e,t){return new Date().format(e,t)};class p{date;constructor(e){this.date=e?new Date(e):new Date}timed(e,t=1){let s=[["year","FullYear"],["month","Month"],["day","Date"],["hour","Hours"],["minute","Minutes"],["second","Seconds"],["millisecond","Milliseconds"]],r=this.date;if(e.quarter)r.setMonth(r.getMonth()+3*e.quarter);if(e.week)r.setDate(r.getDate()+7*e.week);for(let[i,n]of s){let a=e[i];if(a!==void 0&&a!==0)r[`set${n}`](r[`get${n}`]()+a)}if(e.startOfMonth)r.setDate(1),r.setHours(0,0,0,0);if(e.endOfMonth)r.setMonth(r.getMonth()+1,0),r.setHours(23,59,59,999);if(e.week!==void 0&&t!==void 0){let i=(r.getDay()-t+7)%7;r.setDate(r.getDate()-i)}return r}static timed(e,t=1){return new p().timed(e,t)}static local(e){return new Date(e).toLocaleString()}local(){return this.date.toLocaleDateString()}format(e="YYYY-MM-DD HH:mm:ss",t){return Ge(this.date,e,t)}static format(e="YYYY-MM-DD HH:mm:ss",t){let s=new Date,r=typeof s==="number"?new Date(s):typeof s==="string"?new Date(s):s,i=(m,nt=2)=>String(m).padStart(nt,"0"),n=r.getHours(),a=n%12||12,o=new Intl.DateTimeFormat(t,{month:"long"}).format(r),c=new Intl.DateTimeFormat(t,{month:"short"}).format(r),h=new Intl.DateTimeFormat(t,{weekday:"long"}).format(r),l=new Intl.DateTimeFormat(t,{weekday:"short"}).format(r),u=new Intl.DateTimeFormat(t,{hour:"numeric",hour12:!0}).formatToParts(r).find((m)=>m.type==="dayPeriod")?.value||(n<12?"AM":"PM"),g={YYYY:String(r.getFullYear()),YY:i(r.getFullYear()%100),MMMM:o,MMM:c,MM:i(r.getMonth()+1),M:String(r.getMonth()+1),dddd:h,ddd:l,DD:i(r.getDate()),D:String(r.getDate()),HH:i(n),H:String(n),hh:i(a),h:String(a),A:u.toUpperCase(),a:u.toLowerCase(),mm:i(r.getMinutes()),m:String(r.getMinutes()),ss:i(r.getSeconds()),s:String(r.getSeconds()),SSS:i(r.getMilliseconds(),3),Q:String(Math.floor(r.getMonth()/3)+1)};return e.replace(/YYYY|YY|MMMM|MMM|MM|M|dddd|ddd|DD|D|HH|H|hh|h|A|a|mm|m|ss|s|SSS|Q/g,(m)=>g[m])}static get now(){return Date.now()}random(e=new Date){let t=this.date.getTime(),s=e.getTime(),r=t+Math.random()*(s-t);return new Date(r)}static random(e,t=new Date){let s=e.getTime(),r=t.getTime(),i=s+Math.random()*(r-s);return new Date(i)}delta(e){let t=this.date;if(e.year)t.setFullYear(t.getFullYear()+e.year);if(e.month)t.setMonth(t.getMonth()+e.month);if(e.day)t.setDate(t.getDate()+e.day);if(e.hour)t.setHours(t.getHours()+e.hour);if(e.minute)t.setMinutes(t.getMinutes()+e.minute);if(e.second)t.setSeconds(t.getSeconds()+e.second);return t}static delta(e){return new p().delta(e)}}var Kt=ft(et(),1),{file:Ws}=globalThis.Bun,Jt=async(e)=>{return await Bun.file(e).exists()},tt=async(e,t="")=>{if(await Jt(e))return!0;return await Bun.write(e,t),!0};var k=()=>{let e=process.env.SECRET_KEY;if(!e)throw Error("'SECRET_KEY' not found in .env file");return e};var{file:Ps,write:Js}=globalThis.Bun;var X=(e,...t)=>{let s=new Bun.CryptoHasher("sha256",e);return t.forEach((r)=>{s.update(r)}),s.digest()};class q{salt;constructor(e){this.salt=e}getSignature(e){let t=this.deriveKey().toString();return X(t,e).toString("base64")}deriveKey(){return X(this.salt)}sign(e){let t=this.getSignature(e),s=x(e+"."+t);return A(s)}unsign(e){if(!(e.indexOf(".")>-1))throw Error("No sep found");let t=e.indexOf("."),s=e.slice(0,t),r=e.slice(t+1);return this.verifySignature(s,r)}loadUnsign(e){if(this.unsign(e)){let t=x(e),s=x(".").toString()[0];if(s){if(!(s in t))throw Error("No sep found");let r=t.indexOf(s),i=t.subarray(0,r);return Buffer.from(i.toString(),"base64").toString("utf-8")}}return}verifySignature(e,t){return this.getSignature(e)==t?!0:!1}}var{CryptoHasher:Ut}=globalThis.Bun;class C{signer;constructor(e){this.signer=new q(e)}generate(e=21){let s=Bt(e).toString("base64");if(s.endsWith("="))s=s.slice(0,-1);return this.signer.sign(s)}}function H(e){let t=new Ut("md5");return t.update(e),t.digest("hex")}class st{data;modified;new=!0;length=0;constructor(e={}){if(this.modified=!0,this.data={},this.length=K(e),this.length)this.new=!1;D(this.data,e)}set(e,t,s){if(!this.readonly&&e.data[t]!=s){if(this.modified=!0,!(t in e.data))this.length++;return e.data[t]=s,!0}return!1}get(e,t){if(t in e)return e[t];return e.data[t]}has(e,t){if(t in e.data)return!0;return!1}deleteProperty(e,t){if(!this.readonly&&t in e.data)this.modified=!0,delete e.data[t],this.length--;return!0}}class d extends st{sid;modified;readOnly;constructor(e="",t={},s=!1){super(t);this.sid=e;this.modified=!1,this.readOnly=s}get session(){return new Proxy(this,this)}}var rt=(e,t="",s={})=>{let{maxAge:r,expires:i,path:n,domain:a,secure:o,httpOnly:c,sameSite:h}=s,l=r instanceof Date?Math.floor(r.getTime()/1000):typeof r==="number"?r:void 0,u;if(i instanceof Date)u=i.toUTCString();else if(typeof i==="number")u=new Date(i).toUTCString();else if(typeof i==="string")u=i;else if(i===0)u=new Date().toUTCString();let g=[];if(a)g.push(`Domain=${a}`);if(u)g.push(`Expires=${u}`);if(l!==void 0)g.push(`Max-Age=${l}`);if(o)g.push("Secure");if(c)g.push("HttpOnly");if(n!=null)g.push(`Path=${n}`);if(h!=null)g.push(`SameSite=${h}`);return[`${e}=${t}`,...g].join("; ")};class M extends C{config;constructor(e,t){super(t??"salty");this.config=e}async openSession(e,t){if(e&&this.signer.unsign(e))return await this.fetchSession(e,t);return this.new}async fetchSession(e,t){return this.new}async saveSession(e,t,s=!1){return}get new(){return new d(this.generate(),{}).session}get readonly(){return new d(this.generate(),{},!0).session}get getExpiration(){let e=new Date,t=this.config.LIFETIME;return e.setDate(e.getDate()+t).toString()}setCookie(e,t,s=""){let r=null,i={};if(this.config.COOKIE_SAMESITE)r=this.config.COOKIE_SAMESITE;if(s)r=s;if(t===0)i.maxAge=t.toString();else i.expires=t;return rt(this.config.COOKIE_NAME,e.sid,{domain:"",path:this.config.COOKIE_PATH,httpOnly:this.config.COOKIE_HTTPONLY,secure:this.config.COOKIE_SECURE,sameSite:r,...i})}async loadHeader(e,t){let s=async(i)=>{let n="";if(i)n=i.split(";").reduce((c,h)=>{let[l,u]=h.trim().split(/=(.*)/s);return c[l]=u,c},{}).session;let a=n;return await this.openSession(a,t)},r=e.headers;if(r){if("get"in r)return await s(r.get("cookie"));else if("cookie"in r)return await s(r.cookie)}return this.new}}var{file:it,gunzipSync:Gt,gzipSync:Xt,write:qt}=globalThis.Bun;import{promises as Zt}from"fs";class F{path;data;constructor(e){this.data=new Map,this.path=e+"/"}async init(e){let t=H(e),s=this.path+t,r=it(s);if(await r.exists()){let i=await r.arrayBuffer();try{let n=JSON.parse(A(Gt(i)));return n.f_timed=Date.now(),this.data.set(t,n),n}catch(n){}}return null}async checkLast(e){let t=new Date(e);if(t.setMinutes(t.getMinutes()+60),t.getTime()<Date.now())return!0;return!1}async get(e){if(e){let t=this.data.get(e);if(t==null)return await this.init(e);else{if(t&&"f_timed"in t){if(await this.checkLast(t.f_timed))return await this.init(e)}return t}}return null}async set(e,t){let s=H(e),r=this.path+s;tt(r,""),await qt(r,Xt(JSON.stringify(t))),t.f_timed=Date.now(),this.data.set(e,t)}async delete(e){let t=H(e);this.data.delete(t);let s=this.path+t;it(s).exists().then(async(r)=>{await Zt.unlink(s)}).catch()}}class Z extends d{}class v extends M{isJWT;cacher;side=Z;constructor(e,t=".sessions",s=!1){super(e);this.isJWT=s;this.cacher=new F(t)}life(e,t){let{LIFETIME:s,JWT_LIFETIME:r}=this.config;if(new p(t).timed({day:this.isJWT?r:s}).getTime()-new Date().getTime()>0)return!0;else return this.cacher.delete(e),!1}async fetchSession(e,t){let s=this.config.KEY_PREFIX+e,r=await this.cacher.get(s),i={};if(r){let n=!0;if("life"in r)n=this.life(s,r.life);i=n?JSON.parse(r.data):{}}return new this.side(e,i,t).session}async saveSession(e,t,s=!1){let r=(n)=>{if(t){let a=this.setCookie(e,n);if(t)t.set("Set-Cookie",a)}},i=this.config.KEY_PREFIX+e.sid;if(!e.length){if(!e.new&&(e.modified||s))this.cacher.delete(i),r(0);return}if(e.new&&e.modified){let n=new p().timed({day:this.config.LIFETIME}),a=JSON.stringify(e.data);await this.cacher.set(i,{data:a,life:p.now}),r(n)}return}}class Y{client;query;f_timed;data;key;constructor(e,t,s){this.query=s,this.key=t,this.f_timed=Date.now(),this.data=new Map,this.client=e}async init(e){let t=await this.client.query({text:this.query+` where ${this.key} = $1`,values:[e]});for(let[s,r]of this.data)if(!r)this.data.delete(s);if(t.rowCount){let s=t.rows[0];return s.f_timed=Date.now(),this.data.set(e,s),s}else return this.data.set(e,null),null}async checkLast(e){let t=new Date(e);if(t.setMinutes(t.getMinutes()+15),t.getTime()<Date.now())return!0;return!1}async get(e){if(e){let t=this.data.get(e);if(t==null)return await this.init(e);else{if(t&&"f_timed"in t){if(await this.checkLast(t.f_timed))return await this.init(e)}return t}}return null}async set(e){if(this.key in e)e.f_timed=Date.now(),this.data.set(e[this.key],e)}async delete(e){this.data.delete(e)}}class Q extends d{}class V extends M{sclass=Q;client;pgc;constructor(e,t){super(t);this.client=e,this.pgc=new Y(e,"sid","SELECT * FROM session")}async fetchSession(e){let t=this.config.KEY_PREFIX+e,s=await this.pgc.get(t),r={};if(s)r=JSON.parse(s.data);return new this.sclass(e,r).session}async saveSession(e,t,s,r=""){let i=this.config.KEY_PREFIX+e.sid;if(!Object.entries(e.data).length){if(e.modified||s){if(t){await this.client.query({text:"DELETE FROM session WHERE sid = $1",values:[i]}),await this.pgc.delete(i);let o=this.setCookie(e,0);t.header={"Set-Cookie":o}}}return}let n=new p().timed({day:this.config.LIFETIME}),a=JSON.stringify(e.data);if(t){let o=this.getExpiration;await this.client.query({text:"INSERT INTO session(sid, data, expiration) VALUES($1, $2, $3)",values:[i,a,o?o:null]}),await this.pgc.set({sid:i,data:a,expiration:o??"",life:p.now});let c=this.setCookie(e,n);t.header={"Set-Cookie":c}}}}var{CryptoHasher:Qt}=globalThis.Bun;import{sign as at,verify as Vt}from"jsonwebtoken";import{randomBytes as zt}from"crypto";class z extends C{salt;constructor(){super("salty_jwt");this.salt="salty_jwt"}sign(e){let t={issuer:this.salt};return at({data:e},k(),t)}get random(){let e={issuer:this.salt},t={data:es()};return at(t,k(),e)}jwt(){let e=this.generate();return new d(e).session}verify(e,t){try{let s=Vt(e,k());if(s){let{data:r,iat:i,iss:n}=s;if(n==this.salt)if(t){let{days:a,hours:o,minutes:c,seconds:h}=t,l=new Date(i*1000);if(a)l=new Date(l.setDate(l.getDate()+a));else if(o)l=new Date(l.setHours(l.getHours()+o));else if(c)l=new Date(l.setMinutes(l.getMinutes()+c));else if(h)l=new Date(l.setSeconds(l.getSeconds()+h));if(l.getTime()-Date.now()>0)return r}else return r}}catch(s){}return null}open(e,t){if(e){let s=this.verify(e,t);if(s)return new d(e,s,!0).session}return this.jwt()}save(e){let t=e.data;if("access_token"in t)delete t.access_token;return this.sign(t)}new(e){return this.sign(e)}}function es(e=64){return new Qt("sha256").update(zt(e)).digest("hex")}class ts{postgresClient;config={COOKIE_NAME:"session",COOKIE_DOMAIN:"127.0.0.1",COOKIE_PATH:"/",COOKIE_HTTPONLY:!0,COOKIE_SECURE:!0,REFRESH_EACH_REQUEST:!1,COOKIE_SAMESITE:"Strict",KEY_PREFIX:"session:",PERMANENT:!0,USE_SIGNER:!1,ID_LENGTH:32,FILE_THRESHOLD:500,LIFETIME:31,MAX_COOKIE_SIZE:4093,INTERFACE:"fs",STORAGE:".sessions",JWT_STORAGE:".jwt",JWT_LIFETIME:5};constructor({type:e="fs",dir:t}={}){e&&(this.config.INTERFACE=e),t&&this.initStorage(t)}initStorage(e){return this.config.STORAGE=e+"/"+this.config.STORAGE,this.config.JWT_STORAGE=e+"/"+this.config.JWT_STORAGE,this}get session(){if(this.config.INTERFACE==="postgres"&&this.postgresClient)return new V(this.postgresClient,this.config);return new v(this.config,this.config.STORAGE)}get jwt(){return new v(this.config,this.config.JWT_STORAGE)}}class ss{init(e){this.jwtInt=new z,this.session=e.session,this.jwt=e.jwt}}export{ss as Session,d as ServerSide,Q as PostgreSession,V as PGInterface,Y as PGCache,Z as FSession,v as FSInterface,F as FSCached,M as AuthInterface,ts as Auth};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "authored",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "authored",
5
5
  "author": "Marky <markjotep@gmail.com>",
6
6
  "license": "MIT",
@@ -10,9 +10,12 @@
10
10
  "dist"
11
11
  ],
12
12
  "scripts": {
13
- "cp_core": "mkdir -p ./src/core; cp -L ../_misc/@.ts ./src/core; cp -L ../_misc/@n.ts ./src/core;",
14
- "link__": "mkdir -p ./src/core; ln -sf ../../../_misc/@.ts ./src/core; ln -sf ../../../_misc/@n.ts ./src/core; ln -sf ../_misc/tsconfig.json ./",
15
- "build": "tsc && bun build ./src/index.ts --outdir ./dist --minify --packages external --target bun && rollup -c ./util/rollup.config.js"
13
+ "util": "cp -r ../misc/util ./",
14
+ "dirs": "for dir in ./src ./dist ./test ./util ./types; do mkdir -p $dir; done",
15
+ "@": "ln -sf ../../misc/@/ ./src",
16
+ "ts": "ln -sf ../misc/tsconfig.json ./;",
17
+ "init": "bun run dirs && bun run util && bun run @ && bun run ts;",
18
+ "build": "rm -r ./types ; tsc && bun build ./src/index.ts --outdir ./dist --minify --packages external --target bun && rollup -c ./util/rollup.config.js"
16
19
  },
17
20
  "keywords": [
18
21
  "ts",
@@ -27,15 +30,17 @@
27
30
  },
28
31
  "homepage": "https://github.com/MARKjotep/authored#readme",
29
32
  "dependencies": {
30
- "jsonwebtoken": "^9.0.2",
31
- "pg": "^8.13.1"
33
+ "jsonwebtoken": "^9.0.3",
34
+ "pg": "^8.17.2"
32
35
  },
33
36
  "devDependencies": {
34
- "@types/jsonwebtoken": "^9.0.7",
35
- "@types/pg": "^8.11.10"
37
+ "@types/jsonwebtoken": "^9.0.10",
38
+ "@types/pg": "^8.16.0",
39
+ "@coff-r/oven": "link:@coff-r/oven",
40
+ "@coff-r/x": "link:@coff-r/x"
36
41
  },
37
42
  "peerDependencies": {
38
- "typescript": "^5.0.0"
43
+ "typescript": "^5.8.3"
39
44
  },
40
45
  "bun": true,
41
46
  "type": "module"