@flyo/nitro-next 1.3.1 → 1.5.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/dist/proxy.d.mts CHANGED
@@ -1,45 +1,45 @@
1
1
  import { NextResponse } from 'next/server';
2
+ import { NitroState } from './server.mjs';
3
+ import 'react';
4
+ import 'react/jsx-runtime';
5
+ import 'next';
6
+ import '@flyo/nitro-typescript';
2
7
 
3
- interface ProxyConfig {
4
- /**
5
- * If live edit is enabled, caching is disabled
6
- * @default false
7
- */
8
- liveEdit?: boolean;
9
- /**
10
- * Server/CDN cache TTL in seconds
11
- * @default 1200
12
- */
13
- serverCacheTtl?: number;
14
- /**
15
- * Client browser cache TTL in seconds
16
- * @default 900
17
- */
18
- clientCacheTtl?: number;
19
- }
20
8
  /**
21
9
  * Nitro Next.js Proxy Factory
22
10
  *
23
11
  * Creates a Next.js middleware that handles cache control headers.
12
+ * Uses cache TTL values from the Nitro configuration state.
13
+ *
14
+ * @param state The Nitro state containing cache configuration
15
+ * @returns Next.js middleware function
24
16
  *
25
17
  * @example
26
18
  * ```ts
27
- * // proxy.ts (project root or src/)
19
+ * // src/middleware.ts
28
20
  * import { createProxy } from '@flyo/nitro-next/proxy';
21
+ * import { flyoConfig } from './flyo.config';
29
22
  *
30
- * export default createProxy({
31
- * liveEdit: false,
32
- * serverCacheTtl: 1200,
33
- * clientCacheTtl: 900,
34
- * });
23
+ * export default createProxy(flyoConfig());
35
24
  *
36
- * // Next.js requires config to be defined directly in this file
37
25
  * export const config = {
38
26
  * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
39
27
  * };
40
28
  * ```
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * // flyo.config.tsx
33
+ * export const flyoConfig = initNitro({
34
+ * accessToken: process.env.FLYO_ACCESS_TOKEN!,
35
+ * baseUrl: process.env.SITE_URL || 'http://localhost:3000',
36
+ * liveEdit: process.env.FLYO_LIVE_EDIT === 'true',
37
+ * serverCacheTtl: 1200, // 20 minutes
38
+ * clientCacheTtl: 900, // 15 minutes
39
+ * });
40
+ * ```
41
41
  */
42
- declare function createProxy(config?: ProxyConfig): () => NextResponse<unknown>;
42
+ declare function createProxy(state: NitroState): () => NextResponse<unknown>;
43
43
  /**
44
44
  * Proxy matcher configuration
45
45
  * Applies to all routes except Next.js internal routes
@@ -48,4 +48,4 @@ declare const config: {
48
48
  matcher: string[];
49
49
  };
50
50
 
51
- export { type ProxyConfig, config, createProxy };
51
+ export { config, createProxy };
package/dist/proxy.d.ts CHANGED
@@ -1,45 +1,45 @@
1
1
  import { NextResponse } from 'next/server';
2
+ import { NitroState } from './server.js';
3
+ import 'react';
4
+ import 'react/jsx-runtime';
5
+ import 'next';
6
+ import '@flyo/nitro-typescript';
2
7
 
3
- interface ProxyConfig {
4
- /**
5
- * If live edit is enabled, caching is disabled
6
- * @default false
7
- */
8
- liveEdit?: boolean;
9
- /**
10
- * Server/CDN cache TTL in seconds
11
- * @default 1200
12
- */
13
- serverCacheTtl?: number;
14
- /**
15
- * Client browser cache TTL in seconds
16
- * @default 900
17
- */
18
- clientCacheTtl?: number;
19
- }
20
8
  /**
21
9
  * Nitro Next.js Proxy Factory
22
10
  *
23
11
  * Creates a Next.js middleware that handles cache control headers.
12
+ * Uses cache TTL values from the Nitro configuration state.
13
+ *
14
+ * @param state The Nitro state containing cache configuration
15
+ * @returns Next.js middleware function
24
16
  *
25
17
  * @example
26
18
  * ```ts
27
- * // proxy.ts (project root or src/)
19
+ * // src/middleware.ts
28
20
  * import { createProxy } from '@flyo/nitro-next/proxy';
21
+ * import { flyoConfig } from './flyo.config';
29
22
  *
30
- * export default createProxy({
31
- * liveEdit: false,
32
- * serverCacheTtl: 1200,
33
- * clientCacheTtl: 900,
34
- * });
23
+ * export default createProxy(flyoConfig());
35
24
  *
36
- * // Next.js requires config to be defined directly in this file
37
25
  * export const config = {
38
26
  * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
39
27
  * };
40
28
  * ```
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * // flyo.config.tsx
33
+ * export const flyoConfig = initNitro({
34
+ * accessToken: process.env.FLYO_ACCESS_TOKEN!,
35
+ * baseUrl: process.env.SITE_URL || 'http://localhost:3000',
36
+ * liveEdit: process.env.FLYO_LIVE_EDIT === 'true',
37
+ * serverCacheTtl: 1200, // 20 minutes
38
+ * clientCacheTtl: 900, // 15 minutes
39
+ * });
40
+ * ```
41
41
  */
