hono-sessions 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,14 +13,9 @@ Hono Sessions is currently tested on these runtimes:
13
13
 
14
14
  Other runtimes may work, but are untested. In addition to Hono's requirements, the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is required for this library.
15
15
 
16
- If you want to use a backend storage driver (instead of just storing session data in an encrypted cookie), you'll need to use a storage engine provided by Hono Sessions. Right now, those include:
17
-
18
- - Deno KV
19
- - Bun SQLite
20
-
21
16
  ### 🛠️ Features
22
17
  - Flash messages — data that is deleted once it's read (one-off error messages, etc.)
23
- - Built-in Memory and Cookie storage drivers (more coming soon)
18
+ - Built-in Memory and Cookie storage drivers, as well as [community-supported drivers](https://github.com/jcs224/hono_sessions/wiki/Community-adapters) and the ability to [create your own storage driver](https://github.com/jcs224/hono_sessions/wiki/Creating-a-custom-storage-driver)
24
19
  - Encrypted cookies thanks to [iron-webcrypto](https://github.com/brc-dd/iron-webcrypto)
25
20
  - Session expiration after inactivity
26
21
  - Session key rotation*
@@ -32,12 +27,18 @@ If you want to use a backend storage driver (instead of just storing session dat
32
27
 
33
28
  ### Deno
34
29
 
35
- Simply include the package from `deno.land/x`
30
+ Simply include the package from [JSR](https://jsr.io/@jcs224/hono-sessions) or [NPM](https://www.npmjs.com/package/hono-sessions)
36
31
 
37
32
  ```ts
38
- import { sessionMiddleware } from 'https://deno.land/x/hono_sessions/mod.ts'
33
+ // JSR
34
+ import { sessionMiddleware } from 'jsr:@jcs224/hono-sessions'
35
+
36
+ // NPM
37
+ import { sessionMiddleware } from 'npm:hono-sessions'
39
38
  ```
40
39
 
40
+ You can also use `deno add` and not need the `jsr:` specifier.
41
+
41
42
  ### Node, Bun, Cloudflare Workers, etc.
42
43
 
43
44
  Install the NPM package
@@ -49,19 +50,19 @@ npm install hono-sessions
49
50
 
50
51
  ### Deno
51
52
  ```ts
52
- import { Hono } from 'https://deno.land/x/hono/mod.ts'
53
+ import { Hono } from 'npm:hono'
53
54
  import {
54
55
  Session,
55
56
  sessionMiddleware,
56
57
  CookieStore
57
- } from 'https://deno.land/x/hono_sessions/mod.ts'
58
+ } from 'jsr:@jcs224/hono-sessions'
58
59
 
59
60
  // Add types to your session data (optional)
60
61
  type SessionDataTypes = {
61
62
  'counter': number
62
63
  }
63
64
 
64
- // Set up your Hono instance, using your
65
+ // Set up your Hono instance, using your types
65
66
  const app = new Hono<{
66
67
  Variables: {
67
68
  session: Session<SessionDataTypes>,
@@ -93,29 +94,6 @@ app.get('/', async (c, next) => {
93
94
  Deno.serve(app.fetch)
94
95
  ```
95
96
 
96
- #### Using Deno KV storage driver
97
-
98
- ```ts
99
- import { Hono } from 'https://deno.land/x/hono/mod.ts'
100
- import { sessionMiddleware } from 'https://deno.land/x/hono_sessions/mod.ts'
101
- import { DenoKvStore } from 'https://deno.land/x/hono_sessions/src/store/deno/DenoKvStore.ts'
102
-
103
- const app = new Hono()
104
-
105
- const kv = await Deno.openKv()
106
- const store = new DenoKvStore(kv)
107
-
108
- app.use('*', sessionMiddleware({
109
- store,
110
- // ... other session options
111
- }))
112
-
113
- // Other app code
114
-
115
- Deno.serve(app.fetch)
116
-
117
- ```
118
-
119
97
  ### Bun
120
98
 
121
99
  ```ts
@@ -20,6 +20,7 @@ export declare class Session<T = any> {
20
20
  updateAccess(): void;
21
21
  get<K extends keyof T>(key: K): T[K] | null;
22
22
  set<K extends keyof T>(key: K, value: T[K]): void;
23
+ forget<K extends keyof T>(key: K): void;
23
24
  flash<K extends keyof T>(key: K, value: T[K]): void;
24
25
  }
25
26
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"Session.d.ts","sourceRoot":"","sources":["../../src/src/Session.ts"],"names":[],"mappings":"AAAA,UAAU,gBAAgB,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,qBAAa,OAAO,CAAC,CAAC,GAAG,GAAG;IAE1B,OAAO,CAAC,KAAK,CAAgB;;IAW7B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IAInC,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC;IAI1B,aAAa,CAAC,UAAU,EAAE,MAAM;IAIhC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAMjD,aAAa;IAIb,YAAY,IAAI,OAAO;IAIvB,YAAY;IAIZ,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAe3C,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAS1C,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;CAQ7C"}
1
+ {"version":3,"file":"Session.d.ts","sourceRoot":"","sources":["../../src/src/Session.ts"],"names":[],"mappings":"AAAA,UAAU,gBAAgB,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,qBAAa,OAAO,CAAC,CAAC,GAAG,GAAG;IAE1B,OAAO,CAAC,KAAK,CAAgB;;IAW7B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IAInC,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC;IAI1B,aAAa,CAAC,UAAU,EAAE,MAAM;IAIhC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAMjD,aAAa;IAIb,YAAY,IAAI,OAAO;IAIvB,YAAY;IAIZ,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAe3C,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAS1C,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IAMhC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;CAQ7C"}
@@ -56,6 +56,12 @@ export class Session {
56
56
  };
57
57
  this.cache._data[key] = entry;
58
58
  }
59
+ forget(key) {
60
+ const entry = this.cache._data[key];
61
+ if (!entry)
62
+ return;
63
+ delete this.cache._data[key];
64
+ }
59
65
  flash(key, value) {
60
66
  const entry = {
61
67
  value: value,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono-sessions",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "Cookie-based sessions for Hono web framework",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,10 +20,6 @@
20
20
  "./bun-sqlite-store": {
21
21
  "import": "./esm/src/store/bun/BunSqliteStore.js",
22
22
  "require": "./script/src/store/bun/BunSqliteStore.js"
23
- },
24
- "./cloudflare-d1-store": {
25
- "import": "./esm/src/store/cloudflare/CloudflareD1Store.js",
26
- "require": "./script/src/store/cloudflare/CloudflareD1Store.js"
27
23
  }
28
24
  },
29
25
  "dependencies": {
@@ -20,6 +20,7 @@ export declare class Session<T = any> {
20
20
  updateAccess(): void;
21
21
  get<K extends keyof T>(key: K): T[K] | null;
22
22
  set<K extends keyof T>(key: K, value: T[K]): void;
23
+ forget<K extends keyof T>(key: K): void;
23
24
  flash<K extends keyof T>(key: K, value: T[K]): void;
24
25
  }
25
26
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"Session.d.ts","sourceRoot":"","sources":["../../src/src/Session.ts"],"names":[],"mappings":"AAAA,UAAU,gBAAgB,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,qBAAa,OAAO,CAAC,CAAC,GAAG,GAAG;IAE1B,OAAO,CAAC,KAAK,CAAgB;;IAW7B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IAInC,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC;IAI1B,aAAa,CAAC,UAAU,EAAE,MAAM;IAIhC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAMjD,aAAa;IAIb,YAAY,IAAI,OAAO;IAIvB,YAAY;IAIZ,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAe3C,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAS1C,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;CAQ7C"}
1
+ {"version":3,"file":"Session.d.ts","sourceRoot":"","sources":["../../src/src/Session.ts"],"names":[],"mappings":"AAAA,UAAU,gBAAgB,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,qBAAa,OAAO,CAAC,CAAC,GAAG,GAAG;IAE1B,OAAO,CAAC,KAAK,CAAgB;;IAW7B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IAInC,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC;IAI1B,aAAa,CAAC,UAAU,EAAE,MAAM;IAIhC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAMjD,aAAa;IAIb,YAAY,IAAI,OAAO;IAIvB,YAAY;IAIZ,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAe3C,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAS1C,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IAMhC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;CAQ7C"}
@@ -59,6 +59,12 @@ class Session {
59
59
  };
60
60
  this.cache._data[key] = entry;
61
61
  }
62
+ forget(key) {
63
+ const entry = this.cache._data[key];
64
+ if (!entry)
65
+ return;
66
+ delete this.cache._data[key];
67
+ }
62
68
  flash(key, value) {
63
69
  const entry = {
64
70
  value: value,
@@ -1,12 +0,0 @@
1
- import Store from '../Store.js';
2
- import { SessionData } from '../../Session.js';
3
- export declare class CloudflareD1Store implements Store {
4
- db: any;
5
- tableName: string;
6
- constructor(tableName?: string);
7
- getSessionById(sessionId?: string | undefined): Promise<any>;
8
- createSession(sessionId: string, initialData: SessionData): Promise<void>;
9
- deleteSession(sessionId: string): Promise<void>;
10
- persistSessionData(sessionId: string, sessionData: SessionData): Promise<void>;
11
- }
12
- //# sourceMappingURL=CloudflareD1Store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CloudflareD1Store.d.ts","sourceRoot":"","sources":["../../../../src/src/store/cloudflare/CloudflareD1Store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,aAAa,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,qBAAa,iBAAkB,YAAW,KAAK;IAC7C,EAAE,EAAE,GAAG,CAAA;IACP,SAAS,EAAE,MAAM,CAAA;gBAEL,SAAS,GAAE,MAAmB;IAIpC,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAC,SAAS;IAY3C,aAAa,CAAC,SAAS,EAAE,MAAM,EAAC,WAAW,EAAE,WAAW;IAIxD,aAAa,CAAC,SAAS,EAAE,MAAM;IAI/B,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW;CAGrE"}
@@ -1,37 +0,0 @@
1
- export class CloudflareD1Store {
2
- constructor(tableName = 'sessions') {
3
- Object.defineProperty(this, "db", {
4
- enumerable: true,
5
- configurable: true,
6
- writable: true,
7
- value: void 0
8
- });
9
- Object.defineProperty(this, "tableName", {
10
- enumerable: true,
11
- configurable: true,
12
- writable: true,
13
- value: void 0
14
- });
15
- this.tableName = tableName;
16
- }
17
- async getSessionById(sessionId) {
18
- const session = await this.db.prepare(`SELECT data FROM ${this.tableName} WHERE id = ?`)
19
- .bind(sessionId)
20
- .first('data');
21
- if (session) {
22
- return JSON.parse(session);
23
- }
24
- else {
25
- return null;
26
- }
27
- }
28
- async createSession(sessionId, initialData) {
29
- await this.db.prepare(`INSERT INTO ${this.tableName} (id, data) VALUES (?, ?)`).bind(sessionId, JSON.stringify(initialData)).run();
30
- }
31
- async deleteSession(sessionId) {
32
- await this.db.prepare(`DELETE FROM ${this.tableName} WHERE id = ?`).bind(sessionId).run();
33
- }
34
- async persistSessionData(sessionId, sessionData) {
35
- await this.db.prepare(`UPDATE ${this.tableName} SET data = ? WHERE id = ?`).bind(JSON.stringify(sessionData), sessionId).run();
36
- }
37
- }
@@ -1,12 +0,0 @@
1
- import Store from '../Store.js';
2
- import { SessionData } from '../../Session.js';
3
- export declare class CloudflareD1Store implements Store {
4
- db: any;
5
- tableName: string;
6
- constructor(tableName?: string);
7
- getSessionById(sessionId?: string | undefined): Promise<any>;
8
- createSession(sessionId: string, initialData: SessionData): Promise<void>;
9
- deleteSession(sessionId: string): Promise<void>;
10
- persistSessionData(sessionId: string, sessionData: SessionData): Promise<void>;
11
- }
12
- //# sourceMappingURL=CloudflareD1Store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CloudflareD1Store.d.ts","sourceRoot":"","sources":["../../../../src/src/store/cloudflare/CloudflareD1Store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,aAAa,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,qBAAa,iBAAkB,YAAW,KAAK;IAC7C,EAAE,EAAE,GAAG,CAAA;IACP,SAAS,EAAE,MAAM,CAAA;gBAEL,SAAS,GAAE,MAAmB;IAIpC,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAC,SAAS;IAY3C,aAAa,CAAC,SAAS,EAAE,MAAM,EAAC,WAAW,EAAE,WAAW;IAIxD,aAAa,CAAC,SAAS,EAAE,MAAM;IAI/B,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW;CAGrE"}
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CloudflareD1Store = void 0;
4
- class CloudflareD1Store {
5
- constructor(tableName = 'sessions') {
6
- Object.defineProperty(this, "db", {
7
- enumerable: true,
8
- configurable: true,
9
- writable: true,
10
- value: void 0
11
- });
12
- Object.defineProperty(this, "tableName", {
13
- enumerable: true,
14
- configurable: true,
15
- writable: true,
16
- value: void 0
17
- });
18
- this.tableName = tableName;
19
- }
20
- async getSessionById(sessionId) {
21
- const session = await this.db.prepare(`SELECT data FROM ${this.tableName} WHERE id = ?`)
22
- .bind(sessionId)
23
- .first('data');
24
- if (session) {
25
- return JSON.parse(session);
26
- }
27
- else {
28
- return null;
29
- }
30
- }
31
- async createSession(sessionId, initialData) {
32
- await this.db.prepare(`INSERT INTO ${this.tableName} (id, data) VALUES (?, ?)`).bind(sessionId, JSON.stringify(initialData)).run();
33
- }
34
- async deleteSession(sessionId) {
35
- await this.db.prepare(`DELETE FROM ${this.tableName} WHERE id = ?`).bind(sessionId).run();
36
- }
37
- async persistSessionData(sessionId, sessionData) {
38
- await this.db.prepare(`UPDATE ${this.tableName} SET data = ? WHERE id = ?`).bind(JSON.stringify(sessionData), sessionId).run();
39
- }
40
- }
41
- exports.CloudflareD1Store = CloudflareD1Store;