@btst/stack 1.1.0 → 1.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/README.md +12 -12
- package/dist/api/index.cjs +2 -0
- package/dist/api/index.d.cts +1 -0
- package/dist/api/index.d.mts +1 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.mjs +1 -0
- package/dist/client/index.cjs +2 -0
- package/dist/client/index.d.cts +24 -1
- package/dist/client/index.d.mts +24 -1
- package/dist/client/index.d.ts +24 -1
- package/dist/client/index.mjs +1 -0
- package/dist/client/path-utils.cjs +15 -0
- package/dist/client/path-utils.mjs +13 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/plugins/api/index.cjs +0 -2
- package/dist/plugins/api/index.d.cts +0 -1
- package/dist/plugins/api/index.d.mts +0 -1
- package/dist/plugins/api/index.d.ts +0 -1
- package/dist/plugins/api/index.mjs +0 -1
- package/dist/plugins/blog/api/index.d.cts +1 -1
- package/dist/plugins/blog/api/index.d.mts +1 -1
- package/dist/plugins/blog/api/index.d.ts +1 -1
- package/dist/plugins/blog/client/components/shared/better-blog-attribution.cjs +4 -4
- package/dist/plugins/blog/client/components/shared/better-blog-attribution.mjs +4 -4
- package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
- package/dist/plugins/blog/client/index.d.cts +1 -1
- package/dist/plugins/blog/client/index.d.mts +1 -1
- package/dist/plugins/blog/client/index.d.ts +1 -1
- package/dist/plugins/blog/query-keys.d.cts +2 -2
- package/dist/plugins/blog/query-keys.d.mts +2 -2
- package/dist/plugins/blog/query-keys.d.ts +2 -2
- package/package.json +1 -1
- package/src/api/index.ts +2 -0
- package/src/client/index.ts +2 -0
- package/src/client/path-utils.ts +38 -0
- package/src/plugins/api/index.ts +0 -1
- package/src/plugins/blog/client/components/shared/better-blog-attribution.tsx +4 -4
- package/dist/shared/{stack.Cr2JoQdo.d.cts → stack.CoPoHVfV.d.cts} +1 -1
- package/dist/shared/{stack.Cr2JoQdo.d.mts → stack.CoPoHVfV.d.mts} +1 -1
- package/dist/shared/{stack.Cr2JoQdo.d.ts → stack.CoPoHVfV.d.ts} +1 -1
package/README.md
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Composable full-stack plugin system for React frameworks**
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@btst/stack)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
9
|
|
|
10
|
-
[📖 Documentation](https://www.
|
|
10
|
+
[📖 Documentation](https://www.better-stack.ai) • [🐛 Issues](https://github.com/olliethedev/better-stack/issues)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -215,23 +215,23 @@ Now add scheduling, feedback, or newsletters the same way. Each feature is indep
|
|
|
215
215
|
|
|
216
216
|
Better Stack transforms how you think about building apps:
|
|
217
217
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
• **Rapid prototyping** - Add 5 features in an afternoon instead of 5 weeks. Validate ideas faster
|
|
218
|
+
- **Open source** - Share complete features, not just code snippets. Someone can add a newsletter plugin to their Next.js app in minutes
|
|
219
|
+
- **Fast development** - Add 5 features in an afternoon instead of 5 weeks. Validate ideas faster
|
|
220
|
+
- **Agencies** - Create a library of reusable features. Drop scheduling into client A's app, feedback into client B's app.
|
|
221
|
+
- **SaaS platforms** - Offer feature plugins your customers can compose. They pick blog + scheduling + AI assistant, mix and match to build their ideal app
|
|
223
222
|
|
|
224
|
-
|
|
223
|
+
|
|
224
|
+
Each plugin is a complete, self-contained horizontal full-stack feature. No framework lock-in. Just add it and it works.
|
|
225
225
|
|
|
226
226
|
## Learn More
|
|
227
227
|
|
|
228
|
-
For complete documentation, examples, and plugin development guides, visit **[https://www.
|
|
228
|
+
For complete documentation, examples, and plugin development guides, visit **[https://www.better-stack.ai](https://www.better-stack.ai)**
|
|
229
229
|
|
|
230
230
|
## Examples
|
|
231
231
|
|
|
232
|
-
- [Next.js App Router](./examples/nextjs) -
|
|
233
|
-
- [React Router](./examples/react-router) -
|
|
234
|
-
- [TanStack Router](./examples/tanstack) -
|
|
232
|
+
- [Next.js App Router](./examples/nextjs) - Next.js App Router example
|
|
233
|
+
- [React Router](./examples/react-router) - React Router example
|
|
234
|
+
- [TanStack Router](./examples/tanstack) - TanStack Router example
|
|
235
235
|
|
|
236
236
|
## License
|
|
237
237
|
|
package/dist/api/index.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const betterCall = require('better-call');
|
|
4
4
|
const db = require('@btst/db');
|
|
5
|
+
const node = require('better-call/node');
|
|
5
6
|
|
|
6
7
|
function betterStack(config) {
|
|
7
8
|
const { plugins, adapter, dbSchema, basePath } = config;
|
|
@@ -27,4 +28,5 @@ function betterStack(config) {
|
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
exports.toNodeHandler = node.toNodeHandler;
|
|
30
32
|
exports.betterStack = betterStack;
|
package/dist/api/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { d as PrefixedPluginRoutes, e as BackendLibConfig, f as BackendLib } from '../shared/stack.ByOugz9d.cjs';
|
|
2
2
|
export { B as BackendPlugin } from '../shared/stack.ByOugz9d.cjs';
|
|
3
|
+
export { toNodeHandler } from 'better-call/node';
|
|
3
4
|
import '@btst/yar';
|
|
4
5
|
import '@btst/db';
|
|
5
6
|
import 'better-call';
|
package/dist/api/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { d as PrefixedPluginRoutes, e as BackendLibConfig, f as BackendLib } from '../shared/stack.ByOugz9d.mjs';
|
|
2
2
|
export { B as BackendPlugin } from '../shared/stack.ByOugz9d.mjs';
|
|
3
|
+
export { toNodeHandler } from 'better-call/node';
|
|
3
4
|
import '@btst/yar';
|
|
4
5
|
import '@btst/db';
|
|
5
6
|
import 'better-call';
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { d as PrefixedPluginRoutes, e as BackendLibConfig, f as BackendLib } from '../shared/stack.ByOugz9d.js';
|
|
2
2
|
export { B as BackendPlugin } from '../shared/stack.ByOugz9d.js';
|
|
3
|
+
export { toNodeHandler } from 'better-call/node';
|
|
3
4
|
import '@btst/yar';
|
|
4
5
|
import '@btst/db';
|
|
5
6
|
import 'better-call';
|
package/dist/api/index.mjs
CHANGED
package/dist/client/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const yar = require('@btst/yar');
|
|
4
4
|
const sitemapUtils = require('./sitemap-utils.cjs');
|
|
5
5
|
const metaUtils = require('./meta-utils.cjs');
|
|
6
|
+
const pathUtils = require('./path-utils.cjs');
|
|
6
7
|
|
|
7
8
|
function createStackClient(config) {
|
|
8
9
|
const { plugins } = config;
|
|
@@ -36,4 +37,5 @@ function createStackClient(config) {
|
|
|
36
37
|
|
|
37
38
|
exports.sitemapEntryToXmlString = sitemapUtils.sitemapEntryToXmlString;
|
|
38
39
|
exports.metaElementsToObject = metaUtils.metaElementsToObject;
|
|
40
|
+
exports.normalizePath = pathUtils.normalizePath;
|
|
39
41
|
exports.createStackClient = createStackClient;
|
package/dist/client/index.d.cts
CHANGED
|
@@ -72,6 +72,29 @@ interface Metadata {
|
|
|
72
72
|
*/
|
|
73
73
|
declare function metaElementsToObject(metaElements: Array<React.JSX.IntrinsicElements["meta"] | undefined>): Metadata;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Normalizes path segments from framework route params into a consistent path string.
|
|
77
|
+
*
|
|
78
|
+
* Handles different framework param formats:
|
|
79
|
+
* - Next.js: `pathParams.all` (string[])
|
|
80
|
+
* - React Router: `params["*"]` (string)
|
|
81
|
+
* - TanStack Router: `params._splat` (string)
|
|
82
|
+
*
|
|
83
|
+
* @param path - Path segments as string, string array, or undefined
|
|
84
|
+
* @returns Normalized path string starting with "/" (or "/" for empty/undefined)
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* // Next.js
|
|
89
|
+
* normalizePath(pathParams?.all) // ["blog", "post"] => "/blog/post"
|
|
90
|
+
*
|
|
91
|
+
* // React Router / TanStack Router
|
|
92
|
+
* normalizePath(params["*"]) // "blog/post" => "/blog/post"
|
|
93
|
+
* normalizePath(undefined) // => "/"
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare function normalizePath(path?: string | Array<string> | undefined): string;
|
|
97
|
+
|
|
75
98
|
/**
|
|
76
99
|
* Creates the client library with plugin support
|
|
77
100
|
*
|
|
@@ -121,4 +144,4 @@ declare function metaElementsToObject(metaElements: Array<React.JSX.IntrinsicEle
|
|
|
121
144
|
*/
|
|
122
145
|
declare function createStackClient<TPlugins extends Record<string, ClientPlugin<any, any>>, TRoutes extends PluginRoutes<TPlugins> = PluginRoutes<TPlugins>>(config: ClientLibConfig<TPlugins>): ClientLib<TRoutes>;
|
|
123
146
|
|
|
124
|
-
export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient, metaElementsToObject, sitemapEntryToXmlString };
|
|
147
|
+
export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient, metaElementsToObject, normalizePath, sitemapEntryToXmlString };
|
package/dist/client/index.d.mts
CHANGED
|
@@ -72,6 +72,29 @@ interface Metadata {
|
|
|
72
72
|
*/
|
|
73
73
|
declare function metaElementsToObject(metaElements: Array<React.JSX.IntrinsicElements["meta"] | undefined>): Metadata;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Normalizes path segments from framework route params into a consistent path string.
|
|
77
|
+
*
|
|
78
|
+
* Handles different framework param formats:
|
|
79
|
+
* - Next.js: `pathParams.all` (string[])
|
|
80
|
+
* - React Router: `params["*"]` (string)
|
|
81
|
+
* - TanStack Router: `params._splat` (string)
|
|
82
|
+
*
|
|
83
|
+
* @param path - Path segments as string, string array, or undefined
|
|
84
|
+
* @returns Normalized path string starting with "/" (or "/" for empty/undefined)
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* // Next.js
|
|
89
|
+
* normalizePath(pathParams?.all) // ["blog", "post"] => "/blog/post"
|
|
90
|
+
*
|
|
91
|
+
* // React Router / TanStack Router
|
|
92
|
+
* normalizePath(params["*"]) // "blog/post" => "/blog/post"
|
|
93
|
+
* normalizePath(undefined) // => "/"
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare function normalizePath(path?: string | Array<string> | undefined): string;
|
|
97
|
+
|
|
75
98
|
/**
|
|
76
99
|
* Creates the client library with plugin support
|
|
77
100
|
*
|
|
@@ -121,4 +144,4 @@ declare function metaElementsToObject(metaElements: Array<React.JSX.IntrinsicEle
|
|
|
121
144
|
*/
|
|
122
145
|
declare function createStackClient<TPlugins extends Record<string, ClientPlugin<any, any>>, TRoutes extends PluginRoutes<TPlugins> = PluginRoutes<TPlugins>>(config: ClientLibConfig<TPlugins>): ClientLib<TRoutes>;
|
|
123
146
|
|
|
124
|
-
export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient, metaElementsToObject, sitemapEntryToXmlString };
|
|
147
|
+
export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient, metaElementsToObject, normalizePath, sitemapEntryToXmlString };
|
package/dist/client/index.d.ts
CHANGED
|
@@ -72,6 +72,29 @@ interface Metadata {
|
|
|
72
72
|
*/
|
|
73
73
|
declare function metaElementsToObject(metaElements: Array<React.JSX.IntrinsicElements["meta"] | undefined>): Metadata;
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Normalizes path segments from framework route params into a consistent path string.
|
|
77
|
+
*
|
|
78
|
+
* Handles different framework param formats:
|
|
79
|
+
* - Next.js: `pathParams.all` (string[])
|
|
80
|
+
* - React Router: `params["*"]` (string)
|
|
81
|
+
* - TanStack Router: `params._splat` (string)
|
|
82
|
+
*
|
|
83
|
+
* @param path - Path segments as string, string array, or undefined
|
|
84
|
+
* @returns Normalized path string starting with "/" (or "/" for empty/undefined)
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* // Next.js
|
|
89
|
+
* normalizePath(pathParams?.all) // ["blog", "post"] => "/blog/post"
|
|
90
|
+
*
|
|
91
|
+
* // React Router / TanStack Router
|
|
92
|
+
* normalizePath(params["*"]) // "blog/post" => "/blog/post"
|
|
93
|
+
* normalizePath(undefined) // => "/"
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare function normalizePath(path?: string | Array<string> | undefined): string;
|
|
97
|
+
|
|
75
98
|
/**
|
|
76
99
|
* Creates the client library with plugin support
|
|
77
100
|
*
|
|
@@ -121,4 +144,4 @@ declare function metaElementsToObject(metaElements: Array<React.JSX.IntrinsicEle
|
|
|
121
144
|
*/
|
|
122
145
|
declare function createStackClient<TPlugins extends Record<string, ClientPlugin<any, any>>, TRoutes extends PluginRoutes<TPlugins> = PluginRoutes<TPlugins>>(config: ClientLibConfig<TPlugins>): ClientLib<TRoutes>;
|
|
123
146
|
|
|
124
|
-
export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient, metaElementsToObject, sitemapEntryToXmlString };
|
|
147
|
+
export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient, metaElementsToObject, normalizePath, sitemapEntryToXmlString };
|
package/dist/client/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createRouter } from '@btst/yar';
|
|
2
2
|
export { sitemapEntryToXmlString } from './sitemap-utils.mjs';
|
|
3
3
|
export { metaElementsToObject } from './meta-utils.mjs';
|
|
4
|
+
export { normalizePath } from './path-utils.mjs';
|
|
4
5
|
|
|
5
6
|
function createStackClient(config) {
|
|
6
7
|
const { plugins } = config;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function normalizePath(path) {
|
|
4
|
+
if (!path) {
|
|
5
|
+
return "/";
|
|
6
|
+
}
|
|
7
|
+
if (Array.isArray(path)) {
|
|
8
|
+
const segments2 = path.filter(Boolean);
|
|
9
|
+
return segments2.length > 0 ? `/${segments2.join("/")}` : "/";
|
|
10
|
+
}
|
|
11
|
+
const segments = path.split("/").filter(Boolean);
|
|
12
|
+
return segments.length > 0 ? `/${segments.join("/")}` : "/";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
exports.normalizePath = normalizePath;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function normalizePath(path) {
|
|
2
|
+
if (!path) {
|
|
3
|
+
return "/";
|
|
4
|
+
}
|
|
5
|
+
if (Array.isArray(path)) {
|
|
6
|
+
const segments2 = path.filter(Boolean);
|
|
7
|
+
return segments2.length > 0 ? `/${segments2.join("/")}` : "/";
|
|
8
|
+
}
|
|
9
|
+
const segments = path.split("/").filter(Boolean);
|
|
10
|
+
return segments.length > 0 ? `/${segments.join("/")}` : "/";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { normalizePath };
|
package/dist/index.cjs
CHANGED
package/dist/index.d.cts
CHANGED
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const betterCall = require('better-call');
|
|
4
4
|
const db = require('@btst/db');
|
|
5
|
-
const node = require('better-call/node');
|
|
6
5
|
|
|
7
6
|
function defineBackendPlugin(plugin) {
|
|
8
7
|
return plugin;
|
|
@@ -11,5 +10,4 @@ function defineBackendPlugin(plugin) {
|
|
|
11
10
|
exports.createEndpoint = betterCall.createEndpoint;
|
|
12
11
|
exports.createRouter = betterCall.createRouter;
|
|
13
12
|
exports.createDbPlugin = db.createDbPlugin;
|
|
14
|
-
exports.toNodeHandler = node.toNodeHandler;
|
|
15
13
|
exports.defineBackendPlugin = defineBackendPlugin;
|
|
@@ -3,7 +3,6 @@ export { C as ClientPlugin } from '../../shared/stack.ByOugz9d.cjs';
|
|
|
3
3
|
import { Endpoint } from 'better-call';
|
|
4
4
|
export { Endpoint, Router, createEndpoint, createRouter } from 'better-call';
|
|
5
5
|
export { Adapter, DatabaseDefinition, DbPlugin, createDbPlugin } from '@btst/db';
|
|
6
|
-
export { toNodeHandler } from 'better-call/node';
|
|
7
6
|
import '@btst/yar';
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -3,7 +3,6 @@ export { C as ClientPlugin } from '../../shared/stack.ByOugz9d.mjs';
|
|
|
3
3
|
import { Endpoint } from 'better-call';
|
|
4
4
|
export { Endpoint, Router, createEndpoint, createRouter } from 'better-call';
|
|
5
5
|
export { Adapter, DatabaseDefinition, DbPlugin, createDbPlugin } from '@btst/db';
|
|
6
|
-
export { toNodeHandler } from 'better-call/node';
|
|
7
6
|
import '@btst/yar';
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -3,7 +3,6 @@ export { C as ClientPlugin } from '../../shared/stack.ByOugz9d.js';
|
|
|
3
3
|
import { Endpoint } from 'better-call';
|
|
4
4
|
export { Endpoint, Router, createEndpoint, createRouter } from 'better-call';
|
|
5
5
|
export { Adapter, DatabaseDefinition, DbPlugin, createDbPlugin } from '@btst/db';
|
|
6
|
-
export { toNodeHandler } from 'better-call/node';
|
|
7
6
|
import '@btst/yar';
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -2,6 +2,6 @@ export { B as BlogApiContext, c as BlogApiRouter, a as BlogBackendHooks, N as Ne
|
|
|
2
2
|
import '@btst/stack/plugins/api';
|
|
3
3
|
import 'better-call';
|
|
4
4
|
import 'zod';
|
|
5
|
-
import '../../../shared/stack.
|
|
5
|
+
import '../../../shared/stack.CoPoHVfV.cjs';
|
|
6
6
|
import '@tanstack/react-query';
|
|
7
7
|
import '@btst/stack/plugins/client';
|
|
@@ -2,6 +2,6 @@ export { B as BlogApiContext, c as BlogApiRouter, a as BlogBackendHooks, N as Ne
|
|
|
2
2
|
import '@btst/stack/plugins/api';
|
|
3
3
|
import 'better-call';
|
|
4
4
|
import 'zod';
|
|
5
|
-
import '../../../shared/stack.
|
|
5
|
+
import '../../../shared/stack.CoPoHVfV.mjs';
|
|
6
6
|
import '@tanstack/react-query';
|
|
7
7
|
import '@btst/stack/plugins/client';
|
|
@@ -2,6 +2,6 @@ export { B as BlogApiContext, c as BlogApiRouter, a as BlogBackendHooks, N as Ne
|
|
|
2
2
|
import '@btst/stack/plugins/api';
|
|
3
3
|
import 'better-call';
|
|
4
4
|
import 'zod';
|
|
5
|
-
import '../../../shared/stack.
|
|
5
|
+
import '../../../shared/stack.CoPoHVfV.js';
|
|
6
6
|
import '@tanstack/react-query';
|
|
7
7
|
import '@btst/stack/plugins/client';
|
|
@@ -10,12 +10,12 @@ function BetterBlogAttribution() {
|
|
|
10
10
|
"a",
|
|
11
11
|
{
|
|
12
12
|
className: "flex items-center gap-1 font-semibold underline",
|
|
13
|
-
href: "https://www.
|
|
13
|
+
href: "https://www.better-stack.ai",
|
|
14
14
|
target: "_blank",
|
|
15
15
|
rel: "noreferrer noopener",
|
|
16
|
-
"aria-label": "Better
|
|
17
|
-
title: "Better
|
|
18
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cursor-pointer", children: "
|
|
16
|
+
"aria-label": "Better Stack \u2014 Composable full-stack plugin system for React frameworks",
|
|
17
|
+
title: "Better Stack \u2014 Composable full-stack plugin system for React frameworks",
|
|
18
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cursor-pointer", children: "Better-Stack" })
|
|
19
19
|
}
|
|
20
20
|
)
|
|
21
21
|
] }) });
|
|
@@ -8,12 +8,12 @@ function BetterBlogAttribution() {
|
|
|
8
8
|
"a",
|
|
9
9
|
{
|
|
10
10
|
className: "flex items-center gap-1 font-semibold underline",
|
|
11
|
-
href: "https://www.
|
|
11
|
+
href: "https://www.better-stack.ai",
|
|
12
12
|
target: "_blank",
|
|
13
13
|
rel: "noreferrer noopener",
|
|
14
|
-
"aria-label": "Better
|
|
15
|
-
title: "Better
|
|
16
|
-
children: /* @__PURE__ */ jsx("span", { className: "cursor-pointer", children: "
|
|
14
|
+
"aria-label": "Better Stack \u2014 Composable full-stack plugin system for React frameworks",
|
|
15
|
+
title: "Better Stack \u2014 Composable full-stack plugin system for React frameworks",
|
|
16
|
+
children: /* @__PURE__ */ jsx("span", { className: "cursor-pointer", children: "Better-Stack" })
|
|
17
17
|
}
|
|
18
18
|
)
|
|
19
19
|
] }) });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.
|
|
2
|
+
import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.CoPoHVfV.cjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
interface UsePostsOptions {
|
|
@@ -81,8 +81,8 @@ declare function useSuspenseTags(): {
|
|
|
81
81
|
};
|
|
82
82
|
/** Create a new post */
|
|
83
83
|
declare function useCreatePost(): _tanstack_react_query.UseMutationResult<SerializedPost | null, Error, {
|
|
84
|
-
title: string;
|
|
85
84
|
published: boolean;
|
|
85
|
+
title: string;
|
|
86
86
|
content: string;
|
|
87
87
|
excerpt: string;
|
|
88
88
|
tags: ({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.
|
|
2
|
+
import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.CoPoHVfV.mjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
interface UsePostsOptions {
|
|
@@ -81,8 +81,8 @@ declare function useSuspenseTags(): {
|
|
|
81
81
|
};
|
|
82
82
|
/** Create a new post */
|
|
83
83
|
declare function useCreatePost(): _tanstack_react_query.UseMutationResult<SerializedPost | null, Error, {
|
|
84
|
-
title: string;
|
|
85
84
|
published: boolean;
|
|
85
|
+
title: string;
|
|
86
86
|
content: string;
|
|
87
87
|
excerpt: string;
|
|
88
88
|
tags: ({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.
|
|
2
|
+
import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.CoPoHVfV.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
interface UsePostsOptions {
|
|
@@ -81,8 +81,8 @@ declare function useSuspenseTags(): {
|
|
|
81
81
|
};
|
|
82
82
|
/** Create a new post */
|
|
83
83
|
declare function useCreatePost(): _tanstack_react_query.UseMutationResult<SerializedPost | null, Error, {
|
|
84
|
-
title: string;
|
|
85
84
|
published: boolean;
|
|
85
|
+
title: string;
|
|
86
86
|
content: string;
|
|
87
87
|
excerpt: string;
|
|
88
88
|
tags: ({
|
|
@@ -2,7 +2,7 @@ import * as react from 'react';
|
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
import * as _btst_yar from '@btst/yar';
|
|
4
4
|
import { QueryClient } from '@tanstack/react-query';
|
|
5
|
-
import { P as Post, S as SerializedPost } from '../../../shared/stack.
|
|
5
|
+
import { P as Post, S as SerializedPost } from '../../../shared/stack.CoPoHVfV.cjs';
|
|
6
6
|
export { UsePostsOptions, UsePostsResult } from './hooks/index.cjs';
|
|
7
7
|
import 'zod';
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@ import * as react from 'react';
|
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
import * as _btst_yar from '@btst/yar';
|
|
4
4
|
import { QueryClient } from '@tanstack/react-query';
|
|
5
|
-
import { P as Post, S as SerializedPost } from '../../../shared/stack.
|
|
5
|
+
import { P as Post, S as SerializedPost } from '../../../shared/stack.CoPoHVfV.mjs';
|
|
6
6
|
export { UsePostsOptions, UsePostsResult } from './hooks/index.mjs';
|
|
7
7
|
import 'zod';
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@ import * as react from 'react';
|
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
import * as _btst_yar from '@btst/yar';
|
|
4
4
|
import { QueryClient } from '@tanstack/react-query';
|
|
5
|
-
import { P as Post, S as SerializedPost } from '../../../shared/stack.
|
|
5
|
+
import { P as Post, S as SerializedPost } from '../../../shared/stack.CoPoHVfV.js';
|
|
6
6
|
export { UsePostsOptions, UsePostsResult } from './hooks/index.js';
|
|
7
7
|
import 'zod';
|
|
8
8
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
2
2
|
import * as better_call from 'better-call';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { c as createPostSchema, u as updatePostSchema, P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../shared/stack.
|
|
4
|
+
import { c as createPostSchema, u as updatePostSchema, P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../shared/stack.CoPoHVfV.cjs';
|
|
5
5
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
6
6
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
7
7
|
|
|
@@ -172,12 +172,12 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
|
|
|
172
172
|
options: {
|
|
173
173
|
method: "POST";
|
|
174
174
|
body: z.ZodObject<{
|
|
175
|
-
title: z.ZodString;
|
|
176
175
|
slug: z.ZodOptional<z.ZodString>;
|
|
177
176
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
178
177
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
179
178
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
180
179
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
180
|
+
title: z.ZodString;
|
|
181
181
|
content: z.ZodString;
|
|
182
182
|
excerpt: z.ZodString;
|
|
183
183
|
image: z.ZodOptional<z.ZodString>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
2
2
|
import * as better_call from 'better-call';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { c as createPostSchema, u as updatePostSchema, P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../shared/stack.
|
|
4
|
+
import { c as createPostSchema, u as updatePostSchema, P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../shared/stack.CoPoHVfV.mjs';
|
|
5
5
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
6
6
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
7
7
|
|
|
@@ -172,12 +172,12 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
|
|
|
172
172
|
options: {
|
|
173
173
|
method: "POST";
|
|
174
174
|
body: z.ZodObject<{
|
|
175
|
-
title: z.ZodString;
|
|
176
175
|
slug: z.ZodOptional<z.ZodString>;
|
|
177
176
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
178
177
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
179
178
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
180
179
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
180
|
+
title: z.ZodString;
|
|
181
181
|
content: z.ZodString;
|
|
182
182
|
excerpt: z.ZodString;
|
|
183
183
|
image: z.ZodOptional<z.ZodString>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
2
2
|
import * as better_call from 'better-call';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { c as createPostSchema, u as updatePostSchema, P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../shared/stack.
|
|
4
|
+
import { c as createPostSchema, u as updatePostSchema, P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../shared/stack.CoPoHVfV.js';
|
|
5
5
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
6
6
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
7
7
|
|
|
@@ -172,12 +172,12 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
|
|
|
172
172
|
options: {
|
|
173
173
|
method: "POST";
|
|
174
174
|
body: z.ZodObject<{
|
|
175
|
-
title: z.ZodString;
|
|
176
175
|
slug: z.ZodOptional<z.ZodString>;
|
|
177
176
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
178
177
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
179
178
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
180
179
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
180
|
+
title: z.ZodString;
|
|
181
181
|
content: z.ZodString;
|
|
182
182
|
excerpt: z.ZodString;
|
|
183
183
|
image: z.ZodOptional<z.ZodString>;
|
package/package.json
CHANGED
package/src/api/index.ts
CHANGED
package/src/client/index.ts
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes path segments from framework route params into a consistent path string.
|
|
3
|
+
*
|
|
4
|
+
* Handles different framework param formats:
|
|
5
|
+
* - Next.js: `pathParams.all` (string[])
|
|
6
|
+
* - React Router: `params["*"]` (string)
|
|
7
|
+
* - TanStack Router: `params._splat` (string)
|
|
8
|
+
*
|
|
9
|
+
* @param path - Path segments as string, string array, or undefined
|
|
10
|
+
* @returns Normalized path string starting with "/" (or "/" for empty/undefined)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* // Next.js
|
|
15
|
+
* normalizePath(pathParams?.all) // ["blog", "post"] => "/blog/post"
|
|
16
|
+
*
|
|
17
|
+
* // React Router / TanStack Router
|
|
18
|
+
* normalizePath(params["*"]) // "blog/post" => "/blog/post"
|
|
19
|
+
* normalizePath(undefined) // => "/"
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function normalizePath(
|
|
23
|
+
path?: string | Array<string> | undefined,
|
|
24
|
+
): string {
|
|
25
|
+
if (!path) {
|
|
26
|
+
return "/";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (Array.isArray(path)) {
|
|
30
|
+
// Handle Next.js format: pathParams.all (string[])
|
|
31
|
+
const segments = path.filter(Boolean);
|
|
32
|
+
return segments.length > 0 ? `/${segments.join("/")}` : "/";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Handle React Router / TanStack Router format: params["*"] or params._splat (string)
|
|
36
|
+
const segments = path.split("/").filter(Boolean);
|
|
37
|
+
return segments.length > 0 ? `/${segments.join("/")}` : "/";
|
|
38
|
+
}
|
package/src/plugins/api/index.ts
CHANGED
|
@@ -24,7 +24,6 @@ export type { Adapter, DatabaseDefinition, DbPlugin } from "@btst/db";
|
|
|
24
24
|
export type { Endpoint, Router } from "better-call";
|
|
25
25
|
export { createEndpoint, createRouter } from "better-call";
|
|
26
26
|
export { createDbPlugin } from "@btst/db";
|
|
27
|
-
export { toNodeHandler } from "better-call/node";
|
|
28
27
|
|
|
29
28
|
/**
|
|
30
29
|
* Helper to define a backend plugin with full type inference
|
|
@@ -5,13 +5,13 @@ export function BetterBlogAttribution() {
|
|
|
5
5
|
Powered by{" "}
|
|
6
6
|
<a
|
|
7
7
|
className="flex items-center gap-1 font-semibold underline"
|
|
8
|
-
href="https://www.
|
|
8
|
+
href="https://www.better-stack.ai"
|
|
9
9
|
target="_blank"
|
|
10
10
|
rel="noreferrer noopener"
|
|
11
|
-
aria-label="Better
|
|
12
|
-
title="Better
|
|
11
|
+
aria-label="Better Stack — Composable full-stack plugin system for React frameworks"
|
|
12
|
+
title="Better Stack — Composable full-stack plugin system for React frameworks"
|
|
13
13
|
>
|
|
14
|
-
<span className="cursor-pointer">
|
|
14
|
+
<span className="cursor-pointer">Better-Stack</span>
|
|
15
15
|
</a>
|
|
16
16
|
</p>
|
|
17
17
|
</div>
|
|
@@ -35,12 +35,12 @@ interface SerializedTag extends Omit<Tag, "createdAt" | "updatedAt"> {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
declare const createPostSchema: z.ZodObject<{
|
|
38
|
-
title: z.ZodString;
|
|
39
38
|
slug: z.ZodOptional<z.ZodString>;
|
|
40
39
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
41
40
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
42
41
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
43
42
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
43
|
+
title: z.ZodString;
|
|
44
44
|
content: z.ZodString;
|
|
45
45
|
excerpt: z.ZodString;
|
|
46
46
|
image: z.ZodOptional<z.ZodString>;
|
|
@@ -35,12 +35,12 @@ interface SerializedTag extends Omit<Tag, "createdAt" | "updatedAt"> {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
declare const createPostSchema: z.ZodObject<{
|
|
38
|
-
title: z.ZodString;
|
|
39
38
|
slug: z.ZodOptional<z.ZodString>;
|
|
40
39
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
41
40
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
42
41
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
43
42
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
43
|
+
title: z.ZodString;
|
|
44
44
|
content: z.ZodString;
|
|
45
45
|
excerpt: z.ZodString;
|
|
46
46
|
image: z.ZodOptional<z.ZodString>;
|
|
@@ -35,12 +35,12 @@ interface SerializedTag extends Omit<Tag, "createdAt" | "updatedAt"> {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
declare const createPostSchema: z.ZodObject<{
|
|
38
|
-
title: z.ZodString;
|
|
39
38
|
slug: z.ZodOptional<z.ZodString>;
|
|
40
39
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
41
40
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
42
41
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
43
42
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
43
|
+
title: z.ZodString;
|
|
44
44
|
content: z.ZodString;
|
|
45
45
|
excerpt: z.ZodString;
|
|
46
46
|
image: z.ZodOptional<z.ZodString>;
|