@donotdev/cli 0.0.4 → 0.0.6

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 (54) hide show
  1. package/dependencies-matrix.json +234 -114
  2. package/dist/bin/commands/build.js +9 -3
  3. package/dist/bin/commands/bump.js +119 -100
  4. package/dist/bin/commands/cacheout.js +9 -3
  5. package/dist/bin/commands/create-app.js +60 -34
  6. package/dist/bin/commands/create-project.js +61 -34
  7. package/dist/bin/commands/deploy.js +22 -14
  8. package/dist/bin/commands/dev.js +9 -3
  9. package/dist/bin/commands/emu.js +9 -3
  10. package/dist/bin/commands/format.js +9 -3
  11. package/dist/bin/commands/lint.js +9 -3
  12. package/dist/bin/commands/make-admin.d.ts +11 -0
  13. package/dist/bin/commands/make-admin.d.ts.map +1 -0
  14. package/dist/bin/commands/make-admin.js +12 -0
  15. package/dist/bin/commands/make-admin.js.map +1 -0
  16. package/dist/bin/commands/preview.js +9 -3
  17. package/dist/bin/commands/sync-secrets.js +9 -3
  18. package/dist/index.js +72 -44
  19. package/package.json +1 -1
  20. package/templates/app-demo/index.html.example +4 -0
  21. package/templates/app-demo/src/App.tsx.example +28 -10
  22. package/templates/app-demo/src/config/app.ts.example +56 -0
  23. package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +5 -5
  24. package/templates/app-next/src/app/ClientLayout.tsx.example +5 -4
  25. package/templates/app-next/src/app/layout.tsx.example +17 -25
  26. package/templates/app-next/src/globals.css.example +10 -7
  27. package/templates/app-next/src/locales/dndev_en.json.example +68 -0
  28. package/templates/app-next/src/pages/locales/example_en.json.example +5 -0
  29. package/templates/app-vite/index.html.example +3 -0
  30. package/templates/app-vite/src/App.tsx.example +1 -1
  31. package/templates/app-vite/src/globals.css.example +14 -6
  32. package/templates/app-vite/src/locales/dndev_en.json.example +68 -0
  33. package/templates/functions-firebase/README.md.example +25 -0
  34. package/templates/functions-firebase/tsconfig.json.example +3 -13
  35. package/templates/functions-vercel/tsconfig.json.example +1 -13
  36. package/templates/root-consumer/firebase.json.example +1 -1
  37. package/templates/root-consumer/guides/AGENT_START_HERE.md.example +229 -7
  38. package/templates/root-consumer/guides/COMPONENTS_ADV.md.example +456 -0
  39. package/templates/root-consumer/guides/COMPONENTS_ATOMIC.md.example +43 -1
  40. package/templates/root-consumer/guides/COMPONENTS_UI.md.example +6 -0
  41. package/templates/root-consumer/guides/INDEX.md.example +3 -0
  42. package/templates/root-consumer/guides/SETUP_APP_CONFIG.md.example +5 -2
  43. package/templates/root-consumer/guides/SETUP_BILLING.md.example +44 -4
  44. package/templates/root-consumer/guides/SETUP_CRUD.md.example +1244 -0
  45. package/templates/root-consumer/guides/SETUP_FUNCTIONS.md.example +52 -0
  46. package/templates/root-consumer/guides/SETUP_I18N.md.example +145 -6
  47. package/templates/root-consumer/guides/SETUP_LAYOUTS.md.example +18 -0
  48. package/templates/root-consumer/guides/SETUP_PAGES.md.example +25 -0
  49. package/templates/root-consumer/guides/SETUP_PWA.md.example +213 -0
  50. package/templates/root-consumer/guides/USE_ROUTING.md.example +503 -0
  51. package/templates/root-consumer/vercel.json.example +315 -20
  52. package/templates/app-demo/src/Routes.tsx.example +0 -20
  53. package/templates/app-vite/src/Routes.tsx.example +0 -16
  54. package/templates/app-vite/src/pages/locales/README.md.example +0 -1
