@llmnative/react 0.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 (150) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +375 -0
  3. package/bin/cli.js +99 -0
  4. package/dist/index.css +1 -0
  5. package/dist/index.js +838 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +12161 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/dist/types/src/App.d.ts +64 -0
  10. package/dist/types/src/Config.d.ts +65 -0
  11. package/dist/types/src/Global.d.ts +12 -0
  12. package/dist/types/src/Head.d.ts +193 -0
  13. package/dist/types/src/Theme.d.ts +335 -0
  14. package/dist/types/src/auth.d.ts +27 -0
  15. package/dist/types/src/components/Component.d.ts +55 -0
  16. package/dist/types/src/components/FormEnhancer.d.ts +26 -0
  17. package/dist/types/src/components/Template.d.ts +18 -0
  18. package/dist/types/src/components/blocks/Brand.d.ts +14 -0
  19. package/dist/types/src/components/blocks/Breadcrumbs.d.ts +8 -0
  20. package/dist/types/src/components/blocks/Carousel.d.ts +19 -0
  21. package/dist/types/src/components/blocks/Dropdown.d.ts +64 -0
  22. package/dist/types/src/components/blocks/Menu.d.ts +24 -0
  23. package/dist/types/src/components/blocks/Notifications.d.ts +15 -0
  24. package/dist/types/src/components/blocks/Search.d.ts +7 -0
  25. package/dist/types/src/components/index.d.ts +52 -0
  26. package/dist/types/src/components/types.d.ts +11 -0
  27. package/dist/types/src/components/ui/Alert.d.ts +13 -0
  28. package/dist/types/src/components/ui/Badge.d.ts +27 -0
  29. package/dist/types/src/components/ui/Buttons.d.ts +57 -0
  30. package/dist/types/src/components/ui/Card.d.ts +15 -0
  31. package/dist/types/src/components/ui/Code.d.ts +25 -0
  32. package/dist/types/src/components/ui/Gallery.d.ts +55 -0
  33. package/dist/types/src/components/ui/GridSystem.d.ts +21 -0
  34. package/dist/types/src/components/ui/Icon.d.ts +13 -0
  35. package/dist/types/src/components/ui/Image.d.ts +19 -0
  36. package/dist/types/src/components/ui/ImageAvatar.d.ts +16 -0
  37. package/dist/types/src/components/ui/LayoutBuilder.d.ts +19 -0
  38. package/dist/types/src/components/ui/Loader.d.ts +11 -0
  39. package/dist/types/src/components/ui/Modal.d.ts +39 -0
  40. package/dist/types/src/components/ui/Pagination.d.ts +18 -0
  41. package/dist/types/src/components/ui/Percentage.d.ts +19 -0
  42. package/dist/types/src/components/ui/Repeat.d.ts +18 -0
  43. package/dist/types/src/components/ui/Tab.d.ts +20 -0
  44. package/dist/types/src/components/ui/TabDynamic.d.ts +20 -0
  45. package/dist/types/src/components/ui/Table.d.ts +43 -0
  46. package/dist/types/src/components/ui/fields/AssistantAI.d.ts +23 -0
  47. package/dist/types/src/components/ui/fields/Command.d.ts +15 -0
  48. package/dist/types/src/components/ui/fields/Crop.d.ts +27 -0
  49. package/dist/types/src/components/ui/fields/ImageUrl.d.ts +7 -0
  50. package/dist/types/src/components/ui/fields/Input.d.ts +62 -0
  51. package/dist/types/src/components/ui/fields/Prompt.d.ts +31 -0
  52. package/dist/types/src/components/ui/fields/Select.d.ts +38 -0
  53. package/dist/types/src/components/ui/fields/Upload.d.ts +25 -0
  54. package/dist/types/src/components/ui/fields/UploadCSV.d.ts +26 -0
  55. package/dist/types/src/components/ui/useRecordSelection.d.ts +20 -0
  56. package/dist/types/src/components/ui/useStableRecordKey.d.ts +5 -0
  57. package/dist/types/src/components/widgets/Form.d.ts +129 -0
  58. package/dist/types/src/components/widgets/Grid.d.ts +6 -0
  59. package/dist/types/src/components/widgets/ImageEditor.d.ts +14 -0
  60. package/dist/types/src/components/widgets/MarkdownReader.d.ts +14 -0
  61. package/dist/types/src/components/widgets/Prompt.d.ts +31 -0
  62. package/dist/types/src/components/widgets/TabDynamic.d.ts +20 -0
  63. package/dist/types/src/components/widgets/grid-core/GridArray.d.ts +5 -0
  64. package/dist/types/src/components/widgets/grid-core/GridCore.d.ts +5 -0
  65. package/dist/types/src/components/widgets/grid-core/GridDB.d.ts +5 -0
  66. package/dist/types/src/components/widgets/grid-core/GridGalleryView.d.ts +5 -0
  67. package/dist/types/src/components/widgets/grid-core/GridTableView.d.ts +5 -0
  68. package/dist/types/src/components/widgets/grid-core/index.d.ts +7 -0
  69. package/dist/types/src/components/widgets/grid-core/resolveGridPathFromUrl.d.ts +1 -0
  70. package/dist/types/src/components/widgets/grid-core/types.d.ts +227 -0
  71. package/dist/types/src/components/widgets/grid-core/useGridActions.d.ts +49 -0
  72. package/dist/types/src/components/widgets/grid-core/useGridColumns.d.ts +10 -0
  73. package/dist/types/src/components/widgets/grid-core/useGridDBRecords.d.ts +10 -0
  74. package/dist/types/src/components/widgets/grid-core/useGridPreparedRecords.d.ts +10 -0
  75. package/dist/types/src/components/widgets/grid-core/useGridSelection.d.ts +13 -0
  76. package/dist/types/src/components/widgets/grid-core/utils.d.ts +14 -0
  77. package/dist/types/src/conf/Prompt.d.ts +84 -0
  78. package/dist/types/src/constant.d.ts +96 -0
  79. package/dist/types/src/index.d.ts +56 -0
  80. package/dist/types/src/libs/cache.d.ts +9 -0
  81. package/dist/types/src/libs/cn.d.ts +2 -0
  82. package/dist/types/src/libs/converter.d.ts +28 -0
  83. package/dist/types/src/libs/database.d.ts +3 -0
  84. package/dist/types/src/libs/email.d.ts +16 -0
  85. package/dist/types/src/libs/fetch.d.ts +9 -0
  86. package/dist/types/src/libs/imageBuilder.d.ts +112 -0
  87. package/dist/types/src/libs/index.d.ts +14 -0
  88. package/dist/types/src/libs/locale.d.ts +24 -0
  89. package/dist/types/src/libs/log.d.ts +2 -0
  90. package/dist/types/src/libs/order.d.ts +14 -0
  91. package/dist/types/src/libs/path.d.ts +26 -0
  92. package/dist/types/src/libs/sanitizer.d.ts +38 -0
  93. package/dist/types/src/libs/seo.d.ts +8 -0
  94. package/dist/types/src/libs/storage.d.ts +2 -0
  95. package/dist/types/src/libs/utils.d.ts +57 -0
  96. package/dist/types/src/motion.d.ts +38 -0
  97. package/dist/types/src/pages/Blog.d.ts +3 -0
  98. package/dist/types/src/pages/BlogPost.d.ts +16 -0
  99. package/dist/types/src/pages/Helper.d.ts +8 -0
  100. package/dist/types/src/pages/NotFound.d.ts +3 -0
  101. package/dist/types/src/pages/Users.d.ts +3 -0
  102. package/dist/types/src/pages/index.d.ts +3 -0
  103. package/dist/types/src/providers/ProviderConfiguration.d.ts +12 -0
  104. package/dist/types/src/providers/ai/index.d.ts +134 -0
  105. package/dist/types/src/providers/auth/AuthProvider.d.ts +22 -0
  106. package/dist/types/src/providers/auth/AuthProviderContext.d.ts +12 -0
  107. package/dist/types/src/providers/auth/dropbox/DropboxAuthProvider.d.ts +16 -0
  108. package/dist/types/src/providers/auth/google/GoogleAuth.d.ts +44 -0
  109. package/dist/types/src/providers/auth/google/GoogleAuthProvider.d.ts +12 -0
  110. package/dist/types/src/providers/auth/google/apis/auth.d.ts +4 -0
  111. package/dist/types/src/providers/auth/google/auth.d.ts +3 -0
  112. package/dist/types/src/providers/data/DataProvider.d.ts +58 -0
  113. package/dist/types/src/providers/data/DataProviderContext.d.ts +12 -0
  114. package/dist/types/src/providers/data/firebase.d.ts +21 -0
  115. package/dist/types/src/providers/data/mock.d.ts +20 -0
  116. package/dist/types/src/providers/data/supabase.d.ts +19 -0
  117. package/dist/types/src/providers/email/EmailProvider.d.ts +10 -0
  118. package/dist/types/src/providers/email/EmailProviderContext.d.ts +12 -0
  119. package/dist/types/src/providers/email/google/GmailEmailProvider.d.ts +7 -0
  120. package/dist/types/src/providers/email/google/apis/email.d.ts +7 -0
  121. package/dist/types/src/providers/email/google/email.d.ts +13 -0
  122. package/dist/types/src/providers/firebase-init.d.ts +10 -0
  123. package/dist/types/src/providers/icon/IconProvider.d.ts +10 -0
  124. package/dist/types/src/providers/icon/IconProviderContext.d.ts +48 -0
  125. package/dist/types/src/providers/icon/LucideIconProvider.d.ts +5 -0
  126. package/dist/types/src/providers/icon/PhosphorIconProvider.d.ts +10 -0
  127. package/dist/types/src/providers/icon/index.d.ts +6 -0
  128. package/dist/types/src/providers/manifest.d.ts +42 -0
  129. package/dist/types/src/providers/scrape/index.d.ts +10 -0
  130. package/dist/types/src/providers/seo/google/keyword.d.ts +14 -0
  131. package/dist/types/src/providers/seo/google/trend.d.ts +25 -0
  132. package/dist/types/src/providers/storage/StorageProvider.d.ts +7 -0
  133. package/dist/types/src/providers/storage/StorageProviderContext.d.ts +12 -0
  134. package/dist/types/src/providers/storage/dropbox.d.ts +48 -0
  135. package/dist/types/src/providers/storage/firebase.d.ts +13 -0
  136. package/dist/types/src/providers/storage/supabase.d.ts +19 -0
  137. package/dist/types/src/types/Block.d.ts +4 -0
  138. package/dist/types/src/types/FormFields.d.ts +33 -0
  139. package/dist/types/src/types/Layout.d.ts +9 -0
  140. package/dist/types/src/types/Section.d.ts +4 -0
  141. package/dist/types/themes/cyber.d.ts +7 -0
  142. package/dist/types/themes/default.d.ts +7 -0
  143. package/dist/types/themes/flat.d.ts +7 -0
  144. package/package.json +126 -0
  145. package/scripts/cli/create-section.js +65 -0
  146. package/scripts/cli/setup-devtools.js +85 -0
  147. package/scripts/cli/setup-project.js +484 -0
  148. package/themes/cyber.ts +405 -0
  149. package/themes/default.ts +405 -0
  150. package/themes/flat.ts +405 -0
