@shware/http 1.1.11 → 1.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hono/__tests__/authorizer.test.cjs +483 -0
- package/dist/hono/__tests__/authorizer.test.cjs.map +1 -0
- package/dist/hono/__tests__/authorizer.test.d.cts +2 -0
- package/dist/hono/__tests__/authorizer.test.d.ts +2 -0
- package/dist/hono/__tests__/authorizer.test.mjs +481 -0
- package/dist/hono/__tests__/authorizer.test.mjs.map +1 -0
- package/dist/hono/__tests__/csrf.test.cjs +152 -154
- package/dist/hono/__tests__/csrf.test.cjs.map +1 -1
- package/dist/hono/__tests__/csrf.test.mjs +152 -154
- package/dist/hono/__tests__/csrf.test.mjs.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -1
- package/dist/utils/promise.cjs +47 -0
- package/dist/utils/promise.cjs.map +1 -0
- package/dist/utils/promise.d.cts +3 -0
- package/dist/utils/promise.d.ts +3 -0
- package/dist/utils/promise.mjs +22 -0
- package/dist/utils/promise.mjs.map +1 -0
- package/package.json +2 -2
|
@@ -3,160 +3,158 @@ import { Hono } from "hono";
|
|
|
3
3
|
import { csrf } from "../csrf.mjs";
|
|
4
4
|
import { errorHandler } from "../handler.mjs";
|
|
5
5
|
describe("CSRF Protection", () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
expect(res.status).toBe(200);
|
|
159
|
-
});
|
|
6
|
+
let app;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
app = new Hono();
|
|
9
|
+
app.onError(errorHandler);
|
|
10
|
+
});
|
|
11
|
+
it("should allow GET requests without CSRF token", async () => {
|
|
12
|
+
app.use(csrf());
|
|
13
|
+
app.get("/test", (c) => c.text("OK"));
|
|
14
|
+
const res = await app.request("/test");
|
|
15
|
+
expect(res.status).toBe(200);
|
|
16
|
+
expect(await res.text()).toBe("OK");
|
|
17
|
+
});
|
|
18
|
+
it("should allow HEAD requests without CSRF token", async () => {
|
|
19
|
+
app.use(csrf());
|
|
20
|
+
app.all("/test", (c) => c.text("OK"));
|
|
21
|
+
const res = await app.request("/test", { method: "HEAD" });
|
|
22
|
+
expect(res.status).toBe(200);
|
|
23
|
+
});
|
|
24
|
+
it("should allow OPTIONS requests without CSRF token", async () => {
|
|
25
|
+
app.use(csrf());
|
|
26
|
+
app.options("/test", (c) => c.text("OK"));
|
|
27
|
+
const res = await app.request("/test", { method: "OPTIONS" });
|
|
28
|
+
expect(res.status).toBe(200);
|
|
29
|
+
});
|
|
30
|
+
it("should reject POST requests without CSRF token", async () => {
|
|
31
|
+
app.use(csrf());
|
|
32
|
+
app.post("/test", (c) => c.text("OK"));
|
|
33
|
+
const res = await app.request("/test", { method: "POST" });
|
|
34
|
+
expect(res.status).toBe(403);
|
|
35
|
+
});
|
|
36
|
+
it("should reject POST requests with mismatched tokens", async () => {
|
|
37
|
+
app.use(csrf());
|
|
38
|
+
app.post("/test", (c) => c.text("OK"));
|
|
39
|
+
const res = await app.request("/test", {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: { "X-XSRF-TOKEN": "header-token", Cookie: "XSRF-TOKEN=cookie-token" }
|
|
42
|
+
});
|
|
43
|
+
expect(res.status).toBe(403);
|
|
44
|
+
});
|
|
45
|
+
it("should allow POST requests with matching tokens", async () => {
|
|
46
|
+
app.use(csrf());
|
|
47
|
+
app.post("/test", (c) => c.text("OK"));
|
|
48
|
+
const res = await app.request("/test", {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: {
|
|
51
|
+
"X-XSRF-TOKEN": "matching-token",
|
|
52
|
+
Cookie: "XSRF-TOKEN=matching-token"
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
expect(res.status).toBe(200);
|
|
56
|
+
expect(await res.text()).toBe("OK");
|
|
57
|
+
});
|
|
58
|
+
it("should use custom cookie and header names", async () => {
|
|
59
|
+
app.use(csrf({ cookieName: "csrf-token", headerName: "X-CSRF-Token" }));
|
|
60
|
+
app.post("/test", (c) => c.text("OK"));
|
|
61
|
+
const res = await app.request("/test", {
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: {
|
|
64
|
+
"X-CSRF-Token": "test-token",
|
|
65
|
+
Cookie: "csrf-token=test-token"
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
expect(res.status).toBe(200);
|
|
69
|
+
});
|
|
70
|
+
it("should ignore specified paths", async () => {
|
|
71
|
+
app.use(csrf({ ignores: [{ path: "/webhook/*", methods: ["POST"] }] }));
|
|
72
|
+
app.post("/webhook/stripe", (c) => c.text("OK"));
|
|
73
|
+
app.post("/api/data", (c) => c.text("OK"));
|
|
74
|
+
const webhookRes = await app.request("/webhook/stripe", { method: "POST" });
|
|
75
|
+
expect(webhookRes.status).toBe(200);
|
|
76
|
+
const apiRes = await app.request("/api/data", { method: "POST" });
|
|
77
|
+
expect(apiRes.status).toBe(403);
|
|
78
|
+
});
|
|
79
|
+
it("should ignore all methods for a path when methods not specified", async () => {
|
|
80
|
+
app.use(csrf({ ignores: [{ path: "/auth/apple/callback" }] }));
|
|
81
|
+
app.post("/auth/apple/callback", (c) => c.text("OK"));
|
|
82
|
+
app.put("/auth/apple/callback", (c) => c.text("OK"));
|
|
83
|
+
const postRes = await app.request("/auth/apple/callback", { method: "POST" });
|
|
84
|
+
expect(postRes.status).toBe(200);
|
|
85
|
+
const putRes = await app.request("/auth/apple/callback", { method: "PUT" });
|
|
86
|
+
expect(putRes.status).toBe(200);
|
|
87
|
+
});
|
|
88
|
+
it("should handle empty tokens safely", async () => {
|
|
89
|
+
app.use(csrf());
|
|
90
|
+
app.post("/test", (c) => c.text("OK"));
|
|
91
|
+
const res = await app.request("/test", {
|
|
92
|
+
method: "POST",
|
|
93
|
+
headers: { "X-XSRF-TOKEN": "", Cookie: "XSRF-TOKEN=" }
|
|
94
|
+
});
|
|
95
|
+
expect(res.status).toBe(403);
|
|
96
|
+
});
|
|
97
|
+
it("should handle missing cookie", async () => {
|
|
98
|
+
app.use(csrf());
|
|
99
|
+
app.post("/test", (c) => c.text("OK"));
|
|
100
|
+
const res = await app.request("/test", {
|
|
101
|
+
method: "POST",
|
|
102
|
+
headers: { "X-XSRF-TOKEN": "token" }
|
|
103
|
+
});
|
|
104
|
+
expect(res.status).toBe(403);
|
|
105
|
+
});
|
|
106
|
+
it("should handle missing header", async () => {
|
|
107
|
+
app.use(csrf());
|
|
108
|
+
app.post("/test", (c) => c.text("OK"));
|
|
109
|
+
const res = await app.request("/test", {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: { Cookie: "XSRF-TOKEN=token" }
|
|
112
|
+
});
|
|
113
|
+
expect(res.status).toBe(403);
|
|
114
|
+
});
|
|
115
|
+
it("should use custom error message", async () => {
|
|
116
|
+
app.use(csrf({ errorMessage: "Custom CSRF error" }));
|
|
117
|
+
app.post("/test", (c) => c.text("OK"));
|
|
118
|
+
const res = await app.request("/test", { method: "POST" });
|
|
119
|
+
expect(res.status).toBe(403);
|
|
120
|
+
const body = await res.json();
|
|
121
|
+
expect(body.error.message).toBe("Custom CSRF error");
|
|
122
|
+
});
|
|
123
|
+
it("should work with custom safe methods", async () => {
|
|
124
|
+
app.use(csrf({ safeMethods: ["GET"] }));
|
|
125
|
+
app.all("/test", (c) => c.text("OK"));
|
|
126
|
+
const res = await app.request("/test", { method: "HEAD" });
|
|
127
|
+
expect(res.status).toBe(403);
|
|
128
|
+
});
|
|
129
|
+
it("should handle complex ignore patterns", async () => {
|
|
130
|
+
app.use(
|
|
131
|
+
csrf({
|
|
132
|
+
ignores: [
|
|
133
|
+
{ path: "/api/v1/*", methods: ["GET", "POST"] },
|
|
134
|
+
{ path: "/api/v2/*", methods: ["POST"] },
|
|
135
|
+
{ path: "/public/*" }
|
|
136
|
+
// All methods
|
|
137
|
+
]
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
app.get("/api/v1/users", (c) => c.text("OK"));
|
|
141
|
+
app.post("/api/v1/users", (c) => c.text("OK"));
|
|
142
|
+
app.put("/api/v1/users", (c) => c.text("OK"));
|
|
143
|
+
app.post("/api/v2/users", (c) => c.text("OK"));
|
|
144
|
+
app.get("/api/v2/users", (c) => c.text("OK"));
|
|
145
|
+
app.post("/public/data", (c) => c.text("OK"));
|
|
146
|
+
let res = await app.request("/api/v1/users", { method: "GET" });
|
|
147
|
+
expect(res.status).toBe(200);
|
|
148
|
+
res = await app.request("/api/v1/users", { method: "POST" });
|
|
149
|
+
expect(res.status).toBe(200);
|
|
150
|
+
res = await app.request("/api/v1/users", { method: "PUT" });
|
|
151
|
+
expect(res.status).toBe(403);
|
|
152
|
+
res = await app.request("/api/v2/users", { method: "POST" });
|
|
153
|
+
expect(res.status).toBe(200);
|
|
154
|
+
res = await app.request("/api/v2/users", { method: "GET" });
|
|
155
|
+
expect(res.status).toBe(200);
|
|
156
|
+
res = await app.request("/public/data", { method: "POST" });
|
|
157
|
+
expect(res.status).toBe(200);
|
|
160
158
|
});
|
|
161
159
|
});
|
|
162
160
|
//# sourceMappingURL=csrf.test.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/hono/__tests__/csrf.test.ts"],"sourcesContent":["import { Hono } from 'hono';\nimport { csrf } from '../csrf';\nimport { errorHandler, type Env } from '../handler';\n\ndescribe('CSRF Protection', () => {\n describe('csrfProtection middleware', () => {\n let app: Hono<Env>;\n\n beforeEach(() => {\n app = new Hono();\n app.onError(errorHandler);\n });\n\n it('should allow GET requests without CSRF token', async () => {\n app.use(csrf());\n app.get('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test');\n expect(res.status).toBe(200);\n expect(await res.text()).toBe('OK');\n });\n\n it('should allow HEAD requests without CSRF token', async () => {\n app.use(csrf());\n app.all('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', { method: 'HEAD' });\n expect(res.status).toBe(200);\n });\n\n it('should allow OPTIONS requests without CSRF token', async () => {\n app.use(csrf());\n app.options('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', { method: 'OPTIONS' });\n expect(res.status).toBe(200);\n });\n\n it('should reject POST requests without CSRF token', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', { method: 'POST' });\n expect(res.status).toBe(403);\n });\n\n it('should reject POST requests with mismatched tokens', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: { 'X-XSRF-TOKEN': 'header-token', Cookie: 'XSRF-TOKEN=cookie-token' },\n });\n expect(res.status).toBe(403);\n });\n\n it('should allow POST requests with matching tokens', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: {\n 'X-XSRF-TOKEN': 'matching-token',\n Cookie: 'XSRF-TOKEN=matching-token',\n },\n });\n expect(res.status).toBe(200);\n expect(await res.text()).toBe('OK');\n });\n\n it('should use custom cookie and header names', async () => {\n app.use(csrf({ cookieName: 'csrf-token', headerName: 'X-CSRF-Token' }));\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': 'test-token',\n Cookie: 'csrf-token=test-token',\n },\n });\n expect(res.status).toBe(200);\n });\n\n it('should ignore specified paths', async () => {\n app.use(csrf({ ignores: [{ path: '/webhook/*', methods: ['POST'] }] }));\n app.post('/webhook/stripe', (c) => c.text('OK'));\n app.post('/api/data', (c) => c.text('OK'));\n\n // Ignored path should work without CSRF token\n const webhookRes = await app.request('/webhook/stripe', { method: 'POST' });\n expect(webhookRes.status).toBe(200);\n\n // Non-ignored path should require CSRF token\n const apiRes = await app.request('/api/data', { method: 'POST' });\n expect(apiRes.status).toBe(403);\n });\n\n it('should ignore all methods for a path when methods not specified', async () => {\n app.use(csrf({ ignores: [{ path: '/auth/apple/callback' }] }));\n app.post('/auth/apple/callback', (c) => c.text('OK'));\n app.put('/auth/apple/callback', (c) => c.text('OK'));\n\n const postRes = await app.request('/auth/apple/callback', { method: 'POST' });\n expect(postRes.status).toBe(200);\n\n const putRes = await app.request('/auth/apple/callback', { method: 'PUT' });\n expect(putRes.status).toBe(200);\n });\n\n it('should handle empty tokens safely', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: { 'X-XSRF-TOKEN': '', Cookie: 'XSRF-TOKEN=' },\n });\n expect(res.status).toBe(403);\n });\n\n it('should handle missing cookie', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: { 'X-XSRF-TOKEN': 'token' },\n });\n expect(res.status).toBe(403);\n });\n\n it('should handle missing header', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: { Cookie: 'XSRF-TOKEN=token' },\n });\n expect(res.status).toBe(403);\n });\n\n it('should use custom error message', async () => {\n app.use(csrf({ errorMessage: 'Custom CSRF error' }));\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', { method: 'POST' });\n expect(res.status).toBe(403);\n const body = await res.json();\n expect(body.error.message).toBe('Custom CSRF error');\n });\n\n it('should work with custom safe methods', async () => {\n app.use(csrf({ safeMethods: ['GET'] }));\n app.all('/test', (c) => c.text('OK'));\n\n // HEAD is no longer safe, should require CSRF token\n const res = await app.request('/test', { method: 'HEAD' });\n expect(res.status).toBe(403);\n });\n\n it('should handle complex ignore patterns', async () => {\n app.use(\n csrf({\n ignores: [\n { path: '/api/v1/*', methods: ['GET', 'POST'] },\n { path: '/api/v2/*', methods: ['POST'] },\n { path: '/public/*' }, // All methods\n ],\n })\n );\n\n app.get('/api/v1/users', (c) => c.text('OK'));\n app.post('/api/v1/users', (c) => c.text('OK'));\n app.put('/api/v1/users', (c) => c.text('OK'));\n app.post('/api/v2/users', (c) => c.text('OK'));\n app.get('/api/v2/users', (c) => c.text('OK'));\n app.post('/public/data', (c) => c.text('OK'));\n\n // Ignored GET and POST for /api/v1/*\n let res = await app.request('/api/v1/users', { method: 'GET' });\n expect(res.status).toBe(200);\n\n res = await app.request('/api/v1/users', { method: 'POST' });\n expect(res.status).toBe(200);\n\n // PUT not ignored for /api/v1/*\n res = await app.request('/api/v1/users', { method: 'PUT' });\n expect(res.status).toBe(403);\n\n // Only POST ignored for /api/v2/*\n res = await app.request('/api/v2/users', { method: 'POST' });\n expect(res.status).toBe(200);\n\n // GET not ignored for /api/v2/* (but GET is safe by default)\n res = await app.request('/api/v2/users', { method: 'GET' });\n expect(res.status).toBe(200);\n\n // All methods ignored for /public/*\n res = await app.request('/public/data', { method: 'POST' });\n expect(res.status).toBe(200);\n });\n });\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/hono/__tests__/csrf.test.ts"],"sourcesContent":["import { Hono } from 'hono';\nimport { csrf } from '../csrf';\nimport { errorHandler, type Env } from '../handler';\n\ndescribe('CSRF Protection', () => {\n let app: Hono<Env>;\n\n beforeEach(() => {\n app = new Hono();\n app.onError(errorHandler);\n });\n\n it('should allow GET requests without CSRF token', async () => {\n app.use(csrf());\n app.get('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test');\n expect(res.status).toBe(200);\n expect(await res.text()).toBe('OK');\n });\n\n it('should allow HEAD requests without CSRF token', async () => {\n app.use(csrf());\n app.all('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', { method: 'HEAD' });\n expect(res.status).toBe(200);\n });\n\n it('should allow OPTIONS requests without CSRF token', async () => {\n app.use(csrf());\n app.options('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', { method: 'OPTIONS' });\n expect(res.status).toBe(200);\n });\n\n it('should reject POST requests without CSRF token', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', { method: 'POST' });\n expect(res.status).toBe(403);\n });\n\n it('should reject POST requests with mismatched tokens', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: { 'X-XSRF-TOKEN': 'header-token', Cookie: 'XSRF-TOKEN=cookie-token' },\n });\n expect(res.status).toBe(403);\n });\n\n it('should allow POST requests with matching tokens', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: {\n 'X-XSRF-TOKEN': 'matching-token',\n Cookie: 'XSRF-TOKEN=matching-token',\n },\n });\n expect(res.status).toBe(200);\n expect(await res.text()).toBe('OK');\n });\n\n it('should use custom cookie and header names', async () => {\n app.use(csrf({ cookieName: 'csrf-token', headerName: 'X-CSRF-Token' }));\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': 'test-token',\n Cookie: 'csrf-token=test-token',\n },\n });\n expect(res.status).toBe(200);\n });\n\n it('should ignore specified paths', async () => {\n app.use(csrf({ ignores: [{ path: '/webhook/*', methods: ['POST'] }] }));\n app.post('/webhook/stripe', (c) => c.text('OK'));\n app.post('/api/data', (c) => c.text('OK'));\n\n // Ignored path should work without CSRF token\n const webhookRes = await app.request('/webhook/stripe', { method: 'POST' });\n expect(webhookRes.status).toBe(200);\n\n // Non-ignored path should require CSRF token\n const apiRes = await app.request('/api/data', { method: 'POST' });\n expect(apiRes.status).toBe(403);\n });\n\n it('should ignore all methods for a path when methods not specified', async () => {\n app.use(csrf({ ignores: [{ path: '/auth/apple/callback' }] }));\n app.post('/auth/apple/callback', (c) => c.text('OK'));\n app.put('/auth/apple/callback', (c) => c.text('OK'));\n\n const postRes = await app.request('/auth/apple/callback', { method: 'POST' });\n expect(postRes.status).toBe(200);\n\n const putRes = await app.request('/auth/apple/callback', { method: 'PUT' });\n expect(putRes.status).toBe(200);\n });\n\n it('should handle empty tokens safely', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: { 'X-XSRF-TOKEN': '', Cookie: 'XSRF-TOKEN=' },\n });\n expect(res.status).toBe(403);\n });\n\n it('should handle missing cookie', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: { 'X-XSRF-TOKEN': 'token' },\n });\n expect(res.status).toBe(403);\n });\n\n it('should handle missing header', async () => {\n app.use(csrf());\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', {\n method: 'POST',\n headers: { Cookie: 'XSRF-TOKEN=token' },\n });\n expect(res.status).toBe(403);\n });\n\n it('should use custom error message', async () => {\n app.use(csrf({ errorMessage: 'Custom CSRF error' }));\n app.post('/test', (c) => c.text('OK'));\n\n const res = await app.request('/test', { method: 'POST' });\n expect(res.status).toBe(403);\n const body = await res.json();\n expect(body.error.message).toBe('Custom CSRF error');\n });\n\n it('should work with custom safe methods', async () => {\n app.use(csrf({ safeMethods: ['GET'] }));\n app.all('/test', (c) => c.text('OK'));\n\n // HEAD is no longer safe, should require CSRF token\n const res = await app.request('/test', { method: 'HEAD' });\n expect(res.status).toBe(403);\n });\n\n it('should handle complex ignore patterns', async () => {\n app.use(\n csrf({\n ignores: [\n { path: '/api/v1/*', methods: ['GET', 'POST'] },\n { path: '/api/v2/*', methods: ['POST'] },\n { path: '/public/*' }, // All methods\n ],\n })\n );\n\n app.get('/api/v1/users', (c) => c.text('OK'));\n app.post('/api/v1/users', (c) => c.text('OK'));\n app.put('/api/v1/users', (c) => c.text('OK'));\n app.post('/api/v2/users', (c) => c.text('OK'));\n app.get('/api/v2/users', (c) => c.text('OK'));\n app.post('/public/data', (c) => c.text('OK'));\n\n // Ignored GET and POST for /api/v1/*\n let res = await app.request('/api/v1/users', { method: 'GET' });\n expect(res.status).toBe(200);\n\n res = await app.request('/api/v1/users', { method: 'POST' });\n expect(res.status).toBe(200);\n\n // PUT not ignored for /api/v1/*\n res = await app.request('/api/v1/users', { method: 'PUT' });\n expect(res.status).toBe(403);\n\n // Only POST ignored for /api/v2/*\n res = await app.request('/api/v2/users', { method: 'POST' });\n expect(res.status).toBe(200);\n\n // GET not ignored for /api/v2/* (but GET is safe by default)\n res = await app.request('/api/v2/users', { method: 'GET' });\n expect(res.status).toBe(200);\n\n // All methods ignored for /public/*\n res = await app.request('/public/data', { method: 'POST' });\n expect(res.status).toBe(200);\n });\n});\n"],"mappings":"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","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
hasText: () => import_string.hasText,
|
|
46
46
|
initialPageParam: () => import_response.initialPageParam,
|
|
47
47
|
invariant: () => import_invariant.invariant,
|
|
48
|
+
once: () => import_promise.once,
|
|
48
49
|
pageParamsSchema: () => import_response.pageParamsSchema,
|
|
49
50
|
timing: () => import_timing.timing
|
|
50
51
|
});
|
|
@@ -59,6 +60,7 @@ __reExport(index_exports, require("./snowflake.cjs"), module.exports);
|
|
|
59
60
|
var MAX_LENGTH = __toESM(require("./max-length/index.cjs"), 1);
|
|
60
61
|
var import_string = require("./utils/string.cjs");
|
|
61
62
|
var import_timing = require("./utils/timing.cjs");
|
|
63
|
+
var import_promise = require("./utils/promise.cjs");
|
|
62
64
|
var import_invariant = require("./utils/invariant.cjs");
|
|
63
65
|
var import_token_bucket = require("./utils/token-bucket.cjs");
|
|
64
66
|
var import_iso_3601_1 = require("./iso/iso_3601_1.cjs");
|
|
@@ -78,6 +80,7 @@ var import_iso_3601_1 = require("./iso/iso_3601_1.cjs");
|
|
|
78
80
|
hasText,
|
|
79
81
|
initialPageParam,
|
|
80
82
|
invariant,
|
|
83
|
+
once,
|
|
81
84
|
pageParamsSchema,
|
|
82
85
|
timing,
|
|
83
86
|
...require("./error/detail.cjs"),
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\nexport type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './error/reason';\nexport * from './error/detail';\nexport * from './error/status';\nexport { getErrorMessage } from './error/parse';\nexport {\n pageParamsSchema,\n Cursor,\n initialPageParam,\n getPreviousPageParam,\n getNextPageParam,\n} from './response';\nexport type {\n Empty,\n EntityId,\n Entity,\n Response,\n InitParams,\n NextParams,\n PrevParams,\n PageParams,\n ParentPageParams,\n Page,\n} from './response';\n\nexport * from './vaild';\nexport * from './snowflake';\n\nexport * as MAX_LENGTH from './max-length/index';\nexport { hasText } from './utils/string';\nexport { timing } from './utils/timing';\nexport { invariant } from './utils/invariant';\nexport { TokenBucket, type TokenBucketOptions } from './utils/token-bucket';\n\nexport { ISO_3601_1, type ISO3166CountryCode } from './iso/iso_3601_1';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,mBAKO;AAUP,0BAAc,+BA5Bd;AA6BA,0BAAc,+BA7Bd;AA8BA,mBAAgC;AAChC,sBAMO;AAcP,0BAAc,wBAnDd;AAoDA,0BAAc,4BApDd;AAsDA,iBAA4B;AAC5B,oBAAwB;AACxB,oBAAuB;AACvB,uBAA0B;AAC1B,0BAAqD;AAErD,wBAAoD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\nexport type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './error/reason';\nexport * from './error/detail';\nexport * from './error/status';\nexport { getErrorMessage } from './error/parse';\nexport {\n pageParamsSchema,\n Cursor,\n initialPageParam,\n getPreviousPageParam,\n getNextPageParam,\n} from './response';\nexport type {\n Empty,\n EntityId,\n Entity,\n Response,\n InitParams,\n NextParams,\n PrevParams,\n PageParams,\n ParentPageParams,\n Page,\n} from './response';\n\nexport * from './vaild';\nexport * from './snowflake';\n\nexport * as MAX_LENGTH from './max-length/index';\nexport { hasText } from './utils/string';\nexport { timing } from './utils/timing';\nexport { once } from './utils/promise';\nexport { invariant } from './utils/invariant';\nexport { TokenBucket, type TokenBucketOptions } from './utils/token-bucket';\n\nexport { ISO_3601_1, type ISO3166CountryCode } from './iso/iso_3601_1';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,mBAKO;AAUP,0BAAc,+BA5Bd;AA6BA,0BAAc,+BA7Bd;AA8BA,mBAAgC;AAChC,sBAMO;AAcP,0BAAc,wBAnDd;AAoDA,0BAAc,4BApDd;AAsDA,iBAA4B;AAC5B,oBAAwB;AACxB,oBAAuB;AACvB,qBAAqB;AACrB,uBAA0B;AAC1B,0BAAqD;AAErD,wBAAoD;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -9,6 +9,7 @@ export { UidGenerator, uid } from './snowflake.cjs';
|
|
|
9
9
|
export { i as MAX_LENGTH } from './index-BnPgRQDl.cjs';
|
|
10
10
|
export { hasText } from './utils/string.cjs';
|
|
11
11
|
export { timing } from './utils/timing.cjs';
|
|
12
|
+
export { once } from './utils/promise.cjs';
|
|
12
13
|
export { invariant } from './utils/invariant.cjs';
|
|
13
14
|
export { TokenBucket, TokenBucketOptions } from './utils/token-bucket.cjs';
|
|
14
15
|
export { ISO3166CountryCode, ISO_3601_1 } from './iso/iso_3601_1.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { UidGenerator, uid } from './snowflake.js';
|
|
|
9
9
|
export { i as MAX_LENGTH } from './index-BnPgRQDl.js';
|
|
10
10
|
export { hasText } from './utils/string.js';
|
|
11
11
|
export { timing } from './utils/timing.js';
|
|
12
|
+
export { once } from './utils/promise.js';
|
|
12
13
|
export { invariant } from './utils/invariant.js';
|
|
13
14
|
export { TokenBucket, TokenBucketOptions } from './utils/token-bucket.js';
|
|
14
15
|
export { ISO3166CountryCode, ISO_3601_1 } from './iso/iso_3601_1.js';
|
package/dist/index.mjs
CHANGED
|
@@ -20,6 +20,7 @@ export * from "./snowflake.mjs";
|
|
|
20
20
|
import * as MAX_LENGTH from "./max-length/index.mjs";
|
|
21
21
|
import { hasText } from "./utils/string.mjs";
|
|
22
22
|
import { timing } from "./utils/timing.mjs";
|
|
23
|
+
import { once } from "./utils/promise.mjs";
|
|
23
24
|
import { invariant } from "./utils/invariant.mjs";
|
|
24
25
|
import { TokenBucket } from "./utils/token-bucket.mjs";
|
|
25
26
|
import { ISO_3601_1 } from "./iso/iso_3601_1.mjs";
|
|
@@ -38,6 +39,7 @@ export {
|
|
|
38
39
|
hasText,
|
|
39
40
|
initialPageParam,
|
|
40
41
|
invariant,
|
|
42
|
+
once,
|
|
41
43
|
pageParamsSchema,
|
|
42
44
|
timing
|
|
43
45
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\nexport type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './error/reason';\nexport * from './error/detail';\nexport * from './error/status';\nexport { getErrorMessage } from './error/parse';\nexport {\n pageParamsSchema,\n Cursor,\n initialPageParam,\n getPreviousPageParam,\n getNextPageParam,\n} from './response';\nexport type {\n Empty,\n EntityId,\n Entity,\n Response,\n InitParams,\n NextParams,\n PrevParams,\n PageParams,\n ParentPageParams,\n Page,\n} from './response';\n\nexport * from './vaild';\nexport * from './snowflake';\n\nexport * as MAX_LENGTH from './max-length/index';\nexport { hasText } from './utils/string';\nexport { timing } from './utils/timing';\nexport { invariant } from './utils/invariant';\nexport { TokenBucket, type TokenBucketOptions } from './utils/token-bucket';\n\nexport { ISO_3601_1, type ISO3166CountryCode } from './iso/iso_3601_1';\n"],"mappings":";AAaA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAUP,cAAc;AACd,cAAc;AACd,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAcP,cAAc;AACd,cAAc;AAEd,YAAY,gBAAgB;AAC5B,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,mBAA4C;AAErD,SAAS,kBAA2C;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\nexport type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './error/reason';\nexport * from './error/detail';\nexport * from './error/status';\nexport { getErrorMessage } from './error/parse';\nexport {\n pageParamsSchema,\n Cursor,\n initialPageParam,\n getPreviousPageParam,\n getNextPageParam,\n} from './response';\nexport type {\n Empty,\n EntityId,\n Entity,\n Response,\n InitParams,\n NextParams,\n PrevParams,\n PageParams,\n ParentPageParams,\n Page,\n} from './response';\n\nexport * from './vaild';\nexport * from './snowflake';\n\nexport * as MAX_LENGTH from './max-length/index';\nexport { hasText } from './utils/string';\nexport { timing } from './utils/timing';\nexport { once } from './utils/promise';\nexport { invariant } from './utils/invariant';\nexport { TokenBucket, type TokenBucketOptions } from './utils/token-bucket';\n\nexport { ISO_3601_1, type ISO3166CountryCode } from './iso/iso_3601_1';\n"],"mappings":";AAaA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAUP,cAAc;AACd,cAAc;AACd,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAcP,cAAc;AACd,cAAc;AAEd,YAAY,gBAAgB;AAC5B,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,mBAA4C;AAErD,SAAS,kBAA2C;","names":[]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/utils/promise.ts
|
|
21
|
+
var promise_exports = {};
|
|
22
|
+
__export(promise_exports, {
|
|
23
|
+
once: () => once
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(promise_exports);
|
|
26
|
+
function once(fn) {
|
|
27
|
+
let cache = null;
|
|
28
|
+
let promise = null;
|
|
29
|
+
return async (...args) => {
|
|
30
|
+
if (cache) return cache;
|
|
31
|
+
if (!promise) {
|
|
32
|
+
promise = fn(...args).then((result) => {
|
|
33
|
+
cache = result;
|
|
34
|
+
return result;
|
|
35
|
+
}).catch((error) => {
|
|
36
|
+
promise = null;
|
|
37
|
+
throw error;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return promise;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
44
|
+
0 && (module.exports = {
|
|
45
|
+
once
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=promise.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/promise.ts"],"sourcesContent":["export function once<A extends unknown[], T>(fn: (...args: A) => Promise<T>) {\n let cache: T | null = null;\n let promise: Promise<T> | null = null;\n\n return async (...args: A) => {\n if (cache) return cache;\n if (!promise) {\n promise = fn(...args)\n .then((result) => {\n cache = result;\n return result;\n })\n .catch((error) => {\n promise = null;\n throw error;\n });\n }\n\n return promise;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,SAAS,KAA6B,IAAgC;AAC3E,MAAI,QAAkB;AACtB,MAAI,UAA6B;AAEjC,SAAO,UAAU,SAAY;AAC3B,QAAI,MAAO,QAAO;AAClB,QAAI,CAAC,SAAS;AACZ,gBAAU,GAAG,GAAG,IAAI,EACjB,KAAK,CAAC,WAAW;AAChB,gBAAQ;AACR,eAAO;AAAA,MACT,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,kBAAU;AACV,cAAM;AAAA,MACR,CAAC;AAAA,IACL;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/utils/promise.ts
|
|
2
|
+
function once(fn) {
|
|
3
|
+
let cache = null;
|
|
4
|
+
let promise = null;
|
|
5
|
+
return async (...args) => {
|
|
6
|
+
if (cache) return cache;
|
|
7
|
+
if (!promise) {
|
|
8
|
+
promise = fn(...args).then((result) => {
|
|
9
|
+
cache = result;
|
|
10
|
+
return result;
|
|
11
|
+
}).catch((error) => {
|
|
12
|
+
promise = null;
|
|
13
|
+
throw error;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return promise;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
once
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=promise.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/promise.ts"],"sourcesContent":["export function once<A extends unknown[], T>(fn: (...args: A) => Promise<T>) {\n let cache: T | null = null;\n let promise: Promise<T> | null = null;\n\n return async (...args: A) => {\n if (cache) return cache;\n if (!promise) {\n promise = fn(...args)\n .then((result) => {\n cache = result;\n return result;\n })\n .catch((error) => {\n promise = null;\n throw error;\n });\n }\n\n return promise;\n };\n}\n"],"mappings":";AAAO,SAAS,KAA6B,IAAgC;AAC3E,MAAI,QAAkB;AACtB,MAAI,UAA6B;AAEjC,SAAO,UAAU,SAAY;AAC3B,QAAI,MAAO,QAAO;AAClB,QAAI,CAAC,SAAS;AACZ,gBAAU,GAAG,GAAG,IAAI,EACjB,KAAK,CAAC,WAAW;AAChB,gBAAQ;AACR,eAAO;AAAA,MACT,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,kBAAU;AACV,cAAM;AAAA,MACR,CAAC;AAAA,IACL;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shware/http",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"jest": "^30.1.3",
|
|
45
45
|
"ts-jest": "^29.4.1",
|
|
46
46
|
"typescript": "^5.9.2",
|
|
47
|
-
"@repo/eslint-config": "0.0.
|
|
47
|
+
"@repo/eslint-config": "0.0.3",
|
|
48
48
|
"@repo/typescript-config": "0.0.0"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|