@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
|
@@ -0,0 +1,340 @@
|
|
|
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 * as fs from "node:fs";
|
|
9
|
+
import * as path from "node:path";
|
|
10
|
+
import { getFileExtension, hjsonCodec, json5Codec, jsonCodec, jsoncCodec, makeSerializerLayer, NodeStorageLayer, SerializerRegistryService, StorageAdapterService, tomlCodec, toonCodec, yamlCodec, } from "@proseql/node";
|
|
11
|
+
import { Effect, Layer } from "effect";
|
|
12
|
+
/**
|
|
13
|
+
* Map of format names to their canonical file extensions.
|
|
14
|
+
*/
|
|
15
|
+
const FORMAT_EXTENSIONS = {
|
|
16
|
+
json: "json",
|
|
17
|
+
yaml: "yaml",
|
|
18
|
+
toml: "toml",
|
|
19
|
+
json5: "json5",
|
|
20
|
+
jsonc: "jsonc",
|
|
21
|
+
hjson: "hjson",
|
|
22
|
+
toon: "toon",
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Valid format names for validation.
|
|
26
|
+
*/
|
|
27
|
+
export const VALID_FORMATS = Object.keys(FORMAT_EXTENSIONS);
|
|
28
|
+
/**
|
|
29
|
+
* Resolve relative file paths in the config to absolute paths
|
|
30
|
+
* based on the config file's directory.
|
|
31
|
+
*/
|
|
32
|
+
function resolveFilePath(filePath, configPath) {
|
|
33
|
+
if (!filePath) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
if (path.isAbsolute(filePath)) {
|
|
37
|
+
return filePath;
|
|
38
|
+
}
|
|
39
|
+
const configDir = path.dirname(configPath);
|
|
40
|
+
return path.resolve(configDir, filePath);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the persistence layer for storage and serializer operations.
|
|
44
|
+
* Includes all supported formats for maximum compatibility.
|
|
45
|
+
*/
|
|
46
|
+
function buildPersistenceLayer() {
|
|
47
|
+
return Layer.merge(NodeStorageLayer, makeSerializerLayer([
|
|
48
|
+
jsonCodec(),
|
|
49
|
+
yamlCodec(),
|
|
50
|
+
tomlCodec(),
|
|
51
|
+
json5Codec(),
|
|
52
|
+
jsoncCodec(),
|
|
53
|
+
hjsonCodec(),
|
|
54
|
+
toonCodec(),
|
|
55
|
+
]));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Compute the new file path by replacing the extension.
|
|
59
|
+
*
|
|
60
|
+
* @param oldPath - The original file path
|
|
61
|
+
* @param newFormat - The target format name
|
|
62
|
+
* @returns The new file path with the correct extension
|
|
63
|
+
*/
|
|
64
|
+
function computeNewFilePath(oldPath, newFormat) {
|
|
65
|
+
const dir = path.dirname(oldPath);
|
|
66
|
+
const ext = path.extname(oldPath);
|
|
67
|
+
const basename = path.basename(oldPath, ext);
|
|
68
|
+
const newExt = FORMAT_EXTENSIONS[newFormat];
|
|
69
|
+
return path.join(dir, `${basename}.${newExt}`);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Validate that the target format is valid.
|
|
73
|
+
*
|
|
74
|
+
* @param format - The format string to validate
|
|
75
|
+
* @returns true if valid
|
|
76
|
+
*/
|
|
77
|
+
export function isValidFormat(format) {
|
|
78
|
+
return VALID_FORMATS.includes(format);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Update the config file to reference the new file path.
|
|
82
|
+
*
|
|
83
|
+
* For JSON config files, we parse and rewrite the entire file.
|
|
84
|
+
* For TypeScript/JavaScript config files, we use text replacement
|
|
85
|
+
* to preserve formatting, imports, and other code.
|
|
86
|
+
*
|
|
87
|
+
* @param configPath - Path to the config file
|
|
88
|
+
* @param collectionName - Name of the collection to update
|
|
89
|
+
* @param oldFilePath - The old file path (relative or absolute)
|
|
90
|
+
* @param newFilePath - The new file path (relative)
|
|
91
|
+
* @returns true if the config was updated successfully
|
|
92
|
+
*/
|
|
93
|
+
function updateConfigFile(configPath, collectionName, oldFilePath, newFilePath) {
|
|
94
|
+
try {
|
|
95
|
+
const configContent = fs.readFileSync(configPath, "utf-8");
|
|
96
|
+
const ext = path.extname(configPath).toLowerCase();
|
|
97
|
+
if (ext === ".json") {
|
|
98
|
+
// For JSON configs, parse and modify
|
|
99
|
+
const config = JSON.parse(configContent);
|
|
100
|
+
if (config[collectionName] &&
|
|
101
|
+
typeof config[collectionName].file === "string") {
|
|
102
|
+
config[collectionName].file = newFilePath;
|
|
103
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
// For TypeScript/JavaScript configs, use text replacement
|
|
109
|
+
// We need to find the file property for the specific collection and update it
|
|
110
|
+
// Normalize paths for comparison - handle both relative paths starting with "./"
|
|
111
|
+
const normalizedOldPath = oldFilePath.startsWith("./")
|
|
112
|
+
? oldFilePath
|
|
113
|
+
: `./${oldFilePath}`;
|
|
114
|
+
const normalizedNewPath = newFilePath.startsWith("./")
|
|
115
|
+
? newFilePath
|
|
116
|
+
: `./${newFilePath}`;
|
|
117
|
+
// Also prepare versions without "./" prefix
|
|
118
|
+
const oldPathNoPrefix = oldFilePath.replace(/^\.\//, "");
|
|
119
|
+
const newPathNoPrefix = newFilePath.replace(/^\.\//, "");
|
|
120
|
+
// Strategy: Replace the old file path with the new one
|
|
121
|
+
// We look for patterns like:
|
|
122
|
+
// file: "./data/collection.json"
|
|
123
|
+
// file: './data/collection.json'
|
|
124
|
+
// file: "./data/collection.json",
|
|
125
|
+
// file: './data/collection.json',
|
|
126
|
+
let updatedContent = configContent;
|
|
127
|
+
let replaced = false;
|
|
128
|
+
// Try multiple patterns for different quote styles and path formats
|
|
129
|
+
const patterns = [
|
|
130
|
+
// Double quotes with ./
|
|
131
|
+
{
|
|
132
|
+
search: `file: "${normalizedOldPath}"`,
|
|
133
|
+
replace: `file: "${normalizedNewPath}"`,
|
|
134
|
+
},
|
|
135
|
+
// Single quotes with ./
|
|
136
|
+
{
|
|
137
|
+
search: `file: '${normalizedOldPath}'`,
|
|
138
|
+
replace: `file: '${normalizedNewPath}'`,
|
|
139
|
+
},
|
|
140
|
+
// Double quotes without ./
|
|
141
|
+
{
|
|
142
|
+
search: `file: "${oldPathNoPrefix}"`,
|
|
143
|
+
replace: `file: "${newPathNoPrefix}"`,
|
|
144
|
+
},
|
|
145
|
+
// Single quotes without ./
|
|
146
|
+
{
|
|
147
|
+
search: `file: '${oldPathNoPrefix}'`,
|
|
148
|
+
replace: `file: '${newPathNoPrefix}'`,
|
|
149
|
+
},
|
|
150
|
+
// With trailing comma - double quotes with ./
|
|
151
|
+
{
|
|
152
|
+
search: `file: "${normalizedOldPath}",`,
|
|
153
|
+
replace: `file: "${normalizedNewPath}",`,
|
|
154
|
+
},
|
|
155
|
+
// With trailing comma - single quotes with ./
|
|
156
|
+
{
|
|
157
|
+
search: `file: '${normalizedOldPath}',`,
|
|
158
|
+
replace: `file: '${normalizedNewPath}',`,
|
|
159
|
+
},
|
|
160
|
+
// With trailing comma - double quotes without ./
|
|
161
|
+
{
|
|
162
|
+
search: `file: "${oldPathNoPrefix}",`,
|
|
163
|
+
replace: `file: "${newPathNoPrefix}",`,
|
|
164
|
+
},
|
|
165
|
+
// With trailing comma - single quotes without ./
|
|
166
|
+
{
|
|
167
|
+
search: `file: '${oldPathNoPrefix}',`,
|
|
168
|
+
replace: `file: '${newPathNoPrefix}',`,
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
for (const { search, replace } of patterns) {
|
|
172
|
+
if (updatedContent.includes(search)) {
|
|
173
|
+
updatedContent = updatedContent.replace(search, replace);
|
|
174
|
+
replaced = true;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (replaced) {
|
|
179
|
+
fs.writeFileSync(configPath, updatedContent, "utf-8");
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
// If simple replacement didn't work, try regex for more flexible matching
|
|
183
|
+
// Pattern matches: file: "path" or file: 'path' with optional whitespace
|
|
184
|
+
const regexPatterns = [
|
|
185
|
+
// Match with ./ prefix
|
|
186
|
+
new RegExp(`(file:\\s*["'])${escapeRegex(normalizedOldPath)}(["'])`, "g"),
|
|
187
|
+
// Match without ./ prefix
|
|
188
|
+
new RegExp(`(file:\\s*["'])${escapeRegex(oldPathNoPrefix)}(["'])`, "g"),
|
|
189
|
+
];
|
|
190
|
+
for (const regex of regexPatterns) {
|
|
191
|
+
if (regex.test(configContent)) {
|
|
192
|
+
updatedContent = configContent.replace(regex, `$1${normalizedNewPath}$2`);
|
|
193
|
+
fs.writeFileSync(configPath, updatedContent, "utf-8");
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Escape special regex characters in a string.
|
|
205
|
+
*/
|
|
206
|
+
function escapeRegex(str) {
|
|
207
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Execute the convert command.
|
|
211
|
+
*
|
|
212
|
+
* Reads the collection's current data file, deserializes it,
|
|
213
|
+
* and re-serializes it in the target format.
|
|
214
|
+
*
|
|
215
|
+
* @param options - Convert command options
|
|
216
|
+
* @returns Effect that resolves to the convert result
|
|
217
|
+
*/
|
|
218
|
+
export function runConvert(options) {
|
|
219
|
+
const { collection, config, configPath, targetFormat } = options;
|
|
220
|
+
const program = Effect.gen(function* () {
|
|
221
|
+
// Look up the collection in the config
|
|
222
|
+
const collectionConfig = config[collection];
|
|
223
|
+
if (!collectionConfig) {
|
|
224
|
+
return {
|
|
225
|
+
success: false,
|
|
226
|
+
message: `Collection '${collection}' not found in config`,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
// Check if the collection has a file configured
|
|
230
|
+
const originalFilePath = collectionConfig.file;
|
|
231
|
+
if (!originalFilePath) {
|
|
232
|
+
return {
|
|
233
|
+
success: false,
|
|
234
|
+
message: `Collection '${collection}' does not have a file configured (in-memory only)`,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
// Resolve the file path to absolute
|
|
238
|
+
// Note: resolveFilePath returns undefined only when filePath is undefined,
|
|
239
|
+
// but we've already checked originalFilePath is defined above
|
|
240
|
+
const resolvedFilePath = resolveFilePath(originalFilePath, configPath);
|
|
241
|
+
if (!resolvedFilePath) {
|
|
242
|
+
return {
|
|
243
|
+
success: false,
|
|
244
|
+
message: `Could not resolve file path for collection '${collection}'`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
const absoluteFilePath = resolvedFilePath;
|
|
248
|
+
// Get the current format from the file extension
|
|
249
|
+
const currentExt = getFileExtension(absoluteFilePath);
|
|
250
|
+
if (!currentExt) {
|
|
251
|
+
return {
|
|
252
|
+
success: false,
|
|
253
|
+
message: `Could not determine current format from file '${absoluteFilePath}'`,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// Check if already in the target format
|
|
257
|
+
const targetExt = FORMAT_EXTENSIONS[targetFormat];
|
|
258
|
+
if (currentExt === targetExt) {
|
|
259
|
+
return {
|
|
260
|
+
success: false,
|
|
261
|
+
message: `Collection '${collection}' is already in ${targetFormat} format`,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
// Get storage and serializer services
|
|
265
|
+
const storage = yield* StorageAdapterService;
|
|
266
|
+
const serializer = yield* SerializerRegistryService;
|
|
267
|
+
// Check if the file exists
|
|
268
|
+
const exists = yield* storage.exists(absoluteFilePath);
|
|
269
|
+
if (!exists) {
|
|
270
|
+
return {
|
|
271
|
+
success: false,
|
|
272
|
+
message: `Data file '${absoluteFilePath}' does not exist`,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
// Read the current file
|
|
276
|
+
const rawContent = yield* storage
|
|
277
|
+
.read(absoluteFilePath)
|
|
278
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to read file: ${err}`))));
|
|
279
|
+
// Deserialize the current content
|
|
280
|
+
const data = yield* serializer
|
|
281
|
+
.deserialize(rawContent, currentExt)
|
|
282
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to parse ${currentExt} file: ${err}`))));
|
|
283
|
+
// Serialize to the new format
|
|
284
|
+
const newContent = yield* serializer
|
|
285
|
+
.serialize(data, targetExt)
|
|
286
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to serialize to ${targetFormat}: ${err}`))));
|
|
287
|
+
// Compute the new file path
|
|
288
|
+
const newFilePath = computeNewFilePath(absoluteFilePath, targetFormat);
|
|
289
|
+
// Write the new file
|
|
290
|
+
yield* storage
|
|
291
|
+
.write(newFilePath, newContent)
|
|
292
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to write new file '${newFilePath}': ${err}`))));
|
|
293
|
+
// Remove the old file (only if different from new file path)
|
|
294
|
+
if (newFilePath !== absoluteFilePath) {
|
|
295
|
+
yield* storage
|
|
296
|
+
.remove(absoluteFilePath)
|
|
297
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to remove old file '${absoluteFilePath}': ${err}`))));
|
|
298
|
+
}
|
|
299
|
+
// Compute relative paths for display and config update
|
|
300
|
+
const configDir = path.dirname(configPath);
|
|
301
|
+
const relativeOldPath = path.relative(configDir, absoluteFilePath) || absoluteFilePath;
|
|
302
|
+
const relativeNewPath = path.relative(configDir, newFilePath) || newFilePath;
|
|
303
|
+
// Update the config file to reference the new file path
|
|
304
|
+
// We use the relative path with "./" prefix to match the typical config file style
|
|
305
|
+
const configRelativeNewPath = relativeNewPath.startsWith("./")
|
|
306
|
+
? relativeNewPath
|
|
307
|
+
: `./${relativeNewPath}`;
|
|
308
|
+
const configUpdated = updateConfigFile(configPath, collection, originalFilePath, configRelativeNewPath);
|
|
309
|
+
return {
|
|
310
|
+
success: true,
|
|
311
|
+
data: {
|
|
312
|
+
collection,
|
|
313
|
+
oldFile: relativeOldPath,
|
|
314
|
+
oldFormat: currentExt,
|
|
315
|
+
newFile: relativeNewPath,
|
|
316
|
+
newFormat: targetFormat,
|
|
317
|
+
configUpdated,
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
});
|
|
321
|
+
// Run with the persistence layer
|
|
322
|
+
return program.pipe(Effect.provide(buildPersistenceLayer()), Effect.catchAll((error) => {
|
|
323
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
324
|
+
return Effect.succeed({
|
|
325
|
+
success: false,
|
|
326
|
+
message: `Failed to convert: ${message}`,
|
|
327
|
+
});
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Handle the convert command from CLI main.ts.
|
|
332
|
+
* This is the entry point called by the command dispatcher.
|
|
333
|
+
*
|
|
334
|
+
* @param options - Convert command options
|
|
335
|
+
* @returns Promise that resolves to the convert result
|
|
336
|
+
*/
|
|
337
|
+
export async function handleConvert(options) {
|
|
338
|
+
return Effect.runPromise(runConvert(options));
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/commands/convert.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProseQL CLI - Create Command
|
|
3
|
+
*
|
|
4
|
+
* Creates a new entity in a collection. Parses JSON data from --data flag,
|
|
5
|
+
* calls create on the collection, and prints the created entity.
|
|
6
|
+
*/
|
|
7
|
+
import { type DatabaseConfig } from "@proseql/node";
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
/**
|
|
10
|
+
* Options for the create command.
|
|
11
|
+
*/
|
|
12
|
+
export interface CreateOptions {
|
|
13
|
+
/** Name of the collection to create the entity in */
|
|
14
|
+
readonly collection: string;
|
|
15
|
+
/** The database configuration */
|
|
16
|
+
readonly config: DatabaseConfig;
|
|
17
|
+
/** The path to the config file (used for resolving relative file paths) */
|
|
18
|
+
readonly configPath: string;
|
|
19
|
+
/** JSON string containing the entity data */
|
|
20
|
+
readonly data: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of the create command.
|
|
24
|
+
*/
|
|
25
|
+
export interface CreateResult {
|
|
26
|
+
readonly success: boolean;
|
|
27
|
+
readonly message?: string;
|
|
28
|
+
readonly data?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Execute the create command.
|
|
32
|
+
*
|
|
33
|
+
* Boots the database from the config, parses the JSON data,
|
|
34
|
+
* and creates a new entity in the specified collection.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Create command options
|
|
37
|
+
* @returns Effect that resolves to the create result
|
|
38
|
+
*/
|
|
39
|
+
export declare function runCreate(options: CreateOptions): Effect.Effect<CreateResult, never>;
|
|
40
|
+
/**
|
|
41
|
+
* Handle the create command from CLI main.ts.
|
|
42
|
+
* This is the entry point called by the command dispatcher.
|
|
43
|
+
*
|
|
44
|
+
* @param options - Create command options
|
|
45
|
+
* @returns Promise that resolves to the create result
|
|
46
|
+
*/
|
|
47
|
+
export declare function handleCreate(options: CreateOptions): Promise<CreateResult>;
|
|
48
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEN,KAAK,cAAc,EAMnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAS,MAAM,QAAQ,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,qDAAqD;IACrD,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,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAuDD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,aAAa,GACpB,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAwFpC;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,aAAa,GACpB,OAAO,CAAC,YAAY,CAAC,CAEvB"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProseQL CLI - Create Command
|
|
3
|
+
*
|
|
4
|
+
* Creates a new entity in a collection. Parses JSON data from --data flag,
|
|
5
|
+
* calls create on the collection, and prints the created entity.
|
|
6
|
+
*/
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import { createPersistentEffectDatabase, jsonCodec, makeSerializerLayer, NodeStorageLayer, tomlCodec, yamlCodec, } from "@proseql/node";
|
|
9
|
+
import { Effect, Layer } 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
|
+
* Parse JSON data string into an object.
|
|
32
|
+
* Returns an error message if parsing fails.
|
|
33
|
+
*/
|
|
34
|
+
function parseJsonData(data) {
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(data);
|
|
37
|
+
if (typeof parsed !== "object" ||
|
|
38
|
+
parsed === null ||
|
|
39
|
+
Array.isArray(parsed)) {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: "Data must be a JSON object, not an array or primitive",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return { success: true, parsed: parsed };
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
49
|
+
return { success: false, error: `Invalid JSON: ${message}` };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Execute the create command.
|
|
54
|
+
*
|
|
55
|
+
* Boots the database from the config, parses the JSON data,
|
|
56
|
+
* and creates a new entity in the specified collection.
|
|
57
|
+
*
|
|
58
|
+
* @param options - Create command options
|
|
59
|
+
* @returns Effect that resolves to the create result
|
|
60
|
+
*/
|
|
61
|
+
export function runCreate(options) {
|
|
62
|
+
return Effect.gen(function* () {
|
|
63
|
+
const { collection, config, configPath, data } = options;
|
|
64
|
+
// Check if collection exists in config
|
|
65
|
+
if (!(collection in config)) {
|
|
66
|
+
const availableCollections = Object.keys(config).join(", ");
|
|
67
|
+
return {
|
|
68
|
+
success: false,
|
|
69
|
+
message: `Collection '${collection}' not found in config. Available collections: ${availableCollections || "(none)"}`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Parse the JSON data
|
|
73
|
+
const parseResult = parseJsonData(data);
|
|
74
|
+
if (!parseResult.success) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
message: parseResult.error,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const entityData = parseResult.parsed;
|
|
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 execute the create
|
|
86
|
+
const program = Effect.gen(function* () {
|
|
87
|
+
const db = yield* createPersistentEffectDatabase(resolvedConfig, {});
|
|
88
|
+
// Get the collection (type assertion needed since we check collection existence above)
|
|
89
|
+
const coll = db[collection];
|
|
90
|
+
// Execute the create operation
|
|
91
|
+
const created = yield* coll.create(entityData);
|
|
92
|
+
return created;
|
|
93
|
+
});
|
|
94
|
+
// Run the program with the persistence layer
|
|
95
|
+
const result = yield* program.pipe(Effect.provide(PersistenceLayer), Effect.scoped, Effect.catchAll((error) => {
|
|
96
|
+
// Extract error message based on error type
|
|
97
|
+
let message;
|
|
98
|
+
if (error && typeof error === "object") {
|
|
99
|
+
const errorObj = error;
|
|
100
|
+
if ("_tag" in errorObj && typeof errorObj.message === "string") {
|
|
101
|
+
// Tagged error with message field
|
|
102
|
+
message = errorObj.message;
|
|
103
|
+
}
|
|
104
|
+
else if (error instanceof Error) {
|
|
105
|
+
message = error.message;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
message = String(error);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
message = String(error);
|
|
113
|
+
}
|
|
114
|
+
return Effect.succeed({
|
|
115
|
+
success: false,
|
|
116
|
+
message: `Create failed: ${message}`,
|
|
117
|
+
});
|
|
118
|
+
}));
|
|
119
|
+
// Check if we got an error result
|
|
120
|
+
if ("success" in result && result.success === false) {
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
// We got the created entity
|
|
124
|
+
const entity = result;
|
|
125
|
+
return {
|
|
126
|
+
success: true,
|
|
127
|
+
data: entity,
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Handle the create command from CLI main.ts.
|
|
133
|
+
* This is the entry point called by the command dispatcher.
|
|
134
|
+
*
|
|
135
|
+
* @param options - Create command options
|
|
136
|
+
* @returns Promise that resolves to the create result
|
|
137
|
+
*/
|
|
138
|
+
export async function handleCreate(options) {
|
|
139
|
+
return Effect.runPromise(runCreate(options));
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProseQL CLI - Delete Command
|
|
3
|
+
*
|
|
4
|
+
* Deletes an entity from a collection. Prompts for confirmation (unless --force),
|
|
5
|
+
* calls delete on the collection, and prints a confirmation message.
|
|
6
|
+
*/
|
|
7
|
+
import { type DatabaseConfig } from "@proseql/node";
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
/**
|
|
10
|
+
* Options for the delete command.
|
|
11
|
+
*/
|
|
12
|
+
export interface DeleteOptions {
|
|
13
|
+
/** Name of the collection containing the entity */
|
|
14
|
+
readonly collection: string;
|
|
15
|
+
/** ID of the entity to delete */
|
|
16
|
+
readonly id: string;
|
|
17
|
+
/** The database configuration */
|
|
18
|
+
readonly config: DatabaseConfig;
|
|
19
|
+
/** The path to the config file (used for resolving relative file paths) */
|
|
20
|
+
readonly configPath: string;
|
|
21
|
+
/** Skip confirmation prompt if true */
|
|
22
|
+
readonly force?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Result of the delete command.
|
|
26
|
+
*/
|
|
27
|
+
export interface DeleteResult {
|
|
28
|
+
readonly success: boolean;
|
|
29
|
+
readonly message?: string;
|
|
30
|
+
/** Whether the operation was aborted by the user */
|
|
31
|
+
readonly aborted?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Execute the delete command.
|
|
35
|
+
*
|
|
36
|
+
* Boots the database from the config, prompts for confirmation (unless --force),
|
|
37
|
+
* and deletes the entity from the specified collection.
|
|
38
|
+
*
|
|
39
|
+
* @param options - Delete command options
|
|
40
|
+
* @returns Effect that resolves to the delete result
|
|
41
|
+
*/
|
|
42
|
+
export declare function runDelete(options: DeleteOptions): Effect.Effect<DeleteResult, never>;
|
|
43
|
+
/**
|
|
44
|
+
* Handle the delete command from CLI main.ts.
|
|
45
|
+
* This is the entry point called by the command dispatcher.
|
|
46
|
+
*
|
|
47
|
+
* @param options - Delete command options
|
|
48
|
+
* @returns Promise that resolves to the delete result
|
|
49
|
+
*/
|
|
50
|
+
export declare function handleDelete(options: DeleteOptions): Promise<DeleteResult>;
|
|
51
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEN,KAAK,cAAc,EAMnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAS,MAAM,QAAQ,CAAC;AAGvC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC3B;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,aAAa,GACpB,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CA2FpC;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,aAAa,GACpB,OAAO,CAAC,YAAY,CAAC,CAEvB"}
|