bluera-knowledge 0.9.31 → 0.9.34

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 (200) hide show
  1. package/.claude/commands/code-review.md +15 -0
  2. package/.claude/hooks/post-edit-check.sh +5 -3
  3. package/.claude/skills/atomic-commits/SKILL.md +3 -1
  4. package/.claude/skills/code-review-repo/skill.md +62 -0
  5. package/.husky/pre-commit +3 -2
  6. package/.prettierrc +9 -0
  7. package/.versionrc.json +1 -1
  8. package/CHANGELOG.md +35 -0
  9. package/CLAUDE.md +6 -0
  10. package/README.md +25 -13
  11. package/bun.lock +277 -33
  12. package/dist/{chunk-L2YVNC63.js → chunk-6FHWC36B.js} +9 -1
  13. package/dist/chunk-6FHWC36B.js.map +1 -0
  14. package/dist/{chunk-2SJHNRXD.js → chunk-DC7CGSGT.js} +288 -241
  15. package/dist/chunk-DC7CGSGT.js.map +1 -0
  16. package/dist/{chunk-RWSXP3PQ.js → chunk-WFNPNAAP.js} +3194 -3024
  17. package/dist/chunk-WFNPNAAP.js.map +1 -0
  18. package/dist/{chunk-OGEY66FZ.js → chunk-Z2KKVH45.js} +548 -482
  19. package/dist/chunk-Z2KKVH45.js.map +1 -0
  20. package/dist/index.js +871 -754
  21. package/dist/index.js.map +1 -1
  22. package/dist/mcp/server.js +3 -3
  23. package/dist/watch.service-BJV3TI3F.js +7 -0
  24. package/dist/workers/background-worker-cli.js +46 -45
  25. package/dist/workers/background-worker-cli.js.map +1 -1
  26. package/eslint.config.js +43 -1
  27. package/package.json +18 -11
  28. package/plugin.json +8 -0
  29. package/python/requirements.txt +1 -1
  30. package/src/analysis/ast-parser.test.ts +12 -11
  31. package/src/analysis/ast-parser.ts +28 -22
  32. package/src/analysis/code-graph.test.ts +52 -62
  33. package/src/analysis/code-graph.ts +9 -13
  34. package/src/analysis/dependency-usage-analyzer.test.ts +91 -271
  35. package/src/analysis/dependency-usage-analyzer.ts +52 -24
  36. package/src/analysis/go-ast-parser.test.ts +22 -22
  37. package/src/analysis/go-ast-parser.ts +18 -25
  38. package/src/analysis/parser-factory.test.ts +9 -9
  39. package/src/analysis/parser-factory.ts +3 -3
  40. package/src/analysis/python-ast-parser.test.ts +27 -27
  41. package/src/analysis/python-ast-parser.ts +2 -2
  42. package/src/analysis/repo-url-resolver.test.ts +82 -82
  43. package/src/analysis/rust-ast-parser.test.ts +19 -19
  44. package/src/analysis/rust-ast-parser.ts +17 -27
  45. package/src/analysis/tree-sitter-parser.test.ts +3 -3
  46. package/src/analysis/tree-sitter-parser.ts +10 -16
  47. package/src/cli/commands/crawl.test.ts +40 -24
  48. package/src/cli/commands/crawl.ts +186 -161
  49. package/src/cli/commands/index-cmd.test.ts +90 -90
  50. package/src/cli/commands/index-cmd.ts +52 -36
  51. package/src/cli/commands/mcp.test.ts +6 -6
  52. package/src/cli/commands/mcp.ts +2 -2
  53. package/src/cli/commands/plugin-api.test.ts +16 -18
  54. package/src/cli/commands/plugin-api.ts +9 -6
  55. package/src/cli/commands/search.test.ts +16 -7
  56. package/src/cli/commands/search.ts +124 -87
  57. package/src/cli/commands/serve.test.ts +67 -25
  58. package/src/cli/commands/serve.ts +18 -3
  59. package/src/cli/commands/setup.test.ts +176 -101
  60. package/src/cli/commands/setup.ts +140 -117
  61. package/src/cli/commands/store.test.ts +82 -53
  62. package/src/cli/commands/store.ts +56 -37
  63. package/src/cli/program.ts +2 -2
  64. package/src/crawl/article-converter.test.ts +4 -1
  65. package/src/crawl/article-converter.ts +46 -31
  66. package/src/crawl/bridge.test.ts +240 -132
  67. package/src/crawl/bridge.ts +87 -30
  68. package/src/crawl/claude-client.test.ts +124 -56
  69. package/src/crawl/claude-client.ts +7 -15
  70. package/src/crawl/intelligent-crawler.test.ts +65 -22
  71. package/src/crawl/intelligent-crawler.ts +86 -53
  72. package/src/crawl/markdown-utils.ts +1 -4
  73. package/src/db/embeddings.ts +4 -6
  74. package/src/db/lance.test.ts +63 -4
  75. package/src/db/lance.ts +31 -12
  76. package/src/index.ts +26 -17
  77. package/src/logging/index.ts +1 -5
  78. package/src/logging/logger.ts +3 -5
  79. package/src/logging/payload.test.ts +1 -1
  80. package/src/logging/payload.ts +3 -5
  81. package/src/mcp/commands/index.ts +2 -2
  82. package/src/mcp/commands/job.commands.ts +12 -18
  83. package/src/mcp/commands/meta.commands.ts +13 -13
  84. package/src/mcp/commands/registry.ts +5 -8
  85. package/src/mcp/commands/store.commands.ts +19 -19
  86. package/src/mcp/handlers/execute.handler.test.ts +10 -10
  87. package/src/mcp/handlers/execute.handler.ts +4 -5
  88. package/src/mcp/handlers/index.ts +10 -14
  89. package/src/mcp/handlers/job.handler.test.ts +10 -10
  90. package/src/mcp/handlers/job.handler.ts +22 -25
  91. package/src/mcp/handlers/search.handler.test.ts +36 -65
  92. package/src/mcp/handlers/search.handler.ts +135 -104
  93. package/src/mcp/handlers/store.handler.test.ts +41 -52
  94. package/src/mcp/handlers/store.handler.ts +108 -88
  95. package/src/mcp/schemas/index.test.ts +73 -68
  96. package/src/mcp/schemas/index.ts +18 -12
  97. package/src/mcp/server.test.ts +1 -1
  98. package/src/mcp/server.ts +59 -46
  99. package/src/plugin/commands.test.ts +230 -95
  100. package/src/plugin/commands.ts +24 -25
  101. package/src/plugin/dependency-analyzer.test.ts +52 -52
  102. package/src/plugin/dependency-analyzer.ts +85 -22
  103. package/src/plugin/git-clone.test.ts +24 -13
  104. package/src/plugin/git-clone.ts +3 -7
  105. package/src/server/app.test.ts +109 -109
  106. package/src/server/app.ts +32 -23
  107. package/src/server/index.test.ts +64 -66
  108. package/src/services/chunking.service.test.ts +32 -32
  109. package/src/services/chunking.service.ts +16 -9
  110. package/src/services/code-graph.service.test.ts +30 -36
  111. package/src/services/code-graph.service.ts +24 -10
  112. package/src/services/code-unit.service.test.ts +55 -11
  113. package/src/services/code-unit.service.ts +85 -11
  114. package/src/services/config.service.test.ts +37 -18
  115. package/src/services/config.service.ts +30 -7
  116. package/src/services/index.service.test.ts +49 -18
  117. package/src/services/index.service.ts +98 -48
  118. package/src/services/index.ts +8 -10
  119. package/src/services/job.service.test.ts +22 -22
  120. package/src/services/job.service.ts +18 -18
  121. package/src/services/project-root.service.test.ts +1 -3
  122. package/src/services/search.service.test.ts +248 -120
  123. package/src/services/search.service.ts +286 -156
  124. package/src/services/services.test.ts +36 -0
  125. package/src/services/snippet.service.test.ts +14 -6
  126. package/src/services/snippet.service.ts +7 -5
  127. package/src/services/store.service.test.ts +68 -29
  128. package/src/services/store.service.ts +41 -12
  129. package/src/services/watch.service.test.ts +34 -14
  130. package/src/services/watch.service.ts +11 -1
  131. package/src/types/brands.test.ts +3 -1
  132. package/src/types/index.ts +2 -13
  133. package/src/types/search.ts +10 -8
  134. package/src/utils/type-guards.test.ts +20 -15
  135. package/src/utils/type-guards.ts +1 -1
  136. package/src/workers/background-worker-cli.ts +2 -2
  137. package/src/workers/background-worker.test.ts +54 -40
  138. package/src/workers/background-worker.ts +76 -60
  139. package/src/workers/spawn-worker.test.ts +22 -10
  140. package/src/workers/spawn-worker.ts +6 -6
  141. package/tests/analysis/ast-parser.test.ts +3 -3
  142. package/tests/analysis/code-graph.test.ts +5 -5
  143. package/tests/fixtures/code-snippets/api/error-handling.ts +4 -15
  144. package/tests/fixtures/code-snippets/api/rest-controller.ts +3 -9
  145. package/tests/fixtures/code-snippets/auth/jwt-auth.ts +5 -21
  146. package/tests/fixtures/code-snippets/auth/oauth-flow.ts +4 -4
  147. package/tests/fixtures/code-snippets/database/repository-pattern.ts +11 -3
  148. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/aws-lambda/handler.ts +2 -2
  149. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-pages/handler.ts +1 -1
  150. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/serve-static.ts +2 -2
  151. package/tests/fixtures/corpus/oss-repos/hono/src/client/client.ts +2 -2
  152. package/tests/fixtures/corpus/oss-repos/hono/src/client/types.ts +22 -20
  153. package/tests/fixtures/corpus/oss-repos/hono/src/context.ts +13 -10
  154. package/tests/fixtures/corpus/oss-repos/hono/src/helper/accepts/accepts.ts +10 -7
  155. package/tests/fixtures/corpus/oss-repos/hono/src/helper/adapter/index.ts +2 -2
  156. package/tests/fixtures/corpus/oss-repos/hono/src/helper/css/index.ts +1 -1
  157. package/tests/fixtures/corpus/oss-repos/hono/src/helper/factory/index.ts +16 -16
  158. package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/ssg.ts +2 -2
  159. package/tests/fixtures/corpus/oss-repos/hono/src/hono-base.ts +3 -3
  160. package/tests/fixtures/corpus/oss-repos/hono/src/hono.ts +1 -1
  161. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/css.ts +2 -2
  162. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/intrinsic-element/components.ts +1 -1
  163. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/render.ts +7 -7
  164. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/hooks/index.ts +3 -3
  165. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/intrinsic-element/components.ts +1 -1
  166. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/utils.ts +6 -6
  167. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/jsx-renderer/index.ts +3 -3
  168. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/serve-static/index.ts +1 -1
  169. package/tests/fixtures/corpus/oss-repos/hono/src/preset/quick.ts +1 -1
  170. package/tests/fixtures/corpus/oss-repos/hono/src/preset/tiny.ts +1 -1
  171. package/tests/fixtures/corpus/oss-repos/hono/src/router/pattern-router/router.ts +2 -2
  172. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/node.ts +4 -4
  173. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/router.ts +1 -1
  174. package/tests/fixtures/corpus/oss-repos/hono/src/router/trie-router/node.ts +1 -1
  175. package/tests/fixtures/corpus/oss-repos/hono/src/types.ts +166 -169
  176. package/tests/fixtures/corpus/oss-repos/hono/src/utils/body.ts +8 -8
  177. package/tests/fixtures/corpus/oss-repos/hono/src/utils/color.ts +3 -3
  178. package/tests/fixtures/corpus/oss-repos/hono/src/utils/cookie.ts +2 -2
  179. package/tests/fixtures/corpus/oss-repos/hono/src/utils/encode.ts +2 -2
  180. package/tests/fixtures/corpus/oss-repos/hono/src/utils/types.ts +30 -33
  181. package/tests/fixtures/corpus/oss-repos/hono/src/validator/validator.ts +2 -2
  182. package/tests/fixtures/test-server.ts +3 -2
  183. package/tests/helpers/performance-metrics.ts +8 -25
  184. package/tests/helpers/search-relevance.ts +14 -69
  185. package/tests/integration/cli-consistency.test.ts +5 -4
  186. package/tests/integration/e2e-workflow.test.ts +2 -0
  187. package/tests/integration/python-bridge.test.ts +13 -3
  188. package/tests/mcp/server.test.ts +1 -1
  189. package/tests/services/code-unit.service.test.ts +48 -0
  190. package/tests/services/job.service.test.ts +124 -0
  191. package/tests/services/search.progressive-context.test.ts +2 -2
  192. package/.claude-plugin/plugin.json +0 -13
  193. package/BUGS-FOUND.md +0 -71
  194. package/dist/chunk-2SJHNRXD.js.map +0 -1
  195. package/dist/chunk-L2YVNC63.js.map +0 -1
  196. package/dist/chunk-OGEY66FZ.js.map +0 -1
  197. package/dist/chunk-RWSXP3PQ.js.map +0 -1
  198. package/dist/watch.service-YAIKKDCF.js +0 -7
  199. package/skills/atomic-commits/SKILL.md +0 -77
  200. /package/dist/{watch.service-YAIKKDCF.js.map → watch.service-BJV3TI3F.js.map} +0 -0
