Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow ctx.session to be undefined #2

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
root = true

[*]
indent_size = 4
indent_style = space
insert_final_newline = true
2 changes: 1 addition & 1 deletion deno.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"exports": "./mod.ts",
"lock": false,
"tasks": {
"check": "deno cache --allow-import src/mod.ts",
"check": "deno cache --allow-import mod.ts",
"test": "deno test --allow-import test",
"ok": "deno fmt && deno lint && deno task test && deno task check",
"clean": "git clean -fX out test/cov_profile test/coverage coverage.lcov",
Expand Down
9 changes: 4 additions & 5 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ function strictSingleSession<S, C extends Context>(
);
const key = await getSessionKey(ctx);
await propSession.init(key, { custom, lazy: false });
await next(); // no catch: do not write back if middleware throws
await next(); // no catch: do not write back if middleware
await propSession.finish();
};
}
Expand All @@ -260,7 +260,7 @@ function strictMultiSession<S, C extends Context>(
await s.init(key, { custom, lazy: false });
return s;
}));
await next(); // no catch: do not write back if middleware throws
await next(); // no catch: do not write back if middleware
if (ctx.session === undefined) propSessions.forEach((s) => s.delete());
await Promise.all(propSessions.map((s) => s.finish()));
};
Expand Down Expand Up @@ -379,8 +379,7 @@ class PropertySession<O extends {}, P extends keyof O> {
enumerable: true,
get: () => {
if (key === undefined) {
const msg = undef("access", opts);
throw new Error(msg);
return undefined;
}
this.read = true;
if (!opts.lazy || this.wrote) return this.value;
Expand All @@ -389,7 +388,7 @@ class PropertySession<O extends {}, P extends keyof O> {
},
set: (v) => {
if (key === undefined) {
const msg = undef("assign", opts);
const msg = undef("access", opts);
throw new Error(msg);
}
this.wrote = true;
Expand Down
61 changes: 33 additions & 28 deletions test/mod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,26 @@ describe("session", () => {
assertEquals(middleware.calls[0].args[0], ctx);
});

it("should throw when reading from empty session key", async () => {
it("should return undefined when reading from empty session key", async () => {
type C = Context & SessionFlavor<number>;
let composer = new Composer<C>();
const ctx = {} as C;
composer.use(session(), () => ctx.session);
await assertRejects(async () => {
await composer.middleware()(ctx, next);
let ctx = {} as C;
composer.use(session(), () => {
assertEquals(ctx.session, undefined);
});

await composer.middleware()(ctx, next);

ctx = {} as C;
composer = new Composer<C>();
composer.use(
session({ getSessionKey: () => undefined }),
() => ctx.session,
() => {
assertEquals(ctx.session, undefined);
},
);
await assertRejects(async () => {
await composer.middleware()(ctx, next);
});

await composer.middleware()(ctx, next);
});

it("should throw when writing to empty session key", async () => {
Expand Down Expand Up @@ -268,29 +271,30 @@ describe("multi session", () => {
assertEquals(middleware.calls[0].args[0], ctx);
});

it("should throw when reading from empty session key", async () => {
it("should return undefined when reading from empty session key", async () => {
type C = Context & SessionFlavor<{ prop: number }>;
let composer = new Composer<C>();
const ctx = {} as C;
let ctx = {} as C;
composer.use(
session({ type: "multi", prop: {} }),
() => ctx.session.prop,
() => {
assertEquals(ctx.session.prop, undefined);
},
);
await assertRejects(async () => {
await composer.middleware()(ctx, next);
});

ctx = {} as C;
composer = new Composer<C>();
composer.use(
session({
type: "multi",
prop: { getSessionKey: () => undefined },
}),
() => ctx.session.prop,
() => {
assertEquals(ctx.session.prop, undefined);
},
);
await assertRejects(async () => {
await composer.middleware()(ctx, next);
});

await composer.middleware()(ctx, next);
});

it("should throw when writing to empty session key", async () => {
Expand Down Expand Up @@ -493,23 +497,24 @@ describe("lazy session", () => {
assertEquals(middleware.calls[0].args[0], ctx);
});

it("should throw when reading from empty session key", async () => {
it("should return undefined when reading from empty session key", async () => {
type C = Context & LazySessionFlavor<number>;
let composer = new Composer<C>();
const ctx = {} as C;
composer.use(lazySession(), () => ctx.session);
await assertRejects(async () => {
await composer.middleware()(ctx, next);
let ctx = {} as C;
composer.use(lazySession(), () => {
assertEquals(ctx.session, undefined);
});

ctx = {} as C;
composer = new Composer<C>();
composer.use(
lazySession({ getSessionKey: () => undefined }),
() => ctx.session,
() => {
assertEquals(ctx.session, undefined);
},
);
await assertRejects(async () => {
await composer.middleware()(ctx, next);
});

await composer.middleware()(ctx, next);
});

it("should throw when writing to empty session key", async () => {
Expand Down