@btst/stack 1.0.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.
- package/README.md +3 -0
- package/dist/api/index.cjs +30 -0
- package/dist/api/index.d.cts +29 -0
- package/dist/api/index.d.mts +29 -0
- package/dist/api/index.d.ts +29 -0
- package/dist/api/index.mjs +28 -0
- package/dist/client/index.cjs +34 -0
- package/dist/client/index.d.cts +36 -0
- package/dist/client/index.d.mts +36 -0
- package/dist/client/index.d.ts +36 -0
- package/dist/client/index.mjs +26 -0
- package/dist/context/index.cjs +55 -0
- package/dist/context/index.d.cts +86 -0
- package/dist/context/index.d.mts +86 -0
- package/dist/context/index.d.ts +86 -0
- package/dist/context/index.mjs +50 -0
- package/dist/index.cjs +9 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +3 -0
- package/dist/plugins/index.cjs +16 -0
- package/dist/plugins/index.d.cts +64 -0
- package/dist/plugins/index.d.mts +64 -0
- package/dist/plugins/index.d.ts +64 -0
- package/dist/plugins/index.mjs +11 -0
- package/dist/shared/stack.Br2KMECJ.cjs +23 -0
- package/dist/shared/stack.CwGEQ10b.mjs +20 -0
- package/dist/shared/stack.DvFqFlOV.d.cts +22 -0
- package/dist/shared/stack.DvFqFlOV.d.mts +22 -0
- package/dist/shared/stack.DvFqFlOV.d.ts +22 -0
- package/dist/shared/stack.Dva9muUy.d.cts +138 -0
- package/dist/shared/stack.Dva9muUy.d.mts +138 -0
- package/dist/shared/stack.Dva9muUy.d.ts +138 -0
- package/package.json +129 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { createContext, useContext } from 'react';
|
|
4
|
+
|
|
5
|
+
const BetterStackContext = createContext(
|
|
6
|
+
null
|
|
7
|
+
);
|
|
8
|
+
function BetterStackProvider({
|
|
9
|
+
children,
|
|
10
|
+
overrides
|
|
11
|
+
}) {
|
|
12
|
+
const value = {
|
|
13
|
+
overrides
|
|
14
|
+
};
|
|
15
|
+
return /* @__PURE__ */ jsx(BetterStackContext.Provider, { value, children });
|
|
16
|
+
}
|
|
17
|
+
function useBetterStack() {
|
|
18
|
+
const context = useContext(
|
|
19
|
+
BetterStackContext
|
|
20
|
+
);
|
|
21
|
+
if (!context) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"useBetterStack must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return context;
|
|
27
|
+
}
|
|
28
|
+
function usePluginOverrides(pluginName) {
|
|
29
|
+
const context = useBetterStack();
|
|
30
|
+
const overrides = context.overrides[pluginName];
|
|
31
|
+
if (!overrides) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Plugin "${pluginName}" not found in BetterStackProvider. Available plugins: ${Object.keys(context.overrides).join(", ")}`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return overrides;
|
|
37
|
+
}
|
|
38
|
+
function usePluginOverride(pluginName, overrideKey) {
|
|
39
|
+
const overrides = usePluginOverrides(pluginName);
|
|
40
|
+
const override = overrides[overrideKey];
|
|
41
|
+
if (override === void 0) {
|
|
42
|
+
const availableKeys = overrides && typeof overrides === "object" ? Object.keys(overrides).join(", ") : "none";
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Override "${overrideKey}" not found for plugin "${pluginName}". Available overrides: ${availableKeys}`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return override;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { BetterStackProvider, useBetterStack, usePluginOverride, usePluginOverrides };
|
package/dist/index.cjs
ADDED
package/dist/index.d.cts
ADDED
package/dist/index.d.mts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils = require('../shared/stack.Br2KMECJ.cjs');
|
|
4
|
+
require('better-call/client');
|
|
5
|
+
|
|
6
|
+
function defineClientPlugin(plugin) {
|
|
7
|
+
return plugin;
|
|
8
|
+
}
|
|
9
|
+
function defineBackendPlugin(plugin) {
|
|
10
|
+
return plugin;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
exports.createApiClient = utils.createApiClient;
|
|
14
|
+
exports.getServerBaseURL = utils.getServerBaseURL;
|
|
15
|
+
exports.defineBackendPlugin = defineBackendPlugin;
|
|
16
|
+
exports.defineClientPlugin = defineClientPlugin;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { C as ClientPlugin, B as BackendPlugin } from '../shared/stack.Dva9muUy.cjs';
|
|
2
|
+
export { I as InferPluginOverrides, d as PluginOverrides } from '../shared/stack.Dva9muUy.cjs';
|
|
3
|
+
import { Endpoint } from 'better-call';
|
|
4
|
+
export { Endpoint, Router } from 'better-call';
|
|
5
|
+
export { c as createApiClient, g as getServerBaseURL } from '../shared/stack.DvFqFlOV.cjs';
|
|
6
|
+
export { Adapter, DatabaseDefinition, DbPlugin } from '@btst/db';
|
|
7
|
+
export { Route } from '@btst/yar';
|
|
8
|
+
import 'better-call/client';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Plugin utilities and types for building standalone plugins
|
|
12
|
+
*
|
|
13
|
+
* This module exports everything needed to create custom plugins
|
|
14
|
+
* for Better Stack outside of this package.
|
|
15
|
+
*
|
|
16
|
+
* Note: Backend and Client plugins are separate to prevent SSR issues
|
|
17
|
+
* and enable better code splitting. Import them separately:
|
|
18
|
+
* - Backend: import type { BackendPlugin } from "@btst/stack/plugins"
|
|
19
|
+
* - Client: import type { ClientPlugin } from "@btst/stack/plugins"
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Helper to define a client plugin with full type inference
|
|
24
|
+
*
|
|
25
|
+
* Automatically infers route keys, hook names, and their types without needing casts.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const messagesPlugin = defineClientPlugin({
|
|
30
|
+
* name: "messages",
|
|
31
|
+
* routes: () => ({
|
|
32
|
+
* messagesList: createRoute("/messages", () => ({ ... }))
|
|
33
|
+
* }),
|
|
34
|
+
* hooks: () => ({
|
|
35
|
+
* useMessages: () => { ... }
|
|
36
|
+
* })
|
|
37
|
+
* });
|
|
38
|
+
* // No casts needed - route keys, hook names, and types are all preserved!
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @template TPlugin - The exact plugin definition (auto-inferred)
|
|
42
|
+
*/
|
|
43
|
+
declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
|
|
44
|
+
/**
|
|
45
|
+
* Helper to define a backend plugin with full type inference
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const messagesPlugin = defineBackendPlugin({
|
|
50
|
+
* name: "messages",
|
|
51
|
+
* dbPlugin: createDbPlugin("messages", messagesSchema),
|
|
52
|
+
* routes: (adapter) => ({
|
|
53
|
+
* list: endpoint("/messages", { method: "GET" }, async () => { ... }),
|
|
54
|
+
* create: endpoint("/messages", { method: "POST" }, async () => { ... })
|
|
55
|
+
* })
|
|
56
|
+
* });
|
|
57
|
+
* // Route keys "list" and "create" are preserved in types!
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @template TRoutes - The exact shape of routes (auto-inferred from routes function)
|
|
61
|
+
*/
|
|
62
|
+
declare function defineBackendPlugin<TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>>(plugin: BackendPlugin<TRoutes>): BackendPlugin<TRoutes>;
|
|
63
|
+
|
|
64
|
+
export { BackendPlugin, ClientPlugin, defineBackendPlugin, defineClientPlugin };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { C as ClientPlugin, B as BackendPlugin } from '../shared/stack.Dva9muUy.mjs';
|
|
2
|
+
export { I as InferPluginOverrides, d as PluginOverrides } from '../shared/stack.Dva9muUy.mjs';
|
|
3
|
+
import { Endpoint } from 'better-call';
|
|
4
|
+
export { Endpoint, Router } from 'better-call';
|
|
5
|
+
export { c as createApiClient, g as getServerBaseURL } from '../shared/stack.DvFqFlOV.mjs';
|
|
6
|
+
export { Adapter, DatabaseDefinition, DbPlugin } from '@btst/db';
|
|
7
|
+
export { Route } from '@btst/yar';
|
|
8
|
+
import 'better-call/client';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Plugin utilities and types for building standalone plugins
|
|
12
|
+
*
|
|
13
|
+
* This module exports everything needed to create custom plugins
|
|
14
|
+
* for Better Stack outside of this package.
|
|
15
|
+
*
|
|
16
|
+
* Note: Backend and Client plugins are separate to prevent SSR issues
|
|
17
|
+
* and enable better code splitting. Import them separately:
|
|
18
|
+
* - Backend: import type { BackendPlugin } from "@btst/stack/plugins"
|
|
19
|
+
* - Client: import type { ClientPlugin } from "@btst/stack/plugins"
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Helper to define a client plugin with full type inference
|
|
24
|
+
*
|
|
25
|
+
* Automatically infers route keys, hook names, and their types without needing casts.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const messagesPlugin = defineClientPlugin({
|
|
30
|
+
* name: "messages",
|
|
31
|
+
* routes: () => ({
|
|
32
|
+
* messagesList: createRoute("/messages", () => ({ ... }))
|
|
33
|
+
* }),
|
|
34
|
+
* hooks: () => ({
|
|
35
|
+
* useMessages: () => { ... }
|
|
36
|
+
* })
|
|
37
|
+
* });
|
|
38
|
+
* // No casts needed - route keys, hook names, and types are all preserved!
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @template TPlugin - The exact plugin definition (auto-inferred)
|
|
42
|
+
*/
|
|
43
|
+
declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
|
|
44
|
+
/**
|
|
45
|
+
* Helper to define a backend plugin with full type inference
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const messagesPlugin = defineBackendPlugin({
|
|
50
|
+
* name: "messages",
|
|
51
|
+
* dbPlugin: createDbPlugin("messages", messagesSchema),
|
|
52
|
+
* routes: (adapter) => ({
|
|
53
|
+
* list: endpoint("/messages", { method: "GET" }, async () => { ... }),
|
|
54
|
+
* create: endpoint("/messages", { method: "POST" }, async () => { ... })
|
|
55
|
+
* })
|
|
56
|
+
* });
|
|
57
|
+
* // Route keys "list" and "create" are preserved in types!
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @template TRoutes - The exact shape of routes (auto-inferred from routes function)
|
|
61
|
+
*/
|
|
62
|
+
declare function defineBackendPlugin<TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>>(plugin: BackendPlugin<TRoutes>): BackendPlugin<TRoutes>;
|
|
63
|
+
|
|
64
|
+
export { BackendPlugin, ClientPlugin, defineBackendPlugin, defineClientPlugin };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { C as ClientPlugin, B as BackendPlugin } from '../shared/stack.Dva9muUy.js';
|
|
2
|
+
export { I as InferPluginOverrides, d as PluginOverrides } from '../shared/stack.Dva9muUy.js';
|
|
3
|
+
import { Endpoint } from 'better-call';
|
|
4
|
+
export { Endpoint, Router } from 'better-call';
|
|
5
|
+
export { c as createApiClient, g as getServerBaseURL } from '../shared/stack.DvFqFlOV.js';
|
|
6
|
+
export { Adapter, DatabaseDefinition, DbPlugin } from '@btst/db';
|
|
7
|
+
export { Route } from '@btst/yar';
|
|
8
|
+
import 'better-call/client';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Plugin utilities and types for building standalone plugins
|
|
12
|
+
*
|
|
13
|
+
* This module exports everything needed to create custom plugins
|
|
14
|
+
* for Better Stack outside of this package.
|
|
15
|
+
*
|
|
16
|
+
* Note: Backend and Client plugins are separate to prevent SSR issues
|
|
17
|
+
* and enable better code splitting. Import them separately:
|
|
18
|
+
* - Backend: import type { BackendPlugin } from "@btst/stack/plugins"
|
|
19
|
+
* - Client: import type { ClientPlugin } from "@btst/stack/plugins"
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Helper to define a client plugin with full type inference
|
|
24
|
+
*
|
|
25
|
+
* Automatically infers route keys, hook names, and their types without needing casts.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const messagesPlugin = defineClientPlugin({
|
|
30
|
+
* name: "messages",
|
|
31
|
+
* routes: () => ({
|
|
32
|
+
* messagesList: createRoute("/messages", () => ({ ... }))
|
|
33
|
+
* }),
|
|
34
|
+
* hooks: () => ({
|
|
35
|
+
* useMessages: () => { ... }
|
|
36
|
+
* })
|
|
37
|
+
* });
|
|
38
|
+
* // No casts needed - route keys, hook names, and types are all preserved!
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @template TPlugin - The exact plugin definition (auto-inferred)
|
|
42
|
+
*/
|
|
43
|
+
declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
|
|
44
|
+
/**
|
|
45
|
+
* Helper to define a backend plugin with full type inference
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const messagesPlugin = defineBackendPlugin({
|
|
50
|
+
* name: "messages",
|
|
51
|
+
* dbPlugin: createDbPlugin("messages", messagesSchema),
|
|
52
|
+
* routes: (adapter) => ({
|
|
53
|
+
* list: endpoint("/messages", { method: "GET" }, async () => { ... }),
|
|
54
|
+
* create: endpoint("/messages", { method: "POST" }, async () => { ... })
|
|
55
|
+
* })
|
|
56
|
+
* });
|
|
57
|
+
* // Route keys "list" and "create" are preserved in types!
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @template TRoutes - The exact shape of routes (auto-inferred from routes function)
|
|
61
|
+
*/
|
|
62
|
+
declare function defineBackendPlugin<TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>>(plugin: BackendPlugin<TRoutes>): BackendPlugin<TRoutes>;
|
|
63
|
+
|
|
64
|
+
export { BackendPlugin, ClientPlugin, defineBackendPlugin, defineClientPlugin };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { c as createApiClient, g as getServerBaseURL } from '../shared/stack.CwGEQ10b.mjs';
|
|
2
|
+
import 'better-call/client';
|
|
3
|
+
|
|
4
|
+
function defineClientPlugin(plugin) {
|
|
5
|
+
return plugin;
|
|
6
|
+
}
|
|
7
|
+
function defineBackendPlugin(plugin) {
|
|
8
|
+
return plugin;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { defineBackendPlugin, defineClientPlugin };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const client = require('better-call/client');
|
|
4
|
+
|
|
5
|
+
function createApiClient(options) {
|
|
6
|
+
const { baseURL = "", basePath = "/api" } = options ?? {};
|
|
7
|
+
const normalizedBaseURL = baseURL ? baseURL.replace(/\/$/, "") : "";
|
|
8
|
+
const normalizedBasePath = basePath.startsWith("/") ? basePath : `/${basePath}`;
|
|
9
|
+
const finalBasePath = normalizedBasePath.replace(/\/$/, "");
|
|
10
|
+
const apiPath = normalizedBaseURL + finalBasePath;
|
|
11
|
+
return client.createClient({
|
|
12
|
+
baseURL: apiPath
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function getServerBaseURL() {
|
|
16
|
+
if (typeof window === "undefined") {
|
|
17
|
+
return process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000";
|
|
18
|
+
}
|
|
19
|
+
return void 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
exports.createApiClient = createApiClient;
|
|
23
|
+
exports.getServerBaseURL = getServerBaseURL;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createClient } from 'better-call/client';
|
|
2
|
+
|
|
3
|
+
function createApiClient(options) {
|
|
4
|
+
const { baseURL = "", basePath = "/api" } = options ?? {};
|
|
5
|
+
const normalizedBaseURL = baseURL ? baseURL.replace(/\/$/, "") : "";
|
|
6
|
+
const normalizedBasePath = basePath.startsWith("/") ? basePath : `/${basePath}`;
|
|
7
|
+
const finalBasePath = normalizedBasePath.replace(/\/$/, "");
|
|
8
|
+
const apiPath = normalizedBaseURL + finalBasePath;
|
|
9
|
+
return createClient({
|
|
10
|
+
baseURL: apiPath
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function getServerBaseURL() {
|
|
14
|
+
if (typeof window === "undefined") {
|
|
15
|
+
return process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000";
|
|
16
|
+
}
|
|
17
|
+
return void 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { createApiClient as c, getServerBaseURL as g };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createClient } from 'better-call/client';
|
|
2
|
+
import { Router, Endpoint } from 'better-call';
|
|
3
|
+
|
|
4
|
+
interface CreateApiClientOptions {
|
|
5
|
+
baseURL?: string;
|
|
6
|
+
basePath?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a Better Call API client with proper URL handling for both server and client side
|
|
10
|
+
* @param options - Configuration options
|
|
11
|
+
* @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
|
|
12
|
+
* @param options.basePath - The API base path (defaults to '/api')
|
|
13
|
+
* @template TRouter - The router type (Router or Record<string, Endpoint>)
|
|
14
|
+
*/
|
|
15
|
+
declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
|
|
16
|
+
/**
|
|
17
|
+
* Helper to get the server-side baseURL
|
|
18
|
+
* On the server, we need an absolute URL. On the client, we can use relative URLs.
|
|
19
|
+
*/
|
|
20
|
+
declare function getServerBaseURL(): string | undefined;
|
|
21
|
+
|
|
22
|
+
export { createApiClient as c, getServerBaseURL as g };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createClient } from 'better-call/client';
|
|
2
|
+
import { Router, Endpoint } from 'better-call';
|
|
3
|
+
|
|
4
|
+
interface CreateApiClientOptions {
|
|
5
|
+
baseURL?: string;
|
|
6
|
+
basePath?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a Better Call API client with proper URL handling for both server and client side
|
|
10
|
+
* @param options - Configuration options
|
|
11
|
+
* @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
|
|
12
|
+
* @param options.basePath - The API base path (defaults to '/api')
|
|
13
|
+
* @template TRouter - The router type (Router or Record<string, Endpoint>)
|
|
14
|
+
*/
|
|
15
|
+
declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
|
|
16
|
+
/**
|
|
17
|
+
* Helper to get the server-side baseURL
|
|
18
|
+
* On the server, we need an absolute URL. On the client, we can use relative URLs.
|
|
19
|
+
*/
|
|
20
|
+
declare function getServerBaseURL(): string | undefined;
|
|
21
|
+
|
|
22
|
+
export { createApiClient as c, getServerBaseURL as g };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createClient } from 'better-call/client';
|
|
2
|
+
import { Router, Endpoint } from 'better-call';
|
|
3
|
+
|
|
4
|
+
interface CreateApiClientOptions {
|
|
5
|
+
baseURL?: string;
|
|
6
|
+
basePath?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a Better Call API client with proper URL handling for both server and client side
|
|
10
|
+
* @param options - Configuration options
|
|
11
|
+
* @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
|
|
12
|
+
* @param options.basePath - The API base path (defaults to '/api')
|
|
13
|
+
* @template TRouter - The router type (Router or Record<string, Endpoint>)
|
|
14
|
+
*/
|
|
15
|
+
declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
|
|
16
|
+
/**
|
|
17
|
+
* Helper to get the server-side baseURL
|
|
18
|
+
* On the server, we need an absolute URL. On the client, we can use relative URLs.
|
|
19
|
+
*/
|
|
20
|
+
declare function getServerBaseURL(): string | undefined;
|
|
21
|
+
|
|
22
|
+
export { createApiClient as c, getServerBaseURL as g };
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Route, createRouter } from '@btst/yar';
|
|
2
|
+
import { Adapter, DbPlugin, DatabaseDefinition } from '@btst/db';
|
|
3
|
+
import { Endpoint, Router } from 'better-call';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Backend plugin definition
|
|
7
|
+
* Defines API routes and data access for a feature
|
|
8
|
+
*
|
|
9
|
+
* Note: Each plugin defines its own schema using createDbPlugin().
|
|
10
|
+
* Better Stack composes all plugin schemas together at runtime using Better DB's .use() method.
|
|
11
|
+
* You can optionally provide a base schema via the dbSchema config option.
|
|
12
|
+
*
|
|
13
|
+
* @template TRoutes - The exact shape of routes this plugin provides (preserves keys and endpoint types)
|
|
14
|
+
*/
|
|
15
|
+
interface BackendPlugin<TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>> {
|
|
16
|
+
name: string;
|
|
17
|
+
/**
|
|
18
|
+
* Create API endpoints for this plugin
|
|
19
|
+
* Returns an object with named endpoints that will be composed into the router
|
|
20
|
+
*
|
|
21
|
+
* @param adapter - Better DB adapter instance with methods:
|
|
22
|
+
* create, update, updateMany, delete, deleteMany, findOne, findMany, count
|
|
23
|
+
*/
|
|
24
|
+
routes: (adapter: Adapter) => TRoutes;
|
|
25
|
+
dbPlugin: DbPlugin;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Hook function type
|
|
29
|
+
* Generic function type for React hooks returned by plugins
|
|
30
|
+
*/
|
|
31
|
+
type HookFunction = (...args: unknown[]) => unknown;
|
|
32
|
+
/**
|
|
33
|
+
* Frontend plugin definition
|
|
34
|
+
* Defines pages, components, loaders, and React Query hooks for a feature
|
|
35
|
+
*
|
|
36
|
+
* @template TOverrides - The shape of overridable components/functions this plugin requires
|
|
37
|
+
* Example: { Link: ComponentType<{href: string}>, navigate: (path: string) => void }
|
|
38
|
+
* @template TRoutes - The exact shape of routes this plugin provides (preserves keys and route types)
|
|
39
|
+
*/
|
|
40
|
+
interface ClientPlugin<TOverrides = Record<string, never>, TRoutes extends Record<string, Route> = Record<string, Route>> {
|
|
41
|
+
name: string;
|
|
42
|
+
/**
|
|
43
|
+
* Define routes (pages) for this plugin
|
|
44
|
+
* Returns yar routes that will be composed into the router
|
|
45
|
+
*/
|
|
46
|
+
routes: () => TRoutes;
|
|
47
|
+
/**
|
|
48
|
+
* Optional: Create React Query hooks for this plugin
|
|
49
|
+
* These can be used directly in components without the loader
|
|
50
|
+
*/
|
|
51
|
+
hooks?: () => Record<string, HookFunction>;
|
|
52
|
+
/**
|
|
53
|
+
* Optional: Default implementations for overridable components/functions
|
|
54
|
+
* These will be used if no override is provided in BetterStackContext
|
|
55
|
+
*/
|
|
56
|
+
defaultOverrides?: Partial<TOverrides>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Configuration for creating the backend library
|
|
60
|
+
*/
|
|
61
|
+
interface BackendLibConfig<TPlugins extends Record<string, BackendPlugin<any>> = Record<string, BackendPlugin<any>>> {
|
|
62
|
+
dbSchema?: DatabaseDefinition;
|
|
63
|
+
plugins: TPlugins;
|
|
64
|
+
adapter: (db: DatabaseDefinition) => Adapter;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Configuration for creating the client library
|
|
68
|
+
*/
|
|
69
|
+
interface ClientLibConfig<TPlugins extends Record<string, ClientPlugin<any, any>> = Record<string, ClientPlugin<any, any>>> {
|
|
70
|
+
plugins: TPlugins;
|
|
71
|
+
baseURL?: string;
|
|
72
|
+
basePath?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Utility type to extract override types from plugins
|
|
76
|
+
* Maps plugin names to their override types
|
|
77
|
+
*/
|
|
78
|
+
type InferPluginOverrides<TPlugins extends Record<string, ClientPlugin<any, any>>> = {
|
|
79
|
+
[K in keyof TPlugins]: TPlugins[K] extends ClientPlugin<infer TOverrides, any> ? TOverrides : never;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Type for the pluginOverrides prop in BetterStackContext
|
|
83
|
+
* Allows partial overrides per plugin
|
|
84
|
+
*/
|
|
85
|
+
type PluginOverrides<TPlugins extends Record<string, ClientPlugin<any, any>>> = {
|
|
86
|
+
[K in keyof TPlugins]?: Partial<InferPluginOverrides<TPlugins>[K]>;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Extract all routes from all client plugins, merging them into a single record
|
|
90
|
+
*/
|
|
91
|
+
type PluginRoutes<TPlugins extends Record<string, ClientPlugin<any, any>>> = MergeAllPluginRoutes<TPlugins>;
|
|
92
|
+
/**
|
|
93
|
+
* Extract all hooks from all client plugins, organized by plugin name
|
|
94
|
+
* For plugins without hooks, the type will be an empty object
|
|
95
|
+
*/
|
|
96
|
+
type PluginHooks<TPlugins extends Record<string, ClientPlugin<any, any>>> = {
|
|
97
|
+
[K in keyof TPlugins]: TPlugins[K]["hooks"] extends () => infer H ? H : {};
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Prefix all backend plugin route keys with the plugin name
|
|
101
|
+
* Example: { messages: { list: Endpoint } } => { messages_list: Endpoint }
|
|
102
|
+
*/
|
|
103
|
+
type PrefixedPluginRoutes<TPlugins extends Record<string, BackendPlugin<any>>> = UnionToIntersection<{
|
|
104
|
+
[PluginKey in keyof TPlugins]: TPlugins[PluginKey] extends BackendPlugin<infer TRoutes> ? {
|
|
105
|
+
[RouteKey in keyof TRoutes as `${PluginKey & string}_${RouteKey & string}`]: TRoutes[RouteKey];
|
|
106
|
+
} : never;
|
|
107
|
+
}[keyof TPlugins]> extends infer U ? U extends Record<string, Endpoint> ? U : Record<string, Endpoint> : Record<string, Endpoint>;
|
|
108
|
+
/**
|
|
109
|
+
* Result of creating the backend library
|
|
110
|
+
*/
|
|
111
|
+
interface BackendLib<TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>> {
|
|
112
|
+
handler: (request: Request) => Promise<Response>;
|
|
113
|
+
router: Router;
|
|
114
|
+
dbSchema: DatabaseDefinition;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Helper type to extract routes from a client plugin
|
|
118
|
+
*/
|
|
119
|
+
type ExtractPluginRoutes<T> = T extends ClientPlugin<any, infer TRoutes> ? TRoutes : never;
|
|
120
|
+
/**
|
|
121
|
+
* Helper type to merge all routes from all plugins into a single record
|
|
122
|
+
*/
|
|
123
|
+
type MergeAllPluginRoutes<TPlugins extends Record<string, ClientPlugin<any, any>>> = UnionToIntersection<{
|
|
124
|
+
[K in keyof TPlugins]: ExtractPluginRoutes<TPlugins[K]>;
|
|
125
|
+
}[keyof TPlugins]> extends infer U ? U extends Record<string, Route> ? U : Record<string, Route> : Record<string, Route>;
|
|
126
|
+
/**
|
|
127
|
+
* Utility type to convert union to intersection
|
|
128
|
+
*/
|
|
129
|
+
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
130
|
+
/**
|
|
131
|
+
* Result of creating the client library
|
|
132
|
+
*/
|
|
133
|
+
interface ClientLib<TRoutes extends Record<string, Route> = Record<string, Route>, THooks extends Record<string, any> = Record<string, any>> {
|
|
134
|
+
router: ReturnType<typeof createRouter<TRoutes, {}>>;
|
|
135
|
+
hooks: THooks;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export type { BackendPlugin as B, ClientPlugin as C, InferPluginOverrides as I, PluginRoutes as P, PluginHooks as a, ClientLibConfig as b, ClientLib as c, PluginOverrides as d, PrefixedPluginRoutes as e, BackendLibConfig as f, BackendLib as g };
|