@haruhimemoe/next-kit 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.
Files changed (78) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/README.md +210 -0
  4. package/dist/auth/create.d.ts +204 -0
  5. package/dist/auth/create.js +102 -0
  6. package/dist/auth/index.d.ts +13 -0
  7. package/dist/auth/index.js +13 -0
  8. package/dist/auth/indexes.d.ts +23 -0
  9. package/dist/auth/indexes.js +44 -0
  10. package/dist/auth/osu-id.d.ts +10 -0
  11. package/dist/auth/osu-id.js +10 -0
  12. package/dist/auth/osu.d.ts +80 -0
  13. package/dist/auth/osu.js +67 -0
  14. package/dist/auth/session.d.ts +48 -0
  15. package/dist/auth/session.js +32 -0
  16. package/dist/auth-react/RestoreSignedIn.d.ts +33 -0
  17. package/dist/auth-react/RestoreSignedIn.js +38 -0
  18. package/dist/auth-react/account-store.d.ts +55 -0
  19. package/dist/auth-react/account-store.js +78 -0
  20. package/dist/auth-react/index.d.ts +17 -0
  21. package/dist/auth-react/index.js +17 -0
  22. package/dist/auth-react/marker.d.ts +35 -0
  23. package/dist/auth-react/marker.js +30 -0
  24. package/dist/auth-react/sign-in.d.ts +24 -0
  25. package/dist/auth-react/sign-in.js +24 -0
  26. package/dist/auth-react/use-account.d.ts +52 -0
  27. package/dist/auth-react/use-account.js +52 -0
  28. package/dist/env/errors.d.ts +18 -0
  29. package/dist/env/errors.js +21 -0
  30. package/dist/env/index.d.ts +13 -0
  31. package/dist/env/index.js +13 -0
  32. package/dist/env/optional.d.ts +54 -0
  33. package/dist/env/optional.js +84 -0
  34. package/dist/env/osu-app.d.ts +24 -0
  35. package/dist/env/osu-app.js +32 -0
  36. package/dist/env/server-env.d.ts +63 -0
  37. package/dist/env/server-env.js +88 -0
  38. package/dist/mongo/client.d.ts +56 -0
  39. package/dist/mongo/client.js +72 -0
  40. package/dist/mongo/collections.d.ts +16 -0
  41. package/dist/mongo/collections.js +29 -0
  42. package/dist/mongo/duplicate.d.ts +16 -0
  43. package/dist/mongo/duplicate.js +16 -0
  44. package/dist/mongo/index.d.ts +13 -0
  45. package/dist/mongo/index.js +13 -0
  46. package/dist/mongo/indexes.d.ts +55 -0
  47. package/dist/mongo/indexes.js +81 -0
  48. package/dist/server/body.d.ts +57 -0
  49. package/dist/server/body.js +74 -0
  50. package/dist/server/budget.d.ts +39 -0
  51. package/dist/server/budget.js +46 -0
  52. package/dist/server/client-ip.d.ts +30 -0
  53. package/dist/server/client-ip.js +92 -0
  54. package/dist/server/counter.d.ts +80 -0
  55. package/dist/server/counter.js +76 -0
  56. package/dist/server/cross-site.d.ts +32 -0
  57. package/dist/server/cross-site.js +36 -0
  58. package/dist/server/errors.d.ts +57 -0
  59. package/dist/server/errors.js +55 -0
  60. package/dist/server/index.d.ts +20 -0
  61. package/dist/server/index.js +20 -0
  62. package/dist/server/machine-auth.d.ts +55 -0
  63. package/dist/server/machine-auth.js +74 -0
  64. package/dist/server/rate-limit.d.ts +75 -0
  65. package/dist/server/rate-limit.js +101 -0
  66. package/dist/server/safe-next.d.ts +36 -0
  67. package/dist/server/safe-next.js +42 -0
  68. package/dist/server/security-txt.d.ts +32 -0
  69. package/dist/server/security-txt.js +31 -0
  70. package/dist/testing/env.d.ts +29 -0
  71. package/dist/testing/env.js +33 -0
  72. package/dist/testing/index.d.ts +13 -0
  73. package/dist/testing/index.js +13 -0
  74. package/dist/testing/mongo.d.ts +44 -0
  75. package/dist/testing/mongo.js +46 -0
  76. package/dist/testing/msw.d.ts +18 -0
  77. package/dist/testing/msw.js +24 -0
  78. package/package.json +140 -0
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @file src/server/safe-next.ts
3
+ * @desc Where to go after sign-in. Only same-site absolute paths pass; anything else (other
4
+ * hosts, protocol-relative, backslashes, control characters, the sign-in page itself)
5
+ * becomes the caller's fallback, a page every signed-in user can open. Browser-safe, so
6
+ * @haruhimemoe/next-kit/auth-react exports it too. Moved from pools (src/utils/safe-next.ts);
7
+ * packs' copy let /signin through.
8
+ * @author David @dvhsh (https://dvh.sh)
9
+ * @created Mon Sep 28, 2026
10
+ * @modified Mon Sep 28, 2026
11
+ */
12
+ /** The sign-in page both sites use. */
13
+ export const DEFAULT_SIGN_IN_PATH = "/signin";
14
+ /** A `next` longer than this is refused unread. */
15
+ export const MAX_NEXT_LENGTH = 512;
16
+ const hasControlCharacter = (value) => [...value].some((char) => char.charCodeAt(0) < 0x20 || char.charCodeAt(0) === 0x7f);
17
+ const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
18
+ /**
19
+ * @function safeNextPath
20
+ * @param raw {string | null | undefined} untrusted ?next= value
21
+ * @param options {SafeNextOptions} the fallback and the sign-in page
22
+ * @returns {string} a same-site path, or the fallback
23
+ */
24
+ export const safeNextPath = (raw, { fallback, signInPath = DEFAULT_SIGN_IN_PATH }) => {
25
+ if (!raw || raw.length > MAX_NEXT_LENGTH)
26
+ return fallback;
27
+ if (!raw.startsWith("/") || raw.startsWith("//"))
28
+ return fallback;
29
+ if (raw.includes("\\") || hasControlCharacter(raw))
30
+ return fallback;
31
+ // The sign-in page with a session goes on to `next`: back to itself would never end.
32
+ if (new RegExp(`^${escapeRegExp(signInPath)}(?:[/?#]|$)`).test(raw))
33
+ return fallback;
34
+ return raw;
35
+ };
36
+ /**
37
+ * @function signInHref
38
+ * @param next {string} where to land after signing in
39
+ * @param signInPath {string} the sign-in page (default DEFAULT_SIGN_IN_PATH)
40
+ * @returns {string} the sign-in link carrying it, like /signin?next=%2Fpacks
41
+ */
42
+ export const signInHref = (next, signInPath = DEFAULT_SIGN_IN_PATH) => `${signInPath}?next=${encodeURIComponent(next)}`;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @file src/server/security-txt.ts
3
+ * @desc /.well-known/security.txt (RFC 9116): where to report a vulnerability, when the file goes
4
+ * stale (a year after it was built, so a deploy rebuilds it), and the policy. Byte-identical
5
+ * in packs and pools (src/utils/security-txt.ts), which read their SITE constants; the
6
+ * caller passes them here.
7
+ * @author David @dvhsh (https://dvh.sh)
8
+ * @created Mon Sep 28, 2026
9
+ * @modified Mon Sep 28, 2026
10
+ */
11
+ /** RFC 9116 asks for an Expires less than a year out. */
12
+ export declare const SECURITY_TXT_LIFETIME_DAYS = 365;
13
+ /** Where the file is served. */
14
+ export declare const SECURITY_TXT_PATH = "/.well-known/security.txt";
15
+ /** buildSecurityTxt's input. */
16
+ export type SecurityTxtOptions = {
17
+ /** Where to report, as an email address (becomes a mailto: Contact). */
18
+ contactEmail: string;
19
+ /** The site's origin, like https://pools.haruhime.moe (no trailing slash). */
20
+ siteUrl: string;
21
+ /** The security policy, like the repo's SECURITY.md. */
22
+ policyUrl: string;
23
+ /** When the file is built (build time for a static route). */
24
+ now: Date;
25
+ };
26
+ /**
27
+ * @function buildSecurityTxt
28
+ * @param options {SecurityTxtOptions} contact, site, policy and build time
29
+ * @returns {string} the security.txt body: Contact, Expires, Preferred-Languages, Canonical,
30
+ * Policy, one field per line, ending in one newline
31
+ */
32
+ export declare const buildSecurityTxt: ({ contactEmail, siteUrl, policyUrl, now, }: SecurityTxtOptions) => string;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @file src/server/security-txt.ts
3
+ * @desc /.well-known/security.txt (RFC 9116): where to report a vulnerability, when the file goes
4
+ * stale (a year after it was built, so a deploy rebuilds it), and the policy. Byte-identical
5
+ * in packs and pools (src/utils/security-txt.ts), which read their SITE constants; the
6
+ * caller passes them here.
7
+ * @author David @dvhsh (https://dvh.sh)
8
+ * @created Mon Sep 28, 2026
9
+ * @modified Mon Sep 28, 2026
10
+ */
11
+ /** RFC 9116 asks for an Expires less than a year out. */
12
+ export const SECURITY_TXT_LIFETIME_DAYS = 365;
13
+ /** Where the file is served. */
14
+ export const SECURITY_TXT_PATH = "/.well-known/security.txt";
15
+ /**
16
+ * @function buildSecurityTxt
17
+ * @param options {SecurityTxtOptions} contact, site, policy and build time
18
+ * @returns {string} the security.txt body: Contact, Expires, Preferred-Languages, Canonical,
19
+ * Policy, one field per line, ending in one newline
20
+ */
21
+ export const buildSecurityTxt = ({ contactEmail, siteUrl, policyUrl, now, }) => {
22
+ const expires = new Date(now.getTime() + SECURITY_TXT_LIFETIME_DAYS * 86_400_000);
23
+ const lines = [
24
+ `Contact: mailto:${contactEmail}`,
25
+ `Expires: ${expires.toISOString()}`,
26
+ "Preferred-Languages: en",
27
+ `Canonical: ${siteUrl}${SECURITY_TXT_PATH}`,
28
+ `Policy: ${policyUrl}`,
29
+ ];
30
+ return `${lines.join("\n")}\n`;
31
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @file src/testing/env.ts
3
+ * @desc Fake env for tests: a complete, valid set of the osu! app's five variables (no real
4
+ * secrets) and stubEnv, which puts values in process.env through Vitest (undo with
5
+ * vi.unstubAllEnvs). Moved from packs and pools (tests/helpers/server-env.ts, identical).
6
+ * @author David @dvhsh (https://dvh.sh)
7
+ * @created Mon Sep 28, 2026
8
+ * @modified Mon Sep 28, 2026
9
+ */
10
+ /** A complete, valid osu! app env. MONGODB_URI equals the placeholder; tests replace it. */
11
+ export declare const TEST_OSU_APP_ENV: Readonly<{
12
+ MONGODB_URI: "mongodb://127.0.0.1:27017";
13
+ BETTER_AUTH_SECRET: "t8Vq2Lm5Xr9Kc1Wz4Hn7Pb3Jd6Fs0Gy2Qe5R";
14
+ BETTER_AUTH_URL: "http://localhost:3000";
15
+ OSU_CLIENT_ID: "1";
16
+ OSU_CLIENT_SECRET: "test-osu-client-secret";
17
+ }>;
18
+ /**
19
+ * @function stubEnv
20
+ * @param values {Record<string, string>} variables to set
21
+ * @returns {void} stubs each into process.env with vi.stubEnv
22
+ */
23
+ export declare const stubEnv: (values: Record<string, string>) => void;
24
+ /**
25
+ * @function stubOsuAppEnv
26
+ * @param overrides {Record<string, string>} values to change or add
27
+ * @returns {void} stubs TEST_OSU_APP_ENV, with the overrides, into process.env
28
+ */
29
+ export declare const stubOsuAppEnv: (overrides?: Record<string, string>) => void;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @file src/testing/env.ts
3
+ * @desc Fake env for tests: a complete, valid set of the osu! app's five variables (no real
4
+ * secrets) and stubEnv, which puts values in process.env through Vitest (undo with
5
+ * vi.unstubAllEnvs). Moved from packs and pools (tests/helpers/server-env.ts, identical).
6
+ * @author David @dvhsh (https://dvh.sh)
7
+ * @created Mon Sep 28, 2026
8
+ * @modified Mon Sep 28, 2026
9
+ */
10
+ import { vi } from "vitest";
11
+ /** A complete, valid osu! app env. MONGODB_URI equals the placeholder; tests replace it. */
12
+ export const TEST_OSU_APP_ENV = Object.freeze({
13
+ MONGODB_URI: "mongodb://127.0.0.1:27017",
14
+ BETTER_AUTH_SECRET: "t8Vq2Lm5Xr9Kc1Wz4Hn7Pb3Jd6Fs0Gy2Qe5R",
15
+ BETTER_AUTH_URL: "http://localhost:3000",
16
+ OSU_CLIENT_ID: "1",
17
+ OSU_CLIENT_SECRET: "test-osu-client-secret",
18
+ });
19
+ /**
20
+ * @function stubEnv
21
+ * @param values {Record<string, string>} variables to set
22
+ * @returns {void} stubs each into process.env with vi.stubEnv
23
+ */
24
+ export const stubEnv = (values) => {
25
+ for (const [key, value] of Object.entries(values))
26
+ vi.stubEnv(key, value);
27
+ };
28
+ /**
29
+ * @function stubOsuAppEnv
30
+ * @param overrides {Record<string, string>} values to change or add
31
+ * @returns {void} stubs TEST_OSU_APP_ENV, with the overrides, into process.env
32
+ */
33
+ export const stubOsuAppEnv = (overrides = {}) => stubEnv({ ...TEST_OSU_APP_ENV, ...overrides });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @file src/testing/index.ts
3
+ * @desc @haruhimemoe/next-kit/testing: Vitest helpers both apps shared. One in-memory MongoDB per
4
+ * run (a globalSetup) and per-file collection clearing, an msw server that refuses unhandled
5
+ * requests, and a fake osu! app env. Needs vitest, and msw or mongodb-memory-server for
6
+ * their helpers. Never import it from app code.
7
+ * @author David @dvhsh (https://dvh.sh)
8
+ * @created Mon Sep 28, 2026
9
+ * @modified Mon Sep 28, 2026
10
+ */
11
+ export { stubEnv, stubOsuAppEnv, TEST_OSU_APP_ENV } from "./env.js";
12
+ export { BETTER_AUTH_COLLECTIONS, setupTestDb, startMemoryMongo, type TestDbOptions, } from "./mongo.js";
13
+ export { setupMsw } from "./msw.js";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @file src/testing/index.ts
3
+ * @desc @haruhimemoe/next-kit/testing: Vitest helpers both apps shared. One in-memory MongoDB per
4
+ * run (a globalSetup) and per-file collection clearing, an msw server that refuses unhandled
5
+ * requests, and a fake osu! app env. Needs vitest, and msw or mongodb-memory-server for
6
+ * their helpers. Never import it from app code.
7
+ * @author David @dvhsh (https://dvh.sh)
8
+ * @created Mon Sep 28, 2026
9
+ * @modified Mon Sep 28, 2026
10
+ */
11
+ export { stubEnv, stubOsuAppEnv, TEST_OSU_APP_ENV } from "./env.js";
12
+ export { BETTER_AUTH_COLLECTIONS, setupTestDb, startMemoryMongo, } from "./mongo.js";
13
+ export { setupMsw } from "./msw.js";
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @file src/testing/mongo.ts
3
+ * @desc Test databases: a Vitest global setup that starts one in-memory MongoDB for the run and
4
+ * hands its URI to test files (inject("mongoUri")), and setupTestDb, which empties the
5
+ * given collections before each test and closes the client after the file. Moved from
6
+ * packs and pools (tests/setup/integration-global.ts, identical, and tests/helpers/db.ts).
7
+ * @author David @dvhsh (https://dvh.sh)
8
+ * @created Mon Sep 28, 2026
9
+ * @modified Mon Sep 28, 2026
10
+ */
11
+ import type { Db } from "mongodb";
12
+ import type { TestProject } from "vitest/node";
13
+ declare module "vitest" {
14
+ interface ProvidedContext {
15
+ /** The in-memory MongoDB's URI, from startMemoryMongo. */
16
+ mongoUri: string;
17
+ }
18
+ }
19
+ /** The collections better-auth's MongoDB adapter creates (with its default names). */
20
+ export declare const BETTER_AUTH_COLLECTIONS: readonly string[];
21
+ /**
22
+ * @function startMemoryMongo
23
+ * @param project {TestProject} the Vitest project (a globalSetup's argument)
24
+ * @returns {Promise<() => Promise<void>>} provides "mongoUri"; the returned teardown stops the
25
+ * server. Use it as a globalSetup's default export.
26
+ */
27
+ export declare const startMemoryMongo: (project: TestProject) => Promise<() => Promise<void>>;
28
+ /** setupTestDb's options: how the app connects, reaches and closes its database. */
29
+ export type TestDbOptions = {
30
+ /** Connects (and runs the app's start-up work, like index builds). */
31
+ connect: () => Promise<unknown>;
32
+ /** The connected database. */
33
+ db: () => Db;
34
+ /** Closes and forgets the client. */
35
+ close: () => Promise<unknown>;
36
+ /** Every collection a test may write to; emptied before each test. */
37
+ collections: readonly string[];
38
+ };
39
+ /**
40
+ * @function setupTestDb
41
+ * @param options {TestDbOptions} connect, db, close and the collections to empty
42
+ * @returns {void} registers beforeEach (connect, then empty) and afterAll (close) hooks
43
+ */
44
+ export declare const setupTestDb: ({ connect, db, close, collections }: TestDbOptions) => void;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @file src/testing/mongo.ts
3
+ * @desc Test databases: a Vitest global setup that starts one in-memory MongoDB for the run and
4
+ * hands its URI to test files (inject("mongoUri")), and setupTestDb, which empties the
5
+ * given collections before each test and closes the client after the file. Moved from
6
+ * packs and pools (tests/setup/integration-global.ts, identical, and tests/helpers/db.ts).
7
+ * @author David @dvhsh (https://dvh.sh)
8
+ * @created Mon Sep 28, 2026
9
+ * @modified Mon Sep 28, 2026
10
+ */
11
+ import { MongoMemoryServer } from "mongodb-memory-server";
12
+ import { afterAll, beforeEach } from "vitest";
13
+ /** The collections better-auth's MongoDB adapter creates (with its default names). */
14
+ export const BETTER_AUTH_COLLECTIONS = Object.freeze([
15
+ "user",
16
+ "session",
17
+ "account",
18
+ "verification",
19
+ ]);
20
+ /**
21
+ * @function startMemoryMongo
22
+ * @param project {TestProject} the Vitest project (a globalSetup's argument)
23
+ * @returns {Promise<() => Promise<void>>} provides "mongoUri"; the returned teardown stops the
24
+ * server. Use it as a globalSetup's default export.
25
+ */
26
+ export const startMemoryMongo = async (project) => {
27
+ const server = await MongoMemoryServer.create();
28
+ project.provide("mongoUri", server.getUri());
29
+ return async () => {
30
+ await server.stop();
31
+ };
32
+ };
33
+ /**
34
+ * @function setupTestDb
35
+ * @param options {TestDbOptions} connect, db, close and the collections to empty
36
+ * @returns {void} registers beforeEach (connect, then empty) and afterAll (close) hooks
37
+ */
38
+ export const setupTestDb = ({ connect, db, close, collections }) => {
39
+ beforeEach(async () => {
40
+ await connect();
41
+ await Promise.all(collections.map((name) => db().collection(name).deleteMany({})));
42
+ });
43
+ afterAll(async () => {
44
+ await close();
45
+ });
46
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @file src/testing/msw.ts
3
+ * @desc setupMsw(...handlers): an msw server for the test file, listening before the tests with
4
+ * every unhandled request an error (so nothing reaches osu!, the mirror or another app),
5
+ * reset after each test, closed after the file. Moved from packs and pools
6
+ * (tests/helpers/msw.ts).
7
+ * @author David @dvhsh (https://dvh.sh)
8
+ * @created Mon Sep 28, 2026
9
+ * @modified Mon Sep 28, 2026
10
+ */
11
+ import type { RequestHandler } from "msw";
12
+ import { type SetupServer } from "msw/node";
13
+ /**
14
+ * @function setupMsw
15
+ * @param handlers {RequestHandler[]} the file's default handlers
16
+ * @returns {SetupServer} the server (use server.use() to add handlers in a test)
17
+ */
18
+ export declare const setupMsw: (...handlers: RequestHandler[]) => SetupServer;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @file src/testing/msw.ts
3
+ * @desc setupMsw(...handlers): an msw server for the test file, listening before the tests with
4
+ * every unhandled request an error (so nothing reaches osu!, the mirror or another app),
5
+ * reset after each test, closed after the file. Moved from packs and pools
6
+ * (tests/helpers/msw.ts).
7
+ * @author David @dvhsh (https://dvh.sh)
8
+ * @created Mon Sep 28, 2026
9
+ * @modified Mon Sep 28, 2026
10
+ */
11
+ import { setupServer } from "msw/node";
12
+ import { afterAll, afterEach, beforeAll } from "vitest";
13
+ /**
14
+ * @function setupMsw
15
+ * @param handlers {RequestHandler[]} the file's default handlers
16
+ * @returns {SetupServer} the server (use server.use() to add handlers in a test)
17
+ */
18
+ export const setupMsw = (...handlers) => {
19
+ const server = setupServer(...handlers);
20
+ beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
21
+ afterEach(() => server.resetHandlers());
22
+ afterAll(() => server.close());
23
+ return server;
24
+ };
package/package.json ADDED
@@ -0,0 +1,140 @@
1
+ {
2
+ "name": "@haruhimemoe/next-kit",
3
+ "version": "0.1.0",
4
+ "description": "The Next.js server plumbing packs.haruhime.moe and pools.haruhime.moe share: JSON route helpers, rate limits and budgets in MongoDB, bearer machine auth, zod env parsing, a connect-once MongoDB client with safe index builds, better-auth with osu! sign-in, and the signed-in marker and account store for the browser.",
5
+ "keywords": [
6
+ "nextjs",
7
+ "next.js",
8
+ "better-auth",
9
+ "osu",
10
+ "osu!",
11
+ "mongodb",
12
+ "rate limit",
13
+ "zod"
14
+ ],
15
+ "homepage": "https://github.com/haruhimemoe/next-kit#readme",
16
+ "bugs": "https://github.com/haruhimemoe/next-kit/issues",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/haruhimemoe/next-kit.git"
20
+ },
21
+ "license": "MIT",
22
+ "author": "David (https://dvh.sh)",
23
+ "type": "module",
24
+ "exports": {
25
+ "./server": {
26
+ "types": "./dist/server/index.d.ts",
27
+ "default": "./dist/server/index.js"
28
+ },
29
+ "./env": {
30
+ "types": "./dist/env/index.d.ts",
31
+ "default": "./dist/env/index.js"
32
+ },
33
+ "./mongo": {
34
+ "types": "./dist/mongo/index.d.ts",
35
+ "default": "./dist/mongo/index.js"
36
+ },
37
+ "./auth": {
38
+ "types": "./dist/auth/index.d.ts",
39
+ "default": "./dist/auth/index.js"
40
+ },
41
+ "./auth-react": {
42
+ "types": "./dist/auth-react/index.d.ts",
43
+ "default": "./dist/auth-react/index.js"
44
+ },
45
+ "./testing": {
46
+ "types": "./dist/testing/index.d.ts",
47
+ "default": "./dist/testing/index.js"
48
+ },
49
+ "./package.json": "./package.json"
50
+ },
51
+ "files": [
52
+ "dist",
53
+ "CHANGELOG.md"
54
+ ],
55
+ "sideEffects": false,
56
+ "engines": {
57
+ "node": ">=22.12"
58
+ },
59
+ "packageManager": "bun@1.4.2",
60
+ "publishConfig": {
61
+ "access": "public",
62
+ "provenance": true
63
+ },
64
+ "scripts": {
65
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
66
+ "build": "bun run clean && tsc -p tsconfig.build.json",
67
+ "check": "biome check .",
68
+ "check:fix": "biome check --write .",
69
+ "typecheck": "tsc --noEmit",
70
+ "test": "vitest run",
71
+ "test:coverage": "vitest run --coverage",
72
+ "test:watch": "vitest",
73
+ "test:dist": "bun run build && node scripts/smoke.mjs",
74
+ "prepublishOnly": "bun run check && bun run typecheck && bun run test && bun run test:dist",
75
+ "check:consumer": "bun run build && node scripts/check-consumer.mjs"
76
+ },
77
+ "peerDependencies": {
78
+ "@haruhimemoe/osu": "^0.2.0 || ^0.3.0",
79
+ "better-auth": "^1.7.5",
80
+ "mongodb": "^7.6.0",
81
+ "mongodb-memory-server": "^11.3.0",
82
+ "mongoose": "^9.10.2",
83
+ "msw": "^2.15.0",
84
+ "next": "^16.3.6",
85
+ "react": "^19.3.0",
86
+ "vitest": "^5.0.1",
87
+ "zod": "^4.6.5"
88
+ },
89
+ "peerDependenciesMeta": {
90
+ "@haruhimemoe/osu": {
91
+ "optional": true
92
+ },
93
+ "better-auth": {
94
+ "optional": true
95
+ },
96
+ "mongodb": {
97
+ "optional": true
98
+ },
99
+ "mongodb-memory-server": {
100
+ "optional": true
101
+ },
102
+ "mongoose": {
103
+ "optional": true
104
+ },
105
+ "msw": {
106
+ "optional": true
107
+ },
108
+ "next": {
109
+ "optional": true
110
+ },
111
+ "react": {
112
+ "optional": true
113
+ },
114
+ "vitest": {
115
+ "optional": true
116
+ }
117
+ },
118
+ "devDependencies": {
119
+ "@biomejs/biome": "2.5.14",
120
+ "@haruhimemoe/osu": "0.2.0",
121
+ "@testing-library/dom": "10.4.2",
122
+ "@testing-library/react": "16.3.3",
123
+ "@types/node": "26.6.2",
124
+ "@types/react": "19.3.0",
125
+ "@types/react-dom": "19.3.0",
126
+ "@vitest/coverage-v8": "5.0.1",
127
+ "better-auth": "1.7.5",
128
+ "jsdom": "30.1.1",
129
+ "mongodb": "7.6.0",
130
+ "mongodb-memory-server": "11.3.0",
131
+ "mongoose": "9.10.2",
132
+ "msw": "2.15.0",
133
+ "next": "16.3.6",
134
+ "react": "19.3.0",
135
+ "react-dom": "19.3.0",
136
+ "typescript": "7.0.2",
137
+ "vitest": "5.0.1",
138
+ "zod": "4.6.5"
139
+ }
140
+ }