@breadstone/archipel-mcp 0.0.21 → 0.0.23
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 +32 -13
- package/data/guides/ai-text-generation.md +16 -24
- package/data/guides/cryptography-and-otp.md +2 -2
- package/data/guides/database-setup.md +4 -3
- package/data/guides/email-templates.md +52 -42
- package/data/guides/getting-started.md +6 -6
- package/data/guides/resource-management.md +9 -9
- package/data/packages/platform-authentication/api/Interface.IMfaSubjectUpdate.md +1 -1
- package/data/packages/platform-authentication/api/index.md +1 -1
- package/data/packages/platform-blob-storage/api/Variable.AWS_S3_PROVIDER_OPTIONS.md +1 -1
- package/data/packages/platform-blob-storage/api/Variable.AZURE_BLOB_PROVIDER_OPTIONS.md +1 -1
- package/data/packages/platform-blob-storage/api/Variable.BLOB_PROVIDER.md +1 -1
- package/data/packages/platform-blob-storage/api/Variable.VERCEL_BLOB_PROVIDER_OPTIONS.md +1 -1
- package/data/packages/platform-caching/api/Class.RedisLayeredCache.md +3 -3
- package/data/packages/platform-core/api/Class.ErrorTemplateService.md +1 -1
- package/data/packages/platform-core/api/Class.HostService.md +1 -1
- package/data/packages/platform-core/api/Variable.ID_GENERATOR_TOKEN.md +1 -1
- package/data/packages/platform-core/api/index.md +0 -27
- package/data/packages/platform-core/index.md +7 -4
- package/data/packages/platform-cryptography/api/Class.BcryptService.md +4 -4
- package/data/packages/platform-cryptography/api/Class.OtpService.md +6 -6
- package/data/packages/platform-cryptography/api/Variable.BCRYPT_OPTIONS.md +2 -2
- package/data/packages/platform-cryptography/api/Variable.MAX_BCRYPT_PASSWORD_BYTES.md +1 -1
- package/data/packages/platform-cryptography/api/Variable.MIN_BCRYPT_ROUNDS.md +1 -1
- package/data/packages/platform-cryptography/api/Variable.OTP_OPTIONS.md +2 -2
- package/data/packages/platform-cryptography/api/Variable.OTP_SERVICE_TOKEN.md +2 -2
- package/data/packages/platform-cryptography/api/Variable.TOTP_EPOCH_TOLERANCE.md +1 -1
- package/data/packages/platform-cryptography/api/index.md +3 -3
- package/data/packages/platform-documents/api/Class.BaseDocumentRenderer.md +32 -1
- package/data/packages/platform-documents/api/Class.DocumentEngine.md +4 -4
- package/data/packages/platform-documents/api/Class.DocumentModule.md +2 -2
- package/data/packages/platform-documents/api/Class.DocxDocumentRenderer2.md +333 -0
- package/data/packages/platform-documents/api/Class.PdfDocumentRenderer.md +355 -0
- package/data/packages/platform-documents/api/Interface.IDocumentModuleOptions.md +31 -5
- package/data/packages/platform-documents/api/Variable.DOCUMENT_MODULE_OPTIONS.md +1 -1
- package/data/packages/platform-documents/api/Variable.DOCUMENT_PARSER_TOKEN.md +1 -1
- package/data/packages/platform-documents/api/Variable.DOCUMENT_RENDERER_TOKEN.md +1 -1
- package/data/packages/platform-documents/api/Variable.IMAGE_PROCESSOR_TOKEN.md +1 -1
- package/data/packages/platform-documents/api/index.md +2 -0
- package/data/packages/platform-esigning/api/Class.EsigningClientPort.md +1 -1
- package/data/packages/platform-health/index.md +128 -0
- package/data/packages/platform-mailing/api/Class.DeliveryStrategyBase.md +0 -1
- package/data/packages/platform-mailing/api/Class.MailModule.md +1 -1
- package/data/packages/platform-mailing/api/Class.MailVerificationService.md +1 -1
- package/data/packages/platform-mailing/api/Class.TemplateFetchStrategyBase.md +0 -5
- package/data/packages/platform-mailing/api/Variable.SMTP_CONFIG_ENTRIES.md +14 -0
- package/data/packages/platform-mailing/api/Variable.SMTP_HOST.md +14 -0
- package/data/packages/platform-mailing/api/Variable.SMTP_PASSWORD.md +14 -0
- package/data/packages/platform-mailing/api/Variable.SMTP_PORT.md +14 -0
- package/data/packages/platform-mailing/api/Variable.SMTP_SECURE.md +14 -0
- package/data/packages/platform-mailing/api/Variable.SMTP_USER.md +14 -0
- package/data/packages/platform-mailing/api/index.md +7 -4
- package/data/packages/platform-mapping/index.md +121 -0
- package/data/packages/platform-mcp/api/Variable.MCP_MODULE_OPTIONS.md +1 -1
- package/data/packages/platform-openapi/api/Class.SwaggerMultiDocumentService.md +4 -4
- package/data/packages/platform-resources/index.md +135 -0
- package/data/packages/platform-telemetry/api/Class.OtelSdkHolder.md +1 -1
- package/data/packages/platform-telemetry/api/Variable.TELEMETRY_ENABLED.md +1 -1
- package/data/packages/platform-telemetry/api/Variable.TELEMETRY_FACADE.md +1 -1
- package/data/packages/platform-telemetry/api/Variable.TELEMETRY_OPTIONS.md +1 -1
- package/{src/knowledge/configPattern.js → data/patterns/config-pattern.md} +46 -49
- package/{src/knowledge/dtoPattern.js → data/patterns/dto-pattern.md} +58 -61
- package/{src/knowledge/errorHandlingPattern.js → data/patterns/error-handling-pattern.md} +35 -38
- package/{src/knowledge/guardPattern.js → data/patterns/guard-pattern.md} +35 -38
- package/{src/knowledge/mappingPattern.js → data/patterns/mapping-pattern.md} +43 -144
- package/data/patterns/module-pattern.md +182 -0
- package/data/patterns/query-pattern.md +137 -0
- package/data/patterns/repository-pattern.md +208 -0
- package/{src/knowledge/testingPattern.js → data/patterns/testing-pattern.md} +37 -40
- package/package.json +2 -2
- package/src/PatternsLoader.d.ts +12 -0
- package/src/PatternsLoader.js +65 -0
- package/src/generators/mappingPatternGenerator.d.ts +5 -0
- package/src/generators/mappingPatternGenerator.js +107 -0
- package/src/generators/modulePatternGenerator.d.ts +5 -0
- package/src/generators/modulePatternGenerator.js +107 -0
- package/src/generators/queryPatternGenerator.d.ts +4 -0
- package/src/generators/queryPatternGenerator.js +83 -0
- package/src/generators/repositoryPatternGenerator.d.ts +5 -0
- package/src/generators/repositoryPatternGenerator.js +165 -0
- package/src/main.js +15 -9
- package/src/models/IPatternDoc.d.ts +15 -0
- package/src/models/IPatternDoc.js +3 -0
- package/src/tools/registerGetConfigPatternTool.d.ts +2 -1
- package/src/tools/registerGetConfigPatternTool.js +5 -4
- package/src/tools/registerGetDtoPatternTool.d.ts +2 -1
- package/src/tools/registerGetDtoPatternTool.js +5 -4
- package/src/tools/registerGetErrorHandlingPatternTool.d.ts +2 -1
- package/src/tools/registerGetErrorHandlingPatternTool.js +5 -4
- package/src/tools/registerGetGuardPatternTool.d.ts +2 -1
- package/src/tools/registerGetGuardPatternTool.js +5 -4
- package/src/tools/registerGetMappingPatternTool.d.ts +2 -1
- package/src/tools/registerGetMappingPatternTool.js +6 -5
- package/src/tools/registerGetModulePatternTool.d.ts +2 -1
- package/src/tools/registerGetModulePatternTool.js +6 -5
- package/src/tools/registerGetQueryPatternTool.d.ts +2 -1
- package/src/tools/registerGetQueryPatternTool.js +6 -5
- package/src/tools/registerGetRepositoryPatternTool.d.ts +2 -1
- package/src/tools/registerGetRepositoryPatternTool.js +6 -5
- package/src/tools/registerGetTestingPatternTool.d.ts +2 -1
- package/src/tools/registerGetTestingPatternTool.js +5 -4
- package/data/packages/platform-core/api/Class.BlobResourceStrategy.md +0 -195
- package/data/packages/platform-core/api/Class.EmbeddedResourceStrategy.md +0 -215
- package/data/packages/platform-core/api/Class.FileResourceStrategy.md +0 -192
- package/data/packages/platform-core/api/Class.HealthModule.md +0 -42
- package/data/packages/platform-core/api/Class.HealthOrchestrator.md +0 -64
- package/data/packages/platform-core/api/Class.MappingBuilder.md +0 -110
- package/data/packages/platform-core/api/Class.MappingModule.md +0 -46
- package/data/packages/platform-core/api/Class.MappingNotRegisteredError.md +0 -56
- package/data/packages/platform-core/api/Class.MappingProfileBase.md +0 -52
- package/data/packages/platform-core/api/Class.MappingService.md +0 -284
- package/data/packages/platform-core/api/Class.ResourceManager.md +0 -565
- package/data/packages/platform-core/api/Class.ResourceModule.md +0 -46
- package/data/packages/platform-core/api/Class.TypeMappingNotRegisteredError.md +0 -57
- package/data/packages/platform-core/api/Function.createMappingKey.md +0 -39
- package/data/packages/platform-core/api/Interface.IBlobResourceStrategyConfig.md +0 -28
- package/data/packages/platform-core/api/Interface.IBlobServiceAdapter.md +0 -40
- package/data/packages/platform-core/api/Interface.IFileResourceStrategyConfig.md +0 -72
- package/data/packages/platform-core/api/Interface.IHealthCheckResult.md +0 -46
- package/data/packages/platform-core/api/Interface.IHealthIndicator.md +0 -41
- package/data/packages/platform-core/api/Interface.IMappingBuilder.md +0 -76
- package/data/packages/platform-core/api/Interface.IMappingKey.md +0 -58
- package/data/packages/platform-core/api/Interface.IMappingProfile.md +0 -32
- package/data/packages/platform-core/api/Interface.IResourceManagerConfig.md +0 -89
- package/data/packages/platform-core/api/Interface.IResourceMetadata.md +0 -94
- package/data/packages/platform-core/api/Interface.IResourceResult.md +0 -34
- package/data/packages/platform-core/api/Interface.IResourceStrategy.md +0 -134
- package/data/packages/platform-core/api/Variable.HEALTH_INDICATORS_TOKEN.md +0 -14
- package/data/packages/platform-mailing/api/Class.BlobTemplateFetchStrategy.md +0 -60
- package/data/packages/platform-mailing/api/Class.FileTemplateFetchStrategy.md +0 -58
- package/data/packages/platform-mailing/api/Class.LogDeliveryStrategy.md +0 -71
- package/src/knowledge/configPattern.d.ts +0 -5
- package/src/knowledge/dtoPattern.d.ts +0 -5
- package/src/knowledge/errorHandlingPattern.d.ts +0 -5
- package/src/knowledge/guardPattern.d.ts +0 -5
- package/src/knowledge/mappingPattern.d.ts +0 -6
- package/src/knowledge/modulePattern.d.ts +0 -6
- package/src/knowledge/modulePattern.js +0 -283
- package/src/knowledge/queryPattern.d.ts +0 -6
- package/src/knowledge/queryPattern.js +0 -215
- package/src/knowledge/repositoryPattern.d.ts +0 -6
- package/src/knowledge/repositoryPattern.js +0 -367
- package/src/knowledge/testingPattern.d.ts +0 -5
|
@@ -1,35 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
exports.TESTING_PATTERN_KNOWLEDGE = `# Archipel Testing Pattern
|
|
1
|
+
---
|
|
2
|
+
title: Testing Pattern
|
|
3
|
+
description: Vitest conventions, mocking patterns for repositories/services/delegates, AAA structure, and test naming conventions.
|
|
4
|
+
order: 9
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Archipel Testing Pattern
|
|
9
8
|
|
|
10
9
|
## Overview
|
|
11
10
|
|
|
12
11
|
Archipel uses **Vitest** for unit and integration tests with **vi mocking**. Tests follow
|
|
13
|
-
the Arrange-Act-Assert (AAA) pattern with descriptive
|
|
12
|
+
the Arrange-Act-Assert (AAA) pattern with descriptive `describe`/`it` blocks. Each test
|
|
14
13
|
file covers a single class or module.
|
|
15
14
|
|
|
16
15
|
## Test Framework
|
|
17
16
|
|
|
18
17
|
- **Runner:** Vitest
|
|
19
|
-
- **Mocking:**
|
|
20
|
-
- **Assertions:** Vitest built-in (
|
|
18
|
+
- **Mocking:** `vi.fn()`, `vi.mock()`, `vi.spyOn()`
|
|
19
|
+
- **Assertions:** Vitest built-in (`expect`)
|
|
21
20
|
- **E2E:** Supertest against a bootstrapped NestJS app
|
|
22
21
|
|
|
23
22
|
## File Naming & Location
|
|
24
23
|
|
|
25
24
|
| Test Type | File Pattern | Location |
|
|
26
25
|
|-----------|-------------|----------|
|
|
27
|
-
| Unit test |
|
|
28
|
-
| E2E test |
|
|
26
|
+
| Unit test | `*.spec.ts` | Next to the source file |
|
|
27
|
+
| E2E test | `*.e2e-spec.ts` | `test/` directory |
|
|
29
28
|
|
|
30
29
|
## Basic Test Structure
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
```typescript
|
|
33
32
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
34
33
|
|
|
35
34
|
describe('UserService', () => {
|
|
@@ -88,13 +87,13 @@ describe('UserService', () => {
|
|
|
88
87
|
// #endregion
|
|
89
88
|
|
|
90
89
|
});
|
|
91
|
-
|
|
90
|
+
```
|
|
92
91
|
|
|
93
92
|
## Mocking Patterns
|
|
94
93
|
|
|
95
94
|
### Mocking Prisma Delegates (for Repository Tests)
|
|
96
95
|
|
|
97
|
-
|
|
96
|
+
```typescript
|
|
98
97
|
vi.mock('@prisma/client/runtime/client', () => ({
|
|
99
98
|
PrismaClientKnownRequestError: class PrismaClientKnownRequestError extends Error {
|
|
100
99
|
public code: string;
|
|
@@ -117,11 +116,11 @@ vi.mock('@prisma/client/runtime/client', () => ({
|
|
|
117
116
|
}
|
|
118
117
|
},
|
|
119
118
|
}));
|
|
120
|
-
|
|
119
|
+
```
|
|
121
120
|
|
|
122
121
|
### Creating a Mock Delegate
|
|
123
122
|
|
|
124
|
-
|
|
123
|
+
```typescript
|
|
125
124
|
type MockDelegate = Record<
|
|
126
125
|
| 'aggregate' | 'count' | 'create' | 'createMany' | 'createManyAndReturn'
|
|
127
126
|
| 'delete' | 'deleteMany' | 'findFirst' | 'findFirstOrThrow'
|
|
@@ -150,31 +149,31 @@ function createMockDelegate(): MockDelegate {
|
|
|
150
149
|
findUniqueOrThrow: vi.fn(),
|
|
151
150
|
};
|
|
152
151
|
}
|
|
153
|
-
|
|
152
|
+
```
|
|
154
153
|
|
|
155
154
|
### Mocking DatabaseService
|
|
156
155
|
|
|
157
|
-
|
|
156
|
+
```typescript
|
|
158
157
|
const mockDb = {
|
|
159
158
|
transactionCallback: vi.fn(),
|
|
160
159
|
client: {
|
|
161
160
|
user: createMockDelegate(),
|
|
162
161
|
},
|
|
163
162
|
} as unknown as DatabaseService;
|
|
164
|
-
|
|
163
|
+
```
|
|
165
164
|
|
|
166
165
|
### Mocking a Query
|
|
167
166
|
|
|
168
|
-
|
|
167
|
+
```typescript
|
|
169
168
|
const mockQuery = {
|
|
170
169
|
name: 'findUserById',
|
|
171
170
|
run: vi.fn().mockResolvedValue({ id: '1', email: 'test@example.com' }),
|
|
172
171
|
};
|
|
173
|
-
|
|
172
|
+
```
|
|
174
173
|
|
|
175
174
|
## Repository Test Pattern
|
|
176
175
|
|
|
177
|
-
|
|
176
|
+
```typescript
|
|
178
177
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
179
178
|
|
|
180
179
|
// Mock Prisma runtime errors BEFORE importing test subject
|
|
@@ -228,11 +227,11 @@ describe('UserRepository', () => {
|
|
|
228
227
|
});
|
|
229
228
|
|
|
230
229
|
});
|
|
231
|
-
|
|
230
|
+
```
|
|
232
231
|
|
|
233
232
|
## Service Test Pattern
|
|
234
233
|
|
|
235
|
-
|
|
234
|
+
```typescript
|
|
236
235
|
describe('ProductService', () => {
|
|
237
236
|
|
|
238
237
|
let service: ProductService;
|
|
@@ -268,11 +267,11 @@ describe('ProductService', () => {
|
|
|
268
267
|
});
|
|
269
268
|
|
|
270
269
|
});
|
|
271
|
-
|
|
270
|
+
```
|
|
272
271
|
|
|
273
272
|
## Mapping Profile Test Pattern
|
|
274
273
|
|
|
275
|
-
|
|
274
|
+
```typescript
|
|
276
275
|
describe('ProductMappingProfile', () => {
|
|
277
276
|
|
|
278
277
|
let mappingService: MappingService;
|
|
@@ -304,23 +303,23 @@ describe('ProductMappingProfile', () => {
|
|
|
304
303
|
});
|
|
305
304
|
|
|
306
305
|
});
|
|
307
|
-
|
|
306
|
+
```
|
|
308
307
|
|
|
309
308
|
## Test Conventions
|
|
310
309
|
|
|
311
310
|
### Comments
|
|
312
311
|
|
|
313
|
-
|
|
312
|
+
```typescript
|
|
314
313
|
// Use AAA comments:
|
|
315
314
|
// arrange — set up test data and mocks
|
|
316
315
|
// act — call the method under test
|
|
317
316
|
// act & assert — when the assertion is on the thrown error
|
|
318
317
|
// assert — verify the outcome
|
|
319
|
-
|
|
318
|
+
```
|
|
320
319
|
|
|
321
320
|
### Regions
|
|
322
321
|
|
|
323
|
-
|
|
322
|
+
```typescript
|
|
324
323
|
describe('MyClass', () => {
|
|
325
324
|
|
|
326
325
|
// #region Fields
|
|
@@ -334,23 +333,21 @@ describe('MyClass', () => {
|
|
|
334
333
|
// #endregion
|
|
335
334
|
|
|
336
335
|
});
|
|
337
|
-
|
|
336
|
+
```
|
|
338
337
|
|
|
339
338
|
### Naming
|
|
340
339
|
|
|
341
|
-
-
|
|
342
|
-
-
|
|
340
|
+
- `describe` blocks: Class name or method name
|
|
341
|
+
- `it` blocks: `'should <expected behavior> when <condition>'`
|
|
343
342
|
|
|
344
343
|
## Rules
|
|
345
344
|
|
|
346
345
|
1. **Every public service method needs at least one happy-path and one failure-path test.**
|
|
347
|
-
2. **Use
|
|
346
|
+
2. **Use `vi.restoreAllMocks()` in `beforeEach`** — prevent mock leakage between tests.
|
|
348
347
|
3. **Mock at the boundary** — mock repositories in service tests, mock delegates in repository tests.
|
|
349
348
|
4. **AAA pattern** — clearly separate arrange, act, assert with comments.
|
|
350
|
-
5.
|
|
349
|
+
5. **`vi.mock()` for modules must appear before imports** of the mocked module.
|
|
351
350
|
6. **No real database in unit tests** — use mocks. Use Testcontainers for integration tests.
|
|
352
351
|
7. **Assert on behavior, not implementation** — verify return values and thrown errors, not internal calls
|
|
353
352
|
(unless the call IS the behavior, e.g., verifying a repository was called).
|
|
354
|
-
8. **Use
|
|
355
|
-
`;
|
|
356
|
-
//# sourceMappingURL=testingPattern.js.map
|
|
353
|
+
8. **Use `mockResolvedValue` / `mockRejectedValue`** for async mocks.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@breadstone/archipel-mcp",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "MCP server providing Archipel platform knowledge
|
|
3
|
+
"version": "0.0.23",
|
|
4
|
+
"description": "MCP server providing Archipel platform knowledge - documentation, query patterns, and coding conventions - to AI development tools.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/main.js",
|
|
7
7
|
"bin": "./src/main.js",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IPatternDoc } from './models/IPatternDoc';
|
|
2
|
+
/**
|
|
3
|
+
* Loads and indexes Archipel code patterns from the `.docs/patterns/`
|
|
4
|
+
* directory (monorepo dev) or from the bundled `data/patterns/` directory
|
|
5
|
+
* (published npm package).
|
|
6
|
+
*/
|
|
7
|
+
export declare class PatternsLoader {
|
|
8
|
+
private readonly _patterns;
|
|
9
|
+
get patterns(): ReadonlyMap<string, IPatternDoc>;
|
|
10
|
+
load(): void;
|
|
11
|
+
private resolvePatternsDirectory;
|
|
12
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PatternsLoader = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const gray_matter_1 = tslib_1.__importDefault(require("gray-matter"));
|
|
6
|
+
const fs = tslib_1.__importStar(require("node:fs"));
|
|
7
|
+
const path = tslib_1.__importStar(require("node:path"));
|
|
8
|
+
/**
|
|
9
|
+
* Loads and indexes Archipel code patterns from the `.docs/patterns/`
|
|
10
|
+
* directory (monorepo dev) or from the bundled `data/patterns/` directory
|
|
11
|
+
* (published npm package).
|
|
12
|
+
*/
|
|
13
|
+
class PatternsLoader {
|
|
14
|
+
// #region Fields
|
|
15
|
+
_patterns = new Map();
|
|
16
|
+
// #endregion
|
|
17
|
+
// #region Properties
|
|
18
|
+
get patterns() {
|
|
19
|
+
return this._patterns;
|
|
20
|
+
}
|
|
21
|
+
// #endregion
|
|
22
|
+
// #region Methods
|
|
23
|
+
load() {
|
|
24
|
+
const patternsDirectory = this.resolvePatternsDirectory();
|
|
25
|
+
if (!patternsDirectory) {
|
|
26
|
+
process.stderr.write('[archipel-mcp] Warning: Could not locate patterns directory.\n');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const files = fs.readdirSync(patternsDirectory).filter((file) => file.endsWith('.md') && file !== 'index.md');
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
const filePath = path.join(patternsDirectory, file);
|
|
32
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
33
|
+
const parsed = (0, gray_matter_1.default)(raw);
|
|
34
|
+
const name = path.basename(file, '.md');
|
|
35
|
+
this._patterns.set(name, {
|
|
36
|
+
name,
|
|
37
|
+
title: parsed.data['title'] || name,
|
|
38
|
+
description: parsed.data['description'] || '',
|
|
39
|
+
order: parsed.data['order'] || 999,
|
|
40
|
+
content: parsed.content.trim(),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
process.stderr.write(`[archipel-mcp] Loaded ${this._patterns.size} pattern(s)\n`);
|
|
44
|
+
}
|
|
45
|
+
resolvePatternsDirectory() {
|
|
46
|
+
// 1. Bundled data (published npm package)
|
|
47
|
+
const bundledPath = path.resolve(__dirname, '..', 'data', 'patterns');
|
|
48
|
+
if (fs.existsSync(bundledPath)) {
|
|
49
|
+
return bundledPath;
|
|
50
|
+
}
|
|
51
|
+
// 2. Workspace root (monorepo dev)
|
|
52
|
+
const cwdPath = path.resolve(process.cwd(), '.docs', 'patterns');
|
|
53
|
+
if (fs.existsSync(cwdPath)) {
|
|
54
|
+
return cwdPath;
|
|
55
|
+
}
|
|
56
|
+
// 3. Relative from compiled source (dist/tools/mcp/src/)
|
|
57
|
+
const relativePath = path.resolve(__dirname, '..', '..', '..', '..', '.docs', 'patterns');
|
|
58
|
+
if (fs.existsSync(relativePath)) {
|
|
59
|
+
return relativePath;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.PatternsLoader = PatternsLoader;
|
|
65
|
+
//# sourceMappingURL=PatternsLoader.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a full mapping example (input interface, key, profile, module registration,
|
|
3
|
+
* controller usage) for a given entity and its target response class.
|
|
4
|
+
*/
|
|
5
|
+
export declare function MAPPING_PATTERN_WITH_CONTEXT(entityName: string, fields: string[], responseName: string): string;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAPPING_PATTERN_WITH_CONTEXT = MAPPING_PATTERN_WITH_CONTEXT;
|
|
4
|
+
/**
|
|
5
|
+
* Generates a full mapping example (input interface, key, profile, module registration,
|
|
6
|
+
* controller usage) for a given entity and its target response class.
|
|
7
|
+
*/
|
|
8
|
+
function MAPPING_PATTERN_WITH_CONTEXT(entityName, fields, responseName) {
|
|
9
|
+
return `
|
|
10
|
+
## Example: Mapping for "${entityName}" → "${responseName}"
|
|
11
|
+
|
|
12
|
+
Given an entity \`${entityName}\` with fields: ${fields.map((f) => `\`${f}\``).join(', ')}
|
|
13
|
+
|
|
14
|
+
### 1. Input Interface
|
|
15
|
+
|
|
16
|
+
\`\`\`typescript
|
|
17
|
+
// models/mapping-inputs/I${entityName}MappingInput.ts
|
|
18
|
+
|
|
19
|
+
export interface I${entityName}MappingInput {
|
|
20
|
+
${fields.map((f) => ` readonly ${f}: ${inferMappingFieldType(f)};`).join('\n')}
|
|
21
|
+
}
|
|
22
|
+
\`\`\`
|
|
23
|
+
|
|
24
|
+
### 2. Mapping Key
|
|
25
|
+
|
|
26
|
+
\`\`\`typescript
|
|
27
|
+
// constants/MappingKeys.ts
|
|
28
|
+
import { createMappingKey } from '@breadstone/archipel-platform-mapping';
|
|
29
|
+
import { I${entityName}MappingInput } from '../models/mapping-inputs/I${entityName}MappingInput';
|
|
30
|
+
import { ${responseName} } from '../dtos/${responseName}';
|
|
31
|
+
|
|
32
|
+
export const ${toConstantCase(entityName)}_MAPPING_KEY = createMappingKey<I${entityName}MappingInput, ${responseName}>('${toDotNotation(entityName)}');
|
|
33
|
+
\`\`\`
|
|
34
|
+
|
|
35
|
+
### 3. Mapping Profile
|
|
36
|
+
|
|
37
|
+
\`\`\`typescript
|
|
38
|
+
// mappers/${entityName}MappingProfile.ts
|
|
39
|
+
import { MappingProfileBase, IMappingBuilder } from '@breadstone/archipel-platform-mapping';
|
|
40
|
+
import { ${toConstantCase(entityName)}_MAPPING_KEY } from '../constants/MappingKeys';
|
|
41
|
+
import { I${entityName}MappingInput } from '../models/mapping-inputs/I${entityName}MappingInput';
|
|
42
|
+
import { ${responseName} } from '../dtos/${responseName}';
|
|
43
|
+
|
|
44
|
+
export class ${entityName}MappingProfile extends MappingProfileBase {
|
|
45
|
+
|
|
46
|
+
// #region Methods
|
|
47
|
+
|
|
48
|
+
public configure(builder: IMappingBuilder): void {
|
|
49
|
+
builder.createKeyedMap(${toConstantCase(entityName)}_MAPPING_KEY, (input: I${entityName}MappingInput) => {
|
|
50
|
+
const response = new ${responseName}();
|
|
51
|
+
${fields.map((f) => ` response.${f} = input.${f};`).join('\n')}
|
|
52
|
+
|
|
53
|
+
return response;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// #endregion
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
\`\`\`
|
|
61
|
+
|
|
62
|
+
### 4. Module Registration
|
|
63
|
+
|
|
64
|
+
\`\`\`typescript
|
|
65
|
+
import { MappingModule } from '@breadstone/archipel-platform-mapping';
|
|
66
|
+
import { ${entityName}MappingProfile } from './mappers/${entityName}MappingProfile';
|
|
67
|
+
|
|
68
|
+
@Module({
|
|
69
|
+
imports: [
|
|
70
|
+
MappingModule.withProfiles([${entityName}MappingProfile]),
|
|
71
|
+
],
|
|
72
|
+
})
|
|
73
|
+
export class ${entityName}Module {}
|
|
74
|
+
\`\`\`
|
|
75
|
+
|
|
76
|
+
### 5. Controller Usage
|
|
77
|
+
|
|
78
|
+
\`\`\`typescript
|
|
79
|
+
// In a controller method:
|
|
80
|
+
const entity = await this._${lowerFirst(entityName)}Service.findById(id);
|
|
81
|
+
const response = this._mappingService.map(${toConstantCase(entityName)}_MAPPING_KEY, entity);
|
|
82
|
+
\`\`\`
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
function inferMappingFieldType(fieldName) {
|
|
86
|
+
if (fieldName === 'id')
|
|
87
|
+
return 'string';
|
|
88
|
+
if (fieldName.endsWith('Id'))
|
|
89
|
+
return 'string';
|
|
90
|
+
if (fieldName.endsWith('At') || fieldName === 'createdAt' || fieldName === 'updatedAt')
|
|
91
|
+
return 'Date';
|
|
92
|
+
if (fieldName.startsWith('is') || fieldName.startsWith('has'))
|
|
93
|
+
return 'boolean';
|
|
94
|
+
if (fieldName === 'count' || fieldName === 'quantity' || fieldName === 'amount' || fieldName === 'price')
|
|
95
|
+
return 'number';
|
|
96
|
+
return 'string';
|
|
97
|
+
}
|
|
98
|
+
function toConstantCase(name) {
|
|
99
|
+
return name.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase();
|
|
100
|
+
}
|
|
101
|
+
function toDotNotation(name) {
|
|
102
|
+
return name.replace(/([a-z])([A-Z])/g, '$1.$2').toLowerCase();
|
|
103
|
+
}
|
|
104
|
+
function lowerFirst(str) {
|
|
105
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=mappingPatternGenerator.js.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MODULE_PATTERN_WITH_CONTEXT = MODULE_PATTERN_WITH_CONTEXT;
|
|
4
|
+
/**
|
|
5
|
+
* Generates a dynamic NestJS module example with ports, options interface,
|
|
6
|
+
* module class, and consumer registration for the given module and port names.
|
|
7
|
+
*/
|
|
8
|
+
function MODULE_PATTERN_WITH_CONTEXT(moduleName, ports) {
|
|
9
|
+
return `
|
|
10
|
+
## Example: Dynamic Module "${moduleName}"
|
|
11
|
+
|
|
12
|
+
With ports: ${ports.map((p) => `\`${p}\``).join(', ')}
|
|
13
|
+
|
|
14
|
+
### Port Definitions
|
|
15
|
+
|
|
16
|
+
${ports
|
|
17
|
+
.map((port) => `\`\`\`typescript
|
|
18
|
+
// contracts/${port}.ts
|
|
19
|
+
|
|
20
|
+
export abstract class ${port} {
|
|
21
|
+
|
|
22
|
+
// Define abstract methods for the port contract
|
|
23
|
+
public abstract execute(/* args */): Promise<void>;
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
\`\`\``)
|
|
27
|
+
.join('\n\n')}
|
|
28
|
+
|
|
29
|
+
### Options Interface
|
|
30
|
+
|
|
31
|
+
\`\`\`typescript
|
|
32
|
+
// interfaces/I${moduleName}Options.ts
|
|
33
|
+
import { Type } from '@nestjs/common';
|
|
34
|
+
${ports.map((port) => `import { ${port} } from '../contracts/${port}';`).join('\n')}
|
|
35
|
+
|
|
36
|
+
export interface I${moduleName}Options {
|
|
37
|
+
${ports.map((port) => ` ${lowerFirstChar(port)}: Type<${port}>;`).join('\n')}
|
|
38
|
+
isGlobal?: boolean;
|
|
39
|
+
}
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
### Module Class
|
|
43
|
+
|
|
44
|
+
\`\`\`typescript
|
|
45
|
+
// ${moduleName}.ts
|
|
46
|
+
import { ConfigModule } from '@breadstone/archipel-platform-core';
|
|
47
|
+
import { type DynamicModule, Module, type Type } from '@nestjs/common';
|
|
48
|
+
import { I${moduleName}Options } from './interfaces/I${moduleName}Options';
|
|
49
|
+
${ports.map((port) => `import { ${port} } from './contracts/${port}';`).join('\n')}
|
|
50
|
+
|
|
51
|
+
@Module({})
|
|
52
|
+
export class ${moduleName} {
|
|
53
|
+
|
|
54
|
+
public static register(options: I${moduleName}Options): DynamicModule {
|
|
55
|
+
const portProviders = [
|
|
56
|
+
${ports.map((port) => ` { provide: ${port}, useClass: options.${lowerFirstChar(port)} },`).join('\n')}
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
global: options.isGlobal ?? false,
|
|
61
|
+
module: ${moduleName},
|
|
62
|
+
imports: [
|
|
63
|
+
ConfigModule.register('${toKebabCase(moduleName)}', PLATFORM_${toUpperSnakeCase(moduleName)}_CONFIG_ENTRIES),
|
|
64
|
+
],
|
|
65
|
+
providers: [
|
|
66
|
+
...portProviders,
|
|
67
|
+
// Add services, guards, interceptors here
|
|
68
|
+
],
|
|
69
|
+
exports: [
|
|
70
|
+
// Export public services, guards, interceptors
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
\`\`\`
|
|
77
|
+
|
|
78
|
+
### Consumer Usage
|
|
79
|
+
|
|
80
|
+
\`\`\`typescript
|
|
81
|
+
@Module({
|
|
82
|
+
imports: [
|
|
83
|
+
${moduleName}.register({
|
|
84
|
+
${ports.map((port) => ` ${lowerFirstChar(port)}: My${port}Adapter,`).join('\n')}
|
|
85
|
+
}),
|
|
86
|
+
],
|
|
87
|
+
})
|
|
88
|
+
export class AppModule {}
|
|
89
|
+
\`\`\`
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
function lowerFirstChar(str) {
|
|
93
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
94
|
+
}
|
|
95
|
+
function toKebabCase(name) {
|
|
96
|
+
return name
|
|
97
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
98
|
+
.toLowerCase()
|
|
99
|
+
.replace(/module$/, '');
|
|
100
|
+
}
|
|
101
|
+
function toUpperSnakeCase(name) {
|
|
102
|
+
return name
|
|
103
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
104
|
+
.toUpperCase()
|
|
105
|
+
.replace(/MODULE$/, '');
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=modulePatternGenerator.js.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QUERY_PATTERN_WITH_MODEL = QUERY_PATTERN_WITH_MODEL;
|
|
4
|
+
/**
|
|
5
|
+
* Generates model-specific query factory examples based on a Prisma model name and its fields.
|
|
6
|
+
*/
|
|
7
|
+
function QUERY_PATTERN_WITH_MODEL(modelName, fields) {
|
|
8
|
+
return `
|
|
9
|
+
## Example: Queries for "${modelName}"
|
|
10
|
+
|
|
11
|
+
Given a Prisma model \`${modelName}\` with fields: ${fields.map((f) => `\`${f}\``).join(', ')}
|
|
12
|
+
|
|
13
|
+
### findFirst query
|
|
14
|
+
\`\`\`typescript
|
|
15
|
+
import { Prisma } from '@prisma/client';
|
|
16
|
+
import { query } from '@breadstone/archipel-platform-database';
|
|
17
|
+
|
|
18
|
+
export function find${modelName}ByIdQuery(id: string) {
|
|
19
|
+
return query<Prisma.${modelName}Delegate, { ${fields.map((f) => `${f}: ${inferFieldType(f)}`).join('; ')} } | null>(
|
|
20
|
+
'find${modelName}ById',
|
|
21
|
+
(model) =>
|
|
22
|
+
model.findFirst({
|
|
23
|
+
where: { id },
|
|
24
|
+
select: { ${fields.map((f) => `${f}: true`).join(', ')} },
|
|
25
|
+
}),
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
\`\`\`
|
|
29
|
+
|
|
30
|
+
### findMany query
|
|
31
|
+
\`\`\`typescript
|
|
32
|
+
export function findAll${modelName}sQuery(skip = 0, take = 20) {
|
|
33
|
+
return query<Prisma.${modelName}Delegate, Array<{ ${fields.map((f) => `${f}: ${inferFieldType(f)}`).join('; ')} }>>(
|
|
34
|
+
'findAll${modelName}s',
|
|
35
|
+
(model) =>
|
|
36
|
+
model.findMany({
|
|
37
|
+
skip,
|
|
38
|
+
take,
|
|
39
|
+
select: { ${fields.map((f) => `${f}: true`).join(', ')} },
|
|
40
|
+
orderBy: { ${fields.includes('createdAt') ? 'createdAt' : fields[0]}: 'desc' },
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
\`\`\`
|
|
45
|
+
|
|
46
|
+
### count query
|
|
47
|
+
\`\`\`typescript
|
|
48
|
+
export function count${modelName}sQuery() {
|
|
49
|
+
return query<Prisma.${modelName}Delegate, number>(
|
|
50
|
+
'count${modelName}s',
|
|
51
|
+
(model) => model.count(),
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
### Service usage
|
|
57
|
+
\`\`\`typescript
|
|
58
|
+
// In a service method:
|
|
59
|
+
const item = await this._${lowerFirst(modelName)}Repository.execute(find${modelName}ByIdQuery(id));
|
|
60
|
+
const items = await this._${lowerFirst(modelName)}Repository.execute(findAll${modelName}sQuery(0, 50));
|
|
61
|
+
const total = await this._${lowerFirst(modelName)}Repository.execute(count${modelName}sQuery());
|
|
62
|
+
\`\`\`
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
function inferFieldType(fieldName) {
|
|
66
|
+
if (fieldName === 'id')
|
|
67
|
+
return 'string';
|
|
68
|
+
if (fieldName.endsWith('Id'))
|
|
69
|
+
return 'string';
|
|
70
|
+
if (fieldName.endsWith('At') || fieldName === 'createdAt' || fieldName === 'updatedAt')
|
|
71
|
+
return 'Date';
|
|
72
|
+
if (fieldName.startsWith('is') || fieldName.startsWith('has'))
|
|
73
|
+
return 'boolean';
|
|
74
|
+
if (fieldName === 'count' || fieldName === 'quantity' || fieldName === 'amount' || fieldName === 'order')
|
|
75
|
+
return 'number';
|
|
76
|
+
if (fieldName === 'email' || fieldName === 'name' || fieldName === 'title' || fieldName === 'description')
|
|
77
|
+
return 'string';
|
|
78
|
+
return 'unknown';
|
|
79
|
+
}
|
|
80
|
+
function lowerFirst(str) {
|
|
81
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=queryPatternGenerator.js.map
|