@chaim-tools/chaim 0.1.5 → 0.1.7
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 +406 -117
- package/dist/commands/bump.d.ts +10 -0
- package/dist/commands/bump.d.ts.map +1 -0
- package/dist/commands/bump.js +90 -0
- package/dist/commands/bump.js.map +1 -0
- package/dist/commands/context.d.ts +19 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +368 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/types/snapshot-payload.d.ts +1 -1
- package/package.json +9 -8
- package/shared/scripts/setup.sh +20 -26
- package/shared/templates/CHAIM_AGENT_CONTEXT.md +666 -0
package/README.md
CHANGED
|
@@ -1,110 +1,185 @@
|
|
|
1
1
|
# chaim-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The command-line tool that generates type-safe Java SDKs from your DynamoDB schema snapshots. It reads the local snapshots produced by `chaim-cdk`, groups entities by table, validates key consistency, and invokes the Java code generator to produce ready-to-use entity classes, repositories, validators, and configuration.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**npm**: [`@chaim-tools/chaim`](https://www.npmjs.com/package/@chaim-tools/chaim)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Where This Fits
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
.bprint file ──> chaim-cdk ──> chaim-cli ──> chaim-client-java
|
|
11
|
+
^ │
|
|
12
|
+
│ v
|
|
13
|
+
YOU RUN THIS Generated Java SDK
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The CLI sits between the CDK construct and the code generator. It discovers cached snapshots from your file system, resolves table metadata (including GSIs and LSIs), and delegates to `chaim-client-java` for Java source file generation. The generated code supports all `.bprint` field types including recursive nesting (maps within maps, lists of maps within maps) with no depth limit.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
8
19
|
|
|
9
20
|
```bash
|
|
10
|
-
|
|
11
|
-
cdk synth # Creates LOCAL snapshot in OS cache
|
|
12
|
-
# OR
|
|
13
|
-
cdk deploy # Creates LOCAL snapshot + publishes to Chaim SaaS
|
|
21
|
+
npm install -g @chaim-tools/chaim
|
|
14
22
|
```
|
|
15
23
|
|
|
16
|
-
|
|
24
|
+
**Requirements**: Node.js 18+, Java 11+ (runtime for code generation)
|
|
17
25
|
|
|
18
26
|
## Quick Start
|
|
19
27
|
|
|
20
28
|
```bash
|
|
21
|
-
# 1.
|
|
29
|
+
# 1. Synthesize your CDK project to create a local snapshot
|
|
22
30
|
cd my-cdk-project
|
|
23
31
|
cdk synth
|
|
24
32
|
|
|
25
|
-
# 2. Generate SDK (run from your Java application directory)
|
|
26
|
-
cd my-java-app
|
|
33
|
+
# 2. Generate the Java SDK (run from your Java application directory)
|
|
34
|
+
cd ../my-java-app
|
|
27
35
|
chaim generate --package com.mycompany.myapp.model
|
|
28
36
|
|
|
29
|
-
#
|
|
37
|
+
# Your Java SDK is now in ./src/main/java/
|
|
30
38
|
```
|
|
31
39
|
|
|
32
|
-
|
|
40
|
+
The CLI reads snapshots from the OS cache (`~/.chaim/cache/snapshots/`). You can run it from any directory.
|
|
41
|
+
|
|
42
|
+
## CDK Prerequisites
|
|
43
|
+
|
|
44
|
+
Before running `chaim generate`, your CDK project must produce valid snapshots via `cdk synth`. The CDK construct enforces two important safeguards:
|
|
45
|
+
|
|
46
|
+
- **Field reference validation** — All DynamoDB key attributes (table PK/SK, GSI/LSI keys, TTL attribute) must exist as fields in the `.bprint` schema. Mismatches fail the CDK synth immediately with a descriptive error.
|
|
47
|
+
- **Strict failure mode** — Deployment defaults to `STRICT`, meaning ingestion failures cause CloudFormation rollback. Use `FailureMode.BEST_EFFORT` explicitly if you want deployment to continue on ingestion errors.
|
|
48
|
+
|
|
49
|
+
## Commands
|
|
50
|
+
|
|
51
|
+
### `chaim generate`
|
|
52
|
+
|
|
53
|
+
Generates Java SDK code from local snapshots.
|
|
33
54
|
|
|
34
55
|
```bash
|
|
35
|
-
|
|
56
|
+
chaim generate --package com.mycompany.myapp.model
|
|
36
57
|
```
|
|
37
58
|
|
|
38
|
-
|
|
59
|
+
| Option | Required | Default | Description |
|
|
60
|
+
|--------|----------|---------|-------------|
|
|
61
|
+
| `--package <name>` | Yes | — | Java package name (e.g., `com.mycompany.myapp.model`) |
|
|
62
|
+
| `-l, --language <lang>` | No | `java` | Target language |
|
|
63
|
+
| `--output <dir>` | No | `./src/main/java` | Output directory |
|
|
64
|
+
| `--stack <name>` | No | — | Filter snapshots by CDK stack name |
|
|
65
|
+
| `--snapshot-dir <path>` | No | OS cache | Override snapshot directory |
|
|
66
|
+
| `--skip-checks` | No | `false` | Skip environment validation |
|
|
67
|
+
|
|
68
|
+
**What it does**:
|
|
69
|
+
|
|
70
|
+
1. Scans the OS cache for snapshot files produced by `chaim-cdk`
|
|
71
|
+
2. Filters by stack name (if provided) and discards DELETE-action snapshots
|
|
72
|
+
3. Groups entities by physical DynamoDB table (using table ARN or composite key)
|
|
73
|
+
4. Validates that all entities sharing a table have matching partition/sort key field names
|
|
74
|
+
5. Detects field name collisions from `nameOverride` or auto-conversion
|
|
75
|
+
6. Passes schemas and table metadata (including GSI/LSI definitions) to the Java generator. LSI metadata does not include `partitionKey` — the generator uses the table's own partition key since LSIs always share it
|
|
76
|
+
7. Writes generated `.java` files to the output directory
|
|
39
77
|
|
|
40
|
-
|
|
78
|
+
### `chaim validate`
|
|
79
|
+
|
|
80
|
+
Validates a `.bprint` schema file and displays the field mapping table.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
chaim validate ./schemas/user.bprint
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `chaim doctor`
|
|
87
|
+
|
|
88
|
+
Checks your system environment for required dependencies.
|
|
41
89
|
|
|
42
90
|
```bash
|
|
43
91
|
chaim doctor
|
|
44
92
|
```
|
|
45
93
|
|
|
46
|
-
|
|
47
|
-
- Node.js v18+
|
|
48
|
-
- Java 11+ (for code generation)
|
|
49
|
-
- AWS CLI (configured)
|
|
94
|
+
Verifies: Node.js version, Java installation, AWS CLI availability.
|
|
50
95
|
|
|
51
|
-
|
|
96
|
+
### `chaim init`
|
|
52
97
|
|
|
53
|
-
|
|
98
|
+
Verifies and optionally installs prerequisites.
|
|
54
99
|
|
|
55
100
|
```bash
|
|
56
|
-
#
|
|
57
|
-
chaim
|
|
58
|
-
|
|
59
|
-
# Explicitly specify language
|
|
60
|
-
chaim generate --package com.mycompany.myapp.model --language java
|
|
101
|
+
chaim init # Verify only
|
|
102
|
+
chaim init --install # Install missing dependencies
|
|
103
|
+
```
|
|
61
104
|
|
|
62
|
-
|
|
63
|
-
chaim generate --package com.mycompany.myapp.model --stack MyStack
|
|
105
|
+
### `chaim bump`
|
|
64
106
|
|
|
65
|
-
|
|
66
|
-
chaim generate --package com.mycompany.myapp.model --output ./generated
|
|
107
|
+
Increments the `schemaVersion` in a `.bprint` file.
|
|
67
108
|
|
|
68
|
-
|
|
69
|
-
chaim
|
|
109
|
+
```bash
|
|
110
|
+
chaim bump ./schemas/user.bprint # minor bump: 1.3 -> 1.4
|
|
111
|
+
chaim bump ./schemas/user.bprint --major # major bump: 1.3 -> 2.0
|
|
70
112
|
```
|
|
71
113
|
|
|
72
|
-
|
|
114
|
+
| Option | Required | Default | Description |
|
|
115
|
+
|--------|----------|---------|-------------|
|
|
116
|
+
| `<schemaFile>` | Yes | — | Path to the `.bprint` file |
|
|
117
|
+
| `--major` | No | `false` | Major version bump instead of minor |
|
|
73
118
|
|
|
74
|
-
|
|
75
|
-
|--------|----------|-------------|---------|
|
|
76
|
-
| `--package` | **Yes** | Package name (e.g., `com.mycompany.myapp.model` for Java) | - |
|
|
77
|
-
| `-l, --language` | No | Target language for code generation | java |
|
|
78
|
-
| `--output` | No | Output directory | ./src/main/java |
|
|
79
|
-
| `--stack` | No | Filter by CDK stack name | - |
|
|
80
|
-
| `--snapshot-dir` | No | Override snapshot directory | OS cache |
|
|
81
|
-
| `--skip-checks` | No | Skip environment checks | false |
|
|
119
|
+
The `schemaVersion` is a customer-controlled field. The Chaim system validates during `cdk deploy` that the version was bumped when schema content changes. Use this command to increment the version before deploying.
|
|
82
120
|
|
|
83
|
-
|
|
84
|
-
- `java` (default) — generates Java DTOs, ChaimConfig, and ChaimMapperClient
|
|
121
|
+
### `chaim clean`
|
|
85
122
|
|
|
86
|
-
|
|
123
|
+
Prunes old or stack-specific snapshots from the local cache.
|
|
87
124
|
|
|
88
125
|
```bash
|
|
89
|
-
#
|
|
90
|
-
chaim
|
|
126
|
+
chaim clean --all # Remove all snapshots
|
|
127
|
+
chaim clean --stack MyStack # Remove snapshots for a specific stack
|
|
128
|
+
chaim clean --older-than 30 # Remove snapshots older than 30 days
|
|
129
|
+
chaim clean --dry-run # Show what would be deleted
|
|
130
|
+
```
|
|
91
131
|
|
|
92
|
-
|
|
93
|
-
chaim validate ./schemas/user.bprint
|
|
132
|
+
### `chaim context`
|
|
94
133
|
|
|
95
|
-
|
|
96
|
-
|
|
134
|
+
Downloads an AI agent context file that teaches coding agents how to use the Chaim toolchain in your project.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
chaim context # Write .chaim/CHAIM_AGENT_CONTEXT.md; auto-detect agents
|
|
138
|
+
chaim context --agent cursor # Also write .cursor/rules/chaim.md
|
|
139
|
+
chaim context --agent all # Write to all supported agent locations
|
|
140
|
+
chaim context --no-auto # Only write canonical file, skip auto-detection
|
|
141
|
+
chaim context --remove # Remove Chaim context from all locations
|
|
142
|
+
chaim context --list-agents # Show supported agents and detection status
|
|
97
143
|
```
|
|
98
144
|
|
|
145
|
+
| Option | Description |
|
|
146
|
+
|--------|-------------|
|
|
147
|
+
| `--agent <name>` | Target a specific AI tool: `cursor`, `copilot`, `claude`, `windsurf`, `aider`, `generic`, `all` |
|
|
148
|
+
| `--no-auto` | Skip auto-detection; only write the canonical `.chaim/CHAIM_AGENT_CONTEXT.md` |
|
|
149
|
+
| `--remove` | Remove managed Chaim context blocks from all agent locations |
|
|
150
|
+
| `--list-agents` | Show supported agents, their detection status, and file paths |
|
|
151
|
+
|
|
152
|
+
**What it does**:
|
|
153
|
+
|
|
154
|
+
1. Writes a comprehensive guide to `.chaim/CHAIM_AGENT_CONTEXT.md` (always)
|
|
155
|
+
2. Auto-detects which AI tools are present (`.cursor/`, `CLAUDE.md`, `.windsurfrules`, etc.)
|
|
156
|
+
3. Places the context into each detected tool's config location
|
|
157
|
+
|
|
158
|
+
**Supported agents and placement strategy**:
|
|
159
|
+
|
|
160
|
+
| Agent | File | Strategy |
|
|
161
|
+
|-------|------|----------|
|
|
162
|
+
| `cursor` | `.cursor/rules/chaim.md` | Dedicated file (overwrite) |
|
|
163
|
+
| `copilot` | `.github/copilot-instructions.md` | Append managed block |
|
|
164
|
+
| `claude` | `CLAUDE.md` | Append managed block |
|
|
165
|
+
| `windsurf` | `.windsurfrules` | Append managed block |
|
|
166
|
+
| `aider` | `.aider.conf.yml` | Add read-only reference |
|
|
167
|
+
| `generic` | `AGENTS.md` | Append managed block |
|
|
168
|
+
|
|
169
|
+
For append targets, the content is wrapped in HTML comment fences (`<!-- CHAIM_AGENT_CONTEXT_START -->` / `<!-- CHAIM_AGENT_CONTEXT_END -->`). Running the command again replaces the existing block in-place (idempotent). Existing content in those files is preserved.
|
|
170
|
+
|
|
99
171
|
## Snapshot Locations
|
|
100
172
|
|
|
101
|
-
|
|
173
|
+
The CLI reads from the global OS cache, so it works regardless of your current directory.
|
|
102
174
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
175
|
+
| OS | Default Path |
|
|
176
|
+
|----|--------------|
|
|
177
|
+
| macOS / Linux | `~/.chaim/cache/snapshots/` |
|
|
178
|
+
| Windows | `%LOCALAPPDATA%/chaim/cache/snapshots/` |
|
|
106
179
|
|
|
107
|
-
|
|
180
|
+
Override with `CHAIM_SNAPSHOT_DIR` or `--snapshot-dir`.
|
|
181
|
+
|
|
182
|
+
Directory structure:
|
|
108
183
|
```
|
|
109
184
|
~/.chaim/cache/snapshots/
|
|
110
185
|
└── aws/
|
|
@@ -115,97 +190,311 @@ Snapshots are stored in a **global OS cache**, allowing the CLI to work from any
|
|
|
115
190
|
└── {resourceId}.json
|
|
116
191
|
```
|
|
117
192
|
|
|
118
|
-
##
|
|
193
|
+
## Generated Output
|
|
194
|
+
|
|
195
|
+
For a package `com.example.model` with `User` and `Order` entities on the same table:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
src/main/java/com/example/model/
|
|
199
|
+
├── User.java # Entity DTO (@DynamoDbBean + Lombok)
|
|
200
|
+
├── Order.java # Entity DTO
|
|
201
|
+
├── keys/
|
|
202
|
+
│ ├── UserKeys.java # Key constants, INDEX_ constants, key() helper
|
|
203
|
+
│ └── OrderKeys.java
|
|
204
|
+
├── repository/
|
|
205
|
+
│ ├── UserRepository.java # save(), findByKey(), deleteByKey(), queryBy{Index}()
|
|
206
|
+
│ └── OrderRepository.java
|
|
207
|
+
├── validation/
|
|
208
|
+
│ ├── UserValidator.java # Required, constraint, and enum checks
|
|
209
|
+
│ ├── OrderValidator.java
|
|
210
|
+
│ └── ChaimValidationException.java # Structured validation errors
|
|
211
|
+
├── client/
|
|
212
|
+
│ └── ChaimDynamoDbClient.java # DI-friendly DynamoDB client wrapper
|
|
213
|
+
└── config/
|
|
214
|
+
└── ChaimConfig.java # Table constants, lazy client, repository factories
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Field Type Mappings
|
|
218
|
+
|
|
219
|
+
| .bprint Type | Java Type | Notes |
|
|
220
|
+
|--------------|-----------|-------|
|
|
221
|
+
| `string` | `String` | |
|
|
222
|
+
| `number` | `Double` | |
|
|
223
|
+
| `boolean` | `Boolean` | |
|
|
224
|
+
| `timestamp` | `Instant` | `java.time.Instant` |
|
|
225
|
+
| `list` (scalar) | `List<String>`, `List<Double>`, etc. | Parameterized by `items.type` |
|
|
226
|
+
| `list` (map) | `List<{FieldName}Item>` | Inner `@DynamoDbBean` class |
|
|
227
|
+
| `map` | `{FieldName}` (inner class) | Inner `@DynamoDbBean` class; supports recursive nesting |
|
|
228
|
+
| `stringSet` | `Set<String>` | |
|
|
229
|
+
| `numberSet` | `Set<Double>` | |
|
|
119
230
|
|
|
120
|
-
|
|
231
|
+
Recursive nesting is fully supported. A `map` field can contain nested `map` or `list` fields, which generate further inner static classes. There is no hardcoded depth limit — the database itself is the guardrail.
|
|
232
|
+
|
|
233
|
+
## Using the Generated Code
|
|
234
|
+
|
|
235
|
+
### Add Dependencies to Your Java Project
|
|
236
|
+
|
|
237
|
+
The generated code requires these dependencies (Gradle example):
|
|
238
|
+
|
|
239
|
+
```kotlin
|
|
240
|
+
dependencies {
|
|
241
|
+
implementation("software.amazon.awssdk:dynamodb-enhanced:2.21.+")
|
|
242
|
+
compileOnly("org.projectlombok:lombok:1.18.+")
|
|
243
|
+
annotationProcessor("org.projectlombok:lombok:1.18.+")
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Basic Usage
|
|
248
|
+
|
|
249
|
+
```java
|
|
250
|
+
// Use the generated config for a singleton client
|
|
251
|
+
UserRepository users = ChaimConfig.userRepository();
|
|
252
|
+
|
|
253
|
+
// Save an entity (validates constraints automatically)
|
|
254
|
+
User user = User.builder()
|
|
255
|
+
.userId("user-123")
|
|
256
|
+
.email("alice@example.com")
|
|
257
|
+
.isActive(true)
|
|
258
|
+
.build();
|
|
259
|
+
users.save(user);
|
|
260
|
+
|
|
261
|
+
// Find by key
|
|
262
|
+
Optional<User> found = users.findByKey("user-123");
|
|
263
|
+
|
|
264
|
+
// Delete
|
|
265
|
+
users.deleteByKey("user-123");
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### GSI/LSI Queries
|
|
269
|
+
|
|
270
|
+
The generator produces typed query methods for every GSI and LSI on the table. Each index generates a PK-only method and a PK+SK overloaded method (when the index has a sort key).
|
|
271
|
+
|
|
272
|
+
```java
|
|
273
|
+
OrderRepository orders = ChaimConfig.orderRepository();
|
|
274
|
+
|
|
275
|
+
// GSI query — uses the GSI's own partition key
|
|
276
|
+
List<Order> customerOrders = orders.queryByCustomerIndex("customer-123");
|
|
277
|
+
|
|
278
|
+
// GSI query with sort key — PK + SK overload
|
|
279
|
+
List<Order> filtered = orders.queryByCustomerDateIndex("customer-123", "2024-01-15");
|
|
280
|
+
|
|
281
|
+
// LSI query — uses the table's partition key (LSIs always share it)
|
|
282
|
+
List<Order> sorted = orders.queryByAmountIndex("order-456");
|
|
283
|
+
List<Order> ranged = orders.queryByAmountIndex("order-456", "100.00");
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Custom Client (Local DynamoDB, Testing)
|
|
287
|
+
|
|
288
|
+
```java
|
|
289
|
+
ChaimDynamoDbClient client = ChaimConfig.clientBuilder()
|
|
290
|
+
.endpoint("http://localhost:8000")
|
|
291
|
+
.build();
|
|
292
|
+
UserRepository users = ChaimConfig.userRepository(client);
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Troubleshooting
|
|
296
|
+
|
|
297
|
+
### "No snapshot found"
|
|
298
|
+
|
|
299
|
+
You need to create a snapshot first by running `cdk synth` or `cdk deploy` in your CDK project:
|
|
121
300
|
|
|
122
301
|
```bash
|
|
123
|
-
# Navigate to your CDK project
|
|
124
302
|
cd my-cdk-project
|
|
303
|
+
cdk synth
|
|
304
|
+
```
|
|
125
305
|
|
|
126
|
-
|
|
127
|
-
cdk synth # For development
|
|
128
|
-
# OR
|
|
129
|
-
cdk deploy # For production
|
|
306
|
+
Then run `chaim generate` from any directory.
|
|
130
307
|
|
|
131
|
-
|
|
132
|
-
|
|
308
|
+
### Stack filter does not match
|
|
309
|
+
|
|
310
|
+
The CLI shows existing snapshots that did not match your `--stack` filter, helping you adjust the value.
|
|
311
|
+
|
|
312
|
+
## Using in Your Application Codebase
|
|
313
|
+
|
|
314
|
+
A typical project layout:
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
my-cdk-project/ # CDK infrastructure
|
|
318
|
+
├── schemas/
|
|
319
|
+
│ ├── user.bprint
|
|
320
|
+
│ └── order.bprint
|
|
321
|
+
├── lib/my-stack.ts
|
|
322
|
+
└── package.json
|
|
323
|
+
|
|
324
|
+
my-java-app/ # Java application
|
|
325
|
+
├── src/main/java/com/example/model/ # ← generated by `chaim generate`
|
|
326
|
+
│ ├── User.java
|
|
327
|
+
│ ├── Order.java
|
|
328
|
+
│ └── ...
|
|
329
|
+
├── src/main/java/com/example/ # Your application code
|
|
330
|
+
│ └── service/UserService.java
|
|
331
|
+
├── build.gradle.kts
|
|
332
|
+
└── ...
|
|
133
333
|
```
|
|
134
334
|
|
|
135
|
-
|
|
136
|
-
- Haven't run `cdk synth` or `cdk deploy` yet
|
|
137
|
-
- Filters (`--stack`) don't match existing snapshots
|
|
138
|
-
- Snapshots in non-default location (use `--snapshot-dir`)
|
|
335
|
+
Run `cdk synth` once, then `chaim generate --package com.example.model` in your Java project. Re-run whenever you change a `.bprint` file or add a new entity.
|
|
139
336
|
|
|
140
|
-
|
|
337
|
+
## Development
|
|
141
338
|
|
|
142
|
-
|
|
339
|
+
### Prerequisites
|
|
340
|
+
|
|
341
|
+
- **Node.js 18+** — required for building and running the CLI
|
|
342
|
+
- **npm** — comes with Node.js
|
|
143
343
|
|
|
344
|
+
### Setup
|
|
345
|
+
|
|
346
|
+
Clone the repository and install dependencies:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
npm install
|
|
144
350
|
```
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
└── ChaimMapperClient.java # DynamoDB mapper
|
|
351
|
+
|
|
352
|
+
Or use the included setup script, which validates your Node.js version, installs dependencies, and builds in one step:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
npm run setup
|
|
151
356
|
```
|
|
152
357
|
|
|
153
|
-
###
|
|
358
|
+
### Building
|
|
154
359
|
|
|
155
|
-
|
|
156
|
-
// Create mapper client
|
|
157
|
-
ChaimMapperClient mapper = ChaimConfig.createMapper();
|
|
360
|
+
The CLI is written in TypeScript and compiles to `dist/` via the TypeScript compiler.
|
|
158
361
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
user.setEmail("john@example.com");
|
|
163
|
-
mapper.save(user);
|
|
362
|
+
```bash
|
|
363
|
+
npm run build # Compile TypeScript → dist/
|
|
364
|
+
```
|
|
164
365
|
|
|
165
|
-
|
|
166
|
-
|
|
366
|
+
To start from a clean state:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
npm run clean # Delete dist/
|
|
370
|
+
npm run build # Rebuild
|
|
167
371
|
```
|
|
168
372
|
|
|
169
|
-
|
|
373
|
+
The build emits CommonJS modules targeting ES2020 with declarations, declaration maps, and source maps (configured in `tsconfig.json`).
|
|
170
374
|
|
|
171
|
-
|
|
375
|
+
### Running Locally (Development)
|
|
172
376
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
"output": "./src/main/java"
|
|
178
|
-
}
|
|
179
|
-
}
|
|
377
|
+
You can run the CLI directly from source without compiling first:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
npm run dev -- generate --package com.example.model
|
|
180
381
|
```
|
|
181
382
|
|
|
182
|
-
|
|
383
|
+
Or after building, run the compiled output:
|
|
384
|
+
|
|
183
385
|
```bash
|
|
184
|
-
|
|
386
|
+
npm start -- generate --package com.example.model
|
|
387
|
+
# equivalent to: node dist/index.js generate --package com.example.model
|
|
185
388
|
```
|
|
186
389
|
|
|
187
|
-
|
|
390
|
+
### Testing
|
|
391
|
+
|
|
392
|
+
Tests use [Vitest](https://vitest.dev/) and live alongside the source files (`*.test.ts`).
|
|
188
393
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
| `number` | `Double` |
|
|
193
|
-
| `boolean` | `Boolean` |
|
|
194
|
-
| `timestamp` | `Instant` |
|
|
394
|
+
```bash
|
|
395
|
+
npm test # Run all tests in watch mode
|
|
396
|
+
```
|
|
195
397
|
|
|
196
|
-
|
|
398
|
+
To run tests once (CI-friendly):
|
|
197
399
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
| [chaim-bprint-spec](https://github.com/chaim-tools/chaim-bprint-spec) | Schema specification |
|
|
202
|
-
| [chaim-client-java](https://github.com/chaim-tools/chaim-client-java) | Java code generation |
|
|
400
|
+
```bash
|
|
401
|
+
npx vitest run
|
|
402
|
+
```
|
|
203
403
|
|
|
204
|
-
|
|
404
|
+
To run a specific test file:
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
npx vitest run src/commands/generate.test.ts
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Test files:
|
|
411
|
+
|
|
412
|
+
| File | Covers |
|
|
413
|
+
|------|--------|
|
|
414
|
+
| `src/index.test.ts` | CLI entry point and command registration |
|
|
415
|
+
| `src/commands/generate.test.ts` | `chaim generate` command |
|
|
416
|
+
| `src/commands/validate.test.ts` | `chaim validate` command |
|
|
417
|
+
| `src/commands/init.test.ts` | `chaim init` command |
|
|
418
|
+
| `src/commands/doctor.test.ts` | `chaim doctor` command |
|
|
419
|
+
| `src/commands/context.test.ts` | `chaim context` command |
|
|
420
|
+
| `src/services/snapshot-discovery.test.ts` | Snapshot file discovery logic |
|
|
421
|
+
| `src/services/name-resolver.test.ts` | Field name resolution and collision detection |
|
|
422
|
+
|
|
423
|
+
### Linting
|
|
424
|
+
|
|
425
|
+
The project uses ESLint with TypeScript support.
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
npm run lint # Check for lint errors
|
|
429
|
+
npm run lint:fix # Auto-fix lint errors
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Project Structure
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
chaim-cli/
|
|
436
|
+
├── src/ # TypeScript source
|
|
437
|
+
│ ├── index.ts # CLI entry point (Commander.js)
|
|
438
|
+
│ ├── commands/ # Command implementations
|
|
439
|
+
│ │ ├── generate.ts
|
|
440
|
+
│ │ ├── validate.ts
|
|
441
|
+
│ │ ├── init.ts
|
|
442
|
+
│ │ ├── doctor.ts
|
|
443
|
+
│ │ ├── bump.ts
|
|
444
|
+
│ │ ├── clean.ts
|
|
445
|
+
│ │ └── context.ts
|
|
446
|
+
│ └── services/ # Shared logic
|
|
447
|
+
│ ├── snapshot-discovery.ts
|
|
448
|
+
│ └── name-resolver.ts
|
|
449
|
+
├── dist/ # Compiled output (git-ignored)
|
|
450
|
+
├── shared/
|
|
451
|
+
│ ├── scripts/setup.sh # One-time setup helper
|
|
452
|
+
│ └── templates/
|
|
453
|
+
│ └── CHAIM_AGENT_CONTEXT.md # Bundled AI agent context template
|
|
454
|
+
├── tsconfig.json # TypeScript configuration
|
|
455
|
+
├── .eslintrc.js # ESLint configuration
|
|
456
|
+
└── package.json
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
## Publishing to npm
|
|
460
|
+
|
|
461
|
+
Publishing is automated via GitHub Actions. The workflow triggers when you create a GitHub release.
|
|
462
|
+
|
|
463
|
+
### Steps
|
|
464
|
+
|
|
465
|
+
1. **Update the version** in `package.json`:
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
npm version patch # 0.1.5 → 0.1.6
|
|
469
|
+
npm version minor # 0.1.5 → 0.2.0
|
|
470
|
+
npm version major # 0.1.5 → 1.0.0
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
2. **Push the commit and tag**:
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
git push && git push --tags
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
3. **Create a GitHub release** from the tag. Go to the repository's **Releases** page, click **Draft a new release**, select the tag, and publish.
|
|
480
|
+
|
|
481
|
+
4. The `publish.yml` workflow runs automatically: checks out the code, runs `npm ci`, builds, and publishes to npm with `--access public`.
|
|
482
|
+
|
|
483
|
+
### Prerequisites
|
|
484
|
+
|
|
485
|
+
- The repository must have an `NPM_TOKEN` secret configured in **Settings > Secrets and variables > Actions**. This token must have publish permissions for the `@chaim-tools` scope.
|
|
486
|
+
|
|
487
|
+
### Manual Publishing (Emergency)
|
|
488
|
+
|
|
489
|
+
If the workflow fails or you need to publish from your local machine:
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
npm run build
|
|
493
|
+
npm publish --access public
|
|
494
|
+
```
|
|
205
495
|
|
|
206
|
-
|
|
207
|
-
- **Examples**: [chaim-examples](https://github.com/chaim-tools/chaim-examples)
|
|
496
|
+
You must be logged in to npm (`npm login`) with publish access to the `@chaim-tools` scope.
|
|
208
497
|
|
|
209
|
-
|
|
498
|
+
## License
|
|
210
499
|
|
|
211
|
-
|
|
500
|
+
Apache-2.0
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Increment the schemaVersion in a .bprint file.
|
|
3
|
+
*
|
|
4
|
+
* Default is a minor bump (e.g., 1.3 -> 1.4).
|
|
5
|
+
* With --major, performs a major bump (e.g., 1.3 -> 2.0).
|
|
6
|
+
*/
|
|
7
|
+
export declare function bumpCommand(schemaFile: string, options: {
|
|
8
|
+
major?: boolean;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=bump.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bump.d.ts","sourceRoot":"","sources":["../../src/commands/bump.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CA8Df"}
|