@@ -3,11 +3,11 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
3
  // Mock child_process before importing spawn-worker
4
4
  const mockUnref = vi.fn();
5
5
  const mockSpawn = vi.fn(() => ({
6
- unref: mockUnref
6
+ unref: mockUnref,
7
7
  }));
8
8
 
9
9
  vi.mock('child_process', () => ({
10
- spawn: mockSpawn
10
+ spawn: mockSpawn,
11
11
  }));
12
12
 
13
13
  // Import after mocking
@@ -50,11 +50,15 @@ describe('spawnBackgroundWorker', () => {
50
50
  spawnBackgroundWorker('test-job', '/test/data/dir');
51
51
 
52
52
  expect(mockSpawn).toHaveBeenCalledTimes(1);
53
- const [, , options] = mockSpawn.mock.calls[0] as [string, string[], { detached: boolean; stdio: string }];
53
+ const [, , options] = mockSpawn.mock.calls[0] as [
54
+ string,
55
+ string[],
56
+ { detached: boolean; stdio: string },
57
+ ];
54
58
 
55
59
  expect(options).toMatchObject({
56
60
  detached: true,
57
- stdio: 'ignore'
61
+ stdio: 'ignore',
58
62
  });
59
63
  });
60
64
 
@@ -63,11 +67,15 @@ describe('spawnBackgroundWorker', () => {
63
67
  spawnBackgroundWorker('test-job', dataDir);
64
68
 
65
69
  expect(mockSpawn).toHaveBeenCalledTimes(1);
66
- const [, , options] = mockSpawn.mock.calls[0] as [string, string[], { env: Record<string, string> }];
70
+ const [, , options] = mockSpawn.mock.calls[0] as [
71
+ string,
72
+ string[],
73
+ { env: Record<string, string> },
74
+ ];
67
75
 
68
76
  expect(options.env).toMatchObject({
69
77
  ...process.env,
70
- BLUERA_DATA_DIR: dataDir
78
+ BLUERA_DATA_DIR: dataDir,
71
79
  });
72
80
  });