@@ -0,0 +1,484 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const readline = require('readline');
4
+
5
+ const root = process.cwd();
6
+ const args = process.argv.slice(2);
7
+ const shouldReset = args.includes('--reset');
8
+
9
+ function getArg(name, fallback = '') {
10
+ const prefix = `--${name}=`;
11
+ const arg = args.find((item) => item.startsWith(prefix));
12
+ return arg ? arg.slice(prefix.length) : fallback;
13
+ }
14
+
15
+ function ensureDir(dirPath) {
16
+ if (!fs.existsSync(dirPath)) {
17
+ fs.mkdirSync(dirPath, { recursive: true });
18
+ console.log(`Created directory: ${dirPath}`);
19
+ }
20
+ }
21
+
22
+ function ensureFile(filePath, content) {
23
+ ensureDir(path.dirname(filePath));
24
+ if (!fs.existsSync(filePath)) {
25
+ fs.writeFileSync(filePath, content.trimStart());
26
+ console.log(`Created file: ${filePath}`);
27
+ }
28
+ }
29
+
30
+ function resetProjectDirectory() {
31
+ console.log('Resetting scaffold files...');
32
+ [
33
+ 'src',
34
+ 'public',
35
+ 'dist',
36
+ '.env',
37
+ '.firebaserc',
38
+ 'database.rules.json',
39
+ 'firebase.json',
40
+ 'storage.rules',
41
+ 'index.html',
42
+ 'vite.config.ts',
43
+ 'tsconfig.json',
44
+ 'tsconfig.node.json',
45
+ 'postcss.config.js',
46
+ ].forEach((entry) => {
47
+ const entryPath = path.join(root, entry);
48
+ if (fs.existsSync(entryPath)) {
49
+ fs.rmSync(entryPath, { recursive: true, force: true });
50
+ console.log(`Removed: ${entryPath}`);
51
+ }
52
+ });
53
+ }
54
+
55
+ async function askInteractive(callback) {
56
+ const rl = readline.createInterface({
57
+ input: process.stdin,
58
+ output: process.stdout,
59
+ });
60
+
61
+ const question = (text) => new Promise((resolve) => rl.question(text, resolve));
62
+ const defaultName = path.basename(root);
63
+
64
+ try {
65
+ const projectnameInput = await question(`What is your project name? (default: ${defaultName}) `);
66
+ const projectname = projectnameInput.trim() || defaultName;
67
+
68
+ const providerInput = await question('Which data provider? (firebase, supabase, mock, custom; default: mock) ');
69
+ const provider = ['firebase', 'supabase', 'mock', 'custom'].includes(providerInput.trim())
70
+ ? providerInput.trim()
71
+ : 'mock';
72
+
73
+ const iconProviderInput = await question('Which icon provider? (lucide, phosphor; default: lucide) ');
74
+ const iconProvider = ['lucide', 'phosphor'].includes(iconProviderInput.trim())
75
+ ? iconProviderInput.trim()
76
+ : 'lucide';
77
+
78
+ const themeInput = await question('Which theme? (default, flat, cyber; default: default) ');
79
+ const theme = ['default', 'flat', 'cyber'].includes(themeInput.trim())
80
+ ? themeInput.trim()
81
+ : 'default';
82
+
83
+ const templateInput = await question('Which app template? (blank, crm, admin, inventory, project; default: blank) ');
84
+ const template = ['blank', 'crm', 'admin', 'inventory', 'project'].includes(templateInput.trim())
85
+ ? templateInput.trim()
86
+ : 'blank';
87
+
88
+ let hosting = 'n';
89
+ const firebase = {};
90
+ const supabase = {};
91
+
92
+ if (provider === 'firebase') {
93
+ const hostingInput = await question(`Firebase Hosting site? Leave blank to use "${defaultName}", type 'n' to disable: `);
94
+ hosting = hostingInput.trim();
95
+
96
+ firebase.apikey = (await question('Firebase API key: ')).trim();
97
+ firebase.authDomain = (await question('Firebase Auth Domain: ')).trim();
98
+ firebase.dbUrl = (await question('Firebase Database URL: ')).trim();
99
+ firebase.projId = (await question('Firebase Project ID: ')).trim();
100
+ firebase.storageBucket = (await question('Firebase Storage Bucket: ')).trim();
101
+ firebase.messSenderId = (await question('Firebase Messaging Sender ID: ')).trim();
102
+ firebase.appId = (await question('Firebase App ID: ')).trim();
103
+ firebase.measurementId = (await question('Firebase Measurement ID: ')).trim();
104
+ firebase.googleClientId = (await question('Google Client ID: ')).trim();
105
+ }
106
+
107
+ if (provider === 'supabase') {
108
+ supabase.url = (await question('Supabase URL: ')).trim();
109
+ supabase.anonKey = (await question('Supabase anon key: ')).trim();
110
+ }
111
+
112
+ rl.close();
113
+ callback({ projectname, provider, iconProvider, theme, template, hosting, firebase, supabase });
114
+ } catch (error) {
115
+ rl.close();
116
+ console.error('Error during interactive prompt:', error);
117
+ }
118
+ }
119
+
120
+ function normalizeFirebaseProjectId(projectName) {
121
+ return String(projectName ?? '')
122
+ .trim()
123
+ .replace(/^[A-Z]/, (m) => m.toLowerCase())
124
+ .replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)
125
+ .replace(/\s+/g, '-')
126
+ .replace(/[^a-z0-9-]/g, '-')
127
+ .replace(/-+/g, '-')
128
+ .replace(/^-+|-+$/g, '');
129
+ }
130
+
131
+ function createPackageJson(params) {
132
+ const packagePath = path.resolve(__dirname, '../../package.json');
133
+ const version = JSON.parse(fs.readFileSync(packagePath, 'utf8')).version;
134
+
135
+ ensureFile(path.join(root, 'package.json'), JSON.stringify({
136
+ name: normalizeFirebaseProjectId(params.projectname) || 'ash-app',
137
+ version: '0.1.0',
138
+ private: true,
139
+ type: 'module',
140
+ scripts: {
141
+ dev: 'vite',
142
+ build: 'vite build',
143
+ preview: 'vite preview',
144
+ typecheck: 'tsc --noEmit',
145
+ },
146
+ dependencies: {
147
+ '@phosphor-icons/react': '^2.0.0',
148
+ '@vitejs/plugin-react': '^4.3.4',
149
+ firebase: '^10.14.0',
150
+ 'lucide-react': '^0.400.0',
151
+ react: '^18.2.0',
152
+ 'react-dom': '^18.2.0',
153
+ '@llmnative/react': `^${version}`,
154
+ 'react-router-dom': '^6.22.0',
155
+ },
156
+ devDependencies: {
157
+ '@tailwindcss/postcss': '^4.2.4',
158
+ '@types/react': '^18.2.0',
159
+ '@types/react-dom': '^18.2.0',
160
+ autoprefixer: '^10.5.0',
161
+ postcss: '^8.5.14',
162
+ typescript: '^5.6.2',
163
+ vite: '^5.4.21',
164
+ },
165
+ }, null, 2));
166
+ }
167
+
168
+ function createDevTools() {
169
+ require('./setup-devtools').setupDevTools();
170
+ }
171
+
172
+ function createIndexHtml(params) {
173
+ ensureFile(path.join(root, 'index.html'), `
174
+ <!doctype html>
175
+ <html lang="en">
176
+ <head>
177
+ <meta charset="UTF-8" />
178
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
179
+ <title>${params.projectname}</title>
180
+ </head>
181
+ <body>
182
+ <div id="root"></div>
183
+ <script type="module" src="/src/index.tsx"></script>
184
+ </body>
185
+ </html>
186
+ `);
187
+ }
188
+
189
+ function createEnvFile(params) {
190
+ const env = [
191
+ `VITE_PROVIDER=${params.provider}`,
192
+ `VITE_ICON_PROVIDER=${params.iconProvider}`,
193
+ `VITE_THEME=${params.theme}`,
194
+ `VITE_FIREBASE_APIKEY=${params.firebase.apikey ?? ''}`,
195
+ `VITE_FIREBASE_AUTH_DOMAIN=${params.firebase.authDomain ?? ''}`,
196
+ `VITE_FIREBASE_DATABASE_URL=${params.firebase.dbUrl ?? ''}`,
197
+ `VITE_FIREBASE_PROJECT_ID=${params.firebase.projId ?? ''}`,
198
+ `VITE_FIREBASE_STORAGE_BUCKET=${params.firebase.storageBucket ?? ''}`,
199
+ `VITE_FIREBASE_MESSAGING_SENDER_ID=${params.firebase.messSenderId ?? ''}`,
200
+ `VITE_FIREBASE_APP_ID=${params.firebase.appId ?? ''}`,
201
+ `VITE_FIREBASE_MEASUREMENT_ID=${params.firebase.measurementId ?? ''}`,
202
+ `VITE_GOOGLE_CLIENT_ID=${params.firebase.googleClientId ?? ''}`,
203
+ 'VITE_GOOGLE_SCOPE=',
204
+ `VITE_SUPABASE_URL=${params.supabase.url ?? ''}`,
205
+ `VITE_SUPABASE_ANON_KEY=${params.supabase.anonKey ?? ''}`,
206
+ ].join('\n');
207
+
208
+ ensureFile(path.join(root, '.env'), `${env}\n`);
209
+ }
210
+
211
+ function createFirebaseConfig(params) {
212
+ if (params.provider !== 'firebase') return;
213
+
214
+ ensureFile(path.join(root, '.firebaserc'), JSON.stringify({
215
+ projects: { default: params.projectname },
216
+ }, null, 2));
217
+
218
+ const includeHosting = params.hosting.toLowerCase() !== 'n';
219
+ const hostingSite = params.hosting === '' ? params.projectname : params.hosting;
220
+
221
+ ensureFile(path.join(root, 'firebase.json'), JSON.stringify({
222
+ database: { rules: 'database.rules.json' },
223
+ ...(includeHosting && {
224
+ hosting: {
225
+ site: normalizeFirebaseProjectId(hostingSite),
226
+ public: 'dist',
227
+ ignore: ['firebase.json', '**/.*', '**/node_modules/**'],
228
+ predeploy: ['npm run build'],
229
+ rewrites: [{ source: '**', destination: '/index.html' }],
230
+ },
231
+ }),
232
+ }, null, 2));
233
+
234
+ ensureFile(path.join(root, 'database.rules.json'), JSON.stringify({
235
+ rules: {
236
+ '.read': 'auth != null',
237
+ '.write': 'auth != null',
238
+ },
239
+ }, null, 2));
240
+
241
+ ensureFile(path.join(root, 'storage.rules'), `
242
+ rules_version = '2';
243
+
244
+ service firebase.storage {
245
+ match /b/{bucket}/o {
246
+ match /{allPaths=**} {
247
+ allow read, write: if request.auth != null;
248
+ }
249
+ }
250
+ }
251
+ `);
252
+ }
253
+
254
+ function copyDir(src, dest) {
255
+ if (!fs.existsSync(src)) return;
256
+ fs.readdirSync(src, { withFileTypes: true }).forEach((entry) => {
257
+ const srcPath = path.join(src, entry.name);
258
+ const destPath = path.join(dest, entry.name);
259
+ if (entry.isDirectory()) {
260
+ copyDir(srcPath, destPath);
261
+ } else {
262
+ ensureDir(path.dirname(destPath));
263
+ if (!fs.existsSync(destPath)) {
264
+ fs.copyFileSync(srcPath, destPath);
265
+ console.log(`Created file: ${destPath}`);
266
+ }
267
+ }
268
+ });
269
+ }
270
+
271
+ function substituteProjectName(filePath, projectname) {
272
+ const content = fs.readFileSync(filePath, 'utf8');
273
+ const updated = content.replace(/\[projectname\]/g, projectname);
274
+ if (updated !== content) fs.writeFileSync(filePath, updated);
275
+ }
276
+
277
+ function copyTemplateFiles(params) {
278
+ const sharedSrc = path.resolve(__dirname, '../../templates/_shared');
279
+ const templateSrc = path.resolve(__dirname, `../../templates/${params.template}`);
280
+
281
+ // Copy shared layouts and sections
282
+ copyDir(path.join(sharedSrc, 'layouts'), path.join(root, 'src/layouts'));
283
+ copyDir(path.join(sharedSrc, 'sections'), path.join(root, 'src/sections'));
284
+
285
+ // Copy template-specific files (pages, data, conf/menu.ts)
286
+ // layouts and sections from template override shared ones if present
287
+ copyDir(templateSrc, path.join(root, 'src'));
288
+
289
+ // Substitute [projectname] in copied files
290
+ ['src/layouts', 'src/sections', 'src/pages'].forEach((dir) => {
291
+ const absDir = path.join(root, dir);
292
+ if (!fs.existsSync(absDir)) return;
293
+ walkFiles(absDir, (file) => substituteProjectName(file, params.projectname));
294
+ });
295
+ }
296
+
297
+ function walkFiles(dir, fn) {
298
+ fs.readdirSync(dir, { withFileTypes: true }).forEach((entry) => {
299
+ const full = path.join(dir, entry.name);
300
+ if (entry.isDirectory()) walkFiles(full, fn);
301
+ else fn(full);
302
+ });
303
+ }
304
+
305
+ function createSourceFiles(params) {
306
+ copyTemplateFiles(params);
307
+
308
+ ensureFile(path.join(root, 'src/vite-env.d.ts'), `
309
+ /// <reference types="vite/client" />
310
+ `);
311
+
312
+ ensureFile(path.join(root, 'src/styles/globals.css'), `
313
+ @import "tailwindcss";
314
+ @import "@llmnative/react/dist/index.css";
315
+
316
+ @theme inline {
317
+ --color-background: hsl(var(--rf-background));
318
+ --color-foreground: hsl(var(--rf-foreground));
319
+ --color-card: hsl(var(--rf-card));
320
+ --color-card-foreground: hsl(var(--rf-card-foreground));
321
+ --color-popover: hsl(var(--rf-popover));
322
+ --color-popover-foreground: hsl(var(--rf-popover-foreground));
323
+ --color-primary: hsl(var(--rf-primary));
324
+ --color-primary-foreground: hsl(var(--rf-primary-foreground));
325
+ --color-secondary: hsl(var(--rf-secondary));
326
+ --color-secondary-foreground: hsl(var(--rf-secondary-foreground));
327
+ --color-muted: hsl(var(--rf-muted));
328
+ --color-muted-foreground: hsl(var(--rf-muted-foreground));
329
+ --color-accent: hsl(var(--rf-accent));
330
+ --color-accent-foreground: hsl(var(--rf-accent-foreground));
331
+ --color-destructive: hsl(var(--rf-destructive));
332
+ --color-destructive-foreground: hsl(var(--rf-destructive-foreground));
333
+ --color-success: hsl(var(--rf-success));
334
+ --color-success-foreground: hsl(var(--rf-success-foreground));
335
+ --color-warning: hsl(var(--rf-warning));
336
+ --color-warning-foreground: hsl(var(--rf-warning-foreground));
337
+ --color-info: hsl(var(--rf-info));
338
+ --color-info-foreground: hsl(var(--rf-info-foreground));
339
+ --color-border: hsl(var(--rf-border));
340
+ --color-input: hsl(var(--rf-input));
341
+ --color-ring: hsl(var(--rf-ring));
342
+ --radius: 0.5rem;
343
+ }
344
+
345
+ html, body, #root {
346
+ min-height: 100%;
347
+ }
348
+
349
+ body {
350
+ margin: 0;
351
+ font-family: var(--font-sans);
352
+ background-color: hsl(var(--rf-background));
353
+ color: hsl(var(--rf-foreground));
354
+ }
355
+ `);
356
+
357
+ ensureFile(path.join(root, 'src/conf/app.ts'), `
358
+ const env = import.meta.env;
359
+
360
+ export const appConfig = {
361
+ provider: env.VITE_PROVIDER ?? '${params.provider}',
362
+ iconProvider: env.VITE_ICON_PROVIDER ?? '${params.iconProvider}',
363
+ theme: env.VITE_THEME ?? '${params.theme}',
364
+ };
365
+ `);
366
+
367
+ ensureFile(path.join(root, 'src/index.tsx'), `
368
+ import React from 'react';
369
+ import { createRoot } from 'react-dom/client';
370
+ import { App } from '@llmnative/react';
371
+ import './styles/globals.css';
372
+
373
+ import { appConfig } from './conf/app';
374
+ import { menu } from './conf/menu';
375
+ import { mockData } from './data/mockData';
376
+
377
+ const env = import.meta.env;
378
+ const selectedProvider = appConfig.provider;
379
+ const dataDriver =
380
+ selectedProvider === 'firebase' ? 'dbRealtime'
381
+ : selectedProvider === 'supabase' ? 'supabaseDb'
382
+ : 'mock';
383
+ const storageDriver =
384
+ selectedProvider === 'firebase' ? 'firestorage'
385
+ : selectedProvider === 'supabase' ? 'supabaseStorage'
386
+ : undefined;
387
+
388
+ createRoot(document.getElementById('root')!).render(
389
+ <React.StrictMode>
390
+ <App
391
+ importPage={(pageSource) => import(/* @vite-ignore */ pageSource)}
392
+ menuConfig={menu}
393
+ providers={{
394
+ mock: {
395
+ data: mockData,
396
+ },
397
+ firebase: {
398
+ apiKey: env.VITE_FIREBASE_APIKEY ?? '',
399
+ authDomain: env.VITE_FIREBASE_AUTH_DOMAIN ?? '',
400
+ databaseURL: env.VITE_FIREBASE_DATABASE_URL ?? '',
401
+ projectId: env.VITE_FIREBASE_PROJECT_ID ?? '',
402
+ storageBucket: env.VITE_FIREBASE_STORAGE_BUCKET ?? '',
403
+ messagingSenderId: env.VITE_FIREBASE_MESSAGING_SENDER_ID ?? '',
404
+ appId: env.VITE_FIREBASE_APP_ID ?? '',
405
+ measurementId: env.VITE_FIREBASE_MEASUREMENT_ID ?? '',
406
+ },
407
+ supabase: {
408
+ url: env.VITE_SUPABASE_URL ?? '',
409
+ anonKey: env.VITE_SUPABASE_ANON_KEY ?? '',
410
+ },
411
+ google: {
412
+ clientId: env.VITE_GOOGLE_CLIENT_ID ?? '',
413
+ scope: env.VITE_GOOGLE_SCOPE ?? '',
414
+ },
415
+ services: {
416
+ data: dataDriver,
417
+ storage: storageDriver,
418
+ auth: 'googleAuth',
419
+ },
420
+ }}
421
+ iconProvider={appConfig.iconProvider}
422
+ themeProvider={appConfig.theme}
423
+ />
424
+ </React.StrictMode>
425
+ );
426
+ `);
427
+ }
428
+
429
+ function scaffoldProject() {
430
+ const nonInteractive = args.includes('--yes') || args.some((arg) => arg.startsWith('--provider='));
431
+ if (nonInteractive) {
432
+ const defaultName = path.basename(root);
433
+ const params = {
434
+ projectname: getArg('name', defaultName),
435
+ provider: getArg('provider', 'mock'),
436
+ iconProvider: getArg('icon-provider', 'lucide'),
437
+ theme: getArg('theme', getArg('theme-provider', 'default')),
438
+ template: getArg('template', 'blank'),
439
+ hosting: getArg('hosting', 'n'),
440
+ firebase: {
441
+ apikey: getArg('firebase-api-key'),
442
+ authDomain: getArg('firebase-auth-domain'),
443
+ dbUrl: getArg('firebase-database-url'),
444
+ projId: getArg('firebase-project-id'),
445
+ storageBucket: getArg('firebase-storage-bucket'),
446
+ messSenderId: getArg('firebase-messaging-sender-id'),
447
+ appId: getArg('firebase-app-id'),
448
+ measurementId: getArg('firebase-measurement-id'),
449
+ googleClientId:getArg('google-client-id'),
450
+ },
451
+ supabase: {
452
+ url: getArg('supabase-url'),
453
+ anonKey: getArg('supabase-anon-key'),
454
+ },
455
+ };
456
+
457
+ if (shouldReset) resetProjectDirectory();
458
+
459
+ console.log(`\nCreating project: ${params.projectname} | theme: ${params.theme} | template: ${params.template}\n`);
460
+ createPackageJson(params);
461
+ createDevTools();
462
+ createIndexHtml(params);
463
+ createEnvFile(params);
464
+ createFirebaseConfig(params);
465
+ createSourceFiles(params);
466
+ console.log(`\nDone. Run: npm install && npm run dev\n`);
467
+ return;
468
+ }
469
+
470
+ askInteractive((params) => {
471
+ if (shouldReset) resetProjectDirectory();
472
+
473
+ console.log(`\nCreating project: ${params.projectname} | theme: ${params.theme} | template: ${params.template}\n`);
474
+ createPackageJson(params);
475
+ createDevTools();
476
+ createIndexHtml(params);
477
+ createEnvFile(params);
478
+ createFirebaseConfig(params);
479
+ createSourceFiles(params);
480
+ console.log(`\nDone. Run: npm install && npm run dev\n`);
481
+ });
482
+ }
483
+
484
+ module.exports = { scaffoldProject };