@archlast/cli 0.1.0 → 0.2.1
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.
- package/README.md +967 -141
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,149 +1,975 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
CLI tool for Archlast
|
|
4
|
-
|
|
1
|
+
# @archlast/cli
|
|
2
|
+
|
|
3
|
+
The Archlast CLI is a comprehensive command-line tool for development, deployment, and Docker lifecycle management of Archlast applications. It handles code analysis, type generation, hot deployment, container management, and data operations.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Requirements](#requirements)
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Quick Start](#quick-start)
|
|
10
|
+
- [Commands Reference](#commands-reference)
|
|
11
|
+
- [Development Commands](#development-commands)
|
|
12
|
+
- [Docker Management](#docker-management)
|
|
13
|
+
- [Code Generation](#code-generation)
|
|
14
|
+
- [Data Management](#data-management)
|
|
15
|
+
- [Configuration](#configuration)
|
|
16
|
+
- [Environment Variables](#environment-variables)
|
|
17
|
+
- [Generated Files](#generated-files)
|
|
18
|
+
- [Usage Examples](#usage-examples)
|
|
19
|
+
- [Troubleshooting](#troubleshooting)
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
- **Node.js 18+** or **Bun 1.0+**
|
|
24
|
+
- **Docker Desktop** or **Docker Engine** (for container management)
|
|
25
|
+
- An Archlast project with schema and function definitions
|
|
26
|
+
|
|
5
27
|
## Installation
|
|
6
28
|
|
|
7
|
-
###
|
|
29
|
+
### Global Installation (Recommended)
|
|
8
30
|
|
|
9
31
|
```bash
|
|
10
32
|
npm install -g @archlast/cli
|
|
33
|
+
|
|
34
|
+
# Or with bun
|
|
35
|
+
bun add -g @archlast/cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Local Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install -D @archlast/cli
|
|
42
|
+
|
|
43
|
+
# Run via npx
|
|
44
|
+
npx archlast <command>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Verify Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
archlast --version
|
|
51
|
+
archlast --help
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
### 1. Start the Server
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Pull and start the Docker container
|
|
60
|
+
archlast start
|
|
61
|
+
|
|
62
|
+
# Check status
|
|
63
|
+
archlast status
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Development Mode
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Watch for changes and auto-deploy
|
|
70
|
+
archlast dev --path ./my-archlast-app
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 3. Production Deployment
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
archlast deploy --path ./my-archlast-app --server https://api.myapp.com
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Commands Reference
|
|
82
|
+
|
|
83
|
+
### Development Commands
|
|
84
|
+
|
|
85
|
+
#### `archlast dev`
|
|
86
|
+
|
|
87
|
+
Start development mode with file watching. Automatically regenerates types and deploys changes to the server using delta deployments.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
archlast dev [options]
|
|
91
|
+
|
|
92
|
+
Options:
|
|
93
|
+
--path <path> Path to archlast folder (default: ".")
|
|
94
|
+
--server <url> Server URL for code upload (default: "http://localhost:4000")
|
|
95
|
+
--max-poll <number> Maximum server polling retries (default: 30)
|
|
96
|
+
-p, --port <port> Server port (default: 3001)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**What happens:**
|
|
100
|
+
|
|
101
|
+
1. Polls server to ensure it's reachable
|
|
102
|
+
2. Analyzes code for functions, HTTP routes, RPC procedures, and injectables
|
|
103
|
+
3. Generates types in `_generated/` directory
|
|
104
|
+
4. Computes delta (added/modified/removed files) against server manifest
|
|
105
|
+
5. Uploads only changed files (delta deployment)
|
|
106
|
+
6. Watches `src/**/*.ts` for changes and repeats
|
|
107
|
+
|
|
108
|
+
**Example:**
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Watch current directory
|
|
112
|
+
archlast dev
|
|
113
|
+
|
|
114
|
+
# Watch specific project with custom server
|
|
115
|
+
archlast dev --path ./apps/api --server http://localhost:5000
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### `archlast build`
|
|
119
|
+
|
|
120
|
+
Generate types without deploying. Useful for CI/CD pipelines or type checking.
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
archlast build --path ./my-archlast-app
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**What it generates:**
|
|
127
|
+
|
|
128
|
+
- `_generated/server.ts` - DataModel types, QueryCtx, MutationCtx, ActionCtx
|
|
129
|
+
- `_generated/api.ts` - Client-side function references
|
|
130
|
+
- `_generated/rpc.ts` - RPC procedure types
|
|
131
|
+
- `_generated/trpc-router.ts` - tRPC router with AppRouter type
|
|
132
|
+
- `_generated/crud/<collection>.ts` - Auto-generated REST CRUD handlers
|
|
133
|
+
- `_generated/di.ts` - Dependency injection provider registrations (if injectables detected)
|
|
134
|
+
- `_generated/index.ts` - Barrel exports
|
|
135
|
+
|
|
136
|
+
#### `archlast deploy`
|
|
137
|
+
|
|
138
|
+
One-time deployment to the server with delta detection.
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
archlast deploy [options]
|
|
142
|
+
|
|
143
|
+
Options:
|
|
144
|
+
--path <path> Path to archlast folder (default: ".")
|
|
145
|
+
--server <url> Server URL (default: "http://localhost:4000")
|
|
146
|
+
--max-poll <number> Maximum polling retries (default: 30)
|
|
11
147
|
```
|
|
12
148
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
149
|
+
**Deployment Protocol:**
|
|
150
|
+
|
|
151
|
+
The CLI computes a delta by comparing local file hashes against the server's manifest (`GET /_archlast/deploy/manifest`), then sends only changed files to `POST /_archlast/deploy`.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
interface DeltaUploadPayload {
|
|
155
|
+
timestamp: number;
|
|
156
|
+
changes: {
|
|
157
|
+
added: Array<{ filePath: string; code: string }>;
|
|
158
|
+
modified: Array<{ filePath: string; code: string }>;
|
|
159
|
+
removed: string[];
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### `archlast pull`
|
|
165
|
+
|
|
166
|
+
Pull schema or files from the server, or pull Docker images.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
archlast pull [options]
|
|
170
|
+
|
|
171
|
+
Options:
|
|
172
|
+
--path <path> Local path (default: ".")
|
|
173
|
+
--server <url> Server URL (default: "http://localhost:4000")
|
|
174
|
+
--files <files...> Files to pull (default: ["src/schema.ts"])
|
|
175
|
+
--force Overwrite without prompt
|
|
176
|
+
--diff Show diff only
|
|
177
|
+
--merge Attempt merge
|
|
178
|
+
--smart Enable smart pull with change detection
|
|
179
|
+
--docker Pull Docker image instead of schema
|
|
180
|
+
--image <image> Docker image name
|
|
181
|
+
--tag <tag> Docker image tag
|
|
182
|
+
--version <version> Docker image version (alias for --tag)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Examples:**
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Pull schema from server
|
|
189
|
+
archlast pull --server http://localhost:4000
|
|
190
|
+
|
|
191
|
+
# Pull and show diff only
|
|
192
|
+
archlast pull --diff
|
|
193
|
+
|
|
194
|
+
# Smart pull with change detection
|
|
195
|
+
archlast pull --smart
|
|
196
|
+
|
|
197
|
+
# Pull specific Docker image
|
|
198
|
+
archlast pull --docker --image archlast/server --tag v1.2.0
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
### Docker Management
|
|
204
|
+
|
|
205
|
+
All Docker commands support configuration via `archlast.config.js` or CLI flags.
|
|
206
|
+
|
|
207
|
+
#### `archlast start`
|
|
208
|
+
|
|
209
|
+
Start the Archlast Docker container with health checking.
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
archlast start [options]
|
|
213
|
+
|
|
214
|
+
Options:
|
|
215
|
+
--path <path> Path to project root (default: ".")
|
|
216
|
+
--port <port> Host port to expose
|
|
217
|
+
--image <image> Docker image name
|
|
218
|
+
--tag <tag> Docker image tag
|
|
219
|
+
--container <name> Docker container name
|
|
220
|
+
--config <path> Path to archlast.config.js
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**What happens:**
|
|
224
|
+
|
|
225
|
+
1. Loads configuration (CLI flags → config file → .env → defaults)
|
|
226
|
+
2. Generates Docker Compose file at `.archlast/config/docker-compose.yml`
|
|
227
|
+
3. Starts the container via Docker Compose
|
|
228
|
+
4. Waits for health check at `/health` (60 second timeout)
|
|
229
|
+
5. Displays API and Dashboard URLs
|
|
230
|
+
|
|
231
|
+
**Example:**
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Start with defaults
|
|
235
|
+
archlast start
|
|
236
|
+
|
|
237
|
+
# Start on custom port
|
|
238
|
+
archlast start --port 5000
|
|
239
|
+
|
|
240
|
+
# Start specific version
|
|
241
|
+
archlast start --image archlast/server --tag v1.2.0
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Output:**
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
API: http://localhost:4000
|
|
248
|
+
Dashboard: http://localhost:4000/_admin
|
|
249
|
+
Compose: .archlast/config/docker-compose.yml
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
#### `archlast stop`
|
|
253
|
+
|
|
254
|
+
Stop the running container.
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
archlast stop [options]
|
|
258
|
+
|
|
259
|
+
Options:
|
|
260
|
+
--path <path> Path to project root
|
|
261
|
+
--container <name> Docker container name
|
|
262
|
+
--config <path> Path to archlast.config.js
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
#### `archlast restart`
|
|
266
|
+
|
|
267
|
+
Restart the container with optional new configuration.
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
archlast restart [options]
|
|
271
|
+
|
|
272
|
+
# All options from 'start' are available
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
#### `archlast status`
|
|
276
|
+
|
|
277
|
+
Show container status and health information.
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
archlast status [options]
|
|
281
|
+
|
|
282
|
+
Options:
|
|
283
|
+
--path <path> Path to project root
|
|
284
|
+
--container <name> Docker container name
|
|
285
|
+
--config <path> Path to archlast.config.js
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Output includes:**
|
|
289
|
+
|
|
290
|
+
- Container name and state
|
|
291
|
+
- Health status
|
|
292
|
+
- Uptime
|
|
293
|
+
- Port mappings
|
|
294
|
+
- Image version
|
|
295
|
+
- CPU and memory usage
|
|
296
|
+
|
|
297
|
+
#### `archlast logs`
|
|
298
|
+
|
|
299
|
+
Stream container logs in real-time.
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
archlast logs [options]
|
|
303
|
+
|
|
304
|
+
Options:
|
|
305
|
+
--path <path> Path to project root
|
|
306
|
+
--container <name> Docker container name
|
|
307
|
+
--tail <lines> Number of log lines to show (default: 100)
|
|
308
|
+
--no-follow Do not follow logs (exit after showing)
|
|
309
|
+
--config <path> Path to archlast.config.js
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**Examples:**
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
# Follow logs in real-time (default)
|
|
316
|
+
archlast logs
|
|
317
|
+
|
|
318
|
+
# Show last 50 lines and exit
|
|
319
|
+
archlast logs --tail 50 --no-follow
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
#### `archlast upgrade`
|
|
323
|
+
|
|
324
|
+
Pull a new Docker image and restart the container.
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
archlast upgrade [options]
|
|
328
|
+
|
|
329
|
+
Options:
|
|
330
|
+
--path <path> Path to project root
|
|
331
|
+
--port <port> Host port to expose
|
|
332
|
+
--image <image> Docker image name
|
|
333
|
+
--tag <tag> Docker image tag
|
|
334
|
+
--version <version> Docker image version (alias for --tag)
|
|
335
|
+
--container <name> Docker container name
|
|
336
|
+
--config <path> Path to archlast.config.js
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**Example:**
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Upgrade to latest
|
|
343
|
+
archlast upgrade
|
|
344
|
+
|
|
345
|
+
# Upgrade to specific version
|
|
346
|
+
archlast upgrade --tag v1.3.0
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### `archlast config`
|
|
350
|
+
|
|
351
|
+
Show resolved Docker configuration.
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
archlast config [options]
|
|
355
|
+
|
|
356
|
+
Options:
|
|
357
|
+
--path <path> Path to project root
|
|
358
|
+
--config <path> Path to archlast.config.js
|
|
359
|
+
--json Output config as JSON
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
### Code Generation
|
|
365
|
+
|
|
366
|
+
#### `archlast generate crud <collection>`
|
|
367
|
+
|
|
368
|
+
Generate REST CRUD handlers for a collection defined in your schema.
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
archlast generate crud <collection> [options]
|
|
372
|
+
|
|
373
|
+
Options:
|
|
374
|
+
--path <path> Path to archlast folder (default: ".")
|
|
375
|
+
--force Overwrite existing files
|
|
376
|
+
--linked Create linked re-export file (default: true)
|
|
377
|
+
--ejected Create standalone handlers (not linked to _generated)
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**Example:**
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
# Generate CRUD for tasks collection
|
|
384
|
+
archlast generate crud tasks
|
|
385
|
+
|
|
386
|
+
# Force overwrite existing
|
|
387
|
+
archlast generate crud tasks --force
|
|
388
|
+
|
|
389
|
+
# Generate standalone (ejected) handlers
|
|
390
|
+
archlast generate crud tasks --ejected
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**Generated handlers (linked mode):**
|
|
394
|
+
|
|
395
|
+
Creates `src/functions/tasks.ts`:
|
|
396
|
+
|
|
397
|
+
```ts
|
|
398
|
+
// Auto-generated CRUD re-export for "tasks"
|
|
399
|
+
// This file links to the auto-generated handlers in _generated/crud
|
|
400
|
+
export * from "../_generated/crud/tasks";
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Generated handlers (ejected mode):**
|
|
404
|
+
|
|
405
|
+
Creates standalone handlers with full implementation that you can customize:
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
// Auto-generated CRUD handlers for "tasks"
|
|
409
|
+
import { http } from "../_generated/server";
|
|
410
|
+
import type { DataModel } from "../_generated/server";
|
|
411
|
+
|
|
412
|
+
export const listTasks = http.get({
|
|
413
|
+
path: "/tasks",
|
|
414
|
+
auth: "public",
|
|
415
|
+
handler: async (ctx) => {
|
|
416
|
+
return ctx.db.query("tasks").findMany();
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// ... get, create, update, delete handlers
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
### Data Management
|
|
426
|
+
|
|
427
|
+
All data commands require a Better-Auth API key for authentication. API keys use the `arch_` prefix and can be created via the dashboard or Better-Auth API.
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
# Set API key before running data commands
|
|
431
|
+
export ARCHLAST_API_KEY=arch_your_api_key
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
#### `archlast data snapshot`
|
|
435
|
+
|
|
436
|
+
Create a backup snapshot of all data.
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
archlast data snapshot [options]
|
|
440
|
+
|
|
441
|
+
Options:
|
|
442
|
+
--server <url> Server URL (default: "http://localhost:4000")
|
|
443
|
+
-n, --name <name> Custom snapshot name
|
|
444
|
+
--include-sqlite Include SQLite export (default: false)
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
**Example:**
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
archlast data snapshot --name "pre-migration-backup"
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Output:**
|
|
454
|
+
|
|
455
|
+
```
|
|
456
|
+
✅ Snapshot created: snapshot-2024-01-15-123456.zip
|
|
457
|
+
Records: 1234
|
|
458
|
+
Collections: 5
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
#### `archlast data export <outputFile>`
|
|
462
|
+
|
|
463
|
+
Export all data to a local file.
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
archlast data export <outputFile> [options]
|
|
467
|
+
|
|
468
|
+
Options:
|
|
469
|
+
--server <url> Server URL (default: "http://localhost:4000")
|
|
470
|
+
-f, --format <format> Export format: zip or json (default: "zip")
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Example:**
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
archlast data export backup.zip
|
|
477
|
+
archlast data export backup.json --format json
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### `archlast data import <inputFile>`
|
|
481
|
+
|
|
482
|
+
Import data from a local JSON or ZIP file (auto-detects format).
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
archlast data import <inputFile> [options]
|
|
486
|
+
|
|
487
|
+
Options:
|
|
488
|
+
--server <url> Server URL (default: "http://localhost:4000")
|
|
489
|
+
-s, --strategy <strategy> Import strategy: replace or merge (default: "merge")
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
**Example:**
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
archlast data import backup.json --strategy merge
|
|
496
|
+
archlast data import backup.zip
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
#### `archlast data restore <snapshotFile>`
|
|
500
|
+
|
|
501
|
+
Restore database from a server-side snapshot.
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
archlast data restore <snapshotFile> [options]
|
|
505
|
+
|
|
506
|
+
Options:
|
|
507
|
+
--server <url> Server URL (default: "http://localhost:4000")
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
**Example:**
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
archlast data restore snapshot-2024-01-15-123456
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
#### `archlast data delete <snapshotFile>`
|
|
517
|
+
|
|
518
|
+
Delete a snapshot file (supports .json and .zip).
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
archlast data delete <snapshotFile> [options]
|
|
522
|
+
|
|
523
|
+
Options:
|
|
524
|
+
--server <url> Server URL (default: "http://localhost:4000")
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
## Configuration
|
|
530
|
+
|
|
531
|
+
The CLI reads configuration in this priority order:
|
|
532
|
+
|
|
533
|
+
1. **CLI flags** (highest priority)
|
|
534
|
+
2. **archlast.config.js** or **archlast.config.ts**
|
|
535
|
+
3. **.env.local** (takes precedence over .env)
|
|
536
|
+
4. **.env**
|
|
537
|
+
5. **Defaults** (lowest priority)
|
|
538
|
+
|
|
539
|
+
### Configuration File
|
|
540
|
+
|
|
541
|
+
Create `archlast.config.js` in your project root:
|
|
542
|
+
|
|
543
|
+
```js
|
|
544
|
+
// archlast.config.js
|
|
545
|
+
export default {
|
|
546
|
+
// Docker configuration
|
|
547
|
+
docker: {
|
|
548
|
+
image: "archlast/server",
|
|
549
|
+
tag: "latest",
|
|
550
|
+
containerName: "archlast-server",
|
|
551
|
+
volumeName: "archlast-data",
|
|
552
|
+
},
|
|
553
|
+
|
|
554
|
+
// Server settings
|
|
555
|
+
server: {
|
|
556
|
+
port: 4000,
|
|
557
|
+
},
|
|
558
|
+
|
|
559
|
+
// Paths configuration
|
|
560
|
+
paths: {
|
|
561
|
+
config: ".archlast/config",
|
|
562
|
+
deploy: ".archlast-deploy",
|
|
563
|
+
},
|
|
564
|
+
|
|
565
|
+
// CORS settings
|
|
566
|
+
cors: {
|
|
567
|
+
origins: ["http://localhost:3000", "https://myapp.com"],
|
|
568
|
+
},
|
|
569
|
+
|
|
570
|
+
// Environment variables to forward to container
|
|
571
|
+
env: {
|
|
572
|
+
ARCHLAST_DASHBOARD_PORT: "4001",
|
|
573
|
+
ARCHLAST_STORE_PORT: "7001",
|
|
574
|
+
NODE_ENV: "production",
|
|
575
|
+
},
|
|
576
|
+
};
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Default Configuration Values
|
|
580
|
+
|
|
581
|
+
```js
|
|
582
|
+
{
|
|
583
|
+
docker: {
|
|
584
|
+
image: "archlast/server",
|
|
585
|
+
tag: "latest",
|
|
586
|
+
containerName: "archlast-server",
|
|
587
|
+
volumeName: "archlast-data",
|
|
588
|
+
},
|
|
589
|
+
server: {
|
|
590
|
+
port: 4000,
|
|
591
|
+
},
|
|
592
|
+
paths: {
|
|
593
|
+
config: ".archlast/config",
|
|
594
|
+
deploy: ".archlast-deploy",
|
|
595
|
+
},
|
|
596
|
+
cors: {
|
|
597
|
+
origins: ["http://localhost:3000"],
|
|
598
|
+
},
|
|
599
|
+
env: {
|
|
600
|
+
NODE_ENV: "development",
|
|
601
|
+
ARCHLAST_LOG_LEVEL: "info",
|
|
602
|
+
ARCHLAST_DB_ROOT: "/data",
|
|
603
|
+
STORAGE_ROOT: "/data/storage",
|
|
604
|
+
ARCHLAST_DASHBOARD_PORT: "4001",
|
|
605
|
+
ARCHLAST_STORE_PORT: "7001",
|
|
606
|
+
},
|
|
607
|
+
}
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
---
|
|
611
|
+
|
|
612
|
+
## Environment Variables
|
|
613
|
+
|
|
614
|
+
The following environment variable prefixes are automatically forwarded to the Docker container:
|
|
615
|
+
|
|
616
|
+
| Prefix | Description |
|
|
617
|
+
|--------|-------------|
|
|
618
|
+
| `ARCHLAST_*` | All Archlast configuration |
|
|
619
|
+
| `S3_*` | S3 storage configuration |
|
|
620
|
+
| `AWS_*` | AWS credentials |
|
|
621
|
+
| `STORAGE_*` | Storage settings |
|
|
622
|
+
|
|
623
|
+
Additionally, these specific variables are forwarded:
|
|
624
|
+
|
|
625
|
+
- `NODE_ENV`
|
|
626
|
+
- `BETTER_AUTH_SECRET`
|
|
627
|
+
|
|
628
|
+
### Key Variables
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
# API Authentication (Better-Auth API key with arch_ prefix)
|
|
632
|
+
ARCHLAST_API_KEY=arch_your_api_key
|
|
633
|
+
|
|
634
|
+
# Better-Auth Configuration
|
|
635
|
+
BETTER_AUTH_SECRET=your-32-char-secret-for-production
|
|
636
|
+
APP_URL=http://localhost:4000
|
|
637
|
+
|
|
638
|
+
# Server Configuration
|
|
639
|
+
ARCHLAST_PORT=4000
|
|
640
|
+
ARCHLAST_ALLOWED_ORIGINS=http://localhost:3000,https://myapp.com
|
|
641
|
+
ARCHLAST_CORS_ALLOW_CREDENTIALS=true
|
|
642
|
+
|
|
643
|
+
# Database
|
|
644
|
+
ARCHLAST_DB_ROOT=./data
|
|
645
|
+
|
|
646
|
+
# Storage
|
|
647
|
+
STORAGE_ROOT=./storage
|
|
648
|
+
S3_ENABLED=false
|
|
649
|
+
S3_BUCKET=my-bucket
|
|
650
|
+
S3_REGION=us-east-1
|
|
651
|
+
AWS_ACCESS_KEY_ID=your_key
|
|
652
|
+
AWS_SECRET_ACCESS_KEY=your_secret
|
|
653
|
+
|
|
654
|
+
# Document Store
|
|
655
|
+
ARCHLAST_STORE_HOST=127.0.0.1
|
|
656
|
+
ARCHLAST_STORE_PORT=7001
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## Generated Files
|
|
662
|
+
|
|
663
|
+
When you run `archlast dev` or `archlast build`, the CLI generates the following files:
|
|
664
|
+
|
|
665
|
+
### `_generated/server.ts`
|
|
666
|
+
|
|
667
|
+
Contains server-side type definitions:
|
|
668
|
+
|
|
669
|
+
```ts
|
|
670
|
+
// DataModel with all collection types
|
|
671
|
+
export type DataModel = {
|
|
672
|
+
tasks: {
|
|
673
|
+
_id: string;
|
|
674
|
+
_collection: "tasks";
|
|
675
|
+
text: string;
|
|
676
|
+
completed: boolean;
|
|
677
|
+
// ... fields from schema
|
|
678
|
+
};
|
|
679
|
+
// ... other collections
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
// Context types for functions
|
|
683
|
+
export type QueryCtx = { db: DatabaseReader; auth: AuthContext; ... };
|
|
684
|
+
export type MutationCtx = { db: DatabaseWriter; auth: AuthContext; ... };
|
|
685
|
+
export type ActionCtx = { ... };
|
|
686
|
+
|
|
687
|
+
// Function builders
|
|
688
|
+
export const query: QueryBuilder;
|
|
689
|
+
export const mutation: MutationBuilder;
|
|
690
|
+
export const action: ActionBuilder;
|
|
691
|
+
export const http: HttpBuilder;
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### `_generated/api.ts`
|
|
695
|
+
|
|
696
|
+
Contains client-side function references:
|
|
697
|
+
|
|
698
|
+
```ts
|
|
699
|
+
export const api = {
|
|
700
|
+
tasks: {
|
|
701
|
+
list: createFunctionReference<{}, Task[]>("tasks.list"),
|
|
702
|
+
get: createFunctionReference<{ id: string }, Task>("tasks.get"),
|
|
703
|
+
create: createFunctionReference<CreateTaskArgs, Task>("tasks.create"),
|
|
704
|
+
// ...
|
|
705
|
+
},
|
|
706
|
+
// ... other modules
|
|
707
|
+
};
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
### `_generated/rpc.ts`
|
|
711
|
+
|
|
712
|
+
Contains RPC procedure types:
|
|
713
|
+
|
|
714
|
+
```ts
|
|
715
|
+
export type RpcProcedures = {
|
|
716
|
+
"getUser": { args: { id: string }; result: User };
|
|
717
|
+
// ... procedures defined with rpc.query/rpc.mutation
|
|
718
|
+
};
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
### `_generated/trpc-router.ts`
|
|
722
|
+
|
|
723
|
+
Contains tRPC router definition:
|
|
724
|
+
|
|
725
|
+
```ts
|
|
726
|
+
import { initTRPC } from "@trpc/server";
|
|
727
|
+
|
|
728
|
+
const t = initTRPC.create();
|
|
729
|
+
export const appRouter = t.router({
|
|
730
|
+
getUser: t.procedure.input(...).query(...),
|
|
731
|
+
// ...
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
export type AppRouter = typeof appRouter;
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
### `_generated/crud/<collection>.ts`
|
|
738
|
+
|
|
739
|
+
Auto-generated REST CRUD handlers for each collection:
|
|
740
|
+
|
|
741
|
+
```ts
|
|
742
|
+
export const listTasks = http.get({ path: "/tasks", ... });
|
|
743
|
+
export const getTasks = http.get({ path: "/tasks/:id", ... });
|
|
744
|
+
export const createTasks = http.post({ path: "/tasks", ... });
|
|
745
|
+
export const updateTasks = http.patch({ path: "/tasks/:id", ... });
|
|
746
|
+
export const deleteTasks = http.delete({ path: "/tasks/:id", ... });
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### `_generated/di.ts`
|
|
750
|
+
|
|
751
|
+
Dependency injection registrations (if `@injectable()` decorators detected):
|
|
752
|
+
|
|
753
|
+
```ts
|
|
754
|
+
import { Container } from "@archlast/server/di/container";
|
|
755
|
+
|
|
756
|
+
export const providers = [
|
|
757
|
+
{ provide: "EmailService", useClass: ResendEmailService, scope: "transient" },
|
|
758
|
+
// ...
|
|
759
|
+
];
|
|
760
|
+
|
|
761
|
+
export function registerProviders(container: Container): void {
|
|
762
|
+
for (const provider of providers) {
|
|
763
|
+
container.register(provider);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
---
|
|
769
|
+
|
|
770
|
+
## Usage Examples
|
|
771
|
+
|
|
772
|
+
### Complete Development Workflow
|
|
773
|
+
|
|
774
|
+
```bash
|
|
775
|
+
# 1. Initialize and start server
|
|
776
|
+
archlast start
|
|
777
|
+
|
|
778
|
+
# 2. Start development with hot reload
|
|
779
|
+
archlast dev --path ./my-app
|
|
780
|
+
|
|
781
|
+
# 3. Generate CRUD for new collection
|
|
782
|
+
archlast generate crud users
|
|
783
|
+
|
|
784
|
+
# 4. Check logs if issues arise
|
|
785
|
+
archlast logs
|
|
786
|
+
|
|
787
|
+
# 5. Create backup before major changes
|
|
788
|
+
archlast data snapshot --name "before-feature-x"
|
|
789
|
+
|
|
790
|
+
# 6. Deploy to production
|
|
791
|
+
archlast deploy --server https://api.production.com
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### CI/CD Pipeline
|
|
795
|
+
|
|
796
|
+
```yaml
|
|
797
|
+
# .github/workflows/deploy.yml
|
|
798
|
+
name: Deploy Archlast
|
|
799
|
+
|
|
800
|
+
on:
|
|
801
|
+
push:
|
|
802
|
+
branches: [main]
|
|
803
|
+
|
|
804
|
+
jobs:
|
|
805
|
+
deploy:
|
|
806
|
+
runs-on: ubuntu-latest
|
|
807
|
+
steps:
|
|
808
|
+
- uses: actions/checkout@v4
|
|
809
|
+
|
|
810
|
+
- name: Setup Node.js
|
|
811
|
+
uses: actions/setup-node@v4
|
|
812
|
+
with:
|
|
813
|
+
node-version: '20'
|
|
814
|
+
|
|
815
|
+
- name: Install CLI
|
|
816
|
+
run: npm install -g @archlast/cli
|
|
817
|
+
|
|
818
|
+
- name: Build types
|
|
819
|
+
run: archlast build --path ./archlast
|
|
820
|
+
|
|
821
|
+
- name: Deploy
|
|
822
|
+
run: archlast deploy --path ./archlast --server ${{ secrets.API_URL }}
|
|
823
|
+
env:
|
|
824
|
+
ARCHLAST_API_KEY: ${{ secrets.ARCHLAST_API_KEY }}
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
### Multi-Environment Setup
|
|
828
|
+
|
|
829
|
+
```bash
|
|
830
|
+
# Development
|
|
831
|
+
archlast dev --server http://localhost:4000
|
|
832
|
+
|
|
833
|
+
# Staging
|
|
834
|
+
archlast deploy --server https://api.staging.myapp.com
|
|
835
|
+
|
|
836
|
+
# Production
|
|
837
|
+
archlast deploy --server https://api.myapp.com
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
---
|
|
841
|
+
|
|
842
|
+
## Troubleshooting
|
|
843
|
+
|
|
844
|
+
### Common Issues
|
|
845
|
+
|
|
846
|
+
#### "Docker not found"
|
|
847
|
+
|
|
848
|
+
Ensure Docker is installed and running:
|
|
849
|
+
|
|
850
|
+
```bash
|
|
851
|
+
docker --version
|
|
852
|
+
docker ps # Should not error
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
#### "Server not reachable after X retries"
|
|
856
|
+
|
|
857
|
+
The server might not be running or is not healthy:
|
|
858
|
+
|
|
859
|
+
```bash
|
|
860
|
+
archlast status
|
|
861
|
+
archlast start
|
|
862
|
+
archlast logs # Check for errors
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
#### "Authentication failed" / "API key not found"
|
|
866
|
+
|
|
867
|
+
Set the API key with the correct `arch_` prefix:
|
|
868
|
+
|
|
869
|
+
```bash
|
|
870
|
+
export ARCHLAST_API_KEY=arch_your_key
|
|
871
|
+
|
|
872
|
+
# Or add to .env.local file
|
|
873
|
+
echo "ARCHLAST_API_KEY=arch_your_key" >> .env.local
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
API keys can be created via the admin dashboard at `/_archlast/admin/api-keys` or through the Better-Auth API.
|
|
877
|
+
|
|
878
|
+
#### "Permission denied" (Linux)
|
|
879
|
+
|
|
880
|
+
For Docker socket access:
|
|
881
|
+
|
|
882
|
+
```bash
|
|
883
|
+
sudo usermod -aG docker $USER
|
|
884
|
+
newgrp docker
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
#### "Schema file not found"
|
|
888
|
+
|
|
889
|
+
Ensure your schema is at `src/schema.ts` or `src/schema/index.ts`:
|
|
890
|
+
|
|
891
|
+
```
|
|
892
|
+
my-app/
|
|
893
|
+
├── src/
|
|
894
|
+
│ ├── schema.ts # Required
|
|
895
|
+
│ └── functions/
|
|
896
|
+
└── archlast.config.js
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
#### "Collection not found in schema"
|
|
900
|
+
|
|
901
|
+
When using `generate crud`, the collection must be defined with `defineTable`:
|
|
902
|
+
|
|
903
|
+
```ts
|
|
904
|
+
// src/schema.ts
|
|
905
|
+
import { defineTable, v } from "@archlast/server/schema";
|
|
906
|
+
|
|
907
|
+
export const tasks = defineTable({
|
|
908
|
+
_id: v.id().primaryKey(),
|
|
909
|
+
text: v.string(),
|
|
910
|
+
completed: v.boolean().default(false),
|
|
911
|
+
});
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
### Podman Support
|
|
915
|
+
|
|
916
|
+
Podman is experimentally supported. If you encounter issues:
|
|
917
|
+
|
|
918
|
+
```bash
|
|
919
|
+
# Ensure DOCKER_HOST is set correctly
|
|
920
|
+
export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
---
|
|
924
|
+
|
|
925
|
+
## Code Analysis
|
|
926
|
+
|
|
927
|
+
The CLI uses `ts-morph` for sophisticated TypeScript analysis:
|
|
928
|
+
|
|
929
|
+
- **Functions**: Detects `query()`, `mutation()`, `action()` exports
|
|
930
|
+
- **HTTP Routes**: Detects `http.get()`, `http.post()`, `http.put()`, `http.delete()`, `http.patch()`
|
|
931
|
+
- **RPC Procedures**: Detects `rpc.query()`, `rpc.mutation()`
|
|
932
|
+
- **Injectables**: Detects `@injectable()` decorated classes
|
|
933
|
+
- **Schema**: Parses `defineTable()` definitions
|
|
934
|
+
|
|
935
|
+
### Supported Function Patterns
|
|
936
|
+
|
|
937
|
+
```ts
|
|
938
|
+
// Arrow function handler
|
|
939
|
+
export const listTasks = query(async (ctx) => { ... });
|
|
940
|
+
|
|
941
|
+
// Object with handler
|
|
942
|
+
export const createTask = mutation({
|
|
943
|
+
args: { text: v.string().zodSchema },
|
|
944
|
+
handler: async (ctx, args) => { ... },
|
|
945
|
+
});
|
|
946
|
+
|
|
947
|
+
// With auth mode
|
|
948
|
+
export const publicQuery = query({
|
|
949
|
+
auth: "public", // "required" | "optional" | "public"
|
|
950
|
+
handler: async (ctx) => { ... },
|
|
951
|
+
});
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
---
|
|
955
|
+
|
|
124
956
|
## Testing
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
Coverage target: 90%+ lines/branches/functions
|
|
146
|
-
|
|
147
|
-
## Publishing (maintainers)
|
|
148
|
-
|
|
149
|
-
See `docs/npm-publishing.md` for the release workflow and manual publish steps.
|
|
957
|
+
|
|
958
|
+
```bash
|
|
959
|
+
# Run all CLI tests
|
|
960
|
+
bun test
|
|
961
|
+
|
|
962
|
+
# Run specific test
|
|
963
|
+
bun test tests/cli.test.ts
|
|
964
|
+
|
|
965
|
+
# Run with coverage
|
|
966
|
+
bun test --coverage
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
## Keywords
|
|
970
|
+
|
|
971
|
+
archlast, cli, reactive, backend, code-generation, deployment, docker, typescript
|
|
972
|
+
|
|
973
|
+
## License
|
|
974
|
+
|
|
975
|
+
MIT
|