73
81
 
@@ -76,7 +84,11 @@ describe('spawnBackgroundWorker', () => {
76
84
  spawnBackgroundWorker('job-456', testDataDir);
77
85
 
78
86
  expect(mockSpawn).toHaveBeenCalledTimes(1);
79
- const [, , options] = mockSpawn.mock.calls[0] as [string, string[], { env: Record<string, string> }];
87
+ const [, , options] = mockSpawn.mock.calls[0] as [
88
+ string,
89
+ string[],
90
+ { env: Record<string, string> },
91
+ ];
80
92
 
81
93
  expect(options.env.BLUERA_DATA_DIR).toBe(testDataDir);
82
94
  });
@@ -86,7 +98,7 @@ describe('spawnBackgroundWorker', () => {
86
98
  describe('spawnBackgroundWorker (production mode)', () => {
87
99
  const mockUnrefProd = vi.fn();
88
100
  const mockSpawnProd = vi.fn(() => ({
89
- unref: mockUnrefProd
101
+ unref: mockUnrefProd,
90
102
  }));
91
103
 
92
104
  beforeEach(() => {
@@ -102,12 +114,12 @@ describe('spawnBackgroundWorker (production mode)', () => {
102
114
  it('should use Node.js directly in production mode (dist folder)', async () => {
103
115
  // Mock child_process
104
116
  vi.doMock('child_process', () => ({
105
- spawn: mockSpawnProd
117
+ spawn: mockSpawnProd,
106
118
  }));
107
119
 
108
120
  // Mock url module to return a path containing /dist/
109
121
  vi.doMock('url', () => ({
110
- fileURLToPath: () => '/app/dist/workers/spawn-worker.js'
122
+ fileURLToPath: () => '/app/dist/workers/spawn-worker.js',
111
123
  }));
112
124
 
113
125
  // Import fresh module with production path
@@ -1,6 +1,6 @@
1
1
  import { spawn } from 'child_process';
2
- import { fileURLToPath } from 'url';
3
2
  import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
4
 
5
5
  /**
6
6
  * Spawn a background worker process to execute a job
@@ -36,12 +36,12 @@ export function spawnBackgroundWorker(jobId: string, dataDir: string): void {
36
36
 
37
37
  // Spawn the worker process
38
38
  const worker = spawn(command, args, {
39
- detached: true, // Detach from parent process
40
- stdio: 'ignore', // Don't pipe stdio (fully independent)
39
+ detached: true, // Detach from parent process
40
+ stdio: 'ignore', // Don't pipe stdio (fully independent)
41
41
  env: {
42
- ...process.env, // Inherit environment variables
43
- BLUERA_DATA_DIR: dataDir // Pass dataDir to worker
44
- }
42
+ ...process.env, // Inherit environment variables
43
+ BLUERA_DATA_DIR: dataDir, // Pass dataDir to worker
44
+ },
45
45
  });
46
46
 
47
47
  // Unref the worker so the parent can exit
@@ -43,7 +43,7 @@ export class UserService {
43
43
  const parser = new ASTParser();
44
44
  const nodes = parser.parse(code, 'typescript');
45
45
 
46
- const classNode = nodes.find(n => n.type === 'class');
46
+ const classNode = nodes.find((n) => n.type === 'class');
47
47
  expect(classNode).toBeDefined();
48
48
  expect(classNode?.name).toBe('UserService');
49
49
  expect(classNode?.methods).toHaveLength(3); // constructor + create + delete
@@ -78,11 +78,11 @@ class Bar {
78
78
  const parser = new ASTParser();
79
79
  const nodes = parser.parse(code, 'typescript');
80
80
 
81
- const fooNode = nodes.find(n => n.name === 'foo');
81
+ const fooNode = nodes.find((n) => n.name === 'foo');
82
82
  expect(fooNode?.startLine).toBe(2);
83
83
  expect(fooNode?.endLine).toBe(4);
84
84
 
85
- const barNode = nodes.find(n => n.name === 'Bar');
85
+ const barNode = nodes.find((n) => n.name === 'Bar');
86
86
  expect(barNode?.startLine).toBe(6);
87
87
  expect(barNode?.endLine).toBe(8);
88
88
  });
@@ -10,15 +10,15 @@ describe('CodeGraph', () => {
10
10
  name: 'validateToken',
11
11
  exported: true,
12
12
  startLine: 1,
13
- endLine: 5
13
+ endLine: 5,
14
14
  },
15
15
  {
16
16
  type: 'function',
17
17
  name: 'parseToken',
18
18
  exported: false,
19
19
  startLine: 7,
20
- endLine: 10
21
- }
20
+ endLine: 10,
21
+ },
22
22
  ];
23
23
 
24
24
  const graph = new CodeGraph();
@@ -52,9 +52,9 @@ export function handler(req) {
52
52
  graph.analyzeCallRelationships(code, 'src/handler.ts', 'handler');
53
53
 
54
54
  const edges = graph.getEdges('src/handler.ts:handler');
55
- const callEdges = edges.filter(e => e.type === 'calls');
55
+ const callEdges = edges.filter((e) => e.type === 'calls');
56
56
 
57
57
  expect(callEdges.length).toBeGreaterThan(0);
58
- expect(callEdges.some(e => e.to.includes('validateToken'))).toBe(true);
58
+ expect(callEdges.some((e) => e.to.includes('validateToken'))).toBe(true);
59
59
  });
60
60
  });
@@ -17,12 +17,7 @@ export class ApiError extends Error {
17
17
  public readonly isOperational: boolean;
18
18
  public readonly timestamp: Date;
19
19
 
20
- constructor(
21
- statusCode: number,
22
- message: string,
23
- code?: string,
24
- isOperational = true
25
- ) {
20
+ constructor(statusCode: number, message: string, code?: string, isOperational = true) {
26
21
  super(message);
27
22
  this.statusCode = statusCode;
28
23
  this.code = code || 'API_ERROR';
@@ -77,9 +72,7 @@ export class NotFoundError extends ApiError {
77
72
  public readonly resource: string;
78
73
 
79
74
  constructor(resource: string, id?: string) {
80
- const message = id
81
- ? `${resource} with ID '${id}' not found`
82
- : `${resource} not found`;
75
+ const message = id ? `${resource} with ID '${id}' not found` : `${resource} not found`;
83
76
  super(404, message, 'NOT_FOUND');
84
77
  this.resource = resource;
85
78
  Object.setPrototypeOf(this, NotFoundError.prototype);
@@ -106,9 +99,7 @@ export class ValidationError extends ApiError {
106
99
  value?: unknown;
107
100
  }>;
108
101
 
109
- constructor(
110
- errors: Array<{ field: string; message: string; value?: unknown }>
111
- ) {
102
+ constructor(errors: Array<{ field: string; message: string; value?: unknown }>) {
112
103
  super(422, 'Validation failed', 'VALIDATION_ERROR');
113
104
  this.errors = errors;
114
105
  Object.setPrototypeOf(this, ValidationError.prototype);
@@ -239,9 +230,7 @@ export const errorHandler: ErrorRequestHandler = (
239
230
 
240
231
  // Handle unknown errors
241
232
  const internalError = new InternalError(
242
- process.env.NODE_ENV === 'production'
243
- ? 'An unexpected error occurred'
244
- : err.message
233
+ process.env.NODE_ENV === 'production' ? 'An unexpected error occurred' : err.message
245
234
  );
246
235
 
247
236
  const response = formatErrorResponse(internalError, req, requestId);
@@ -92,7 +92,7 @@ function validateBody<T>(schema: z.ZodSchema<T>, data: unknown): T {
92
92
  const result = schema.safeParse(data);
93
93
 
94
94
  if (!result.success) {
95
- const errors = result.error.errors.map(err => ({
95
+ const errors = result.error.errors.map((err) => ({
96
96
  field: err.path.join('.'),
97
97
  message: err.message,
98
98
  }));
@@ -132,11 +132,7 @@ export class UserController {
132
132
  asyncHandler(this.createUser.bind(this))
133
133
  );
134
134
 
135
- this.router.put(
136
- '/:id',
137
- authenticateToken,
138
- asyncHandler(this.updateUser.bind(this))
139
- );
135
+ this.router.put('/:id', authenticateToken, asyncHandler(this.updateUser.bind(this)));
140
136
 
141
137
  this.router.delete(
142
138
  '/:id',
@@ -217,9 +213,7 @@ export class UserController {
217
213
  const data = validateBody(createUserSchema, req.body);
218
214
 
219
215
  // Check for existing user
220
- const existingUser = Array.from(users.values()).find(
221
- u => u.email === data.email
222
- );
216
+ const existingUser = Array.from(users.values()).find((u) => u.email === data.email);
223
217
 
224
218
  if (existingUser) {
225
219
  throw new BadRequestError('User with this email already exists', {
@@ -51,11 +51,7 @@ declare global {
51
51
  * @param user - User object containing id, email, and roles
52
52
  * @returns JWT access token
53
53
  */
54
- export function generateAccessToken(user: {
55
- id: string;
56
- email: string;
57
- roles: string[];
58
- }): string {
54
+ export function generateAccessToken(user: { id: string; email: string; roles: string[] }): string {
59
55
  const payload: JwtPayload = {
60
56
  userId: user.id,
61
57
  email: user.email,
@@ -76,11 +72,7 @@ export function generateAccessToken(user: {
76
72
  export function generateRefreshToken(userId: string): string {
77
73
  const tokenId = randomBytes(16).toString('hex');
78
74
 
79
- return jwt.sign(
80
- { userId, tokenId },
81
- REFRESH_SECRET,
82
- { expiresIn: REFRESH_TOKEN_EXPIRY }
83
- );
75
+ return jwt.sign({ userId, tokenId }, REFRESH_SECRET, { expiresIn: REFRESH_TOKEN_EXPIRY });
84
76
  }
85
77
 
86
78
  /**
@@ -88,11 +80,7 @@ export function generateRefreshToken(userId: string): string {
88
80
  * @param user - User object
89
81
  * @returns Token pair with access token, refresh token, and expiry time
90
82
  */
91
- export function generateTokenPair(user: {
92
- id: string;
93
- email: string;
94
- roles: string[];
95
- }): TokenPair {
83
+ export function generateTokenPair(user: { id: string; email: string; roles: string[] }): TokenPair {
96
84
  return {
97
85
  accessToken: generateAccessToken(user),
98
86
  refreshToken: generateRefreshToken(user.id),
@@ -137,11 +125,7 @@ export function verifyRefreshToken(token: string): { userId: string; tokenId: st
137
125
  * Express middleware to authenticate requests using JWT
138
126
  * Extracts the token from the Authorization header (Bearer scheme)
139
127
  */
140
- export function authenticateToken(
141
- req: Request,
142
- res: Response,
143
- next: NextFunction
144
- ): void {
128
+ export function authenticateToken(req: Request, res: Response, next: NextFunction): void {
145
129
  const authHeader = req.headers['authorization'];
146
130
  const token = authHeader && authHeader.split(' ')[1];
147
131
 
@@ -179,7 +163,7 @@ export function requireRoles(...requiredRoles: string[]) {
179
163
  return;
180
164
  }
181
165
 
182
- const hasRole = req.user.roles.some(role => requiredRoles.includes(role));
166
+ const hasRole = req.user.roles.some((role) => requiredRoles.includes(role));
183
167
 
184
168
  if (!hasRole) {
185
169
  res.status(403).json({
@@ -180,7 +180,7 @@ export async function exchangeCodeForTokens(
180
180
  method: 'POST',
181
181
  headers: {
182
182
  'Content-Type': 'application/x-www-form-urlencoded',
183
- 'Accept': 'application/json',
183
+ Accept: 'application/json',
184
184
  },
185
185
  body: body.toString(),
186
186
  });
@@ -202,8 +202,8 @@ export async function fetchUserInfo(
202
202
  ): Promise<Record<string, unknown>> {
203
203
  const response = await fetch(config.userInfoUrl, {
204
204
  headers: {
205
- 'Authorization': `Bearer ${accessToken}`,
206
- 'Accept': 'application/json',
205
+ Authorization: `Bearer ${accessToken}`,
206
+ Accept: 'application/json',
207
207
  },
208
208
  });
209
209
 
@@ -232,7 +232,7 @@ export async function refreshAccessToken(
232
232
  method: 'POST',
233
233
  headers: {
234
234
  'Content-Type': 'application/x-www-form-urlencoded',
235
- 'Accept': 'application/json',
235
+ Accept: 'application/json',
236
236
  },
237
237
  body: body.toString(),
238
238
  });
@@ -45,7 +45,11 @@ export interface IRepository<T extends Entity> {
45
45
  findById(id: string): Promise<T | null>;
46
46
  findOne(options: QueryOptions<T>): Promise<T | null>;
47
47
  findMany(options?: QueryOptions<T>): Promise<T[]>;
48
- findPaginated(page: number, pageSize: number, options?: QueryOptions<T>): Promise<PaginatedResult<T>>;
48
+ findPaginated(
49
+ page: number,
50
+ pageSize: number,
51
+ options?: QueryOptions<T>
52
+ ): Promise<PaginatedResult<T>>;
49
53
  create(data: Omit<T, 'id'>): Promise<T>;
50
54
  update(id: string, data: Partial<T>): Promise<T>;
51
55
  delete(id: string): Promise<void>;
@@ -75,7 +79,7 @@ export abstract class BaseRepository<T extends Entity> implements IRepository<T>
75
79
 
76
80
  // Apply where filters
77
81
  if (options?.where) {
78
- result = result.filter(item => {
82
+ result = result.filter((item) => {
79
83
  return Object.entries(options.where!).every(([key, value]) => {
80
84
  return item[key as keyof T] === value;
81
85
  });
@@ -126,7 +130,11 @@ export abstract class BaseRepository<T extends Entity> implements IRepository<T>
126
130
  options?: QueryOptions<T>
127
131
  ): Promise<PaginatedResult<T>> {
128
132
  const allItems = Array.from(this.items.values());
129
- const filtered = this.applyFilters(allItems, { ...options, limit: undefined, offset: undefined });
133
+ const filtered = this.applyFilters(allItems, {
134
+ ...options,
135
+ limit: undefined,
136
+ offset: undefined,
137
+ });
130
138
  const total = filtered.length;
131
139
 
132
140
  const offset = (page - 1) * pageSize;
@@ -108,7 +108,7 @@ const streamToNodeStream = async (
108
108
  export const streamHandle = <
109
109
  E extends Env = Env,
110
110
  S extends Schema = {},
111
- BasePath extends string = '/'
111
+ BasePath extends string = '/',
112
112
  >(
113
113
  app: Hono<E, S, BasePath>
114
114
  ): Handler => {
@@ -206,7 +206,7 @@ abstract class EventProcessor<E extends LambdaEvent> {
206
206
  const domainName =
207
207
  event.requestContext && 'domainName' in event.requestContext
208
208
  ? event.requestContext.domainName
209
- : event.headers?.['host'] ?? event.multiValueHeaders?.['host']?.[0]
209
+ : (event.headers?.['host'] ?? event.multiValueHeaders?.['host']?.[0])
210
210
  const path = this.getPath(event)
211
211
  const urlPath = `https://${domainName}${path}`
212
212
  const url = queryString ? `${urlPath}?${queryString}` : urlPath
@@ -24,7 +24,7 @@ declare type PagesFunction<
24
24
  Env = unknown,
25
25
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
26
  Params extends string = any,
27
- Data extends Record<string, unknown> = Record<string, unknown>
27
+ Data extends Record<string, unknown> = Record<string, unknown>,
28
28
  > = (context: EventContext<Env, Params, Data>) => Response | Promise<Response>
29
29
 
30
30
  export const handle =
@@ -27,8 +27,8 @@ export const serveStatic = <E extends Env = Env>(
27
27
  namespace: options.namespace
28
28
  ? options.namespace
29
29
  : c.env
30
- ? c.env.__STATIC_CONTENT
31
- : undefined,
30
+ ? c.env.__STATIC_CONTENT
31
+ : undefined,
32
32
  })
33
33
  }
34
34
  return baseServeStatic({
@@ -96,8 +96,8 @@ class ClientRequestImpl {
96
96
  ...(typeof opt?.headers === 'function'
97
97
  ? await opt.headers()
98
98
  : opt?.headers
99
- ? opt.headers
100
- : {}),
99
+ ? opt.headers
100
+ : {}),
101
101
  }
102
102
 
103
103
  if (args?.cookie) {
@@ -54,8 +54,8 @@ type BlankRecordToNever<T> = T extends any
54
54
  ? T extends null
55
55
  ? null
56
56
  : keyof T extends never
57
- ? never
58
- : T
57
+ ? never
58
+ : T
59
59
  : never
60
60
 
61
61
  type ClientResponseOfEndpoint<T extends Endpoint = Endpoint> = T extends {
@@ -69,15 +69,16 @@ type ClientResponseOfEndpoint<T extends Endpoint = Endpoint> = T extends {
69
69
  export interface ClientResponse<
70
70
  T,
71
71
  U extends number = StatusCode,
72
- F extends ResponseFormat = ResponseFormat
73
- > extends globalThis.Response {
72
+ F extends ResponseFormat = ResponseFormat,
73
+ >
74
+ extends globalThis.Response {
74
75
  readonly body: ReadableStream | null
75
76
  readonly bodyUsed: boolean
76
77
  ok: U extends SuccessStatusCode
77
78
  ? true
78
79
  : U extends Exclude<StatusCode, SuccessStatusCode>
79
- ? false
80
- : boolean
80
+ ? false
81
+ : boolean
81
82
  status: U
82
83
  statusText: string
83
84
  headers: Headers
@@ -87,8 +88,8 @@ export interface ClientResponse<
87
88
  json(): F extends 'text'
88
89
  ? Promise<never>
89
90
  : F extends 'json'
90
- ? Promise<BlankRecordToNever<T>>
91
- : Promise<unknown>
91
+ ? Promise<BlankRecordToNever<T>>
92
+ : Promise<unknown>
92
93
  text(): F extends 'text' ? (T extends string ? Promise<T> : Promise<never>) : Promise<string>
93
94
  blob(): Promise<Blob>
94
95
  formData(): Promise<FormData>
@@ -147,25 +148,26 @@ export type InferRequestOptionsType<T> = T extends (
147
148
  type PathToChain<
148
149
  Path extends string,
149
150
  E extends Schema,
150
- Original extends string = Path
151
+ Original extends string = Path,
151
152
  > = Path extends `/${infer P}`
152
153
  ? PathToChain<P, E, Path>
153
154
  : Path extends `${infer P}/${infer R}`
154
- ? { [K in P]: PathToChain<R, E, Original> }
155
- : {
156
- [K in Path extends '' ? 'index' : Path]: ClientRequest<
157
- E extends Record<string, unknown> ? E[Original] : never
158
- >
159
- }
155
+ ? { [K in P]: PathToChain<R, E, Original> }
156
+ : {
157
+ [K in Path extends '' ? 'index' : Path]: ClientRequest<
158
+ E extends Record<string, unknown> ? E[Original] : never
159
+ >
160
+ }
160
161
 
161
162
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
162
- export type Client<T> = T extends Hono<any, infer S, any>
163
- ? S extends Record<infer K, Schema>
164
- ? K extends string
165
- ? PathToChain<K, S>
163
+ export type Client<T> =
164
+ T extends Hono<any, infer S, any>
165
+ ? S extends Record<infer K, Schema>
166
+ ? K extends string
167
+ ? PathToChain<K, S>
168
+ : never
166
169
  : never
167
170
  : never
168
- : never
169
171
 
170
172
  export type Callback = (opts: CallbackOptions) => unknown
171
173
 
@@ -134,8 +134,10 @@ interface TextRespond {
134
134
  status?: U,
135
135
  headers?: HeaderRecord
136
136
  ): Response & TypedResponse<T, U, 'text'>
137
- <T extends string, U extends StatusCode = StatusCode>(text: T, init?: ResponseInit): Response &
138
- TypedResponse<T, U, 'text'>
137
+ <T extends string, U extends StatusCode = StatusCode>(
138
+ text: T,
139
+ init?: ResponseInit
140
+ ): Response & TypedResponse<T, U, 'text'>
139
141
  }
140
142
 
141
143
  /**
@@ -154,7 +156,7 @@ interface TextRespond {
154
156
  interface JSONRespond {
155
157
  <
156
158
  T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue,
157
- U extends StatusCode = StatusCode
159
+ U extends StatusCode = StatusCode,
158
160
  >(
159
161
  object: T,
160
162
  status?: U,
@@ -162,7 +164,7 @@ interface JSONRespond {
162
164
  ): JSONRespondReturn<T, U>
163
165
  <
164
166
  T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue,
165
- U extends StatusCode = StatusCode
167
+ U extends StatusCode = StatusCode,
166
168
  >(
167
169
  object: T,
168
170
  init?: ResponseInit
@@ -177,7 +179,7 @@ interface JSONRespond {
177
179
  */
178
180
  type JSONRespondReturn<
179
181
  T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue,
180
- U extends StatusCode
182
+ U extends StatusCode,
181
183
  > = Response &
182
184
  TypedResponse<
183
185
  SimplifyDeepArray<T> extends JSONValue
@@ -205,9 +207,10 @@ interface HTMLRespond {
205
207
  status?: StatusCode,
206
208
  headers?: HeaderRecord
207
209
  ): T extends string ? Response : Promise<Response>
208
- <T extends string | Promise<string>>(html: T, init?: ResponseInit): T extends string
209
- ? Response
210
- : Promise<Response>
210
+ <T extends string | Promise<string>>(
211
+ html: T,
212
+ init?: ResponseInit
213
+ ): T extends string ? Response : Promise<Response>
211
214
  }
212
215
 
213
216
  /**
@@ -345,7 +348,7 @@ export class Context<
345
348
  E extends Env = any,
346
349
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
347
350
  P extends string = any,
348
- I extends Input = {}
351
+ I extends Input = {},
349
352
  > {
350
353
  #rawRequest: Request
351
354
  #req: HonoRequest<P, I['out']> | undefined
@@ -835,7 +838,7 @@ export class Context<
835
838
  */
836
839
  json: JSONRespond = <
837
840
  T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue,
838
- U extends StatusCode = StatusCode
841
+ U extends StatusCode = StatusCode,
839
842
  >(
840
843
  object: T,
841
844
  arg?: U | ResponseInit,
@@ -34,13 +34,16 @@ export const parseAccept = (acceptHeader: string): Accept[] => {
34
34
  const params = parts.slice(1) // ['q=0.9', 'image/webp']
35
35
  const q = params.find((param) => param.startsWith('q='))
36
36
 
37
- const paramsObject = params.reduce((acc, param) => {
38
- const keyValue = param.split('=')
39
- const key = keyValue[0].trim()
40
- const value = keyValue[1].trim()
41
- acc[key] = value
42
- return acc
43
- }, {} as { [key: string]: string })
37
+ const paramsObject = params.reduce(
38
+ (acc, param) => {
39
+ const keyValue = param.split('=')
40
+ const key = keyValue[0].trim()
41
+ const value = keyValue[1].trim()
42
+ acc[key] = value
43
+ return acc
44
+ },
45
+ {} as { [key: string]: string }
46
+ )
44
47
 
45
48
  return {
46
49
  type: type,
@@ -28,8 +28,8 @@ export const env = <T extends Record<string, unknown>, C extends Context = Conte
28
28
  },
29
29
  workerd: () => c.env,
30
30
  // On Fastly Compute, you can use the ConfigStore to manage user-defined data.
31
- fastly: () => ({} as T),
32
- other: () => ({} as T),
31
+ fastly: () => ({}) as T,
32
+ other: () => ({}) as T,
33
33
  }
34
34
 
35
35
  return runtimeEnvHandlers[runtime]()
@@ -26,7 +26,7 @@ type CssClassName = HtmlEscapedString & CssClassNameCommon
26
26
 
27
27
  type usedClassNameData = [
28
28
  Record<string, string>, // class name to add
29
- Record<string, true> // class name already added
29
+ Record<string, true>, // class name already added
30
30
  ]
31
31
 
32
32
  interface CssType {