@flyo/nitro-next 1.3.0 → 1.4.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 +39 -0
- package/dist/proxy.d.mts +4 -4
- package/dist/proxy.d.ts +4 -4
- package/dist/proxy.js +6 -7
- package/dist/proxy.js.map +1 -1
- package/dist/proxy.mjs +6 -7
- package/dist/proxy.mjs.map +1 -1
- package/dist/server.d.mts +23 -1
- package/dist/server.d.ts +23 -1
- package/dist/server.js +16 -0
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +15 -0
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @flyo/nitro-next
|
|
2
|
+
|
|
3
|
+
This directory contains the source code for the **@flyo/nitro-next** package - a Next.js integration library for connecting the Flyo Headless Content Hub into your Next.js projects.
|
|
4
|
+
|
|
5
|
+
## What's Included
|
|
6
|
+
|
|
7
|
+
- **Server Components**: Server-side rendering utilities for Flyo content
|
|
8
|
+
- **Client Components**: Client-side React components for interactive content
|
|
9
|
+
- **Proxy Utilities**: Image proxy and asset handling
|
|
10
|
+
- **Route Helpers**: Next.js App Router integration helpers for pages and entities
|
|
11
|
+
|
|
12
|
+
## Documentation
|
|
13
|
+
|
|
14
|
+
For complete documentation, installation instructions, and usage examples, please visit:
|
|
15
|
+
|
|
16
|
+
**https://github.com/flyocloud/nitro-next**
|
|
17
|
+
|
|
18
|
+
## Development
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Install dependencies
|
|
22
|
+
npm install
|
|
23
|
+
|
|
24
|
+
# Build the package
|
|
25
|
+
npm run build
|
|
26
|
+
|
|
27
|
+
# Run tests
|
|
28
|
+
npm test
|
|
29
|
+
|
|
30
|
+
# Development mode (watch)
|
|
31
|
+
npm run dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Package Structure
|
|
35
|
+
|
|
36
|
+
- `src/` - Source TypeScript files
|
|
37
|
+
- `dist/` - Built output (generated)
|
|
38
|
+
- `tsup.config.ts` - Build configuration
|
|
39
|
+
- `jest.config.js` - Test configuration
|
package/dist/proxy.d.mts
CHANGED
|
@@ -2,10 +2,10 @@ import { NextResponse } from 'next/server';
|
|
|
2
2
|
|
|
3
3
|
interface ProxyConfig {
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @default
|
|
5
|
+
* If live edit is enabled, caching is disabled
|
|
6
|
+
* @default false
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
liveEdit?: boolean;
|
|
9
9
|
/**
|
|
10
10
|
* Server/CDN cache TTL in seconds
|
|
11
11
|
* @default 1200
|
|
@@ -28,7 +28,7 @@ interface ProxyConfig {
|
|
|
28
28
|
* import { createProxy } from '@flyo/nitro-next/proxy';
|
|
29
29
|
*
|
|
30
30
|
* export default createProxy({
|
|
31
|
-
*
|
|
31
|
+
* liveEdit: false,
|
|
32
32
|
* serverCacheTtl: 1200,
|
|
33
33
|
* clientCacheTtl: 900,
|
|
34
34
|
* });
|
package/dist/proxy.d.ts
CHANGED
|
@@ -2,10 +2,10 @@ import { NextResponse } from 'next/server';
|
|
|
2
2
|
|
|
3
3
|
interface ProxyConfig {
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @default
|
|
5
|
+
* If live edit is enabled, caching is disabled
|
|
6
|
+
* @default false
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
liveEdit?: boolean;
|
|
9
9
|
/**
|
|
10
10
|
* Server/CDN cache TTL in seconds
|
|
11
11
|
* @default 1200
|
|
@@ -28,7 +28,7 @@ interface ProxyConfig {
|
|
|
28
28
|
* import { createProxy } from '@flyo/nitro-next/proxy';
|
|
29
29
|
*
|
|
30
30
|
* export default createProxy({
|
|
31
|
-
*
|
|
31
|
+
* liveEdit: false,
|
|
32
32
|
* serverCacheTtl: 1200,
|
|
33
33
|
* clientCacheTtl: 900,
|
|
34
34
|
* });
|
package/dist/proxy.js
CHANGED
|
@@ -27,24 +27,23 @@ module.exports = __toCommonJS(proxy_exports);
|
|
|
27
27
|
var import_server = require("next/server");
|
|
28
28
|
function createProxy(config2 = {}) {
|
|
29
29
|
const {
|
|
30
|
-
|
|
30
|
+
liveEdit = false,
|
|
31
31
|
serverCacheTtl = 1200,
|
|
32
32
|
clientCacheTtl = 900
|
|
33
33
|
} = config2;
|
|
34
34
|
return function proxy() {
|
|
35
35
|
const res = import_server.NextResponse.next();
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
if (liveEdit) {
|
|
37
|
+
res.headers.set("Vercel-CDN-Cache-Control", "no-store");
|
|
38
|
+
res.headers.set("CDN-Cache-Control", "no-store");
|
|
39
|
+
res.headers.set("Cache-Control", "no-store");
|
|
40
|
+
} else {
|
|
38
41
|
const cdn = serverCacheTtl > 0 ? `max-age=${serverCacheTtl}` : "no-store";
|
|
39
42
|
res.headers.set("Vercel-CDN-Cache-Control", cdn);
|
|
40
43
|
res.headers.set("CDN-Cache-Control", cdn);
|
|
41
44
|
if (clientCacheTtl > 0) {
|
|
42
45
|
res.headers.set("Cache-Control", `max-age=${clientCacheTtl}`);
|
|
43
46
|
}
|
|
44
|
-
} else {
|
|
45
|
-
res.headers.set("Vercel-CDN-Cache-Control", "no-store");
|
|
46
|
-
res.headers.set("CDN-Cache-Control", "no-store");
|
|
47
|
-
res.headers.set("Cache-Control", "no-store");
|
|
48
47
|
}
|
|
49
48
|
return res;
|
|
50
49
|
};
|
package/dist/proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\n\nexport interface ProxyConfig {\n /**\n *
|
|
1
|
+
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\n\nexport interface ProxyConfig {\n /**\n * If live edit is enabled, caching is disabled\n * @default false\n */\n liveEdit?: boolean;\n /**\n * Server/CDN cache TTL in seconds\n * @default 1200\n */\n serverCacheTtl?: number;\n /**\n * Client browser cache TTL in seconds\n * @default 900\n */\n clientCacheTtl?: number;\n}\n\n/**\n * Nitro Next.js Proxy Factory\n * \n * Creates a Next.js middleware that handles cache control headers.\n * \n * @example\n * ```ts\n * // proxy.ts (project root or src/)\n * import { createProxy } from '@flyo/nitro-next/proxy';\n * \n * export default createProxy({\n * liveEdit: false,\n * serverCacheTtl: 1200,\n * clientCacheTtl: 900,\n * });\n * \n * // Next.js requires config to be defined directly in this file\n * export const config = {\n * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],\n * };\n * ```\n */\nexport function createProxy(config: ProxyConfig = {}) {\n const {\n liveEdit = false,\n serverCacheTtl = 1200,\n clientCacheTtl = 900,\n } = config;\n\n return function proxy() {\n const res = NextResponse.next();\n\n if (liveEdit) {\n // Development or live edit mode - no caching\n res.headers.set('Vercel-CDN-Cache-Control', 'no-store');\n res.headers.set('CDN-Cache-Control', 'no-store');\n res.headers.set('Cache-Control', 'no-store');\n } else {\n // Production with caching enabled\n const cdn = serverCacheTtl > 0 ? `max-age=${serverCacheTtl}` : 'no-store';\n res.headers.set('Vercel-CDN-Cache-Control', cdn);\n res.headers.set('CDN-Cache-Control', cdn);\n\n if (clientCacheTtl > 0) {\n res.headers.set('Cache-Control', `max-age=${clientCacheTtl}`);\n }\n }\n\n return res;\n };\n}\n\n\n/**\n * Proxy matcher configuration\n * Applies to all routes except Next.js internal routes\n */\nexport const config = {\n matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6B;AA0CtB,SAAS,YAAYA,UAAsB,CAAC,GAAG;AACpD,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB,IAAIA;AAEJ,SAAO,SAAS,QAAQ;AACtB,UAAM,MAAM,2BAAa,KAAK;AAE9B,QAAI,UAAU;AAEZ,UAAI,QAAQ,IAAI,4BAA4B,UAAU;AACtD,UAAI,QAAQ,IAAI,qBAAqB,UAAU;AAC/C,UAAI,QAAQ,IAAI,iBAAiB,UAAU;AAAA,IAC7C,OAAO;AAEL,YAAM,MAAM,iBAAiB,IAAI,WAAW,cAAc,KAAK;AAC/D,UAAI,QAAQ,IAAI,4BAA4B,GAAG;AAC/C,UAAI,QAAQ,IAAI,qBAAqB,GAAG;AAExC,UAAI,iBAAiB,GAAG;AACtB,YAAI,QAAQ,IAAI,iBAAiB,WAAW,cAAc,EAAE;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAOO,IAAM,SAAS;AAAA,EACpB,SAAS,CAAC,+CAA+C;AAC3D;","names":["config"]}
|
package/dist/proxy.mjs
CHANGED
|
@@ -2,24 +2,23 @@
|
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
3
|
function createProxy(config2 = {}) {
|
|
4
4
|
const {
|
|
5
|
-
|
|
5
|
+
liveEdit = false,
|
|
6
6
|
serverCacheTtl = 1200,
|
|
7
7
|
clientCacheTtl = 900
|
|
8
8
|
} = config2;
|
|
9
9
|
return function proxy() {
|
|
10
10
|
const res = NextResponse.next();
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if (liveEdit) {
|
|
12
|
+
res.headers.set("Vercel-CDN-Cache-Control", "no-store");
|
|
13
|
+
res.headers.set("CDN-Cache-Control", "no-store");
|
|
14
|
+
res.headers.set("Cache-Control", "no-store");
|
|
15
|
+
} else {
|
|
13
16
|
const cdn = serverCacheTtl > 0 ? `max-age=${serverCacheTtl}` : "no-store";
|
|
14
17
|
res.headers.set("Vercel-CDN-Cache-Control", cdn);
|
|
15
18
|
res.headers.set("CDN-Cache-Control", cdn);
|
|
16
19
|
if (clientCacheTtl > 0) {
|
|
17
20
|
res.headers.set("Cache-Control", `max-age=${clientCacheTtl}`);
|
|
18
21
|
}
|
|
19
|
-
} else {
|
|
20
|
-
res.headers.set("Vercel-CDN-Cache-Control", "no-store");
|
|
21
|
-
res.headers.set("CDN-Cache-Control", "no-store");
|
|
22
|
-
res.headers.set("Cache-Control", "no-store");
|
|
23
22
|
}
|
|
24
23
|
return res;
|
|
25
24
|
};
|
package/dist/proxy.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\n\nexport interface ProxyConfig {\n /**\n *
|
|
1
|
+
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\n\nexport interface ProxyConfig {\n /**\n * If live edit is enabled, caching is disabled\n * @default false\n */\n liveEdit?: boolean;\n /**\n * Server/CDN cache TTL in seconds\n * @default 1200\n */\n serverCacheTtl?: number;\n /**\n * Client browser cache TTL in seconds\n * @default 900\n */\n clientCacheTtl?: number;\n}\n\n/**\n * Nitro Next.js Proxy Factory\n * \n * Creates a Next.js middleware that handles cache control headers.\n * \n * @example\n * ```ts\n * // proxy.ts (project root or src/)\n * import { createProxy } from '@flyo/nitro-next/proxy';\n * \n * export default createProxy({\n * liveEdit: false,\n * serverCacheTtl: 1200,\n * clientCacheTtl: 900,\n * });\n * \n * // Next.js requires config to be defined directly in this file\n * export const config = {\n * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],\n * };\n * ```\n */\nexport function createProxy(config: ProxyConfig = {}) {\n const {\n liveEdit = false,\n serverCacheTtl = 1200,\n clientCacheTtl = 900,\n } = config;\n\n return function proxy() {\n const res = NextResponse.next();\n\n if (liveEdit) {\n // Development or live edit mode - no caching\n res.headers.set('Vercel-CDN-Cache-Control', 'no-store');\n res.headers.set('CDN-Cache-Control', 'no-store');\n res.headers.set('Cache-Control', 'no-store');\n } else {\n // Production with caching enabled\n const cdn = serverCacheTtl > 0 ? `max-age=${serverCacheTtl}` : 'no-store';\n res.headers.set('Vercel-CDN-Cache-Control', cdn);\n res.headers.set('CDN-Cache-Control', cdn);\n\n if (clientCacheTtl > 0) {\n res.headers.set('Cache-Control', `max-age=${clientCacheTtl}`);\n }\n }\n\n return res;\n };\n}\n\n\n/**\n * Proxy matcher configuration\n * Applies to all routes except Next.js internal routes\n */\nexport const config = {\n matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],\n};\n"],"mappings":";AAAA,SAAS,oBAAoB;AA0CtB,SAAS,YAAYA,UAAsB,CAAC,GAAG;AACpD,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB,IAAIA;AAEJ,SAAO,SAAS,QAAQ;AACtB,UAAM,MAAM,aAAa,KAAK;AAE9B,QAAI,UAAU;AAEZ,UAAI,QAAQ,IAAI,4BAA4B,UAAU;AACtD,UAAI,QAAQ,IAAI,qBAAqB,UAAU;AAC/C,UAAI,QAAQ,IAAI,iBAAiB,UAAU;AAAA,IAC7C,OAAO;AAEL,YAAM,MAAM,iBAAiB,IAAI,WAAW,cAAc,KAAK;AAC/D,UAAI,QAAQ,IAAI,4BAA4B,GAAG;AAC/C,UAAI,QAAQ,IAAI,qBAAqB,GAAG;AAExC,UAAI,iBAAiB,GAAG;AACtB,YAAI,QAAQ,IAAI,iBAAiB,WAAW,cAAc,EAAE;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAOO,IAAM,SAAS;AAAA,EACpB,SAAS,CAAC,+CAA+C;AAC3D;","names":["config"]}
|
package/dist/server.d.mts
CHANGED
|
@@ -70,6 +70,28 @@ declare function NitroPage({ page, }: {
|
|
|
70
70
|
declare function NitroBlock({ block, }: {
|
|
71
71
|
block: Block;
|
|
72
72
|
}): react_jsx_runtime.JSX.Element | null;
|
|
73
|
+
/**
|
|
74
|
+
* NitroSlot component renders nested blocks from a slot
|
|
75
|
+
* Used for recursive block rendering when blocks contain slots
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```tsx
|
|
79
|
+
* import { NitroSlot } from '@flyo/nitro-next/server';
|
|
80
|
+
*
|
|
81
|
+
* export default function MyComponent({ block }) {
|
|
82
|
+
* return (
|
|
83
|
+
* <div>
|
|
84
|
+
* <NitroSlot slot={block.slots.mysuperslotname} />
|
|
85
|
+
* </div>
|
|
86
|
+
* );
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
declare function NitroSlot({ slot, }: {
|
|
91
|
+
slot?: {
|
|
92
|
+
content?: Block[];
|
|
93
|
+
};
|
|
94
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
73
95
|
/**
|
|
74
96
|
* Default page route handler for Nitro pages
|
|
75
97
|
* Can be re-exported directly from Next.js app routes
|
|
@@ -170,4 +192,4 @@ declare function nitroEntityGenerateMetadata<T = any>(props: EntityRouteParams<T
|
|
|
170
192
|
resolver: EntityResolver<T>;
|
|
171
193
|
}): Promise<Metadata>;
|
|
172
194
|
|
|
173
|
-
export { type EntityResolver, NitroBlock, NitroPage, type NitroState, getNitro, getNitroConfig, getNitroEntities, getNitroPages, globalNitroState, initNitro, nitroEntityGenerateMetadata, nitroEntityRoute, nitroPageGenerateMetadata, nitroPageGenerateStaticParams, nitroPageRoute };
|
|
195
|
+
export { type EntityResolver, NitroBlock, NitroPage, NitroSlot, type NitroState, getNitro, getNitroConfig, getNitroEntities, getNitroPages, globalNitroState, initNitro, nitroEntityGenerateMetadata, nitroEntityRoute, nitroPageGenerateMetadata, nitroPageGenerateStaticParams, nitroPageRoute };
|
package/dist/server.d.ts
CHANGED
|
@@ -70,6 +70,28 @@ declare function NitroPage({ page, }: {
|
|
|
70
70
|
declare function NitroBlock({ block, }: {
|
|
71
71
|
block: Block;
|
|
72
72
|
}): react_jsx_runtime.JSX.Element | null;
|
|
73
|
+
/**
|
|
74
|
+
* NitroSlot component renders nested blocks from a slot
|
|
75
|
+
* Used for recursive block rendering when blocks contain slots
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```tsx
|
|
79
|
+
* import { NitroSlot } from '@flyo/nitro-next/server';
|
|
80
|
+
*
|
|
81
|
+
* export default function MyComponent({ block }) {
|
|
82
|
+
* return (
|
|
83
|
+
* <div>
|
|
84
|
+
* <NitroSlot slot={block.slots.mysuperslotname} />
|
|
85
|
+
* </div>
|
|
86
|
+
* );
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
declare function NitroSlot({ slot, }: {
|
|
91
|
+
slot?: {
|
|
92
|
+
content?: Block[];
|
|
93
|
+
};
|
|
94
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
73
95
|
/**
|
|
74
96
|
* Default page route handler for Nitro pages
|
|
75
97
|
* Can be re-exported directly from Next.js app routes
|
|
@@ -170,4 +192,4 @@ declare function nitroEntityGenerateMetadata<T = any>(props: EntityRouteParams<T
|
|
|
170
192
|
resolver: EntityResolver<T>;
|
|
171
193
|
}): Promise<Metadata>;
|
|
172
194
|
|
|
173
|
-
export { type EntityResolver, NitroBlock, NitroPage, type NitroState, getNitro, getNitroConfig, getNitroEntities, getNitroPages, globalNitroState, initNitro, nitroEntityGenerateMetadata, nitroEntityRoute, nitroPageGenerateMetadata, nitroPageGenerateStaticParams, nitroPageRoute };
|
|
195
|
+
export { type EntityResolver, NitroBlock, NitroPage, NitroSlot, type NitroState, getNitro, getNitroConfig, getNitroEntities, getNitroPages, globalNitroState, initNitro, nitroEntityGenerateMetadata, nitroEntityRoute, nitroPageGenerateMetadata, nitroPageGenerateStaticParams, nitroPageRoute };
|
package/dist/server.js
CHANGED
|
@@ -22,6 +22,7 @@ var server_exports = {};
|
|
|
22
22
|
__export(server_exports, {
|
|
23
23
|
NitroBlock: () => NitroBlock,
|
|
24
24
|
NitroPage: () => NitroPage,
|
|
25
|
+
NitroSlot: () => NitroSlot,
|
|
25
26
|
getNitro: () => getNitro,
|
|
26
27
|
getNitroConfig: () => getNitroConfig,
|
|
27
28
|
getNitroEntities: () => getNitroEntities,
|
|
@@ -142,6 +143,20 @@ function NitroBlock({
|
|
|
142
143
|
}
|
|
143
144
|
return null;
|
|
144
145
|
}
|
|
146
|
+
function NitroSlot({
|
|
147
|
+
slot
|
|
148
|
+
}) {
|
|
149
|
+
if (!slot?.content || !Array.isArray(slot.content)) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: slot.content.map((block, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
153
|
+
NitroBlock,
|
|
154
|
+
{
|
|
155
|
+
block
|
|
156
|
+
},
|
|
157
|
+
block.uid || index
|
|
158
|
+
)) });
|
|
159
|
+
}
|
|
145
160
|
async function nitroPageRoute(props) {
|
|
146
161
|
const { page } = await resolveNitroRoute(props);
|
|
147
162
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NitroPage, { page });
|
|
@@ -213,6 +228,7 @@ async function nitroEntityGenerateMetadata(props, options) {
|
|
|
213
228
|
0 && (module.exports = {
|
|
214
229
|
NitroBlock,
|
|
215
230
|
NitroPage,
|
|
231
|
+
NitroSlot,
|
|
216
232
|
getNitro,
|
|
217
233
|
getNitroConfig,
|
|
218
234
|
getNitroEntities,
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.tsx"],"sourcesContent":["import { cache } from 'react';\nimport type { Metadata } from 'next';\nimport { notFound } from 'next/navigation';\nimport {\n Page,\n Block,\n Entity,\n ConfigApi,\n ConfigResponse,\n Configuration,\n PagesApi,\n EntitiesApi\n} from '@flyo/nitro-typescript';\n\n/**\n * Interface for Nitro configuration state\n */\nexport interface NitroState {\n configuration: Configuration | null;\n lang: string | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n components: Record<string, any>;\n showMissingComponentAlert: boolean;\n liveEdit: boolean;\n}\n\n/**\n * Global Nitro state - shared across server and middleware\n */\nexport const globalNitroState: NitroState = {\n configuration: null,\n lang: null,\n components: {},\n showMissingComponentAlert: false,\n liveEdit: false\n};\n\n/**\n * Access the Nitro configuration state\n * Can be used anywhere: server components, middlewares, API routes, etc.\n * Must be called after initNitro() has been initialized.\n * \n * @throws {Error} If Nitro has not been initialized with initNitro()\n * \n * @example\n * ```ts\n * const state = getNitro();\n * const { configuration, lang, components } = state;\n * ```\n */\nexport function getNitro(): NitroState {\n if (!globalNitroState.configuration) {\n throw new Error('Nitro has not been initialized. Make sure to call initNitro() first.');\n }\n return globalNitroState;\n}\n\nexport const initNitro = ({\n accessToken,\n lang,\n components,\n showMissingComponentAlert,\n liveEdit,\n}: {\n accessToken: string;\n lang?: string;\n components?: object;\n showMissingComponentAlert?: boolean;\n liveEdit?: boolean;\n}): ( () => Configuration ) => {\n\n if (!globalNitroState.configuration) {\n globalNitroState.configuration = new Configuration({\n apiKey: accessToken,\n });\n }\n\n globalNitroState.lang = lang ?? null;\n globalNitroState.components = components ?? {};\n globalNitroState.showMissingComponentAlert = showMissingComponentAlert ?? liveEdit ?? false;\n globalNitroState.liveEdit = liveEdit ?? false;\n\n return () => globalNitroState.configuration!;\n}\n\nexport const getNitroConfig = cache(async (): Promise<ConfigResponse> => {\n const state = getNitro();\n\n const configApi = new ConfigApi(state.configuration!);\n const useLang = state.lang ?? undefined;\n\n const config = await configApi.config({ lang: useLang });\n \n return config;\n});\n\nexport function getNitroPages(): PagesApi {\n return new PagesApi(getNitro().configuration!);\n}\n\nexport function getNitroEntities(): EntitiesApi {\n return new EntitiesApi(getNitro().configuration!);\n}\n\n/**\n * Route params type for Next.js catch-all routes\n */\ntype RouteParams = {\n params: Promise<{ slug?: string[] }>;\n};\n\n/**\n * Generic route params type for entity routes\n * Allows any param structure from Next.js app router\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EntityRouteParams<T = any> = {\n params: Promise<T>;\n};\n\n/**\n * Internal helper to resolve Nitro page from route params\n * Uses React cache to avoid duplicate fetching\n */\nconst resolveNitroRoute = cache(async ({ params }: RouteParams) => {\n const { slug } = await params;\n const path = slug?.join('/') ?? '';\n\n const cfg = await getNitroConfig();\n\n if (!cfg.pages?.includes(path)) {\n notFound();\n }\n\n const page = await getNitroPages()\n .page({ slug: path })\n .catch((error: unknown) => {\n console.error('Error fetching page:', path, error);\n notFound();\n });\n\n if (!page) {\n notFound();\n }\n\n return { page, path, cfg };\n});\n\n/**\n * Entity resolver function type\n * Users provide this to resolve entities from their route params\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type EntityResolver<T = any> = (params: Promise<T>) => Promise<Entity>;\n\n/**\n * Internal helper to wrap and cache entity resolvers\n * Ensures the resolver is only called once per unique params\n */\nfunction createCachedEntityResolver<T>(\n resolver: EntityResolver<T>\n): (props: EntityRouteParams<T>) => Promise<Entity> {\n return cache(async ({ params }: EntityRouteParams<T>) => {\n const entity = await resolver(params);\n \n if (!entity) {\n notFound();\n }\n \n return entity;\n });\n}\n\n\n/**\n * NitroPage component renders all blocks from a Flyo page\n */\nexport function NitroPage({\n page,\n}: {\n page: Page\n}) {\n if (!page?.json || !Array.isArray(page.json)) {\n return null;\n }\n\n return (\n <>\n {page.json.map((block: Block, index: number) => (\n <NitroBlock\n key={block.uid || index}\n block={block}\n />\n ))}\n </>\n );\n}\n\nexport function NitroBlock({\n block,\n}: {\n block: Block\n}) {\n if (!block) {\n return null;\n }\n\n const state = getNitro();\n const Component = block.component ? state.components[block.component] : undefined;\n\n if (Component) {\n return <Component block={block} />;\n }\n\n if (state.showMissingComponentAlert) {\n return (\n <div style={{ border: '1px solid #fff', padding: '1rem', marginBottom: '1rem', backgroundColor: 'red' }}>\n Component <b>{block.component}</b> not found.\n </div>\n );\n }\n\n return null;\n}\n\n/**\n * Default page route handler for Nitro pages\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageRoute as default } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageRoute(props: RouteParams) {\n const { page } = await resolveNitroRoute(props);\n return <NitroPage page={page} />;\n}\n\n/**\n * Generate metadata for Nitro pages\n * Provides basic meta tags based on Flyo page data\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageGenerateMetadata as generateMetadata } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageGenerateMetadata(\n props: RouteParams\n): Promise<Metadata> {\n const { page } = await resolveNitroRoute(props);\n\n // Extract meta information from page\n const meta = page.meta_json;\n \n const title = meta?.title ?? page.title ?? 'Page';\n const description = meta?.description ?? '';\n const image = meta?.image ?? '';\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n images: image ? [image] : [],\n type: 'website',\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : [],\n },\n };\n}\n\n/**\n * Generate static params for all Nitro pages\n * Enables static site generation (SSG) for all pages\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageGenerateStaticParams as generateStaticParams } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageGenerateStaticParams() {\n const cfg = await getNitroConfig();\n const pages = cfg.pages ?? [];\n\n return pages.map((path: string) => ({\n slug: path === '' ? undefined : path.split('/'),\n }));\n}\n\n/**\n * Default entity route handler with custom resolver\n * Flexible solution that works with any route param structure\n * \n * @example\n * ```ts\n * // app/blog/[slug]/page.tsx\n * const resolver = async (params: Promise<{ slug: string }>) => {\n * const { slug } = await params;\n * return getNitroEntities().entityBySlug({ slug, typeId: 123 });\n * };\n * \n * export default (props) => nitroEntityRoute(props, {\n * resolver,\n * render: (entity) => <h1>{entity.entity?.entity_title}</h1>\n * });\n * ```\n * \n * @example\n * ```ts\n * // app/items/[uniqueid]/page.tsx\n * const resolver = async (params: Promise<{ uniqueid: string }>) => {\n * const { uniqueid } = await params;\n * return getNitroEntities().entityByUniqueid({ uniqueid });\n * };\n * \n * export default (props) => nitroEntityRoute(props, { resolver });\n * ```\n * \n * @example\n * ```ts\n * // app/custom/[whatever]/page.tsx\n * const resolver = async (params: Promise<{ whatever: string }>) => {\n * const { whatever } = await params;\n * return getNitroEntities().entityBySlug({ slug: whatever });\n * };\n * \n * export default (props) => nitroEntityRoute(props, { resolver });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function nitroEntityRoute<T = any>(\n props: EntityRouteParams<T>,\n options: {\n resolver: EntityResolver<T>;\n render?: (entity: Entity) => React.ReactNode;\n }\n) {\n const cachedResolver = createCachedEntityResolver(options.resolver);\n \n return (async () => {\n const entity = await cachedResolver(props);\n \n if (options.render) {\n return options.render(entity);\n }\n\n // Default simple render - users should provide their own render function\n return <div>{entity.entity?.entity_title}</div>;\n })();\n}\n\n/**\n * Generate metadata for Nitro entities with custom resolver\n * Works with any route param structure\n * \n * @example\n * ```ts\n * // app/blog/[slug]/page.tsx\n * const resolver = async (params: Promise<{ slug: string }>) => {\n * const { slug } = await params;\n * return getNitroEntities().entityBySlug({ slug, typeId: 123 });\n * };\n * \n * export const generateMetadata = (props) => nitroEntityGenerateMetadata(props, { resolver });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function nitroEntityGenerateMetadata<T = any>(\n props: EntityRouteParams<T>,\n options: {\n resolver: EntityResolver<T>;\n }\n): Promise<Metadata> {\n const cachedResolver = createCachedEntityResolver(options.resolver);\n const entity = await cachedResolver(props);\n\n const title = entity.entity?.entity_title ?? 'Entity';\n const description = entity.entity?.entity_teaser ?? '';\n const image = entity.entity?.entity_image ?? '';\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n images: image ? [image] : [],\n type: 'website',\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : [],\n },\n };\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.tsx"],"sourcesContent":["import { cache } from 'react';\nimport type { Metadata } from 'next';\nimport { notFound } from 'next/navigation';\nimport {\n Page,\n Block,\n Entity,\n ConfigApi,\n ConfigResponse,\n Configuration,\n PagesApi,\n EntitiesApi\n} from '@flyo/nitro-typescript';\n\n/**\n * Interface for Nitro configuration state\n */\nexport interface NitroState {\n configuration: Configuration | null;\n lang: string | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n components: Record<string, any>;\n showMissingComponentAlert: boolean;\n liveEdit: boolean;\n}\n\n/**\n * Global Nitro state - shared across server and middleware\n */\nexport const globalNitroState: NitroState = {\n configuration: null,\n lang: null,\n components: {},\n showMissingComponentAlert: false,\n liveEdit: false\n};\n\n/**\n * Access the Nitro configuration state\n * Can be used anywhere: server components, middlewares, API routes, etc.\n * Must be called after initNitro() has been initialized.\n * \n * @throws {Error} If Nitro has not been initialized with initNitro()\n * \n * @example\n * ```ts\n * const state = getNitro();\n * const { configuration, lang, components } = state;\n * ```\n */\nexport function getNitro(): NitroState {\n if (!globalNitroState.configuration) {\n throw new Error('Nitro has not been initialized. Make sure to call initNitro() first.');\n }\n return globalNitroState;\n}\n\nexport const initNitro = ({\n accessToken,\n lang,\n components,\n showMissingComponentAlert,\n liveEdit,\n}: {\n accessToken: string;\n lang?: string;\n components?: object;\n showMissingComponentAlert?: boolean;\n liveEdit?: boolean;\n}): ( () => Configuration ) => {\n\n if (!globalNitroState.configuration) {\n globalNitroState.configuration = new Configuration({\n apiKey: accessToken,\n });\n }\n\n globalNitroState.lang = lang ?? null;\n globalNitroState.components = components ?? {};\n globalNitroState.showMissingComponentAlert = showMissingComponentAlert ?? liveEdit ?? false;\n globalNitroState.liveEdit = liveEdit ?? false;\n\n return () => globalNitroState.configuration!;\n}\n\nexport const getNitroConfig = cache(async (): Promise<ConfigResponse> => {\n const state = getNitro();\n\n const configApi = new ConfigApi(state.configuration!);\n const useLang = state.lang ?? undefined;\n\n const config = await configApi.config({ lang: useLang });\n \n return config;\n});\n\nexport function getNitroPages(): PagesApi {\n return new PagesApi(getNitro().configuration!);\n}\n\nexport function getNitroEntities(): EntitiesApi {\n return new EntitiesApi(getNitro().configuration!);\n}\n\n/**\n * Route params type for Next.js catch-all routes\n */\ntype RouteParams = {\n params: Promise<{ slug?: string[] }>;\n};\n\n/**\n * Generic route params type for entity routes\n * Allows any param structure from Next.js app router\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EntityRouteParams<T = any> = {\n params: Promise<T>;\n};\n\n/**\n * Internal helper to resolve Nitro page from route params\n * Uses React cache to avoid duplicate fetching\n */\nconst resolveNitroRoute = cache(async ({ params }: RouteParams) => {\n const { slug } = await params;\n const path = slug?.join('/') ?? '';\n\n const cfg = await getNitroConfig();\n\n if (!cfg.pages?.includes(path)) {\n notFound();\n }\n\n const page = await getNitroPages()\n .page({ slug: path })\n .catch((error: unknown) => {\n console.error('Error fetching page:', path, error);\n notFound();\n });\n\n if (!page) {\n notFound();\n }\n\n return { page, path, cfg };\n});\n\n/**\n * Entity resolver function type\n * Users provide this to resolve entities from their route params\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type EntityResolver<T = any> = (params: Promise<T>) => Promise<Entity>;\n\n/**\n * Internal helper to wrap and cache entity resolvers\n * Ensures the resolver is only called once per unique params\n */\nfunction createCachedEntityResolver<T>(\n resolver: EntityResolver<T>\n): (props: EntityRouteParams<T>) => Promise<Entity> {\n return cache(async ({ params }: EntityRouteParams<T>) => {\n const entity = await resolver(params);\n \n if (!entity) {\n notFound();\n }\n \n return entity;\n });\n}\n\n\n/**\n * NitroPage component renders all blocks from a Flyo page\n */\nexport function NitroPage({\n page,\n}: {\n page: Page\n}) {\n if (!page?.json || !Array.isArray(page.json)) {\n return null;\n }\n\n return (\n <>\n {page.json.map((block: Block, index: number) => (\n <NitroBlock\n key={block.uid || index}\n block={block}\n />\n ))}\n </>\n );\n}\n\nexport function NitroBlock({\n block,\n}: {\n block: Block\n}) {\n if (!block) {\n return null;\n }\n\n const state = getNitro();\n const Component = block.component ? state.components[block.component] : undefined;\n\n if (Component) {\n return <Component block={block} />;\n }\n\n if (state.showMissingComponentAlert) {\n return (\n <div style={{ border: '1px solid #fff', padding: '1rem', marginBottom: '1rem', backgroundColor: 'red' }}>\n Component <b>{block.component}</b> not found.\n </div>\n );\n }\n\n return null;\n}\n\n/**\n * NitroSlot component renders nested blocks from a slot\n * Used for recursive block rendering when blocks contain slots\n * \n * @example\n * ```tsx\n * import { NitroSlot } from '@flyo/nitro-next/server';\n * \n * export default function MyComponent({ block }) {\n * return (\n * <div>\n * <NitroSlot slot={block.slots.mysuperslotname} />\n * </div>\n * );\n * }\n * ```\n */\nexport function NitroSlot({\n slot,\n}: {\n slot?: {\n content?: Block[];\n };\n}) {\n if (!slot?.content || !Array.isArray(slot.content)) {\n return null;\n }\n\n return (\n <>\n {slot.content.map((block: Block, index: number) => (\n <NitroBlock\n key={block.uid || index}\n block={block}\n />\n ))}\n </>\n );\n}\n\n/**\n * Default page route handler for Nitro pages\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageRoute as default } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageRoute(props: RouteParams) {\n const { page } = await resolveNitroRoute(props);\n return <NitroPage page={page} />;\n}\n\n/**\n * Generate metadata for Nitro pages\n * Provides basic meta tags based on Flyo page data\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageGenerateMetadata as generateMetadata } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageGenerateMetadata(\n props: RouteParams\n): Promise<Metadata> {\n const { page } = await resolveNitroRoute(props);\n\n // Extract meta information from page\n const meta = page.meta_json;\n \n const title = meta?.title ?? page.title ?? 'Page';\n const description = meta?.description ?? '';\n const image = meta?.image ?? '';\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n images: image ? [image] : [],\n type: 'website',\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : [],\n },\n };\n}\n\n/**\n * Generate static params for all Nitro pages\n * Enables static site generation (SSG) for all pages\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageGenerateStaticParams as generateStaticParams } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageGenerateStaticParams() {\n const cfg = await getNitroConfig();\n const pages = cfg.pages ?? [];\n\n return pages.map((path: string) => ({\n slug: path === '' ? undefined : path.split('/'),\n }));\n}\n\n/**\n * Default entity route handler with custom resolver\n * Flexible solution that works with any route param structure\n * \n * @example\n * ```ts\n * // app/blog/[slug]/page.tsx\n * const resolver = async (params: Promise<{ slug: string }>) => {\n * const { slug } = await params;\n * return getNitroEntities().entityBySlug({ slug, typeId: 123 });\n * };\n * \n * export default (props) => nitroEntityRoute(props, {\n * resolver,\n * render: (entity) => <h1>{entity.entity?.entity_title}</h1>\n * });\n * ```\n * \n * @example\n * ```ts\n * // app/items/[uniqueid]/page.tsx\n * const resolver = async (params: Promise<{ uniqueid: string }>) => {\n * const { uniqueid } = await params;\n * return getNitroEntities().entityByUniqueid({ uniqueid });\n * };\n * \n * export default (props) => nitroEntityRoute(props, { resolver });\n * ```\n * \n * @example\n * ```ts\n * // app/custom/[whatever]/page.tsx\n * const resolver = async (params: Promise<{ whatever: string }>) => {\n * const { whatever } = await params;\n * return getNitroEntities().entityBySlug({ slug: whatever });\n * };\n * \n * export default (props) => nitroEntityRoute(props, { resolver });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function nitroEntityRoute<T = any>(\n props: EntityRouteParams<T>,\n options: {\n resolver: EntityResolver<T>;\n render?: (entity: Entity) => React.ReactNode;\n }\n) {\n const cachedResolver = createCachedEntityResolver(options.resolver);\n \n return (async () => {\n const entity = await cachedResolver(props);\n \n if (options.render) {\n return options.render(entity);\n }\n\n // Default simple render - users should provide their own render function\n return <div>{entity.entity?.entity_title}</div>;\n })();\n}\n\n/**\n * Generate metadata for Nitro entities with custom resolver\n * Works with any route param structure\n * \n * @example\n * ```ts\n * // app/blog/[slug]/page.tsx\n * const resolver = async (params: Promise<{ slug: string }>) => {\n * const { slug } = await params;\n * return getNitroEntities().entityBySlug({ slug, typeId: 123 });\n * };\n * \n * export const generateMetadata = (props) => nitroEntityGenerateMetadata(props, { resolver });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function nitroEntityGenerateMetadata<T = any>(\n props: EntityRouteParams<T>,\n options: {\n resolver: EntityResolver<T>;\n }\n): Promise<Metadata> {\n const cachedResolver = createCachedEntityResolver(options.resolver);\n const entity = await cachedResolver(props);\n\n const title = entity.entity?.entity_title ?? 'Entity';\n const description = entity.entity?.entity_teaser ?? '';\n const image = entity.entity?.entity_image ?? '';\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n images: image ? [image] : [],\n type: 'website',\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : [],\n },\n };\n}"],"mappings":"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","names":[]}
|
package/dist/server.mjs
CHANGED
|
@@ -111,6 +111,20 @@ function NitroBlock({
|
|
|
111
111
|
}
|
|
112
112
|
return null;
|
|
113
113
|
}
|
|
114
|
+
function NitroSlot({
|
|
115
|
+
slot
|
|
116
|
+
}) {
|
|
117
|
+
if (!slot?.content || !Array.isArray(slot.content)) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
return /* @__PURE__ */ jsx(Fragment, { children: slot.content.map((block, index) => /* @__PURE__ */ jsx(
|
|
121
|
+
NitroBlock,
|
|
122
|
+
{
|
|
123
|
+
block
|
|
124
|
+
},
|
|
125
|
+
block.uid || index
|
|
126
|
+
)) });
|
|
127
|
+
}
|
|
114
128
|
async function nitroPageRoute(props) {
|
|
115
129
|
const { page } = await resolveNitroRoute(props);
|
|
116
130
|
return /* @__PURE__ */ jsx(NitroPage, { page });
|
|
@@ -181,6 +195,7 @@ async function nitroEntityGenerateMetadata(props, options) {
|
|
|
181
195
|
export {
|
|
182
196
|
NitroBlock,
|
|
183
197
|
NitroPage,
|
|
198
|
+
NitroSlot,
|
|
184
199
|
getNitro,
|
|
185
200
|
getNitroConfig,
|
|
186
201
|
getNitroEntities,
|
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.tsx"],"sourcesContent":["import { cache } from 'react';\nimport type { Metadata } from 'next';\nimport { notFound } from 'next/navigation';\nimport {\n Page,\n Block,\n Entity,\n ConfigApi,\n ConfigResponse,\n Configuration,\n PagesApi,\n EntitiesApi\n} from '@flyo/nitro-typescript';\n\n/**\n * Interface for Nitro configuration state\n */\nexport interface NitroState {\n configuration: Configuration | null;\n lang: string | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n components: Record<string, any>;\n showMissingComponentAlert: boolean;\n liveEdit: boolean;\n}\n\n/**\n * Global Nitro state - shared across server and middleware\n */\nexport const globalNitroState: NitroState = {\n configuration: null,\n lang: null,\n components: {},\n showMissingComponentAlert: false,\n liveEdit: false\n};\n\n/**\n * Access the Nitro configuration state\n * Can be used anywhere: server components, middlewares, API routes, etc.\n * Must be called after initNitro() has been initialized.\n * \n * @throws {Error} If Nitro has not been initialized with initNitro()\n * \n * @example\n * ```ts\n * const state = getNitro();\n * const { configuration, lang, components } = state;\n * ```\n */\nexport function getNitro(): NitroState {\n if (!globalNitroState.configuration) {\n throw new Error('Nitro has not been initialized. Make sure to call initNitro() first.');\n }\n return globalNitroState;\n}\n\nexport const initNitro = ({\n accessToken,\n lang,\n components,\n showMissingComponentAlert,\n liveEdit,\n}: {\n accessToken: string;\n lang?: string;\n components?: object;\n showMissingComponentAlert?: boolean;\n liveEdit?: boolean;\n}): ( () => Configuration ) => {\n\n if (!globalNitroState.configuration) {\n globalNitroState.configuration = new Configuration({\n apiKey: accessToken,\n });\n }\n\n globalNitroState.lang = lang ?? null;\n globalNitroState.components = components ?? {};\n globalNitroState.showMissingComponentAlert = showMissingComponentAlert ?? liveEdit ?? false;\n globalNitroState.liveEdit = liveEdit ?? false;\n\n return () => globalNitroState.configuration!;\n}\n\nexport const getNitroConfig = cache(async (): Promise<ConfigResponse> => {\n const state = getNitro();\n\n const configApi = new ConfigApi(state.configuration!);\n const useLang = state.lang ?? undefined;\n\n const config = await configApi.config({ lang: useLang });\n \n return config;\n});\n\nexport function getNitroPages(): PagesApi {\n return new PagesApi(getNitro().configuration!);\n}\n\nexport function getNitroEntities(): EntitiesApi {\n return new EntitiesApi(getNitro().configuration!);\n}\n\n/**\n * Route params type for Next.js catch-all routes\n */\ntype RouteParams = {\n params: Promise<{ slug?: string[] }>;\n};\n\n/**\n * Generic route params type for entity routes\n * Allows any param structure from Next.js app router\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EntityRouteParams<T = any> = {\n params: Promise<T>;\n};\n\n/**\n * Internal helper to resolve Nitro page from route params\n * Uses React cache to avoid duplicate fetching\n */\nconst resolveNitroRoute = cache(async ({ params }: RouteParams) => {\n const { slug } = await params;\n const path = slug?.join('/') ?? '';\n\n const cfg = await getNitroConfig();\n\n if (!cfg.pages?.includes(path)) {\n notFound();\n }\n\n const page = await getNitroPages()\n .page({ slug: path })\n .catch((error: unknown) => {\n console.error('Error fetching page:', path, error);\n notFound();\n });\n\n if (!page) {\n notFound();\n }\n\n return { page, path, cfg };\n});\n\n/**\n * Entity resolver function type\n * Users provide this to resolve entities from their route params\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type EntityResolver<T = any> = (params: Promise<T>) => Promise<Entity>;\n\n/**\n * Internal helper to wrap and cache entity resolvers\n * Ensures the resolver is only called once per unique params\n */\nfunction createCachedEntityResolver<T>(\n resolver: EntityResolver<T>\n): (props: EntityRouteParams<T>) => Promise<Entity> {\n return cache(async ({ params }: EntityRouteParams<T>) => {\n const entity = await resolver(params);\n \n if (!entity) {\n notFound();\n }\n \n return entity;\n });\n}\n\n\n/**\n * NitroPage component renders all blocks from a Flyo page\n */\nexport function NitroPage({\n page,\n}: {\n page: Page\n}) {\n if (!page?.json || !Array.isArray(page.json)) {\n return null;\n }\n\n return (\n <>\n {page.json.map((block: Block, index: number) => (\n <NitroBlock\n key={block.uid || index}\n block={block}\n />\n ))}\n </>\n );\n}\n\nexport function NitroBlock({\n block,\n}: {\n block: Block\n}) {\n if (!block) {\n return null;\n }\n\n const state = getNitro();\n const Component = block.component ? state.components[block.component] : undefined;\n\n if (Component) {\n return <Component block={block} />;\n }\n\n if (state.showMissingComponentAlert) {\n return (\n <div style={{ border: '1px solid #fff', padding: '1rem', marginBottom: '1rem', backgroundColor: 'red' }}>\n Component <b>{block.component}</b> not found.\n </div>\n );\n }\n\n return null;\n}\n\n/**\n * Default page route handler for Nitro pages\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageRoute as default } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageRoute(props: RouteParams) {\n const { page } = await resolveNitroRoute(props);\n return <NitroPage page={page} />;\n}\n\n/**\n * Generate metadata for Nitro pages\n * Provides basic meta tags based on Flyo page data\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageGenerateMetadata as generateMetadata } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageGenerateMetadata(\n props: RouteParams\n): Promise<Metadata> {\n const { page } = await resolveNitroRoute(props);\n\n // Extract meta information from page\n const meta = page.meta_json;\n \n const title = meta?.title ?? page.title ?? 'Page';\n const description = meta?.description ?? '';\n const image = meta?.image ?? '';\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n images: image ? [image] : [],\n type: 'website',\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : [],\n },\n };\n}\n\n/**\n * Generate static params for all Nitro pages\n * Enables static site generation (SSG) for all pages\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageGenerateStaticParams as generateStaticParams } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageGenerateStaticParams() {\n const cfg = await getNitroConfig();\n const pages = cfg.pages ?? [];\n\n return pages.map((path: string) => ({\n slug: path === '' ? undefined : path.split('/'),\n }));\n}\n\n/**\n * Default entity route handler with custom resolver\n * Flexible solution that works with any route param structure\n * \n * @example\n * ```ts\n * // app/blog/[slug]/page.tsx\n * const resolver = async (params: Promise<{ slug: string }>) => {\n * const { slug } = await params;\n * return getNitroEntities().entityBySlug({ slug, typeId: 123 });\n * };\n * \n * export default (props) => nitroEntityRoute(props, {\n * resolver,\n * render: (entity) => <h1>{entity.entity?.entity_title}</h1>\n * });\n * ```\n * \n * @example\n * ```ts\n * // app/items/[uniqueid]/page.tsx\n * const resolver = async (params: Promise<{ uniqueid: string }>) => {\n * const { uniqueid } = await params;\n * return getNitroEntities().entityByUniqueid({ uniqueid });\n * };\n * \n * export default (props) => nitroEntityRoute(props, { resolver });\n * ```\n * \n * @example\n * ```ts\n * // app/custom/[whatever]/page.tsx\n * const resolver = async (params: Promise<{ whatever: string }>) => {\n * const { whatever } = await params;\n * return getNitroEntities().entityBySlug({ slug: whatever });\n * };\n * \n * export default (props) => nitroEntityRoute(props, { resolver });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function nitroEntityRoute<T = any>(\n props: EntityRouteParams<T>,\n options: {\n resolver: EntityResolver<T>;\n render?: (entity: Entity) => React.ReactNode;\n }\n) {\n const cachedResolver = createCachedEntityResolver(options.resolver);\n \n return (async () => {\n const entity = await cachedResolver(props);\n \n if (options.render) {\n return options.render(entity);\n }\n\n // Default simple render - users should provide their own render function\n return <div>{entity.entity?.entity_title}</div>;\n })();\n}\n\n/**\n * Generate metadata for Nitro entities with custom resolver\n * Works with any route param structure\n * \n * @example\n * ```ts\n * // app/blog/[slug]/page.tsx\n * const resolver = async (params: Promise<{ slug: string }>) => {\n * const { slug } = await params;\n * return getNitroEntities().entityBySlug({ slug, typeId: 123 });\n * };\n * \n * export const generateMetadata = (props) => nitroEntityGenerateMetadata(props, { resolver });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function nitroEntityGenerateMetadata<T = any>(\n props: EntityRouteParams<T>,\n options: {\n resolver: EntityResolver<T>;\n }\n): Promise<Metadata> {\n const cachedResolver = createCachedEntityResolver(options.resolver);\n const entity = await cachedResolver(props);\n\n const title = entity.entity?.entity_title ?? 'Entity';\n const description = entity.entity?.entity_teaser ?? '';\n const image = entity.entity?.entity_image ?? '';\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n images: image ? [image] : [],\n type: 'website',\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : [],\n },\n };\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.tsx"],"sourcesContent":["import { cache } from 'react';\nimport type { Metadata } from 'next';\nimport { notFound } from 'next/navigation';\nimport {\n Page,\n Block,\n Entity,\n ConfigApi,\n ConfigResponse,\n Configuration,\n PagesApi,\n EntitiesApi\n} from '@flyo/nitro-typescript';\n\n/**\n * Interface for Nitro configuration state\n */\nexport interface NitroState {\n configuration: Configuration | null;\n lang: string | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n components: Record<string, any>;\n showMissingComponentAlert: boolean;\n liveEdit: boolean;\n}\n\n/**\n * Global Nitro state - shared across server and middleware\n */\nexport const globalNitroState: NitroState = {\n configuration: null,\n lang: null,\n components: {},\n showMissingComponentAlert: false,\n liveEdit: false\n};\n\n/**\n * Access the Nitro configuration state\n * Can be used anywhere: server components, middlewares, API routes, etc.\n * Must be called after initNitro() has been initialized.\n * \n * @throws {Error} If Nitro has not been initialized with initNitro()\n * \n * @example\n * ```ts\n * const state = getNitro();\n * const { configuration, lang, components } = state;\n * ```\n */\nexport function getNitro(): NitroState {\n if (!globalNitroState.configuration) {\n throw new Error('Nitro has not been initialized. Make sure to call initNitro() first.');\n }\n return globalNitroState;\n}\n\nexport const initNitro = ({\n accessToken,\n lang,\n components,\n showMissingComponentAlert,\n liveEdit,\n}: {\n accessToken: string;\n lang?: string;\n components?: object;\n showMissingComponentAlert?: boolean;\n liveEdit?: boolean;\n}): ( () => Configuration ) => {\n\n if (!globalNitroState.configuration) {\n globalNitroState.configuration = new Configuration({\n apiKey: accessToken,\n });\n }\n\n globalNitroState.lang = lang ?? null;\n globalNitroState.components = components ?? {};\n globalNitroState.showMissingComponentAlert = showMissingComponentAlert ?? liveEdit ?? false;\n globalNitroState.liveEdit = liveEdit ?? false;\n\n return () => globalNitroState.configuration!;\n}\n\nexport const getNitroConfig = cache(async (): Promise<ConfigResponse> => {\n const state = getNitro();\n\n const configApi = new ConfigApi(state.configuration!);\n const useLang = state.lang ?? undefined;\n\n const config = await configApi.config({ lang: useLang });\n \n return config;\n});\n\nexport function getNitroPages(): PagesApi {\n return new PagesApi(getNitro().configuration!);\n}\n\nexport function getNitroEntities(): EntitiesApi {\n return new EntitiesApi(getNitro().configuration!);\n}\n\n/**\n * Route params type for Next.js catch-all routes\n */\ntype RouteParams = {\n params: Promise<{ slug?: string[] }>;\n};\n\n/**\n * Generic route params type for entity routes\n * Allows any param structure from Next.js app router\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EntityRouteParams<T = any> = {\n params: Promise<T>;\n};\n\n/**\n * Internal helper to resolve Nitro page from route params\n * Uses React cache to avoid duplicate fetching\n */\nconst resolveNitroRoute = cache(async ({ params }: RouteParams) => {\n const { slug } = await params;\n const path = slug?.join('/') ?? '';\n\n const cfg = await getNitroConfig();\n\n if (!cfg.pages?.includes(path)) {\n notFound();\n }\n\n const page = await getNitroPages()\n .page({ slug: path })\n .catch((error: unknown) => {\n console.error('Error fetching page:', path, error);\n notFound();\n });\n\n if (!page) {\n notFound();\n }\n\n return { page, path, cfg };\n});\n\n/**\n * Entity resolver function type\n * Users provide this to resolve entities from their route params\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type EntityResolver<T = any> = (params: Promise<T>) => Promise<Entity>;\n\n/**\n * Internal helper to wrap and cache entity resolvers\n * Ensures the resolver is only called once per unique params\n */\nfunction createCachedEntityResolver<T>(\n resolver: EntityResolver<T>\n): (props: EntityRouteParams<T>) => Promise<Entity> {\n return cache(async ({ params }: EntityRouteParams<T>) => {\n const entity = await resolver(params);\n \n if (!entity) {\n notFound();\n }\n \n return entity;\n });\n}\n\n\n/**\n * NitroPage component renders all blocks from a Flyo page\n */\nexport function NitroPage({\n page,\n}: {\n page: Page\n}) {\n if (!page?.json || !Array.isArray(page.json)) {\n return null;\n }\n\n return (\n <>\n {page.json.map((block: Block, index: number) => (\n <NitroBlock\n key={block.uid || index}\n block={block}\n />\n ))}\n </>\n );\n}\n\nexport function NitroBlock({\n block,\n}: {\n block: Block\n}) {\n if (!block) {\n return null;\n }\n\n const state = getNitro();\n const Component = block.component ? state.components[block.component] : undefined;\n\n if (Component) {\n return <Component block={block} />;\n }\n\n if (state.showMissingComponentAlert) {\n return (\n <div style={{ border: '1px solid #fff', padding: '1rem', marginBottom: '1rem', backgroundColor: 'red' }}>\n Component <b>{block.component}</b> not found.\n </div>\n );\n }\n\n return null;\n}\n\n/**\n * NitroSlot component renders nested blocks from a slot\n * Used for recursive block rendering when blocks contain slots\n * \n * @example\n * ```tsx\n * import { NitroSlot } from '@flyo/nitro-next/server';\n * \n * export default function MyComponent({ block }) {\n * return (\n * <div>\n * <NitroSlot slot={block.slots.mysuperslotname} />\n * </div>\n * );\n * }\n * ```\n */\nexport function NitroSlot({\n slot,\n}: {\n slot?: {\n content?: Block[];\n };\n}) {\n if (!slot?.content || !Array.isArray(slot.content)) {\n return null;\n }\n\n return (\n <>\n {slot.content.map((block: Block, index: number) => (\n <NitroBlock\n key={block.uid || index}\n block={block}\n />\n ))}\n </>\n );\n}\n\n/**\n * Default page route handler for Nitro pages\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageRoute as default } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageRoute(props: RouteParams) {\n const { page } = await resolveNitroRoute(props);\n return <NitroPage page={page} />;\n}\n\n/**\n * Generate metadata for Nitro pages\n * Provides basic meta tags based on Flyo page data\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageGenerateMetadata as generateMetadata } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageGenerateMetadata(\n props: RouteParams\n): Promise<Metadata> {\n const { page } = await resolveNitroRoute(props);\n\n // Extract meta information from page\n const meta = page.meta_json;\n \n const title = meta?.title ?? page.title ?? 'Page';\n const description = meta?.description ?? '';\n const image = meta?.image ?? '';\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n images: image ? [image] : [],\n type: 'website',\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : [],\n },\n };\n}\n\n/**\n * Generate static params for all Nitro pages\n * Enables static site generation (SSG) for all pages\n * Can be re-exported directly from Next.js app routes\n * \n * @example\n * ```ts\n * // app/[[...slug]]/page.tsx\n * export { nitroPageGenerateStaticParams as generateStaticParams } from '@flyo/nitro-next/server';\n * ```\n */\nexport async function nitroPageGenerateStaticParams() {\n const cfg = await getNitroConfig();\n const pages = cfg.pages ?? [];\n\n return pages.map((path: string) => ({\n slug: path === '' ? undefined : path.split('/'),\n }));\n}\n\n/**\n * Default entity route handler with custom resolver\n * Flexible solution that works with any route param structure\n * \n * @example\n * ```ts\n * // app/blog/[slug]/page.tsx\n * const resolver = async (params: Promise<{ slug: string }>) => {\n * const { slug } = await params;\n * return getNitroEntities().entityBySlug({ slug, typeId: 123 });\n * };\n * \n * export default (props) => nitroEntityRoute(props, {\n * resolver,\n * render: (entity) => <h1>{entity.entity?.entity_title}</h1>\n * });\n * ```\n * \n * @example\n * ```ts\n * // app/items/[uniqueid]/page.tsx\n * const resolver = async (params: Promise<{ uniqueid: string }>) => {\n * const { uniqueid } = await params;\n * return getNitroEntities().entityByUniqueid({ uniqueid });\n * };\n * \n * export default (props) => nitroEntityRoute(props, { resolver });\n * ```\n * \n * @example\n * ```ts\n * // app/custom/[whatever]/page.tsx\n * const resolver = async (params: Promise<{ whatever: string }>) => {\n * const { whatever } = await params;\n * return getNitroEntities().entityBySlug({ slug: whatever });\n * };\n * \n * export default (props) => nitroEntityRoute(props, { resolver });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function nitroEntityRoute<T = any>(\n props: EntityRouteParams<T>,\n options: {\n resolver: EntityResolver<T>;\n render?: (entity: Entity) => React.ReactNode;\n }\n) {\n const cachedResolver = createCachedEntityResolver(options.resolver);\n \n return (async () => {\n const entity = await cachedResolver(props);\n \n if (options.render) {\n return options.render(entity);\n }\n\n // Default simple render - users should provide their own render function\n return <div>{entity.entity?.entity_title}</div>;\n })();\n}\n\n/**\n * Generate metadata for Nitro entities with custom resolver\n * Works with any route param structure\n * \n * @example\n * ```ts\n * // app/blog/[slug]/page.tsx\n * const resolver = async (params: Promise<{ slug: string }>) => {\n * const { slug } = await params;\n * return getNitroEntities().entityBySlug({ slug, typeId: 123 });\n * };\n * \n * export const generateMetadata = (props) => nitroEntityGenerateMetadata(props, { resolver });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function nitroEntityGenerateMetadata<T = any>(\n props: EntityRouteParams<T>,\n options: {\n resolver: EntityResolver<T>;\n }\n): Promise<Metadata> {\n const cachedResolver = createCachedEntityResolver(options.resolver);\n const entity = await cachedResolver(props);\n\n const title = entity.entity?.entity_title ?? 'Entity';\n const description = entity.entity?.entity_teaser ?? '';\n const image = entity.entity?.entity_image ?? '';\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n images: image ? [image] : [],\n type: 'website',\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : [],\n },\n };\n}"],"mappings":"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","names":[]}
|