@jaypie/mcp 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -3
- package/prompts/Branch_Management.md +34 -0
- package/prompts/Development_Process.md +67 -0
- package/prompts/Jaypie_Agent_Rules.md +110 -0
- package/prompts/Jaypie_Auth0_Express_Mongoose.md +736 -0
- package/prompts/Jaypie_Browser_and_Frontend_Web_Packages.md +18 -0
- package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +156 -0
- package/prompts/Jaypie_CICD_with_GitHub_Actions.md +151 -0
- package/prompts/Jaypie_Commander_CLI_Package.md +166 -0
- package/prompts/Jaypie_Core_Errors_and_Logging.md +39 -0
- package/prompts/Jaypie_Eslint_NPM_Package.md +78 -0
- package/prompts/Jaypie_Ideal_Project_Structure.md +78 -0
- package/prompts/Jaypie_Init_Express_on_Lambda.md +87 -0
- package/prompts/Jaypie_Init_Jaypie_CDK_Package.md +35 -0
- package/prompts/Jaypie_Init_Lambda_Package.md +245 -0
- package/prompts/Jaypie_Init_Monorepo_Project.md +44 -0
- package/prompts/Jaypie_Init_Project_Subpackage.md +70 -0
- package/prompts/Jaypie_Legacy_Patterns.md +11 -0
- package/prompts/Jaypie_Llm_Calls.md +113 -0
- package/prompts/Jaypie_Llm_Tools.md +124 -0
- package/prompts/Jaypie_Mocks_and_Testkit.md +137 -0
- package/prompts/Jaypie_Mongoose_Models_Package.md +231 -0
- package/prompts/Jaypie_Mongoose_with_Express_CRUD.md +1000 -0
- package/prompts/Jaypie_Scrub.md +177 -0
- package/prompts/Write_Efficient_Prompt_Guides.md +48 -0
- package/prompts/Write_and_Maintain_Engaging_Readme.md +67 -0
- package/prompts/templates/cdk-subpackage/bin/cdk.ts +11 -0
- package/prompts/templates/cdk-subpackage/cdk.json +19 -0
- package/prompts/templates/cdk-subpackage/lib/cdk-app.ts +41 -0
- package/prompts/templates/cdk-subpackage/lib/cdk-infrastructure.ts +15 -0
- package/prompts/templates/express-subpackage/index.ts +8 -0
- package/prompts/templates/express-subpackage/src/app.ts +18 -0
- package/prompts/templates/express-subpackage/src/handler.config.ts +44 -0
- package/prompts/templates/express-subpackage/src/routes/resource/__tests__/resourceGet.route.spec.ts +29 -0
- package/prompts/templates/express-subpackage/src/routes/resource/resourceGet.route.ts +22 -0
- package/prompts/templates/express-subpackage/src/routes/resource.router.ts +11 -0
- package/prompts/templates/express-subpackage/src/types/express.ts +9 -0
- package/prompts/templates/project-monorepo/.vscode/settings.json +72 -0
- package/prompts/templates/project-monorepo/eslint.config.mjs +1 -0
- package/prompts/templates/project-monorepo/package.json +20 -0
- package/prompts/templates/project-monorepo/tsconfig.base.json +18 -0
- package/prompts/templates/project-monorepo/tsconfig.json +6 -0
- package/prompts/templates/project-monorepo/vitest.workspace.js +3 -0
- package/prompts/templates/project-subpackage/package.json +16 -0
- package/prompts/templates/project-subpackage/tsconfig.json +11 -0
- package/prompts/templates/project-subpackage/vite.config.ts +21 -0
- package/prompts/templates/project-subpackage/vitest.config.ts +7 -0
- package/prompts/templates/project-subpackage/vitest.setup.ts +6 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
trigger: glob
|
|
3
|
+
globs: packages/tools/*
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# LLM Tools with Jaypie 🔧
|
|
7
|
+
|
|
8
|
+
Extend LLM capabilities with tools for external actions and data retrieval
|
|
9
|
+
|
|
10
|
+
## Goal
|
|
11
|
+
|
|
12
|
+
Create and integrate tools that enable LLMs to perform specific functions beyond their training data
|
|
13
|
+
|
|
14
|
+
## Interface
|
|
15
|
+
|
|
16
|
+
Implement the `LlmTool` interface:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
interface LlmTool {
|
|
20
|
+
description: string;
|
|
21
|
+
name: string;
|
|
22
|
+
parameters: JsonObject;
|
|
23
|
+
type: "function" | string;
|
|
24
|
+
call: (args?: JsonObject) => Promise<AnyValue> | AnyValue;
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Properties:
|
|
29
|
+
- `description`: Clear explanation of tool functionality
|
|
30
|
+
- `name`: Unique identifier
|
|
31
|
+
- `parameters`: JSON Schema defining input parameters
|
|
32
|
+
- `type`: Usually "function" (OpenAI convention)
|
|
33
|
+
- `call`: Implementation function executed on invocation
|
|
34
|
+
|
|
35
|
+
## Example: Dice Roller
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { LlmTool } from "../types/LlmTool.interface.js";
|
|
39
|
+
import { log, random, tryParseNumber } from "../util";
|
|
40
|
+
|
|
41
|
+
export const roll: LlmTool = {
|
|
42
|
+
description: "Roll one or more dice with a specified number of sides",
|
|
43
|
+
name: "roll",
|
|
44
|
+
parameters: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
number: {
|
|
48
|
+
type: "number",
|
|
49
|
+
description: "Number of dice to roll. Default: 1",
|
|
50
|
+
},
|
|
51
|
+
sides: {
|
|
52
|
+
type: "number",
|
|
53
|
+
description: "Number of sides on each die. Default: 6",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
required: ["number", "sides"],
|
|
57
|
+
},
|
|
58
|
+
type: "function",
|
|
59
|
+
call: ({ number = 1, sides = 6 } = {}): {
|
|
60
|
+
rolls: number[];
|
|
61
|
+
total: number;
|
|
62
|
+
} => {
|
|
63
|
+
const rng = random();
|
|
64
|
+
const rolls: number[] = [];
|
|
65
|
+
let total = 0;
|
|
66
|
+
|
|
67
|
+
const parsedNumber = tryParseNumber(number, {
|
|
68
|
+
defaultValue: 1,
|
|
69
|
+
warnFunction: log.warn,
|
|
70
|
+
}) as number;
|
|
71
|
+
const parsedSides = tryParseNumber(sides, {
|
|
72
|
+
defaultValue: 6,
|
|
73
|
+
warnFunction: log.warn,
|
|
74
|
+
}) as number;
|
|
75
|
+
|
|
76
|
+
for (let i = 0; i < parsedNumber; i++) {
|
|
77
|
+
const rollValue = rng({ min: 1, max: parsedSides, integer: true });
|
|
78
|
+
rolls.push(rollValue);
|
|
79
|
+
total += rollValue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { rolls, total };
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Best Practices
|
|
88
|
+
|
|
89
|
+
### Input Validation
|
|
90
|
+
Validate and sanitize parameters with utilities like `tryParseNumber`.
|
|
91
|
+
|
|
92
|
+
### Clear Descriptions
|
|
93
|
+
Write precise descriptions for tools and parameters to guide LLM usage.
|
|
94
|
+
|
|
95
|
+
### Consistent Returns
|
|
96
|
+
Return consistent data structures for predictable LLM interpretation.
|
|
97
|
+
|
|
98
|
+
### Error Handling
|
|
99
|
+
Implement robust error handling to prevent crashes and provide meaningful messages.
|
|
100
|
+
|
|
101
|
+
## Integration
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { Llm } from "jaypie";
|
|
105
|
+
import { roll } from "./tools/roll.js";
|
|
106
|
+
|
|
107
|
+
const llm = new Llm({
|
|
108
|
+
provider: "openai",
|
|
109
|
+
model: "gpt-4o"
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const response = await llm.operate([
|
|
113
|
+
{ role: "user", content: "Roll 3d20 and tell me the result" },
|
|
114
|
+
{
|
|
115
|
+
tools: [roll],
|
|
116
|
+
},
|
|
117
|
+
]);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## References
|
|
121
|
+
|
|
122
|
+
- [Jaypie Library](https://github.com/finlaysonstudio/jaypie)
|
|
123
|
+
- [OpenAI Function Calling](https://platform.openai.com/docs/guides/function-calling)
|
|
124
|
+
- [Jaypie_Llm_Calls.md](./Jaypie_Llm_Calls.md) to better understand Llm.operate()
|
|
@@ -0,0 +1,137 @@
|
|
|
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
|
+
```
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Document describes a Jaypie pattern repeated in many projects but not yet offered as a package within Jaypie
|
|
3
|
+
globs: packages/models/**
|
|
4
|
+
status: Work in Progress
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Jaypie Mongoose Models Package
|
|
8
|
+
|
|
9
|
+
Create reusable MongoDB models with rich relationship management using Mongoose and Jaypie.
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
|
|
13
|
+
Define document schemas with bidirectional relationships and consistent utilities for mongoose models.
|
|
14
|
+
|
|
15
|
+
## Guidelines
|
|
16
|
+
|
|
17
|
+
- Uses ES modules with `.js` extensions (`"type": "module"`)
|
|
18
|
+
- Requires mongoose and jaypie as dependencies
|
|
19
|
+
- Follows schema organization pattern: definition → hooks → methods → statics → export
|
|
20
|
+
- Every schema should use `projectSchema.plugin.js` for relationship methods
|
|
21
|
+
- Every document has `uuid` field for external references
|
|
22
|
+
|
|
23
|
+
## Process
|
|
24
|
+
|
|
25
|
+
### Package Setup
|
|
26
|
+
|
|
27
|
+
1. Create package structure:
|
|
28
|
+
```
|
|
29
|
+
models/
|
|
30
|
+
├── package.json
|
|
31
|
+
├── src/
|
|
32
|
+
│ ├── constants.js
|
|
33
|
+
│ ├── index.js
|
|
34
|
+
│ ├── user.schema.js
|
|
35
|
+
│ ├── projectSchema.plugin.js
|
|
36
|
+
│ └── __tests__/
|
|
37
|
+
│ ├── constants.spec.js
|
|
38
|
+
│ ├── index.spec.js
|
|
39
|
+
│ ├── user.schema.spec.js
|
|
40
|
+
│ └── projectSchema.plugin.spec.js
|
|
41
|
+
├── testSetup.js
|
|
42
|
+
└── vite.config.js
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. Configure package.json:
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"name": "@yournamespace/models",
|
|
49
|
+
"type": "module",
|
|
50
|
+
"exports": {
|
|
51
|
+
".": {
|
|
52
|
+
"default": {
|
|
53
|
+
"require": "./dist/module.cjs.js",
|
|
54
|
+
"default": "./src/index.js"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"main": "src/index.js",
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"jaypie": "^1.1.0",
|
|
61
|
+
"mongoose": "^7.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Core Files Implementation
|
|
67
|
+
|
|
68
|
+
1. projectSchema.plugin.js
|
|
69
|
+
- Plugin providing relationship management methods
|
|
70
|
+
- Key functions: allLeanByIds, allLeanByUuids, createWithRelationships, deleteWithRelationships, toJsonWithRelationships, updateWithRelationships
|
|
71
|
+
- Utility functions: idsToUuids, uuidsToIds, oneByUuid, oneByXid
|
|
72
|
+
|
|
73
|
+
2. constants.ts
|
|
74
|
+
```typescript
|
|
75
|
+
import { v5 as uuidv5 } from "uuid";
|
|
76
|
+
|
|
77
|
+
const NAMESPACE_ROOT = "your-namespace-uuid";
|
|
78
|
+
export const NAMESPACE = {
|
|
79
|
+
USER: uuidv5("USER", NAMESPACE_ROOT),
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const SCHEMA = {
|
|
83
|
+
USER: "user",
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export default {
|
|
87
|
+
NAMESPACE,
|
|
88
|
+
SCHEMA,
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
3. user.schema.ts
|
|
93
|
+
```typescript
|
|
94
|
+
import { Schema } from "mongoose";
|
|
95
|
+
import projectSchema from "./projectSchema.plugin.js";
|
|
96
|
+
|
|
97
|
+
const schema = new Schema(
|
|
98
|
+
{
|
|
99
|
+
deletedAt: {
|
|
100
|
+
type: Schema.Types.Date,
|
|
101
|
+
},
|
|
102
|
+
name: {
|
|
103
|
+
type: Schema.Types.String,
|
|
104
|
+
},
|
|
105
|
+
uuid: {
|
|
106
|
+
index: true,
|
|
107
|
+
type: Schema.Types.String,
|
|
108
|
+
},
|
|
109
|
+
xid: {
|
|
110
|
+
index: true,
|
|
111
|
+
type: Schema.Types.String,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{ timestamps: true },
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
schema.plugin(projectSchema);
|
|
118
|
+
|
|
119
|
+
export default schema;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
4. index.ts
|
|
123
|
+
```typescript
|
|
124
|
+
import { connect, disconnect, envsKey, log } from "jaypie";
|
|
125
|
+
import mongoose, { Model, Schema } from "mongoose";
|
|
126
|
+
import { SCHEMA } from "./constants.js";
|
|
127
|
+
import userSchema from "./user.schema.js";
|
|
128
|
+
|
|
129
|
+
let instantiatedModel: Record<string, Model<any>> | null;
|
|
130
|
+
const { model } = mongoose;
|
|
131
|
+
|
|
132
|
+
function getModel(name: string, schema: Schema): Model<any> {
|
|
133
|
+
if (!instantiatedModel) {
|
|
134
|
+
log.warn("[@yournamespace/models] Models have not been instantiated");
|
|
135
|
+
instantiatedModel = {};
|
|
136
|
+
}
|
|
137
|
+
return instantiatedModel[name] || (instantiatedModel[name] = model(name, schema));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export default {
|
|
141
|
+
connect: async (uri: string = envsKey("MONGODB_URI")) => {
|
|
142
|
+
if (instantiatedModel) {
|
|
143
|
+
log.warn("[@yournamespace/models] Models already instantiated");
|
|
144
|
+
} else {
|
|
145
|
+
instantiatedModel = {};
|
|
146
|
+
}
|
|
147
|
+
return uri ? mongoose.connect(uri) : connect();
|
|
148
|
+
},
|
|
149
|
+
disconnect: () => {
|
|
150
|
+
instantiatedModel = null;
|
|
151
|
+
return disconnect();
|
|
152
|
+
},
|
|
153
|
+
get User() {
|
|
154
|
+
return getModel(SCHEMA.USER, userSchema);
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export { default as MODEL } from "./constants.js";
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Testing
|
|
162
|
+
|
|
163
|
+
1. vite.config.ts
|
|
164
|
+
```typescript
|
|
165
|
+
import { defineConfig } from "vite";
|
|
166
|
+
|
|
167
|
+
export default defineConfig({
|
|
168
|
+
test: {
|
|
169
|
+
globals: false,
|
|
170
|
+
setupFiles: ["./testSetup.ts"],
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
2. testSetup.ts
|
|
176
|
+
```typescript
|
|
177
|
+
import { beforeEach, vi } from "vitest";
|
|
178
|
+
import mongoose from "mongoose";
|
|
179
|
+
|
|
180
|
+
// Mock mongoose methods
|
|
181
|
+
vi.mock("mongoose", async () => {
|
|
182
|
+
const actual = await vi.importActual("mongoose");
|
|
183
|
+
return {
|
|
184
|
+
...actual,
|
|
185
|
+
connect: vi.fn().mockResolvedValue({}),
|
|
186
|
+
disconnect: vi.fn().mockResolvedValue({}),
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Reset mocks before each test
|
|
191
|
+
beforeEach(() => {
|
|
192
|
+
vi.clearAllMocks();
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Usage
|
|
197
|
+
|
|
198
|
+
1. Connect to database:
|
|
199
|
+
```typescript
|
|
200
|
+
import Model from "@yournamespace/models";
|
|
201
|
+
|
|
202
|
+
await Model.connect();
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
2. Create document:
|
|
206
|
+
```typescript
|
|
207
|
+
const user = await Model.User.createWithRelationships({
|
|
208
|
+
uuid: "user-uuid",
|
|
209
|
+
values: { name: "Test User" },
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
3. Find document:
|
|
214
|
+
```typescript
|
|
215
|
+
const user = await Model.User.oneByUuid("user-uuid");
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
4. Update with relationships:
|
|
219
|
+
```typescript
|
|
220
|
+
await Model.User.updateWithRelationships({
|
|
221
|
+
uuid: "user-uuid",
|
|
222
|
+
values: { name: "Updated Name" },
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
5. Delete with relationships:
|
|
227
|
+
```typescript
|
|
228
|
+
await Model.User.deleteWithRelationships({
|
|
229
|
+
uuid: "user-uuid",
|
|
230
|
+
});
|
|
231
|
+
```
|