@gatwech/core 0.0.10 → 1.0.0-beta.18

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 (130) hide show
  1. package/dist/api/index.d.mts +2 -2
  2. package/dist/context/index.d.mts +2 -2
  3. package/dist/db/adapter/index.d.mts +2 -2
  4. package/dist/db/index.d.mts +2 -2
  5. package/dist/env/index.d.mts +1 -1
  6. package/dist/env/index.mjs +1 -1
  7. package/dist/{env-JMSMESs1.mjs → env-4_Lym7sj.mjs} +7 -7
  8. package/dist/index-65G5U5DB.d.mts +3002 -0
  9. package/dist/{index-DLP-K0uY.d.mts → index-CmdhhvA2.d.mts} +3 -3
  10. package/dist/index.d.mts +3 -3
  11. package/dist/oauth2/index.d.mts +2 -2
  12. package/dist/social-providers/index.d.mts +3 -3
  13. package/dist/social-providers/index.mjs +71 -2412
  14. package/dist/src/api/index.d.ts +119 -0
  15. package/dist/src/async_hooks/index.d.ts +6 -0
  16. package/dist/src/context/endpoint-context.d.ts +14 -0
  17. package/dist/src/context/index.d.ts +3 -0
  18. package/dist/src/context/request-state.d.ts +13 -0
  19. package/dist/src/context/transaction.d.ts +11 -0
  20. package/dist/src/db/adapter/index.d.ts +401 -0
  21. package/{src/db/index.ts → dist/src/db/index.d.ts} +2 -18
  22. package/dist/src/db/plugin.d.ts +10 -0
  23. package/dist/src/db/schema/account.d.ts +22 -0
  24. package/dist/src/db/schema/rate-limit.d.ts +10 -0
  25. package/dist/src/db/schema/session.d.ts +17 -0
  26. package/dist/src/db/schema/shared.d.ts +6 -0
  27. package/dist/src/db/schema/user.d.ts +16 -0
  28. package/{src/db/schema/verification.ts → dist/src/db/schema/verification.d.ts} +8 -8
  29. package/dist/src/db/type.d.ts +159 -0
  30. package/dist/src/env/color-depth.d.ts +1 -0
  31. package/dist/src/env/env-impl.d.ts +29 -0
  32. package/dist/src/env/index.d.ts +3 -0
  33. package/dist/src/env/logger.d.ts +50 -0
  34. package/dist/src/error/codes.d.ts +27 -0
  35. package/dist/src/error/index.d.ts +4 -0
  36. package/dist/src/oauth2/client-credentials-token.d.ts +21 -0
  37. package/dist/src/oauth2/create-authorization-url.d.ts +21 -0
  38. package/dist/src/oauth2/index.d.ts +6 -0
  39. package/dist/src/oauth2/oauth-provider.d.ts +178 -0
  40. package/dist/src/oauth2/refresh-access-token.d.ts +20 -0
  41. package/dist/src/oauth2/utils.d.ts +3 -0
  42. package/dist/src/oauth2/validate-authorization-code.d.ts +28 -0
  43. package/dist/src/social-providers/github.d.ts +89 -0
  44. package/dist/src/social-providers/google.d.ts +82 -0
  45. package/dist/src/social-providers/index.d.ts +93 -0
  46. package/dist/src/types/context.d.ts +177 -0
  47. package/dist/src/types/cookie.d.ts +15 -0
  48. package/dist/src/types/helper.d.ts +9 -0
  49. package/dist/src/types/index.d.ts +7 -0
  50. package/dist/src/types/init-options.d.ts +1140 -0
  51. package/dist/src/types/plugin-client.d.ts +88 -0
  52. package/dist/src/types/plugin.d.ts +120 -0
  53. package/dist/src/utils/error-codes.d.ts +9 -0
  54. package/package.json +11 -5
  55. package/.turbo/turbo-build.log +0 -42
  56. package/dist/index-DjrJweYn.d.mts +0 -7312
  57. package/src/api/index.ts +0 -57
  58. package/src/async_hooks/index.ts +0 -35
  59. package/src/context/endpoint-context.ts +0 -48
  60. package/src/context/index.ts +0 -21
  61. package/src/context/request-state.test.ts +0 -346
  62. package/src/context/request-state.ts +0 -75
  63. package/src/context/transaction.ts +0 -72
  64. package/src/db/adapter/index.ts +0 -466
  65. package/src/db/plugin.ts +0 -11
  66. package/src/db/schema/account.ts +0 -34
  67. package/src/db/schema/rate-limit.ts +0 -21
  68. package/src/db/schema/session.ts +0 -17
  69. package/src/db/schema/shared.ts +0 -7
  70. package/src/db/schema/user.ts +0 -16
  71. package/src/db/type.ts +0 -180
  72. package/src/env/color-depth.ts +0 -172
  73. package/src/env/env-impl.ts +0 -124
  74. package/src/env/index.ts +0 -23
  75. package/src/env/logger.test.ts +0 -33
  76. package/src/env/logger.ts +0 -145
  77. package/src/error/codes.ts +0 -31
  78. package/src/error/index.ts +0 -11
  79. package/src/oauth2/client-credentials-token.ts +0 -102
  80. package/src/oauth2/create-authorization-url.ts +0 -85
  81. package/src/oauth2/index.ts +0 -21
  82. package/src/oauth2/oauth-provider.ts +0 -211
  83. package/src/oauth2/refresh-access-token.ts +0 -124
  84. package/src/oauth2/utils.ts +0 -36
  85. package/src/oauth2/validate-authorization-code.ts +0 -154
  86. package/src/social-providers/apple.ts +0 -213
  87. package/src/social-providers/atlassian.ts +0 -132
  88. package/src/social-providers/cognito.ts +0 -269
  89. package/src/social-providers/discord.ts +0 -169
  90. package/src/social-providers/dropbox.ts +0 -112
  91. package/src/social-providers/facebook.ts +0 -204
  92. package/src/social-providers/figma.ts +0 -115
  93. package/src/social-providers/github.ts +0 -154
  94. package/src/social-providers/gitlab.ts +0 -152
  95. package/src/social-providers/google.ts +0 -171
  96. package/src/social-providers/huggingface.ts +0 -118
  97. package/src/social-providers/index.ts +0 -124
  98. package/src/social-providers/kakao.ts +0 -178
  99. package/src/social-providers/kick.ts +0 -92
  100. package/src/social-providers/line.ts +0 -169
  101. package/src/social-providers/linear.ts +0 -120
  102. package/src/social-providers/linkedin.ts +0 -110
  103. package/src/social-providers/microsoft-entra-id.ts +0 -245
  104. package/src/social-providers/naver.ts +0 -112
  105. package/src/social-providers/notion.ts +0 -108
  106. package/src/social-providers/paybin.ts +0 -122
  107. package/src/social-providers/paypal.ts +0 -263
  108. package/src/social-providers/polar.ts +0 -107
  109. package/src/social-providers/reddit.ts +0 -122
  110. package/src/social-providers/roblox.ts +0 -110
  111. package/src/social-providers/salesforce.ts +0 -159
  112. package/src/social-providers/slack.ts +0 -111
  113. package/src/social-providers/spotify.ts +0 -93
  114. package/src/social-providers/tiktok.ts +0 -210
  115. package/src/social-providers/twitch.ts +0 -111
  116. package/src/social-providers/twitter.ts +0 -198
  117. package/src/social-providers/vk.ts +0 -126
  118. package/src/social-providers/zoom.ts +0 -217
  119. package/src/types/context.ts +0 -269
  120. package/src/types/cookie.ts +0 -7
  121. package/src/types/helper.ts +0 -6
  122. package/src/types/index.ts +0 -21
  123. package/src/types/init-options.ts +0 -1346
  124. package/src/types/plugin-client.ts +0 -100
  125. package/src/types/plugin.ts +0 -158
  126. package/src/utils/error-codes.ts +0 -51
  127. package/tsconfig.json +0 -7
  128. package/tsdown.config.ts +0 -20
  129. /package/{src/index.ts → dist/src/index.d.ts} +0 -0
  130. /package/{src/utils/index.ts → dist/src/utils/index.d.ts} +0 -0