@@ -4,6 +4,31 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## ⚠️ CRITICAL: Import Rules for Functions
8
+
9
+ **Functions run on Node.js - you MUST use `/server` imports or your function will crash on deploy.**
10
+
11
+ ```typescript
12
+ // ✅ CORRECT - Functions MUST use /server imports
13
+ import { getFirebaseAdminAuth } from '@donotdev/firebase/server';
14
+ import { getFirebaseAdminFirestore } from '@donotdev/firebase/server';
15
+ import { handleError } from '@donotdev/core/server';
16
+
17
+ // ❌ WRONG - This will crash on deploy (pulls in React/client code)
18
+ import { getAuth } from '@donotdev/firebase';
19
+ import { getFirestore } from '@donotdev/firebase';
20
+ import { handleError } from '@donotdev/core';
21
+ ```
22
+
23
+ **Why?** Functions run in Node.js, not the browser. Client imports (`@donotdev/firebase`) include React and browser-only code that will crash your function.
24
+
25
+ **Rule:** Always use `/server` suffix for:
26
+ - `@donotdev/firebase/server` (not `@donotdev/firebase`)
27
+ - `@donotdev/core/server` (not `@donotdev/core`)
28
+ - `@donotdev/utils/server` (not `@donotdev/utils`)
29
+
30
+ ---
31
+
7
32
  ## Standard Use
8
33
 
9
34
  **Structure:**
@@ -59,4 +84,31 @@ export const createCheckoutSession = generic(stripeBackConfig);
59
84
 
60
85
  ---
61
86
 
87
+ ## Advanced: Custom Functions with Firebase
88
+
89
+ **When writing custom functions that access Firestore/Auth, use `/server` imports:**
90
+
91
+ ```typescript
92
+ import { onCall } from 'firebase-functions/v2/https';
93
+ import { FUNCTION_CONFIG } from '@donotdev/functions/firebase';
94
+ // ✅ MUST use /server imports in functions
95
+ import { getFirebaseAdminFirestore } from '@donotdev/firebase/server';
96
+ import { getFirebaseAdminAuth } from '@donotdev/firebase/server';
97
+ import { handleError } from '@donotdev/core/server';
98
+
99
+ export const myCustomFunction = onCall(FUNCTION_CONFIG, async (request) => {
100
+ const firestore = getFirebaseAdminFirestore();
101
+ const auth = getFirebaseAdminAuth();
102
+
103
+ // Your custom logic here
104
+ const doc = await firestore.collection('users').doc(request.auth.uid).get();
105
+
106
+ return { data: doc.data() };
107
+ });
108
+ ```
109
+
110
+ **Remember:** All Firebase imports in functions MUST use `@donotdev/firebase/server`, never `@donotdev/firebase`.
111
+
112
+ ---
113
+
62
114
  **Add functions, get backend. Framework handles the rest.**
@@ -4,15 +4,81 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## Translation File Locations (CRITICAL)
8
+
9
+ **Two paths - choose based on when translations are needed:**
10
+
11
+ 1. **Eager (`src/locales/`)**: Always loaded - use for common UI, navigation, app-wide content
12
+ 2. **Lazy (`src/pages/locales/`)**: Loaded when page loads - use for page-specific content
13
+
14
+ **✅ RULE OF THUMB:**
15
+ - **Eager**: Navigation, buttons, common messages (used everywhere)
16
+ - **Lazy**: Page content, feature content, large text blocks (used on specific pages)
17
+
18
+ **Framework auto-discovers both paths. No configuration needed.**
19
+
20
+ ---
21
+
7
22
  ## Standard Use
8
23
 
