@next-safe-action/adapter-better-auth 0.0.0 → 0.1.1
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/LICENSE +21 -0
- package/README.md +169 -0
- package/dist/index.d.mts +62 -0
- package/dist/index.mjs +23 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +82 -8
- package/index.js +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Edoardo Ranghieri
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/next-safe-action/next-safe-action/main/assets/logo.png" alt="next-safe-action logo" width="36" height="36">
|
|
3
|
+
<a href="https://github.com/next-safe-action/next-safe-action/packages/adapter-better-auth"><h1>adapter-better-auth</h1></a>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
This adapter offers a way to seamlessly integrate [next-safe-action](https://github.com/next-safe-action/next-safe-action) with [Better Auth](https://www.better-auth.com). It provides a `betterAuthMiddleware()` function that fetches the session, blocks unauthenticated requests, and injects fully-typed `{ user, session }` data into the action context.
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- Next.js >= `15.1.0`
|
|
11
|
+
- next-safe-action >= `8.4.0`
|
|
12
|
+
- better-auth >= `1.5.0`
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npm i next-safe-action better-auth @next-safe-action/adapter-better-auth
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
### 1. Set up Better Auth
|
|
23
|
+
|
|
24
|
+
Create your Better Auth server instance:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// src/lib/auth.ts
|
|
28
|
+
import { betterAuth } from "better-auth";
|
|
29
|
+
|
|
30
|
+
export const auth = betterAuth({
|
|
31
|
+
// ...your config (database, plugins, etc.)
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Create an authenticated action client
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
// src/lib/safe-action.ts
|
|
39
|
+
import { createSafeActionClient } from "next-safe-action";
|
|
40
|
+
import { betterAuthMiddleware } from "@next-safe-action/adapter-better-auth";
|
|
41
|
+
import { auth } from "./auth";
|
|
42
|
+
|
|
43
|
+
export const actionClient = createSafeActionClient();
|
|
44
|
+
|
|
45
|
+
export const authClient = actionClient.use(betterAuthMiddleware(auth));
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3. Use it in your actions
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// src/app/actions.ts
|
|
52
|
+
"use server";
|
|
53
|
+
|
|
54
|
+
import { z } from "zod";
|
|
55
|
+
import { authClient } from "@/lib/safe-action";
|
|
56
|
+
|
|
57
|
+
export const updateProfile = authClient
|
|
58
|
+
.inputSchema(z.object({ name: z.string().min(1) }))
|
|
59
|
+
.action(async ({ parsedInput, ctx }) => {
|
|
60
|
+
// ctx.auth.user and ctx.auth.session are fully typed
|
|
61
|
+
const userId = ctx.auth.user.id;
|
|
62
|
+
|
|
63
|
+
await db.user.update({
|
|
64
|
+
where: { id: userId },
|
|
65
|
+
data: { name: parsedInput.name },
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return { success: true };
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## How it works
|
|
73
|
+
|
|
74
|
+
`betterAuthMiddleware()` creates a pre-validation middleware for the safe action client's `.use()` chain:
|
|
75
|
+
|
|
76
|
+
1. **Fetches the session** by calling `auth.api.getSession({ headers: await headers() })`
|
|
77
|
+
2. **Blocks unauthenticated requests** by calling `unauthorized()` from `next/navigation` when no session exists
|
|
78
|
+
3. **Injects typed context** by passing `{ auth: { user, session } }` to `next()`, merging it into the action context
|
|
79
|
+
|
|
80
|
+
### `unauthorized()` and auth interrupts
|
|
81
|
+
|
|
82
|
+
The default behavior uses `unauthorized()` from `next/navigation`, which requires `experimental.authInterrupts` in your Next.js configuration:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// next.config.ts
|
|
86
|
+
import type { NextConfig } from "next";
|
|
87
|
+
|
|
88
|
+
const nextConfig: NextConfig = {
|
|
89
|
+
experimental: {
|
|
90
|
+
authInterrupts: true,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default nextConfig;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Custom authorization
|
|
98
|
+
|
|
99
|
+
Pass an `authorize` callback to customize the authorization flow. The session is pre-fetched and passed to the callback:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { unauthorized } from "next/navigation";
|
|
103
|
+
import { betterAuthMiddleware } from "@next-safe-action/adapter-better-auth";
|
|
104
|
+
import { auth } from "./auth";
|
|
105
|
+
|
|
106
|
+
// Role-based access
|
|
107
|
+
export const adminClient = actionClient.use(
|
|
108
|
+
betterAuthMiddleware(auth, {
|
|
109
|
+
authorize: ({ sessionData, next }) => {
|
|
110
|
+
if (!sessionData || sessionData.user.role !== "admin") {
|
|
111
|
+
unauthorized();
|
|
112
|
+
}
|
|
113
|
+
return next({ ctx: { auth: sessionData } });
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### `authorize` callback parameters
|
|
120
|
+
|
|
121
|
+
- `auth`: the Better Auth server instance
|
|
122
|
+
- `sessionData`: the pre-fetched session data (`{ user, session } | null`)
|
|
123
|
+
- `ctx`: the current action context from preceding middleware
|
|
124
|
+
- `next`: call this to continue the middleware chain, pass `{ ctx }` to inject context
|
|
125
|
+
|
|
126
|
+
## Server Action cookies
|
|
127
|
+
|
|
128
|
+
If your actions call Better Auth functions that set cookies (e.g. `signInEmail`, `signUpEmail`), add the `nextCookies()` plugin to your Better Auth instance. Refer to the [Better Auth documentation](https://better-auth.com/docs/integrations/next#server-action-cookies) for more details.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
// src/lib/auth.ts
|
|
132
|
+
import { betterAuth } from "better-auth";
|
|
133
|
+
import { nextCookies } from "better-auth/next-js";
|
|
134
|
+
|
|
135
|
+
export const auth = betterAuth({
|
|
136
|
+
// ...your config
|
|
137
|
+
plugins: [
|
|
138
|
+
// ...other plugins
|
|
139
|
+
nextCookies(), // must be the last plugin in the array
|
|
140
|
+
],
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## API reference
|
|
145
|
+
|
|
146
|
+
### `betterAuthMiddleware(auth, opts?)`
|
|
147
|
+
|
|
148
|
+
Creates a middleware function for use with the safe action client's `.use()` method.
|
|
149
|
+
|
|
150
|
+
**Parameters:**
|
|
151
|
+
|
|
152
|
+
- `auth`: the Better Auth server instance (return value of `betterAuth()`)
|
|
153
|
+
- `opts?`: optional object with an `authorize` callback for custom authorization logic
|
|
154
|
+
|
|
155
|
+
**Returns:** a middleware function compatible with `.use()`
|
|
156
|
+
|
|
157
|
+
### Exported types
|
|
158
|
+
|
|
159
|
+
- `BetterAuthContext<Options>`: the context shape added by the middleware (`{ auth: { user, session } }`)
|
|
160
|
+
- `AuthorizeFn<Options, NextCtx>`: the `authorize` callback signature
|
|
161
|
+
- `BetterAuthMiddlewareOpts<Options, NextCtx>`: the options object type for `betterAuthMiddleware`
|
|
162
|
+
|
|
163
|
+
## Documentation
|
|
164
|
+
|
|
165
|
+
For full documentation, visit [next-safe-action.dev/docs/integrations/better-auth](https://next-safe-action.dev/docs/integrations/better-auth).
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { MiddlewareFn, MiddlewareResult } from "next-safe-action";
|
|
2
|
+
import { Auth, BetterAuthOptions } from "better-auth";
|
|
3
|
+
|
|
4
|
+
//#region src/index.types.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The default context shape added by `betterAuthMiddleware`.
|
|
7
|
+
* Contains `auth.user` and `auth.session`, fully typed from the better-auth instance.
|
|
8
|
+
*/
|
|
9
|
+
type BetterAuthContext<O extends BetterAuthOptions> = {
|
|
10
|
+
auth: Auth<O>["$Infer"]["Session"];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Authorize callback signature for custom authorization logic.
|
|
14
|
+
* Receives the pre-fetched session data, current context, and the `next` function.
|
|
15
|
+
*/
|
|
16
|
+
type AuthorizeFn<O extends BetterAuthOptions, NC extends object, Ctx extends object = object> = (args: {
|
|
17
|
+
sessionData: Auth<O>["$Infer"]["Session"] | null;
|
|
18
|
+
ctx: Ctx;
|
|
19
|
+
next: <C extends object>(opts?: {
|
|
20
|
+
ctx?: C;
|
|
21
|
+
}) => Promise<MiddlewareResult<any, C>>;
|
|
22
|
+
}) => Promise<MiddlewareResult<any, NC>>;
|
|
23
|
+
/**
|
|
24
|
+
* Options for `betterAuthMiddleware`.
|
|
25
|
+
*/
|
|
26
|
+
type BetterAuthMiddlewareOpts<O extends BetterAuthOptions, NC extends object, Ctx extends object = object> = {
|
|
27
|
+
authorize: AuthorizeFn<O, NC, Ctx>;
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/index.d.ts
|
|
31
|
+
/**
|
|
32
|
+
* Creates a next-safe-action middleware that integrates with better-auth.
|
|
33
|
+
*
|
|
34
|
+
* Default behavior: fetches the session via `auth.api.getSession()`, calls `unauthorized()` if
|
|
35
|
+
* no session exists, and injects `{ auth: { user, session } }` into the action context.
|
|
36
|
+
*
|
|
37
|
+
* Pass an `authorize` callback to customize the authorization flow. The session is pre-fetched
|
|
38
|
+
* and passed to the callback, so common customizations (e.g. role checks) don't need to re-fetch.
|
|
39
|
+
*
|
|
40
|
+
* Note: `unauthorized()` requires `experimental.authInterrupts: true` in your `next.config.ts` file.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* // Default: fetch session, unauthorized() if absent
|
|
45
|
+
* actionClient.use(betterAuthMiddleware(auth));
|
|
46
|
+
*
|
|
47
|
+
* // Custom: check role
|
|
48
|
+
* actionClient.use(betterAuthMiddleware(auth, {
|
|
49
|
+
* authorize: ({ sessionData, next }) => {
|
|
50
|
+
* if (!sessionData || sessionData.user.role !== "admin") {
|
|
51
|
+
* unauthorized();
|
|
52
|
+
* }
|
|
53
|
+
* return next({ ctx: { auth: sessionData } });
|
|
54
|
+
* },
|
|
55
|
+
* }));
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
declare function betterAuthMiddleware<O extends BetterAuthOptions>(auth: Auth<O>): MiddlewareFn<any, any, object, BetterAuthContext<O>>;
|
|
59
|
+
declare function betterAuthMiddleware<O extends BetterAuthOptions, NC extends object, Ctx extends object>(auth: Auth<O>, opts: BetterAuthMiddlewareOpts<O, NC, Ctx>): MiddlewareFn<any, any, Ctx, NC>;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { type AuthorizeFn, type BetterAuthContext, type BetterAuthMiddlewareOpts, betterAuthMiddleware };
|
|
62
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createMiddleware } from "next-safe-action";
|
|
2
|
+
import { headers } from "next/headers.js";
|
|
3
|
+
import { unauthorized } from "next/navigation.js";
|
|
4
|
+
//#region src/index.ts
|
|
5
|
+
function betterAuthMiddleware(auth, opts) {
|
|
6
|
+
return createMiddleware().define(async ({ ctx, next }) => {
|
|
7
|
+
const sessionData = await auth.api.getSession({ headers: await headers() });
|
|
8
|
+
if (opts?.authorize) return opts.authorize({
|
|
9
|
+
sessionData,
|
|
10
|
+
ctx,
|
|
11
|
+
next
|
|
12
|
+
});
|
|
13
|
+
if (!sessionData) unauthorized();
|
|
14
|
+
return next({ ctx: { auth: {
|
|
15
|
+
user: sessionData.user,
|
|
16
|
+
session: sessionData.session
|
|
17
|
+
} } });
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { betterAuthMiddleware };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { Auth, BetterAuthOptions } from \"better-auth\";\nimport { createMiddleware } from \"next-safe-action\";\nimport type { MiddlewareFn } from \"next-safe-action\";\nimport { headers } from \"next/headers\";\nimport { unauthorized } from \"next/navigation\";\nimport type { BetterAuthContext, BetterAuthMiddlewareOpts } from \"./index.types\";\n\n/**\n * Creates a next-safe-action middleware that integrates with better-auth.\n *\n * Default behavior: fetches the session via `auth.api.getSession()`, calls `unauthorized()` if\n * no session exists, and injects `{ auth: { user, session } }` into the action context.\n *\n * Pass an `authorize` callback to customize the authorization flow. The session is pre-fetched\n * and passed to the callback, so common customizations (e.g. role checks) don't need to re-fetch.\n *\n * Note: `unauthorized()` requires `experimental.authInterrupts: true` in your `next.config.ts` file.\n *\n * @example\n * ```ts\n * // Default: fetch session, unauthorized() if absent\n * actionClient.use(betterAuthMiddleware(auth));\n *\n * // Custom: check role\n * actionClient.use(betterAuthMiddleware(auth, {\n * authorize: ({ sessionData, next }) => {\n * if (!sessionData || sessionData.user.role !== \"admin\") {\n * unauthorized();\n * }\n * return next({ ctx: { auth: sessionData } });\n * },\n * }));\n * ```\n */\nexport function betterAuthMiddleware<O extends BetterAuthOptions>(\n\tauth: Auth<O>\n): MiddlewareFn<any, any, object, BetterAuthContext<O>>;\nexport function betterAuthMiddleware<O extends BetterAuthOptions, NC extends object, Ctx extends object>(\n\tauth: Auth<O>,\n\topts: BetterAuthMiddlewareOpts<O, NC, Ctx>\n): MiddlewareFn<any, any, Ctx, NC>;\nexport function betterAuthMiddleware<O extends BetterAuthOptions>(\n\tauth: Auth<O>,\n\topts?: BetterAuthMiddlewareOpts<O, any, any>\n) {\n\treturn createMiddleware().define(async ({ ctx, next }) => {\n\t\tconst sessionData = await auth.api.getSession({ headers: await headers() });\n\n\t\tif (opts?.authorize) {\n\t\t\treturn opts.authorize({ sessionData, ctx, next });\n\t\t}\n\n\t\tif (!sessionData) {\n\t\t\tunauthorized();\n\t\t}\n\n\t\treturn next({ ctx: { auth: { user: sessionData.user, session: sessionData.session } } });\n\t});\n}\n\nexport type { AuthorizeFn, BetterAuthContext, BetterAuthMiddlewareOpts } from \"./index.types\";\n"],"mappings":";;;;AAyCA,SAAgB,qBACf,MACA,MACC;AACD,QAAO,kBAAkB,CAAC,OAAO,OAAO,EAAE,KAAK,WAAW;EACzD,MAAM,cAAc,MAAM,KAAK,IAAI,WAAW,EAAE,SAAS,MAAM,SAAS,EAAE,CAAC;AAE3E,MAAI,MAAM,UACT,QAAO,KAAK,UAAU;GAAE;GAAa;GAAK;GAAM,CAAC;AAGlD,MAAI,CAAC,YACJ,eAAc;AAGf,SAAO,KAAK,EAAE,KAAK,EAAE,MAAM;GAAE,MAAM,YAAY;GAAM,SAAS,YAAY;GAAS,EAAE,EAAE,CAAC;GACvF"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,89 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@next-safe-action/adapter-better-auth",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Better Auth adapter for next-safe-action.",
|
|
6
|
+
"main": "./dist/index.mjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.mts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.mts",
|
|
15
|
+
"default": "./dist/index.mjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"typesVersions": {
|
|
19
|
+
"*": {
|
|
20
|
+
".": [
|
|
21
|
+
"./dist/index.d.mts"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"funding": [
|
|
26
|
+
{
|
|
27
|
+
"type": "github",
|
|
28
|
+
"url": "https://github.com/sponsors/TheEdoRan"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "paypal",
|
|
32
|
+
"url": "https://www.paypal.com/donate/?hosted_button_id=ES9JRPSC66XKW"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"keywords": [
|
|
36
|
+
"next",
|
|
37
|
+
"nextjs",
|
|
38
|
+
"react",
|
|
39
|
+
"rsc",
|
|
40
|
+
"react server components",
|
|
41
|
+
"mutation",
|
|
42
|
+
"action",
|
|
43
|
+
"actions",
|
|
44
|
+
"react actions",
|
|
45
|
+
"next actions",
|
|
46
|
+
"server actions",
|
|
47
|
+
"next-safe-action",
|
|
48
|
+
"next safe action",
|
|
49
|
+
"better-auth",
|
|
50
|
+
"better auth",
|
|
51
|
+
"auth",
|
|
52
|
+
"authentication"
|
|
53
|
+
],
|
|
8
54
|
"author": "Edoardo Ranghieri",
|
|
9
55
|
"license": "MIT",
|
|
10
|
-
"
|
|
11
|
-
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^24",
|
|
58
|
+
"better-auth": "^1.5.6",
|
|
59
|
+
"next": "^16",
|
|
60
|
+
"oxlint": "^1.57.0",
|
|
61
|
+
"oxlint-tsgolint": "^0.15.0",
|
|
62
|
+
"tsdown": "^0.21.0",
|
|
63
|
+
"typescript": "^6.0.2",
|
|
64
|
+
"vitest": "^3.1.1",
|
|
65
|
+
"zod": "^4.3.6",
|
|
66
|
+
"next-safe-action": "8.4.0"
|
|
67
|
+
},
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"better-auth": ">= 1.5.0",
|
|
70
|
+
"next": ">= 15.1.0",
|
|
71
|
+
"next-safe-action": ">= 8.4.0"
|
|
72
|
+
},
|
|
73
|
+
"engines": {
|
|
74
|
+
"node": ">=18.17"
|
|
75
|
+
},
|
|
76
|
+
"repository": {
|
|
77
|
+
"type": "git",
|
|
78
|
+
"url": "https://github.com/next-safe-action/next-safe-action.git",
|
|
79
|
+
"directory": "packages/adapter-better-auth"
|
|
80
|
+
},
|
|
12
81
|
"publishConfig": {
|
|
13
82
|
"access": "public"
|
|
83
|
+
},
|
|
84
|
+
"scripts": {
|
|
85
|
+
"test": "vitest run",
|
|
86
|
+
"lint": "tsc --noEmit && oxlint --type-aware .",
|
|
87
|
+
"build": "tsdown"
|
|
14
88
|
}
|
|
15
|
-
}
|
|
89
|
+
}
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {}
|