@terreno/api 0.1.0 → 0.2.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 (40) hide show
  1. package/dist/api.d.ts +28 -2
  2. package/dist/api.js +20 -7
  3. package/dist/betterAuth.d.ts +91 -0
  4. package/dist/betterAuth.js +8 -0
  5. package/dist/betterAuth.test.d.ts +1 -0
  6. package/dist/betterAuth.test.js +181 -0
  7. package/dist/betterAuthApp.d.ts +22 -0
  8. package/dist/betterAuthApp.js +38 -0
  9. package/dist/betterAuthApp.test.d.ts +1 -0
  10. package/dist/betterAuthApp.test.js +242 -0
  11. package/dist/betterAuthSetup.d.ts +60 -0
  12. package/dist/betterAuthSetup.js +278 -0
  13. package/dist/betterAuthSetup.test.d.ts +1 -0
  14. package/dist/betterAuthSetup.test.js +684 -0
  15. package/dist/expressServer.js +2 -2
  16. package/dist/index.d.ts +4 -0
  17. package/dist/index.js +4 -0
  18. package/dist/terrenoApp.d.ts +189 -0
  19. package/dist/terrenoApp.js +352 -0
  20. package/dist/terrenoApp.test.d.ts +1 -0
  21. package/dist/terrenoApp.test.js +264 -0
  22. package/dist/terrenoPlugin.d.ts +34 -0
  23. package/package.json +6 -3
  24. package/src/api.ts +61 -3
  25. package/src/betterAuth.test.ts +160 -0
  26. package/src/betterAuth.ts +104 -0
  27. package/src/betterAuthApp.test.ts +114 -0
  28. package/src/betterAuthApp.ts +60 -0
  29. package/src/betterAuthSetup.test.ts +485 -0
  30. package/src/betterAuthSetup.ts +251 -0
  31. package/src/expressServer.ts +4 -5
  32. package/src/index.ts +4 -0
  33. package/src/openApiValidator.ts +1 -1
  34. package/src/terrenoApp.test.ts +201 -0
  35. package/src/terrenoApp.ts +347 -0
  36. package/src/terrenoPlugin.ts +34 -0
  37. package/.claude/CLAUDE.local.md +0 -204
  38. package/.cursor/rules/00-root.mdc +0 -338
  39. package/.github/copilot-instructions.md +0 -333
  40. package/AGENTS.md +0 -333