9
- **Files:** `src/locales/<namespace>_<2-char-ISO>.json` (eager) | `src/pages/locales/<namespace>_<2-char-ISO>.json` (lazy)
24
+ **CRITICAL: Two Translation Paths - Choose Based on When Translations Are Needed**
25
+
26
+ ### Eager Translations (Always Loaded)
27
+ **Path:** `src/locales/<namespace>_<2-char-ISO>.json`
28
+
29
+ **Use for:**
30
+ - Common UI elements (buttons, labels, navigation)
31
+ - Critical app-wide translations (app name, common messages)
32
+ - Translations needed on every page
33
+
34
+ **Example:**
35
+ ```
36
+ src/
37
+ locales/
38
+ common_en.json # ✅ Eager - always available
39
+ common_fr.json
40
+ navigation_en.json # ✅ Eager - used in header/sidebar
41
+ navigation_fr.json
42
+ ```
10
43
 
44
+ ### Lazy Translations (Loaded When Page Loads)
45
+ **Path:** `src/pages/locales/<namespace>_<2-char-ISO>.json`
46
+
47
+ **Use for:**
48
+ - Page-specific content (page titles, descriptions, page content)
49
+ - Feature-specific translations (dashboard, blog, admin)
50
+ - Translations only needed when that page/feature is accessed
51
+
52
+ **Example:**
53
+ ```
54
+ src/
55
+ pages/
56
+ HomePage.tsx
57
+ locales/
58
+ home_en.json # ✅ Lazy - loaded when HomePage loads
59
+ home_fr.json
60
+ dashboard/
61
+ DashboardPage.tsx
62
+ locales/
63
+ dashboard_en.json # ✅ Lazy - loaded when DashboardPage loads
64
+ dashboard_fr.json
65
+ ```
66
+
67
+ **✅ DECISION GUIDE:**
68
+ - **Eager (`src/locales/`)**: Navigation, common buttons, app-wide messages
69
+ - **Lazy (`src/pages/locales/`)**: Page content, feature-specific content, large text blocks
70
+
71
+ **Usage:**
11
72
  ```tsx
12
73
  import { useTranslation } from '@donotdev/core';
13
74
 
14
- const { t } = useTranslation(NAMESPACE);
15
- t('title');
75
+ // Eager namespace (common, navigation, etc.)
76
+ const { t } = useTranslation('common');
77
+ t('app.title');
78
+
79
+ // Lazy namespace (page-specific)
80
+ const { t } = useTranslation('home');
81
+ t('hero.title');
16
82
  ```
17
83
 
18
84
  **LanguageSelector:** Included in layout presets. Import from `@donotdev/core` if needed elsewhere.
@@ -21,14 +87,87 @@ t('title');
21
87
 
22
88
  ## Advanced: Array Translations
23
89
 
90
+ ### Low-level: translateArray
91
+
24
92
  ```tsx
25
93
  import { translateArray, translateObjectArray, maybeTranslate } from '@donotdev/core';
26
94
 
27
- translateArray(t, 'benefits', 10); // Up to 10 items (benefits.0-9), safe if only 4 exist
28
- translateObjectArray(t, 'cases', 10, ['useCase', 'bestFit']); // Up to 10 objects
29
- maybeTranslate(t, 'products.earlyBird.name'); // Auto-detects key vs string
95
+ // Get array of strings (filters missing translations automatically)
96
+ const benefits = translateArray(t, 'benefits', 10); // Up to 10 items (benefits.0-9), safe if only 4 exist
97
+ const features = translateArray(t, 'features.list', 5); // Nested keys work
98
+
99
+ // Get array of objects
100
+ const cases = translateObjectArray(t, 'cases', 10, ['useCase', 'bestFit']);
101
+
102
+ // Auto-detect if value is a translation key or literal string
103
+ maybeTranslate(t, 'products.earlyBird.name');
30
104
  ```
31
105
 
