@jaypie/mcp 0.2.0 → 0.2.2
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/dist/index.js +1 -1
- package/package.json +2 -2
- package/prompts/Jaypie_Repokit.md +103 -0
- package/prompts/Jaypie_Vocabulary_Package.md +451 -0
package/dist/index.js
CHANGED
|
@@ -797,7 +797,7 @@ async function searchDatadogRum(credentials, options = {}, logger = nullLogger)
|
|
|
797
797
|
});
|
|
798
798
|
}
|
|
799
799
|
|
|
800
|
-
const BUILD_VERSION_STRING = "@jaypie/mcp@0.2.
|
|
800
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.2.2#fd3043b3"
|
|
801
801
|
;
|
|
802
802
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
803
803
|
const __dirname$1 = path.dirname(__filename$1);
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaypie/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Jaypie MCP",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
|
-
"url": "https://github.com/finlaysonstudio/jaypie"
|
|
7
|
+
"url": "git+https://github.com/finlaysonstudio/jaypie.git"
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"author": "Finlayson Studio",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: development utilities bundle for Jaypie repositories
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Jaypie Repokit
|
|
6
|
+
|
|
7
|
+
Essential development utilities bundled for Jaypie repositories. Provides common tools needed for build scripts, development workflows, and repository maintenance.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install --save-dev @jaypie/repokit
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Exported Utilities
|
|
16
|
+
|
|
17
|
+
### dotenv
|
|
18
|
+
|
|
19
|
+
Re-exports everything from `dotenv` for environment variable management.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { config } from "@jaypie/repokit";
|
|
23
|
+
|
|
24
|
+
config(); // Load .env file
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### rimraf
|
|
28
|
+
|
|
29
|
+
Re-exports `rimraf` for cross-platform file deletion.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { rimraf } from "@jaypie/repokit";
|
|
33
|
+
|
|
34
|
+
await rimraf("./dist");
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## CLI Tools (via npx)
|
|
38
|
+
|
|
39
|
+
The package includes CLI tools as dependencies that can be run via npx or in package.json scripts:
|
|
40
|
+
|
|
41
|
+
### env-cmd
|
|
42
|
+
|
|
43
|
+
Run commands with environment variables from a file.
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"scripts": {
|
|
48
|
+
"start:dev": "env-cmd -f .env.development node server.js"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### sort-package-json
|
|
54
|
+
|
|
55
|
+
Sort package.json files for consistent formatting.
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"scripts": {
|
|
60
|
+
"format:package": "sort-package-json ./package.json"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### tsx
|
|
66
|
+
|
|
67
|
+
Run TypeScript files directly without compilation.
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"scripts": {
|
|
72
|
+
"bin:script": "tsx scripts/my-script.ts"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Common Usage Patterns
|
|
78
|
+
|
|
79
|
+
### Build Scripts
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"scripts": {
|
|
84
|
+
"clean": "rimraf ./dist",
|
|
85
|
+
"format:package": "sort-package-json ./package.json",
|
|
86
|
+
"bin:setup": "tsx scripts/setup.ts"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Environment Management
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// scripts/deploy.ts
|
|
95
|
+
import { config } from "@jaypie/repokit";
|
|
96
|
+
|
|
97
|
+
config({ path: ".env.production" });
|
|
98
|
+
console.log(process.env.API_KEY);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Why Use Repokit
|
|
102
|
+
|
|
103
|
+
Instead of installing `dotenv`, `rimraf`, `env-cmd`, `sort-package-json`, and `tsx` individually in each package, install `@jaypie/repokit` once to get all essential development utilities. This ensures consistent versions across all Jaypie repositories.
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Complete guide to using Jaypie Vocabulary for type coercion, service handlers, and Commander CLI integration
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Jaypie Vocabulary Package
|
|
6
|
+
|
|
7
|
+
Jaypie Vocabulary (`@jaypie/vocabulary`) provides type coercion utilities and service handler patterns for consistent input handling across Jaypie applications. It includes adapters for integrating service handlers with Commander.js CLIs.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @jaypie/vocabulary
|
|
13
|
+
# For CLI integration:
|
|
14
|
+
npm install commander
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Core Concepts
|
|
18
|
+
|
|
19
|
+
### Design Philosophy
|
|
20
|
+
|
|
21
|
+
Vocabulary follows the "Fabric" philosophy:
|
|
22
|
+
- **Smooth, pliable** - Things that feel right should work
|
|
23
|
+
- **Catch bad passes** - Invalid inputs throw clear errors
|
|
24
|
+
|
|
25
|
+
This means `"true"` works where `true` is expected, `"42"` works where `42` is expected, and invalid conversions fail fast with `BadRequestError`.
|
|
26
|
+
|
|
27
|
+
## serviceHandler
|
|
28
|
+
|
|
29
|
+
Factory function that creates validated service endpoints with automatic type coercion.
|
|
30
|
+
|
|
31
|
+
### Basic Usage
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { serviceHandler } from "@jaypie/vocabulary";
|
|
35
|
+
|
|
36
|
+
const divisionHandler = serviceHandler({
|
|
37
|
+
alias: "division",
|
|
38
|
+
description: "Divides two numbers",
|
|
39
|
+
input: {
|
|
40
|
+
numerator: {
|
|
41
|
+
type: Number,
|
|
42
|
+
default: 12,
|
|
43
|
+
description: "Number on top",
|
|
44
|
+
},
|
|
45
|
+
denominator: {
|
|
46
|
+
type: Number,
|
|
47
|
+
default: 3,
|
|
48
|
+
description: "Number on bottom",
|
|
49
|
+
validate: (value) => value !== 0,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
service: ({ numerator, denominator }) => numerator / denominator,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
await divisionHandler(); // → 4
|
|
56
|
+
await divisionHandler({ numerator: 24 }); // → 8
|
|
57
|
+
await divisionHandler({ numerator: "14", denominator: "7" }); // → 2 (coerced)
|
|
58
|
+
await divisionHandler('{"numerator": "18"}'); // → 6 (JSON parsed)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Handler Properties
|
|
62
|
+
|
|
63
|
+
Config properties are attached directly to the handler for introspection:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const handler = serviceHandler({
|
|
67
|
+
alias: "greet",
|
|
68
|
+
description: "Greet a user",
|
|
69
|
+
input: { name: { type: String } },
|
|
70
|
+
service: ({ name }) => `Hello, ${name}!`,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
handler.alias; // "greet"
|
|
74
|
+
handler.description; // "Greet a user"
|
|
75
|
+
handler.input; // { name: { type: String } }
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Input Field Definition
|
|
79
|
+
|
|
80
|
+
| Property | Type | Description |
|
|
81
|
+
|----------|------|-------------|
|
|
82
|
+
| `type` | `CoercionType` | Required. The target type for coercion |
|
|
83
|
+
| `default` | `unknown` | Default value if not provided |
|
|
84
|
+
| `description` | `string` | Field description (used in CLI help) |
|
|
85
|
+
| `required` | `boolean` | Whether field is required (default: true unless default set) |
|
|
86
|
+
| `validate` | `function \| RegExp \| array` | Validation after coercion |
|
|
87
|
+
| `flag` | `string` | Override long flag name for Commander.js |
|
|
88
|
+
| `letter` | `string` | Short switch letter for Commander.js |
|
|
89
|
+
|
|
90
|
+
### Validation-Only Mode
|
|
91
|
+
|
|
92
|
+
When no `service` function is provided, the handler returns the processed input:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
const validateUser = serviceHandler({
|
|
96
|
+
input: {
|
|
97
|
+
age: { type: Number, validate: (v) => v >= 18 },
|
|
98
|
+
email: { type: /^[^@]+@[^@]+\.[^@]+$/ },
|
|
99
|
+
role: { type: ["admin", "user", "guest"], default: "user" },
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
await validateUser({ age: "25", email: "bob@example.com" });
|
|
104
|
+
// → { age: 25, email: "bob@example.com", role: "user" }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Type Coercion
|
|
108
|
+
|
|
109
|
+
### Supported Types
|
|
110
|
+
|
|
111
|
+
| Type | Aliases | Description |
|
|
112
|
+
|------|---------|-------------|
|
|
113
|
+
| `String` | `"string"`, `""` | String coercion |
|
|
114
|
+
| `Number` | `"number"` | Number coercion |
|
|
115
|
+
| `Boolean` | `"boolean"` | Boolean coercion |
|
|
116
|
+
| `Array` | `"array"`, `[]` | Array coercion |
|
|
117
|
+
| `Object` | `"object"`, `{}` | Object coercion |
|
|
118
|
+
| `[String]` | `[""]` | Typed array of strings |
|
|
119
|
+
| `[Number]` | - | Typed array of numbers |
|
|
120
|
+
| `[Boolean]` | - | Typed array of booleans |
|
|
121
|
+
| `[Object]` | `[{}]` | Typed array of objects |
|
|
122
|
+
| `/regex/` | - | String with regex validation |
|
|
123
|
+
| `["a", "b"]` | - | Validated string (must match) |
|
|
124
|
+
| `[1, 2, 3]` | - | Validated number (must match) |
|
|
125
|
+
|
|
126
|
+
### Coercion Examples
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { coerce } from "@jaypie/vocabulary";
|
|
130
|
+
|
|
131
|
+
// Boolean coercion
|
|
132
|
+
coerce("true", Boolean); // → true
|
|
133
|
+
coerce("false", Boolean); // → false
|
|
134
|
+
coerce(1, Boolean); // → true
|
|
135
|
+
coerce(0, Boolean); // → false
|
|
136
|
+
|
|
137
|
+
// Number coercion
|
|
138
|
+
coerce("42", Number); // → 42
|
|
139
|
+
coerce("true", Number); // → 1
|
|
140
|
+
coerce("false", Number); // → 0
|
|
141
|
+
|
|
142
|
+
// String coercion
|
|
143
|
+
coerce(true, String); // → "true"
|
|
144
|
+
coerce(42, String); // → "42"
|
|
145
|
+
|
|
146
|
+
// Array coercion
|
|
147
|
+
coerce("1,2,3", [Number]); // → [1, 2, 3]
|
|
148
|
+
coerce("a\tb\tc", [String]); // → ["a", "b", "c"]
|
|
149
|
+
coerce([1, 2], [String]); // → ["1", "2"]
|
|
150
|
+
|
|
151
|
+
// Unwrapping
|
|
152
|
+
coerce({ value: "42" }, Number); // → 42
|
|
153
|
+
coerce(["true"], Boolean); // → true
|
|
154
|
+
coerce('{"value": 5}', Number); // → 5
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### RegExp Type Shorthand
|
|
158
|
+
|
|
159
|
+
A bare RegExp coerces to String and validates:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const handler = serviceHandler({
|
|
163
|
+
input: {
|
|
164
|
+
email: { type: /^[^@]+@[^@]+\.[^@]+$/ },
|
|
165
|
+
},
|
|
166
|
+
service: ({ email }) => email,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
await handler({ email: "bob@example.com" }); // ✓
|
|
170
|
+
await handler({ email: "invalid" }); // ✗ BadRequestError
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Validated Type Shorthand
|
|
174
|
+
|
|
175
|
+
Arrays of literals validate against allowed values:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// String validation
|
|
179
|
+
input: {
|
|
180
|
+
currency: { type: ["usd", "eur", "gbp"] }, // Must be one of these
|
|
181
|
+
pattern: { type: [/^test-/, "special"] }, // Matches regex OR equals "special"
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Number validation
|
|
185
|
+
input: {
|
|
186
|
+
priority: { type: [1, 2, 3, 4, 5] }, // Must be 1-5
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Commander.js Integration
|
|
191
|
+
|
|
192
|
+
### registerServiceCommand (Recommended)
|
|
193
|
+
|
|
194
|
+
The simplest way to register a service handler as a Commander command:
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { Command } from "commander";
|
|
198
|
+
import { serviceHandler } from "@jaypie/vocabulary";
|
|
199
|
+
import { registerServiceCommand } from "@jaypie/vocabulary/commander";
|
|
200
|
+
|
|
201
|
+
const handler = serviceHandler({
|
|
202
|
+
alias: "greet",
|
|
203
|
+
description: "Greet a user",
|
|
204
|
+
input: {
|
|
205
|
+
userName: { type: String, flag: "user", letter: "u" },
|
|
206
|
+
loud: { type: Boolean, letter: "l", default: false },
|
|
207
|
+
},
|
|
208
|
+
service: ({ loud, userName }) => {
|
|
209
|
+
const greeting = `Hello, ${userName}!`;
|
|
210
|
+
console.log(loud ? greeting.toUpperCase() : greeting);
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const program = new Command();
|
|
215
|
+
registerServiceCommand({ handler, program });
|
|
216
|
+
program.parse();
|
|
217
|
+
// Usage: greet --user Alice -l
|
|
218
|
+
// Output: HELLO, ALICE!
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### registerServiceCommand Options
|
|
222
|
+
|
|
223
|
+
| Option | Type | Description |
|
|
224
|
+
|--------|------|-------------|
|
|
225
|
+
| `handler` | `ServiceHandlerFunction` | Required. The service handler |
|
|
226
|
+
| `program` | `Command` | Required. Commander program or command |
|
|
227
|
+
| `name` | `string` | Override command name (default: handler.alias) |
|
|
228
|
+
| `description` | `string` | Override description (default: handler.description) |
|
|
229
|
+
| `exclude` | `string[]` | Field names to exclude from options |
|
|
230
|
+
| `overrides` | `Record<string, override>` | Per-field option overrides |
|
|
231
|
+
|
|
232
|
+
### Input Flag and Letter Properties
|
|
233
|
+
|
|
234
|
+
Define CLI flags directly in input definitions:
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
input: {
|
|
238
|
+
userName: {
|
|
239
|
+
type: String,
|
|
240
|
+
flag: "user", // Long flag: --user (instead of --user-name)
|
|
241
|
+
letter: "u", // Short flag: -u
|
|
242
|
+
description: "User name to greet",
|
|
243
|
+
},
|
|
244
|
+
verbose: {
|
|
245
|
+
type: Boolean,
|
|
246
|
+
letter: "v", // -v
|
|
247
|
+
},
|
|
248
|
+
}
|
|
249
|
+
// Generates: --user <userName>, -u and --verbose, -v
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Manual Integration
|
|
253
|
+
|
|
254
|
+
For more control, use `createCommanderOptions` and `parseCommanderOptions`:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { Command } from "commander";
|
|
258
|
+
import { serviceHandler } from "@jaypie/vocabulary";
|
|
259
|
+
import {
|
|
260
|
+
createCommanderOptions,
|
|
261
|
+
parseCommanderOptions,
|
|
262
|
+
} from "@jaypie/vocabulary/commander";
|
|
263
|
+
|
|
264
|
+
const handler = serviceHandler({
|
|
265
|
+
input: {
|
|
266
|
+
userName: { type: String, description: "User name" },
|
|
267
|
+
maxRetries: { type: Number, default: 3 },
|
|
268
|
+
verbose: { type: Boolean },
|
|
269
|
+
},
|
|
270
|
+
service: (input) => console.log(input),
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const program = new Command();
|
|
274
|
+
|
|
275
|
+
// Create options from handler input
|
|
276
|
+
const { options } = createCommanderOptions(handler.input, {
|
|
277
|
+
exclude: ["internalField"],
|
|
278
|
+
overrides: {
|
|
279
|
+
userName: { short: "u", description: "Override description" },
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
options.forEach((opt) => program.addOption(opt));
|
|
283
|
+
|
|
284
|
+
// Wire up action
|
|
285
|
+
program.action(async (opts) => {
|
|
286
|
+
const input = parseCommanderOptions(opts, { input: handler.input });
|
|
287
|
+
await handler(input);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
program.parse();
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Boolean Flag Behavior
|
|
294
|
+
|
|
295
|
+
Commander.js automatically handles boolean flags:
|
|
296
|
+
- `--verbose` sets to `true`
|
|
297
|
+
- `--no-verbose` sets to `false` (for flags with `default: true`)
|
|
298
|
+
|
|
299
|
+
## Complete CLI Example
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
// src/commands/evaluate.ts
|
|
303
|
+
import { Command } from "commander";
|
|
304
|
+
import { serviceHandler } from "@jaypie/vocabulary";
|
|
305
|
+
import { registerServiceCommand } from "@jaypie/vocabulary/commander";
|
|
306
|
+
|
|
307
|
+
export const evaluateHandler = serviceHandler({
|
|
308
|
+
alias: "evaluate",
|
|
309
|
+
description: "Run an evaluation job",
|
|
310
|
+
input: {
|
|
311
|
+
jobId: {
|
|
312
|
+
type: String,
|
|
313
|
+
flag: "job",
|
|
314
|
+
letter: "j",
|
|
315
|
+
description: "Job identifier",
|
|
316
|
+
},
|
|
317
|
+
priority: {
|
|
318
|
+
type: [1, 2, 3, 4, 5],
|
|
319
|
+
default: 3,
|
|
320
|
+
letter: "p",
|
|
321
|
+
description: "Job priority (1-5)",
|
|
322
|
+
},
|
|
323
|
+
tags: {
|
|
324
|
+
type: [String],
|
|
325
|
+
letter: "t",
|
|
326
|
+
required: false,
|
|
327
|
+
description: "Tags to apply",
|
|
328
|
+
},
|
|
329
|
+
dryRun: {
|
|
330
|
+
type: Boolean,
|
|
331
|
+
letter: "d",
|
|
332
|
+
default: false,
|
|
333
|
+
description: "Run without executing",
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
service: async ({ dryRun, jobId, priority, tags }) => {
|
|
337
|
+
console.log(`Running job ${jobId} with priority ${priority}`);
|
|
338
|
+
if (tags?.length) console.log(`Tags: ${tags.join(", ")}`);
|
|
339
|
+
if (dryRun) {
|
|
340
|
+
console.log("(dry run - no changes made)");
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
// Execute job...
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
export function evaluateCommand(program: Command): Command {
|
|
348
|
+
registerServiceCommand({ handler: evaluateHandler, program });
|
|
349
|
+
return program;
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Usage:
|
|
354
|
+
```bash
|
|
355
|
+
# Required job, default priority
|
|
356
|
+
cli evaluate --job abc123
|
|
357
|
+
|
|
358
|
+
# With all options
|
|
359
|
+
cli evaluate -j abc123 -p 1 -t urgent -t critical --dry-run
|
|
360
|
+
|
|
361
|
+
# Help
|
|
362
|
+
cli evaluate --help
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## TypeScript Types
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
import type {
|
|
369
|
+
// Coercion types
|
|
370
|
+
CoercionType,
|
|
371
|
+
ScalarType,
|
|
372
|
+
CompositeType,
|
|
373
|
+
TypedArrayType,
|
|
374
|
+
ValidatedStringType,
|
|
375
|
+
ValidatedNumberType,
|
|
376
|
+
RegExpType,
|
|
377
|
+
ArrayElementType,
|
|
378
|
+
|
|
379
|
+
// Service handler types
|
|
380
|
+
InputFieldDefinition,
|
|
381
|
+
ValidateFunction,
|
|
382
|
+
ServiceFunction,
|
|
383
|
+
ServiceHandlerConfig,
|
|
384
|
+
ServiceHandlerFunction,
|
|
385
|
+
} from "@jaypie/vocabulary";
|
|
386
|
+
|
|
387
|
+
import type {
|
|
388
|
+
// Commander adapter types
|
|
389
|
+
CommanderOptionOverride,
|
|
390
|
+
CreateCommanderOptionsConfig,
|
|
391
|
+
CreateCommanderOptionsResult,
|
|
392
|
+
ParseCommanderOptionsConfig,
|
|
393
|
+
RegisterServiceCommandConfig,
|
|
394
|
+
RegisterServiceCommandResult,
|
|
395
|
+
} from "@jaypie/vocabulary/commander";
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Exports
|
|
399
|
+
|
|
400
|
+
### Main Export (`@jaypie/vocabulary`)
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
// Coercion functions
|
|
404
|
+
export {
|
|
405
|
+
coerce,
|
|
406
|
+
coerceFromArray,
|
|
407
|
+
coerceFromObject,
|
|
408
|
+
coerceToArray,
|
|
409
|
+
coerceToBoolean,
|
|
410
|
+
coerceToNumber,
|
|
411
|
+
coerceToObject,
|
|
412
|
+
coerceToString,
|
|
413
|
+
} from "./coerce.js";
|
|
414
|
+
|
|
415
|
+
// Service Handler
|
|
416
|
+
export { serviceHandler } from "./serviceHandler.js";
|
|
417
|
+
|
|
418
|
+
// Commander namespace
|
|
419
|
+
export * as commander from "./commander/index.js";
|
|
420
|
+
|
|
421
|
+
// Version
|
|
422
|
+
export const VOCABULARY_VERSION: string;
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Commander Export (`@jaypie/vocabulary/commander`)
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
export { createCommanderOptions } from "./createCommanderOptions.js";
|
|
429
|
+
export { parseCommanderOptions } from "./parseCommanderOptions.js";
|
|
430
|
+
export { registerServiceCommand } from "./registerServiceCommand.js";
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Error Handling
|
|
434
|
+
|
|
435
|
+
Invalid coercions throw `BadRequestError` from `@jaypie/errors`:
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
import { BadRequestError } from "@jaypie/errors";
|
|
439
|
+
|
|
440
|
+
// These throw BadRequestError:
|
|
441
|
+
await handler({ numerator: "not-a-number" }); // Cannot coerce to Number
|
|
442
|
+
await handler({ priority: 10 }); // Validation fails (not in [1,2,3,4,5])
|
|
443
|
+
await handler({}); // Missing required field
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## Integration with Other Packages
|
|
447
|
+
|
|
448
|
+
Vocabulary is designed to be consumed by:
|
|
449
|
+
- **`@jaypie/lambda`** - Lambda handler input processing
|
|
450
|
+
- **`@jaypie/express`** - Express route input validation
|
|
451
|
+
- **CLI packages** - Commander.js integration via the commander adapter
|