package/AGENTS.md DELETED
@@ -1,333 +0,0 @@
1
- # Terreno
2
-
3
- A monorepo containing shared packages for building full-stack applications with React Native and Express/Mongoose.
4
-
5
- ## Packages
6
-
7
- - **api/** - REST API framework built on Express/Mongoose (`@terreno/api`)
8
- - **ui/** - React Native UI component library (`@terreno/ui`)
9
- - **rtk/** - Redux Toolkit Query utilities for API backends (`@terreno/rtk`)
10
- - **mcp-server/** - MCP server for AI assistant integration (`@terreno/mcp-server`)
11
- - **demo/** - Demo app for showcasing and testing UI components
12
- - **example-frontend/** - Example Expo app demonstrating full stack usage
13
- - **example-backend/** - Example Express backend using @terreno/api
14
-
15
- ## Development
16
-
17
- Uses [Bun](https://bun.sh/) as the package manager.
18
-
19
- ```bash
20
- bun install # Install dependencies
21
- bun run compile # Compile all packages
22
- bun run lint # Lint all packages
23
- bun run lint:fix # Fix lint issues
24
- bun run test # Run tests in api and ui
25
- ```
26
-
27
- ### Package-specific commands
28
-
29
- ```bash
30
- bun run api:test # Test API package
31
- bun run ui:test # Test UI package
32
- bun run demo:start # Start demo app
33
- bun run frontend:web # Start frontend example
34
- bun run backend:dev # Start backend example
35
- bun run mcp:build # Build MCP server
36
- bun run mcp:start # Start MCP server
37
- ```
38
-
39
- ## How the Packages Work Together
40
-
41
- The three core packages form a complete full-stack framework:
42
-
43
- ```
44
- BACKEND
45
- @terreno/api
46
- - Mongoose models with modelRouter -> CRUD endpoints
47
- - Built-in auth (JWT + Passport)
48
- - Automatic OpenAPI spec generation
49
- |
50
- /openapi.json
51
- |
52
- RTK Query SDK Codegen
53
- |
54
- FRONTEND
55
- @terreno/rtk
56
- - Generated hooks from OpenAPI spec
57
- - Auth slice with JWT token management
58
- - Automatic token refresh
59
- +
60
- @terreno/ui
61
- - React Native components (Box, Button, TextField, etc.)
62
- - TerrenoProvider for theming
63
- ```
64
-
65
- ### Integration Flow
66
-
67
- 1. **Backend (api)**: Define Mongoose models, use `modelRouter` to create CRUD endpoints with permissions
68
- 2. **OpenAPI Generation**: `setupServer` automatically generates `/openapi.json`
69
- 3. **SDK Codegen**: Frontend runs `bun run sdk` to generate RTK Query hooks from OpenAPI spec
70
- 4. **Frontend (rtk + ui)**: Use generated hooks with UI components for type-safe API calls
71
-
72
- ## Example Apps (Keep These Updated!)
73
-
74
- The `example-frontend/` and `example-backend/` directories serve as both documentation and integration tests. When adding features to api, ui, or rtk:
75
-
76
- 1. **Add examples** demonstrating new features
77
- 2. **Update SDK** after backend changes: `cd example-frontend && bun run sdk`
78
- 3. **Verify integration** by running both examples together
79
-
80
- ### Running the Full Stack
81
-
82
- ```bash
83
- # Terminal 1: Start backend
84
- bun run backend:dev
85
-
86
- # Terminal 2: Start frontend
87
- bun run frontend:web
88
- ```
89
-
90
- ## Code Style
91
-
92
- ### TypeScript/JavaScript
93
- - Use ES module syntax and TypeScript for all code
94
- - Prefer interfaces over types; avoid enums, use maps
95
- - Prefer const arrow functions over `function` keyword
96
- - Use descriptive variable names with auxiliary verbs (e.g., `isLoading`)
97
- - Use camelCase directories (e.g., `components/authWizard`)
98
- - Favor named exports
99
- - Use the RORO pattern (Receive an Object, Return an Object)
100
-
101
- ### Dates and Time
102
- - Always use Luxon instead of Date or dayjs
103
-
104
- ### Error Handling
105
- - Check error conditions at start of functions and return early
106
- - Limit nested if statements
107
- - Use multiline syntax with curly braces for all conditionals
108
-
109
- ### Testing
110
- - Use bun test with expect for testing
111
-
112
- ### Logging
113
- - Frontend: Use `console.info`, `console.debug`, `console.warn`, or `console.error` for permanent logs
114
- - Backend: Use `logger.info/warn/error/debug` for permanent logs
115
- - Use `console.log` only for debugging (to be removed)
116
-
117
- ### Development Practices
118
- - Don't apologize for errors: fix them
119
- - Prioritize modularity, DRY, performance, and security
120
- - Focus on readability over performance
121
- - Write complete, functional code without TODOs when possible
122
- - Comments should describe purpose, not effect
123
-
124
- ## Package Reference
125
-
126
- ### @terreno/api
127
-
128
- REST API framework providing:
129
-
130
- - **modelRouter**: Auto-generates CRUD endpoints for Mongoose models
131
- - **Permissions**: `IsAuthenticated`, `IsOwner`, `IsAdmin`, `IsAuthenticatedOrReadOnly`
132
- - **Query Filters**: `OwnerQueryFilter` for filtering list queries by owner
133
- - **setupServer**: Express server setup with auth, OpenAPI, and middleware
134
- - **APIError**: Standardized error handling
135
- - **logger**: Winston-based logging
136
-
137
- Key imports:
138
- ```typescript
139
- import {
140
- modelRouter,
141
- setupServer,
142
- Permissions,
143
- OwnerQueryFilter,
144
- APIError,
145
- logger,
146
- asyncHandler,
147
- authenticateMiddleware,
148
- } from "@terreno/api";
149
- ```
150
-
151
- #### modelRouter Usage
152
-
153
- ```typescript
154
- import {modelRouter, modelRouterOptions, Permissions} from "@terreno/api";
155
-
156
- const router = modelRouter(YourModel, {
157
- permissions: {
158
- list: [Permissions.IsAuthenticated],
159
- create: [Permissions.IsAuthenticated],
160
- read: [Permissions.IsOwner],
161
- update: [Permissions.IsOwner],
162
- delete: [], // Disabled
163
- },
164
- sort: "-created",
165
- queryFields: ["_id", "type", "name"],
166
- });
167
- ```
168
-
169
- #### Custom Routes
170
-
171
- For non-CRUD endpoints, use the OpenAPI builder:
172
-
173
- ```typescript
174
- import {asyncHandler, authenticateMiddleware, createOpenApiBuilder} from "@terreno/api";
175
-
176
- router.get("/yourRoute/:id", [
177
- authenticateMiddleware(),
178
- createOpenApiBuilder(options)
179
- .withTags(["yourTag"])
180
- .withSummary("Brief summary")
181
- .withPathParameter("id", {type: "string"})
182
- .withResponse(200, {data: {type: "object"}})
183
- .build(),
184
- ], asyncHandler(async (req, res) => {
185
- return res.json({data: result});
186
- }));
187
- ```
188
-
189
- #### API Conventions
190
-
191
- - Throw `APIError` with appropriate status codes: `throw new APIError({status: 400, title: "Message"})`
192
- - Do not use `Model.findOne` - use `Model.findExactlyOne` or `Model.findOneOrThrow`
193
- - Define statics/methods by direct assignment: `schema.methods = {bar() {}}`
194
- - All model types live in `src/modelInterfaces.ts`
195
- - In routes: `req.user` is `UserDocument | undefined`
196
- - In @terreno/api callbacks: cast with `const user = u as unknown as UserDocument`
197
-
198
- ### @terreno/ui
199
-
200
- React Native component library with 88+ components:
201
-
202
- - **Layout**: Box, Page, SplitPage, Card
203
- - **Forms**: TextField, SelectField, DateTimeField, CheckBox
204
- - **Display**: Text, Heading, Badge, DataTable
205
- - **Actions**: Button, IconButton, Link
206
- - **Feedback**: Spinner, Modal, Toast
207
- - **Theming**: TerrenoProvider, useTheme
208
-
209
- Key imports:
210
- ```typescript
211
- import {
212
- Box,
213
- Button,
214
- Card,
215
- Page,
216
- Text,
217
- TextField,
218
- TerrenoProvider,
219
- } from "@terreno/ui";
220
- ```
221
-
222
- #### UI Component Examples
223
-
224
- Layout with Box:
225
- ```typescript
226
- <Box direction="row" padding={4} gap={2} alignItems="center">
227
- <Text>Content</Text>
228
- <Button text="Action" />
229
- </Box>
230
- ```
231
-
232
- Buttons:
233
- ```typescript
234
- <Button
235
- text="Submit"
236
- variant="primary" // 'primary' | 'secondary' | 'outline' | 'ghost'
237
- onClick={handleSubmit}
238
- loading={isLoading}
239
- iconName="check"
240
- />
241
- ```
242
-
243
- Forms:
244
- ```typescript
245
- <TextField
246
- label="Email"
247
- value={email}
248
- onChangeText={setEmail}
249
- error={emailError}
250
- helperText="Enter a valid email"
251
- />
252
- ```
253
-
254
- Modals:
255
- ```typescript
256
- <Modal
257
- title="Confirm Action"
258
- visible={isVisible}
259
- primaryButtonText="Confirm"
260
- secondaryButtonText="Cancel"
261
- onDismiss={() => setIsVisible(false)}
262
- onPrimaryAction={handleConfirm}
263
- >
264
- <Text>Are you sure?</Text>
265
- </Modal>
266
- ```
267
-
268
- #### UI Common Pitfalls
269
-
270
- - Don't use inline styles when theme values are available
271
- - Don't use raw `View`/`Text` when `Box`/@terreno/ui `Text` are available
272
- - Don't forget loading and error states
273
- - Don't use `style` prop when equivalent props exist (`padding`, `margin`)
274
- - Never modify `openApiSdk.ts` manually
275
-
276
- ### @terreno/rtk
277
-
278
- Redux Toolkit Query integration:
279
-
280
- - **generateAuthSlice**: Creates auth reducer and middleware with JWT handling
281
- - **emptyApi**: Base RTK Query API for code generation
282
- - **Platform utilities**: Secure token storage (expo-secure-store for native, AsyncStorage for web)
283
-
284
- Key imports:
285
- ```typescript
286
- import {generateAuthSlice} from "@terreno/rtk";
287
- ```
288
-
289
- Always use generated SDK hooks - never use `axios` or `request` directly:
290
-
291
- ```typescript
292
- // Correct
293
- import {useGetYourRouteQuery} from "@/store/openApiSdk";
294
- const {data, isLoading, error} = useGetYourRouteQuery({id: "value"});
295
-
296
- // Wrong - don't use axios directly
297
- // const result = await axios.get("/api/yourRoute/value");
298
- ```
299
-
300
- ## React Best Practices (Frontend Packages)
301
-
302
- - Use functional components with `React.FC` type
303
- - Import hooks directly: `import {useEffect, useMemo} from 'react'`
304
- - Always provide return types for functions
305
- - Add explanatory comment above each `useEffect`
306
- - Wrap callbacks in `useCallback`
307
- - Prefer const arrow functions
308
- - Use inline styles over `StyleSheet.create`
309
- - Use Luxon for date operations
310
- - Place static content and interfaces at beginning of file
311
- - Minimize `use client`, `useEffect`, and `setState`
312
- - Always support React-Native Web
313
-
314
- ## CI/CD Workflows
315
-
316
- ### Required Secret Validation
317
-
318
- GitHub Actions workflows that use secrets or environment variables must validate all required variables are set before using them. Add a validation step early in the job that fails fast with a clear error message listing any missing variables.
319
-
320
- ```yaml
321
- - name: Validate required secrets
322
- run: |
323
- missing=()
324
- if [ -z "$VAR_NAME" ]; then missing+=("VAR_NAME"); fi
325
- if [ ${#missing[@]} -ne 0 ]; then
326
- echo "::error::Missing required secrets: ${missing[*]}"
327
- exit 1
328
- fi
329
- ```
330
-
331
- ## Dependency Management
332
-
333
- Uses [Bun Catalogs](https://bun.sh/docs/install/catalogs) - shared versions defined in root `package.json` under `catalog`. Reference with `catalog:` in workspace packages.