42
- declare function createProxy(config?: ProxyConfig): () => NextResponse<unknown>;
42
+ declare function createProxy(state: NitroState): () => NextResponse<unknown>;
43
43
  /**
44
44
  * Proxy matcher configuration
45
45
  * Applies to all routes except Next.js internal routes
@@ -48,4 +48,4 @@ declare const config: {
48
48
  matcher: string[];
49
49
  };
50
50
 
51
- export { type ProxyConfig, config, createProxy };
51
+ export { config, createProxy };
package/dist/proxy.js CHANGED
@@ -25,24 +25,19 @@ __export(proxy_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(proxy_exports);
27
27
  var import_server = require("next/server");
28
- function createProxy(config2 = {}) {
29
- const {
30
- liveEdit = false,
31
- serverCacheTtl = 1200,
32
- clientCacheTtl = 900
33
- } = config2;
28
+ function createProxy(state) {
34
29
  return function proxy() {
35
30
  const res = import_server.NextResponse.next();
36
- if (liveEdit) {
31
+ if (state.liveEdit) {
37
32
  res.headers.set("Vercel-CDN-Cache-Control", "no-store");
38
33
  res.headers.set("CDN-Cache-Control", "no-store");
39
34
  res.headers.set("Cache-Control", "no-store");
40
35
  } else {
41
- const cdn = serverCacheTtl > 0 ? `max-age=${serverCacheTtl}` : "no-store";
36
+ const cdn = state.serverCacheTtl > 0 ? `max-age=${state.serverCacheTtl}` : "no-store";
42
37
  res.headers.set("Vercel-CDN-Cache-Control", cdn);
43
38
  res.headers.set("CDN-Cache-Control", cdn);
44
- if (clientCacheTtl > 0) {
45
- res.headers.set("Cache-Control", `max-age=${clientCacheTtl}`);
39
+ if (state.clientCacheTtl > 0) {
40
+ res.headers.set("Cache-Control", `max-age=${state.clientCacheTtl}`);
46
41
  }
47
42
  }
48
43
  return res;
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 * 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"]}
1
+ {"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\nimport type { NitroState } from './server';\n\n/**\n * Nitro Next.js Proxy Factory\n * \n * Creates a Next.js middleware that handles cache control headers.\n * Uses cache TTL values from the Nitro configuration state.\n * \n * @param state The Nitro state containing cache configuration\n * @returns Next.js middleware function\n * \n * @example\n * ```ts\n * // src/middleware.ts\n * import { createProxy } from '@flyo/nitro-next/proxy';\n * import { flyoConfig } from './flyo.config';\n * \n * export default createProxy(flyoConfig());\n * \n * export const config = {\n * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],\n * };\n * ```\n * \n * @example\n * ```ts\n * // flyo.config.tsx\n * export const flyoConfig = initNitro({\n * accessToken: process.env.FLYO_ACCESS_TOKEN!,\n * baseUrl: process.env.SITE_URL || 'http://localhost:3000',\n * liveEdit: process.env.FLYO_LIVE_EDIT === 'true',\n * serverCacheTtl: 1200, // 20 minutes\n * clientCacheTtl: 900, // 15 minutes\n * });\n * ```\n */\nexport function createProxy(state: NitroState) {\n return function proxy() {\n const res = NextResponse.next();\n\n if (state.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 = state.serverCacheTtl > 0 ? `max-age=${state.serverCacheTtl}` : 'no-store';\n res.headers.set('Vercel-CDN-Cache-Control', cdn);\n res.headers.set('CDN-Cache-Control', cdn);\n\n if (state.clientCacheTtl > 0) {\n res.headers.set('Cache-Control', `max-age=${state.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;AAqCtB,SAAS,YAAY,OAAmB;AAC7C,SAAO,SAAS,QAAQ;AACtB,UAAM,MAAM,2BAAa,KAAK;AAE9B,QAAI,MAAM,UAAU;AAElB,UAAI,QAAQ,IAAI,4BAA4B,UAAU;AACtD,UAAI,QAAQ,IAAI,qBAAqB,UAAU;AAC/C,UAAI,QAAQ,IAAI,iBAAiB,UAAU;AAAA,IAC7C,OAAO;AAEL,YAAM,MAAM,MAAM,iBAAiB,IAAI,WAAW,MAAM,cAAc,KAAK;AAC3E,UAAI,QAAQ,IAAI,4BAA4B,GAAG;AAC/C,UAAI,QAAQ,IAAI,qBAAqB,GAAG;AAExC,UAAI,MAAM,iBAAiB,GAAG;AAC5B,YAAI,QAAQ,IAAI,iBAAiB,WAAW,MAAM,cAAc,EAAE;AAAA,MACpE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAOO,IAAM,SAAS;AAAA,EACpB,SAAS,CAAC,+CAA+C;AAC3D;","names":[]}
package/dist/proxy.mjs CHANGED
@@ -1,23 +1,18 @@
1
1
  // src/proxy.ts
2
2
  import { NextResponse } from "next/server";
3
- function createProxy(config2 = {}) {
4
- const {
5
- liveEdit = false,
6
- serverCacheTtl = 1200,
7
- clientCacheTtl = 900
8
- } = config2;
3
+ function createProxy(state) {
9
4
  return function proxy() {
10
5
  const res = NextResponse.next();
11
- if (liveEdit) {
6
+ if (state.liveEdit) {
12
7
  res.headers.set("Vercel-CDN-Cache-Control", "no-store");
13
8
  res.headers.set("CDN-Cache-Control", "no-store");
14
9
  res.headers.set("Cache-Control", "no-store");
15
10
  } else {
16
- const cdn = serverCacheTtl > 0 ? `max-age=${serverCacheTtl}` : "no-store";
11
+ const cdn = state.serverCacheTtl > 0 ? `max-age=${state.serverCacheTtl}` : "no-store";
17
12
  res.headers.set("Vercel-CDN-Cache-Control", cdn);
18
13
  res.headers.set("CDN-Cache-Control", cdn);
19
- if (clientCacheTtl > 0) {
20
- res.headers.set("Cache-Control", `max-age=${clientCacheTtl}`);
14
+ if (state.clientCacheTtl > 0) {
15
+ res.headers.set("Cache-Control", `max-age=${state.clientCacheTtl}`);
21
16
  }
22
17
  }
23
18
  return res;
@@ -1 +1 @@
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"]}
1
+ {"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\nimport type { NitroState } from './server';\n\n/**\n * Nitro Next.js Proxy Factory\n * \n * Creates a Next.js middleware that handles cache control headers.\n * Uses cache TTL values from the Nitro configuration state.\n * \n * @param state The Nitro state containing cache configuration\n * @returns Next.js middleware function\n * \n * @example\n * ```ts\n * // src/middleware.ts\n * import { createProxy } from '@flyo/nitro-next/proxy';\n * import { flyoConfig } from './flyo.config';\n * \n * export default createProxy(flyoConfig());\n * \n * export const config = {\n * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],\n * };\n * ```\n * \n * @example\n * ```ts\n * // flyo.config.tsx\n * export const flyoConfig = initNitro({\n * accessToken: process.env.FLYO_ACCESS_TOKEN!,\n * baseUrl: process.env.SITE_URL || 'http://localhost:3000',\n * liveEdit: process.env.FLYO_LIVE_EDIT === 'true',\n * serverCacheTtl: 1200, // 20 minutes\n * clientCacheTtl: 900, // 15 minutes\n * });\n * ```\n */\nexport function createProxy(state: NitroState) {\n return function proxy() {\n const res = NextResponse.next();\n\n if (state.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 = state.serverCacheTtl > 0 ? `max-age=${state.serverCacheTtl}` : 'no-store';\n res.headers.set('Vercel-CDN-Cache-Control', cdn);\n res.headers.set('CDN-Cache-Control', cdn);\n\n if (state.clientCacheTtl > 0) {\n res.headers.set('Cache-Control', `max-age=${state.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;AAqCtB,SAAS,YAAY,OAAmB;AAC7C,SAAO,SAAS,QAAQ;AACtB,UAAM,MAAM,aAAa,KAAK;AAE9B,QAAI,MAAM,UAAU;AAElB,UAAI,QAAQ,IAAI,4BAA4B,UAAU;AACtD,UAAI,QAAQ,IAAI,qBAAqB,UAAU;AAC/C,UAAI,QAAQ,IAAI,iBAAiB,UAAU;AAAA,IAC7C,OAAO;AAEL,YAAM,MAAM,MAAM,iBAAiB,IAAI,WAAW,MAAM,cAAc,KAAK;AAC3E,UAAI,QAAQ,IAAI,4BAA4B,GAAG;AAC/C,UAAI,QAAQ,IAAI,qBAAqB,GAAG;AAExC,UAAI,MAAM,iBAAiB,GAAG;AAC5B,YAAI,QAAQ,IAAI,iBAAiB,WAAW,MAAM,cAAc,EAAE;AAAA,MACpE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAOO,IAAM,SAAS;AAAA,EACpB,SAAS,CAAC,+CAA+C;AAC3D;","names":[]}
package/dist/server.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
- import { Metadata } from 'next';
4
- import { Configuration, ConfigResponse, PagesApi, EntitiesApi, Entity, Page, Block } from '@flyo/nitro-typescript';
3
+ import { Metadata, MetadataRoute } from 'next';
4
+ import { Configuration, ConfigResponse, PagesApi, EntitiesApi, SitemapApi, SearchApi, Entity, Page, Block } from '@flyo/nitro-typescript';
5
5
 
6
6
  /**
7
7
  * Interface for Nitro configuration state
@@ -9,9 +9,12 @@ import { Configuration, ConfigResponse, PagesApi, EntitiesApi, Entity, Page, Blo
9
9
  interface NitroState {
10
10
  configuration: Configuration | null;
11
11
  lang: string | null;
12
+ baseUrl: string | null;
12
13
  components: Record<string, any>;
13
14
  showMissingComponentAlert: boolean;
14
15
  liveEdit: boolean;
16
+ serverCacheTtl: number;
17
+ clientCacheTtl: number;
15
18
  }
16
19
  /**
17
20
  * Global Nitro state - shared across server and middleware
@@ -31,16 +34,21 @@ declare const globalNitroState: NitroState;
31
34
  * ```
32
35
  */
33
36
  declare function getNitro(): NitroState;
34
- declare const initNitro: ({ accessToken, lang, components, showMissingComponentAlert, liveEdit, }: {
37
+ declare const initNitro: ({ accessToken, lang, baseUrl, components, showMissingComponentAlert, liveEdit, serverCacheTtl, clientCacheTtl, }: {
35
38
  accessToken: string;
36
39
  lang?: string;
40
+ baseUrl?: string;
37
41
  components?: object;
38
42
  showMissingComponentAlert?: boolean;
39
43
  liveEdit?: boolean;
40
- }) => (() => Configuration);
44
+ serverCacheTtl?: number;
45
+ clientCacheTtl?: number;
46
+ }) => (() => NitroState);
41
47
  declare const getNitroConfig: () => Promise<ConfigResponse>;
42
48
  declare function getNitroPages(): PagesApi;
43
49
  declare function getNitroEntities(): EntitiesApi;
50
+ declare function getNitroSitemap(): SitemapApi;
51
+ declare function getNitroSearch(): SearchApi;
44
52
  /**
45
53
  * Route params type for Next.js catch-all routes
46
54
  */
@@ -70,6 +78,28 @@ declare function NitroPage({ page, }: {
70
78
  declare function NitroBlock({ block, }: {
71
79
  block: Block;
72
80
  }): react_jsx_runtime.JSX.Element | null;
81
+ /**
82
+ * NitroSlot component renders nested blocks from a slot
83
+ * Used for recursive block rendering when blocks contain slots
84
+ *
85
+ * @example
86
+ * ```tsx
87
+ * import { NitroSlot } from '@flyo/nitro-next/server';
88
+ *
89
+ * export default function MyComponent({ block }) {
90
+ * return (
91
+ * <div>
92
+ * <NitroSlot slot={block.slots.mysuperslotname} />
93
+ * </div>
94
+ * );
95
+ * }
96
+ * ```
97
+ */
98
+ declare function NitroSlot({ slot, }: {
99
+ slot?: {
100
+ content?: Block[];
101
+ };
102
+ }): react_jsx_runtime.JSX.Element | null;
73
103
  /**
74
104
  * Default page route handler for Nitro pages
75
105
  * Can be re-exported directly from Next.js app routes
@@ -169,5 +199,35 @@ declare function nitroEntityRoute<T = any>(props: EntityRouteParams<T>, options:
169
199
  declare function nitroEntityGenerateMetadata<T = any>(props: EntityRouteParams<T>, options: {
170
200
  resolver: EntityResolver<T>;
171
201
  }): Promise<Metadata>;
202
+ /**
203
+ * Generate sitemap for Next.js from Flyo Nitro
204
+ * Fetches all pages and entities from the sitemap endpoint
205
+ * Uses the baseUrl from the Nitro configuration state
206
+ *
207
+ * @param state The Nitro state containing configuration and baseUrl
208
+ * @returns Promise resolving to Next.js MetadataRoute.Sitemap format
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * // app/sitemap.ts
213
+ * import { nitroSitemap } from '@flyo/nitro-next/server';
214
+ * import { flyoConfig } from '../flyo.config';
215
+ *
216
+ * export default async function sitemap() {
217
+ * return nitroSitemap(flyoConfig());
218
+ * }
219
+ * ```
220
+ *
221
+ * @example
222
+ * ```ts
223
+ * // flyo.config.tsx
224
+ * export const flyoConfig = initNitro({
225
+ * accessToken: process.env.FLYO_ACCESS_TOKEN!,
226
+ * baseUrl: process.env.SITE_URL || 'http://localhost:3000',
227
+ * lang: 'en',
228
+ * });
229
+ * ```
230
+ */
231
+ declare function nitroSitemap(state: NitroState): Promise<MetadataRoute.Sitemap>;
172
232
 
173
- export { type EntityResolver, NitroBlock, NitroPage, type NitroState, getNitro, getNitroConfig, getNitroEntities, getNitroPages, globalNitroState, initNitro, nitroEntityGenerateMetadata, nitroEntityRoute, nitroPageGenerateMetadata, nitroPageGenerateStaticParams, nitroPageRoute };
233
+ export { type EntityResolver, NitroBlock, NitroPage, NitroSlot, type NitroState, getNitro, getNitroConfig, getNitroEntities, getNitroPages, getNitroSearch, getNitroSitemap, globalNitroState, initNitro, nitroEntityGenerateMetadata, nitroEntityRoute, nitroPageGenerateMetadata, nitroPageGenerateStaticParams, nitroPageRoute, nitroSitemap };
package/dist/server.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
- import { Metadata } from 'next';
4
- import { Configuration, ConfigResponse, PagesApi, EntitiesApi, Entity, Page, Block } from '@flyo/nitro-typescript';
3
+ import { Metadata, MetadataRoute } from 'next';
4
+ import { Configuration, ConfigResponse, PagesApi, EntitiesApi, SitemapApi, SearchApi, Entity, Page, Block } from '@flyo/nitro-typescript';
5
5
 
6
6
  /**
7
7
  * Interface for Nitro configuration state
@@ -9,9 +9,12 @@ import { Configuration, ConfigResponse, PagesApi, EntitiesApi, Entity, Page, Blo
9
9
  interface NitroState {
10
10
  configuration: Configuration | null;
11
11
  lang: string | null;
12
+ baseUrl: string | null;
12
13
  components: Record<string, any>;
13
14
  showMissingComponentAlert: boolean;
14
15
  liveEdit: boolean;
16
+ serverCacheTtl: number;
17
+ clientCacheTtl: number;
15
18
  }
16
19
  /**
17
20
  * Global Nitro state - shared across server and middleware
@@ -31,16 +34,21 @@ declare const globalNitroState: NitroState;
31
34
  * ```
32
35
  */
33
36
  declare function getNitro(): NitroState;
34
- declare const initNitro: ({ accessToken, lang, components, showMissingComponentAlert, liveEdit, }: {
37
+ declare const initNitro: ({ accessToken, lang, baseUrl, components, showMissingComponentAlert, liveEdit, serverCacheTtl, clientCacheTtl, }: {
35
38
  accessToken: string;
36
39
  lang?: string;
40
+ baseUrl?: string;
37
41
  components?: object;
38
42
  showMissingComponentAlert?: boolean;
39
43
  liveEdit?: boolean;
40
- }) => (() => Configuration);
44
+ serverCacheTtl?: number;
45
+ clientCacheTtl?: number;
46
+ }) => (() => NitroState);
41
47
  declare const getNitroConfig: () => Promise<ConfigResponse>;
42
48
  declare function getNitroPages(): PagesApi;
43
49
  declare function getNitroEntities(): EntitiesApi;
50
+ declare function getNitroSitemap(): SitemapApi;
51
+ declare function getNitroSearch(): SearchApi;
44
52
  /**
45
53
  * Route params type for Next.js catch-all routes
46
54
  */
@@ -70,6 +78,28 @@ declare function NitroPage({ page, }: {
70
78
  declare function NitroBlock({ block, }: {
71
79
  block: Block;
72
80
  }): react_jsx_runtime.JSX.Element | null;
81
+ /**
82
+ * NitroSlot component renders nested blocks from a slot
83
+ * Used for recursive block rendering when blocks contain slots
84
+ *
85
+ * @example
86
+ * ```tsx
87
+ * import { NitroSlot } from '@flyo/nitro-next/server';
88
+ *
89
+ * export default function MyComponent({ block }) {
90
+ * return (
91
+ * <div>
92
+ * <NitroSlot slot={block.slots.mysuperslotname} />
93
+ * </div>
94
+ * );
95
+ * }
96
+ * ```
97
+ */
98
+ declare function NitroSlot({ slot, }: {
99
+ slot?: {
100
+ content?: Block[];
101
+ };
102
+ }): react_jsx_runtime.JSX.Element | null;
73
103
  /**
74
104
  * Default page route handler for Nitro pages
75
105
  * Can be re-exported directly from Next.js app routes
@@ -169,5 +199,35 @@ declare function nitroEntityRoute<T = any>(props: EntityRouteParams<T>, options:
169
199
  declare function nitroEntityGenerateMetadata<T = any>(props: EntityRouteParams<T>, options: {
170
200
  resolver: EntityResolver<T>;
171
201
  }): Promise<Metadata>;
202
+ /**
203
+ * Generate sitemap for Next.js from Flyo Nitro
204
+ * Fetches all pages and entities from the sitemap endpoint
205
+ * Uses the baseUrl from the Nitro configuration state
206
+ *
207
+ * @param state The Nitro state containing configuration and baseUrl
208
+ * @returns Promise resolving to Next.js MetadataRoute.Sitemap format
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * // app/sitemap.ts
213
+ * import { nitroSitemap } from '@flyo/nitro-next/server';
214
+ * import { flyoConfig } from '../flyo.config';
215
+ *
216
+ * export default async function sitemap() {
217
+ * return nitroSitemap(flyoConfig());
218
+ * }
219
+ * ```
220
+ *
221
+ * @example
222
+ * ```ts
223
+ * // flyo.config.tsx
224
+ * export const flyoConfig = initNitro({
225
+ * accessToken: process.env.FLYO_ACCESS_TOKEN!,
226
+ * baseUrl: process.env.SITE_URL || 'http://localhost:3000',
227
+ * lang: 'en',
228
+ * });
229
+ * ```
230
+ */
231
+ declare function nitroSitemap(state: NitroState): Promise<MetadataRoute.Sitemap>;
172
232
 
173
- export { type EntityResolver, NitroBlock, NitroPage, type NitroState, getNitro, getNitroConfig, getNitroEntities, getNitroPages, globalNitroState, initNitro, nitroEntityGenerateMetadata, nitroEntityRoute, nitroPageGenerateMetadata, nitroPageGenerateStaticParams, nitroPageRoute };
233
+ export { type EntityResolver, NitroBlock, NitroPage, NitroSlot, type NitroState, getNitro, getNitroConfig, getNitroEntities, getNitroPages, getNitroSearch, getNitroSitemap, globalNitroState, initNitro, nitroEntityGenerateMetadata, nitroEntityRoute, nitroPageGenerateMetadata, nitroPageGenerateStaticParams, nitroPageRoute, nitroSitemap };
package/dist/server.js CHANGED
@@ -22,17 +22,21 @@ 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,
28
29
  getNitroPages: () => getNitroPages,
30
+ getNitroSearch: () => getNitroSearch,
31
+ getNitroSitemap: () => getNitroSitemap,
29
32
  globalNitroState: () => globalNitroState,
30
33
  initNitro: () => initNitro,
31
34
  nitroEntityGenerateMetadata: () => nitroEntityGenerateMetadata,
32
35
  nitroEntityRoute: () => nitroEntityRoute,
33
36
  nitroPageGenerateMetadata: () => nitroPageGenerateMetadata,
34
37
  nitroPageGenerateStaticParams: () => nitroPageGenerateStaticParams,
35
- nitroPageRoute: () => nitroPageRoute
38
+ nitroPageRoute: () => nitroPageRoute,
39
+ nitroSitemap: () => nitroSitemap
36
40
  });
37
41
  module.exports = __toCommonJS(server_exports);
38
42
  var import_react = require("react");
@@ -42,9 +46,12 @@ var import_jsx_runtime = require("react/jsx-runtime");
42
46
  var globalNitroState = {
43
47
  configuration: null,
44
48
  lang: null,
49
+ baseUrl: null,
45
50
  components: {},
46
51
  showMissingComponentAlert: false,
47
- liveEdit: false
52
+ liveEdit: false,
53
+ serverCacheTtl: 1200,
54
+ clientCacheTtl: 900
48
55
  };
49
56
  function getNitro() {
50
57
  if (!globalNitroState.configuration) {
@@ -55,9 +62,12 @@ function getNitro() {
55
62
  var initNitro = ({
56
63
  accessToken,
57
64
  lang,
65
+ baseUrl,
58
66
  components,
59
67
  showMissingComponentAlert,
60
- liveEdit
68
+ liveEdit,
69
+ serverCacheTtl,
70
+ clientCacheTtl
61
71
  }) => {
62
72
  if (!globalNitroState.configuration) {
63
73
  globalNitroState.configuration = new import_nitro_typescript.Configuration({
@@ -65,10 +75,13 @@ var initNitro = ({
65
75
  });
66
76
  }
67
77
  globalNitroState.lang = lang ?? null;
78
+ globalNitroState.baseUrl = baseUrl ?? null;
68
79
  globalNitroState.components = components ?? {};
69
80
  globalNitroState.showMissingComponentAlert = showMissingComponentAlert ?? liveEdit ?? false;
70
81
  globalNitroState.liveEdit = liveEdit ?? false;
71
- return () => globalNitroState.configuration;
82
+ globalNitroState.serverCacheTtl = serverCacheTtl ?? 1200;
83
+ globalNitroState.clientCacheTtl = clientCacheTtl ?? 900;
84
+ return () => globalNitroState;
72
85
  };
73
86
  var getNitroConfig = (0, import_react.cache)(async () => {
74
87
  const state = getNitro();
@@ -83,6 +96,12 @@ function getNitroPages() {
83
96
  function getNitroEntities() {
84
97
  return new import_nitro_typescript.EntitiesApi(getNitro().configuration);
85
98
  }
99
+ function getNitroSitemap() {
100
+ return new import_nitro_typescript.SitemapApi(getNitro().configuration);
101
+ }
102
+ function getNitroSearch() {
103
+ return new import_nitro_typescript.SearchApi(getNitro().configuration);
104
+ }
86
105
  var resolveNitroRoute = (0, import_react.cache)(async ({ params }) => {
87
106
  const { slug } = await params;
88
107
  const path = slug?.join("/") ?? "";
@@ -142,6 +161,20 @@ function NitroBlock({
142
161
  }
143
162
  return null;
144
163
  }
164
+ function NitroSlot({
165
+ slot
166
+ }) {
167
+ if (!slot?.content || !Array.isArray(slot.content)) {
168
+ return null;
169
+ }
170
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: slot.content.map((block, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
171
+ NitroBlock,
172
+ {
173
+ block
174
+ },
175
+ block.uid || index
176
+ )) });
177
+ }
145
178
  async function nitroPageRoute(props) {
146
179
  const { page } = await resolveNitroRoute(props);
147
180
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NitroPage, { page });
@@ -209,20 +242,52 @@ async function nitroEntityGenerateMetadata(props, options) {
209
242
  }
210
243
  };
211
244
  }
245
+ async function nitroSitemap(state) {
246
+ const sitemapApi = getNitroSitemap();
247
+ const lang = state.lang ?? void 0;
248
+ if (!state.baseUrl) {
249
+ throw new Error("baseUrl is not configured in Nitro state. Please set it in initNitro().");
250
+ }
251
+ const items = await sitemapApi.sitemap({ lang });
252
+ const baseUrl = state.baseUrl;
253
+ const cleanBaseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
254
+ return items.map((item) => {
255
+ let path = "";
256
+ if (item.routes && typeof item.routes === "object") {
257
+ const routeValues = Object.values(item.routes);
258
+ if (routeValues.length > 0) {
259
+ path = routeValues[0];
260
+ }
261
+ }
262
+ if (!path && item.entity_slug) {
263
+ path = item.entity_slug;
264
+ }
265
+ const cleanPath = path && !path.startsWith("/") ? `/${path}` : path;
266
+ const lastModified = /* @__PURE__ */ new Date();
267
+ return {
268
+ url: `${cleanBaseUrl}${cleanPath}`,
269
+ lastModified
270
+ };
271
+ });
272
+ }
212
273
  // Annotate the CommonJS export names for ESM import in node:
213
274
  0 && (module.exports = {
214
275
  NitroBlock,
215
276
  NitroPage,
277
+ NitroSlot,
216
278
  getNitro,
217
279
  getNitroConfig,
218
280
  getNitroEntities,
219
281
  getNitroPages,
282
+ getNitroSearch,
283
+ getNitroSitemap,
220
284
  globalNitroState,
221
285
  initNitro,
222
286
  nitroEntityGenerateMetadata,
223
287
  nitroEntityRoute,
224
288
  nitroPageGenerateMetadata,
225
289
  nitroPageGenerateStaticParams,
226
- nitroPageRoute
290
+ nitroPageRoute,
291
+ nitroSitemap
227
292
  });
228
293
  //# sourceMappingURL=server.js.map
@@ -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, MetadataRoute } 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 SitemapApi,\n SearchApi\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 baseUrl: string | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n components: Record<string, any>;\n showMissingComponentAlert: boolean;\n liveEdit: boolean;\n serverCacheTtl: number;\n clientCacheTtl: number;\n}\n\n/**\n * Global Nitro state - shared across server and middleware\n */\nexport const globalNitroState: NitroState = {\n configuration: null,\n lang: null,\n baseUrl: null,\n components: {},\n showMissingComponentAlert: false,\n liveEdit: false,\n serverCacheTtl: 1200,\n clientCacheTtl: 900\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 baseUrl,\n components,\n showMissingComponentAlert,\n liveEdit,\n serverCacheTtl,\n clientCacheTtl,\n}: {\n accessToken: string;\n lang?: string;\n baseUrl?: string;\n components?: object;\n showMissingComponentAlert?: boolean;\n liveEdit?: boolean;\n serverCacheTtl?: number;\n clientCacheTtl?: number;\n}): ( () => NitroState ) => {\n\n if (!globalNitroState.configuration) {\n globalNitroState.configuration = new Configuration({\n apiKey: accessToken,\n });\n }\n\n globalNitroState.lang = lang ?? null;\n globalNitroState.baseUrl = baseUrl ?? null;\n globalNitroState.components = components ?? {};\n globalNitroState.showMissingComponentAlert = showMissingComponentAlert ?? liveEdit ?? false;\n globalNitroState.liveEdit = liveEdit ?? false;\n globalNitroState.serverCacheTtl = serverCacheTtl ?? 1200;\n globalNitroState.clientCacheTtl = clientCacheTtl ?? 900;\n\n return () => globalNitroState;\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\nexport function getNitroSitemap(): SitemapApi {\n return new SitemapApi(getNitro().configuration!);\n}\n\nexport function getNitroSearch(): SearchApi {\n return new SearchApi(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}\n\n/**\n * Generate sitemap for Next.js from Flyo Nitro\n * Fetches all pages and entities from the sitemap endpoint\n * Uses the baseUrl from the Nitro configuration state\n * \n * @param state The Nitro state containing configuration and baseUrl\n * @returns Promise resolving to Next.js MetadataRoute.Sitemap format\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { nitroSitemap } from '@flyo/nitro-next/server';\n * import { flyoConfig } from '../flyo.config';\n * \n * export default async function sitemap() {\n * return nitroSitemap(flyoConfig());\n * }\n * ```\n * \n * @example\n * ```ts\n * // flyo.config.tsx\n * export const flyoConfig = initNitro({\n * accessToken: process.env.FLYO_ACCESS_TOKEN!,\n * baseUrl: process.env.SITE_URL || 'http://localhost:3000',\n * lang: 'en',\n * });\n * ```\n */\nexport async function nitroSitemap(state: NitroState): Promise<MetadataRoute.Sitemap> {\n const sitemapApi = getNitroSitemap();\n const lang = state.lang ?? undefined;\n\n if (!state.baseUrl) {\n throw new Error('baseUrl is not configured in Nitro state. Please set it in initNitro().');\n }\n\n // Fetch all sitemap entries from Flyo Nitro\n const items = await sitemapApi.sitemap({ lang });\n\n const baseUrl = state.baseUrl;\n \n // Remove trailing slash from baseUrl for consistency\n const cleanBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n\n return items.map((item) => {\n // Prefer routes object if available, otherwise use entity_slug\n let path = '';\n \n if (item.routes && typeof item.routes === 'object') {\n // Use the first available route from the routes object\n const routeValues = Object.values(item.routes);\n if (routeValues.length > 0) {\n path = routeValues[0];\n }\n }\n \n // Fallback to entity_slug if no routes found\n if (!path && item.entity_slug) {\n path = item.entity_slug;\n }\n\n // Ensure path starts with /\n const cleanPath = path && !path.startsWith('/') ? `/${path}` : path;\n\n // Convert Unix timestamp to Date if available\n const lastModified = new Date();\n\n return {\n url: `${cleanBaseUrl}${cleanPath}`,\n lastModified,\n };\n });\n}"],"mappings":"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","names":[]}
package/dist/server.mjs CHANGED
@@ -5,15 +5,20 @@ import {
5
5
  ConfigApi,
6
6
  Configuration,
7
7
  PagesApi,
8
- EntitiesApi
8
+ EntitiesApi,
9
+ SitemapApi,
10
+ SearchApi
9
11
  } from "@flyo/nitro-typescript";
10
12
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
13
  var globalNitroState = {
12
14
  configuration: null,
13
15
  lang: null,
16
+ baseUrl: null,
14
17
  components: {},
15
18
  showMissingComponentAlert: false,
16
- liveEdit: false
19
+ liveEdit: false,
20
+ serverCacheTtl: 1200,
21
+ clientCacheTtl: 900
17
22
  };
18
23
  function getNitro() {
19
24
  if (!globalNitroState.configuration) {
@@ -24,9 +29,12 @@ function getNitro() {
24
29
  var initNitro = ({
25
30
  accessToken,
26
31
  lang,
32
+ baseUrl,
27
33
  components,
28
34
  showMissingComponentAlert,
29
- liveEdit
35
+ liveEdit,
36
+ serverCacheTtl,
37
+ clientCacheTtl
30
38
  }) => {
31
39
  if (!globalNitroState.configuration) {
32
40
  globalNitroState.configuration = new Configuration({
@@ -34,10 +42,13 @@ var initNitro = ({
34
42
  });
35
43
  }
36
44
  globalNitroState.lang = lang ?? null;
45
+ globalNitroState.baseUrl = baseUrl ?? null;
37
46
  globalNitroState.components = components ?? {};
38
47
  globalNitroState.showMissingComponentAlert = showMissingComponentAlert ?? liveEdit ?? false;
39
48
  globalNitroState.liveEdit = liveEdit ?? false;
40
- return () => globalNitroState.configuration;
49
+ globalNitroState.serverCacheTtl = serverCacheTtl ?? 1200;
50
+ globalNitroState.clientCacheTtl = clientCacheTtl ?? 900;
51
+ return () => globalNitroState;
41
52
  };
42
53
  var getNitroConfig = cache(async () => {
43
54
  const state = getNitro();
@@ -52,6 +63,12 @@ function getNitroPages() {
52
63
  function getNitroEntities() {
53
64
  return new EntitiesApi(getNitro().configuration);
54
65
  }
66
+ function getNitroSitemap() {
67
+ return new SitemapApi(getNitro().configuration);
68
+ }
69
+ function getNitroSearch() {
70
+ return new SearchApi(getNitro().configuration);
71
+ }
55
72
  var resolveNitroRoute = cache(async ({ params }) => {
56
73
  const { slug } = await params;
57
74
  const path = slug?.join("/") ?? "";
@@ -111,6 +128,20 @@ function NitroBlock({
111
128
  }
112
129
  return null;
113
130
  }
131
+ function NitroSlot({
132
+ slot
133
+ }) {
134
+ if (!slot?.content || !Array.isArray(slot.content)) {
135
+ return null;
136
+ }
137
+ return /* @__PURE__ */ jsx(Fragment, { children: slot.content.map((block, index) => /* @__PURE__ */ jsx(
138
+ NitroBlock,
139
+ {
140
+ block
141
+ },
142
+ block.uid || index
143
+ )) });
144
+ }
114
145
  async function nitroPageRoute(props) {
115
146
  const { page } = await resolveNitroRoute(props);
116
147
  return /* @__PURE__ */ jsx(NitroPage, { page });
@@ -178,19 +209,51 @@ async function nitroEntityGenerateMetadata(props, options) {
178
209
  }
179
210
  };
180
211
  }
212
+ async function nitroSitemap(state) {
213
+ const sitemapApi = getNitroSitemap();
214
+ const lang = state.lang ?? void 0;
215
+ if (!state.baseUrl) {
216
+ throw new Error("baseUrl is not configured in Nitro state. Please set it in initNitro().");
217
+ }
218
+ const items = await sitemapApi.sitemap({ lang });
219
+ const baseUrl = state.baseUrl;
220
+ const cleanBaseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
221
+ return items.map((item) => {
222
+ let path = "";
223
+ if (item.routes && typeof item.routes === "object") {
224
+ const routeValues = Object.values(item.routes);
225
+ if (routeValues.length > 0) {
226
+ path = routeValues[0];
227
+ }
228
+ }
229
+ if (!path && item.entity_slug) {
230
+ path = item.entity_slug;
231
+ }
232
+ const cleanPath = path && !path.startsWith("/") ? `/${path}` : path;
233
+ const lastModified = /* @__PURE__ */ new Date();
234
+ return {
235
+ url: `${cleanBaseUrl}${cleanPath}`,
236
+ lastModified
237
+ };
238
+ });
239
+ }
181
240
  export {
182
241
  NitroBlock,
183
242
  NitroPage,
243
+ NitroSlot,
184
244
  getNitro,
185
245
  getNitroConfig,
186
246
  getNitroEntities,
187
247
  getNitroPages,
248
+ getNitroSearch,
249
+ getNitroSitemap,
188
250
  globalNitroState,
189
251
  initNitro,
190
252
  nitroEntityGenerateMetadata,
191
253
  nitroEntityRoute,
192
254
  nitroPageGenerateMetadata,
193
255
  nitroPageGenerateStaticParams,
194
- nitroPageRoute
256
+ nitroPageRoute,
257
+ nitroSitemap
195
258
  };
196
259
  //# sourceMappingURL=server.mjs.map
@@ -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, MetadataRoute } 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 SitemapApi,\n SearchApi\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 baseUrl: string | null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n components: Record<string, any>;\n showMissingComponentAlert: boolean;\n liveEdit: boolean;\n serverCacheTtl: number;\n clientCacheTtl: number;\n}\n\n/**\n * Global Nitro state - shared across server and middleware\n */\nexport const globalNitroState: NitroState = {\n configuration: null,\n lang: null,\n baseUrl: null,\n components: {},\n showMissingComponentAlert: false,\n liveEdit: false,\n serverCacheTtl: 1200,\n clientCacheTtl: 900\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 baseUrl,\n components,\n showMissingComponentAlert,\n liveEdit,\n serverCacheTtl,\n clientCacheTtl,\n}: {\n accessToken: string;\n lang?: string;\n baseUrl?: string;\n components?: object;\n showMissingComponentAlert?: boolean;\n liveEdit?: boolean;\n serverCacheTtl?: number;\n clientCacheTtl?: number;\n}): ( () => NitroState ) => {\n\n if (!globalNitroState.configuration) {\n globalNitroState.configuration = new Configuration({\n apiKey: accessToken,\n });\n }\n\n globalNitroState.lang = lang ?? null;\n globalNitroState.baseUrl = baseUrl ?? null;\n globalNitroState.components = components ?? {};\n globalNitroState.showMissingComponentAlert = showMissingComponentAlert ?? liveEdit ?? false;\n globalNitroState.liveEdit = liveEdit ?? false;\n globalNitroState.serverCacheTtl = serverCacheTtl ?? 1200;\n globalNitroState.clientCacheTtl = clientCacheTtl ?? 900;\n\n return () => globalNitroState;\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\nexport function getNitroSitemap(): SitemapApi {\n return new SitemapApi(getNitro().configuration!);\n}\n\nexport function getNitroSearch(): SearchApi {\n return new SearchApi(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}\n\n/**\n * Generate sitemap for Next.js from Flyo Nitro\n * Fetches all pages and entities from the sitemap endpoint\n * Uses the baseUrl from the Nitro configuration state\n * \n * @param state The Nitro state containing configuration and baseUrl\n * @returns Promise resolving to Next.js MetadataRoute.Sitemap format\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { nitroSitemap } from '@flyo/nitro-next/server';\n * import { flyoConfig } from '../flyo.config';\n * \n * export default async function sitemap() {\n * return nitroSitemap(flyoConfig());\n * }\n * ```\n * \n * @example\n * ```ts\n * // flyo.config.tsx\n * export const flyoConfig = initNitro({\n * accessToken: process.env.FLYO_ACCESS_TOKEN!,\n * baseUrl: process.env.SITE_URL || 'http://localhost:3000',\n * lang: 'en',\n * });\n * ```\n */\nexport async function nitroSitemap(state: NitroState): Promise<MetadataRoute.Sitemap> {\n const sitemapApi = getNitroSitemap();\n const lang = state.lang ?? undefined;\n\n if (!state.baseUrl) {\n throw new Error('baseUrl is not configured in Nitro state. Please set it in initNitro().');\n }\n\n // Fetch all sitemap entries from Flyo Nitro\n const items = await sitemapApi.sitemap({ lang });\n\n const baseUrl = state.baseUrl;\n \n // Remove trailing slash from baseUrl for consistency\n const cleanBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n\n return items.map((item) => {\n // Prefer routes object if available, otherwise use entity_slug\n let path = '';\n \n if (item.routes && typeof item.routes === 'object') {\n // Use the first available route from the routes object\n const routeValues = Object.values(item.routes);\n if (routeValues.length > 0) {\n path = routeValues[0];\n }\n }\n \n // Fallback to entity_slug if no routes found\n if (!path && item.entity_slug) {\n path = item.entity_slug;\n }\n\n // Ensure path starts with /\n const cleanPath = path && !path.startsWith('/') ? `/${path}` : path;\n\n // Convert Unix timestamp to Date if available\n const lastModified = new Date();\n\n return {\n url: `${cleanBaseUrl}${cleanPath}`,\n lastModified,\n };\n });\n}"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flyo/nitro-next",
3
- "version": "1.3.1",
3
+ "version": "1.5.0",
4
4
  "description": "Connecting Flyo Headless Content Hub into your Next.js project.",
5
5
  "homepage": "https://dev.flyo.cloud/nitro",
6
6
  "keywords": [