@vurb/core 3.2.3 → 3.3.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/README.md +677 -677
- package/dist/cli/constants.js +59 -59
- package/dist/cli/templates/config.js +26 -26
- package/dist/cli/templates/constants.d.ts +1 -1
- package/dist/cli/templates/constants.d.ts.map +1 -1
- package/dist/cli/templates/constants.js +1 -1
- package/dist/cli/templates/constants.js.map +1 -1
- package/dist/cli/templates/core.d.ts.map +1 -1
- package/dist/cli/templates/core.js +96 -169
- package/dist/cli/templates/core.js.map +1 -1
- package/dist/cli/templates/middleware.js +25 -25
- package/dist/cli/templates/readme.js +142 -142
- package/dist/cli/templates/testing.js +84 -84
- package/dist/cli/templates/tools.js +46 -46
- package/dist/cli/templates/vectors/database.js +69 -69
- package/dist/cli/templates/vectors/oauth.js +63 -63
- package/dist/cli/templates/vectors/openapi.js +97 -97
- package/dist/core/middleware/AuditTrail.d.ts +128 -0
- package/dist/core/middleware/AuditTrail.d.ts.map +1 -0
- package/dist/core/middleware/AuditTrail.js +94 -0
- package/dist/core/middleware/AuditTrail.js.map +1 -0
- package/dist/core/middleware/InputFirewall.d.ts +95 -0
- package/dist/core/middleware/InputFirewall.d.ts.map +1 -0
- package/dist/core/middleware/InputFirewall.js +104 -0
- package/dist/core/middleware/InputFirewall.js.map +1 -0
- package/dist/core/middleware/RateLimiter.d.ts +151 -0
- package/dist/core/middleware/RateLimiter.d.ts.map +1 -0
- package/dist/core/middleware/RateLimiter.js +121 -0
- package/dist/core/middleware/RateLimiter.js.map +1 -0
- package/dist/core/middleware/index.d.ts +6 -0
- package/dist/core/middleware/index.d.ts.map +1 -1
- package/dist/core/middleware/index.js +4 -0
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/index.d.ts +28 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/introspection/SemanticProbe.js +49 -49
- package/dist/observability/TelemetryEvent.d.ts +61 -1
- package/dist/observability/TelemetryEvent.d.ts.map +1 -1
- package/dist/presenter/JudgeChain.d.ts +129 -0
- package/dist/presenter/JudgeChain.d.ts.map +1 -0
- package/dist/presenter/JudgeChain.js +215 -0
- package/dist/presenter/JudgeChain.js.map +1 -0
- package/dist/presenter/PostProcessor.d.ts.map +1 -1
- package/dist/presenter/PostProcessor.js +11 -66
- package/dist/presenter/PostProcessor.js.map +1 -1
- package/dist/presenter/Presenter.d.ts +175 -37
- package/dist/presenter/Presenter.d.ts.map +1 -1
- package/dist/presenter/Presenter.js +265 -154
- package/dist/presenter/Presenter.js.map +1 -1
- package/dist/presenter/PresenterPipeline.d.ts +147 -0
- package/dist/presenter/PresenterPipeline.d.ts.map +1 -0
- package/dist/presenter/PresenterPipeline.js +271 -0
- package/dist/presenter/PresenterPipeline.js.map +1 -0
- package/dist/presenter/PromptFirewall.d.ts +160 -0
- package/dist/presenter/PromptFirewall.d.ts.map +1 -0
- package/dist/presenter/PromptFirewall.js +228 -0
- package/dist/presenter/PromptFirewall.js.map +1 -0
- package/dist/presenter/ResponseBuilder.d.ts +13 -0
- package/dist/presenter/ResponseBuilder.d.ts.map +1 -1
- package/dist/presenter/ResponseBuilder.js +28 -1
- package/dist/presenter/ResponseBuilder.js.map +1 -1
- package/dist/presenter/TelemetryCollector.d.ts +48 -0
- package/dist/presenter/TelemetryCollector.d.ts.map +1 -0
- package/dist/presenter/TelemetryCollector.js +93 -0
- package/dist/presenter/TelemetryCollector.js.map +1 -0
- package/dist/presenter/definePresenter.d.ts +112 -0
- package/dist/presenter/definePresenter.d.ts.map +1 -1
- package/dist/presenter/definePresenter.js +110 -0
- package/dist/presenter/definePresenter.js.map +1 -1
- package/dist/presenter/index.d.ts +6 -2
- package/dist/presenter/index.d.ts.map +1 -1
- package/dist/presenter/index.js +5 -1
- package/dist/presenter/index.js.map +1 -1
- package/dist/presenter/ui.d.ts +31 -8
- package/dist/presenter/ui.d.ts.map +1 -1
- package/dist/presenter/ui.js +16 -16
- package/dist/presenter/ui.js.map +1 -1
- package/dist/prompt/FluentPromptBuilder.d.ts.map +1 -1
- package/dist/resource/ResourceBuilder.d.ts +129 -0
- package/dist/resource/ResourceBuilder.d.ts.map +1 -0
- package/dist/resource/ResourceBuilder.js +93 -0
- package/dist/resource/ResourceBuilder.js.map +1 -0
- package/dist/resource/ResourceRegistry.d.ts +147 -0
- package/dist/resource/ResourceRegistry.d.ts.map +1 -0
- package/dist/resource/ResourceRegistry.js +234 -0
- package/dist/resource/ResourceRegistry.js.map +1 -0
- package/dist/resource/SubscriptionManager.d.ts +67 -0
- package/dist/resource/SubscriptionManager.d.ts.map +1 -0
- package/dist/resource/SubscriptionManager.js +86 -0
- package/dist/resource/SubscriptionManager.js.map +1 -0
- package/dist/resource/index.d.ts +13 -0
- package/dist/resource/index.d.ts.map +1 -0
- package/dist/resource/index.js +13 -0
- package/dist/resource/index.js.map +1 -0
- package/dist/server/ServerAttachment.d.ts +26 -0
- package/dist/server/ServerAttachment.d.ts.map +1 -1
- package/dist/server/ServerAttachment.js +70 -2
- package/dist/server/ServerAttachment.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/startServer.d.ts +22 -1
- package/dist/server/startServer.d.ts.map +1 -1
- package/dist/server/startServer.js +98 -5
- package/dist/server/startServer.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/constants.js
CHANGED
|
@@ -33,64 +33,64 @@ export const VALID_TRANSPORTS = ['stdio', 'sse'];
|
|
|
33
33
|
export const VALID_VECTORS = ['vanilla', 'prisma', 'n8n', 'openapi', 'oauth'];
|
|
34
34
|
// ─── Help Text ───────────────────────────────────────────────────
|
|
35
35
|
/** @internal exported for testing */
|
|
36
|
-
export const HELP = `
|
|
37
|
-
vurb — Vurb CLI
|
|
38
|
-
|
|
39
|
-
USAGE
|
|
40
|
-
vurb create <name> Scaffold a new Vurb server
|
|
41
|
-
vurb dev --server <entry> Start HMR dev server with auto-reload
|
|
42
|
-
vurb lock Generate or update ${LOCKFILE_NAME}
|
|
43
|
-
vurb lock --check Verify lockfile is up to date (CI gate)
|
|
44
|
-
vurb deploy Bundle, compress & deploy to Edge
|
|
45
|
-
vurb remote Show current remote configuration
|
|
46
|
-
vurb inspect Launch the real-time TUI dashboard
|
|
47
|
-
vurb insp --demo Launch TUI with built-in simulator
|
|
48
|
-
|
|
49
|
-
CREATE OPTIONS
|
|
50
|
-
--transport <stdio|sse> Transport layer (default: stdio)
|
|
51
|
-
--vector <type> Ingestion vector: vanilla, prisma, n8n, openapi, oauth
|
|
52
|
-
--testing Include test suite (default: true)
|
|
53
|
-
--no-testing Skip test suite
|
|
54
|
-
--yes, -y Skip prompts, use defaults
|
|
55
|
-
|
|
56
|
-
DEV OPTIONS
|
|
57
|
-
--server, -s <path> Path to server entrypoint (default: auto-detect)
|
|
58
|
-
--dir, -d <path> Directory to watch for changes (default: auto-detect from server)
|
|
59
|
-
|
|
60
|
-
DEPLOY OPTIONS
|
|
61
|
-
--server, -s <path> Path to server entrypoint (default: auto-detect)
|
|
62
|
-
--token <token> Override VURB_DEPLOY_TOKEN (connection token)
|
|
63
|
-
--allow-insecure Suppress HTTP plaintext warning
|
|
64
|
-
|
|
65
|
-
REMOTE OPTIONS
|
|
66
|
-
vurb remote <url> Override API endpoint (default: Vinkius Cloud)
|
|
67
|
-
vurb remote --server-id <id> Set target server UUID
|
|
68
|
-
|
|
69
|
-
INSPECTOR OPTIONS
|
|
70
|
-
--demo, -d Launch with built-in simulator (no server needed)
|
|
71
|
-
--out, -o <mode> Output: tui (default), stderr (headless ECS/K8s)
|
|
72
|
-
--pid, -p <pid> Connect to a specific server PID
|
|
73
|
-
--path <path> Custom IPC socket/pipe path
|
|
74
|
-
|
|
75
|
-
LOCK OPTIONS
|
|
76
|
-
--server, -s <path> Path to server entrypoint
|
|
77
|
-
--name, -n <name> Server name for lockfile header
|
|
78
|
-
--cwd <dir> Project root directory
|
|
79
|
-
|
|
80
|
-
GLOBAL
|
|
81
|
-
--help, -h Show this help message
|
|
82
|
-
|
|
83
|
-
EXAMPLES
|
|
84
|
-
vurb create my-server
|
|
85
|
-
vurb create my-server -y
|
|
86
|
-
vurb create my-server --vector prisma --transport sse
|
|
87
|
-
vurb dev --server ./src/server.ts
|
|
88
|
-
vurb dev --server ./src/server.ts --dir ./src/tools
|
|
89
|
-
vurb lock --server ./src/server.ts
|
|
90
|
-
vurb deploy
|
|
91
|
-
vurb remote --server-id abc-123-def
|
|
92
|
-
vurb remote http://localhost:8080 --server-id abc-123-def
|
|
93
|
-
vurb inspect --demo
|
|
94
|
-
vurb insp --pid 12345
|
|
36
|
+
export const HELP = `
|
|
37
|
+
vurb — Vurb CLI
|
|
38
|
+
|
|
39
|
+
USAGE
|
|
40
|
+
vurb create <name> Scaffold a new Vurb server
|
|
41
|
+
vurb dev --server <entry> Start HMR dev server with auto-reload
|
|
42
|
+
vurb lock Generate or update ${LOCKFILE_NAME}
|
|
43
|
+
vurb lock --check Verify lockfile is up to date (CI gate)
|
|
44
|
+
vurb deploy Bundle, compress & deploy to Edge
|
|
45
|
+
vurb remote Show current remote configuration
|
|
46
|
+
vurb inspect Launch the real-time TUI dashboard
|
|
47
|
+
vurb insp --demo Launch TUI with built-in simulator
|
|
48
|
+
|
|
49
|
+
CREATE OPTIONS
|
|
50
|
+
--transport <stdio|sse> Transport layer (default: stdio)
|
|
51
|
+
--vector <type> Ingestion vector: vanilla, prisma, n8n, openapi, oauth
|
|
52
|
+
--testing Include test suite (default: true)
|
|
53
|
+
--no-testing Skip test suite
|
|
54
|
+
--yes, -y Skip prompts, use defaults
|
|
55
|
+
|
|
56
|
+
DEV OPTIONS
|
|
57
|
+
--server, -s <path> Path to server entrypoint (default: auto-detect)
|
|
58
|
+
--dir, -d <path> Directory to watch for changes (default: auto-detect from server)
|
|
59
|
+
|
|
60
|
+
DEPLOY OPTIONS
|
|
61
|
+
--server, -s <path> Path to server entrypoint (default: auto-detect)
|
|
62
|
+
--token <token> Override VURB_DEPLOY_TOKEN (connection token)
|
|
63
|
+
--allow-insecure Suppress HTTP plaintext warning
|
|
64
|
+
|
|
65
|
+
REMOTE OPTIONS
|
|
66
|
+
vurb remote <url> Override API endpoint (default: Vinkius Cloud)
|
|
67
|
+
vurb remote --server-id <id> Set target server UUID
|
|
68
|
+
|
|
69
|
+
INSPECTOR OPTIONS
|
|
70
|
+
--demo, -d Launch with built-in simulator (no server needed)
|
|
71
|
+
--out, -o <mode> Output: tui (default), stderr (headless ECS/K8s)
|
|
72
|
+
--pid, -p <pid> Connect to a specific server PID
|
|
73
|
+
--path <path> Custom IPC socket/pipe path
|
|
74
|
+
|
|
75
|
+
LOCK OPTIONS
|
|
76
|
+
--server, -s <path> Path to server entrypoint
|
|
77
|
+
--name, -n <name> Server name for lockfile header
|
|
78
|
+
--cwd <dir> Project root directory
|
|
79
|
+
|
|
80
|
+
GLOBAL
|
|
81
|
+
--help, -h Show this help message
|
|
82
|
+
|
|
83
|
+
EXAMPLES
|
|
84
|
+
vurb create my-server
|
|
85
|
+
vurb create my-server -y
|
|
86
|
+
vurb create my-server --vector prisma --transport sse
|
|
87
|
+
vurb dev --server ./src/server.ts
|
|
88
|
+
vurb dev --server ./src/server.ts --dir ./src/tools
|
|
89
|
+
vurb lock --server ./src/server.ts
|
|
90
|
+
vurb deploy
|
|
91
|
+
vurb remote --server-id abc-123-def
|
|
92
|
+
vurb remote http://localhost:8080 --server-id abc-123-def
|
|
93
|
+
vurb inspect --demo
|
|
94
|
+
vurb insp --pid 12345
|
|
95
95
|
`.trim();
|
|
96
96
|
//# sourceMappingURL=constants.js.map
|
|
@@ -85,47 +85,47 @@ export function tsconfig() {
|
|
|
85
85
|
}
|
|
86
86
|
/** Generate `.gitignore` */
|
|
87
87
|
export function gitignore() {
|
|
88
|
-
return `node_modules/
|
|
89
|
-
dist/
|
|
90
|
-
*.tsbuildinfo
|
|
91
|
-
.env
|
|
92
|
-
.env.local
|
|
93
|
-
coverage/
|
|
88
|
+
return `node_modules/
|
|
89
|
+
dist/
|
|
90
|
+
*.tsbuildinfo
|
|
91
|
+
.env
|
|
92
|
+
.env.local
|
|
93
|
+
coverage/
|
|
94
94
|
`;
|
|
95
95
|
}
|
|
96
96
|
/** Generate `.env.example` with vector-specific vars */
|
|
97
97
|
export function envExample(config) {
|
|
98
|
-
let env = `# ── Vurb Server Environment ─────────────────────
|
|
99
|
-
# Copy this to .env and fill in your values.
|
|
100
|
-
|
|
101
|
-
# Server
|
|
102
|
-
NODE_ENV=development
|
|
98
|
+
let env = `# ── Vurb Server Environment ─────────────────────
|
|
99
|
+
# Copy this to .env and fill in your values.
|
|
100
|
+
|
|
101
|
+
# Server
|
|
102
|
+
NODE_ENV=development
|
|
103
103
|
`;
|
|
104
104
|
if (config.vector === 'prisma') {
|
|
105
|
-
env += `
|
|
106
|
-
# Database (Prisma)
|
|
107
|
-
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
|
|
105
|
+
env += `
|
|
106
|
+
# Database (Prisma)
|
|
107
|
+
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
|
|
108
108
|
`;
|
|
109
109
|
}
|
|
110
110
|
if (config.vector === 'n8n') {
|
|
111
|
-
env += `
|
|
112
|
-
# n8n Workflow Automation
|
|
113
|
-
N8N_BASE_URL=http://localhost:5678
|
|
114
|
-
N8N_API_KEY=your-api-key-here
|
|
111
|
+
env += `
|
|
112
|
+
# n8n Workflow Automation
|
|
113
|
+
N8N_BASE_URL=http://localhost:5678
|
|
114
|
+
N8N_API_KEY=your-api-key-here
|
|
115
115
|
`;
|
|
116
116
|
}
|
|
117
117
|
if (config.vector === 'oauth') {
|
|
118
|
-
env += `
|
|
119
|
-
# OAuth Device Flow (RFC 8628)
|
|
120
|
-
OAUTH_CLIENT_ID=your-client-id
|
|
121
|
-
OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
|
|
122
|
-
OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
|
|
118
|
+
env += `
|
|
119
|
+
# OAuth Device Flow (RFC 8628)
|
|
120
|
+
OAUTH_CLIENT_ID=your-client-id
|
|
121
|
+
OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
|
|
122
|
+
OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
|
|
123
123
|
`;
|
|
124
124
|
}
|
|
125
125
|
if (config.transport === 'sse') {
|
|
126
|
-
env += `
|
|
127
|
-
# Streamable HTTP Transport
|
|
128
|
-
PORT=3001
|
|
126
|
+
env += `
|
|
127
|
+
# Streamable HTTP Transport
|
|
128
|
+
PORT=3001
|
|
129
129
|
`;
|
|
130
130
|
}
|
|
131
131
|
return env;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Template Constants — Version pins for generated package.json
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
export declare const CORE_VERSION = "^2.
|
|
5
|
+
export declare const CORE_VERSION = "^3.2.0";
|
|
6
6
|
export declare const TESTING_VERSION = "^1.0.0";
|
|
7
7
|
export declare const MCP_SDK_VERSION = "^1.12.1";
|
|
8
8
|
export declare const ZOD_VERSION = "^3.25.1";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,eAAe,WAAW,CAAC;AACxC,eAAO,MAAM,eAAe,YAAY,CAAC;AACzC,eAAO,MAAM,WAAW,YAAY,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Template Constants — Version pins for generated package.json
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
export const CORE_VERSION = '^2.
|
|
5
|
+
export const CORE_VERSION = '^3.2.0';
|
|
6
6
|
export const TESTING_VERSION = '^1.0.0';
|
|
7
7
|
export const MCP_SDK_VERSION = '^1.12.1';
|
|
8
8
|
export const ZOD_VERSION = '^3.25.1';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/cli/templates/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/cli/templates/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,2DAA2D;AAC3D,wBAAgB,MAAM,IAAI,MAAM,CAa/B;AAED,qEAAqE;AACrE,wBAAgB,SAAS,IAAI,MAAM,CA8BlC;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,2DAA2D;AAC3D,wBAAgB,MAAM,IAAI,MAAM,CAa/B;AAED,qEAAqE;AACrE,wBAAgB,SAAS,IAAI,MAAM,CA8BlC;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAgEtD"}
|
|
@@ -1,186 +1,113 @@
|
|
|
1
1
|
/** Generate `src/vurb.ts` — The one-file context center */
|
|
2
2
|
export function vurbTs() {
|
|
3
|
-
return `/**
|
|
4
|
-
* Vurb Instance — Context Initialization
|
|
5
|
-
*
|
|
6
|
-
* Define your context type ONCE. Every f.query(), f.mutation(),
|
|
7
|
-
* f.presenter(), f.prompt(), and f.middleware() call inherits
|
|
8
|
-
* AppContext — zero generic repetition anywhere in the codebase.
|
|
9
|
-
*/
|
|
10
|
-
import { initVurb } from '@vurb/core';
|
|
11
|
-
import type { AppContext } from './context.js';
|
|
12
|
-
|
|
13
|
-
export const f = initVurb<AppContext>();
|
|
3
|
+
return `/**
|
|
4
|
+
* Vurb Instance — Context Initialization
|
|
5
|
+
*
|
|
6
|
+
* Define your context type ONCE. Every f.query(), f.mutation(),
|
|
7
|
+
* f.presenter(), f.prompt(), and f.middleware() call inherits
|
|
8
|
+
* AppContext — zero generic repetition anywhere in the codebase.
|
|
9
|
+
*/
|
|
10
|
+
import { initVurb } from '@vurb/core';
|
|
11
|
+
import type { AppContext } from './context.js';
|
|
12
|
+
|
|
13
|
+
export const f = initVurb<AppContext>();
|
|
14
14
|
`;
|
|
15
15
|
}
|
|
16
16
|
/** Generate `src/context.ts` — Application context type + factory */
|
|
17
17
|
export function contextTs() {
|
|
18
|
-
return `/**
|
|
19
|
-
* Application Context — Shared State for Every Tool Handler
|
|
20
|
-
*
|
|
21
|
-
* Every f.query() / f.mutation() handler receives (input, ctx)
|
|
22
|
-
* where ctx is this AppContext. Extend it with your own services
|
|
23
|
-
* (DB client, auth, external APIs, etc.)
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
export interface AppContext {
|
|
27
|
-
/** Current user role for RBAC checks */
|
|
28
|
-
role: 'ADMIN' | 'USER' | 'GUEST';
|
|
29
|
-
|
|
30
|
-
/** Tenant identifier (multi-tenancy) */
|
|
31
|
-
tenantId: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Create the application context for each tool invocation.
|
|
36
|
-
*
|
|
37
|
-
* In production, hydrate this from the MCP session metadata,
|
|
38
|
-
* JWT tokens, or environment variables.
|
|
39
|
-
*/
|
|
40
|
-
export function createContext(): AppContext {
|
|
41
|
-
return {
|
|
42
|
-
role: 'ADMIN',
|
|
43
|
-
tenantId: 'default',
|
|
44
|
-
};
|
|
45
|
-
}
|
|
18
|
+
return `/**
|
|
19
|
+
* Application Context — Shared State for Every Tool Handler
|
|
20
|
+
*
|
|
21
|
+
* Every f.query() / f.mutation() handler receives (input, ctx)
|
|
22
|
+
* where ctx is this AppContext. Extend it with your own services
|
|
23
|
+
* (DB client, auth, external APIs, etc.)
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export interface AppContext {
|
|
27
|
+
/** Current user role for RBAC checks */
|
|
28
|
+
role: 'ADMIN' | 'USER' | 'GUEST';
|
|
29
|
+
|
|
30
|
+
/** Tenant identifier (multi-tenancy) */
|
|
31
|
+
tenantId: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Create the application context for each tool invocation.
|
|
36
|
+
*
|
|
37
|
+
* In production, hydrate this from the MCP session metadata,
|
|
38
|
+
* JWT tokens, or environment variables.
|
|
39
|
+
*/
|
|
40
|
+
export function createContext(): AppContext {
|
|
41
|
+
return {
|
|
42
|
+
role: 'ADMIN',
|
|
43
|
+
tenantId: 'default',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
46
|
`;
|
|
47
47
|
}
|
|
48
48
|
/** Generate `src/server.ts` — Bootstrap with autoDiscover + transport */
|
|
49
49
|
export function serverTs(config) {
|
|
50
50
|
if (config.transport === 'stdio') {
|
|
51
51
|
// Simplified: one-liner bootstrap via startServer()
|
|
52
|
-
return `/**
|
|
53
|
-
* Server Bootstrap — Vurb
|
|
54
|
-
*
|
|
55
|
-
* Tools are auto-discovered from src/tools/.
|
|
56
|
-
* Drop a file, it becomes a tool.
|
|
57
|
-
*/
|
|
58
|
-
import { fileURLToPath } from 'node:url';
|
|
59
|
-
import { autoDiscover, PromptRegistry, startServer } from '@vurb/core';
|
|
60
|
-
import { createContext } from './context.js';
|
|
61
|
-
import { f } from './vurb.js';
|
|
62
|
-
import { GreetPrompt } from './prompts/greet.js';
|
|
63
|
-
|
|
64
|
-
// ── Registry ─────────────────────────────────────────────
|
|
65
|
-
const registry = f.registry();
|
|
66
|
-
const prompts = new PromptRegistry();
|
|
67
|
-
|
|
68
|
-
// ── Auto-Discover & Register ─────────────────────────────
|
|
69
|
-
await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
|
|
70
|
-
prompts.register(GreetPrompt);
|
|
71
|
-
|
|
72
|
-
// ── Start ────────────────────────────────────────────────
|
|
73
|
-
await startServer({
|
|
74
|
-
name: '${config.name}',
|
|
75
|
-
registry,
|
|
76
|
-
prompts,
|
|
77
|
-
contextFactory: () => createContext(),
|
|
78
|
-
});
|
|
52
|
+
return `/**
|
|
53
|
+
* Server Bootstrap — Vurb
|
|
54
|
+
*
|
|
55
|
+
* Tools are auto-discovered from src/tools/.
|
|
56
|
+
* Drop a file, it becomes a tool.
|
|
57
|
+
*/
|
|
58
|
+
import { fileURLToPath } from 'node:url';
|
|
59
|
+
import { autoDiscover, PromptRegistry, startServer } from '@vurb/core';
|
|
60
|
+
import { createContext } from './context.js';
|
|
61
|
+
import { f } from './vurb.js';
|
|
62
|
+
import { GreetPrompt } from './prompts/greet.js';
|
|
63
|
+
|
|
64
|
+
// ── Registry ─────────────────────────────────────────────
|
|
65
|
+
const registry = f.registry();
|
|
66
|
+
const prompts = new PromptRegistry();
|
|
67
|
+
|
|
68
|
+
// ── Auto-Discover & Register ─────────────────────────────
|
|
69
|
+
await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
|
|
70
|
+
prompts.register(GreetPrompt);
|
|
71
|
+
|
|
72
|
+
// ── Start ────────────────────────────────────────────────
|
|
73
|
+
await startServer({
|
|
74
|
+
name: '${config.name}',
|
|
75
|
+
registry,
|
|
76
|
+
prompts,
|
|
77
|
+
contextFactory: () => createContext(),
|
|
78
|
+
});
|
|
79
79
|
`;
|
|
80
80
|
}
|
|
81
|
-
// Streamable HTTP transport —
|
|
82
|
-
return `/**
|
|
83
|
-
* Server Bootstrap — Vurb with Streamable HTTP Transport
|
|
84
|
-
*
|
|
85
|
-
* Tools are auto-discovered from src/tools/.
|
|
86
|
-
* Drop a file, it becomes a tool.
|
|
87
|
-
*/
|
|
88
|
-
import { fileURLToPath } from 'node:url';
|
|
89
|
-
import {
|
|
90
|
-
import {
|
|
91
|
-
import {
|
|
92
|
-
import {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
contextFactory: () => createContext(),
|
|
112
|
-
prompts,
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// ── Transport ────────────────────────────────────────────
|
|
116
|
-
const PORT = Number(process.env['PORT'] ?? 3001);
|
|
117
|
-
const sessions = new Map<string, StreamableHTTPServerTransport>();
|
|
118
|
-
|
|
119
|
-
const httpServer = createServer(async (req, res) => {
|
|
120
|
-
try {
|
|
121
|
-
const url = new URL(req.url ?? '/', \`http://localhost:\${PORT}\`);
|
|
122
|
-
|
|
123
|
-
if (url.pathname !== '/mcp') {
|
|
124
|
-
res.writeHead(404).end();
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (req.method === 'POST') {
|
|
129
|
-
// Parse JSON body
|
|
130
|
-
const chunks: Buffer[] = [];
|
|
131
|
-
for await (const chunk of req) chunks.push(chunk as Buffer);
|
|
132
|
-
const body = JSON.parse(Buffer.concat(chunks).toString());
|
|
133
|
-
|
|
134
|
-
const sessionId = req.headers['mcp-session-id'] as string | undefined;
|
|
135
|
-
|
|
136
|
-
// Existing session — route to its transport
|
|
137
|
-
if (sessionId && sessions.has(sessionId)) {
|
|
138
|
-
const transport = sessions.get(sessionId)!;
|
|
139
|
-
await transport.handleRequest(req, res, body);
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// New session — create transport
|
|
144
|
-
const transport = new StreamableHTTPServerTransport({
|
|
145
|
-
sessionIdGenerator: () => crypto.randomUUID(),
|
|
146
|
-
onsessioninitialized: (id) => {
|
|
147
|
-
sessions.set(id, transport);
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
|
-
transport.onclose = () => {
|
|
151
|
-
const id = [...sessions.entries()].find(([, t]) => t === transport)?.[0];
|
|
152
|
-
if (id) sessions.delete(id);
|
|
153
|
-
};
|
|
154
|
-
await server.connect(transport);
|
|
155
|
-
await transport.handleRequest(req, res, body);
|
|
156
|
-
} else if (req.method === 'GET') {
|
|
157
|
-
const sessionId = req.headers['mcp-session-id'] as string | undefined;
|
|
158
|
-
if (sessionId && sessions.has(sessionId)) {
|
|
159
|
-
const transport = sessions.get(sessionId)!;
|
|
160
|
-
await transport.handleRequest(req, res);
|
|
161
|
-
} else {
|
|
162
|
-
res.writeHead(400).end('Missing or invalid session');
|
|
163
|
-
}
|
|
164
|
-
} else if (req.method === 'DELETE') {
|
|
165
|
-
const sessionId = req.headers['mcp-session-id'] as string | undefined;
|
|
166
|
-
if (sessionId && sessions.has(sessionId)) {
|
|
167
|
-
const transport = sessions.get(sessionId)!;
|
|
168
|
-
await transport.handleRequest(req, res);
|
|
169
|
-
} else {
|
|
170
|
-
res.writeHead(400).end('Missing or invalid session');
|
|
171
|
-
}
|
|
172
|
-
} else {
|
|
173
|
-
res.writeHead(405).end();
|
|
174
|
-
}
|
|
175
|
-
} catch (err) {
|
|
176
|
-
console.error('[Vurb] Unhandled error in HTTP handler:', err);
|
|
177
|
-
if (!res.headersSent) res.writeHead(500).end();
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
httpServer.listen(PORT, () => {
|
|
182
|
-
console.error(\`⚡ Vurb server on http://localhost:\${PORT}/mcp\`);
|
|
183
|
-
});
|
|
81
|
+
// Streamable HTTP transport — startServer handles all HTTP plumbing
|
|
82
|
+
return `/**
|
|
83
|
+
* Server Bootstrap — Vurb with Streamable HTTP Transport
|
|
84
|
+
*
|
|
85
|
+
* Tools are auto-discovered from src/tools/.
|
|
86
|
+
* Drop a file, it becomes a tool.
|
|
87
|
+
*/
|
|
88
|
+
import { fileURLToPath } from 'node:url';
|
|
89
|
+
import { autoDiscover, PromptRegistry, startServer } from '@vurb/core';
|
|
90
|
+
import { createContext } from './context.js';
|
|
91
|
+
import { f } from './vurb.js';
|
|
92
|
+
import { GreetPrompt } from './prompts/greet.js';
|
|
93
|
+
|
|
94
|
+
// ── Registry ─────────────────────────────────────────────
|
|
95
|
+
const registry = f.registry();
|
|
96
|
+
const prompts = new PromptRegistry();
|
|
97
|
+
|
|
98
|
+
// ── Auto-Discover & Register ─────────────────────────────
|
|
99
|
+
await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
|
|
100
|
+
prompts.register(GreetPrompt);
|
|
101
|
+
|
|
102
|
+
// ── Start ────────────────────────────────────────────────
|
|
103
|
+
await startServer({
|
|
104
|
+
name: '${config.name}',
|
|
105
|
+
registry,
|
|
106
|
+
prompts,
|
|
107
|
+
contextFactory: () => createContext(),
|
|
108
|
+
transport: 'http',
|
|
109
|
+
port: Number(process.env['PORT'] ?? 3001),
|
|
110
|
+
});
|
|
184
111
|
`;
|
|
185
112
|
}
|
|
186
113
|
//# sourceMappingURL=core.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/cli/templates/core.ts"],"names":[],"mappings":"AAQA,2DAA2D;AAC3D,MAAM,UAAU,MAAM;IAClB,OAAO;;;;;;;;;;;CAWV,CAAC;AACF,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,SAAS;IACrB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BV,CAAC;AACF,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,QAAQ,CAAC,MAAqB;IAC1C,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QAC/B,oDAAoD;QACpD,OAAO;;;;;;;;;;;;;;;;;;;;;;aAsBF,MAAM,CAAC,IAAI;;;;;CAKvB,CAAC;IACE,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/cli/templates/core.ts"],"names":[],"mappings":"AAQA,2DAA2D;AAC3D,MAAM,UAAU,MAAM;IAClB,OAAO;;;;;;;;;;;CAWV,CAAC;AACF,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,SAAS;IACrB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BV,CAAC;AACF,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,QAAQ,CAAC,MAAqB;IAC1C,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QAC/B,oDAAoD;QACpD,OAAO;;;;;;;;;;;;;;;;;;;;;;aAsBF,MAAM,CAAC,IAAI;;;;;CAKvB,CAAC;IACE,CAAC;IAED,oEAAoE;IACpE,OAAO;;;;;;;;;;;;;;;;;;;;;;aAsBE,MAAM,CAAC,IAAI;;;;;;;CAOvB,CAAC;AACF,CAAC"}
|
|
@@ -4,31 +4,31 @@
|
|
|
4
4
|
*/
|
|
5
5
|
/** Generate `src/middleware/auth.ts` — RBAC middleware */
|
|
6
6
|
export function authMiddlewareTs() {
|
|
7
|
-
return `/**
|
|
8
|
-
* Auth Middleware — RBAC Guard (Fluent API)
|
|
9
|
-
*
|
|
10
|
-
* Demonstrates f.middleware() — tRPC-style context derivation.
|
|
11
|
-
* Rejects GUEST requests with a structured error.
|
|
12
|
-
*
|
|
13
|
-
* Usage in tools:
|
|
14
|
-
* f.query('users.list')
|
|
15
|
-
* .use(withAuth)
|
|
16
|
-
* .handle(async (input, ctx) => {
|
|
17
|
-
* // ctx now has ctx.role guaranteed non-GUEST
|
|
18
|
-
* });
|
|
19
|
-
*
|
|
20
|
-
* In production, replace with JWT validation,
|
|
21
|
-
* API key checks, or OAuth token verification.
|
|
22
|
-
*/
|
|
23
|
-
import { f } from '../vurb.js';
|
|
24
|
-
import { error } from '@vurb/core';
|
|
25
|
-
|
|
26
|
-
export const withAuth = f.middleware(async (ctx) => {
|
|
27
|
-
if (ctx.role === 'GUEST') {
|
|
28
|
-
throw error('Access denied. Authentication required.');
|
|
29
|
-
}
|
|
30
|
-
return { verified: true as const };
|
|
31
|
-
});
|
|
7
|
+
return `/**
|
|
8
|
+
* Auth Middleware — RBAC Guard (Fluent API)
|
|
9
|
+
*
|
|
10
|
+
* Demonstrates f.middleware() — tRPC-style context derivation.
|
|
11
|
+
* Rejects GUEST requests with a structured error.
|
|
12
|
+
*
|
|
13
|
+
* Usage in tools:
|
|
14
|
+
* f.query('users.list')
|
|
15
|
+
* .use(withAuth)
|
|
16
|
+
* .handle(async (input, ctx) => {
|
|
17
|
+
* // ctx now has ctx.role guaranteed non-GUEST
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* In production, replace with JWT validation,
|
|
21
|
+
* API key checks, or OAuth token verification.
|
|
22
|
+
*/
|
|
23
|
+
import { f } from '../vurb.js';
|
|
24
|
+
import { error } from '@vurb/core';
|
|
25
|
+
|
|
26
|
+
export const withAuth = f.middleware(async (ctx) => {
|
|
27
|
+
if (ctx.role === 'GUEST') {
|
|
28
|
+
throw error('Access denied. Authentication required.');
|
|
29
|
+
}
|
|
30
|
+
return { verified: true as const };
|
|
31
|
+
});
|
|
32
32
|
`;
|
|
33
33
|
}
|
|
34
34
|
//# sourceMappingURL=middleware.js.map
|