@donotdev/cli 0.0.13 → 0.0.14

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 (32) hide show
  1. package/dependencies-matrix.json +2 -2
  2. package/dist/bin/commands/agent-setup.d.ts +6 -0
  3. package/dist/bin/commands/agent-setup.d.ts.map +1 -0
  4. package/dist/bin/commands/agent-setup.js +623 -0
  5. package/dist/bin/commands/agent-setup.js.map +1 -0
  6. package/dist/bin/commands/build.js +13 -12
  7. package/dist/bin/commands/bump.js +70 -28
  8. package/dist/bin/commands/cacheout.js +13 -12
  9. package/dist/bin/commands/create-app.js +53 -151
  10. package/dist/bin/commands/create-project.js +72 -166
  11. package/dist/bin/commands/deploy.js +16 -15
  12. package/dist/bin/commands/dev.js +13 -12
  13. package/dist/bin/commands/emu.js +13 -12
  14. package/dist/bin/commands/format.js +13 -12
  15. package/dist/bin/commands/lint.js +13 -12
  16. package/dist/bin/commands/preview.js +13 -12
  17. package/dist/bin/commands/sync-secrets.js +13 -12
  18. package/dist/bin/commands/wai.js +7397 -11
  19. package/dist/index.js +74 -55
  20. package/package.json +1 -1
  21. package/templates/root-consumer/.claude/commands/brainstorm.md.example +1 -1
  22. package/templates/root-consumer/.claude/commands/build.md.example +1 -1
  23. package/templates/root-consumer/.claude/commands/design.md.example +1 -1
  24. package/templates/root-consumer/.claude/commands/polish.md.example +1 -1
  25. package/templates/root-consumer/.dndev/args.json.example +6 -0
  26. package/templates/root-consumer/.gemini/settings.json.example +2 -2
  27. package/templates/root-consumer/AI.md.example +25 -14
  28. package/templates/root-consumer/CLAUDE.md.example +10 -4
  29. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +34 -0
  30. package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +186 -0
  31. package/templates/root-consumer/guides/dndev/INDEX.md.example +1 -0
  32. package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +12 -7
