@agentuity/cli 0.0.95 → 0.0.96
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/AGENTS.md +54 -0
- package/dist/auth.d.ts +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +8 -5
- package/dist/auth.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +190 -27
- package/dist/cli.js.map +1 -1
- package/dist/cmd/build/entry-generator.d.ts +20 -0
- package/dist/cmd/build/entry-generator.d.ts.map +1 -0
- package/dist/cmd/build/entry-generator.js +366 -0
- package/dist/cmd/build/entry-generator.js.map +1 -0
- package/dist/cmd/build/index.d.ts.map +1 -1
- package/dist/cmd/build/index.js +5 -23
- package/dist/cmd/build/index.js.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.d.ts +33 -0
- package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -0
- package/dist/cmd/build/vite/agent-discovery.js +297 -0
- package/dist/cmd/build/vite/agent-discovery.js.map +1 -0
- package/dist/cmd/build/vite/browser-env-plugin.d.ts +9 -0
- package/dist/cmd/build/vite/browser-env-plugin.d.ts.map +1 -0
- package/dist/cmd/build/vite/browser-env-plugin.js +28 -0
- package/dist/cmd/build/vite/browser-env-plugin.js.map +1 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts +29 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -0
- package/dist/cmd/build/vite/bun-dev-server.js +54 -0
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -0
- package/dist/cmd/build/vite/config-loader.d.ts +23 -0
- package/dist/cmd/build/vite/config-loader.d.ts.map +1 -0
- package/dist/cmd/build/vite/config-loader.js +50 -0
- package/dist/cmd/build/vite/config-loader.js.map +1 -0
- package/dist/cmd/build/vite/index.d.ts +26 -0
- package/dist/cmd/build/vite/index.d.ts.map +1 -0
- package/dist/cmd/build/vite/index.js +127 -0
- package/dist/cmd/build/vite/index.js.map +1 -0
- package/dist/cmd/build/vite/lifecycle-generator.d.ts +11 -0
- package/dist/cmd/build/vite/lifecycle-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/lifecycle-generator.js +35 -0
- package/dist/cmd/build/vite/lifecycle-generator.js.map +1 -0
- package/dist/cmd/build/vite/metadata-generator.d.ts +32 -0
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/metadata-generator.js +489 -0
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -0
- package/dist/cmd/build/vite/patch-plugin.d.ts +21 -0
- package/dist/cmd/build/vite/patch-plugin.d.ts.map +1 -0
- package/dist/cmd/build/vite/patch-plugin.js +70 -0
- package/dist/cmd/build/vite/patch-plugin.js.map +1 -0
- package/dist/cmd/build/vite/registry-generator.d.ts +19 -0
- package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -0
- package/dist/cmd/build/{route-registry.js → vite/registry-generator.js} +126 -48
- package/dist/cmd/build/vite/registry-generator.js.map +1 -0
- package/dist/cmd/build/vite/route-discovery.d.ts +58 -0
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -0
- package/dist/cmd/build/vite/route-discovery.js +125 -0
- package/dist/cmd/build/vite/route-discovery.js.map +1 -0
- package/dist/cmd/build/vite/server-bundler.d.ts +16 -0
- package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -0
- package/dist/cmd/build/vite/server-bundler.js +194 -0
- package/dist/cmd/build/vite/server-bundler.js.map +1 -0
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts +19 -0
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -0
- package/dist/cmd/build/vite/vite-asset-server-config.js +105 -0
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -0
- package/dist/cmd/build/vite/vite-asset-server.d.ts +23 -0
- package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -0
- package/dist/cmd/build/vite/vite-asset-server.js +40 -0
- package/dist/cmd/build/vite/vite-asset-server.js.map +1 -0
- package/dist/cmd/build/vite/vite-builder.d.ts +44 -0
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -0
- package/dist/cmd/build/vite/vite-builder.js +232 -0
- package/dist/cmd/build/vite/vite-builder.js.map +1 -0
- package/dist/cmd/build/vite/workbench-generator.d.ts +10 -0
- package/dist/cmd/build/vite/workbench-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/workbench-generator.js +135 -0
- package/dist/cmd/build/vite/workbench-generator.js.map +1 -0
- package/dist/cmd/build/vite-bundler.d.ts +23 -0
- package/dist/cmd/build/vite-bundler.d.ts.map +1 -0
- package/dist/cmd/build/vite-bundler.js +79 -0
- package/dist/cmd/build/vite-bundler.js.map +1 -0
- package/dist/cmd/cloud/agent/get.d.ts.map +1 -1
- package/dist/cmd/cloud/agent/get.js +1 -0
- package/dist/cmd/cloud/agent/get.js.map +1 -1
- package/dist/cmd/cloud/agent/list.d.ts.map +1 -1
- package/dist/cmd/cloud/agent/list.js +1 -0
- package/dist/cmd/cloud/agent/list.js.map +1 -1
- package/dist/cmd/cloud/db/get.d.ts.map +1 -1
- package/dist/cmd/cloud/db/get.js +1 -0
- package/dist/cmd/cloud/db/get.js.map +1 -1
- package/dist/cmd/cloud/db/list.d.ts.map +1 -1
- package/dist/cmd/cloud/db/list.js +1 -0
- package/dist/cmd/cloud/db/list.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +152 -128
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/list.js +4 -0
- package/dist/cmd/cloud/deployment/list.js.map +1 -1
- package/dist/cmd/cloud/env/list.d.ts.map +1 -1
- package/dist/cmd/cloud/env/list.js +1 -0
- package/dist/cmd/cloud/env/list.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/get.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/get.js +1 -0
- package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/keys.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/keys.js +1 -0
- package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/list-namespaces.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/list-namespaces.js +1 -0
- package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/stats.js +1 -0
- package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
- package/dist/cmd/cloud/secret/list.d.ts.map +1 -1
- package/dist/cmd/cloud/secret/list.js +1 -0
- package/dist/cmd/cloud/secret/list.js.map +1 -1
- package/dist/cmd/cloud/session/list.d.ts.map +1 -1
- package/dist/cmd/cloud/session/list.js +4 -0
- package/dist/cmd/cloud/session/list.js.map +1 -1
- package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/get.js +1 -0
- package/dist/cmd/cloud/storage/get.js.map +1 -1
- package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/list.js +3 -0
- package/dist/cmd/cloud/storage/list.js.map +1 -1
- package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/get.js +1 -0
- package/dist/cmd/cloud/stream/get.js.map +1 -1
- package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/list.js +1 -0
- package/dist/cmd/cloud/stream/list.js.map +1 -1
- package/dist/cmd/cloud/vector/get.d.ts.map +1 -1
- package/dist/cmd/cloud/vector/get.js +1 -0
- package/dist/cmd/cloud/vector/get.js.map +1 -1
- package/dist/cmd/cloud/vector/search.d.ts.map +1 -1
- package/dist/cmd/cloud/vector/search.js +1 -0
- package/dist/cmd/cloud/vector/search.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +289 -758
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/dev/sync.d.ts +1 -1
- package/dist/cmd/dev/sync.d.ts.map +1 -1
- package/dist/cmd/dev/sync.js +3 -0
- package/dist/cmd/dev/sync.js.map +1 -1
- package/dist/cmd/profile/show.d.ts.map +1 -1
- package/dist/cmd/profile/show.js +3 -4
- package/dist/cmd/profile/show.js.map +1 -1
- package/dist/cmd/project/create.d.ts.map +1 -1
- package/dist/cmd/project/create.js +3 -4
- package/dist/cmd/project/create.js.map +1 -1
- package/dist/cmd/project/list.d.ts.map +1 -1
- package/dist/cmd/project/list.js +1 -0
- package/dist/cmd/project/list.js.map +1 -1
- package/dist/cmd/project/show.d.ts.map +1 -1
- package/dist/cmd/project/show.js +1 -0
- package/dist/cmd/project/show.js.map +1 -1
- package/dist/cmd/upgrade/index.d.ts.map +1 -1
- package/dist/cmd/upgrade/index.js +5 -3
- package/dist/cmd/upgrade/index.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +29 -11
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime-bootstrap.d.ts +3 -2
- package/dist/runtime-bootstrap.d.ts.map +1 -1
- package/dist/runtime-bootstrap.js +7 -2
- package/dist/runtime-bootstrap.js.map +1 -1
- package/dist/schemas/deploy.d.ts +1 -1
- package/dist/types.d.ts +40 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/bun-version-checker.d.ts +11 -0
- package/dist/utils/bun-version-checker.d.ts.map +1 -0
- package/dist/utils/bun-version-checker.js +56 -0
- package/dist/utils/bun-version-checker.js.map +1 -0
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +5 -2
- package/dist/version-check.js.map +1 -1
- package/package.json +10 -3
- package/src/auth.ts +9 -5
- package/src/cli.ts +228 -29
- package/src/cmd/build/entry-generator.ts +404 -0
- package/src/cmd/build/index.ts +7 -28
- package/src/cmd/build/vite/agent-discovery.ts +467 -0
- package/src/cmd/build/vite/browser-env-plugin.ts +34 -0
- package/src/cmd/build/vite/bun-dev-server.ts +78 -0
- package/src/cmd/build/vite/config-loader.ts +70 -0
- package/src/cmd/build/vite/index.ts +166 -0
- package/src/cmd/build/vite/lifecycle-generator.ts +43 -0
- package/src/cmd/build/vite/metadata-generator.ts +602 -0
- package/src/cmd/build/vite/patch-plugin.ts +88 -0
- package/src/cmd/build/vite/registry-generator.ts +288 -0
- package/src/cmd/build/vite/route-discovery.ts +186 -0
- package/src/cmd/build/vite/server-bundler.ts +258 -0
- package/src/cmd/build/vite/vite-asset-server-config.ts +134 -0
- package/src/cmd/build/vite/vite-asset-server.ts +63 -0
- package/src/cmd/build/vite/vite-builder.ts +284 -0
- package/src/cmd/build/vite/workbench-generator.ts +152 -0
- package/src/cmd/build/vite-bundler.ts +110 -0
- package/src/cmd/cloud/agent/get.ts +2 -0
- package/src/cmd/cloud/agent/list.ts +1 -0
- package/src/cmd/cloud/db/get.ts +1 -0
- package/src/cmd/cloud/db/list.ts +1 -0
- package/src/cmd/cloud/deploy.ts +175 -144
- package/src/cmd/cloud/deployment/list.ts +4 -0
- package/src/cmd/cloud/env/list.ts +1 -0
- package/src/cmd/cloud/keyvalue/get.ts +1 -0
- package/src/cmd/cloud/keyvalue/keys.ts +1 -0
- package/src/cmd/cloud/keyvalue/list-namespaces.ts +1 -0
- package/src/cmd/cloud/keyvalue/stats.ts +2 -0
- package/src/cmd/cloud/secret/list.ts +1 -0
- package/src/cmd/cloud/session/list.ts +4 -0
- package/src/cmd/cloud/storage/get.ts +1 -0
- package/src/cmd/cloud/storage/list.ts +4 -0
- package/src/cmd/cloud/stream/get.ts +1 -0
- package/src/cmd/cloud/stream/list.ts +1 -0
- package/src/cmd/cloud/vector/get.ts +1 -0
- package/src/cmd/cloud/vector/search.ts +1 -0
- package/src/cmd/dev/index.ts +319 -921
- package/src/cmd/dev/sync.ts +5 -1
- package/src/cmd/profile/show.ts +3 -4
- package/src/cmd/project/create.ts +3 -4
- package/src/cmd/project/list.ts +1 -0
- package/src/cmd/project/show.ts +1 -0
- package/src/cmd/upgrade/index.ts +6 -3
- package/src/config.ts +31 -11
- package/src/index.ts +2 -0
- package/src/runtime-bootstrap.ts +8 -2
- package/src/types.ts +48 -1
- package/src/utils/bun-version-checker.ts +70 -0
- package/src/version-check.ts +6 -2
- package/dist/cmd/build/bundler.d.ts +0 -28
- package/dist/cmd/build/bundler.d.ts.map +0 -1
- package/dist/cmd/build/bundler.js +0 -800
- package/dist/cmd/build/bundler.js.map +0 -1
- package/dist/cmd/build/config-loader.d.ts +0 -16
- package/dist/cmd/build/config-loader.d.ts.map +0 -1
- package/dist/cmd/build/config-loader.js +0 -227
- package/dist/cmd/build/config-loader.js.map +0 -1
- package/dist/cmd/build/file.d.ts +0 -2
- package/dist/cmd/build/file.d.ts.map +0 -1
- package/dist/cmd/build/file.js +0 -10
- package/dist/cmd/build/file.js.map +0 -1
- package/dist/cmd/build/fix-duplicate-exports.d.ts +0 -2
- package/dist/cmd/build/fix-duplicate-exports.d.ts.map +0 -1
- package/dist/cmd/build/fix-duplicate-exports.js +0 -170
- package/dist/cmd/build/fix-duplicate-exports.js.map +0 -1
- package/dist/cmd/build/plugin.d.ts +0 -6
- package/dist/cmd/build/plugin.d.ts.map +0 -1
- package/dist/cmd/build/plugin.js +0 -645
- package/dist/cmd/build/plugin.js.map +0 -1
- package/dist/cmd/build/route-discovery.d.ts +0 -54
- package/dist/cmd/build/route-discovery.d.ts.map +0 -1
- package/dist/cmd/build/route-discovery.js +0 -148
- package/dist/cmd/build/route-discovery.js.map +0 -1
- package/dist/cmd/build/route-registry.d.ts +0 -38
- package/dist/cmd/build/route-registry.d.ts.map +0 -1
- package/dist/cmd/build/route-registry.js.map +0 -1
- package/src/cmd/build/bundler.ts +0 -965
- package/src/cmd/build/config-loader.ts +0 -268
- package/src/cmd/build/file.ts +0 -10
- package/src/cmd/build/fix-duplicate-exports.ts +0 -207
- package/src/cmd/build/plugin.ts +0 -782
- package/src/cmd/build/route-discovery.ts +0 -202
- package/src/cmd/build/route-registry.ts +0 -222
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { existsSync, readdirSync, lstatSync } from 'node:fs';
|
|
2
|
-
import { join, relative } from 'node:path';
|
|
3
|
-
import { toCamelCase } from '../../utils/string';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Information about a discovered route file
|
|
7
|
-
*/
|
|
8
|
-
export interface DiscoveredRouteFile {
|
|
9
|
-
/** Full path to the route file */
|
|
10
|
-
filepath: string;
|
|
11
|
-
/** Relative path from apiDir (e.g., 'auth/route.ts', 'v1/users/route.ts') */
|
|
12
|
-
relativePath: string;
|
|
13
|
-
/** Mount path for the route (e.g., '/api/auth', '/api/v1/users') */
|
|
14
|
-
mountPath: string;
|
|
15
|
-
/** Safe variable name for importing (e.g., 'authRoute', 'v1UsersRoute') */
|
|
16
|
-
variableName: string;
|
|
17
|
-
/** Import path relative to build output (e.g., './src/api/auth/route') */
|
|
18
|
-
importPath: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Recursively discover all TypeScript files in an API directory.
|
|
23
|
-
* Any .ts file CAN be a route if it exports a router, but not all files MUST be routes.
|
|
24
|
-
* Files without router exports (utility files, types, helpers) are discovered but gracefully skipped during processing.
|
|
25
|
-
*
|
|
26
|
-
* Supports nested structures like:
|
|
27
|
-
* - src/api/index.ts (root API router - handled separately)
|
|
28
|
-
* - src/api/auth/route.ts -> mounted at /api/auth
|
|
29
|
-
* - src/api/auth/login.ts -> mounted at /api/auth
|
|
30
|
-
* - src/api/v1/users/route.ts -> mounted at /api/v1/users
|
|
31
|
-
* - src/api/auth/helpers.ts -> discovered but skipped if no router export
|
|
32
|
-
*
|
|
33
|
-
* @param apiDir - Absolute path to the src/api directory
|
|
34
|
-
* @param currentDir - Current directory being scanned (used for recursion)
|
|
35
|
-
* @param results - Accumulated results (used for recursion)
|
|
36
|
-
* @returns Array of discovered TypeScript files with mount information
|
|
37
|
-
*/
|
|
38
|
-
export function discoverRouteFiles(
|
|
39
|
-
apiDir: string,
|
|
40
|
-
currentDir: string = apiDir,
|
|
41
|
-
results: DiscoveredRouteFile[] = []
|
|
42
|
-
): DiscoveredRouteFile[] {
|
|
43
|
-
if (!existsSync(currentDir)) {
|
|
44
|
-
return results;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const entries = readdirSync(currentDir);
|
|
48
|
-
|
|
49
|
-
for (const entry of entries) {
|
|
50
|
-
const entryPath = join(currentDir, entry);
|
|
51
|
-
const stat = lstatSync(entryPath);
|
|
52
|
-
|
|
53
|
-
// Skip symlinks to prevent infinite recursion
|
|
54
|
-
if (stat.isSymbolicLink()) {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (stat.isFile() && entry.endsWith('.ts') && !entry.endsWith('.generated.ts')) {
|
|
59
|
-
// Found a TypeScript file
|
|
60
|
-
const relativePath = relative(apiDir, entryPath);
|
|
61
|
-
const isRootIndex = relativePath === 'index.ts';
|
|
62
|
-
|
|
63
|
-
// Skip root index.ts - it's handled separately
|
|
64
|
-
if (isRootIndex) {
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// For subdirectory files, determine mount path
|
|
69
|
-
// src/api/auth/route.ts -> /api/auth
|
|
70
|
-
// src/api/auth/login.ts -> /api/auth
|
|
71
|
-
// src/api/v1/users/route.ts -> /api/v1/users
|
|
72
|
-
// src/api/admin/helpers.ts -> /api/admin (discovered but may be skipped during processing)
|
|
73
|
-
const pathParts = relativePath.split('/');
|
|
74
|
-
pathParts.pop(); // Remove filename
|
|
75
|
-
|
|
76
|
-
// Skip files directly in src/api/ to avoid mount path conflicts with root index.ts
|
|
77
|
-
if (pathParts.length === 0) {
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const mountPath = `/api/${pathParts.join('/')}`;
|
|
82
|
-
|
|
83
|
-
// Generate safe variable name
|
|
84
|
-
// auth/route.ts -> authRoute
|
|
85
|
-
// v1/users/route.ts -> v1UsersRoute
|
|
86
|
-
// admin/login.ts -> adminLoginRoute
|
|
87
|
-
const variableParts = pathParts.map((p, idx) => {
|
|
88
|
-
const camel = toCamelCase(p);
|
|
89
|
-
// Capitalize first letter of all parts except the first
|
|
90
|
-
return idx === 0 ? camel : camel.charAt(0).toUpperCase() + camel.slice(1);
|
|
91
|
-
});
|
|
92
|
-
const baseName = entry.replace('.ts', '');
|
|
93
|
-
if (baseName !== 'route' && baseName !== 'index') {
|
|
94
|
-
const camelBase = toCamelCase(baseName);
|
|
95
|
-
// Always capitalize the base name since it's not the first part
|
|
96
|
-
variableParts.push(camelBase.charAt(0).toUpperCase() + camelBase.slice(1));
|
|
97
|
-
}
|
|
98
|
-
const variableName = variableParts.join('') + 'Route';
|
|
99
|
-
|
|
100
|
-
// Generate import path relative to build output
|
|
101
|
-
// src/api/auth/route.ts -> ./src/api/auth/route
|
|
102
|
-
const importPath = './src/api/' + relativePath.replace('.ts', '');
|
|
103
|
-
|
|
104
|
-
results.push({
|
|
105
|
-
filepath: entryPath,
|
|
106
|
-
relativePath,
|
|
107
|
-
mountPath,
|
|
108
|
-
variableName,
|
|
109
|
-
importPath,
|
|
110
|
-
});
|
|
111
|
-
} else if (stat.isDirectory()) {
|
|
112
|
-
// Recursively scan subdirectories
|
|
113
|
-
discoverRouteFiles(apiDir, entryPath, results);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return results;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Detect potential route path conflicts
|
|
122
|
-
*
|
|
123
|
-
* @param routes - Array of route metadata with method and path
|
|
124
|
-
* @returns Array of conflict descriptions
|
|
125
|
-
*/
|
|
126
|
-
export interface RouteConflict {
|
|
127
|
-
type: 'duplicate' | 'ambiguous-param' | 'wildcard-overlap';
|
|
128
|
-
routes: Array<{ method: string; path: string; filename: string }>;
|
|
129
|
-
message: string;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export function detectRouteConflicts(
|
|
133
|
-
routes: Array<{ method: string; path: string; filename: string }>
|
|
134
|
-
): RouteConflict[] {
|
|
135
|
-
const conflicts: RouteConflict[] = [];
|
|
136
|
-
|
|
137
|
-
// Group routes by method+path
|
|
138
|
-
const methodPathMap = new Map<string, Array<{ path: string; filename: string }>>();
|
|
139
|
-
|
|
140
|
-
for (const route of routes) {
|
|
141
|
-
const key = `${route.method.toUpperCase()} ${route.path}`;
|
|
142
|
-
if (!methodPathMap.has(key)) {
|
|
143
|
-
methodPathMap.set(key, []);
|
|
144
|
-
}
|
|
145
|
-
methodPathMap.get(key)!.push({ path: route.path, filename: route.filename });
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Check for exact duplicates
|
|
149
|
-
for (const [methodPath, routeList] of methodPathMap.entries()) {
|
|
150
|
-
if (routeList.length > 1) {
|
|
151
|
-
const [method] = methodPath.split(' ', 2);
|
|
152
|
-
conflicts.push({
|
|
153
|
-
type: 'duplicate',
|
|
154
|
-
routes: routeList.map((r) => ({ method, path: r.path, filename: r.filename })),
|
|
155
|
-
message: `Duplicate route: ${methodPath} defined in ${routeList.length} files`,
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Check for ambiguous parameter routes (same method, different param names)
|
|
161
|
-
// e.g., GET /users/:id and GET /users/:userId
|
|
162
|
-
const methodGroups = new Map<string, Array<{ path: string; filename: string }>>();
|
|
163
|
-
for (const route of routes) {
|
|
164
|
-
const method = route.method.toUpperCase();
|
|
165
|
-
if (!methodGroups.has(method)) {
|
|
166
|
-
methodGroups.set(method, []);
|
|
167
|
-
}
|
|
168
|
-
methodGroups.get(method)!.push({ path: route.path, filename: route.filename });
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
for (const [method, routeList] of methodGroups.entries()) {
|
|
172
|
-
// Normalize params to check for conflicts
|
|
173
|
-
const normalized = routeList.map((r) => ({
|
|
174
|
-
...r,
|
|
175
|
-
normalizedPath: r.path.replace(/:[^/]+/g, ':param'),
|
|
176
|
-
}));
|
|
177
|
-
|
|
178
|
-
const pathMap = new Map<string, Array<{ path: string; filename: string }>>();
|
|
179
|
-
for (const route of normalized) {
|
|
180
|
-
if (!pathMap.has(route.normalizedPath)) {
|
|
181
|
-
pathMap.set(route.normalizedPath, []);
|
|
182
|
-
}
|
|
183
|
-
pathMap.get(route.normalizedPath)!.push({ path: route.path, filename: route.filename });
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
for (const [normalizedPath, paths] of pathMap.entries()) {
|
|
187
|
-
if (paths.length > 1 && normalizedPath.includes(':param')) {
|
|
188
|
-
// Check if the actual param names differ
|
|
189
|
-
const uniquePaths = new Set(paths.map((p) => p.path));
|
|
190
|
-
if (uniquePaths.size > 1) {
|
|
191
|
-
conflicts.push({
|
|
192
|
-
type: 'ambiguous-param',
|
|
193
|
-
routes: paths.map(({ path, filename }) => ({ method, path, filename })),
|
|
194
|
-
message: `Ambiguous param routes: ${method} ${Array.from(uniquePaths).join(', ')}`,
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return conflicts;
|
|
202
|
-
}
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Route information extracted from route files
|
|
6
|
-
*/
|
|
7
|
-
export interface RouteInfo {
|
|
8
|
-
/** HTTP method (GET, POST, etc.) */
|
|
9
|
-
method: string;
|
|
10
|
-
/** Route path */
|
|
11
|
-
path: string;
|
|
12
|
-
/** Relative file path */
|
|
13
|
-
filename: string;
|
|
14
|
-
/** Variable name of the route handler */
|
|
15
|
-
handlerVariable?: string;
|
|
16
|
-
/** Whether this route uses validator */
|
|
17
|
-
hasValidator: boolean;
|
|
18
|
-
/** Route type: 'api' | 'websocket' | 'sse' | 'stream' */
|
|
19
|
-
routeType?: string;
|
|
20
|
-
/** Agent variable name if using agent.validator() */
|
|
21
|
-
agentVariable?: string;
|
|
22
|
-
/** Agent import path (e.g., '@agent/hello', '../shared/agents') */
|
|
23
|
-
agentImportPath?: string;
|
|
24
|
-
/** Input schema variable name if using validator({ input }) */
|
|
25
|
-
inputSchemaVariable?: string;
|
|
26
|
-
/** Output schema variable name if using validator({ output }) */
|
|
27
|
-
outputSchemaVariable?: string;
|
|
28
|
-
/** Whether this route is a streaming route (from validator({ stream: true })) */
|
|
29
|
-
stream?: boolean;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Generate RouteRegistry type definitions from discovered routes.
|
|
34
|
-
*
|
|
35
|
-
* Creates a module augmentation for @agentuity/react that provides
|
|
36
|
-
* strongly-typed route keys with input/output schema information.
|
|
37
|
-
*
|
|
38
|
-
* @param srcDir - Source directory path
|
|
39
|
-
* @param routes - Array of route information
|
|
40
|
-
*/
|
|
41
|
-
export function generateRouteRegistry(srcDir: string, routes: RouteInfo[]): void {
|
|
42
|
-
// Filter routes by type (include ALL routes, not just those with validators)
|
|
43
|
-
// Note: 'stream' routes are HTTP routes that return ReadableStream, so include them with API routes
|
|
44
|
-
const apiRoutes = routes.filter((r) => r.routeType === 'api' || r.routeType === 'stream');
|
|
45
|
-
const websocketRoutes = routes.filter((r) => r.routeType === 'websocket');
|
|
46
|
-
const sseRoutes = routes.filter((r) => r.routeType === 'sse');
|
|
47
|
-
|
|
48
|
-
if (apiRoutes.length === 0 && websocketRoutes.length === 0 && sseRoutes.length === 0) {
|
|
49
|
-
// No routes, skip generation
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Generate imports for agents and schemas
|
|
54
|
-
const imports: string[] = [];
|
|
55
|
-
const agentImports = new Map<string, string>(); // Maps agent variable to unique import name
|
|
56
|
-
const schemaImports = new Set<string>(); // Track which schema variables we've seen
|
|
57
|
-
|
|
58
|
-
// Combine all routes for import collection
|
|
59
|
-
const allRoutes = [...apiRoutes, ...websocketRoutes, ...sseRoutes];
|
|
60
|
-
|
|
61
|
-
// First pass: collect all unique agents and schema variables (only for routes with validators)
|
|
62
|
-
allRoutes.forEach((route) => {
|
|
63
|
-
// Skip routes without validators - they won't need imports
|
|
64
|
-
if (!route.hasValidator) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
// If this route uses an agent, import it directly
|
|
68
|
-
if (route.agentVariable && route.agentImportPath && !agentImports.has(route.agentVariable)) {
|
|
69
|
-
// Resolve the import path (could be @agent/hello, ../shared, etc.)
|
|
70
|
-
let resolvedPath = route.agentImportPath;
|
|
71
|
-
|
|
72
|
-
// If it's a path alias like @agent/hello, convert to relative path
|
|
73
|
-
if (resolvedPath.startsWith('@agent/')) {
|
|
74
|
-
resolvedPath = `../src/agent/${resolvedPath.substring('@agent/'.length)}`;
|
|
75
|
-
} else if (resolvedPath.startsWith('@api/')) {
|
|
76
|
-
resolvedPath = `../src/web/${resolvedPath.substring('@api/'.length)}`;
|
|
77
|
-
} else if (resolvedPath.startsWith('./') || resolvedPath.startsWith('../')) {
|
|
78
|
-
// Relative path - need to resolve relative to route file location
|
|
79
|
-
const routeDir = route.filename.substring(0, route.filename.lastIndexOf('/'));
|
|
80
|
-
resolvedPath = `../${routeDir}/${resolvedPath}`;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Generate unique import name: agent_hello, agent_user, etc.
|
|
84
|
-
const uniqueImportName = `agent_${route.agentVariable}`;
|
|
85
|
-
imports.push(`import type ${uniqueImportName} from '${resolvedPath}';`);
|
|
86
|
-
agentImports.set(route.agentVariable, uniqueImportName);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Track schema variables for potential import from route file
|
|
90
|
-
if (route.inputSchemaVariable) {
|
|
91
|
-
schemaImports.add(route.inputSchemaVariable);
|
|
92
|
-
}
|
|
93
|
-
if (route.outputSchemaVariable) {
|
|
94
|
-
schemaImports.add(route.outputSchemaVariable);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Import schema variables from route files
|
|
99
|
-
const routeFileImports = new Map<string, Set<string>>(); // Maps route file to schema variables
|
|
100
|
-
allRoutes.forEach((route) => {
|
|
101
|
-
// Only import schemas for routes with validators
|
|
102
|
-
if (!route.hasValidator) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (route.inputSchemaVariable || route.outputSchemaVariable) {
|
|
106
|
-
const filename = route.filename.replace(/\\/g, '/');
|
|
107
|
-
const importPath = `../${filename.replace(/\.ts$/, '')}`;
|
|
108
|
-
|
|
109
|
-
if (!routeFileImports.has(importPath)) {
|
|
110
|
-
routeFileImports.set(importPath, new Set());
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (route.inputSchemaVariable) {
|
|
114
|
-
routeFileImports.get(importPath)!.add(route.inputSchemaVariable);
|
|
115
|
-
}
|
|
116
|
-
if (route.outputSchemaVariable) {
|
|
117
|
-
routeFileImports.get(importPath)!.add(route.outputSchemaVariable);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Generate imports for schema variables
|
|
123
|
-
routeFileImports.forEach((schemas, importPath) => {
|
|
124
|
-
const schemaList = Array.from(schemas).join(', ');
|
|
125
|
-
imports.push(`import type { ${schemaList} } from '${importPath}';`);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
const importsStr = imports.join('\n');
|
|
129
|
-
|
|
130
|
-
// Helper function to generate route entry
|
|
131
|
-
const generateRouteEntry = (route: RouteInfo): string => {
|
|
132
|
-
const routeKey = route.path; // Use path only for websocket/sse, or METHOD path for API
|
|
133
|
-
|
|
134
|
-
// If route doesn't have a validator, use never for schemas
|
|
135
|
-
if (!route.hasValidator) {
|
|
136
|
-
const streamValue = route.stream === true ? 'true' : 'false';
|
|
137
|
-
return ` '${routeKey}': {
|
|
138
|
-
inputSchema: never;
|
|
139
|
-
outputSchema: never;
|
|
140
|
-
stream: ${streamValue};
|
|
141
|
-
};`;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// If we have an agent variable, we can infer types from it
|
|
145
|
-
if (route.agentVariable) {
|
|
146
|
-
const importName = agentImports.get(route.agentVariable)!;
|
|
147
|
-
return ` '${routeKey}': {
|
|
148
|
-
inputSchema: typeof ${importName} extends { inputSchema?: infer I } ? I : never;
|
|
149
|
-
outputSchema: typeof ${importName} extends { outputSchema?: infer O } ? O : never;
|
|
150
|
-
stream: typeof ${importName} extends { stream?: infer S } ? S : false;
|
|
151
|
-
};`;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// If we have standalone validator with schema variables
|
|
155
|
-
if (route.inputSchemaVariable || route.outputSchemaVariable) {
|
|
156
|
-
const inputType = route.inputSchemaVariable
|
|
157
|
-
? `typeof ${route.inputSchemaVariable}`
|
|
158
|
-
: 'never';
|
|
159
|
-
const outputType = route.outputSchemaVariable
|
|
160
|
-
? `typeof ${route.outputSchemaVariable}`
|
|
161
|
-
: 'never';
|
|
162
|
-
const streamValue = route.stream === true ? 'true' : 'false';
|
|
163
|
-
return ` '${routeKey}': {
|
|
164
|
-
inputSchema: ${inputType};
|
|
165
|
-
outputSchema: ${outputType};
|
|
166
|
-
stream: ${streamValue};
|
|
167
|
-
};`;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Fall back to any if we can't determine the schema source
|
|
171
|
-
return ` '${routeKey}': {
|
|
172
|
-
// Unable to extract schema types - validator might use inline schemas
|
|
173
|
-
inputSchema: any;
|
|
174
|
-
outputSchema: any;
|
|
175
|
-
};`;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
// Generate RouteRegistry interface (API routes use METHOD path format)
|
|
179
|
-
const apiRouteEntries = apiRoutes
|
|
180
|
-
.map((route) => {
|
|
181
|
-
const routeKey = `${route.method.toUpperCase()} ${route.path}`;
|
|
182
|
-
return generateRouteEntry({ ...route, path: routeKey });
|
|
183
|
-
})
|
|
184
|
-
.join('\n');
|
|
185
|
-
|
|
186
|
-
// Generate WebSocketRouteRegistry (path only, no method)
|
|
187
|
-
const websocketRouteEntries = websocketRoutes.map(generateRouteEntry).join('\n');
|
|
188
|
-
|
|
189
|
-
// Generate SSERouteRegistry (path only, no method)
|
|
190
|
-
const sseRouteEntries = sseRoutes.map(generateRouteEntry).join('\n');
|
|
191
|
-
|
|
192
|
-
const generatedContent = `// Auto-generated by Agentuity - do not edit manually
|
|
193
|
-
${importsStr}
|
|
194
|
-
|
|
195
|
-
// Augment @agentuity/react types with project-specific routes
|
|
196
|
-
declare module '@agentuity/react' {
|
|
197
|
-
export interface RouteRegistry {
|
|
198
|
-
${apiRouteEntries}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
export interface WebSocketRouteRegistry {
|
|
202
|
-
${websocketRouteEntries}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
export interface SSERouteRegistry {
|
|
206
|
-
${sseRouteEntries}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
`;
|
|
210
|
-
|
|
211
|
-
// Get the project root (parent of srcDir)
|
|
212
|
-
const projectRoot = join(srcDir, '..');
|
|
213
|
-
const agentuityDir = join(projectRoot, '.agentuity');
|
|
214
|
-
const registryPath = join(agentuityDir, 'routes.generated.ts');
|
|
215
|
-
|
|
216
|
-
// Ensure .agentuity directory exists
|
|
217
|
-
if (!existsSync(agentuityDir)) {
|
|
218
|
-
mkdirSync(agentuityDir, { recursive: true });
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
writeFileSync(registryPath, generatedContent, 'utf-8');
|
|
222
|
-
}
|