@llmnative/react 0.1.1 → 1.1.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.
Files changed (185) hide show
  1. package/README.md +397 -364
  2. package/bin/cli.js +117 -98
  3. package/dist/index.css +1 -1
  4. package/dist/index.js +21 -823
  5. package/dist/index.mjs +14984 -9345
  6. package/dist/style.css +1 -0
  7. package/dist/types/src/App.d.ts +75 -14
  8. package/dist/types/src/Config.d.ts +28 -5
  9. package/dist/types/src/Global.d.ts +2 -2
  10. package/dist/types/src/I18n.d.ts +186 -0
  11. package/dist/types/src/Theme.d.ts +153 -81
  12. package/dist/types/src/auth.d.ts +13 -1
  13. package/dist/types/src/components/Component.d.ts +13 -27
  14. package/dist/types/src/components/ErrorBoundary.d.ts +30 -0
  15. package/dist/types/src/components/blocks/Brand.d.ts +9 -4
  16. package/dist/types/src/components/blocks/Breadcrumbs.d.ts +50 -4
  17. package/dist/types/src/components/blocks/Carousel.d.ts +7 -5
  18. package/dist/types/src/components/blocks/Dropdown.d.ts +38 -20
  19. package/dist/types/src/components/blocks/ListCard.d.ts +38 -0
  20. package/dist/types/src/components/blocks/Menu.d.ts +15 -16
  21. package/dist/types/src/components/blocks/Notifications.d.ts +11 -3
  22. package/dist/types/src/components/blocks/ProviderSwitcher.d.ts +65 -0
  23. package/dist/types/src/components/blocks/Search.d.ts +3 -2
  24. package/dist/types/src/components/blocks/SideNav.d.ts +45 -0
  25. package/dist/types/src/components/blocks/ThemeSwitcher.d.ts +28 -0
  26. package/dist/types/src/components/blocks/Toolbar.d.ts +23 -0
  27. package/dist/types/src/components/index.d.ts +28 -7
  28. package/dist/types/src/components/types.d.ts +10 -3
  29. package/dist/types/src/components/ui/Alert.d.ts +20 -4
  30. package/dist/types/src/components/ui/Badge.d.ts +12 -5
  31. package/dist/types/src/components/ui/Buttons.d.ts +16 -12
  32. package/dist/types/src/components/ui/Card.d.ts +11 -7
  33. package/dist/types/src/components/ui/Code.d.ts +5 -1
  34. package/dist/types/src/components/ui/Gallery.d.ts +16 -16
  35. package/dist/types/src/components/ui/GridSystem.d.ts +5 -2
  36. package/dist/types/src/components/ui/Icon.d.ts +6 -1
  37. package/dist/types/src/components/ui/Image.d.ts +7 -1
  38. package/dist/types/src/components/ui/ImageAvatar.d.ts +4 -1
  39. package/dist/types/src/components/ui/Loader.d.ts +3 -1
  40. package/dist/types/src/components/ui/LocaleSwitcher.d.ts +14 -0
  41. package/dist/types/src/components/ui/Modal.d.ts +46 -15
  42. package/dist/types/src/components/ui/Pagination.d.ts +16 -3
  43. package/dist/types/src/components/ui/Percentage.d.ts +14 -5
  44. package/dist/types/src/components/ui/Repeat.d.ts +14 -6
  45. package/dist/types/src/components/ui/Tab.d.ts +29 -2
  46. package/dist/types/src/components/ui/TabDynamic.d.ts +4 -3
  47. package/dist/types/src/components/ui/Table.d.ts +18 -14
  48. package/dist/types/src/components/ui/fields/CodeEditor.d.ts +46 -0
  49. package/dist/types/src/components/ui/fields/ContextMenu.d.ts +87 -0
  50. package/dist/types/src/components/ui/fields/Crop.d.ts +4 -2
  51. package/dist/types/src/components/ui/fields/ImageField.d.ts +31 -0
  52. package/dist/types/src/components/ui/fields/Input.d.ts +43 -14
  53. package/dist/types/src/components/ui/fields/Prompt.d.ts +2 -31
  54. package/dist/types/src/components/ui/fields/RichText.d.ts +89 -0
  55. package/dist/types/src/components/ui/fields/Select.d.ts +13 -10
  56. package/dist/types/src/components/ui/fields/Upload.d.ts +50 -2
  57. package/dist/types/src/components/ui/fields/UploadCSV.d.ts +2 -0
  58. package/dist/types/src/components/ui/useRecordSelection.d.ts +1 -2
  59. package/dist/types/src/components/widgets/Form.d.ts +80 -43
  60. package/dist/types/src/components/widgets/ImageEditor.d.ts +4 -5
  61. package/dist/types/src/components/widgets/MarkdownReader.d.ts +4 -4
  62. package/dist/types/src/components/widgets/Prompt.d.ts +90 -22
  63. package/dist/types/src/components/widgets/TabDynamic.d.ts +4 -3
  64. package/dist/types/src/components/widgets/form-controller.d.ts +42 -0
  65. package/dist/types/src/components/widgets/grid-core/GridCore.d.ts +1 -1
  66. package/dist/types/src/components/widgets/grid-core/GridDB.d.ts +1 -1
  67. package/dist/types/src/components/widgets/grid-core/GridGalleryView.d.ts +1 -1
  68. package/dist/types/src/components/widgets/grid-core/GridTableView.d.ts +1 -1
  69. package/dist/types/src/components/widgets/grid-core/types.d.ts +77 -27
  70. package/dist/types/src/components/widgets/grid-core/useGridActions.d.ts +4 -8
  71. package/dist/types/src/components/widgets/grid-core/useGridColumns.d.ts +2 -2
  72. package/dist/types/src/components/widgets/grid-core/useGridDBRecords.d.ts +1 -2
  73. package/dist/types/src/components/widgets/grid-core/useGridPreparedRecords.d.ts +2 -2
  74. package/dist/types/src/components/widgets/grid-core/useGridSelection.d.ts +4 -5
  75. package/dist/types/src/components/widgets/grid-core/utils.d.ts +11 -3
  76. package/dist/types/src/conf/Prompt.d.ts +1 -1
  77. package/dist/types/src/conf/i18n/ar.d.ts +2 -0
  78. package/dist/types/src/conf/i18n/de.d.ts +2 -0
  79. package/dist/types/src/conf/i18n/en.d.ts +2 -0
  80. package/dist/types/src/conf/i18n/index.d.ts +6 -0
  81. package/dist/types/src/conf/i18n/it.d.ts +2 -0
  82. package/dist/types/src/conf/i18n/ru.d.ts +2 -0
  83. package/dist/types/src/conf/i18n/zh.d.ts +2 -0
  84. package/dist/types/src/constant.d.ts +1 -1
  85. package/dist/types/src/index.d.ts +48 -13
  86. package/dist/types/src/libs/converter.d.ts +4 -4
  87. package/dist/types/src/libs/editorHeight.d.ts +12 -0
  88. package/dist/types/src/libs/fetch.d.ts +4 -4
  89. package/dist/types/src/libs/imageBuilder.d.ts +63 -14
  90. package/dist/types/src/libs/imageVariants.d.ts +35 -0
  91. package/dist/types/src/libs/index.d.ts +1 -4
  92. package/dist/types/src/libs/promptUtils.d.ts +24 -0
  93. package/dist/types/src/libs/sanitizer.d.ts +2 -2
  94. package/dist/types/src/libs/utils.d.ts +9 -10
  95. package/dist/types/src/pages/index.d.ts +0 -2
  96. package/dist/types/src/providers/ProviderConfiguration.d.ts +6 -0
  97. package/dist/types/src/providers/ProviderDescriptor.d.ts +18 -0
  98. package/dist/types/src/providers/ProviderRegistryContext.d.ts +51 -0
  99. package/dist/types/src/providers/ProviderSession.d.ts +68 -0
  100. package/dist/types/src/providers/ai/AIProvider.d.ts +57 -0
  101. package/dist/types/src/providers/ai/AIProviderContext.d.ts +13 -0
  102. package/dist/types/src/providers/ai/anthropic.d.ts +2 -0
  103. package/dist/types/src/providers/ai/deepseek.d.ts +1 -0
  104. package/dist/types/src/providers/ai/gemini.d.ts +2 -0
  105. package/dist/types/src/providers/ai/glm.d.ts +1 -0
  106. package/dist/types/src/providers/ai/index.d.ts +20 -134
  107. package/dist/types/src/providers/ai/mistral.d.ts +1 -0
  108. package/dist/types/src/providers/ai/openai.d.ts +1 -0
  109. package/dist/types/src/providers/ai/openaiCompatible.d.ts +19 -0
  110. package/dist/types/src/providers/ai/opencode.d.ts +2 -0
  111. package/dist/types/src/providers/ai/openrouter.d.ts +1 -0
  112. package/dist/types/src/providers/ai/shared.d.ts +55 -0
  113. package/dist/types/src/providers/api/ApiProvider.d.ts +43 -0
  114. package/dist/types/src/providers/api/direct.d.ts +14 -0
  115. package/dist/types/src/providers/api/firebase.d.ts +14 -0
  116. package/dist/types/src/providers/api/mock.d.ts +7 -0
  117. package/dist/types/src/providers/api/supabase.d.ts +14 -0
  118. package/dist/types/src/providers/auth/AuthProvider.d.ts +10 -2
  119. package/dist/types/src/providers/auth/firebase/FirebaseAuthProvider.d.ts +49 -0
  120. package/dist/types/src/providers/auth/google/GoogleAuth.d.ts +2 -2
  121. package/dist/types/src/providers/auth/supabase/SupabaseAuthProvider.d.ts +48 -0
  122. package/dist/types/src/providers/credentials/CredentialsProvider.d.ts +3 -0
  123. package/dist/types/src/providers/credentials/CredentialsProviderContext.d.ts +12 -0
  124. package/dist/types/src/providers/credentials/google/GoogleServiceAccountProvider.d.ts +8 -0
  125. package/dist/types/src/providers/data/DataProvider.d.ts +27 -1
  126. package/dist/types/src/providers/data/firebase.d.ts +5 -4
  127. package/dist/types/src/providers/data/firestore.d.ts +45 -0
  128. package/dist/types/src/providers/data/mock.d.ts +8 -1
  129. package/dist/types/src/providers/data/supabase.d.ts +36 -10
  130. package/dist/types/src/providers/email/definitions.d.ts +3 -0
  131. package/dist/types/src/providers/firebase-init.d.ts +24 -7
  132. package/dist/types/src/providers/icon/PhosphorIconProvider.d.ts +1 -1
  133. package/dist/types/src/providers/manifest.d.ts +20 -14
  134. package/dist/types/src/providers/proxy/index.d.ts +7 -0
  135. package/dist/types/src/providers/proxy/vite.d.ts +3 -0
  136. package/dist/types/src/providers/publish/PublishProvider.d.ts +29 -0
  137. package/dist/types/src/providers/publish/definitions.d.ts +3 -0
  138. package/dist/types/src/providers/scrape/index.d.ts +2 -1
  139. package/dist/types/src/providers/seo/google/keyword.d.ts +6 -1
  140. package/dist/types/src/providers/storage/StorageProvider.d.ts +155 -4
  141. package/dist/types/src/providers/storage/dropbox.d.ts +3 -3
  142. package/dist/types/src/providers/storage/firebase.d.ts +44 -7
  143. package/dist/types/src/providers/storage/supabase.d.ts +47 -7
  144. package/dist/types/src/providers/supabase-init.d.ts +35 -0
  145. package/dist/types/src/types/FormFields.d.ts +4 -2
  146. package/dist/types/src/types/FormSchema.d.ts +29 -0
  147. package/dist/types/themes/tokyo-night-light.d.ts +3 -0
  148. package/dist/types/themes/tokyo-night.d.ts +3 -0
  149. package/dist/types/themes/vscode-dark-plus.d.ts +3 -0
  150. package/dist/types/themes/vscode-light-plus.d.ts +3 -0
  151. package/dist/vite.js +1 -0
  152. package/dist/vite.mjs +54 -0
  153. package/package.json +46 -8
  154. package/scripts/cli/proxy-templates/cloudflare.ts +34 -0
  155. package/scripts/cli/proxy-templates/express.ts +77 -0
  156. package/scripts/cli/proxy-templates/nextjs-app.ts +42 -0
  157. package/scripts/cli/proxy-templates/nextjs-pages.ts +41 -0
  158. package/scripts/cli/proxy-templates/scaffold.json +33 -0
  159. package/scripts/cli/setup-devtools.js +155 -85
  160. package/scripts/cli/setup-project.js +618 -484
  161. package/themes/cyber.ts +469 -405
  162. package/themes/default.ts +469 -405
  163. package/themes/flat.ts +469 -405
  164. package/themes/tokyo-night-light.ts +38 -0
  165. package/themes/tokyo-night.ts +38 -0
  166. package/themes/vscode-dark-plus.ts +29 -0
  167. package/themes/vscode-light-plus.ts +29 -0
  168. package/dist/index.js.map +0 -1
  169. package/dist/index.mjs.map +0 -1
  170. package/dist/types/src/components/FormEnhancer.d.ts +0 -26
  171. package/dist/types/src/components/Template.d.ts +0 -18
  172. package/dist/types/src/components/ui/fields/AssistantAI.d.ts +0 -23
  173. package/dist/types/src/components/ui/fields/Command.d.ts +0 -15
  174. package/dist/types/src/components/ui/fields/ImageUrl.d.ts +0 -7
  175. package/dist/types/src/libs/cache.d.ts +0 -9
  176. package/dist/types/src/libs/database.d.ts +0 -3
  177. package/dist/types/src/libs/log.d.ts +0 -2
  178. package/dist/types/src/libs/seo.d.ts +0 -8
  179. package/dist/types/src/libs/storage.d.ts +0 -2
  180. package/dist/types/src/pages/Blog.d.ts +0 -3
  181. package/dist/types/src/pages/BlogPost.d.ts +0 -16
  182. package/dist/types/src/pages/Helper.d.ts +0 -8
  183. package/dist/types/src/providers/auth/google/apis/auth.d.ts +0 -4
  184. package/dist/types/src/types/Block.d.ts +0 -4
  185. package/dist/types/src/types/Section.d.ts +0 -4
