@donkeylabs/cli 2.2.0 → 2.3.0
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/package.json
CHANGED
|
@@ -45,6 +45,7 @@ export interface ProcessInfo {
|
|
|
45
45
|
export interface ServerOutput {
|
|
46
46
|
routes: RouteInfo[];
|
|
47
47
|
processes: ProcessInfo[];
|
|
48
|
+
coreEvents?: Record<string, string>;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/**
|
|
@@ -124,7 +125,7 @@ export async function extractRoutesFromServer(entryPath: string): Promise<Server
|
|
|
124
125
|
commands: p.commands,
|
|
125
126
|
}));
|
|
126
127
|
|
|
127
|
-
resolve({ routes, processes });
|
|
128
|
+
resolve({ routes, processes, coreEvents: result.coreEvents });
|
|
128
129
|
} catch (e) {
|
|
129
130
|
console.warn(pc.yellow("Failed to parse route data from server"));
|
|
130
131
|
resolve({ routes: [], processes: [] });
|
package/src/commands/generate.ts
CHANGED
|
@@ -954,7 +954,7 @@ export async function generateCommand(_args: string[]): Promise<void> {
|
|
|
954
954
|
await generateRegistry(plugins, outPath);
|
|
955
955
|
await generateContext(plugins, services, outPath);
|
|
956
956
|
await generateRouteTypes(fileRoutes, outPath);
|
|
957
|
-
await generateEventTypes(serverEvents, outPath);
|
|
957
|
+
await generateEventTypes(serverEvents, outPath, serverOutput.coreEvents);
|
|
958
958
|
await generateProcessTypes(serverProcesses, outPath);
|
|
959
959
|
|
|
960
960
|
const generated = ["registry", "context", "routes", "events", "processes"];
|
|
@@ -1373,9 +1373,17 @@ function parseZodObjectFields(objectContent: string): string {
|
|
|
1373
1373
|
|
|
1374
1374
|
/**
|
|
1375
1375
|
* Generate events.ts with namespace-nested types and EventMap.
|
|
1376
|
+
* Includes both core framework events and user-defined events.
|
|
1376
1377
|
*/
|
|
1377
|
-
async function generateEventTypes(
|
|
1378
|
-
|
|
1378
|
+
async function generateEventTypes(
|
|
1379
|
+
events: EventDefinitionInfo[],
|
|
1380
|
+
outPath: string,
|
|
1381
|
+
coreEvents?: Record<string, string>
|
|
1382
|
+
): Promise<void> {
|
|
1383
|
+
const hasCoreEvents = coreEvents && Object.keys(coreEvents).length > 0;
|
|
1384
|
+
const hasUserEvents = events.length > 0;
|
|
1385
|
+
|
|
1386
|
+
if (!hasCoreEvents && !hasUserEvents) {
|
|
1379
1387
|
// Still generate an empty file for consistency
|
|
1380
1388
|
const content = `// Auto-generated by donkeylabs generate
|
|
1381
1389
|
// Events - import as: import { type EventMap, type EventName } from ".@donkeylabs/server/events";
|
|
@@ -1398,10 +1406,32 @@ declare module "@donkeylabs/server" {
|
|
|
1398
1406
|
return;
|
|
1399
1407
|
}
|
|
1400
1408
|
|
|
1401
|
-
// Group events by namespace (first part of event name)
|
|
1409
|
+
// Group ALL events by namespace (first part of event name)
|
|
1402
1410
|
// e.g., "order.created" -> namespace "Order", event "Created"
|
|
1403
|
-
|
|
1411
|
+
// e.g., "workflow.step.started" -> namespace "Workflow", event "StepStarted"
|
|
1412
|
+
const byNamespace = new Map<string, { eventName: string; pascalName: string; tsType: string; fullName: string; isCore: boolean }[]>();
|
|
1413
|
+
|
|
1414
|
+
// Add core events first (using pre-computed TS type strings)
|
|
1415
|
+
if (hasCoreEvents) {
|
|
1416
|
+
for (const [eventFullName, tsTypeString] of Object.entries(coreEvents!)) {
|
|
1417
|
+
const parts = eventFullName.split(".");
|
|
1418
|
+
const namespace = toPascalCase(parts[0] || "App");
|
|
1419
|
+
const eventName = parts.slice(1).map(p => toPascalCase(p)).join("") || toPascalCase(parts[0] || "Event");
|
|
1420
|
+
|
|
1421
|
+
if (!byNamespace.has(namespace)) {
|
|
1422
|
+
byNamespace.set(namespace, []);
|
|
1423
|
+
}
|
|
1424
|
+
byNamespace.get(namespace)!.push({
|
|
1425
|
+
eventName,
|
|
1426
|
+
pascalName: eventName,
|
|
1427
|
+
tsType: tsTypeString,
|
|
1428
|
+
fullName: eventFullName,
|
|
1429
|
+
isCore: true,
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1404
1433
|
|
|
1434
|
+
// Add user-defined events (from Zod schemas)
|
|
1405
1435
|
for (const event of events) {
|
|
1406
1436
|
const parts = event.name.split(".");
|
|
1407
1437
|
const namespace = toPascalCase(parts[0] || "App");
|
|
@@ -1413,25 +1443,41 @@ declare module "@donkeylabs/server" {
|
|
|
1413
1443
|
byNamespace.get(namespace)!.push({
|
|
1414
1444
|
eventName,
|
|
1415
1445
|
pascalName: eventName,
|
|
1416
|
-
|
|
1446
|
+
tsType: zodSchemaToTypeScript(event.schemaSource),
|
|
1417
1447
|
fullName: event.name,
|
|
1448
|
+
isCore: false,
|
|
1418
1449
|
});
|
|
1419
1450
|
}
|
|
1420
1451
|
|
|
1421
1452
|
// Generate namespace blocks
|
|
1422
1453
|
const namespaceBlocks: string[] = [];
|
|
1454
|
+
const coreNamespaceBlocks: string[] = [];
|
|
1455
|
+
const userNamespaceBlocks: string[] = [];
|
|
1423
1456
|
const eventMapEntries: string[] = [];
|
|
1424
1457
|
const eventRegistryEntries: string[] = [];
|
|
1425
1458
|
const eventNames: string[] = [];
|
|
1426
1459
|
|
|
1460
|
+
// Track which namespaces are core-only, user-only, or mixed
|
|
1427
1461
|
for (const [namespace, nsEvents] of byNamespace) {
|
|
1462
|
+
const hasCoreInNs = nsEvents.some(e => e.isCore);
|
|
1463
|
+
const hasUserInNs = nsEvents.some(e => !e.isCore);
|
|
1464
|
+
|
|
1428
1465
|
const eventTypeDecls = nsEvents.map(e => {
|
|
1429
|
-
const tsType = zodSchemaToTypeScript(e.schemaSource);
|
|
1430
1466
|
return ` /** Event data for "${e.fullName}" */
|
|
1431
|
-
export type ${e.pascalName} = ${tsType};`;
|
|
1467
|
+
export type ${e.pascalName} = ${e.tsType};`;
|
|
1432
1468
|
}).join("\n\n");
|
|
1433
1469
|
|
|
1434
|
-
|
|
1470
|
+
const block = `export namespace ${namespace} {\n${eventTypeDecls}\n}`;
|
|
1471
|
+
|
|
1472
|
+
if (hasCoreInNs && !hasUserInNs) {
|
|
1473
|
+
coreNamespaceBlocks.push(block);
|
|
1474
|
+
} else if (!hasCoreInNs && hasUserInNs) {
|
|
1475
|
+
userNamespaceBlocks.push(block);
|
|
1476
|
+
} else {
|
|
1477
|
+
// Mixed - put in core section
|
|
1478
|
+
coreNamespaceBlocks.push(block);
|
|
1479
|
+
}
|
|
1480
|
+
namespaceBlocks.push(block);
|
|
1435
1481
|
|
|
1436
1482
|
// Add to EventMap and EventRegistry
|
|
1437
1483
|
for (const e of nsEvents) {
|
|
@@ -1441,11 +1487,20 @@ declare module "@donkeylabs/server" {
|
|
|
1441
1487
|
}
|
|
1442
1488
|
}
|
|
1443
1489
|
|
|
1490
|
+
// Build the output with clear sections
|
|
1491
|
+
const sections: string[] = [];
|
|
1492
|
+
|
|
1493
|
+
if (coreNamespaceBlocks.length > 0) {
|
|
1494
|
+
sections.push(`// Core framework events\n${coreNamespaceBlocks.join("\n\n")}`);
|
|
1495
|
+
}
|
|
1496
|
+
if (userNamespaceBlocks.length > 0) {
|
|
1497
|
+
sections.push(`// User-defined events\n${userNamespaceBlocks.join("\n\n")}`);
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1444
1500
|
const content = `// Auto-generated by donkeylabs generate
|
|
1445
1501
|
// Events - import as: import { type EventMap, type EventName, Order, User } from ".@donkeylabs/server/events";
|
|
1446
1502
|
|
|
1447
|
-
|
|
1448
|
-
${namespaceBlocks.join("\n\n")}
|
|
1503
|
+
${sections.join("\n\n")}
|
|
1449
1504
|
|
|
1450
1505
|
/** Map of all event names to their data types */
|
|
1451
1506
|
export interface EventMap {
|