@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,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProseQL CLI - Migrate Command
|
|
3
|
+
*
|
|
4
|
+
* Manages schema migrations: shows status, performs dry runs, and executes migrations.
|
|
5
|
+
* Supports subcommands: `migrate status`, `migrate --dry-run`, `migrate` (run).
|
|
6
|
+
*/
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import { getFileExtension, jsonCodec, makeSerializerLayer, NodeStorageLayer, SerializerRegistryService, StorageAdapterService, tomlCodec, yamlCodec, } from "@proseql/node";
|
|
9
|
+
import { Effect, Layer } from "effect";
|
|
10
|
+
import { confirm } from "../prompt.js";
|
|
11
|
+
/**
|
|
12
|
+
* Detect which subcommand is being requested based on positional args and flags.
|
|
13
|
+
*
|
|
14
|
+
* @param positionalArgs - Positional arguments after "migrate"
|
|
15
|
+
* @param dryRun - Whether --dry-run flag was passed
|
|
16
|
+
* @returns The detected subcommand
|
|
17
|
+
*/
|
|
18
|
+
export function detectSubcommand(positionalArgs, dryRun) {
|
|
19
|
+
// Check for "status" subcommand
|
|
20
|
+
if (positionalArgs.length > 0 && positionalArgs[0] === "status") {
|
|
21
|
+
return "status";
|
|
22
|
+
}
|
|
23
|
+
// Check for --dry-run flag
|
|
24
|
+
if (dryRun) {
|
|
25
|
+
return "dry-run";
|
|
26
|
+
}
|
|
27
|
+
// Default to "run" - actually execute migrations
|
|
28
|
+
return "run";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolve relative file paths in the config to absolute paths
|
|
32
|
+
* based on the config file's directory.
|
|
33
|
+
*/
|
|
34
|
+
function resolveConfigPaths(config, configPath) {
|
|
35
|
+
const configDir = path.dirname(configPath);
|
|
36
|
+
const resolved = {};
|
|
37
|
+
for (const [collectionName, collectionConfig] of Object.entries(config)) {
|
|
38
|
+
if (collectionConfig.file && !path.isAbsolute(collectionConfig.file)) {
|
|
39
|
+
resolved[collectionName] = {
|
|
40
|
+
...collectionConfig,
|
|
41
|
+
file: path.resolve(configDir, collectionConfig.file),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
resolved[collectionName] = collectionConfig;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return resolved;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build the persistence layer for storage and serializer operations.
|
|
52
|
+
*/
|
|
53
|
+
function buildPersistenceLayer() {
|
|
54
|
+
return Layer.merge(NodeStorageLayer, makeSerializerLayer([jsonCodec(), yamlCodec(), tomlCodec()]));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Read the _version from a data file.
|
|
58
|
+
* Returns 0 if the file doesn't exist or has no _version field.
|
|
59
|
+
*
|
|
60
|
+
* @param filePath - Path to the data file
|
|
61
|
+
* @returns Effect yielding the file version and existence status
|
|
62
|
+
*/
|
|
63
|
+
function readFileVersion(filePath) {
|
|
64
|
+
return Effect.gen(function* () {
|
|
65
|
+
const storage = yield* StorageAdapterService;
|
|
66
|
+
const serializer = yield* SerializerRegistryService;
|
|
67
|
+
// Check if file exists
|
|
68
|
+
const exists = yield* storage.exists(filePath);
|
|
69
|
+
if (!exists) {
|
|
70
|
+
return { version: 0, exists: false };
|
|
71
|
+
}
|
|
72
|
+
// Read and parse the file
|
|
73
|
+
const raw = yield* storage.read(filePath);
|
|
74
|
+
const ext = getFileExtension(filePath) || "json";
|
|
75
|
+
const parsed = yield* serializer
|
|
76
|
+
.deserialize(raw, ext)
|
|
77
|
+
.pipe(Effect.catchAll(() => Effect.succeed(null)));
|
|
78
|
+
// Extract _version from parsed data
|
|
79
|
+
if (parsed !== null &&
|
|
80
|
+
typeof parsed === "object" &&
|
|
81
|
+
!Array.isArray(parsed)) {
|
|
82
|
+
const maybeVersion = parsed._version;
|
|
83
|
+
if (typeof maybeVersion === "number") {
|
|
84
|
+
return { version: maybeVersion, exists: true };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Default to version 0 if no _version field
|
|
88
|
+
return { version: 0, exists: true };
|
|
89
|
+
}).pipe(
|
|
90
|
+
// Catch any storage/serialization errors and return version 0
|
|
91
|
+
Effect.catchAll(() => Effect.succeed({ version: 0, exists: true })));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Determine the migration status based on file and config versions.
|
|
95
|
+
*
|
|
96
|
+
* @param fileVersion - Current version from the file
|
|
97
|
+
* @param targetVersion - Target version from config
|
|
98
|
+
* @param fileExists - Whether the data file exists
|
|
99
|
+
* @returns The appropriate DryRunStatus
|
|
100
|
+
*/
|
|
101
|
+
function determineStatus(fileVersion, targetVersion, fileExists) {
|
|
102
|
+
if (!fileExists) {
|
|
103
|
+
return "no-file";
|
|
104
|
+
}
|
|
105
|
+
if (fileVersion > targetVersion) {
|
|
106
|
+
return "ahead";
|
|
107
|
+
}
|
|
108
|
+
if (fileVersion === targetVersion) {
|
|
109
|
+
return "up-to-date";
|
|
110
|
+
}
|
|
111
|
+
return "needs-migration";
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get the list of migrations that would be applied for a collection.
|
|
115
|
+
*
|
|
116
|
+
* @param collectionConfig - The collection configuration
|
|
117
|
+
* @param fileVersion - Current version from the file
|
|
118
|
+
* @param targetVersion - Target version from config
|
|
119
|
+
* @returns Array of migrations to apply
|
|
120
|
+
*/
|
|
121
|
+
function getMigrationsToApply(collectionConfig, fileVersion, targetVersion) {
|
|
122
|
+
const migrations = collectionConfig.migrations ?? [];
|
|
123
|
+
return migrations
|
|
124
|
+
.filter((m) => m.from >= fileVersion && m.to <= targetVersion)
|
|
125
|
+
.sort((a, b) => a.from - b.from)
|
|
126
|
+
.map((m) => {
|
|
127
|
+
const result = {
|
|
128
|
+
from: m.from,
|
|
129
|
+
to: m.to,
|
|
130
|
+
};
|
|
131
|
+
if (m.description !== undefined) {
|
|
132
|
+
return { ...result, description: m.description };
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Execute the migrate status subcommand.
|
|
139
|
+
*
|
|
140
|
+
* Displays each collection's current file version vs config version,
|
|
141
|
+
* highlighting collections that need migration.
|
|
142
|
+
*/
|
|
143
|
+
function runMigrateStatus(config, configPath) {
|
|
144
|
+
const resolvedConfig = resolveConfigPaths(config, configPath);
|
|
145
|
+
const program = Effect.gen(function* () {
|
|
146
|
+
const collections = [];
|
|
147
|
+
for (const [name, collectionConfig] of Object.entries(resolvedConfig)) {
|
|
148
|
+
// Only include versioned collections
|
|
149
|
+
if (collectionConfig.version === undefined) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const targetVersion = collectionConfig.version;
|
|
153
|
+
const filePath = collectionConfig.file ?? "(in-memory)";
|
|
154
|
+
// Skip in-memory collections (no file to check)
|
|
155
|
+
if (!collectionConfig.file) {
|
|
156
|
+
collections.push({
|
|
157
|
+
name,
|
|
158
|
+
filePath: "(in-memory)",
|
|
159
|
+
currentVersion: 0,
|
|
160
|
+
targetVersion,
|
|
161
|
+
migrationsToApply: [],
|
|
162
|
+
status: "no-file",
|
|
163
|
+
});
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
// Read the file version
|
|
167
|
+
const { version: fileVersion, exists: fileExists } = yield* readFileVersion(collectionConfig.file);
|
|
168
|
+
// Determine the status
|
|
169
|
+
const status = determineStatus(fileVersion, targetVersion, fileExists);
|
|
170
|
+
// Get migrations to apply (only if needs migration)
|
|
171
|
+
const migrationsToApply = status === "needs-migration"
|
|
172
|
+
? getMigrationsToApply(collectionConfig, fileVersion, targetVersion)
|
|
173
|
+
: [];
|
|
174
|
+
collections.push({
|
|
175
|
+
name,
|
|
176
|
+
filePath,
|
|
177
|
+
currentVersion: fileVersion,
|
|
178
|
+
targetVersion,
|
|
179
|
+
migrationsToApply,
|
|
180
|
+
status,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
success: true,
|
|
185
|
+
data: { collections },
|
|
186
|
+
};
|
|
187
|
+
});
|
|
188
|
+
// Run with the persistence layer
|
|
189
|
+
return program.pipe(Effect.provide(buildPersistenceLayer()));
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Execute the migrate dry-run subcommand.
|
|
193
|
+
*
|
|
194
|
+
* Shows what migrations would run without executing them.
|
|
195
|
+
* This reads the current file versions and determines which migrations
|
|
196
|
+
* would be applied, but does not actually execute any transforms or write files.
|
|
197
|
+
*/
|
|
198
|
+
function runMigrateDryRun(config, configPath) {
|
|
199
|
+
const resolvedConfig = resolveConfigPaths(config, configPath);
|
|
200
|
+
const program = Effect.gen(function* () {
|
|
201
|
+
const collections = [];
|
|
202
|
+
for (const [name, collectionConfig] of Object.entries(resolvedConfig)) {
|
|
203
|
+
// Only include versioned collections
|
|
204
|
+
if (collectionConfig.version === undefined) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const targetVersion = collectionConfig.version;
|
|
208
|
+
const filePath = collectionConfig.file ?? "(in-memory)";
|
|
209
|
+
// Skip in-memory collections (no file to migrate)
|
|
210
|
+
if (!collectionConfig.file) {
|
|
211
|
+
collections.push({
|
|
212
|
+
name,
|
|
213
|
+
filePath: "(in-memory)",
|
|
214
|
+
currentVersion: 0,
|
|
215
|
+
targetVersion,
|
|
216
|
+
migrationsToApply: [],
|
|
217
|
+
status: "no-file",
|
|
218
|
+
});
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
// Read the file version
|
|
222
|
+
const { version: fileVersion, exists: fileExists } = yield* readFileVersion(collectionConfig.file);
|
|
223
|
+
// Determine the status
|
|
224
|
+
const status = determineStatus(fileVersion, targetVersion, fileExists);
|
|
225
|
+
// Get migrations to apply (only if needs migration)
|
|
226
|
+
const migrationsToApply = status === "needs-migration"
|
|
227
|
+
? getMigrationsToApply(collectionConfig, fileVersion, targetVersion)
|
|
228
|
+
: [];
|
|
229
|
+
collections.push({
|
|
230
|
+
name,
|
|
231
|
+
filePath,
|
|
232
|
+
currentVersion: fileVersion,
|
|
233
|
+
targetVersion,
|
|
234
|
+
migrationsToApply,
|
|
235
|
+
status,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
success: true,
|
|
240
|
+
data: { collections },
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
// Run with the persistence layer
|
|
244
|
+
return program.pipe(Effect.provide(buildPersistenceLayer()));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Execute migrations for a single collection.
|
|
248
|
+
*
|
|
249
|
+
* - Reads the file
|
|
250
|
+
* - Parses it
|
|
251
|
+
* - Runs the migrations on each entity
|
|
252
|
+
* - Updates the `_version` field
|
|
253
|
+
* - Writes the file back
|
|
254
|
+
*/
|
|
255
|
+
function migrateCollection(name, collectionConfig, fileVersion) {
|
|
256
|
+
const targetVersion = collectionConfig.version ?? 0;
|
|
257
|
+
const filePath = collectionConfig.file;
|
|
258
|
+
// This should not happen as we filter before calling this
|
|
259
|
+
if (!filePath) {
|
|
260
|
+
return Effect.succeed({
|
|
261
|
+
name,
|
|
262
|
+
success: false,
|
|
263
|
+
fromVersion: fileVersion,
|
|
264
|
+
toVersion: targetVersion,
|
|
265
|
+
migrationsApplied: 0,
|
|
266
|
+
error: "No file path configured",
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return Effect.gen(function* () {
|
|
270
|
+
const storage = yield* StorageAdapterService;
|
|
271
|
+
const serializer = yield* SerializerRegistryService;
|
|
272
|
+
const ext = getFileExtension(filePath) || "json";
|
|
273
|
+
// Read the file
|
|
274
|
+
const raw = yield* storage
|
|
275
|
+
.read(filePath)
|
|
276
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to read file: ${err}`))));
|
|
277
|
+
// Parse the file
|
|
278
|
+
const parsed = yield* serializer
|
|
279
|
+
.deserialize(raw, ext)
|
|
280
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to parse file: ${err}`))));
|
|
281
|
+
if (typeof parsed !== "object" ||
|
|
282
|
+
parsed === null ||
|
|
283
|
+
Array.isArray(parsed)) {
|
|
284
|
+
return yield* Effect.fail(new Error("File does not contain a valid object"));
|
|
285
|
+
}
|
|
286
|
+
const data = parsed;
|
|
287
|
+
// Get the migrations to apply
|
|
288
|
+
const migrations = collectionConfig.migrations ?? [];
|
|
289
|
+
const applicableMigrations = migrations
|
|
290
|
+
.filter((m) => m.from >= fileVersion && m.to <= targetVersion)
|
|
291
|
+
.sort((a, b) => a.from - b.from);
|
|
292
|
+
// Run the migrations by chaining transforms
|
|
293
|
+
let migratedData = data;
|
|
294
|
+
for (const migration of applicableMigrations) {
|
|
295
|
+
try {
|
|
296
|
+
migratedData = migration.transform(migratedData);
|
|
297
|
+
}
|
|
298
|
+
catch (err) {
|
|
299
|
+
return {
|
|
300
|
+
name,
|
|
301
|
+
success: false,
|
|
302
|
+
fromVersion: fileVersion,
|
|
303
|
+
toVersion: targetVersion,
|
|
304
|
+
migrationsApplied: applicableMigrations.indexOf(migration),
|
|
305
|
+
error: `Migration ${migration.from}→${migration.to} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Update the _version field
|
|
310
|
+
migratedData = {
|
|
311
|
+
...migratedData,
|
|
312
|
+
_version: targetVersion,
|
|
313
|
+
};
|
|
314
|
+
// Serialize the data
|
|
315
|
+
const serialized = yield* serializer
|
|
316
|
+
.serialize(migratedData, ext)
|
|
317
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to serialize data: ${err}`))));
|
|
318
|
+
// Write the file
|
|
319
|
+
yield* storage
|
|
320
|
+
.write(filePath, serialized)
|
|
321
|
+
.pipe(Effect.catchAll((err) => Effect.fail(new Error(`Failed to write file: ${err}`))));
|
|
322
|
+
return {
|
|
323
|
+
name,
|
|
324
|
+
success: true,
|
|
325
|
+
fromVersion: fileVersion,
|
|
326
|
+
toVersion: targetVersion,
|
|
327
|
+
migrationsApplied: applicableMigrations.length,
|
|
328
|
+
};
|
|
329
|
+
}).pipe(Effect.catchAll((err) => Effect.succeed({
|
|
330
|
+
name,
|
|
331
|
+
success: false,
|
|
332
|
+
fromVersion: fileVersion,
|
|
333
|
+
toVersion: targetVersion,
|
|
334
|
+
migrationsApplied: 0,
|
|
335
|
+
error: err instanceof Error ? err.message : String(err),
|
|
336
|
+
})));
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Execute migrations (the "run" subcommand).
|
|
340
|
+
*
|
|
341
|
+
* Prompts for confirmation (unless --force), executes all pending migrations,
|
|
342
|
+
* and reports results.
|
|
343
|
+
*/
|
|
344
|
+
function runMigrate(config, configPath, force) {
|
|
345
|
+
const resolvedConfig = resolveConfigPaths(config, configPath);
|
|
346
|
+
const program = Effect.gen(function* () {
|
|
347
|
+
// First, do a dry-run to determine which collections need migration
|
|
348
|
+
const dryRunCollections = [];
|
|
349
|
+
for (const [name, collectionConfig] of Object.entries(resolvedConfig)) {
|
|
350
|
+
// Only include versioned collections
|
|
351
|
+
if (collectionConfig.version === undefined) {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
const targetVersion = collectionConfig.version;
|
|
355
|
+
const filePath = collectionConfig.file ?? "(in-memory)";
|
|
356
|
+
// Skip in-memory collections (no file to migrate)
|
|
357
|
+
if (!collectionConfig.file) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
// Read the file version
|
|
361
|
+
const { version: fileVersion, exists: fileExists } = yield* readFileVersion(collectionConfig.file);
|
|
362
|
+
// Determine the status
|
|
363
|
+
const status = determineStatus(fileVersion, targetVersion, fileExists);
|
|
364
|
+
// Get migrations to apply (only if needs migration)
|
|
365
|
+
const migrationsToApply = status === "needs-migration"
|
|
366
|
+
? getMigrationsToApply(collectionConfig, fileVersion, targetVersion)
|
|
367
|
+
: [];
|
|
368
|
+
dryRunCollections.push({
|
|
369
|
+
name,
|
|
370
|
+
filePath,
|
|
371
|
+
currentVersion: fileVersion,
|
|
372
|
+
targetVersion,
|
|
373
|
+
migrationsToApply,
|
|
374
|
+
status,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
// Filter to collections that need migration
|
|
378
|
+
const collectionsToMigrate = dryRunCollections.filter((c) => c.status === "needs-migration");
|
|
379
|
+
if (collectionsToMigrate.length === 0) {
|
|
380
|
+
// Check if there are any versioned collections at all
|
|
381
|
+
const versionedCount = dryRunCollections.length;
|
|
382
|
+
if (versionedCount === 0) {
|
|
383
|
+
return {
|
|
384
|
+
success: true,
|
|
385
|
+
message: "No versioned collections found. Nothing to migrate.",
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
return {
|
|
389
|
+
success: true,
|
|
390
|
+
message: "All collections are up-to-date. Nothing to migrate.",
|
|
391
|
+
data: { collections: dryRunCollections },
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
// Prompt for confirmation
|
|
395
|
+
const totalMigrations = collectionsToMigrate.reduce((sum, c) => sum + c.migrationsToApply.length, 0);
|
|
396
|
+
const confirmResult = yield* Effect.promise(() => confirm({
|
|
397
|
+
message: `Run ${totalMigrations} migration(s) on ${collectionsToMigrate.length} collection(s)?`,
|
|
398
|
+
force,
|
|
399
|
+
}));
|
|
400
|
+
if (!confirmResult.confirmed) {
|
|
401
|
+
return {
|
|
402
|
+
success: false,
|
|
403
|
+
message: "Migration cancelled.",
|
|
404
|
+
aborted: true,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
// Execute migrations for each collection
|
|
408
|
+
const migrationResults = [];
|
|
409
|
+
for (const collectionDryRun of collectionsToMigrate) {
|
|
410
|
+
const collectionConfig = resolvedConfig[collectionDryRun.name];
|
|
411
|
+
const result = yield* migrateCollection(collectionDryRun.name, collectionConfig, collectionDryRun.currentVersion);
|
|
412
|
+
migrationResults.push(result);
|
|
413
|
+
}
|
|
414
|
+
// Build the summary
|
|
415
|
+
const succeeded = migrationResults.filter((r) => r.success).length;
|
|
416
|
+
const failed = migrationResults.filter((r) => !r.success).length;
|
|
417
|
+
const totalApplied = migrationResults.reduce((sum, r) => sum + r.migrationsApplied, 0);
|
|
418
|
+
const _runResult = {
|
|
419
|
+
collectionsProcessed: migrationResults.length,
|
|
420
|
+
collectionsSucceeded: succeeded,
|
|
421
|
+
collectionsFailed: failed,
|
|
422
|
+
details: migrationResults,
|
|
423
|
+
};
|
|
424
|
+
// Build message
|
|
425
|
+
let message;
|
|
426
|
+
if (failed === 0) {
|
|
427
|
+
message = `Migration complete. Applied ${totalApplied} migration(s) to ${succeeded} collection(s).`;
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
message = `Migration completed with errors. ${succeeded}/${migrationResults.length} collection(s) succeeded.`;
|
|
431
|
+
}
|
|
432
|
+
// Build updated dry-run result showing post-migration state
|
|
433
|
+
const updatedCollections = dryRunCollections.map((c) => {
|
|
434
|
+
const migrationResult = migrationResults.find((r) => r.name === c.name);
|
|
435
|
+
if (migrationResult?.success) {
|
|
436
|
+
return {
|
|
437
|
+
...c,
|
|
438
|
+
currentVersion: migrationResult.toVersion,
|
|
439
|
+
migrationsToApply: [],
|
|
440
|
+
status: "up-to-date",
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
return c;
|
|
444
|
+
});
|
|
445
|
+
return {
|
|
446
|
+
success: failed === 0,
|
|
447
|
+
message,
|
|
448
|
+
data: { collections: updatedCollections },
|
|
449
|
+
};
|
|
450
|
+
});
|
|
451
|
+
// Run with the persistence layer
|
|
452
|
+
return program.pipe(Effect.provide(buildPersistenceLayer()));
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Execute the migrate command.
|
|
456
|
+
*
|
|
457
|
+
* Routes to the appropriate subcommand handler based on options.
|
|
458
|
+
*
|
|
459
|
+
* @param options - Migrate command options
|
|
460
|
+
* @returns Effect that resolves to the migrate result
|
|
461
|
+
*/
|
|
462
|
+
export function runMigrateCommand(options) {
|
|
463
|
+
const { config, configPath, subcommand, force = false } = options;
|
|
464
|
+
switch (subcommand) {
|
|
465
|
+
case "status":
|
|
466
|
+
return runMigrateStatus(config, configPath);
|
|
467
|
+
case "dry-run":
|
|
468
|
+
return runMigrateDryRun(config, configPath);
|
|
469
|
+
case "run":
|
|
470
|
+
return runMigrate(config, configPath, force);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Handle the migrate command from CLI main.ts.
|
|
475
|
+
* This is the entry point called by the command dispatcher.
|
|
476
|
+
*
|
|
477
|
+
* @param options - Migrate command options
|
|
478
|
+
* @returns Promise that resolves to the migrate result
|
|
479
|
+
*/
|
|
480
|
+
export async function handleMigrate(options) {
|
|
481
|
+
return Effect.runPromise(runMigrateCommand(options));
|
|
482
|
+
}
|
|
483
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProseQL CLI - Query Command
|
|
3
|
+
*
|
|
4
|
+
* Boots the database from config, resolves collection by name, and executes
|
|
5
|
+
* queries with parsed where, select, sort, and limit options.
|
|
6
|
+
*/
|
|
7
|
+
import { type DatabaseConfig } from "@proseql/node";
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
import { type FilterParseError } from "../parsers/filter-parser.js";
|
|
10
|
+
/**
|
|
11
|
+
* Options for the query command.
|
|
12
|
+
*/
|
|
13
|
+
export interface QueryOptions {
|
|
14
|
+
/** Name of the collection to query */
|
|
15
|
+
readonly collection: string;
|
|
16
|
+
/** The database configuration */
|
|
17
|
+
readonly config: DatabaseConfig;
|
|
18
|
+
/** The path to the config file (used for resolving relative file paths) */
|
|
19
|
+
readonly configPath: string;
|
|
20
|
+
/** Filter expressions from --where flags */
|
|
21
|
+
readonly where?: readonly string[];
|
|
22
|
+
/** Comma-separated field list from --select flag */
|
|
23
|
+
readonly select?: string;
|
|
24
|
+
/** Sort expression from --sort flag (e.g., "year:desc") */
|
|
25
|
+
readonly sort?: string;
|
|
26
|
+
/** Limit from --limit flag */
|
|
27
|
+
readonly limit?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Result of the query command.
|
|
31
|
+
*/
|
|
32
|
+
export interface QueryResult {
|
|
33
|
+
readonly success: boolean;
|
|
34
|
+
readonly message?: string;
|
|
35
|
+
readonly data?: ReadonlyArray<Record<string, unknown>>;
|
|
36
|
+
readonly count?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Execute the query command.
|
|
40
|
+
*
|
|
41
|
+
* Boots the database from the config, resolves the collection by name,
|
|
42
|
+
* and executes a query with the provided options.
|
|
43
|
+
*
|
|
44
|
+
* @param options - Query command options
|
|
45
|
+
* @returns Result with queried data or error message
|
|
46
|
+
*/
|
|
47
|
+
export declare function runQuery(options: QueryOptions): Effect.Effect<QueryResult, FilterParseError>;
|
|
48
|
+
/**
|
|
49
|
+
* Handle the query command from CLI main.ts.
|
|
50
|
+
* This is the entry point called by the command dispatcher.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Query command options
|
|
53
|
+
* @returns Promise that resolves to the query results or rejects on error
|
|
54
|
+
*/
|
|
55
|
+
export declare function handleQuery(options: QueryOptions): Promise<QueryResult>;
|
|
56
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEN,KAAK,cAAc,EAMnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAS,MAAM,EAAiB,MAAM,QAAQ,CAAC;AACtD,OAAO,EACN,KAAK,gBAAgB,EAErB,MAAM,6BAA6B,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,sCAAsC;IACtC,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,4CAA4C;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACxB;AA8DD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACvB,OAAO,EAAE,YAAY,GACnB,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAqH9C;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAa7E"}
|