@proseql/cli 0.2.4
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/LICENSE +21 -0
- package/README.md +333 -0
- package/dist/commands/collections.d.ts +53 -0
- package/dist/commands/collections.d.ts.map +1 -0
- package/dist/commands/collections.js +145 -0
- package/dist/commands/collections.js.map +1 -0
- package/dist/commands/convert.d.ts +72 -0
- package/dist/commands/convert.d.ts.map +1 -0
- package/dist/commands/convert.js +340 -0
- package/dist/commands/convert.js.map +1 -0
- package/dist/commands/create.d.ts +48 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +141 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/delete.d.ts +51 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +122 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/describe.d.ts +74 -0
- package/dist/commands/describe.d.ts.map +1 -0
- package/dist/commands/describe.js +206 -0
- package/dist/commands/describe.js.map +1 -0
- package/dist/commands/init.d.ts +37 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +340 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/migrate.d.ts +65 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +483 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/query.d.ts +56 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +159 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/stats.d.ts +55 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +188 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/update.d.ts +50 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +121 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/config/discovery.d.ts +37 -0
- package/dist/config/discovery.d.ts.map +1 -0
- package/dist/config/discovery.js +171 -0
- package/dist/config/discovery.js.map +1 -0
- package/dist/config/loader.d.ts +49 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +195 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +66 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +621 -0
- package/dist/main.js.map +1 -0
- package/dist/output/csv.d.ts +14 -0
- package/dist/output/csv.d.ts.map +1 -0
- package/dist/output/csv.js +54 -0
- package/dist/output/csv.js.map +1 -0
- package/dist/output/formatter.d.ts +18 -0
- package/dist/output/formatter.d.ts.map +1 -0
- package/dist/output/formatter.js +29 -0
- package/dist/output/formatter.js.map +1 -0
- package/dist/output/json.d.ts +13 -0
- package/dist/output/json.d.ts.map +1 -0
- package/dist/output/json.js +15 -0
- package/dist/output/json.js.map +1 -0
- package/dist/output/table.d.ts +18 -0
- package/dist/output/table.d.ts.map +1 -0
- package/dist/output/table.js +115 -0
- package/dist/output/table.js.map +1 -0
- package/dist/output/yaml.d.ts +13 -0
- package/dist/output/yaml.d.ts.map +1 -0
- package/dist/output/yaml.js +16 -0
- package/dist/output/yaml.js.map +1 -0
- package/dist/parsers/filter-parser.d.ts +65 -0
- package/dist/parsers/filter-parser.d.ts.map +1 -0
- package/dist/parsers/filter-parser.js +198 -0
- package/dist/parsers/filter-parser.js.map +1 -0
- package/dist/parsers/set-parser.d.ts +55 -0
- package/dist/parsers/set-parser.d.ts.map +1 -0
- package/dist/parsers/set-parser.js +198 -0
- package/dist/parsers/set-parser.js.map +1 -0
- package/dist/prompt.d.ts +58 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +121 -0
- package/dist/prompt.js.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Simon W. Jackson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# @proseql/cli
|
|
2
|
+
|
|
3
|
+
Command-line interface for ProseQL databases. Query, create, update, and manage your plain text database files from the terminal.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
# Run directly with npx
|
|
9
|
+
npx @proseql/cli --help
|
|
10
|
+
|
|
11
|
+
# Or install globally
|
|
12
|
+
npm install -g @proseql/cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
# Initialize a new project
|
|
19
|
+
proseql init
|
|
20
|
+
|
|
21
|
+
# Query a collection
|
|
22
|
+
proseql query books --where 'year > 1970' --limit 10
|
|
23
|
+
|
|
24
|
+
# Create an entity
|
|
25
|
+
proseql create books --data '{"title":"Dune","author":"Frank Herbert","year":1965}'
|
|
26
|
+
|
|
27
|
+
# Update an entity
|
|
28
|
+
proseql update books abc123 --set 'year=2025,title=New Title'
|
|
29
|
+
|
|
30
|
+
# Delete an entity
|
|
31
|
+
proseql delete books abc123 --force
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
### `init`
|
|
37
|
+
|
|
38
|
+
Scaffold a new ProseQL project with config and data files.
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
proseql init
|
|
42
|
+
proseql init --format yaml
|
|
43
|
+
proseql init --format toml
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Creates:
|
|
47
|
+
- `proseql.config.ts` with an example `notes` collection
|
|
48
|
+
- `data/notes.{json,yaml,toml}` with sample data
|
|
49
|
+
- Updates `.gitignore` to exclude the data directory (if in a git repo)
|
|
50
|
+
|
|
51
|
+
| Option | Description |
|
|
52
|
+
|--------|-------------|
|
|
53
|
+
| `--format <fmt>` | Data file format: `json` (default), `yaml`, `toml` |
|
|
54
|
+
|
|
55
|
+
### `query`
|
|
56
|
+
|
|
57
|
+
Query a collection with filters, sorting, and pagination.
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
proseql query <collection> [options]
|
|
61
|
+
|
|
62
|
+
# Examples
|
|
63
|
+
proseql query books
|
|
64
|
+
proseql query books --where 'year > 1970'
|
|
65
|
+
proseql query books --where 'genre = sci-fi' --where 'year < 2000'
|
|
66
|
+
proseql query books --select 'title,author' --sort 'year:desc' --limit 5
|
|
67
|
+
proseql query books --json | jq '.[] | .title'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Option | Description |
|
|
71
|
+
|--------|-------------|
|
|
72
|
+
| `-w, --where <expr>` | Filter expression (can be repeated) |
|
|
73
|
+
| `-s, --select <fields>` | Comma-separated fields to include |
|
|
74
|
+
| `--sort <field:dir>` | Sort by field (`asc` or `desc`) |
|
|
75
|
+
| `-l, --limit <n>` | Limit number of results |
|
|
76
|
+
|
|
77
|
+
Filter expressions use the format `field operator value`:
|
|
78
|
+
- `year > 1970`
|
|
79
|
+
- `genre = sci-fi`
|
|
80
|
+
- `title != "Old Title"`
|
|
81
|
+
- `rating >= 4.5`
|
|
82
|
+
|
|
83
|
+
### `create`
|
|
84
|
+
|
|
85
|
+
Create a new entity in a collection.
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
proseql create <collection> --data '<json>'
|
|
89
|
+
|
|
90
|
+
# Examples
|
|
91
|
+
proseql create books --data '{"title":"Neuromancer","author":"William Gibson","year":1984}'
|
|
92
|
+
proseql create notes --data '{"title":"Meeting notes","content":"..."}'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
| Option | Description |
|
|
96
|
+
|--------|-------------|
|
|
97
|
+
| `-d, --data <json>` | JSON object containing the entity data (required) |
|
|
98
|
+
|
|
99
|
+
The created entity is printed to stdout. An ID is auto-generated if not provided.
|
|
100
|
+
|
|
101
|
+
### `update`
|
|
102
|
+
|
|
103
|
+
Update an existing entity by ID.
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
proseql update <collection> <id> --set '<assignments>'
|
|
107
|
+
|
|
108
|
+
# Examples
|
|
109
|
+
proseql update books abc123 --set 'year=2025'
|
|
110
|
+
proseql update books abc123 --set 'year=2025,title=Updated Title'
|
|
111
|
+
proseql update notes xyz --set 'content=New content here'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
| Option | Description |
|
|
115
|
+
|--------|-------------|
|
|
116
|
+
| `--set <assignments>` | Comma-separated field assignments (required) |
|
|
117
|
+
|
|
118
|
+
Values are automatically coerced: numbers become numbers, `true`/`false` become booleans.
|
|
119
|
+
|
|
120
|
+
### `delete`
|
|
121
|
+
|
|
122
|
+
Delete an entity by ID.
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
proseql delete <collection> <id> [options]
|
|
126
|
+
|
|
127
|
+
# Examples
|
|
128
|
+
proseql delete books abc123
|
|
129
|
+
proseql delete books abc123 --force
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
| Option | Description |
|
|
133
|
+
|--------|-------------|
|
|
134
|
+
| `-f, --force` | Skip confirmation prompt |
|
|
135
|
+
|
|
136
|
+
Without `--force`, you'll be prompted to confirm the deletion.
|
|
137
|
+
|
|
138
|
+
### `collections`
|
|
139
|
+
|
|
140
|
+
List all collections with entity counts and file paths.
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
proseql collections
|
|
144
|
+
|
|
145
|
+
# Output:
|
|
146
|
+
# name count file format
|
|
147
|
+
# books 42 data/books.yaml yaml
|
|
148
|
+
# authors 12 data/authors.json json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `describe`
|
|
152
|
+
|
|
153
|
+
Show schema details for a collection.
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
proseql describe <collection>
|
|
157
|
+
|
|
158
|
+
# Examples
|
|
159
|
+
proseql describe books
|
|
160
|
+
proseql describe books --json
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Displays:
|
|
164
|
+
- Field names, types, and required/optional status
|
|
165
|
+
- Indexed fields
|
|
166
|
+
- Unique constraints
|
|
167
|
+
- Relationships
|
|
168
|
+
- Search index configuration
|
|
169
|
+
- Schema version (if versioned)
|
|
170
|
+
- Append-only mode (if enabled)
|
|
171
|
+
|
|
172
|
+
### `stats`
|
|
173
|
+
|
|
174
|
+
Show statistics for all collections.
|
|
175
|
+
|
|
176
|
+
```sh
|
|
177
|
+
proseql stats
|
|
178
|
+
|
|
179
|
+
# Output:
|
|
180
|
+
# name count file format size
|
|
181
|
+
# books 42 data/books.yaml yaml 12.5 KB
|
|
182
|
+
# authors 12 data/authors.json json 2.1 KB
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Includes entity counts, file paths, formats, and file sizes on disk.
|
|
186
|
+
|
|
187
|
+
### `migrate`
|
|
188
|
+
|
|
189
|
+
Run schema migrations.
|
|
190
|
+
|
|
191
|
+
```sh
|
|
192
|
+
# Show migration status
|
|
193
|
+
proseql migrate status
|
|
194
|
+
|
|
195
|
+
# Preview what would run (dry run)
|
|
196
|
+
proseql migrate --dry-run
|
|
197
|
+
|
|
198
|
+
# Execute pending migrations
|
|
199
|
+
proseql migrate
|
|
200
|
+
proseql migrate --force # skip confirmation
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
| Option | Description |
|
|
204
|
+
|--------|-------------|
|
|
205
|
+
| `--dry-run` | Show what would be done without executing |
|
|
206
|
+
| `-f, --force` | Skip confirmation prompt |
|
|
207
|
+
|
|
208
|
+
Migration status shows:
|
|
209
|
+
- Current file version vs target version
|
|
210
|
+
- Collections that need migration
|
|
211
|
+
- Number of migrations to apply
|
|
212
|
+
|
|
213
|
+
### `convert`
|
|
214
|
+
|
|
215
|
+
Convert a collection's data file to a different format.
|
|
216
|
+
|
|
217
|
+
```sh
|
|
218
|
+
proseql convert <collection> --to <format>
|
|
219
|
+
|
|
220
|
+
# Examples
|
|
221
|
+
proseql convert books --to yaml
|
|
222
|
+
proseql convert notes --to json
|
|
223
|
+
proseql convert config --to toml
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
| Option | Description |
|
|
227
|
+
|--------|-------------|
|
|
228
|
+
| `--to <format>` | Target format (required) |
|
|
229
|
+
|
|
230
|
+
Supported formats: `json`, `yaml`, `toml`, `json5`, `jsonc`, `hjson`, `toon`
|
|
231
|
+
|
|
232
|
+
The command:
|
|
233
|
+
1. Reads the current data file
|
|
234
|
+
2. Re-serializes in the target format
|
|
235
|
+
3. Writes the new file with the correct extension
|
|
236
|
+
4. Removes the old file
|
|
237
|
+
5. Updates the config file to reference the new path
|
|
238
|
+
|
|
239
|
+
## Global Options
|
|
240
|
+
|
|
241
|
+
| Option | Description |
|
|
242
|
+
|--------|-------------|
|
|
243
|
+
| `-h, --help` | Show help message |
|
|
244
|
+
| `-v, --version` | Show version |
|
|
245
|
+
| `-c, --config <path>` | Path to config file (default: auto-discover) |
|
|
246
|
+
| `--json` | Output as JSON |
|
|
247
|
+
| `--yaml` | Output as YAML |
|
|
248
|
+
| `--csv` | Output as CSV |
|
|
249
|
+
|
|
250
|
+
## Output Formats
|
|
251
|
+
|
|
252
|
+
All commands that return data support multiple output formats:
|
|
253
|
+
|
|
254
|
+
```sh
|
|
255
|
+
# Default: table format (human-readable)
|
|
256
|
+
proseql query books
|
|
257
|
+
|
|
258
|
+
# JSON (pipe to jq, etc.)
|
|
259
|
+
proseql query books --json
|
|
260
|
+
|
|
261
|
+
# YAML
|
|
262
|
+
proseql query books --yaml
|
|
263
|
+
|
|
264
|
+
# CSV (for spreadsheets)
|
|
265
|
+
proseql query books --csv
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Table is the default. JSON is useful for scripting and piping to other tools.
|
|
269
|
+
|
|
270
|
+
## Config Discovery
|
|
271
|
+
|
|
272
|
+
The CLI automatically discovers your config file by searching upward from the current directory:
|
|
273
|
+
|
|
274
|
+
1. `proseql.config.ts`
|
|
275
|
+
2. `proseql.config.js`
|
|
276
|
+
3. `proseql.config.json`
|
|
277
|
+
|
|
278
|
+
The first file found is used. Override with `--config`:
|
|
279
|
+
|
|
280
|
+
```sh
|
|
281
|
+
proseql query books --config ./path/to/proseql.config.ts
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Examples
|
|
285
|
+
|
|
286
|
+
### Querying with filters and piping to jq
|
|
287
|
+
|
|
288
|
+
```sh
|
|
289
|
+
# Get all sci-fi books as JSON
|
|
290
|
+
proseql query books --where 'genre = sci-fi' --json
|
|
291
|
+
|
|
292
|
+
# Pipe to jq for further processing
|
|
293
|
+
proseql query books --json | jq '.[] | {title, year}'
|
|
294
|
+
|
|
295
|
+
# Count results
|
|
296
|
+
proseql query books --where 'year > 2000' --json | jq length
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Batch operations with shell scripts
|
|
300
|
+
|
|
301
|
+
```sh
|
|
302
|
+
# Export all collections to JSON
|
|
303
|
+
for collection in $(proseql collections --json | jq -r '.[].name'); do
|
|
304
|
+
proseql query "$collection" --json > "export-$collection.json"
|
|
305
|
+
done
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Migration workflow
|
|
309
|
+
|
|
310
|
+
```sh
|
|
311
|
+
# Check what needs migrating
|
|
312
|
+
proseql migrate status
|
|
313
|
+
|
|
314
|
+
# Preview the changes
|
|
315
|
+
proseql migrate --dry-run
|
|
316
|
+
|
|
317
|
+
# Apply migrations
|
|
318
|
+
proseql migrate --force
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Format conversion
|
|
322
|
+
|
|
323
|
+
```sh
|
|
324
|
+
# Convert from JSON to YAML for better readability
|
|
325
|
+
proseql convert books --to yaml
|
|
326
|
+
|
|
327
|
+
# Convert to TOML for config-like data
|
|
328
|
+
proseql convert settings --to toml
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## License
|
|
332
|
+
|
|
333
|
+
MIT
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProseQL CLI - Collections Command
|
|
3
|
+
*
|
|
4
|
+
* Boots the database from config, lists all collection names with entity count,
|
|
5
|
+
* file path, and serialization format.
|
|
6
|
+
*/
|
|
7
|
+
import { type DatabaseConfig } from "@proseql/node";
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
/**
|
|
10
|
+
* Options for the collections command.
|
|
11
|
+
*/
|
|
12
|
+
export interface CollectionsOptions {
|
|
13
|
+
/** The database configuration */
|
|
14
|
+
readonly config: DatabaseConfig;
|
|
15
|
+
/** The path to the config file (used for resolving relative file paths) */
|
|
16
|
+
readonly configPath: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Information about a single collection.
|
|
20
|
+
*/
|
|
21
|
+
export interface CollectionInfo {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly count: number;
|
|
24
|
+
readonly file: string;
|
|
25
|
+
readonly format: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of the collections command.
|
|
29
|
+
*/
|
|
30
|
+
export interface CollectionsResult {
|
|
31
|
+
readonly success: boolean;
|
|
32
|
+
readonly message?: string;
|
|
33
|
+
readonly data?: ReadonlyArray<CollectionInfo>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Execute the collections command.
|
|
37
|
+
*
|
|
38
|
+
* Boots the database from the config, and lists all collections with
|
|
39
|
+
* their entity counts, file paths, and serialization formats.
|
|
40
|
+
*
|
|
41
|
+
* @param options - Collections command options
|
|
42
|
+
* @returns Result with collection information or error message
|
|
43
|
+
*/
|
|
44
|
+
export declare function runCollections(options: CollectionsOptions): Effect.Effect<CollectionsResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Handle the collections command from CLI main.ts.
|
|
47
|
+
* This is the entry point called by the command dispatcher.
|
|
48
|
+
*
|
|
49
|
+
* @param options - Collections command options
|
|
50
|
+
* @returns Promise that resolves to the collections info or rejects on error
|
|
51
|
+
*/
|
|
52
|
+
export declare function handleCollections(options: CollectionsOptions): Promise<CollectionsResult>;
|
|
53
|
+
//# sourceMappingURL=collections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../src/commands/collections.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEN,KAAK,cAAc,EAMnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAS,MAAM,EAAiB,MAAM,QAAQ,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;CAC9C;AA4DD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,kBAAkB,GACzB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CA0FlC;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,kBAAkB,GACzB,OAAO,CAAC,iBAAiB,CAAC,CAG5B"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProseQL CLI - Collections Command
|
|
3
|
+
*
|
|
4
|
+
* Boots the database from config, lists all collection names with entity count,
|
|
5
|
+
* file path, and serialization format.
|
|
6
|
+
*/
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import { createPersistentEffectDatabase, jsonCodec, makeSerializerLayer, NodeStorageLayer, tomlCodec, yamlCodec, } from "@proseql/node";
|
|
9
|
+
import { Chunk, Effect, Layer, Stream } from "effect";
|
|
10
|
+
/**
|
|
11
|
+
* Resolve relative file paths in the config to absolute paths
|
|
12
|
+
* based on the config file's directory.
|
|
13
|
+
*/
|
|
14
|
+
function resolveConfigPaths(config, configPath) {
|
|
15
|
+
const configDir = path.dirname(configPath);
|
|
16
|
+
const resolved = {};
|
|
17
|
+
for (const [collectionName, collectionConfig] of Object.entries(config)) {
|
|
18
|
+
if (collectionConfig.file && !path.isAbsolute(collectionConfig.file)) {
|
|
19
|
+
resolved[collectionName] = {
|
|
20
|
+
...collectionConfig,
|
|
21
|
+
file: path.resolve(configDir, collectionConfig.file),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
resolved[collectionName] = collectionConfig;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return resolved;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Determine the serialization format from a file path.
|
|
32
|
+
* Returns the format based on the file extension.
|
|
33
|
+
*/
|
|
34
|
+
function getFormatFromFile(filePath) {
|
|
35
|
+
if (!filePath) {
|
|
36
|
+
return "(in-memory)";
|
|
37
|
+
}
|
|
38
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
39
|
+
switch (ext) {
|
|
40
|
+
case ".json":
|
|
41
|
+
return "json";
|
|
42
|
+
case ".jsonl":
|
|
43
|
+
return "jsonl";
|
|
44
|
+
case ".yaml":
|
|
45
|
+
case ".yml":
|
|
46
|
+
return "yaml";
|
|
47
|
+
case ".toml":
|
|
48
|
+
return "toml";
|
|
49
|
+
case ".json5":
|
|
50
|
+
return "json5";
|
|
51
|
+
case ".jsonc":
|
|
52
|
+
return "jsonc";
|
|
53
|
+
case ".hjson":
|
|
54
|
+
return "hjson";
|
|
55
|
+
case ".toon":
|
|
56
|
+
return "toon";
|
|
57
|
+
default:
|
|
58
|
+
return ext ? ext.slice(1) : "unknown";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Execute the collections command.
|
|
63
|
+
*
|
|
64
|
+
* Boots the database from the config, and lists all collections with
|
|
65
|
+
* their entity counts, file paths, and serialization formats.
|
|
66
|
+
*
|
|
67
|
+
* @param options - Collections command options
|
|
68
|
+
* @returns Result with collection information or error message
|
|
69
|
+
*/
|
|
70
|
+
export function runCollections(options) {
|
|
71
|
+
return Effect.gen(function* () {
|
|
72
|
+
const { config, configPath } = options;
|
|
73
|
+
const collectionNames = Object.keys(config);
|
|
74
|
+
if (collectionNames.length === 0) {
|
|
75
|
+
return {
|
|
76
|
+
success: true,
|
|
77
|
+
data: [],
|
|
78
|
+
message: "No collections configured",
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// Resolve relative file paths in the config
|
|
82
|
+
const resolvedConfig = resolveConfigPaths(config, configPath);
|
|
83
|
+
// Build the persistence layer for database operations
|
|
84
|
+
const PersistenceLayer = Layer.merge(NodeStorageLayer, makeSerializerLayer([jsonCodec(), yamlCodec(), tomlCodec()]));
|
|
85
|
+
// Boot the database and gather collection info
|
|
86
|
+
const program = Effect.gen(function* () {
|
|
87
|
+
const db = yield* createPersistentEffectDatabase(resolvedConfig, {});
|
|
88
|
+
const results = [];
|
|
89
|
+
for (const name of collectionNames) {
|
|
90
|
+
const collectionConfig = resolvedConfig[name];
|
|
91
|
+
const filePath = collectionConfig?.file;
|
|
92
|
+
// Get the collection (type assertion needed since we verify existence via config)
|
|
93
|
+
const coll = db[name];
|
|
94
|
+
// Count entities by querying all and collecting
|
|
95
|
+
const stream = coll.query();
|
|
96
|
+
const chunk = yield* Stream.runCollect(stream);
|
|
97
|
+
const count = Chunk.size(chunk);
|
|
98
|
+
// Get format from file extension
|
|
99
|
+
const format = getFormatFromFile(filePath);
|
|
100
|
+
// Get relative file path for display (relative to config dir)
|
|
101
|
+
const configDir = path.dirname(configPath);
|
|
102
|
+
const displayPath = filePath
|
|
103
|
+
? path.relative(configDir, filePath) || filePath
|
|
104
|
+
: "(in-memory)";
|
|
105
|
+
results.push({
|
|
106
|
+
name,
|
|
107
|
+
count,
|
|
108
|
+
file: displayPath,
|
|
109
|
+
format,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return results;
|
|
113
|
+
});
|
|
114
|
+
// Run the program with the persistence layer
|
|
115
|
+
const result = yield* program.pipe(Effect.provide(PersistenceLayer), Effect.scoped, Effect.catchAll((error) => {
|
|
116
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
117
|
+
return Effect.succeed({
|
|
118
|
+
success: false,
|
|
119
|
+
message: `Failed to list collections: ${message}`,
|
|
120
|
+
});
|
|
121
|
+
}));
|
|
122
|
+
// Check if we got an error result
|
|
123
|
+
if ("success" in result && result.success === false) {
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
// We got data
|
|
127
|
+
const data = result;
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
data,
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Handle the collections command from CLI main.ts.
|
|
136
|
+
* This is the entry point called by the command dispatcher.
|
|
137
|
+
*
|
|
138
|
+
* @param options - Collections command options
|
|
139
|
+
* @returns Promise that resolves to the collections info or rejects on error
|
|
140
|
+
*/
|
|
141
|
+
export async function handleCollections(options) {
|
|
142
|
+
const result = await Effect.runPromise(runCollections(options));
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=collections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collections.js","sourceRoot":"","sources":["../../src/commands/collections.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProseQL CLI - Convert Command
|
|
3
|
+
*
|
|
4
|
+
* Converts a collection's data file from one format to another.
|
|
5
|
+
* Reads the current data file, serializes in the target format,
|
|
6
|
+
* and writes the new file with the correct extension.
|
|
7
|
+
*/
|
|
8
|
+
import { type DatabaseConfig } from "@proseql/node";
|
|
9
|
+
import { Effect } from "effect";
|
|
10
|
+
/**
|
|
11
|
+
* Supported target formats for conversion.
|
|
12
|
+
*/
|
|
13
|
+
export type TargetFormat = "json" | "yaml" | "toml" | "json5" | "jsonc" | "hjson" | "toon";
|
|
14
|
+
/**
|
|
15
|
+
* Valid format names for validation.
|
|
16
|
+
*/
|
|
17
|
+
export declare const VALID_FORMATS: readonly TargetFormat[];
|
|
18
|
+
/**
|
|
19
|
+
* Options for the convert command.
|
|
20
|
+
*/
|
|
21
|
+
export interface ConvertOptions {
|
|
22
|
+
/** The collection to convert */
|
|
23
|
+
readonly collection: string;
|
|
24
|
+
/** The database configuration */
|
|
25
|
+
readonly config: DatabaseConfig;
|
|
26
|
+
/** The path to the config file (used for resolving relative file paths) */
|
|
27
|
+
readonly configPath: string;
|
|
28
|
+
/** The target format to convert to */
|
|
29
|
+
readonly targetFormat: TargetFormat;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Result of the convert command.
|
|
33
|
+
*/
|
|
34
|
+
export interface ConvertResult {
|
|
35
|
+
readonly success: boolean;
|
|
36
|
+
readonly message?: string;
|
|
37
|
+
/** Details about the conversion */
|
|
38
|
+
readonly data?: {
|
|
39
|
+
readonly collection: string;
|
|
40
|
+
readonly oldFile: string;
|
|
41
|
+
readonly oldFormat: string;
|
|
42
|
+
readonly newFile: string;
|
|
43
|
+
readonly newFormat: string;
|
|
44
|
+
readonly configUpdated: boolean;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Validate that the target format is valid.
|
|
49
|
+
*
|
|
50
|
+
* @param format - The format string to validate
|
|
51
|
+
* @returns true if valid
|
|
52
|
+
*/
|
|
53
|
+
export declare function isValidFormat(format: string): format is TargetFormat;
|
|
54
|
+
/**
|
|
55
|
+
* Execute the convert command.
|
|
56
|
+
*
|
|
57
|
+
* Reads the collection's current data file, deserializes it,
|
|
58
|
+
* and re-serializes it in the target format.
|
|
59
|
+
*
|
|
60
|
+
* @param options - Convert command options
|
|
61
|
+
* @returns Effect that resolves to the convert result
|
|
62
|
+
*/
|
|
63
|
+
export declare function runConvert(options: ConvertOptions): Effect.Effect<ConvertResult, never>;
|
|
64
|
+
/**
|
|
65
|
+
* Handle the convert command from CLI main.ts.
|
|
66
|
+
* This is the entry point called by the command dispatcher.
|
|
67
|
+
*
|
|
68
|
+
* @param options - Convert command options
|
|
69
|
+
* @returns Promise that resolves to the convert result
|
|
70
|
+
*/
|
|
71
|
+
export declare function handleConvert(options: ConvertOptions): Promise<ConvertResult>;
|
|
72
|
+
//# sourceMappingURL=convert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/commands/convert.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EACN,KAAK,cAAc,EAanB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAS,MAAM,QAAQ,CAAC;AAEvC;;GAEG;AACH,MAAM,MAAM,YAAY,GACrB,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,GACP,OAAO,GACP,MAAM,CAAC;AAeV;;GAEG;AACH,eAAO,MAAM,aAAa,EAErB,SAAS,YAAY,EAAE,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,gCAAgC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sCAAsC;IACtC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE;QACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;KAChC,CAAC;CACF;AAsDD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,YAAY,CAEpE;AAiKD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACzB,OAAO,EAAE,cAAc,GACrB,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAsKrC;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAClC,OAAO,EAAE,cAAc,GACrB,OAAO,CAAC,aAAa,CAAC,CAExB"}
|