@dheme/next 1.8.0 → 1.9.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/index.d.mts CHANGED
@@ -6,6 +6,20 @@ export { ThemeActionsState, ThemeDataState, ThemeGenerator, ThemeGeneratorProps,
6
6
 
7
7
  interface DhemeProviderProps extends DhemeProviderProps$1 {
8
8
  cookieSync?: boolean;
9
+ /**
10
+ * URL of a proxy route that forwards theme requests server-side,
11
+ * keeping the API key out of the browser entirely.
12
+ *
13
+ * Set up the route with `createDhemeHandler` from `@dheme/next/server`:
14
+ * @example
15
+ * // app/api/dheme/route.ts
16
+ * import { createDhemeHandler } from '@dheme/next/server';
17
+ * export const { POST } = createDhemeHandler({ apiKey: process.env.DHEME_API_KEY! });
18
+ *
19
+ * // layout.tsx
20
+ * <DhemeProvider proxyUrl="/api/dheme" theme="..." />
21
+ */
22
+ proxyUrl?: string;
9
23
  }
10
24
  interface GenerateThemeStylesOptions {
11
25
  /** API key (obrigatório para uso externo; omitir para rotas internas sem autenticação) */
@@ -21,6 +35,6 @@ interface GenerateThemeStylesOptions {
21
35
  onGenerateTheme?: (params: GenerateThemeRequest) => Promise<GenerateThemeResponse>;
22
36
  }
23
37
 
24
- declare function DhemeProvider({ children, cookieSync, onThemeChange, onModeChange, theme: primaryColor, themeParams, ...props }: DhemeProviderProps): React.ReactElement;
38
+ declare function DhemeProvider({ children, cookieSync, proxyUrl, onThemeChange, onModeChange, onGenerateTheme, theme: primaryColor, themeParams, ...props }: DhemeProviderProps): React.ReactElement;
25
39
 
26
40
  export { DhemeProvider, type DhemeProviderProps, type GenerateThemeStylesOptions };
package/dist/index.d.ts CHANGED
@@ -6,6 +6,20 @@ export { ThemeActionsState, ThemeDataState, ThemeGenerator, ThemeGeneratorProps,
6
6
 
7
7
  interface DhemeProviderProps extends DhemeProviderProps$1 {
8
8
  cookieSync?: boolean;
9
+ /**
10
+ * URL of a proxy route that forwards theme requests server-side,
11
+ * keeping the API key out of the browser entirely.
12
+ *
13
+ * Set up the route with `createDhemeHandler` from `@dheme/next/server`:
14
+ * @example
15
+ * // app/api/dheme/route.ts
16
+ * import { createDhemeHandler } from '@dheme/next/server';
17
+ * export const { POST } = createDhemeHandler({ apiKey: process.env.DHEME_API_KEY! });
18
+ *
19
+ * // layout.tsx
20
+ * <DhemeProvider proxyUrl="/api/dheme" theme="..." />
21
+ */
22
+ proxyUrl?: string;
9
23
  }
10
24
  interface GenerateThemeStylesOptions {
11
25
  /** API key (obrigatório para uso externo; omitir para rotas internas sem autenticação) */
@@ -21,6 +35,6 @@ interface GenerateThemeStylesOptions {
21
35
  onGenerateTheme?: (params: GenerateThemeRequest) => Promise<GenerateThemeResponse>;
22
36
  }
23
37
 
24
- declare function DhemeProvider({ children, cookieSync, onThemeChange, onModeChange, theme: primaryColor, themeParams, ...props }: DhemeProviderProps): React.ReactElement;
38
+ declare function DhemeProvider({ children, cookieSync, proxyUrl, onThemeChange, onModeChange, onGenerateTheme, theme: primaryColor, themeParams, ...props }: DhemeProviderProps): React.ReactElement;
25
39
 
26
40
  export { DhemeProvider, type DhemeProviderProps, type GenerateThemeStylesOptions };
package/dist/index.js CHANGED
@@ -53,8 +53,10 @@ function setCookie(name, value) {
53
53
  function DhemeProvider({
54
54
  children,
55
55
  cookieSync = true,
56
+ proxyUrl,
56
57
  onThemeChange,
57
58
  onModeChange,
59
+ onGenerateTheme,
58
60
  theme: primaryColor,
59
61
  themeParams,
60
62
  ...props
@@ -82,11 +84,28 @@ function DhemeProvider({
82
84
  },
83
85
  [cookieSync, onModeChange]
84
86
  );
87
+ const proxyGenerateTheme = (0, import_react.useCallback)(
88
+ async (params) => {
89
+ const res = await fetch(proxyUrl, {
90
+ method: "POST",
91
+ headers: { "Content-Type": "application/json" },
92
+ body: JSON.stringify(params)
93
+ });
94
+ if (!res.ok) {
95
+ const body = await res.json().catch(() => ({}));
96
+ throw new Error(body.error ?? `Proxy request failed: ${res.status}`);
97
+ }
98
+ return res.json();
99
+ },
100
+ [proxyUrl]
101
+ );
102
+ const resolvedGenerateTheme = proxyUrl ? proxyGenerateTheme : onGenerateTheme;
85
103
  return import_react.default.createElement(import_react2.DhemeProvider, {
86
104
  ...props,
87
105
  theme: primaryColor,
88
106
  themeParams,
89
107
  persist: true,
108
+ onGenerateTheme: resolvedGenerateTheme,
90
109
  onThemeChange: handleThemeChange,
91
110
  onModeChange: handleModeChange,
92
111
  children
package/dist/index.mjs CHANGED
@@ -10,8 +10,10 @@ function setCookie(name, value) {
10
10
  function DhemeProvider({
11
11
  children,
12
12
  cookieSync = true,
13
+ proxyUrl,
13
14
  onThemeChange,
14
15
  onModeChange,
16
+ onGenerateTheme,
15
17
  theme: primaryColor,
16
18
  themeParams,
17
19
  ...props
@@ -39,11 +41,28 @@ function DhemeProvider({
39
41
  },
40
42
  [cookieSync, onModeChange]
41
43
  );
44
+ const proxyGenerateTheme = useCallback(
45
+ async (params) => {
46
+ const res = await fetch(proxyUrl, {
47
+ method: "POST",
48
+ headers: { "Content-Type": "application/json" },
49
+ body: JSON.stringify(params)
50
+ });
51
+ if (!res.ok) {
52
+ const body = await res.json().catch(() => ({}));
53
+ throw new Error(body.error ?? `Proxy request failed: ${res.status}`);
54
+ }
55
+ return res.json();
56
+ },
57
+ [proxyUrl]
58
+ );
59
+ const resolvedGenerateTheme = proxyUrl ? proxyGenerateTheme : onGenerateTheme;
42
60
  return React.createElement(ReactDhemeProvider, {
43
61
  ...props,
44
62
  theme: primaryColor,
45
63
  themeParams,
46
64
  persist: true,
65
+ onGenerateTheme: resolvedGenerateTheme,
47
66
  onThemeChange: handleThemeChange,
48
67
  onModeChange: handleModeChange,
49
68
  children
package/dist/server.d.mts CHANGED
@@ -59,4 +59,25 @@ declare class ThemeCache {
59
59
  }
60
60
  declare const themeCache: ThemeCache;
61
61
 
62
- export { DhemeScript, type DhemeScriptProps, type GenerateThemeStylesOptions, generateThemeStyles, getModeFromCookie, getParamsFromCookie, themeCache };
62
+ interface DhemeHandlerConfig {
63
+ /** API key — keep in an environment variable, never in client code. */
64
+ apiKey: string;
65
+ baseUrl?: string;
66
+ }
67
+ /**
68
+ * Creates a Next.js App Router Route Handler that proxies theme generation
69
+ * requests server-side, so the API key is never exposed to the browser.
70
+ *
71
+ * @example
72
+ * // app/api/dheme/route.ts
73
+ * import { createDhemeHandler } from '@dheme/next/server';
74
+ * export const { POST } = createDhemeHandler({ apiKey: process.env.DHEME_API_KEY! });
75
+ *
76
+ * // Then in your layout, use proxyUrl instead of apiKey:
77
+ * // <DhemeProvider proxyUrl="/api/dheme" theme="..." />
78
+ */
79
+ declare function createDhemeHandler(config: DhemeHandlerConfig): {
80
+ POST: (request: Request) => Promise<Response>;
81
+ };
82
+
83
+ export { type DhemeHandlerConfig, DhemeScript, type DhemeScriptProps, type GenerateThemeStylesOptions, createDhemeHandler, generateThemeStyles, getModeFromCookie, getParamsFromCookie, themeCache };
package/dist/server.d.ts CHANGED
@@ -59,4 +59,25 @@ declare class ThemeCache {
59
59
  }
60
60
  declare const themeCache: ThemeCache;
61
61
 
62
- export { DhemeScript, type DhemeScriptProps, type GenerateThemeStylesOptions, generateThemeStyles, getModeFromCookie, getParamsFromCookie, themeCache };
62
+ interface DhemeHandlerConfig {
63
+ /** API key — keep in an environment variable, never in client code. */
64
+ apiKey: string;
65
+ baseUrl?: string;
66
+ }
67
+ /**
68
+ * Creates a Next.js App Router Route Handler that proxies theme generation
69
+ * requests server-side, so the API key is never exposed to the browser.
70
+ *
71
+ * @example
72
+ * // app/api/dheme/route.ts
73
+ * import { createDhemeHandler } from '@dheme/next/server';
74
+ * export const { POST } = createDhemeHandler({ apiKey: process.env.DHEME_API_KEY! });
75
+ *
76
+ * // Then in your layout, use proxyUrl instead of apiKey:
77
+ * // <DhemeProvider proxyUrl="/api/dheme" theme="..." />
78
+ */
79
+ declare function createDhemeHandler(config: DhemeHandlerConfig): {
80
+ POST: (request: Request) => Promise<Response>;
81
+ };
82
+
83
+ export { type DhemeHandlerConfig, DhemeScript, type DhemeScriptProps, type GenerateThemeStylesOptions, createDhemeHandler, generateThemeStyles, getModeFromCookie, getParamsFromCookie, themeCache };
package/dist/server.js CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var server_exports = {};
32
32
  __export(server_exports, {
33
33
  DhemeScript: () => DhemeScript,
34
+ createDhemeHandler: () => createDhemeHandler,
34
35
  generateThemeStyles: () => generateThemeStyles,
35
36
  getModeFromCookie: () => getModeFromCookie,
36
37
  getParamsFromCookie: () => getParamsFromCookie,
@@ -170,9 +171,33 @@ async function getParamsFromCookie() {
170
171
  return null;
171
172
  }
172
173
  }
174
+
175
+ // src/server/handler.ts
176
+ var import_sdk3 = require("@dheme/sdk");
177
+ function createDhemeHandler(config) {
178
+ const client = new import_sdk3.DhemeClient({ apiKey: config.apiKey, baseUrl: config.baseUrl });
179
+ async function POST(request) {
180
+ let body;
181
+ try {
182
+ body = await request.json();
183
+ } catch {
184
+ return Response.json({ error: "Invalid JSON body" }, { status: 400 });
185
+ }
186
+ try {
187
+ const response = await client.generateTheme(body);
188
+ return Response.json(response.data);
189
+ } catch (err) {
190
+ const message = err instanceof Error ? err.message : "Internal server error";
191
+ const status = message.includes("429") || message.toLowerCase().includes("rate limit") ? 429 : 500;
192
+ return Response.json({ error: message }, { status });
193
+ }
194
+ }
195
+ return { POST };
196
+ }
173
197
  // Annotate the CommonJS export names for ESM import in node:
174
198
  0 && (module.exports = {
175
199
  DhemeScript,
200
+ createDhemeHandler,
176
201
  generateThemeStyles,
177
202
  getModeFromCookie,
178
203
  getParamsFromCookie,
package/dist/server.mjs CHANGED
@@ -130,8 +130,32 @@ async function getParamsFromCookie() {
130
130
  return null;
131
131
  }
132
132
  }
133
+
134
+ // src/server/handler.ts
135
+ import { DhemeClient as DhemeClient3 } from "@dheme/sdk";
136
+ function createDhemeHandler(config) {
137
+ const client = new DhemeClient3({ apiKey: config.apiKey, baseUrl: config.baseUrl });
138
+ async function POST(request) {
139
+ let body;
140
+ try {
141
+ body = await request.json();
142
+ } catch {
143
+ return Response.json({ error: "Invalid JSON body" }, { status: 400 });
144
+ }
145
+ try {
146
+ const response = await client.generateTheme(body);
147
+ return Response.json(response.data);
148
+ } catch (err) {
149
+ const message = err instanceof Error ? err.message : "Internal server error";
150
+ const status = message.includes("429") || message.toLowerCase().includes("rate limit") ? 429 : 500;
151
+ return Response.json({ error: message }, { status });
152
+ }
153
+ }
154
+ return { POST };
155
+ }
133
156
  export {
134
157
  DhemeScript,
158
+ createDhemeHandler,
135
159
  generateThemeStyles,
136
160
  getModeFromCookie,
137
161
  getParamsFromCookie,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dheme/next",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Next.js App Router bindings for Dheme SDK with server-side theme generation",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "dependencies": {
58
58
  "@dheme/sdk": "^1.1.0",
59
- "@dheme/react": "^2.8.0"
59
+ "@dheme/react": "^2.11.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/react": "^18.2.0",