@@ -0,0 +1,77 @@
1
+ // @ts-nocheck - scaffold template, copied to user project by CLI
2
+ import type { IncomingMessage, ServerResponse } from 'node:http';
3
+
4
+ const PROXY_CALLER_HEADER = 'x-llmnative-proxy';
5
+ export const PROXY_PATH = '/api/proxy';
6
+
7
+ type AppLike = {
8
+ all: (route: string, handler: (req: IncomingMessage, res: ServerResponse) => void) => unknown;
9
+ };
10
+
11
+ const readRequestBody = async (req: IncomingMessage): Promise<Buffer | undefined> => {
12
+ const chunks: Buffer[] = [];
13
+ for await (const chunk of req) {
14
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
15
+ }
16
+ return chunks.length === 0 ? undefined : Buffer.concat(chunks);
17
+ };
18
+
19
+ export const proxyHandler = async (req: IncomingMessage, res: ServerResponse) => {
20
+ const requestUrl = new URL(req.url || '/', 'http://localhost');
21
+ const target = requestUrl.searchParams.get('url');
22
+
23
+ if (req.headers[PROXY_CALLER_HEADER] !== '1') {
24
+ res.statusCode = 403;
25
+ res.setHeader('Content-Type', 'application/json');
26
+ res.end(JSON.stringify({ error: 'Proxy access denied.' }));
27
+ return;
28
+ }
29
+
30
+ if (!target) {
31
+ res.statusCode = 400;
32
+ res.setHeader('Content-Type', 'application/json');
33
+ res.end(JSON.stringify({ error: 'Missing "url" query parameter.' }));
34
+ return;
35
+ }
36
+
37
+ try {
38
+ const targetUrl = new URL(target);
39
+ if (targetUrl.pathname.startsWith(PROXY_PATH) && ['localhost', '127.0.0.1'].includes(targetUrl.hostname)) {
40
+ res.statusCode = 508;
41
+ res.setHeader('Content-Type', 'application/json');
42
+ res.end(JSON.stringify({ error: 'Recursive proxy target detected.', target }));
43
+ return;
44
+ }
45
+
46
+ const body = await readRequestBody(req);
47
+ const headers = new Headers();
48
+ const skipHeaders = new Set([PROXY_CALLER_HEADER, 'host', 'origin', 'referer', 'content-length', 'transfer-encoding', 'connection']);
49
+
50
+ Object.entries(req.headers).forEach(([key, value]) => {
51
+ if (!value || skipHeaders.has(key.toLowerCase())) return;
52
+ headers.set(key, Array.isArray(value) ? value.join(', ') : value);
53
+ });
54
+
55
+ const upstream = await fetch(target, {
56
+ method: req.method || 'GET',
57
+ headers,
58
+ body: body && !['GET', 'HEAD'].includes((req.method || 'GET').toUpperCase()) ? body : undefined,
59
+ redirect: 'follow',
60
+ });
61
+
62
+ res.statusCode = upstream.status;
63
+ upstream.headers.forEach((value, key) => {
64
+ if (key.toLowerCase() === 'content-encoding') return;
65
+ res.setHeader(key, value);
66
+ });
67
+ res.end(Buffer.from(await upstream.arrayBuffer()));
68
+ } catch (error) {
69
+ res.statusCode = 502;
70
+ res.setHeader('Content-Type', 'application/json');
71
+ res.end(JSON.stringify({ error: error instanceof Error ? error.message : 'Proxy request failed.' }));
72
+ }
73
+ };
74
+
75
+ export const registerProxy = (app: AppLike, route = PROXY_PATH) => {
76
+ app.all(route, (req, res) => { void proxyHandler(req, res); });
77
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * LLMNative proxy - Next.js App Router.
3
+ *
4
+ * Place this file at:
5
+ * app/api/proxy/route.ts
6
+ */
7
+
8
+ const PASSTHROUGH_METHODS = new Set(['GET', 'HEAD']);
9
+
10
+ async function handler(request: Request): Promise<Response> {
11
+ const { searchParams } = new URL(request.url);
12
+ const targetUrl = searchParams.get('url');
13
+
14
+ if (!targetUrl) {
15
+ return Response.json({ error: 'Missing url query parameter' }, { status: 400 });
16
+ }
17
+
18
+ const headers = new Headers(request.headers);
19
+ headers.delete('host');
20
+ headers.delete('x-llmnative-proxy');
21
+
22
+ const hasBody = !PASSTHROUGH_METHODS.has(request.method.toUpperCase());
23
+
24
+ const upstream = await fetch(targetUrl, {
25
+ method: request.method,
26
+ headers,
27
+ body: hasBody ? request.body : undefined,
28
+ ...(hasBody ? { duplex: 'half' } : {}),
29
+ } as RequestInit);
30
+
31
+ return new Response(upstream.body, {
32
+ status: upstream.status,
33
+ headers: upstream.headers,
34
+ });
35
+ }
36
+
37
+ export const GET = handler;
38
+ export const POST = handler;
39
+ export const PUT = handler;
40
+ export const PATCH = handler;
41
+ export const DELETE = handler;
42
+ export const OPTIONS = handler;
@@ -0,0 +1,41 @@
1
+ // @ts-nocheck - scaffold template, copied to user project by CLI
2
+ import type { NextApiRequest, NextApiResponse } from 'next';
3
+
4
+ /**
5
+ * LLMNative proxy - Next.js Pages Router.
6
+ *
7
+ * Place this file at:
8
+ * pages/api/proxy.ts
9
+ */
10
+ export default async function handler(req: NextApiRequest, res: NextApiResponse) {
11
+ const targetUrl = req.query.url as string | undefined;
12
+
13
+ if (!targetUrl) {
14
+ res.status(400).json({ error: 'Missing url query parameter' });
15
+ return;
16
+ }
17
+
18
+ const headers: Record<string, string> = {};
19
+ for (const [key, value] of Object.entries(req.headers)) {
20
+ if (key === 'host' || key === 'x-llmnative-proxy') continue;
21
+ if (typeof value === 'string') headers[key] = value;
22
+ else if (Array.isArray(value)) headers[key] = value.join(', ');
23
+ }
24
+
25
+ const hasBody = !['GET', 'HEAD'].includes(req.method?.toUpperCase() ?? 'GET');
26
+
27
+ const upstream = await fetch(targetUrl, {
28
+ method: req.method,
29
+ headers,
30
+ body: hasBody ? JSON.stringify(req.body) : undefined,
31
+ });
32
+
33
+ res.status(upstream.status);
34
+ upstream.headers.forEach((value, key) => res.setHeader(key, value));
35
+ const buffer = await upstream.arrayBuffer();
36
+ res.end(Buffer.from(buffer));
37
+ }
38
+
39
+ export const config = {
40
+ api: { bodyParser: true },
41
+ };
@@ -0,0 +1,33 @@
1
+ {
2
+ "vite": {
3
+ "label": "Vite dev server",
4
+ "packageExport": "@llmnative/react/vite",
5
+ "exportName": "createProxyPlugin",
6
+ "outputPath": "dev/proxy.ts",
7
+ "hint": "Import createProxyPlugin() and add it to plugins[] in vite.config.ts"
8
+ },
9
+ "express": {
10
+ "label": "Express",
11
+ "templateFile": "express.ts",
12
+ "outputPath": "server/proxy.ts",
13
+ "hint": "Import registerProxy() and mount it with app.use() in your server entry"
14
+ },
15
+ "nextjs-app": {
16
+ "label": "Next.js App Router",
17
+ "templateFile": "nextjs-app.ts",
18
+ "outputPath": "app/api/proxy/route.ts",
19
+ "hint": "File placed at app/api/proxy/route.ts - no extra setup needed"
20
+ },
21
+ "nextjs-pages": {
22
+ "label": "Next.js Pages Router",
23
+ "templateFile": "nextjs-pages.ts",
24
+ "outputPath": "pages/api/proxy.ts",
25
+ "hint": "File placed at pages/api/proxy.ts - no extra setup needed"
26
+ },
27
+ "cloudflare": {
28
+ "label": "Cloudflare Worker / Pages Function",
29
+ "templateFile": "cloudflare.ts",
30
+ "outputPath": "functions/api/proxy.ts",
31
+ "hint": "File placed at functions/api/proxy.ts for Cloudflare Pages, or deploy as a standalone Worker"
32
+ }
33
+ }
@@ -1,85 +1,155 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const root = process.cwd();
5
-
6
- function ensureFile(filePath, content) {
7
- if (!fs.existsSync(filePath)) {
8
- fs.writeFileSync(filePath, content.trimStart());
9
- console.log(`Created file: ${filePath}`);
10
- }
11
- }
12
-
13
- function setupDevTools() {
14
- console.log('Setting up Vite + React + TypeScript');
15
-
16
- ensureFile(path.join(root, 'tsconfig.json'), `
17
- {
18
- "compilerOptions": {
19
- "target": "ES2021",
20
- "useDefineForClassFields": true,
21
- "lib": ["DOM", "DOM.Iterable", "ES2021"],
22
- "allowJs": false,
23
- "skipLibCheck": true,
24
- "esModuleInterop": true,
25
- "allowSyntheticDefaultImports": true,
26
- "strict": true,
27
- "forceConsistentCasingInFileNames": true,
28
- "module": "ESNext",
29
- "moduleResolution": "Bundler",
30
- "resolveJsonModule": true,
31
- "isolatedModules": true,
32
- "noEmit": true,
33
- "jsx": "react-jsx"
34
- },
35
- "include": ["src"],
36
- "references": [{ "path": "./tsconfig.node.json" }]
37
- }
38
- `);
39
-
40
- ensureFile(path.join(root, 'tsconfig.node.json'), `
41
- {
42
- "compilerOptions": {
43
- "composite": true,
44
- "skipLibCheck": true,
45
- "module": "ESNext",
46
- "moduleResolution": "Bundler",
47
- "allowSyntheticDefaultImports": true,
48
- "strict": true
49
- },
50
- "include": ["vite.config.ts"]
51
- }
52
- `);
53
-
54
- ensureFile(path.join(root, 'vite.config.ts'), `
55
- import { defineConfig } from 'vite';
56
- import react from '@vitejs/plugin-react';
57
-
58
- export default defineConfig(({ mode }) => {
59
- return {
60
- plugins: [react()],
61
- resolve: {
62
- dedupe: ['react', 'react-dom', 'react-router-dom'],
63
- },
64
- build: {
65
- cssMinify: false,
66
- chunkSizeWarningLimit: 10000,
67
- },
68
- define: {
69
- 'process.env.NODE_ENV': JSON.stringify(mode === 'production' ? 'production' : 'development'),
70
- },
71
- };
72
- });
73
- `);
74
-
75
- ensureFile(path.join(root, 'postcss.config.js'), `
76
- export default {
77
- plugins: {
78
- '@tailwindcss/postcss': {},
79
- autoprefixer: {},
80
- },
81
- };
82
- `);
83
- }
84
-
85
- module.exports = { setupDevTools };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const root = process.cwd();
5
+ // Templates and the vite/packageExport split live in scripts/cli/proxy-templates/scaffold.json —
6
+ // the same JSON the framework's src/providers/proxy/scaffold.ts imports, so there's one shared
7
+ // source instead of two hand-maintained maps that can drift (as they had before this fix).
8
+ const PROXY_TEMPLATES_DIR = path.resolve(__dirname, 'proxy-templates');
9
+ const PROXY_PROVIDERS = require(path.join(PROXY_TEMPLATES_DIR, 'scaffold.json'));
10
+
11
+ function ensureFile(filePath, content) {
12
+ if (!fs.existsSync(filePath)) {
13
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
14
+ fs.writeFileSync(filePath, content.trimStart());
15
+ console.log(`Created file: ${filePath}`);
16
+ }
17
+ }
18
+
19
+ function ensureDir(dirPath) {
20
+ if (!fs.existsSync(dirPath)) {
21
+ fs.mkdirSync(dirPath, { recursive: true });
22
+ console.log(`Created directory: ${dirPath}`);
23
+ }
24
+ }
25
+
26
+ function copyProxyFile(proxyProvider) {
27
+ const descriptor = PROXY_PROVIDERS[proxyProvider];
28
+ if (!descriptor) return;
29
+
30
+ const dest = path.join(root, descriptor.outputPath);
31
+ ensureDir(path.dirname(dest));
32
+ if (fs.existsSync(dest)) return;
33
+
34
+ if (descriptor.packageExport) {
35
+ // vite only: re-export the framework's own build instead of copying a snapshot that
36
+ // could drift from the real implementation — see dist/vite.mjs / package.json exports.
37
+ fs.writeFileSync(dest, `export { ${descriptor.exportName} } from '${descriptor.packageExport}';\n`);
38
+ console.log(`Created file: ${dest}`);
39
+ return;
40
+ }
41
+
42
+ const src = path.join(PROXY_TEMPLATES_DIR, descriptor.templateFile);
43
+ if (!fs.existsSync(src)) {
44
+ console.warn(`Proxy template not found: ${src}`);
45
+ return;
46
+ }
47
+ fs.copyFileSync(src, dest);
48
+ console.log(`Created file: ${dest}`);
49
+ }
50
+
51
+ function createViteConfig(proxyProvider) {
52
+ const usesVitePlugin = proxyProvider === 'vite';
53
+ const importBlock = usesVitePlugin
54
+ ? "import { createProxyPlugin } from './dev/proxy';\n"
55
+ : '';
56
+ const pluginBlock = usesVitePlugin
57
+ ? " env.VITE_PROXY_ENABLED === 'true' ? createProxyPlugin() : null,\n"
58
+ : '';
59
+
60
+ return `
61
+ import { defineConfig, loadEnv } from 'vite';
62
+ import react from '@vitejs/plugin-react';
63
+ ${importBlock}
64
+ export default defineConfig(({ mode }) => {
65
+ const env = loadEnv(mode, process.cwd(), '');
66
+
67
+ return {
68
+ plugins: [
69
+ react(),
70
+ ${pluginBlock} ].filter(Boolean),
71
+ resolve: {
72
+ dedupe: ['react', 'react-dom', 'react-router-dom'],
73
+ },
74
+ build: {
75
+ cssMinify: false,
76
+ chunkSizeWarningLimit: 10000,
77
+ },
78
+ define: {
79
+ 'process.env.NODE_ENV': JSON.stringify(mode === 'production' ? 'production' : 'development'),
80
+ },
81
+ };
82
+ });
83
+ `;
84
+ }
85
+
86
+ function setupDevTools(options = {}) {
87
+ const proxyProvider = options.proxyProvider ?? 'none';
88
+
89
+ console.log('Setting up Vite + React + TypeScript');
90
+
91
+ ensureFile(path.join(root, 'tsconfig.json'), `
92
+ {
93
+ "compilerOptions": {
94
+ "target": "ES2021",
95
+ "useDefineForClassFields": true,
96
+ "lib": ["DOM", "DOM.Iterable", "ES2021"],
97
+ "allowJs": false,
98
+ "skipLibCheck": true,
99
+ "esModuleInterop": true,
100
+ "allowSyntheticDefaultImports": true,
101
+ "strict": true,
102
+ "forceConsistentCasingInFileNames": true,
103
+ "module": "ESNext",
104
+ "moduleResolution": "Bundler",
105
+ "resolveJsonModule": true,
106
+ "isolatedModules": true,
107
+ "noEmit": true,
108
+ "jsx": "react-jsx"
109
+ },
110
+ "include": ["src"],
111
+ "references": [{ "path": "./tsconfig.node.json" }]
112
+ }
113
+ `);
114
+
115
+ ensureFile(path.join(root, 'tsconfig.node.json'), `
116
+ {
117
+ "compilerOptions": {
118
+ "composite": true,
119
+ "skipLibCheck": true,
120
+ "module": "ESNext",
121
+ "moduleResolution": "Bundler",
122
+ "allowSyntheticDefaultImports": true,
123
+ "strict": true
124
+ },
125
+ "include": ["vite.config.ts", "dev/**/*.ts", "server/**/*.ts"]
126
+ }
127
+ `);
128
+
129
+ if (proxyProvider !== 'none') {
130
+ copyProxyFile(proxyProvider);
131
+ }
132
+
133
+ ensureFile(path.join(root, 'vite.config.ts'), createViteConfig(proxyProvider));
134
+
135
+ ensureFile(path.join(root, 'postcss.config.js'), `
136
+ export default {
137
+ plugins: {
138
+ '@tailwindcss/postcss': {},
139
+ autoprefixer: {},
140
+ },
141
+ };
142
+ `);
143
+
144
+ if (proxyProvider !== 'none' && PROXY_PROVIDERS[proxyProvider]) {
145
+ console.log(`\nProxy file created: ${PROXY_PROVIDERS[proxyProvider].outputPath}`);
146
+ if (proxyProvider === 'express') {
147
+ console.log(' → Add registerProxy(app) to your server entry file.');
148
+ }
149
+ if (proxyProvider === 'vite') {
150
+ console.log(' → createProxyPlugin() is already wired into vite.config.ts.');
151
+ }
152
+ }
153
+ }
154
+
155
+ module.exports = { setupDevTools, PROXY_PROVIDERS };