glasswork 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 (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +182 -0
  3. package/dist/bootstrap.d.ts +55 -0
  4. package/dist/bootstrap.d.ts.map +1 -0
  5. package/dist/bootstrap.js +359 -0
  6. package/dist/bootstrap.js.map +1 -0
  7. package/dist/core/bootstrap.d.ts +55 -0
  8. package/dist/core/bootstrap.d.ts.map +1 -0
  9. package/dist/core/bootstrap.js +329 -0
  10. package/dist/core/bootstrap.js.map +1 -0
  11. package/dist/core/module.d.ts +21 -0
  12. package/dist/core/module.d.ts.map +1 -0
  13. package/dist/core/module.js +85 -0
  14. package/dist/core/module.js.map +1 -0
  15. package/dist/core/types.d.ts +273 -0
  16. package/dist/core/types.d.ts.map +1 -0
  17. package/dist/core/types.js +2 -0
  18. package/dist/core/types.js.map +1 -0
  19. package/dist/environment.d.ts +21 -0
  20. package/dist/environment.d.ts.map +1 -0
  21. package/dist/environment.js +29 -0
  22. package/dist/environment.js.map +1 -0
  23. package/dist/error-handler.d.ts +33 -0
  24. package/dist/error-handler.d.ts.map +1 -0
  25. package/dist/error-handler.js +53 -0
  26. package/dist/error-handler.js.map +1 -0
  27. package/dist/errors.d.ts +36 -0
  28. package/dist/errors.d.ts.map +1 -0
  29. package/dist/errors.js +65 -0
  30. package/dist/errors.js.map +1 -0
  31. package/dist/get-client-ip.d.ts +24 -0
  32. package/dist/get-client-ip.d.ts.map +1 -0
  33. package/dist/get-client-ip.js +49 -0
  34. package/dist/get-client-ip.js.map +1 -0
  35. package/dist/http/error-handler.d.ts +33 -0
  36. package/dist/http/error-handler.d.ts.map +1 -0
  37. package/dist/http/error-handler.js +55 -0
  38. package/dist/http/error-handler.js.map +1 -0
  39. package/dist/http/errors.d.ts +36 -0
  40. package/dist/http/errors.d.ts.map +1 -0
  41. package/dist/http/errors.js +65 -0
  42. package/dist/http/errors.js.map +1 -0
  43. package/dist/http/route-helpers.d.ts +172 -0
  44. package/dist/http/route-helpers.d.ts.map +1 -0
  45. package/dist/http/route-helpers.js +249 -0
  46. package/dist/http/route-helpers.js.map +1 -0
  47. package/dist/index.d.ts +33 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +29 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/logger.d.ts +37 -0
  52. package/dist/logger.d.ts.map +1 -0
  53. package/dist/logger.js +52 -0
  54. package/dist/logger.js.map +1 -0
  55. package/dist/middleware/rate-limit.d.ts +7 -0
  56. package/dist/middleware/rate-limit.d.ts.map +1 -0
  57. package/dist/middleware/rate-limit.js +182 -0
  58. package/dist/middleware/rate-limit.js.map +1 -0
  59. package/dist/module.d.ts +21 -0
  60. package/dist/module.d.ts.map +1 -0
  61. package/dist/module.js +85 -0
  62. package/dist/module.js.map +1 -0
  63. package/dist/omit.d.ts +20 -0
  64. package/dist/omit.d.ts.map +1 -0
  65. package/dist/omit.js +28 -0
  66. package/dist/omit.js.map +1 -0
  67. package/dist/openapi/defaults.d.ts +11 -0
  68. package/dist/openapi/defaults.d.ts.map +1 -0
  69. package/dist/openapi/defaults.js +127 -0
  70. package/dist/openapi/defaults.js.map +1 -0
  71. package/dist/openapi/hooks.d.ts +14 -0
  72. package/dist/openapi/hooks.d.ts.map +1 -0
  73. package/dist/openapi/hooks.js +80 -0
  74. package/dist/openapi/hooks.js.map +1 -0
  75. package/dist/openapi/openapi.d.ts +24 -0
  76. package/dist/openapi/openapi.d.ts.map +1 -0
  77. package/dist/openapi/openapi.js +108 -0
  78. package/dist/openapi/openapi.js.map +1 -0
  79. package/dist/openapi-defaults.d.ts +11 -0
  80. package/dist/openapi-defaults.d.ts.map +1 -0
  81. package/dist/openapi-defaults.js +127 -0
  82. package/dist/openapi-defaults.js.map +1 -0
  83. package/dist/openapi-hooks.d.ts +14 -0
  84. package/dist/openapi-hooks.d.ts.map +1 -0
  85. package/dist/openapi-hooks.js +80 -0
  86. package/dist/openapi-hooks.js.map +1 -0
  87. package/dist/openapi.d.ts +24 -0
  88. package/dist/openapi.d.ts.map +1 -0
  89. package/dist/openapi.js +106 -0
  90. package/dist/openapi.js.map +1 -0
  91. package/dist/pagination.d.ts +48 -0
  92. package/dist/pagination.d.ts.map +1 -0
  93. package/dist/pagination.js +43 -0
  94. package/dist/pagination.js.map +1 -0
  95. package/dist/pick.d.ts +20 -0
  96. package/dist/pick.d.ts.map +1 -0
  97. package/dist/pick.js +28 -0
  98. package/dist/pick.js.map +1 -0
  99. package/dist/rate-limit.d.ts +7 -0
  100. package/dist/rate-limit.d.ts.map +1 -0
  101. package/dist/rate-limit.js +180 -0
  102. package/dist/rate-limit.js.map +1 -0
  103. package/dist/route-helpers.d.ts +172 -0
  104. package/dist/route-helpers.d.ts.map +1 -0
  105. package/dist/route-helpers.js +249 -0
  106. package/dist/route-helpers.js.map +1 -0
  107. package/dist/serialize-dates.d.ts +27 -0
  108. package/dist/serialize-dates.d.ts.map +1 -0
  109. package/dist/serialize-dates.js +39 -0
  110. package/dist/serialize-dates.js.map +1 -0
  111. package/dist/testing.d.ts +87 -0
  112. package/dist/testing.d.ts.map +1 -0
  113. package/dist/testing.js +94 -0
  114. package/dist/testing.js.map +1 -0
  115. package/dist/types.d.ts +273 -0
  116. package/dist/types.d.ts.map +1 -0
  117. package/dist/types.js +2 -0
  118. package/dist/types.js.map +1 -0
  119. package/dist/utils/deep-merge.d.ts +5 -0
  120. package/dist/utils/deep-merge.d.ts.map +1 -0
  121. package/dist/utils/deep-merge.js +21 -0
  122. package/dist/utils/deep-merge.js.map +1 -0
  123. package/dist/utils/environment.d.ts +21 -0
  124. package/dist/utils/environment.d.ts.map +1 -0
  125. package/dist/utils/environment.js +29 -0
  126. package/dist/utils/environment.js.map +1 -0
  127. package/dist/utils/get-client-ip.d.ts +24 -0
  128. package/dist/utils/get-client-ip.d.ts.map +1 -0
  129. package/dist/utils/get-client-ip.js +49 -0
  130. package/dist/utils/get-client-ip.js.map +1 -0
  131. package/dist/utils/logger.d.ts +37 -0
  132. package/dist/utils/logger.d.ts.map +1 -0
  133. package/dist/utils/logger.js +52 -0
  134. package/dist/utils/logger.js.map +1 -0
  135. package/dist/utils/omit.d.ts +20 -0
  136. package/dist/utils/omit.d.ts.map +1 -0
  137. package/dist/utils/omit.js +28 -0
  138. package/dist/utils/omit.js.map +1 -0
  139. package/dist/utils/pagination.d.ts +48 -0
  140. package/dist/utils/pagination.d.ts.map +1 -0
  141. package/dist/utils/pagination.js +42 -0
  142. package/dist/utils/pagination.js.map +1 -0
  143. package/dist/utils/pick.d.ts +20 -0
  144. package/dist/utils/pick.d.ts.map +1 -0
  145. package/dist/utils/pick.js +28 -0
  146. package/dist/utils/pick.js.map +1 -0
  147. package/dist/utils/serialize-dates.d.ts +27 -0
  148. package/dist/utils/serialize-dates.d.ts.map +1 -0
  149. package/dist/utils/serialize-dates.js +39 -0
  150. package/dist/utils/serialize-dates.js.map +1 -0
  151. package/dist/utils.d.ts +9 -0
  152. package/dist/utils.d.ts.map +1 -0
  153. package/dist/utils.js +31 -0
  154. package/dist/utils.js.map +1 -0
  155. package/package.json +79 -0
@@ -0,0 +1,48 @@
1
+ import type { Context } from 'hono';
2
+ /**
3
+ * Pagination input parameters
4
+ */
5
+ export interface PaginationInput {
6
+ page: number;
7
+ limit: number;
8
+ }
9
+ /**
10
+ * Paginated output structure
11
+ */
12
+ export interface PaginatedOutput<T> {
13
+ data: T[];
14
+ total: number;
15
+ page: number;
16
+ limit: number;
17
+ }
18
+ /**
19
+ * Execute a paginated query and set response headers.
20
+ *
21
+ * This helper extracts pagination parameters from the query string,
22
+ * executes the provided function, and sets the appropriate response headers.
23
+ *
24
+ * @template T - The type of items in the result
25
+ * @param c - Hono context
26
+ * @param fn - Function that executes the paginated query
27
+ * @returns Array of items (headers are set as side effect)
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * router.get('/users', route({
32
+ * paginate: true,
33
+ * handler: async ({ context }) => {
34
+ * return await paginate(context, (p) => userService.getUsers(p));
35
+ * }
36
+ * }));
37
+ * ```
38
+ */
39
+ export declare function paginate<T>(c: Context, fn: (p: PaginationInput) => Promise<PaginatedOutput<T>>): Promise<T[]>;
40
+ /**
41
+ * Extract pagination parameters from Hono context.
42
+ *
43
+ * @param c - Hono context
44
+ * @param defaultLimit - Default limit if not provided (default: 100)
45
+ * @returns Pagination input with page and limit
46
+ */
47
+ export declare function paginationInput(c: Context, defaultLimit?: number): PaginationInput;
48
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,CAAC,EAAE,OAAO,EACV,EAAE,EAAE,CAAC,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GACtD,OAAO,CAAC,CAAC,EAAE,CAAC,CAUd;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,SAAM,GAAG,eAAe,CAI/E"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Execute a paginated query and set response headers.
3
+ *
4
+ * This helper extracts pagination parameters from the query string,
5
+ * executes the provided function, and sets the appropriate response headers.
6
+ *
7
+ * @template T - The type of items in the result
8
+ * @param c - Hono context
9
+ * @param fn - Function that executes the paginated query
10
+ * @returns Array of items (headers are set as side effect)
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * router.get('/users', route({
15
+ * paginate: true,
16
+ * handler: async ({ context }) => {
17
+ * return await paginate(context, (p) => userService.getUsers(p));
18
+ * }
19
+ * }));
20
+ * ```
21
+ */
22
+ export async function paginate(c, fn) {
23
+ const pagination = paginationInput(c);
24
+ const result = await fn(pagination);
25
+ // Set pagination headers
26
+ c.header('X-Total-Count', result.total.toString());
27
+ c.header('X-Page', result.page.toString());
28
+ c.header('X-Limit', result.limit.toString());
29
+ return result.data;
30
+ }
31
+ /**
32
+ * Extract pagination parameters from Hono context.
33
+ *
34
+ * @param c - Hono context
35
+ * @param defaultLimit - Default limit if not provided (default: 100)
36
+ * @returns Pagination input with page and limit
37
+ */
38
+ export function paginationInput(c, defaultLimit = 100) {
39
+ const page = Number.parseInt(c.req.query('page') ?? '1', 10);
40
+ const limit = Number.parseInt(c.req.query('limit') ?? defaultLimit.toString(), 10);
41
+ return { page, limit };
42
+ }
43
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,CAAU,EACV,EAAuD;IAEvD,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC;IAEpC,yBAAyB;IACzB,CAAC,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE7C,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,CAAU,EAAE,YAAY,GAAG,GAAG;IAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IACnF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC"}
package/dist/pick.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Creates a new object by picking specified keys from the source object.
3
+ *
4
+ * This implementation preserves the object's prototype, making it suitable
5
+ * for use with class instances and objects with custom prototypes.
6
+ *
7
+ * @template T - The type of the source object
8
+ * @template K - The type of keys to pick (must be keys of T)
9
+ * @param obj - The source object to pick keys from
10
+ * @param paths - Array of keys to pick from the object
11
+ * @returns A new object containing only the specified keys
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const user = { id: 1, name: 'John', email: 'john@example.com', password: 'secret' };
16
+ * const publicUser = pick(user, ['id', 'name']); // { id: 1, name: 'John' }
17
+ * ```
18
+ */
19
+ export declare function pick<T extends object, K extends keyof T>(obj: T, paths: K[]): Pick<T, K>;
20
+ //# sourceMappingURL=pick.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pick.d.ts","sourceRoot":"","sources":["../src/pick.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAUxF"}
package/dist/pick.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Creates a new object by picking specified keys from the source object.
3
+ *
4
+ * This implementation preserves the object's prototype, making it suitable
5
+ * for use with class instances and objects with custom prototypes.
6
+ *
7
+ * @template T - The type of the source object
8
+ * @template K - The type of keys to pick (must be keys of T)
9
+ * @param obj - The source object to pick keys from
10
+ * @param paths - Array of keys to pick from the object
11
+ * @returns A new object containing only the specified keys
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const user = { id: 1, name: 'John', email: 'john@example.com', password: 'secret' };
16
+ * const publicUser = pick(user, ['id', 'name']); // { id: 1, name: 'John' }
17
+ * ```
18
+ */
19
+ export function pick(obj, paths) {
20
+ const result = Object.create(Object.getPrototypeOf(obj));
21
+ for (const key of paths) {
22
+ if (Object.hasOwn(obj, key)) {
23
+ result[key] = obj[key];
24
+ }
25
+ }
26
+ return result;
27
+ }
28
+ //# sourceMappingURL=pick.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pick.js","sourceRoot":"","sources":["../src/pick.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,IAAI,CAAsC,GAAM,EAAE,KAAU;IAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAe,CAAC;IAEvE,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { MiddlewareHandler } from 'hono';
2
+ import type { RateLimitOptions } from './types.js';
3
+ /**
4
+ * Create rate limiting middleware
5
+ */
6
+ export declare function createRateLimitMiddleware(options: RateLimitOptions): MiddlewareHandler;
7
+ //# sourceMappingURL=rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkKnD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,CAuDtF"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * In-memory rate limiter storage
3
+ */
4
+ class MemoryStore {
5
+ store = new Map();
6
+ async get(key) {
7
+ const item = this.store.get(key);
8
+ if (!item) {
9
+ return null;
10
+ }
11
+ if (item.windowEnd < Date.now()) {
12
+ this.store.delete(key);
13
+ return null;
14
+ }
15
+ return item;
16
+ }
17
+ async set(key, value) {
18
+ this.store.set(key, value);
19
+ }
20
+ async increment(key) {
21
+ const item = this.store.get(key);
22
+ if (item) {
23
+ item.count += 1;
24
+ }
25
+ }
26
+ // Cleanup expired entries periodically
27
+ startCleanup(intervalMs = 60000) {
28
+ setInterval(() => {
29
+ const now = Date.now();
30
+ for (const [key, item] of this.store.entries()) {
31
+ if (item.windowEnd < now) {
32
+ this.store.delete(key);
33
+ }
34
+ }
35
+ }, intervalMs);
36
+ }
37
+ }
38
+ /**
39
+ * DynamoDB rate limiter storage
40
+ */
41
+ class DynamoDBStore {
42
+ client;
43
+ tableName;
44
+ constructor(tableName, region) {
45
+ this.tableName = tableName;
46
+ // Lazy load AWS SDK only when needed
47
+ this.initClient(region);
48
+ }
49
+ async initClient(region) {
50
+ const { DynamoDBClient } = await import('@aws-sdk/client-dynamodb');
51
+ const { DynamoDBDocumentClient } = await import('@aws-sdk/lib-dynamodb');
52
+ const dynamoClient = new DynamoDBClient(region ? { region } : {});
53
+ this.client = DynamoDBDocumentClient.from(dynamoClient);
54
+ }
55
+ async get(key) {
56
+ const { GetCommand } = await import('@aws-sdk/lib-dynamodb');
57
+ const client = this.client;
58
+ try {
59
+ // @ts-expect-error - client type is complex
60
+ const { Item } = await client.send(new GetCommand({
61
+ TableName: this.tableName,
62
+ Key: { bucketId: key },
63
+ }));
64
+ if (!Item || Item.windowEnd < Date.now()) {
65
+ return null;
66
+ }
67
+ return {
68
+ count: Item.count,
69
+ windowEnd: Item.windowEnd,
70
+ };
71
+ }
72
+ catch {
73
+ return null;
74
+ }
75
+ }
76
+ async set(key, value) {
77
+ const { PutCommand } = await import('@aws-sdk/lib-dynamodb');
78
+ const client = this.client;
79
+ const expiresAt = Math.floor(value.windowEnd / 1000);
80
+ try {
81
+ // @ts-expect-error - client type is complex
82
+ await client.send(new PutCommand({
83
+ TableName: this.tableName,
84
+ Item: {
85
+ bucketId: key,
86
+ count: value.count,
87
+ windowEnd: value.windowEnd,
88
+ expiresAt,
89
+ },
90
+ }));
91
+ }
92
+ catch (error) {
93
+ console.error('[Glasswork] DynamoDB rate limit set failed:', error);
94
+ }
95
+ }
96
+ async increment(key) {
97
+ const { UpdateCommand } = await import('@aws-sdk/lib-dynamodb');
98
+ const client = this.client;
99
+ try {
100
+ // @ts-expect-error - client type is complex
101
+ await client.send(new UpdateCommand({
102
+ TableName: this.tableName,
103
+ Key: { bucketId: key },
104
+ UpdateExpression: 'SET #c = #c + :inc',
105
+ ExpressionAttributeNames: { '#c': 'count' },
106
+ ExpressionAttributeValues: { ':inc': 1 },
107
+ }));
108
+ }
109
+ catch (error) {
110
+ console.error('[Glasswork] DynamoDB rate limit increment failed:', error);
111
+ }
112
+ }
113
+ }
114
+ /**
115
+ * Extract client IP from request context
116
+ */
117
+ function getClientIdentifier(context) {
118
+ // Check various headers for client IP
119
+ const forwarded = context.req.header('x-forwarded-for');
120
+ if (forwarded) {
121
+ return forwarded.split(',')[0].trim();
122
+ }
123
+ const realIp = context.req.header('x-real-ip');
124
+ if (realIp) {
125
+ return realIp;
126
+ }
127
+ return 'unknown';
128
+ }
129
+ /**
130
+ * Create rate limiting middleware
131
+ */
132
+ export function createRateLimitMiddleware(options) {
133
+ const { storage, windowMs = 60000, maxRequests = 100, dynamodb } = options;
134
+ // Create appropriate storage backend
135
+ const store = storage === 'dynamodb' && dynamodb
136
+ ? new DynamoDBStore(dynamodb.tableName, dynamodb.region)
137
+ : new MemoryStore();
138
+ // Start cleanup for memory store
139
+ if (store instanceof MemoryStore) {
140
+ store.startCleanup();
141
+ }
142
+ return async (context, next) => {
143
+ const clientId = getClientIdentifier(context);
144
+ const now = Date.now();
145
+ const windowEnd = now + windowMs;
146
+ const setHeaders = (remaining, resetMs) => {
147
+ context.header('RateLimit-Limit', String(maxRequests));
148
+ context.header('RateLimit-Remaining', String(Math.max(0, remaining)));
149
+ context.header('RateLimit-Reset', String(Math.ceil(resetMs / 1000)));
150
+ };
151
+ try {
152
+ const item = await store.get(clientId);
153
+ // New window or expired
154
+ if (!item) {
155
+ await store.set(clientId, { count: 1, windowEnd });
156
+ setHeaders(maxRequests - 1, windowMs);
157
+ await next();
158
+ return;
159
+ }
160
+ // Rate limit exceeded
161
+ if (item.count >= maxRequests) {
162
+ const retryMs = item.windowEnd - now;
163
+ setHeaders(0, retryMs);
164
+ context.header('Retry-After', String(Math.ceil(retryMs / 1000)));
165
+ return context.json({ error: 'Too Many Requests' }, 429);
166
+ }
167
+ // Increment counter
168
+ await store.increment(clientId);
169
+ setHeaders(maxRequests - (item.count + 1), item.windowEnd - now);
170
+ await next();
171
+ }
172
+ catch (error) {
173
+ console.error('[Glasswork] Rate limiter error:', error);
174
+ // Fail open - allow request
175
+ setHeaders(maxRequests, windowMs);
176
+ await next();
177
+ }
178
+ };
179
+ }
180
+ //# sourceMappingURL=rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,172 @@
1
+ import type { Context, Hono, MiddlewareHandler } from 'hono';
2
+ import type { DescribeRouteOptions } from 'hono-openapi';
3
+ import type { BaseIssue, BaseSchema, BaseSchemaAsync, InferOutput } from 'valibot';
4
+ import type { OpenAPIResponseHook } from './types.js';
5
+ /**
6
+ * Set the global OpenAPI response hooks.
7
+ * This is called during bootstrap and makes hooks available to route definitions.
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function setGlobalResponseHooks(hooks: OpenAPIResponseHook[]): void;
12
+ /**
13
+ * Get the current global OpenAPI response hooks.
14
+ *
15
+ * @internal
16
+ */
17
+ export declare function getGlobalResponseHooks(): OpenAPIResponseHook[];
18
+ /**
19
+ * Valibot schema type (compatible with both sync and async schemas)
20
+ */
21
+ export type ValibotSchema = BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>;
22
+ /**
23
+ * Helper type to infer the output type from a Valibot schema
24
+ */
25
+ type InferSchemaType<T> = T extends ValibotSchema ? InferOutput<T> : never;
26
+ /**
27
+ * Helper type to infer the response type from the 200/201 status code schema
28
+ *
29
+ * Prisma client extension converts Date → string at the database layer,
30
+ * so handlers return string-based entities that match the response schema output type.
31
+ */
32
+ type InferResponseType<T> = T extends {
33
+ 200: infer TSchema;
34
+ } ? TSchema extends ValibotSchema ? InferOutput<TSchema> : unknown : T extends {
35
+ 201: infer TSchema;
36
+ } ? TSchema extends ValibotSchema ? InferOutput<TSchema> : unknown : unknown;
37
+ /**
38
+ * HTTP status codes with descriptions
39
+ */
40
+ declare const STATUS_DESCRIPTIONS: {
41
+ readonly 200: "Success";
42
+ readonly 201: "Created";
43
+ readonly 204: "No Content";
44
+ readonly 400: "Bad Request";
45
+ readonly 401: "Unauthorized";
46
+ readonly 403: "Forbidden";
47
+ readonly 404: "Not Found";
48
+ readonly 409: "Conflict";
49
+ readonly 422: "Unprocessable Entity";
50
+ readonly 429: "Too Many Requests";
51
+ readonly 500: "Internal Server Error";
52
+ };
53
+ /**
54
+ * Route factory function type.
55
+ * Receives a real Hono instance and services from DI container.
56
+ */
57
+ export type RouteFactory = (router: Hono, services: Record<string, unknown>) => void;
58
+ /**
59
+ * Create routes with typed service injection.
60
+ *
61
+ * @template TServices - The shape of services required by these routes
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * interface AuthRoutesServices {
66
+ * authService: AuthService;
67
+ * userService: UserService;
68
+ * }
69
+ *
70
+ * export const authRoutes = createRoutes<AuthRoutesServices>((router, services) => {
71
+ * // services.authService is typed as AuthService!
72
+ * // services.userService is typed as UserService!
73
+ * router.post('/login', ...);
74
+ * });
75
+ * ```
76
+ */
77
+ export declare function createRoutes<TServices = Record<string, unknown>>(factory: (router: Hono, services: TServices) => void): RouteFactory;
78
+ /**
79
+ * Route configuration with automatic type inference from Valibot schemas
80
+ *
81
+ * @template TBody - The body schema (automatically inferred)
82
+ * @template TResponses - The responses object (automatically inferred)
83
+ */
84
+ export interface RouteConfig<TBody extends ValibotSchema | undefined = undefined, TResponses extends Partial<Record<keyof typeof STATUS_DESCRIPTIONS, ValibotSchema | undefined>> = Record<never, never>, TPublic extends boolean = false> {
85
+ tags?: string[];
86
+ summary?: string;
87
+ description?: string;
88
+ operationId?: string;
89
+ /**
90
+ * Whether this is a public route (no authentication required)
91
+ * - false (default): Session is required and typed as non-nullable
92
+ * - true: Session is optional and typed as nullable
93
+ */
94
+ public?: TPublic;
95
+ body?: TBody;
96
+ query?: ValibotSchema;
97
+ params?: ValibotSchema;
98
+ responses?: TResponses;
99
+ openapi?: Partial<Omit<DescribeRouteOptions, 'responses' | 'operationId' | 'tags' | 'summary' | 'description'>>;
100
+ /**
101
+ * Custom middleware to apply before validation and handler
102
+ */
103
+ middleware?: MiddlewareHandler[];
104
+ /**
105
+ * Enable pagination - adds pagination query params and response headers to OpenAPI spec
106
+ */
107
+ paginate?: boolean;
108
+ /**
109
+ * Route handler - body and return types are automatically inferred from schemas
110
+ * Session is required by default (unless public: true)
111
+ *
112
+ * Prisma client extension converts Date → string at the database layer,
113
+ * so handler return types match the response schema output type.
114
+ */
115
+ handler: (context: RouteContext<TBody extends ValibotSchema ? InferSchemaType<TBody> : never, TPublic extends true ? false : true>) => Promise<InferResponseType<TResponses>> | InferResponseType<TResponses>;
116
+ }
117
+ /**
118
+ * Route handler context with typed body
119
+ *
120
+ * Leverages Hono's ContextVariableMap for session typing.
121
+ * If your middleware extends ContextVariableMap (e.g., auth middleware),
122
+ * the session will be automatically typed in route handlers.
123
+ *
124
+ * @template TBody - The typed body (inferred from schema)
125
+ * @template TSessionRequired - Whether session is guaranteed to exist (true by default, false for public routes)
126
+ */
127
+ export interface RouteContext<TBody = never, TSessionRequired extends boolean = true> {
128
+ body: TBody;
129
+ query: Record<string, string>;
130
+ params: Record<string, string>;
131
+ services: Record<string, unknown>;
132
+ /**
133
+ * Session from context variables (typed via Hono's ContextVariableMap)
134
+ * - Required by default (for authenticated routes)
135
+ * - Optional only for public routes (public: true)
136
+ */
137
+ session: TSessionRequired extends true ? NonNullable<Context['var']['session']> : Context['var']['session'];
138
+ /**
139
+ * Client IP address (extracted from headers and connection info)
140
+ */
141
+ ip: string;
142
+ /**
143
+ * User agent string from request headers
144
+ */
145
+ userAgent: string | undefined;
146
+ /**
147
+ * Original Hono context (for advanced use cases)
148
+ */
149
+ context: Context;
150
+ }
151
+ /**
152
+ * Create a route handler with validation and OpenAPI metadata.
153
+ *
154
+ * Type inference works automatically:
155
+ * - Body type is inferred from the `body` schema
156
+ * - Return type is inferred from the `responses[200]` schema
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * route({
161
+ * body: StartSessionDto,
162
+ * responses: { 200: StartSessionResponseDto },
163
+ * handler: async ({ body }) => {
164
+ * // body is typed as InferOutput<typeof StartSessionDto>
165
+ * return { email: body.email }; // Must match StartSessionResponseDto
166
+ * }
167
+ * })
168
+ * ```
169
+ */
170
+ export declare function route<TBody extends ValibotSchema | undefined = undefined, TResponses extends Partial<Record<keyof typeof STATUS_DESCRIPTIONS, ValibotSchema | undefined>> = Record<never, never>, TPublic extends boolean = false>(config: RouteConfig<TBody, TResponses, TPublic>): MiddlewareHandler[];
171
+ export {};
172
+ //# sourceMappingURL=route-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../src/route-helpers.ts"],"names":[],"mappings":"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"}