package/src/api/index.ts DELETED
@@ -1,57 +0,0 @@
1
- import {
2
- createEndpoint,
3
- createMiddleware,
4
- type EndpointContext,
5
- type EndpointOptions,
6
- } from "better-call";
7
- import { runWithEndpointContext } from "../context";
8
- import type { AuthContext } from "../types";
9
-
10
- export const optionsMiddleware = createMiddleware(async () => {
11
- /**
12
- * This will be passed on the instance of
13
- * the context. Used to infer the type
14
- * here.
15
- */
16
- return {} as AuthContext;
17
- });
18
-
19
- export const createAuthMiddleware = createMiddleware.create({
20
- use: [
21
- optionsMiddleware,
22
- /**
23
- * Only use for post hooks
24
- */
25
- createMiddleware(async () => {
26
- return {} as {
27
- returned?: unknown | undefined;
28
- responseHeaders?: Headers | undefined;
29
- };
30
- }),
31
- ],
32
- });
33
-
34
- const use = [optionsMiddleware];
35
-
36
- export const createAuthEndpoint = <
37
- Path extends string,
38
- Opts extends EndpointOptions,
39
- R,
40
- >(
41
- path: Path,
42
- options: Opts,
43
- handler: (ctx: EndpointContext<Path, Opts, AuthContext>) => Promise<R>,
44
- ) => {
45
- return createEndpoint(
46
- path,
47
- {
48
- ...options,
49
- use: [...(options?.use || []), ...use],
50
- },
51
- // todo: prettify the code, we want to call `runWithEndpointContext` to top level
52
- async (ctx) => runWithEndpointContext(ctx as any, () => handler(ctx)),
53
- );
54
- };
55
-
56
- export type AuthEndpoint = ReturnType<typeof createAuthEndpoint>;
57
- export type AuthMiddleware = ReturnType<typeof createAuthMiddleware>;
@@ -1,35 +0,0 @@
1
- /**
2
- * AsyncLocalStorage will be import directly in 1.5.x
3
- */
4
- import type { AsyncLocalStorage } from "node:async_hooks";
5
-
6
- // We only export the type here to avoid issues in environments where AsyncLocalStorage is not available.
7
- export type { AsyncLocalStorage };
8
-
9
- const AsyncLocalStoragePromise: Promise<typeof AsyncLocalStorage> = import(
10
- /* @vite-ignore */
11
- /* webpackIgnore: true */
12
- "node:async_hooks"
13
- )
14
- .then((mod) => mod.AsyncLocalStorage)
15
- .catch((err) => {
16
- if ("AsyncLocalStorage" in globalThis) {
17
- return (globalThis as any).AsyncLocalStorage;
18
- }
19
- console.warn(
20
- "[payvo-auth] Warning: AsyncLocalStorage is not available in this environment. Some features may not work as expected."
21
- );
22
- console.warn(
23
- "[payvo-auth] Please read more about this warning at https://payvo-auth.com/docs/installation#mount-handler"
24
- );
25
- console.warn(
26
- "[payvo-auth] If you are using Cloudflare Workers, please see: https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag"
27
- );
28
- throw err;
29
- });
30
-
31
- export async function getAsyncLocalStorage(): Promise<
32
- typeof AsyncLocalStorage
33
- > {
34
- return AsyncLocalStoragePromise;
35
- }
@@ -1,48 +0,0 @@
1
- import type { EndpointContext, InputContext } from "better-call";
2
- import { type AsyncLocalStorage, getAsyncLocalStorage } from "../async_hooks";
3
- import type { AuthContext } from "../types";
4
-
5
- export type AuthEndpointContext = Partial<
6
- InputContext<string, any> & EndpointContext<string, any>
7
- > & {
8
- context: AuthContext;
9
- };
10
-
11
- let currentContextAsyncStorage: AsyncLocalStorage<AuthEndpointContext> | null =
12
- null;
13
-
14
- const ensureAsyncStorage = async () => {
15
- if (!currentContextAsyncStorage) {
16
- const AsyncLocalStorage = await getAsyncLocalStorage();
17
- currentContextAsyncStorage = new AsyncLocalStorage();
18
- }
19
- return currentContextAsyncStorage;
20
- };
21
-
22
- /**
23
- * This is for internal use only. Most users should use `getCurrentAuthContext` instead.
24
- *
25
- * It is exposed for advanced use cases where you need direct access to the AsyncLocalStorage instance.
26
- */
27
- export async function getCurrentAuthContextAsyncLocalStorage() {
28
- return ensureAsyncStorage();
29
- }
30
-
31
- export async function getCurrentAuthContext(): Promise<AuthEndpointContext> {
32
- const als = await ensureAsyncStorage();
33
- const context = als.getStore();
34
- if (!context) {
35
- throw new Error(
36
- "No auth context found. Please make sure you are calling this function within a `runWithEndpointContext` callback.",
37
- );
38
- }
39
- return context;
40
- }
41
-
42
- export async function runWithEndpointContext<T>(
43
- context: AuthEndpointContext,
44
- fn: () => T,
45
- ): Promise<T> {
46
- const als = await ensureAsyncStorage();
47
- return als.run(context, fn);
48
- }
@@ -1,21 +0,0 @@
1
- export {
2
- type AuthEndpointContext,
3
- getCurrentAuthContext,
4
- getCurrentAuthContextAsyncLocalStorage,
5
- runWithEndpointContext,
6
- } from "./endpoint-context";
7
- export {
8
- defineRequestState,
9
- getCurrentRequestState,
10
- getRequestStateAsyncLocalStorage,
11
- hasRequestState,
12
- type RequestState,
13
- type RequestStateWeakMap,
14
- runWithRequestState,
15
- } from "./request-state";
16
- export {
17
- getCurrentAdapter,
18
- getCurrentDBAdapterAsyncLocalStorage,
19
- runWithAdapter,
20
- runWithTransaction,
21
- } from "./transaction";
@@ -1,346 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import z from "zod";
3
- import {
4
- defineRequestState,
5
- getCurrentRequestState,
6
- hasRequestState,
7
- type RequestStateWeakMap,
8
- runWithRequestState,
9
- } from "./request-state";
10
-
11
- describe("request-state", () => {
12
- describe("runWithRequestState", () => {
13
- it("should execute function within request state context", async () => {
14
- const store: RequestStateWeakMap = new WeakMap();
15
- const result = await runWithRequestState(store, async () => {
16
- const hasStore = await hasRequestState();
17
- expect(hasStore).toBe(true);
18
- return "success";
19
- });
20
- expect(result).toBe("success");
21
- });
22
-
23
- it("should isolate request states between concurrent requests", async () => {
24
- const store1: RequestStateWeakMap = new WeakMap();
25
- const store2: RequestStateWeakMap = new WeakMap();
26
-
27
- const schema = z.object({ id: z.string() });
28
- const { get, set } = defineRequestState(schema);
29
-
30
- const [result1, result2] = await Promise.all([
31
- runWithRequestState(store1, async () => {
32
- await set({ id: "store1" });
33
- // Simulate some async work
34
- await new Promise((resolve) => setTimeout(resolve, 10));
35
- return await get();
36
- }),
37
- runWithRequestState(store2, async () => {
38
- await set({ id: "store2" });
39
- // Simulate some async work
40
- await new Promise((resolve) => setTimeout(resolve, 5));
41
- return await get();
42
- }),
43
- ]);
44
-
45
- expect(result1).toEqual({ id: "store1" });
46
- expect(result2).toEqual({ id: "store2" });
47
- });
48
-
49
- it("should support nested async operations", async () => {
50
- const store: RequestStateWeakMap = new WeakMap();
51
- const schema = z.object({ value: z.number() });
52
- const { get, set } = defineRequestState(schema);
53
-
54
- await runWithRequestState(store, async () => {
55
- await set({ value: 1 });
56
-
57
- const nestedResult = await (async () => {
58
- const current = await get();
59
- await set({ value: (current?.value || 0) + 1 });
60
- return await get();
61
- })();
62
-
63
- expect(nestedResult).toEqual({ value: 2 });
64
- expect(await get()).toEqual({ value: 2 });
65
- });
66
- });
67
- });
68
-
69
- describe("hasRequestState", () => {
70
- it("should return false when not in request state context", async () => {
71
- const hasStore = await hasRequestState();
72
- expect(hasStore).toBe(false);
73
- });
74
-
75
- it("should return true when in request state context", async () => {
76
- const store: RequestStateWeakMap = new WeakMap();
77
- await runWithRequestState(store, async () => {
78
- const hasStore = await hasRequestState();
79
- expect(hasStore).toBe(true);
80
- });
81
- });
82
- });
83
-
84
- describe("getCurrentRequestState", () => {
85
- it("should throw error when not in request state context", async () => {
86
- await expect(getCurrentRequestState()).rejects.toThrow(
87
- "No request state found",
88
- );
89
- });
90
-
91
- it("should return the current store when in context", async () => {
92
- const store: RequestStateWeakMap = new WeakMap();
93
- await runWithRequestState(store, async () => {
94
- const currentStore = await getCurrentRequestState();
95
- expect(currentStore).toBe(store);
96
- });
97
- });
98
- });
99
-
100
- describe("defineRequestState", () => {
101
- it("should create a request state with get and set methods", async () => {
102
- const schema = z.object({ name: z.string() });
103
- const store = defineRequestState(schema);
104
-
105
- expect(store).toHaveProperty("get");
106
- expect(store).toHaveProperty("set");
107
- expect(typeof store.get).toBe("function");
108
- expect(typeof store.set).toBe("function");
109
- });
110
-
111
- it("should store and retrieve values using schema as key", async () => {
112
- const requestState: RequestStateWeakMap = new WeakMap();
113
- const schema = z.object({ name: z.string(), age: z.number() });
114
- const { get, set } = defineRequestState(schema);
115
-
116
- await runWithRequestState(requestState, async () => {
117
- await set({ name: "John", age: 30 });
118
- const value = await get();
119
- expect(value).toEqual({ name: "John", age: 30 });
120
- });
121
- });
122
-
123
- it("should return undefined for unset values", async () => {
124
- const requestState: RequestStateWeakMap = new WeakMap();
125
- const schema = z.object({ value: z.string() });
126
- const { get } = defineRequestState(schema);
127
-
128
- await runWithRequestState(requestState, async () => {
129
- const value = await get();
130
- expect(value).toBeUndefined();
131
- });
132
- });
133
-
134
- it("should handle multiple stores with different schemas independently", async () => {
135
- const requestState: RequestStateWeakMap = new WeakMap();
136
- const schema1 = z.object({ type: z.literal("user") });
137
- const schema2 = z.object({ type: z.literal("session") });
138
-
139
- const store1 = defineRequestState(schema1);
140
- const store2 = defineRequestState(schema2);
141
-
142
- await runWithRequestState(requestState, async () => {
143
- await store1.set({ type: "user" });
144
- await store2.set({ type: "session" });
145
-
146
- expect(await store1.get()).toEqual({ type: "user" });
147
- expect(await store2.get()).toEqual({ type: "session" });
148
- });
149
- });
150
-
151
- it("should overwrite existing values", async () => {
152
- const requestState: RequestStateWeakMap = new WeakMap();
153
- const schema = z.object({ count: z.number() });
154
- const { get, set } = defineRequestState(schema);
155
-
156
- await runWithRequestState(requestState, async () => {
157
- await set({ count: 1 });
158
- expect(await get()).toEqual({ count: 1 });
159
-
160
- await set({ count: 2 });
161
- expect(await get()).toEqual({ count: 2 });
162
- });
163
- });
164
-
165
- it("should handle complex nested objects", async () => {
166
- const requestState: RequestStateWeakMap = new WeakMap();
167
- const schema = z.object({
168
- user: z.object({
169
- id: z.string(),
170
- profile: z.object({
171
- name: z.string(),
172
- settings: z.object({
173
- theme: z.string(),
174
- }),
175
- }),
176
- }),
177
- });
178
- const { get, set } = defineRequestState(schema);
179
-
180
- await runWithRequestState(requestState, async () => {
181
- const value = {
182
- user: {
183
- id: "123",
184
- profile: {
185
- name: "John",
186
- settings: {
187
- theme: "dark",
188
- },
189
- },
190
- },
191
- };
192
- await set(value);
193
- expect(await get()).toEqual(value);
194
- });
195
- });
196
-
197
- it("should handle arrays in schema", async () => {
198
- const requestState: RequestStateWeakMap = new WeakMap();
199
- const schema = z.object({
200
- tags: z.array(z.string()),
201
- scores: z.array(z.number()),
202
- });
203
- const { get, set } = defineRequestState(schema);
204
-
205
- await runWithRequestState(requestState, async () => {
206
- await set({ tags: ["auth", "oauth"], scores: [1, 2, 3] });
207
- const value = await get();
208
- expect(value).toEqual({ tags: ["auth", "oauth"], scores: [1, 2, 3] });
209
- });
210
- });
211
-
212
- it("should throw error when accessing outside request state context", async () => {
213
- const schema = z.object({ value: z.string() });
214
- const { get, set } = defineRequestState(schema);
215
-
216
- await expect(get()).rejects.toThrow("No request state found");
217
- await expect(set({ value: "test" })).rejects.toThrow(
218
- "No request state found",
219
- );
220
- });
221
- });
222
-
223
- describe("type inference", () => {
224
- it("should infer types from schema", async () => {
225
- const requestState: RequestStateWeakMap = new WeakMap();
226
- const schema = z.object({
227
- id: z.string(),
228
- count: z.number(),
229
- active: z.boolean(),
230
- });
231
- const { get, set } = defineRequestState(schema);
232
-
233
- await runWithRequestState(requestState, async () => {
234
- // TypeScript should infer the correct types here
235
- await set({ id: "123", count: 42, active: true });
236
- const value = await get();
237
-
238
- if (value) {
239
- // These should all be properly typed
240
- const id: string = value.id;
241
- const count: number = value.count;
242
- const active: boolean = value.active;
243
-
244
- expect(id).toBe("123");
245
- expect(count).toBe(42);
246
- expect(active).toBe(true);
247
- }
248
- });
249
- });
250
- });
251
-
252
- describe("error handling", () => {
253
- it("should handle errors thrown within runWithRequestState", async () => {
254
- const store: RequestStateWeakMap = new WeakMap();
255
-
256
- await expect(
257
- runWithRequestState(store, async () => {
258
- throw new Error("Test error");
259
- }),
260
- ).rejects.toThrow("Test error");
261
- });
262
-
263
- it("should clean up context after error", async () => {
264
- const store: RequestStateWeakMap = new WeakMap();
265
-
266
- try {
267
- await runWithRequestState(store, async () => {
268
- throw new Error("Test error");
269
- });
270
- } catch (e) {
271
- // Error is expected
272
- }
273
-
274
- // Should not have a store context after the error
275
- const hasStore = await hasRequestState();
276
- expect(hasStore).toBe(false);
277
- });
278
- });
279
-
280
- describe("WeakMap behavior", () => {
281
- it("should use schema objects as keys in WeakMap", async () => {
282
- const store: RequestStateWeakMap = new WeakMap();
283
- const schema1 = z.object({ value: z.string() });
284
- const schema2 = z.object({ value: z.string() }); // Same structure, different instance
285
-
286
- const store1 = defineRequestState(schema1);
287
- const store2 = defineRequestState(schema2);
288
-
289
- await runWithRequestState(store, async () => {
290
- await store1.set({ value: "first" });
291
- await store2.set({ value: "second" });
292
-
293
- // Different schema instances should have different values
294
- expect(await store1.get()).toEqual({ value: "first" });
295
- expect(await store2.get()).toEqual({ value: "second" });
296
- });
297
- });
298
- });
299
-
300
- describe("concurrent request isolation", () => {
301
- it("should maintain separate stores for 10 concurrent requests", async () => {
302
- const schema = z.object({ requestId: z.number() });
303
- const { get, set } = defineRequestState(schema);
304
-
305
- const promises = Array.from({ length: 10 }, (_, i) => {
306
- const store: RequestStateWeakMap = new WeakMap();
307
- return runWithRequestState(store, async () => {
308
- await set({ requestId: i });
309
- // Simulate async work with varying delays
310
- await new Promise((resolve) =>
311
- setTimeout(resolve, Math.random() * 20),
312
- );
313
- const value = await get();
314
- return value;
315
- });
316
- });
317
-
318
- const results = await Promise.all(promises);
319
-
320
- // Each request should have its own unique ID
321
- results.forEach((result, index) => {
322
- expect(result).toEqual({ requestId: index });
323
- });
324
- });
325
-
326
- it("should handle rapid consecutive requests", async () => {
327
- const schema = z.object({ counter: z.number() });
328
- const { get, set } = defineRequestState(schema);
329
-
330
- const results = await Promise.all(
331
- Array.from({ length: 100 }, async (_, i) => {
332
- const store: RequestStateWeakMap = new WeakMap();
333
- return runWithRequestState(store, async () => {
334
- await set({ counter: i });
335
- return await get();
336
- });
337
- }),
338
- );
339
-
340
- // Each request should have its own counter value
341
- results.forEach((result, index) => {
342
- expect(result).toEqual({ counter: index });
343
- });
344
- });
345
- });
346
- });
@@ -1,75 +0,0 @@
1
- import type { StandardSchemaV1 } from "@standard-schema/spec";
2
- import z from "zod";
3
- import { type AsyncLocalStorage, getAsyncLocalStorage } from "../async_hooks";
4
-
5
- export type RequestStateWeakMap = WeakMap<StandardSchemaV1, any>;
6
-
7
- let requestStateAsyncStorage: AsyncLocalStorage<RequestStateWeakMap> | null =
8
- null;
9
-
10
- const ensureAsyncStorage = async () => {
11
- if (!requestStateAsyncStorage) {
12
- const AsyncLocalStorage = await getAsyncLocalStorage();
13
- requestStateAsyncStorage = new AsyncLocalStorage();
14
- }
15
- return requestStateAsyncStorage;
16
- };
17
-
18
- export async function getRequestStateAsyncLocalStorage() {
19
- return ensureAsyncStorage();
20
- }
21
-
22
- export async function hasRequestState() {
23
- const als = await ensureAsyncStorage();
24
- return als.getStore() !== undefined;
25
- }
26
-
27
- export async function getCurrentRequestState(): Promise<RequestStateWeakMap> {
28
- const als = await ensureAsyncStorage();
29
- const store = als.getStore();
30
- if (!store) {
31
- throw new Error(
32
- "No request state found. Please make sure you are calling this function within a `runWithRequestState` callback.",
33
- );
34
- }
35
- return store;
36
- }
37
-
38
- export async function runWithRequestState<T>(
39
- store: RequestStateWeakMap,
40
- fn: () => T,
41
- ): Promise<T> {
42
- const als = await ensureAsyncStorage();
43
- return als.run(store, fn);
44
- }
45
-
46
- export interface RequestState<T> {
47
- get<S>(): Promise<S & T>;
48
- set(value: T): Promise<void>;
49
- }
50
-
51
- export function defineRequestState<T>(
52
- schema?: StandardSchemaV1<T>,
53
- ): RequestState<T>;
54
- export function defineRequestState<Schema extends StandardSchemaV1>(
55
- schema?: Schema,
56
- ): RequestState<StandardSchemaV1.InferInput<Schema>>;
57
- export function defineRequestState(
58
- schema: StandardSchemaV1 = z.any(),
59
- ): RequestState<any> {
60
- return {
61
- async get() {
62
- const store = await getCurrentRequestState();
63
- return store.get(schema);
64
- },
65
-
66
- async set(value) {
67
- const store = await getCurrentRequestState();
68
- const parsedValue = await schema["~standard"].validate(value);
69
- if (parsedValue.issues) {
70
- throw new Error(`Invalid value: ${JSON.stringify(parsedValue.issues)}`);
71
- }
72
- store.set(schema, parsedValue.value);
73
- },
74
- };
75
- }
@@ -1,72 +0,0 @@
1
- import { type AsyncLocalStorage, getAsyncLocalStorage } from "../async_hooks";
2
- import type { DBAdapter, DBTransactionAdapter } from "../db/adapter";
3
-
4
- let currentAdapterAsyncStorage: AsyncLocalStorage<DBTransactionAdapter> | null =
5
- null;
6
-
7
- const ensureAsyncStorage = async () => {
8
- if (!currentAdapterAsyncStorage) {
9
- const AsyncLocalStorage = await getAsyncLocalStorage();
10
- currentAdapterAsyncStorage = new AsyncLocalStorage();
11
- }
12
- return currentAdapterAsyncStorage;
13
- };
14
-
15
- /**
16
- * This is for internal use only. Most users should use `getCurrentAdapter` instead.
17
- *
18
- * It is exposed for advanced use cases where you need direct access to the AsyncLocalStorage instance.
19
- */
20
- export const getCurrentDBAdapterAsyncLocalStorage = async () => {
21
- return ensureAsyncStorage();
22
- };
23
-
24
- export const getCurrentAdapter = async (
25
- fallback: DBTransactionAdapter,
26
- ): Promise<DBTransactionAdapter> => {
27
- return ensureAsyncStorage()
28
- .then((als) => {
29
- return als.getStore() || fallback;
30
- })
31
- .catch(() => {
32
- return fallback;
33
- });
34
- };
35
-
36
- export const runWithAdapter = async <R>(
37
- adapter: DBAdapter,
38
- fn: () => R,
39
- ): Promise<R> => {
40
- let called = true;
41
- return ensureAsyncStorage()
42
- .then((als) => {
43
- called = true;
44
- return als.run(adapter, fn);
45
- })
46
- .catch((err) => {
47
- if (!called) {
48
- return fn();
49
- }
50
- throw err;
51
- });
52
- };
53
-
54
- export const runWithTransaction = async <R>(
55
- adapter: DBAdapter,
56
- fn: () => R,
57
- ): Promise<R> => {
58
- let called = true;
59
- return ensureAsyncStorage()
60
- .then((als) => {
61
- called = true;
62
- return adapter.transaction(async (trx) => {
63
- return als.run(trx, fn);
64
- });
65
- })
66
- .catch((err) => {
67
- if (!called) {
68
- return fn();
69
- }
70
- throw err;
71
- });
72
- };