@@ -0,0 +1,186 @@
1
+ # Framework Gotchas
2
+
3
+ **Common mistakes. Read before coding. Phase tags show when each matters most.**
4
+
5
+ ---
6
+
7
+ ## Imports [Phase 1, 2, 3]
8
+
9
+ **Server code MUST use `/server` imports — client imports crash on deploy.**
10
+
11
+ ```typescript
12
+ // ✅ CORRECT
13
+ import { getFirebaseAdminFirestore } from '@donotdev/firebase/server';
14
+ import { handleError } from '@donotdev/core/server';
15
+
16
+ // ❌ WRONG - crashes on deploy
17
+ import { getFirestore } from '@donotdev/firebase';
18
+ import { handleError } from '@donotdev/core';
19
+ ```
20
+
21
+ **Rule:** Always use `/server` suffix for `@donotdev/firebase/server`, `@donotdev/core/server`, `@donotdev/utils/server`.
22
+
23
+ **ESM only — never use `require()`.**
24
+
25
+ ```typescript
26
+ // ❌ WRONG
27
+ const { something } = require('@donotdev/package');
28
+
29
+ // ✅ CORRECT
30
+ import { something } from '@donotdev/package';
31
+ ```
32
+
33
+ **Import ordering is mandatory:**
34
+ 1. React (values, then types)
35
+ 2. Other vendors (values, then types)
36
+ 3. `@donotdev/*` packages (values, then types)
37
+ 4. Relative imports (values, then types)
38
+
39
+ One line for values, one line for types. Blank line between categories.
40
+
41
+ ---
42
+
43
+ ## Routing [Phase 1, 3]
44
+
45
+ **Never import from `react-router-dom` — use framework routing.**
46
+
47
+ ```tsx
48
+ // ❌ WRONG - breaks framework features
49
+ import { Link, useNavigate, useParams } from 'react-router-dom';
50
+
51
+ // ✅ CORRECT
52
+ import { Link, useNavigate, useParams } from '@donotdev/ui/routing';
53
+ ```
54
+
55
+ **Routes are auto-discovered** from `src/pages/*Page.tsx` with `pageMeta`. Don't use `<Routes>`, `<Route>`, or manual `<Outlet />`.
56
+
57
+ **Use `useRouteParam('id')` for typed route params** — not `useParams()` from react-router-dom.
58
+
59
+ **Navigation is auto-built.** Use `<DnDevNavigationMenu>` or `useNavigationItems()`. Don't build nav manually — you lose auth filtering and route discovery.
60
+
61
+ ---
62
+
63
+ ## Styling [Phase 3, 4]
64
+
65
+ **No inline `fontSize` or `font-size` — use `Text` level prop.**
66
+
67
+ ```tsx
68
+ // ❌ WRONG
69
+ <Text style={{ fontSize: '18px' }}>Title</Text>
70
+
71
+ // ✅ CORRECT
72
+ <Text level="h2">Title</Text>
73
+ ```
74
+
75
+ Levels: `h1`, `h2`, `h3`, `h4`, `body`, `small`, `caption`. Limit to 2–3 levels per page.
76
+
77
+ **RTL: Always use `start`/`end` — never `left`/`right`.**
78
+
79
+ ```css
80
+ /* ❌ WRONG - breaks RTL */
81
+ text-align: left;
82
+
83
+ /* ✅ CORRECT - works in both LTR and RTL */
84
+ text-align: start;
85
+ ```
86
+
87
+ Same for inline styles: `textAlign: 'start'` not `textAlign: 'left'`. Same for data attributes: `data-text-align="start|center|end"`.
88
+
89
+ ---
90
+
91
+ ## Components [Phase 3]
92
+
93
+ **Always `lookup_symbol` before using any `@donotdev` component.** Never guess props.
94
+
95
+ Common wrong props:
96
+ - `Button`: no `size`, `tone`, `gap` — use `variant`, `display`
97
+ - `Text`: no `size`, `tone`, `color` — use `level`, `variant`
98
+ - `Stack`: no `spacing`, `size` — use `gap`
99
+ - `Card`: no `padding`, `margin`, `size` — use `title`, `subtitle`, `content`, `footer`
100
+ - `Grid`: no `columns` — use `cols`
101
+
102
+ **If you can't do it with framework components:** Stop. Tell the user what's missing. Don't invent custom workarounds.
103
+
104
+ ---
105
+
106
+ ## CRUD [Phase 2, 3]
107
+
108
+ **Hidden fields are auto-added by `defineEntity()` — don't define them manually:**
109
+ - `id`, `createdAt`, `updatedAt`, `createdById`, `updatedById`, `status`
110
+
111
+ **Scope field is auto-added** when `scope` is configured. Don't manually define the scope field (e.g., `companyId`).
112
+
113
+ **Custom form fields MUST use framework's `useController`:**
114
+
115
+ ```typescript
116
+ // ❌ WRONG
117
+ import { useController } from 'react-hook-form';
118
+
119
+ // ✅ CORRECT
120
+ import { useController } from '@donotdev/crud';
121
+ ```
122
+
123
+ **Form components receive `control` prop, not `field` prop.**
124
+
125
+ **Price field is structured:** `{ amount, currency, vatIncluded, discountPercent }`. Don't store computed discount amounts.
126
+
127
+ **File uploads are deferred** — files upload on form submit, not on selection. Images show optimistic blob URLs.
128
+
129
+ **Entity namespace defaults to `entity-{name}`** (lowercase). Translation files must match: `locales/entity-product_en.json`.
130
+
131
+ ---
132
+
133
+ ## Functions [Phase 3, 4]
134
+
135
+ **Use `createFunction` for custom functions — 3 params, everything included:**
136
+
137
+ ```typescript
138
+ import { createFunction } from '@donotdev/functions/firebase';
139
+
140
+ export const myFunction = createFunction(schema, 'operation_name', async (data, { uid }) => {
141
+ // Your logic
142
+ });
143
+ ```
144
+
145
+ **Use `createBaseFunction` only when you need custom config** (memory, timeout, region override).
146
+
147
+ **Deploy with `dndev deploy`** — not `firebase deploy`. Manual deploy causes CORS 403 on preflight because Cloud Run blocks unauthenticated OPTIONS by default.
148
+
149
+ **Naming:** Export in camelCase (`getDashboardMetrics`), operation ID in snake_case (`get_dashboard_metrics`).
150
+
151
+ **CRUD functions are one-liner:** `export const crud = createCrudFunctions(entities);` — generates all CRUD endpoints per entity. Access controlled via `entity.access`.
152
+
153
+ ---
154
+
155
+ ## i18n [Phase 3, 4]
156
+
157
+ **Phase 3: hardcode strings. Phase 4: add translations.** Don't i18n too early.
158
+
159
+ **Two loading strategies:**
160
+ - **Eager** (always loaded): `src/locales/common_en.json` — navigation, buttons, common UI
161
+ - **Lazy** (loaded per page): `src/pages/locales/home_en.json` — page-specific content
162
+
163
+ **Status field translations** fall back: `entity-{name}` namespace → `crud` namespace.
164
+
165
+ **Rich text uses `<Trans>` component** with supported tags only: `<accent>`, `<primary>`, `<muted>`, `<success>`, `<warning>`, `<error>`, `<bold>`, `<code>`.
166
+
167
+ **Array translations use `tList`:**
168
+ ```tsx
169
+ import { tList } from '@donotdev/ui';
170
+ <Card content={tList(t, 'features.items', 4)} />
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Dependencies [Phase 1]
176
+
177
+ **Apps don't declare bundled deps.** Framework packages (`@donotdev/*`) provide everything. Don't add `react-router-dom`, `react-hook-form`, `valibot`, etc. to app's `package.json` — they come through framework deps.
178
+
179
+ **Environment variables:**
180
+ - Client: `apps/my-app/.env` (prefix with `VITE_*`)
181
+ - Server: `functions/.env` (secrets: `STRIPE_*`, OAuth tokens)
182
+ - Local overrides: `.env.local` (gitignored)
183
+
184
+ ---
185
+
186
+ **When in doubt: search the codebase first, ask the user second, never guess.**
@@ -9,6 +9,7 @@
9
9
  ## Getting Started
10
10
 
11
11
  - [ENV_SETUP.md](./ENV_SETUP.md) - **START HERE** — Full onboarding flow (install → firebase → deploy)
12
+ - [GOTCHAS.md](./GOTCHAS.md) - **Common mistakes & pitfalls** (phase-tagged, read before coding)
12
13
  - [SETUP_FIREBASE.md](./SETUP_FIREBASE.md) - Firebase project setup (`dndev firebase:setup`)
13
14
  - [SETUP_TESTING.md](./SETUP_TESTING.md) - Test generation (Phase 4)
14
15
 
@@ -47,21 +47,26 @@ export const crud = createCrudFunctions(entities);
47
47
 
48
48
  ## Custom Functions
49
49
 
50
- **When writing custom functions, use `/server` imports:**
50
+ **Use `createFunction` handles config, validation, auth, rate limiting, metrics automatically:**
51
51
 
52
52
  ```typescript
53
- import { onCall } from 'firebase-functions/v2/https';
54
- import { FUNCTION_CONFIG } from '@donotdev/functions/firebase';
53
+ import * as v from 'valibot';
54
+ import { createFunction } from '@donotdev/functions/firebase';
55
55
  import { getFirebaseAdminFirestore } from '@donotdev/firebase/server';
56
- import { handleError } from '@donotdev/core/server';
57
56
 
58
- export const myFunction = onCall(FUNCTION_CONFIG, async (request) => {
57
+ const schema = v.object({ productId: v.string() });
58
+
59
+ export const getProductDetails = createFunction(schema, 'get_product_details', async (data, { uid }) => {
59
60
  const db = getFirebaseAdminFirestore();
60
- // Your logic here
61
- return { data: 'result' };
61
+ const doc = await db.collection('products').doc(data.productId).get();
62
+ return doc.data();
62
63
  });
63
64
  ```
64
65
 
66
+ **That's it.** Rate limiting, metrics, auth, schema validation — all included by default. No config needed.
67
+
68
+ **Advanced:** Use `createBaseFunction` if you need custom config (memory, timeout, region override).
69
+
65
70
  ---
66
71
 
67
72
  ## Post-Deployment: Cloud Run IAM