106
+ ### High-level: tList (Recommended for Cards)
107
+
108
+ `tList` wraps `translateArray` and returns a `List` component ready for `Card` content:
109
+
110
+ ```tsx
111
+ import { tList } from '@donotdev/ui';
112
+
113
+ // With default icon (CheckCircle)
114
+ <Card content={tList(t, 'features.items', 4)} />
115
+
116
+ // With custom icon
117
+ <Card content={tList(t, 'features.items', 4, Star)} />
118
+
119
+ // Without icon (for emoji-prefixed labels like "🚀 Kick-off")
120
+ <Card content={tList(t, 'features.items', 4, null)} />
121
+ ```
122
+
123
+ **JSON structure:**
124
+ ```json
125
+ {
126
+ "features": {
127
+ "items": [
128
+ "Feature 1",
129
+ "Feature 2",
130
+ "Feature 3"
131
+ ]
132
+ }
133
+ }
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Advanced: Rich Text (Trans)
139
+
140
+ For inline styling in translations, use `Trans` instead of `t()`. Use when translations contain HTML-like tags for styling.
141
+
142
+ ```tsx
143
+ import { Trans } from '@donotdev/core';
144
+
145
+ // Translation: "<accent>MVP</accent> in 2 weeks"
146
+ <HeroSection title={<Trans ns={NAMESPACE} i18nKey="hero.title" />} />
147
+
148
+ // Translation: "I need <accent>Clarity</accent>"
149
+ <Card title={<Trans ns={NAMESPACE} i18nKey="products.transformation.title" />} />
150
+ ```
151
+
152
+ **JSON with tags:**
153
+ ```json
154
+ {
155
+ "hero": {
156
+ "title": "Idea to <accent>MVP</accent> in 2 weeks"
157
+ },
158
+ "products": {
159
+ "transformation": {
160
+ "title": "I need <accent>Clarity</accent>",
161
+ "subtitle": "...for a <accent>critical</accent> application"
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ **Supported tags:** `<accent>` `<primary>` `<muted>` `<success>` `<warning>` `<error>` `<bold>` `<code>`
168
+
169
+ **Note:** `Trans` accepts `ns` prop (string) for namespace. Use `t()` for plain strings, `Trans` for rich text with styling tags.
170
+
32
171
  ---
33
172
 
34
173
  ## Advanced: I18N Components
@@ -18,6 +18,24 @@ export const appConfig: AppConfig = {
18
18
 
19
19
  ---
20
20
 
21
+ ## Preset Capabilities
22
+
23
+ **The `docs` preset AUTOMATICALLY generates sidebar navigation from your `src/pages` files. You do not need to configure a sidebar manually.**
24
+
25
+ All presets automatically include these components when applicable:
26
+
27
+ * **LanguageSelector** - Automatically shown if more than 1 language is configured
28
+ * **ThemeToggle** - Automatically shown if more than 1 theme is available
29
+ * **AuthMenu** - Automatically shown if auth is configured in `.env` (Firebase keys present)
30
+ * **Navigation Menu** - Automatically generated from `src/pages/*Page.tsx` files for sidebars
31
+ * **GoTo Component** - Command palette (Cmd+K) for quick navigation - always available
32
+ * **Footer** - Automatic footer with copyright and legal links
33
+ * **LegalLinks + Copyright** - Automatically included in footer from `config/legal.ts`
34
+
35
+ **You don't need to add these manually - the framework handles them based on your configuration.**
36
+
37
+ ---
38
+
21
39
  ## Advanced: Slot Overrides
22
40
 
23
41
  **Customize zones:**
@@ -4,6 +4,14 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## File Routing Rule
8
+
9
+ **CRITICAL: Only files ending in `Page.tsx` inside `src/pages` become routes.**
10
+
11
+ Files must be named `*Page.tsx` (e.g., `HomePage.tsx`, `AboutPage.tsx`, `BlogPostPage.tsx`). Files without the `Page.tsx` suffix are ignored by the routing system.
12
+
13
+ ---
14
+
7
15
  ## Standard Use
8
16
 
9
17
  **Pattern:** `src/pages/**/*Page.tsx` → routes
@@ -103,8 +111,25 @@ import { useNavigate, Link } from '@donotdev/ui';
103
111
  const navigate = useNavigate();
104
112
  navigate('/about');
105
113
  <Link path="/about">About</Link>
114
+
115
+ // Card with navigation (supports middle-click)
116
+ import { Card } from '@donotdev/components';
117
+ import { Link } from '@donotdev/ui';
118
+
119
+ <Link
120
+ path="/about"
121
+ style={{ display: 'block', textDecoration: 'none', height: '100%' }}
122
+ aria-label="Learn more about About"
123
+ >
124
+ <Card title="About" subtitle="Learn more" />
125
+ </Link>
106
126
  ```
107
127
 
128
+ **Navigation patterns:**
129
+ - **Link component:** Use for text links, buttons, or wrapping other components
130
+ - **Card navigation:** Wrap Card in Link for clickable cards with middle-click support
131
+ - **onClick only:** Use `onClick={() => navigate()}` for actions that don't need middle-click
132
+
108
133
  **Pre-configured:** Navigation menu auto-generated, sitemap auto-built (if `generateSitemap: true`).
109
134
 
110
135
  ---
@@ -0,0 +1,213 @@
1
+ # PWA Setup
2
+
3
+ **For AI Agents:** Enable PWA in config, add required app metadata. Framework handles service worker, manifest, and caching.
4
+
5
+ ---
6
+
7
+ ## Quick Start
8
+
9
+ ### 1. Add Required App Metadata
10
+
11
+ PWA requires `name`, `shortName`, and `description` in your app config:
12
+
13
+ ```typescript
14
+ // src/config/app.ts
15
+ import type { AppConfig } from '@donotdev/core';
16
+
17
+ export const appConfig: AppConfig = {
18
+ app: {
19
+ name: 'My App', // Full app name (required for PWA)
20
+ shortName: 'App', // Short name for home screen (required for PWA)
21
+ description: 'My app description', // App description (required for PWA)
22
+ url: 'https://myapp.com',
23
+ },
24
+ // ... rest of config
25
+ };
26
+ ```
27
+
28
+ ### 2. Enable PWA in Build Config
29
+
30
+ **For Vite apps:**
31
+
32
+ ```typescript
33
+ // vite.config.ts
34
+ import { defineViteConfig } from '@donotdev/core/vite';
35
+ import { appConfig } from './src/config/app';
36
+
37
+ export default defineViteConfig({
38
+ appConfig,
39
+ pwa: {
40
+ enabled: true, // Enable PWA in production builds
41
+ devEnabled: false, // Enable PWA in development (optional)
42
+ },
43
+ });
44
+ ```
45
+
46
+ **For Next.js apps:**
47
+
48
+ ```typescript
49
+ // next.config.ts
50
+ import { defineNextConfig } from '@donotdev/core/next';
51
+ import { appConfig } from './src/config/app';
52
+
53
+ export default defineNextConfig({
54
+ appConfig,
55
+ pwa: {
56
+ enabled: true, // Enable PWA in production builds
57
+ devEnabled: false, // Enable PWA in development (optional)
58
+ },
59
+ });
60
+ ```
61
+
62
+ **Done.** Framework automatically:
63
+ - Generates `manifest.json` from app metadata
64
+ - Creates service worker with Workbox
65
+ - Discovers and precaches app icons
66
+ - Sets up offline caching strategies
67
+
68
+ ---
69
+
70
+ ## What Gets Auto-Generated
71
+
72
+ ### Manifest (`manifest.json`)
73
+ - **Name & description:** From `appConfig.app.name`, `shortName`, `description`
74
+ - **Icons:** Auto-discovered from `public/` folder (favicon, apple-touch-icon, etc.)
75
+ - **Theme colors:** Defaults to white background, black theme (customizable)
76
+ - **Display mode:** `standalone` (app-like experience)
77
+
78
+ ### Service Worker (`sw.js`)
79
+ - **Precaching:** All JS, CSS, HTML, icons, and fonts
80
+ - **Runtime caching:** Smart defaults for API calls and images
81
+ - **Offline support:** Navigation fallback to `/`
82
+ - **Update strategy:** Prompts user to update when new version available
83
+
84
+ ### Icons
85
+ Framework discovers icons from:
86
+ - `public/favicon.svg` or `public/favicon.ico`
87
+ - `public/apple-touch-icon.png`
88
+ - Any icons generated by AssetPlugin
89
+
90
+ ---
91
+
92
+ ## Optional Configuration
93
+
94
+ ### Custom Manifest Values
95
+
96
+ ```typescript
97
+ // vite.config.ts or next.config.ts
98
+ export default defineViteConfig({
99
+ appConfig,
100
+ pwa: {
101
+ enabled: true,
102
+ manifest: {
103
+ // Override any manifest values
104
+ theme_color: '#667eea',
105
+ background_color: '#ffffff',
106
+ display: 'standalone',
107
+ orientation: 'portrait',
108
+ },
109
+ },
110
+ });
111
+ ```
112
+
113
+ ### Custom Workbox Configuration
114
+
115
+ ```typescript
116
+ pwa: {
117
+ enabled: true,
118
+ workbox: {
119
+ // Maximum file size to cache (default: 5MB)
120
+ maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
121
+
122
+ // Custom precache patterns
123
+ globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
124
+ globIgnores: ['**/node_modules/**'],
125
+
126
+ // Runtime caching strategies
127
+ runtimeCaching: [
128
+ {
129
+ urlPattern: /^https:\/\/api\.example\.com\/.*/i,
130
+ handler: 'NetworkFirst',
131
+ options: {
132
+ cacheName: 'api-cache',
133
+ expiration: {
134
+ maxEntries: 50,
135
+ maxAgeSeconds: 60 * 60, // 1 hour
136
+ },
137
+ },
138
+ },
139
+ ],
140
+ },
141
+ },
142
+ ```
143
+
144
+ ### Development Mode
145
+
146
+ Enable PWA in development for testing:
147
+
148
+ ```typescript
149
+ pwa: {
150
+ enabled: true,
151
+ devEnabled: true, // Enable service worker in dev mode
152
+ debug: true, // Enable debug logging
153
+ },
154
+ ```
155
+
156
+ **Note:** Service workers require HTTPS (or localhost). Use `server: { https: true }` in Vite config for local HTTPS.
157
+
158
+ ---
159
+
160
+ ## Testing PWA
161
+
162
+ 1. **Build for production:**
163
+ ```bash
164
+ bun run build
165
+ ```
166
+
167
+ 2. **Serve production build:**
168
+ ```bash
169
+ bun run preview # Vite
170
+ # or
171
+ bun run start # Next.js
172
+ ```
173
+
174
+ 3. **Test in browser:**
175
+ - Open DevTools → Application → Service Workers
176
+ - Check "Offline" checkbox to test offline mode
177
+ - Verify manifest in Application → Manifest
178
+ - Test "Add to Home Screen" prompt
179
+
180
+ ---
181
+
182
+ ## Requirements Checklist
183
+
184
+ - [ ] `appConfig.app.name` defined
185
+ - [ ] `appConfig.app.shortName` defined
186
+ - [ ] `appConfig.app.description` defined
187
+ - [ ] `pwa.enabled: true` in build config
188
+ - [ ] Icons in `public/` folder (auto-discovered)
189
+ - [ ] HTTPS in production (required for service workers)
190
+
191
+ ---
192
+
193
+ ## Troubleshooting
194
+
195
+ **PWA not working:**
196
+ - Check browser console for service worker errors
197
+ - Verify HTTPS (required except localhost)
198
+ - Check manifest.json exists in build output
199
+ - Verify app metadata is complete
200
+
201
+ **Icons not showing:**
202
+ - Ensure icons exist in `public/` folder
203
+ - Check icon formats (SVG, PNG, ICO supported)
204
+ - Verify AssetPlugin discovered icons (check build logs)
205
+
206
+ **Service worker not registering:**
207
+ - Check browser console for registration errors
208
+ - Verify HTTPS (service workers require secure context)
209
+ - Clear browser cache and hard refresh
210
+
211
+ ---
212
+
213
+ **Zero config. Override when needed.**