@jaypie/mcp 0.3.2 → 0.4.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/dist/createMcpServer.d.ts +7 -1
- package/dist/index.js +26 -3135
- package/dist/index.js.map +1 -1
- package/dist/suite.d.ts +1 -0
- package/dist/suite.js +2442 -0
- package/dist/suite.js.map +1 -0
- package/package.json +8 -3
- package/release-notes/constructs/1.2.17.md +11 -0
- package/release-notes/fabric/0.1.2.md +11 -0
- package/release-notes/fabric/0.1.3.md +25 -0
- package/release-notes/fabric/0.1.4.md +42 -0
- package/release-notes/mcp/0.3.3.md +12 -0
- package/release-notes/mcp/0.3.4.md +36 -0
- package/release-notes/mcp/0.4.0.md +27 -0
- package/release-notes/testkit/1.2.15.md +23 -0
- package/skills/agents.md +25 -0
- package/skills/aws.md +107 -0
- package/skills/cdk.md +141 -0
- package/skills/cicd.md +152 -0
- package/skills/datadog.md +129 -0
- package/skills/debugging.md +148 -0
- package/skills/dns.md +134 -0
- package/skills/dynamodb.md +140 -0
- package/skills/errors.md +142 -0
- package/skills/fabric.md +191 -0
- package/skills/index.md +7 -0
- package/skills/jaypie.md +100 -0
- package/skills/legacy.md +97 -0
- package/skills/logs.md +160 -0
- package/skills/mocks.md +174 -0
- package/skills/models.md +195 -0
- package/skills/releasenotes.md +94 -0
- package/skills/secrets.md +155 -0
- package/skills/services.md +175 -0
- package/skills/style.md +190 -0
- package/skills/tests.md +209 -0
- package/skills/tools.md +127 -0
- package/skills/topics.md +116 -0
- package/skills/variables.md +146 -0
- package/skills/writing.md +153 -0
- package/prompts/Branch_Management.md +0 -34
- package/prompts/Development_Process.md +0 -89
- package/prompts/Jaypie_Agent_Rules.md +0 -110
- package/prompts/Jaypie_Auth0_Express_Mongoose.md +0 -736
- package/prompts/Jaypie_Browser_and_Frontend_Web_Packages.md +0 -18
- package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +0 -430
- package/prompts/Jaypie_CICD_with_GitHub_Actions.md +0 -371
- package/prompts/Jaypie_Commander_CLI_Package.md +0 -166
- package/prompts/Jaypie_Core_Errors_and_Logging.md +0 -39
- package/prompts/Jaypie_DynamoDB_Package.md +0 -774
- package/prompts/Jaypie_Eslint_NPM_Package.md +0 -78
- package/prompts/Jaypie_Express_Package.md +0 -630
- package/prompts/Jaypie_Fabric_Commander.md +0 -411
- package/prompts/Jaypie_Fabric_LLM.md +0 -312
- package/prompts/Jaypie_Fabric_Lambda.md +0 -308
- package/prompts/Jaypie_Fabric_MCP.md +0 -316
- package/prompts/Jaypie_Fabric_Package.md +0 -513
- package/prompts/Jaypie_Fabricator.md +0 -617
- package/prompts/Jaypie_Ideal_Project_Structure.md +0 -78
- package/prompts/Jaypie_Init_CICD_with_GitHub_Actions.md +0 -1186
- package/prompts/Jaypie_Init_Express_on_Lambda.md +0 -115
- package/prompts/Jaypie_Init_Jaypie_CDK_Package.md +0 -35
- package/prompts/Jaypie_Init_Lambda_Package.md +0 -505
- package/prompts/Jaypie_Init_Monorepo_Project.md +0 -44
- package/prompts/Jaypie_Init_Project_Subpackage.md +0 -65
- package/prompts/Jaypie_Legacy_Patterns.md +0 -15
- package/prompts/Jaypie_Llm_Calls.md +0 -449
- package/prompts/Jaypie_Llm_Tools.md +0 -155
- package/prompts/Jaypie_MCP_Package.md +0 -281
- package/prompts/Jaypie_Mocks_and_Testkit.md +0 -137
- package/prompts/Jaypie_Repokit.md +0 -103
- package/prompts/Jaypie_Scrub.md +0 -177
- package/prompts/Jaypie_Streaming.md +0 -467
- package/prompts/Templates_CDK_Subpackage.md +0 -115
- package/prompts/Templates_Express_Subpackage.md +0 -187
- package/prompts/Templates_Project_Monorepo.md +0 -326
- package/prompts/Templates_Project_Subpackage.md +0 -93
- package/prompts/Write_Efficient_Prompt_Guides.md +0 -48
- package/prompts/Write_and_Maintain_Engaging_Readme.md +0 -67
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: MCP server package with documentation, AWS, Datadog, and LLM tools
|
|
3
|
-
include: "packages/mcp/**"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# @jaypie/mcp Package
|
|
7
|
-
|
|
8
|
-
The `@jaypie/mcp` package provides a Model Context Protocol (MCP) server for AI agents working with Jaypie projects. It includes tools for accessing documentation, AWS CLI operations, Datadog observability, and LLM debugging.
|
|
9
|
-
|
|
10
|
-
## Package Structure
|
|
11
|
-
|
|
12
|
-
```
|
|
13
|
-
packages/mcp/
|
|
14
|
-
├── src/
|
|
15
|
-
│ ├── index.ts # CLI entrypoint, exports createMcpServer and mcpExpressHandler
|
|
16
|
-
│ ├── createMcpServer.ts # Core MCP server factory with tool definitions
|
|
17
|
-
│ ├── mcpExpressHandler.ts # Express middleware for HTTP transport
|
|
18
|
-
│ ├── aws.ts # AWS CLI integration (spawn-based)
|
|
19
|
-
│ ├── datadog.ts # Datadog API integration (https-based)
|
|
20
|
-
│ └── llm.ts # LLM debug utilities
|
|
21
|
-
├── prompts/ # Markdown guides served via list_prompts/read_prompt tools
|
|
22
|
-
├── release-notes/ # Version history by package (e.g., release-notes/mcp/0.3.2.md)
|
|
23
|
-
└── dist/ # Built output
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Usage
|
|
27
|
-
|
|
28
|
-
### CLI (stdio transport)
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npx jaypie-mcp # Run MCP server via stdio
|
|
32
|
-
npx jaypie-mcp --verbose # Run with debug logging
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Express Integration (HTTP transport)
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
import express from "express";
|
|
39
|
-
import { mcpExpressHandler } from "@jaypie/mcp";
|
|
40
|
-
|
|
41
|
-
const app = express();
|
|
42
|
-
app.use(express.json());
|
|
43
|
-
app.use("/mcp", await mcpExpressHandler({ version: "1.0.0" }));
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Direct Server Creation
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
import { createMcpServer } from "@jaypie/mcp";
|
|
50
|
-
|
|
51
|
-
const server = createMcpServer({ version: "1.0.0", verbose: true });
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## MCP Tools (29 total)
|
|
55
|
-
|
|
56
|
-
### Documentation Tools (5)
|
|
57
|
-
|
|
58
|
-
| Tool | Description |
|
|
59
|
-
|------|-------------|
|
|
60
|
-
| `list_prompts` | Lists all `.md` files in `prompts/` with descriptions and required file patterns |
|
|
61
|
-
| `read_prompt` | Returns content of a specific prompt file |
|
|
62
|
-
| `version` | Returns package version string |
|
|
63
|
-
| `list_release_notes` | Lists release notes by package, supports `since_version` filtering |
|
|
64
|
-
| `read_release_note` | Returns full content of a specific release note |
|
|
65
|
-
|
|
66
|
-
### AWS CLI Tools (16)
|
|
67
|
-
|
|
68
|
-
Requires AWS CLI installed and configured. All tools accept optional `profile` and `region` parameters.
|
|
69
|
-
|
|
70
|
-
| Tool | Description |
|
|
71
|
-
|------|-------------|
|
|
72
|
-
| `aws_list_profiles` | List available AWS profiles from ~/.aws/config and credentials |
|
|
73
|
-
| `aws_stepfunctions_list_executions` | List Step Function executions for a state machine |
|
|
74
|
-
| `aws_stepfunctions_stop_execution` | Stop a running Step Function execution |
|
|
75
|
-
| `aws_lambda_list_functions` | List Lambda functions with optional prefix filtering |
|
|
76
|
-
| `aws_lambda_get_function` | Get configuration and details for a specific Lambda function |
|
|
77
|
-
| `aws_logs_filter_log_events` | Search CloudWatch Logs with pattern and time range filtering |
|
|
78
|
-
| `aws_s3_list_objects` | List objects in an S3 bucket with optional prefix filtering |
|
|
79
|
-
| `aws_cloudformation_describe_stack` | Get details and status of a CloudFormation stack |
|
|
80
|
-
| `aws_dynamodb_describe_table` | Get metadata about a DynamoDB table |
|
|
81
|
-
| `aws_dynamodb_scan` | Scan a DynamoDB table (use sparingly on large tables) |
|
|
82
|
-
| `aws_dynamodb_query` | Query a DynamoDB table by partition key |
|
|
83
|
-
| `aws_dynamodb_get_item` | Get a single item from a DynamoDB table by primary key |
|
|
84
|
-
| `aws_sqs_list_queues` | List SQS queues with optional prefix filtering |
|
|
85
|
-
| `aws_sqs_get_queue_attributes` | Get queue attributes including message counts |
|
|
86
|
-
| `aws_sqs_receive_message` | Peek at messages in an SQS queue (does not delete) |
|
|
87
|
-
| `aws_sqs_purge_queue` | Delete all messages from an SQS queue (irreversible) |
|
|
88
|
-
|
|
89
|
-
### Datadog Tools (6)
|
|
90
|
-
|
|
91
|
-
Requires `DATADOG_API_KEY` and `DATADOG_APP_KEY` environment variables.
|
|
92
|
-
|
|
93
|
-
| Tool | Description |
|
|
94
|
-
|------|-------------|
|
|
95
|
-
| `datadog_logs` | Search individual log entries |
|
|
96
|
-
| `datadog_log_analytics` | Aggregate logs with groupBy operations |
|
|
97
|
-
| `datadog_monitors` | List and filter monitors by status/tags |
|
|
98
|
-
| `datadog_synthetics` | List synthetic tests or get results for a specific test |
|
|
99
|
-
| `datadog_metrics` | Query timeseries metrics |
|
|
100
|
-
| `datadog_rum` | Search Real User Monitoring events |
|
|
101
|
-
|
|
102
|
-
### LLM Tools (2)
|
|
103
|
-
|
|
104
|
-
| Tool | Description |
|
|
105
|
-
|------|-------------|
|
|
106
|
-
| `llm_debug_call` | Debug LLM API calls and inspect raw responses |
|
|
107
|
-
| `llm_list_providers` | List available LLM providers with their models |
|
|
108
|
-
|
|
109
|
-
## Environment Variables
|
|
110
|
-
|
|
111
|
-
### AWS CLI Integration
|
|
112
|
-
|
|
113
|
-
| Variable | Description |
|
|
114
|
-
|----------|-------------|
|
|
115
|
-
| `AWS_PROFILE` | Default profile if not specified per-call |
|
|
116
|
-
| `AWS_REGION` or `AWS_DEFAULT_REGION` | Default region if not specified |
|
|
117
|
-
|
|
118
|
-
AWS tools use the host's existing credential chain:
|
|
119
|
-
- `~/.aws/credentials` and `~/.aws/config` files
|
|
120
|
-
- Environment variables (`AWS_ACCESS_KEY_ID`, etc.)
|
|
121
|
-
- SSO sessions established via `aws sso login`
|
|
122
|
-
|
|
123
|
-
### Datadog Integration
|
|
124
|
-
|
|
125
|
-
| Variable | Description |
|
|
126
|
-
|----------|-------------|
|
|
127
|
-
| `DATADOG_API_KEY` or `DD_API_KEY` | Datadog API key |
|
|
128
|
-
| `DATADOG_APP_KEY` or `DD_APP_KEY` | Datadog Application key |
|
|
129
|
-
| `DD_ENV` | Default environment filter |
|
|
130
|
-
| `DD_SERVICE` | Default service filter |
|
|
131
|
-
| `DD_SOURCE` | Default log source (defaults to "lambda") |
|
|
132
|
-
| `DD_QUERY` | Default query terms appended to searches |
|
|
133
|
-
|
|
134
|
-
## Adding New Tools
|
|
135
|
-
|
|
136
|
-
Tools are registered in `createMcpServer.ts` using the MCP SDK pattern:
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
server.tool(
|
|
140
|
-
"tool_name",
|
|
141
|
-
"Description shown to AI agents",
|
|
142
|
-
{
|
|
143
|
-
// Zod schema for parameters
|
|
144
|
-
param1: z.string().describe("Parameter description"),
|
|
145
|
-
param2: z.number().optional().describe("Optional parameter"),
|
|
146
|
-
},
|
|
147
|
-
async ({ param1, param2 }) => {
|
|
148
|
-
// Implementation
|
|
149
|
-
return {
|
|
150
|
-
content: [{ type: "text" as const, text: "Result text" }],
|
|
151
|
-
};
|
|
152
|
-
},
|
|
153
|
-
);
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### AWS Tool Pattern
|
|
157
|
-
|
|
158
|
-
AWS tools use `child_process.spawn` to call the AWS CLI:
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
// In aws.ts
|
|
162
|
-
export async function myAwsOperation(
|
|
163
|
-
options: MyOperationOptions,
|
|
164
|
-
logger: Logger = nullLogger,
|
|
165
|
-
): Promise<AwsCommandResult<MyResultType>> {
|
|
166
|
-
const args = ["--required-arg", options.requiredArg];
|
|
167
|
-
if (options.optionalArg) {
|
|
168
|
-
args.push("--optional-arg", options.optionalArg);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return executeAwsCommand(
|
|
172
|
-
"service-name", // e.g., "stepfunctions", "lambda", "s3api"
|
|
173
|
-
"command-name", // e.g., "list-executions", "get-function"
|
|
174
|
-
args,
|
|
175
|
-
{ profile: options.profile, region: options.region },
|
|
176
|
-
logger,
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Datadog Tool Pattern
|
|
182
|
-
|
|
183
|
-
Datadog tools use Node.js `https` module directly:
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
// In datadog.ts
|
|
187
|
-
export async function myDatadogOperation(
|
|
188
|
-
credentials: DatadogCredentials,
|
|
189
|
-
options: MyOptions,
|
|
190
|
-
logger: Logger = nullLogger,
|
|
191
|
-
): Promise<MyResult> {
|
|
192
|
-
const requestOptions = {
|
|
193
|
-
hostname: "api.datadoghq.com",
|
|
194
|
-
port: 443,
|
|
195
|
-
path: "/api/v2/endpoint",
|
|
196
|
-
method: "POST",
|
|
197
|
-
headers: {
|
|
198
|
-
"DD-API-KEY": credentials.apiKey,
|
|
199
|
-
"DD-APPLICATION-KEY": credentials.appKey,
|
|
200
|
-
"Content-Type": "application/json",
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
return new Promise((resolve) => {
|
|
205
|
-
const req = https.request(requestOptions, (res) => {
|
|
206
|
-
// Handle response
|
|
207
|
-
});
|
|
208
|
-
req.write(JSON.stringify(body));
|
|
209
|
-
req.end();
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Adding New Prompts
|
|
215
|
-
|
|
216
|
-
Prompts are markdown files in `prompts/` with optional YAML frontmatter:
|
|
217
|
-
|
|
218
|
-
```yaml
|
|
219
|
-
---
|
|
220
|
-
description: Brief description shown in list_prompts
|
|
221
|
-
include: "packages/express/**" # File patterns this guide applies to
|
|
222
|
-
---
|
|
223
|
-
|
|
224
|
-
# Prompt Title
|
|
225
|
-
|
|
226
|
-
Markdown content here...
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
Prompts are automatically available via `list_prompts` and `read_prompt` tools.
|
|
230
|
-
|
|
231
|
-
## Adding New Release Notes
|
|
232
|
-
|
|
233
|
-
Release notes are organized by package in `release-notes/`:
|
|
234
|
-
|
|
235
|
-
```
|
|
236
|
-
release-notes/
|
|
237
|
-
├── jaypie/
|
|
238
|
-
│ └── 1.2.3.md
|
|
239
|
-
└── mcp/
|
|
240
|
-
└── 0.3.2.md
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
Each release note uses YAML frontmatter:
|
|
244
|
-
|
|
245
|
-
```yaml
|
|
246
|
-
---
|
|
247
|
-
version: 0.3.2
|
|
248
|
-
date: 2025-01-19
|
|
249
|
-
summary: Brief one-line summary for listing
|
|
250
|
-
---
|
|
251
|
-
|
|
252
|
-
## Changes
|
|
253
|
-
|
|
254
|
-
- Feature 1
|
|
255
|
-
- Bug fix 2
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
Release notes are automatically available via `list_release_notes` and `read_release_note` tools. The `since_version` parameter allows clients to query only releases newer than a specific version.
|
|
259
|
-
|
|
260
|
-
## Exports
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
import { createMcpServer, mcpExpressHandler } from "@jaypie/mcp";
|
|
264
|
-
import type { CreateMcpServerOptions, McpExpressHandlerOptions } from "@jaypie/mcp";
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Commands
|
|
268
|
-
|
|
269
|
-
```bash
|
|
270
|
-
npm run build -w packages/mcp # Build with rollup
|
|
271
|
-
npm run test -w packages/mcp # Run tests (vitest run)
|
|
272
|
-
npm run typecheck -w packages/mcp # Type check (tsc --noEmit)
|
|
273
|
-
npm run format packages/mcp # Format with eslint --fix
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
## Security Considerations
|
|
277
|
-
|
|
278
|
-
1. **Allowlisted operations only** - No arbitrary command execution
|
|
279
|
-
2. **Read-heavy design** - Most tools are read-only; mutating operations have explicit warnings
|
|
280
|
-
3. **No credential exposure** - Credentials never passed through MCP; uses host's credential chain
|
|
281
|
-
4. **Profile isolation** - Each call can specify a different profile for multi-account work
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Jaypie projects rely heavily on mocking the entire jaypie package, often in setup files, as well as manual mocks. Recommended when creating new tests or addressing failures.
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Jaypie Mocks and Testkit
|
|
6
|
-
|
|
7
|
-
Adds unit tests for a JavaScript or TypeScript file.
|
|
8
|
-
|
|
9
|
-
## Requirements
|
|
10
|
-
|
|
11
|
-
- Use **Vitest** for all test files.
|
|
12
|
-
- Create a new test file as a sibling to the implementation, not a separate directory or tree
|
|
13
|
-
- Use **ECMAScript module syntax** (`import/export`), not CommonJS.
|
|
14
|
-
- Import the function under test using a relative path and include the `.js` extension.
|
|
15
|
-
- Use `describe` blocks for each function and `it` blocks for each behavior.
|
|
16
|
-
- Include tests for:
|
|
17
|
-
- Normal/expected input
|
|
18
|
-
- Edge cases
|
|
19
|
-
- Error handling (if applicable)
|
|
20
|
-
- Ensure all tests are deterministic and do not rely on randomness or network calls unless mocked.
|
|
21
|
-
|
|
22
|
-
## File Style Rules
|
|
23
|
-
|
|
24
|
-
- Use double quotes.
|
|
25
|
-
- Use ES6+ syntax.
|
|
26
|
-
- Do not modify the original file.
|
|
27
|
-
- Do not include any setup or installation instructions.
|
|
28
|
-
|
|
29
|
-
## Jaypie Testkit
|
|
30
|
-
`@jaypie/testkit` is the testing library.
|
|
31
|
-
`matchers` are exported and extend expect in the test setup.
|
|
32
|
-
All jaypie functions can be mocked with `vi.mock("jaypie", async () => vi.importActual("@jaypie/testkit/mock"));`
|
|
33
|
-
### Classes
|
|
34
|
-
Mocked jaypie classes should mocked members for each mocked implementation.
|
|
35
|
-
```
|
|
36
|
-
Llm.operate.mockResolvedValue("Bueno");
|
|
37
|
-
const llm = new Llm();
|
|
38
|
-
const response = llm.operate();
|
|
39
|
-
expect(response).toBeString("Bueno");
|
|
40
|
-
expect(Llm.operate).toHaveBeenCalled()
|
|
41
|
-
```
|
|
42
|
-
### Errors
|
|
43
|
-
Use matchers to test errors.
|
|
44
|
-
`expect(fn).toThrowBadGatewayError();`
|
|
45
|
-
`await expect(async() => fn()).toThrowBadGatewayError();`
|
|
46
|
-
Do not use `.rejects`
|
|
47
|
-
### Express
|
|
48
|
-
Most express functions are wrapped in `expressHandler` which is mocked.
|
|
49
|
-
Test express functions directly with a `req` object.
|
|
50
|
-
Handle cases where the `req` object is undefined or incomplete.
|
|
51
|
-
supertest is also available to test http responses.
|
|
52
|
-
### Logging
|
|
53
|
-
`log` is mocked by `@jaypie/testkit/mock` or separately using `spyLog` and `restoreLog` in `@jaypie/testkit`.
|
|
54
|
-
Use matchers on `log` functions and `toBeCalledAboveTrace` on `log` itself.
|
|
55
|
-
`expect(log).not.toBeCalledAboveTrace();`
|
|
56
|
-
`expect(log.warn).toBeCalled();`
|
|
57
|
-
### Matchers
|
|
58
|
-
toBeCalledAboveTrace, toBeCalledWithInitialParams, toBeClass, toBeJaypieError, toMatchBase64, toMatchJwt, toMatchMongoId, toMatchSchema, toMatchSignedCookie, toMatchUuid4, toMatchUuid5, toMatchUuid, toThrowBadGatewayError, toThrowBadRequestError, toThrowConfigurationError, toThrowForbiddenError, toThrowGatewayTimeoutError, toThrowInternalError, toThrowJaypieError, toThrowNotFoundError, toThrowUnauthorizedError, toThrowUnavailableError,
|
|
59
|
-
### Order of Tests
|
|
60
|
-
Tests are named `./__tests__/<subject>.spec.<js|ts>`.
|
|
61
|
-
Each file should have one top-level `describe` block.
|
|
62
|
-
Organize tests in one of seven second-level describe block sections in this order:
|
|
63
|
-
1. Base Cases - it is the type we expect ("It is a Function"). For functions, the simplest possible call works and returns not undefined ("It Works"). For objects, the expected shape.
|
|
64
|
-
2. Error Conditions - any error handling the code performs
|
|
65
|
-
3. Security - any security checks the code performs
|
|
66
|
-
4. Observability - any logging the code performs
|
|
67
|
-
5. Happy Paths - The most common use case
|
|
68
|
-
6. Features - Features in addition to the happy path
|
|
69
|
-
7. Specific Scenarios - Special cases
|
|
70
|
-
Omit describe blocks for sections that are not applicable or empty.
|
|
71
|
-
Whenever possible, especially when refactoring, write the test first so the user can confirm the expected behavior passes/fails.
|
|
72
|
-
### Test Coverage
|
|
73
|
-
Aim for complete coverage of all happy paths, features, and error conditions.
|
|
74
|
-
Whenever possible, confirm mocked functions are called.
|
|
75
|
-
Confirm calls to log above debug in Observability. Do not confirm calls to debug, var, or trace.
|
|
76
|
-
|
|
77
|
-
## Configuration
|
|
78
|
-
|
|
79
|
-
### Typical Package
|
|
80
|
-
|
|
81
|
-
`package.json`
|
|
82
|
-
```json
|
|
83
|
-
"scripts": {
|
|
84
|
-
"test": "vitest run",
|
|
85
|
-
"test:watch": "vitest watch",
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
`vitest.config.ts`
|
|
90
|
-
```typescript
|
|
91
|
-
import { defineConfig } from "vite";
|
|
92
|
-
|
|
93
|
-
export default defineConfig({
|
|
94
|
-
test: {
|
|
95
|
-
setupFiles: ["./vitest.setup.ts"],
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
`vitest.setup.ts`
|
|
101
|
-
```typescript
|
|
102
|
-
// This file left intentionally blank
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
* `vitest.setup.ts` can be used to extend the jest matchers, for example, or setting up other mocks
|
|
106
|
-
```typescript
|
|
107
|
-
import * as extendedMatchers from "jest-extended";
|
|
108
|
-
import { expect } from "vitest";
|
|
109
|
-
|
|
110
|
-
expect.extend(extendedMatchers);
|
|
111
|
-
```
|
|
112
|
-
* Before creating a `vitest.setup.ts`, check if `testSetup.js` exists.
|
|
113
|
-
|
|
114
|
-
## NPM Workspaces (monorepos)
|
|
115
|
-
|
|
116
|
-
* Configure sub-packages following the above
|
|
117
|
-
* Usually only sub-packages have `vitest.config.ts` and `vitest.setup.ts`
|
|
118
|
-
* Configure the root package as follows, iterating for each `<package>` below
|
|
119
|
-
|
|
120
|
-
`package.json`
|
|
121
|
-
```json
|
|
122
|
-
"scripts": {
|
|
123
|
-
"test": "vitest run",
|
|
124
|
-
"test:watch": "vitest watch",
|
|
125
|
-
"test:<package>": "npm run test --workspace packages/<package>"
|
|
126
|
-
"test:<package>:watch": "npm run test:watch --workspace packages/<package>"
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
`vitest.workspace.ts`
|
|
131
|
-
```typescript
|
|
132
|
-
import { defineWorkspace } from "vitest/config";
|
|
133
|
-
|
|
134
|
-
export default defineWorkspace([
|
|
135
|
-
"packages/<package>",
|
|
136
|
-
]);
|
|
137
|
-
```
|
|
@@ -1,103 +0,0 @@
|
|
|
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.
|
package/prompts/Jaypie_Scrub.md
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: House style beyond linting to keep the repository clean and organized
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Jaypie Scrub File 🧽
|
|
6
|
-
|
|
7
|
-
Repository style rules beyond linting
|
|
8
|
-
|
|
9
|
-
## 🚒 Errors
|
|
10
|
-
|
|
11
|
-
Jaypie offers a number of HTTP and special-use errors not limited to:
|
|
12
|
-
`import { BadGatewayError, BadRequestError, ConfigurationError, ForbiddenError, InternalError, NotFoundError, TooManyRequestsError, UnauthorizedError } from "jaypie";`
|
|
13
|
-
|
|
14
|
-
### Prefer to Throw Jaypie Errors
|
|
15
|
-
|
|
16
|
-
* BadGatewayError when an external provider errors
|
|
17
|
-
* InternalError for default 500 errors
|
|
18
|
-
* ConfigurationError is a 500 variant when the problem is traceable to the coding or configuration of the system (incorrect type, incompatible options)
|
|
19
|
-
|
|
20
|
-
<Bad>
|
|
21
|
-
if (!item) {
|
|
22
|
-
log.error("Item not found");
|
|
23
|
-
return {
|
|
24
|
-
statusCode: 404,
|
|
25
|
-
body: JSON.stringify({ error: "Item not found" }),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
</Bad>
|
|
29
|
-
<Good>
|
|
30
|
-
log.error("Item not found");
|
|
31
|
-
throw new NotFoundError();
|
|
32
|
-
</Good>
|
|
33
|
-
|
|
34
|
-
### Throw Jaypie Errors to Return HTTP Errors in Express
|
|
35
|
-
|
|
36
|
-
Inside a Jaypie `expressHandler`, thrown Jaypie errors will return the correct status to the client.
|
|
37
|
-
Never try to alter `res` or return an error status code.
|
|
38
|
-
|
|
39
|
-
### Avoid Custom Error Strings
|
|
40
|
-
|
|
41
|
-
Though supported, rely on default error messages when throwing.
|
|
42
|
-
Custom error messages should be logged.
|
|
43
|
-
|
|
44
|
-
<Bad>
|
|
45
|
-
throw new NotFoundError("Item not found");
|
|
46
|
-
</Bad>
|
|
47
|
-
<Good>
|
|
48
|
-
log.error("Item not found");
|
|
49
|
-
throw new NotFoundError();
|
|
50
|
-
</Good>
|
|
51
|
-
|
|
52
|
-
## 🧹 Linting
|
|
53
|
-
|
|
54
|
-
Use double quotes, trailing commas, and semicolons.
|
|
55
|
-
Do not delete `// eslint-disable-next-line no-shadow` comments; add when shadowing variables, especially `error` in catch blocks.
|
|
56
|
-
|
|
57
|
-
## 📢 Logging
|
|
58
|
-
|
|
59
|
-
### Levels
|
|
60
|
-
|
|
61
|
-
* Only use `log.trace` in the happy path
|
|
62
|
-
* Use `log.debug` when straying from the happy path
|
|
63
|
-
* Use `log.warn`, `log.error` as needed
|
|
64
|
-
* Avoid the use of `info`
|
|
65
|
-
|
|
66
|
-
### Logging Variables
|
|
67
|
-
|
|
68
|
-
* Log variables with `log.var({ item })`
|
|
69
|
-
* Only use single-key objects
|
|
70
|
-
* The key can be changed for clarity
|
|
71
|
-
* When logging large arrays, objects, and strings, consider logging abridged/truncated value or summary heuristics like length
|
|
72
|
-
|
|
73
|
-
### Do Not Mix Strings and Objects
|
|
74
|
-
|
|
75
|
-
<Bad>
|
|
76
|
-
log.trace("Looking up item", { item: item.id });
|
|
77
|
-
</Bad>
|
|
78
|
-
<Good>
|
|
79
|
-
log.trace(`Looking up item ${item.id}`);
|
|
80
|
-
# OR
|
|
81
|
-
log.trace(`Looking up item`);
|
|
82
|
-
log.var({ item: item.id });
|
|
83
|
-
</Good>
|
|
84
|
-
|
|
85
|
-
### Separate Variables
|
|
86
|
-
|
|
87
|
-
Do not combine into a single call:
|
|
88
|
-
|
|
89
|
-
<Bad>
|
|
90
|
-
log.debug({ userId: String(user.id), groupId: String(user.group) });
|
|
91
|
-
</Bad>
|
|
92
|
-
<Good>
|
|
93
|
-
log.var({ userId: user.id });
|
|
94
|
-
log.var({ groupId: user.group }); // Jaypie will coerce strings
|
|
95
|
-
</Good>
|
|
96
|
-
|
|
97
|
-
### Logging in Catch Statements
|
|
98
|
-
|
|
99
|
-
* Log the highest level first
|
|
100
|
-
* Use warn for errors that are part of normal operations like items not found, unauthorized users
|
|
101
|
-
* Use error for things that should not happen like database connections failing
|
|
102
|
-
* Follow up with lower-level debug and var logs as needed
|
|
103
|
-
|
|
104
|
-
### Prefixing
|
|
105
|
-
|
|
106
|
-
Using a prefix in square brackets helps identify functions and libraries.
|
|
107
|
-
`log.trace("[newRoute] Starting route");`
|
|
108
|
-
|
|
109
|
-
## 📛 Naming Things
|
|
110
|
-
|
|
111
|
-
### Pluralization
|
|
112
|
-
|
|
113
|
-
* Prefer singular
|
|
114
|
-
* Objects should be singular
|
|
115
|
-
* A model is singular. `Model.User`
|
|
116
|
-
* Arrays should be plural
|
|
117
|
-
|
|
118
|
-
## 🧪 Testing
|
|
119
|
-
|
|
120
|
-
Aim for complete coverage of all happy paths, features, and error conditions.
|
|
121
|
-
Whenever possible, confirm mocked functions are called.
|
|
122
|
-
|
|
123
|
-
### Errors
|
|
124
|
-
|
|
125
|
-
Jaypie Testkit includes custom matchers for errors: toBeJaypieError, toThrowBadGatewayError, toThrowBadRequestError, toThrowConfigurationError, toThrowForbiddenError, toThrowGatewayTimeoutError, toThrowInternalError, toThrowJaypieError, toThrowNotFoundError, toThrowUnauthorizedError, toThrowUnavailableError,
|
|
126
|
-
`expect(fn).toThrowBadGatewayError();`
|
|
127
|
-
`await expect(async() => fn()).toThrowBadGatewayError();`
|
|
128
|
-
Do not use `.rejects`
|
|
129
|
-
|
|
130
|
-
### Function Calls
|
|
131
|
-
|
|
132
|
-
* Always test a function was called before testing specific values
|
|
133
|
-
```
|
|
134
|
-
expect(fn).toBeCalled();
|
|
135
|
-
expect(fn).toBeCalledWith(12);
|
|
136
|
-
```
|
|
137
|
-
Avoid overly specific tests on mock values and strings, especially log string.
|
|
138
|
-
Test key values that need to be passed through the application.
|
|
139
|
-
Use asymmetric matchers for mock values and strings.
|
|
140
|
-
|
|
141
|
-
### Mocks
|
|
142
|
-
|
|
143
|
-
* Assume `jaypie` is mocked by `@jaypie/testkit/mock`
|
|
144
|
-
* Both of these should be mocked in the subpackage's `testSetup.js` or `vitest.setup.ts`
|
|
145
|
-
|
|
146
|
-
### No Test Code in Implementations
|
|
147
|
-
|
|
148
|
-
Do not check for test conditions, environment variables, or mocks outside the test logic.
|
|
149
|
-
Production code should never have special handling for test cases.
|
|
150
|
-
All code should be structured to be fully mockable.
|
|
151
|
-
Appropriate use of mocks should allow special handling to be dictated in the test file.
|
|
152
|
-
|
|
153
|
-
### Observability
|
|
154
|
-
|
|
155
|
-
* The primary happy path should check `log.not.toBeCalledAboveTrace()`
|
|
156
|
-
* Check `expect(log.warn).toBeCalled();` for `warn` and `error` on error cases
|
|
157
|
-
* Do not confirm calls to debug, var, or trace.
|
|
158
|
-
|
|
159
|
-
### Organization
|
|
160
|
-
|
|
161
|
-
Each file should have one top-level `describe` block.
|
|
162
|
-
Organize tests in one of seven second-level describe block sections in this order:
|
|
163
|
-
|
|
164
|
-
1. Base Cases - it is the type we expect ("It is a Function"). For functions, the simplest possible call works and returns not undefined ("It Works"). For objects, the expected shape.
|
|
165
|
-
2. Error Conditions - any error handling the code performs
|
|
166
|
-
3. Security - any security checks the code performs
|
|
167
|
-
4. Observability - any logging the code performs
|
|
168
|
-
5. Happy Paths - The most common use case
|
|
169
|
-
6. Features - Features in addition to the happy path
|
|
170
|
-
7. Specific Scenarios - Special cases
|
|
171
|
-
|
|
172
|
-
Omit describe blocks for sections that are not applicable or empty.
|
|
173
|
-
|
|
174
|
-
## 🍱 Miscellaneous
|
|
175
|
-
|
|
176
|
-
Alphabetize as much as possible.
|
|
177
|
-
Whenever a hard-coded value like `site: "datadoghq.com"` is used, define a constant at the top of the file, `const DATADOG_SITE = "datadoghq.com"`, and reference that throughout.
|