@caryyon/plugin-express 0.1.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/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # @caryyon/plugin-express
2
+
3
+ Lattice plugin for Express.js applications. Automatically discovers routes and dependencies, then submits to the Lattice collector for visualization.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Configure npm to use GitHub Packages for @caryyon scope
9
+ echo "@caryyon:registry=https://npm.pkg.github.com" >> .npmrc
10
+
11
+ # Install the plugin
12
+ yarn add @caryyon/plugin-express
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import express from 'express';
19
+ import { LatticePlugin } from '@caryyon/plugin-express';
20
+
21
+ const app = express();
22
+
23
+ // Your routes
24
+ app.get('/users', (req, res) => res.json([]));
25
+ app.post('/users', (req, res) => res.json({ id: 1 }));
26
+
27
+ // Add Lattice (AFTER all routes are defined)
28
+ const lattice = new LatticePlugin();
29
+ await lattice.analyze(app);
30
+
31
+ app.listen(3000);
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ ```typescript
37
+ const lattice = new LatticePlugin({
38
+ // Service identity
39
+ serviceName: 'my-service', // Auto-detected if not provided
40
+ environment: 'production', // Defaults to NODE_ENV
41
+
42
+ // API connection
43
+ apiEndpoint: 'https://api.lattice.dev/v1',
44
+ apiKey: process.env.LATTICE_API_KEY,
45
+
46
+ // Behavior
47
+ enabled: true, // Enable/disable plugin
48
+ autoSubmit: true, // Auto-submit on analyze
49
+ submitInterval: 300000, // Re-submit every 5 minutes
50
+
51
+ // Discovery options
52
+ discoverRoutes: true,
53
+ discoverDependencies: true,
54
+
55
+ // Callbacks
56
+ onAnalyzed: (metadata) => {
57
+ console.log(`Discovered ${metadata.routes.length} routes`);
58
+ },
59
+ onSubmitted: (response) => {
60
+ console.log(`Submitted: ${response.serviceId}`);
61
+ },
62
+ onError: (error) => {
63
+ console.error('Lattice error:', error);
64
+ },
65
+ });
66
+ ```
67
+
68
+ ## Environment Variables
69
+
70
+ ```bash
71
+ LATTICE_SERVICE_NAME=my-service
72
+ LATTICE_API_ENDPOINT=https://api.lattice.dev/v1
73
+ LATTICE_API_KEY=your-api-key
74
+ LATTICE_ENABLED=true
75
+ ```
76
+
77
+ ## API
78
+
79
+ ### `analyze(app: Express): Promise<ServiceMetadataSubmission>`
80
+
81
+ Analyze Express app and discover routes and dependencies.
82
+
83
+ ### `submit(metadata?: ServiceMetadataSubmission): Promise<SubmissionResponse>`
84
+
85
+ Submit metadata to Lattice collector API.
86
+
87
+ ### `getMetadata(): ServiceMetadataSubmission | null`
88
+
89
+ Get currently analyzed metadata.
90
+
91
+ ### `start(): void`
92
+
93
+ Start auto-submit interval.
94
+
95
+ ### `stop(): void`
96
+
97
+ Stop auto-submit interval.
98
+
99
+ ## License
100
+
101
+ MIT
@@ -0,0 +1,10 @@
1
+ import { ServiceMetadataSubmission } from '@caryyon/core';
2
+ import { SubmissionResponse } from '../config/types';
3
+ export declare class ApiClient {
4
+ private apiEndpoint;
5
+ private apiKey;
6
+ constructor(apiEndpoint: string, apiKey: string);
7
+ submitMetadata(metadata: ServiceMetadataSubmission): Promise<SubmissionResponse>;
8
+ healthCheck(): Promise<boolean>;
9
+ }
10
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/client/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAA+B,MAAM,eAAe,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAKrD,qBAAa,SAAS;IACpB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAEX,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAQzC,cAAc,CAAC,QAAQ,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkChF,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAatC"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiClient = void 0;
4
+ const core_1 = require("@caryyon/core");
5
+ class ApiClient {
6
+ apiEndpoint;
7
+ apiKey;
8
+ constructor(apiEndpoint, apiKey) {
9
+ this.apiEndpoint = apiEndpoint.replace(/\/$/, '');
10
+ this.apiKey = apiKey;
11
+ }
12
+ async submitMetadata(metadata) {
13
+ const url = `${this.apiEndpoint}${core_1.API_ENDPOINTS.INGEST_METADATA}`;
14
+ try {
15
+ const response = await fetch(url, {
16
+ method: 'POST',
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ ...(this.apiKey && { [core_1.HTTP_HEADERS.API_KEY]: this.apiKey }),
20
+ [core_1.HTTP_HEADERS.SCHEMA_VERSION]: '1.0.0',
21
+ },
22
+ body: JSON.stringify(metadata),
23
+ });
24
+ if (!response.ok) {
25
+ const errorText = await response.text();
26
+ throw new Error(`API submission failed: ${response.status} ${response.statusText} - ${errorText}`);
27
+ }
28
+ const result = (await response.json());
29
+ return result;
30
+ }
31
+ catch (error) {
32
+ if (error instanceof Error) {
33
+ throw new Error(`Failed to submit metadata: ${error.message}`);
34
+ }
35
+ throw error;
36
+ }
37
+ }
38
+ async healthCheck() {
39
+ const url = `${this.apiEndpoint}${core_1.API_ENDPOINTS.HEALTH}`;
40
+ try {
41
+ const response = await fetch(url, {
42
+ method: 'GET',
43
+ });
44
+ return response.ok;
45
+ }
46
+ catch (error) {
47
+ return false;
48
+ }
49
+ }
50
+ }
51
+ exports.ApiClient = ApiClient;
52
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/client/api-client.ts"],"names":[],"mappings":";;;AAAA,wCAAuF;AAMvF,MAAa,SAAS;IACZ,WAAW,CAAS;IACpB,MAAM,CAAS;IAEvB,YAAY,WAAmB,EAAE,MAAc;QAC7C,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAKD,KAAK,CAAC,cAAc,CAAC,QAAmC;QACtD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,GAAG,oBAAa,CAAC,eAAe,EAAE,CAAC;QAElE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,mBAAY,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC3D,CAAC,mBAAY,CAAC,cAAc,CAAC,EAAE,OAAO;iBACvC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;aAC/B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CACb,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,MAAM,SAAS,EAAE,CAClF,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;YAC7D,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,WAAW;QACf,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,GAAG,oBAAa,CAAC,MAAM,EAAE,CAAC;QAEzD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,KAAK;aACd,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC,EAAE,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AA3DD,8BA2DC"}
@@ -0,0 +1,25 @@
1
+ import { ServiceMetadataSubmission } from '@caryyon/core';
2
+ export interface LatticeConfig {
3
+ serviceName?: string;
4
+ environment?: string;
5
+ apiEndpoint?: string;
6
+ apiKey?: string;
7
+ enabled?: boolean;
8
+ autoSubmit?: boolean;
9
+ submitInterval?: number;
10
+ discoverRoutes?: boolean;
11
+ discoverDependencies?: boolean;
12
+ dependencyDepth?: number;
13
+ packageJsonPath?: string;
14
+ onAnalyzed?: (metadata: ServiceMetadataSubmission) => void;
15
+ onSubmitted?: (response: SubmissionResponse) => void;
16
+ onError?: (error: Error) => void;
17
+ }
18
+ export interface SubmissionResponse {
19
+ success: boolean;
20
+ serviceId: string;
21
+ routesProcessed: number;
22
+ dependenciesProcessed: number;
23
+ }
24
+ export declare const DEFAULT_CONFIG: Required<Omit<LatticeConfig, 'onAnalyzed' | 'onSubmitted' | 'onError' | 'packageJsonPath'>>;
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAK1D,MAAM,WAAW,aAAa;IAE5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC3D,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACrD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAKD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAKD,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,GAAG,aAAa,GAAG,SAAS,GAAG,iBAAiB,CAAC,CAWtH,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_CONFIG = void 0;
4
+ exports.DEFAULT_CONFIG = {
5
+ serviceName: '',
6
+ environment: process.env['NODE_ENV'] || 'development',
7
+ apiEndpoint: process.env['LATTICE_API_ENDPOINT'] || 'https://api.lattice.dev/v1',
8
+ apiKey: process.env['LATTICE_API_KEY'] || '',
9
+ enabled: process.env['LATTICE_ENABLED'] !== 'false',
10
+ autoSubmit: process.env['LATTICE_AUTO_SUBMIT'] !== 'false',
11
+ submitInterval: parseInt(process.env['LATTICE_SUBMIT_INTERVAL'] || '300000', 10),
12
+ discoverRoutes: true,
13
+ discoverDependencies: true,
14
+ dependencyDepth: 1,
15
+ };
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":";;;AA4Ca,QAAA,cAAc,GAAgG;IACzH,WAAW,EAAE,EAAE;IACf,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,aAAa;IACrD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,4BAA4B;IAChF,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE;IAC5C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,OAAO;IACnD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,KAAK,OAAO;IAC1D,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,QAAQ,EAAE,EAAE,CAAC;IAChF,cAAc,EAAE,IAAI;IACpB,oBAAoB,EAAE,IAAI;IAC1B,eAAe,EAAE,CAAC;CACnB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Dependency } from '@caryyon/core';
2
+ export declare class DependencyAnalyzer {
3
+ analyzeDependencies(serviceId: string, packageJsonPath?: string): Dependency[];
4
+ private findPackageJson;
5
+ private readPackageJson;
6
+ private parseDependencies;
7
+ private extractVersion;
8
+ private extractScope;
9
+ }
10
+ //# sourceMappingURL=dependency-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.d.ts","sourceRoot":"","sources":["../../src/discovery/dependency-analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAA8B,MAAM,eAAe,CAAC;AAiBvE,qBAAa,kBAAkB;IAI7B,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAkD9E,OAAO,CAAC,eAAe;IA8BvB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,YAAY;CAOrB"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DependencyAnalyzer = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const core_1 = require("@caryyon/core");
7
+ class DependencyAnalyzer {
8
+ analyzeDependencies(serviceId, packageJsonPath) {
9
+ const pkgPath = this.findPackageJson(packageJsonPath);
10
+ if (!pkgPath) {
11
+ console.warn('package.json not found, skipping dependency analysis');
12
+ return [];
13
+ }
14
+ const packageJson = this.readPackageJson(pkgPath);
15
+ const dependencies = [];
16
+ if (packageJson.dependencies) {
17
+ dependencies.push(...this.parseDependencies(serviceId, packageJson.dependencies, core_1.DependencyType.Direct));
18
+ }
19
+ if (packageJson.devDependencies) {
20
+ dependencies.push(...this.parseDependencies(serviceId, packageJson.devDependencies, core_1.DependencyType.Dev));
21
+ }
22
+ if (packageJson.peerDependencies) {
23
+ dependencies.push(...this.parseDependencies(serviceId, packageJson.peerDependencies, core_1.DependencyType.Peer));
24
+ }
25
+ return dependencies;
26
+ }
27
+ findPackageJson(customPath) {
28
+ if (customPath) {
29
+ return (0, fs_1.existsSync)(customPath) ? customPath : null;
30
+ }
31
+ let currentDir = process.cwd();
32
+ for (let i = 0; i < 5; i++) {
33
+ const pkgPath = (0, path_1.join)(currentDir, 'package.json');
34
+ if ((0, fs_1.existsSync)(pkgPath)) {
35
+ return pkgPath;
36
+ }
37
+ const parentDir = (0, path_1.resolve)(currentDir, '..');
38
+ if (parentDir === currentDir) {
39
+ break;
40
+ }
41
+ currentDir = parentDir;
42
+ }
43
+ return null;
44
+ }
45
+ readPackageJson(path) {
46
+ try {
47
+ const content = (0, fs_1.readFileSync)(path, 'utf-8');
48
+ return JSON.parse(content);
49
+ }
50
+ catch (error) {
51
+ console.error('Failed to read package.json:', error);
52
+ return {};
53
+ }
54
+ }
55
+ parseDependencies(serviceId, deps, type) {
56
+ return Object.entries(deps).map(([packageName, versionRange]) => {
57
+ const dependency = {
58
+ id: (0, core_1.generateId)(),
59
+ serviceId,
60
+ packageName,
61
+ version: this.extractVersion(versionRange),
62
+ versionRange,
63
+ dependencyType: type,
64
+ scope: this.extractScope(packageName),
65
+ firstSeen: new Date(),
66
+ lastSeen: new Date(),
67
+ };
68
+ return dependency;
69
+ });
70
+ }
71
+ extractVersion(versionRange) {
72
+ return versionRange.replace(/^[~^>=<*]/, '').trim();
73
+ }
74
+ extractScope(packageName) {
75
+ if (packageName.startsWith('@')) {
76
+ const parts = packageName.split('/');
77
+ return parts[0];
78
+ }
79
+ return undefined;
80
+ }
81
+ }
82
+ exports.DependencyAnalyzer = DependencyAnalyzer;
83
+ //# sourceMappingURL=dependency-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.js","sourceRoot":"","sources":["../../src/discovery/dependency-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Application } from 'express';
2
+ import { Route } from '@caryyon/core';
3
+ export declare class RouteAnalyzer {
4
+ analyzeRoutes(app: Application, serviceId: string): Route[];
5
+ private normalizeMethod;
6
+ private normalizePath;
7
+ }
8
+ //# sourceMappingURL=route-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-analyzer.d.ts","sourceRoot":"","sources":["../../src/discovery/route-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,EAAE,KAAK,EAA0B,MAAM,eAAe,CAAC;AAM9D,qBAAa,aAAa;IAIxB,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,EAAE;IAgC3D,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,aAAa;CAatB"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouteAnalyzer = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const express_list_endpoints_1 = tslib_1.__importDefault(require("express-list-endpoints"));
6
+ const core_1 = require("@caryyon/core");
7
+ class RouteAnalyzer {
8
+ analyzeRoutes(app, serviceId) {
9
+ const endpoints = (0, express_list_endpoints_1.default)(app);
10
+ const routes = [];
11
+ for (const endpoint of endpoints) {
12
+ for (const method of endpoint.methods) {
13
+ if (method === 'OPTIONS' || method === 'HEAD') {
14
+ continue;
15
+ }
16
+ const route = {
17
+ id: (0, core_1.generateId)(),
18
+ serviceId,
19
+ method: this.normalizeMethod(method),
20
+ path: this.normalizePath(endpoint.path),
21
+ middlewareChain: endpoint.middlewares || [],
22
+ firstSeen: new Date(),
23
+ lastSeen: new Date(),
24
+ };
25
+ routes.push(route);
26
+ }
27
+ }
28
+ return routes;
29
+ }
30
+ normalizeMethod(method) {
31
+ const upperMethod = method.toUpperCase();
32
+ if (upperMethod in core_1.HttpMethod) {
33
+ return core_1.HttpMethod[upperMethod];
34
+ }
35
+ return core_1.HttpMethod.ALL;
36
+ }
37
+ normalizePath(path) {
38
+ if (path !== '/' && path.endsWith('/')) {
39
+ path = path.slice(0, -1);
40
+ }
41
+ if (!path.startsWith('/')) {
42
+ path = '/' + path;
43
+ }
44
+ return path;
45
+ }
46
+ }
47
+ exports.RouteAnalyzer = RouteAnalyzer;
48
+ //# sourceMappingURL=route-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-analyzer.js","sourceRoot":"","sources":["../../src/discovery/route-analyzer.ts"],"names":[],"mappings":";;;;AACA,4FAAmD;AACnD,wCAA8D;AAM9D,MAAa,aAAa;IAIxB,aAAa,CAAC,GAAgB,EAAE,SAAiB;QAE/C,MAAM,SAAS,GAAG,IAAA,gCAAa,EAAC,GAAU,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBAEtC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;oBAC9C,SAAS;gBACX,CAAC;gBAED,MAAM,KAAK,GAAU;oBACnB,EAAE,EAAE,IAAA,iBAAU,GAAE;oBAChB,SAAS;oBACT,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;oBACpC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACvC,eAAe,EAAE,QAAQ,CAAC,WAAW,IAAI,EAAE;oBAC3C,SAAS,EAAE,IAAI,IAAI,EAAE;oBACrB,QAAQ,EAAE,IAAI,IAAI,EAAE;iBACrB,CAAC;gBAEF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAKO,eAAe,CAAC,MAAc;QACpC,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QAEzC,IAAI,WAAW,IAAI,iBAAU,EAAE,CAAC;YAC9B,OAAO,iBAAU,CAAC,WAAsC,CAAC,CAAC;QAC5D,CAAC;QAGD,OAAO,iBAAU,CAAC,GAAG,CAAC;IACxB,CAAC;IAKO,aAAa,CAAC,IAAY;QAEhC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;QAGD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;QACpB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA/DD,sCA+DC"}
@@ -0,0 +1,11 @@
1
+ export declare class ServiceNameDetector {
2
+ detectServiceName(customName?: string): string;
3
+ private getPackageJsonName;
4
+ private getKubernetesServiceName;
5
+ private getDockerContainerName;
6
+ private getCloudServiceName;
7
+ private getGitRepoName;
8
+ private getFallbackName;
9
+ private sanitizeName;
10
+ }
11
+ //# sourceMappingURL=service-name-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-name-detector.d.ts","sourceRoot":"","sources":["../../src/discovery/service-name-detector.ts"],"names":[],"mappings":"AAQA,qBAAa,mBAAmB;IAI9B,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;IAsD9C,OAAO,CAAC,kBAAkB;IA+B1B,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,sBAAsB;IAiB9B,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,YAAY;CA2BrB"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ServiceNameDetector = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const os_1 = require("os");
7
+ class ServiceNameDetector {
8
+ detectServiceName(customName) {
9
+ if (customName) {
10
+ return this.sanitizeName(customName);
11
+ }
12
+ if (process.env['LATTICE_SERVICE_NAME']) {
13
+ return this.sanitizeName(process.env['LATTICE_SERVICE_NAME']);
14
+ }
15
+ if (process.env['SERVICE_NAME']) {
16
+ return this.sanitizeName(process.env['SERVICE_NAME']);
17
+ }
18
+ const pkgName = this.getPackageJsonName();
19
+ if (pkgName) {
20
+ return this.sanitizeName(pkgName);
21
+ }
22
+ const k8sName = this.getKubernetesServiceName();
23
+ if (k8sName) {
24
+ return this.sanitizeName(k8sName);
25
+ }
26
+ const dockerName = this.getDockerContainerName();
27
+ if (dockerName) {
28
+ return this.sanitizeName(dockerName);
29
+ }
30
+ const cloudName = this.getCloudServiceName();
31
+ if (cloudName) {
32
+ return this.sanitizeName(cloudName);
33
+ }
34
+ const gitName = this.getGitRepoName();
35
+ if (gitName) {
36
+ return this.sanitizeName(gitName);
37
+ }
38
+ const fallbackName = this.getFallbackName();
39
+ return this.sanitizeName(fallbackName);
40
+ }
41
+ getPackageJsonName() {
42
+ try {
43
+ let currentDir = process.cwd();
44
+ for (let i = 0; i < 5; i++) {
45
+ const pkgPath = (0, path_1.join)(currentDir, 'package.json');
46
+ if ((0, fs_1.existsSync)(pkgPath)) {
47
+ const content = (0, fs_1.readFileSync)(pkgPath, 'utf-8');
48
+ const pkg = JSON.parse(content);
49
+ if (pkg.name) {
50
+ return pkg.name.replace(/^@[\w-]+\//, '');
51
+ }
52
+ }
53
+ const parentDir = (0, path_1.join)(currentDir, '..');
54
+ if (parentDir === currentDir)
55
+ break;
56
+ currentDir = parentDir;
57
+ }
58
+ }
59
+ catch (error) {
60
+ }
61
+ return null;
62
+ }
63
+ getKubernetesServiceName() {
64
+ return (process.env['K8S_SERVICE_NAME'] ||
65
+ process.env['KUBERNETES_SERVICE_NAME'] ||
66
+ process.env['K8S_POD_NAME'] ||
67
+ null);
68
+ }
69
+ getDockerContainerName() {
70
+ if (process.env['DOCKER_CONTAINER_NAME']) {
71
+ return process.env['DOCKER_CONTAINER_NAME'];
72
+ }
73
+ if ((0, fs_1.existsSync)('/.dockerenv')) {
74
+ return (0, os_1.hostname)();
75
+ }
76
+ return null;
77
+ }
78
+ getCloudServiceName() {
79
+ if (process.env['AWS_ECS_SERVICE_NAME']) {
80
+ return process.env['AWS_ECS_SERVICE_NAME'];
81
+ }
82
+ if (process.env['K_SERVICE']) {
83
+ return process.env['K_SERVICE'];
84
+ }
85
+ if (process.env['CONTAINER_APP_NAME']) {
86
+ return process.env['CONTAINER_APP_NAME'];
87
+ }
88
+ return null;
89
+ }
90
+ getGitRepoName() {
91
+ try {
92
+ const gitConfigPath = (0, path_1.join)(process.cwd(), '.git', 'config');
93
+ if ((0, fs_1.existsSync)(gitConfigPath)) {
94
+ const config = (0, fs_1.readFileSync)(gitConfigPath, 'utf-8');
95
+ const urlMatch = config.match(/url\s*=\s*.*\/([^/]+?)(?:\.git)?$/m);
96
+ if (urlMatch?.[1]) {
97
+ return urlMatch[1];
98
+ }
99
+ }
100
+ }
101
+ catch (error) {
102
+ }
103
+ return null;
104
+ }
105
+ getFallbackName() {
106
+ const dirName = (0, path_1.basename)(process.cwd());
107
+ if (dirName && dirName !== '/' && dirName !== '.') {
108
+ return dirName;
109
+ }
110
+ return (0, os_1.hostname)() || 'unknown-service';
111
+ }
112
+ sanitizeName(name) {
113
+ let sanitized = name.toLowerCase();
114
+ sanitized = sanitized.replace(/[^a-z0-9-]/g, '-');
115
+ sanitized = sanitized.replace(/^-+|-+$/g, '');
116
+ sanitized = sanitized.replace(/-+/g, '-');
117
+ if (sanitized.length < 2) {
118
+ sanitized = 'svc-' + sanitized;
119
+ }
120
+ if (sanitized.length > 63) {
121
+ sanitized = sanitized.substring(0, 63);
122
+ }
123
+ sanitized = sanitized.replace(/-+$/, '');
124
+ return sanitized || 'unknown-service';
125
+ }
126
+ }
127
+ exports.ServiceNameDetector = ServiceNameDetector;
128
+ //# sourceMappingURL=service-name-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-name-detector.js","sourceRoot":"","sources":["../../src/discovery/service-name-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { Application } from 'express';
2
+ import { ServiceMetadataSubmission } from '@caryyon/core';
3
+ import { LatticeConfig, SubmissionResponse } from './config/types';
4
+ export declare class LatticePlugin {
5
+ private config;
6
+ private routeAnalyzer;
7
+ private dependencyAnalyzer;
8
+ private serviceNameDetector;
9
+ private apiClient;
10
+ private metadata;
11
+ private submitTimer;
12
+ private metricsTracker;
13
+ constructor(config?: LatticeConfig);
14
+ analyze(app: Application): Promise<ServiceMetadataSubmission>;
15
+ submit(metadata?: ServiceMetadataSubmission): Promise<SubmissionResponse | null>;
16
+ getMetadata(): ServiceMetadataSubmission | null;
17
+ getServiceName(): string;
18
+ isEnabled(): boolean;
19
+ start(): void;
20
+ stop(): void;
21
+ createMetricsMiddleware(): (req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => void;
22
+ private handleError;
23
+ private getPackageJson;
24
+ private getEmptyMetadata;
25
+ }
26
+ export * from './config/types';
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAEL,yBAAyB,EAG1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAkB,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAWnF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAkL;IAChM,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,cAAc,CAA+B;gBAEzC,MAAM,GAAE,aAAkB;IAmBhC,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA6E7D,MAAM,CAAC,QAAQ,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IA+BtF,WAAW,IAAI,yBAAyB,GAAG,IAAI;IAO/C,cAAc,IAAI,MAAM;IAOxB,SAAS,IAAI,OAAO;IAOpB,KAAK,IAAI,IAAI;IAsBb,IAAI,IAAI,IAAI;IAWZ,uBAAuB;IAgBvB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,gBAAgB;CAoBzB;AAGD,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LatticePlugin = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const core_1 = require("@caryyon/core");
6
+ const types_1 = require("./config/types");
7
+ const route_analyzer_1 = require("./discovery/route-analyzer");
8
+ const dependency_analyzer_1 = require("./discovery/dependency-analyzer");
9
+ const service_name_detector_1 = require("./discovery/service-name-detector");
10
+ const api_client_1 = require("./client/api-client");
11
+ const metrics_tracker_1 = require("./middleware/metrics-tracker");
12
+ class LatticePlugin {
13
+ config;
14
+ routeAnalyzer;
15
+ dependencyAnalyzer;
16
+ serviceNameDetector;
17
+ apiClient;
18
+ metadata = null;
19
+ submitTimer = null;
20
+ metricsTracker = null;
21
+ constructor(config = {}) {
22
+ this.config = {
23
+ ...types_1.DEFAULT_CONFIG,
24
+ ...config,
25
+ };
26
+ this.routeAnalyzer = new route_analyzer_1.RouteAnalyzer();
27
+ this.dependencyAnalyzer = new dependency_analyzer_1.DependencyAnalyzer();
28
+ this.serviceNameDetector = new service_name_detector_1.ServiceNameDetector();
29
+ this.apiClient = new api_client_1.ApiClient(this.config.apiEndpoint, this.config.apiKey);
30
+ }
31
+ async analyze(app) {
32
+ if (!this.config.enabled) {
33
+ console.log('Lattice plugin is disabled');
34
+ return this.getEmptyMetadata();
35
+ }
36
+ try {
37
+ const serviceName = this.serviceNameDetector.detectServiceName(this.config.serviceName);
38
+ const pkgJson = this.getPackageJson();
39
+ const serviceId = (0, core_1.generateId)();
40
+ const service = {
41
+ id: serviceId,
42
+ name: serviceName,
43
+ version: pkgJson?.version,
44
+ environment: this.config.environment,
45
+ language: 'typescript',
46
+ framework: 'express',
47
+ runtime: `node-${process.version}`,
48
+ status: core_1.ServiceStatus.Active,
49
+ firstSeen: new Date(),
50
+ lastSeen: new Date(),
51
+ discoveredBy: {
52
+ pluginName: '@lattice/plugin-express',
53
+ pluginVersion: '0.1.0',
54
+ schemaVersion: '1.0.0',
55
+ },
56
+ };
57
+ const routes = this.config.discoverRoutes
58
+ ? this.routeAnalyzer.analyzeRoutes(app, serviceId)
59
+ : [];
60
+ const dependencies = this.config.discoverDependencies
61
+ ? this.dependencyAnalyzer.analyzeDependencies(serviceId, this.config.packageJsonPath)
62
+ : [];
63
+ this.metadata = {
64
+ service,
65
+ routes,
66
+ dependencies,
67
+ };
68
+ if (this.config.onAnalyzed) {
69
+ this.config.onAnalyzed(this.metadata);
70
+ }
71
+ console.log(`✅ Lattice discovered service "${serviceName}" with ${routes.length} routes and ${dependencies.length} dependencies`);
72
+ if (this.config.autoSubmit) {
73
+ await this.submit();
74
+ }
75
+ this.start();
76
+ return this.metadata;
77
+ }
78
+ catch (error) {
79
+ this.handleError(error);
80
+ throw error;
81
+ }
82
+ }
83
+ async submit(metadata) {
84
+ if (!this.config.enabled) {
85
+ return null;
86
+ }
87
+ const dataToSubmit = metadata || this.metadata;
88
+ if (!dataToSubmit) {
89
+ throw new Error('No metadata to submit. Call analyze() first.');
90
+ }
91
+ try {
92
+ const response = await this.apiClient.submitMetadata(dataToSubmit);
93
+ if (this.config.onSubmitted) {
94
+ this.config.onSubmitted(response);
95
+ }
96
+ console.log(`✅ Lattice metadata submitted: ${response.serviceId}`);
97
+ return response;
98
+ }
99
+ catch (error) {
100
+ this.handleError(error);
101
+ return null;
102
+ }
103
+ }
104
+ getMetadata() {
105
+ return this.metadata;
106
+ }
107
+ getServiceName() {
108
+ return this.metadata?.service.name || 'unknown';
109
+ }
110
+ isEnabled() {
111
+ return this.config.enabled;
112
+ }
113
+ start() {
114
+ if (!this.config.enabled || !this.config.autoSubmit || this.submitTimer) {
115
+ return;
116
+ }
117
+ this.submitTimer = setInterval(() => {
118
+ if (this.metadata) {
119
+ this.metadata.service.lastSeen = new Date();
120
+ this.submit().catch((error) => {
121
+ console.error('Auto-submit failed:', error);
122
+ });
123
+ }
124
+ }, this.config.submitInterval);
125
+ this.submitTimer.unref();
126
+ }
127
+ stop() {
128
+ if (this.submitTimer) {
129
+ clearInterval(this.submitTimer);
130
+ this.submitTimer = null;
131
+ }
132
+ }
133
+ createMetricsMiddleware() {
134
+ if (!this.metricsTracker) {
135
+ const serviceName = this.serviceNameDetector.detectServiceName(this.config.serviceName);
136
+ this.metricsTracker = new metrics_tracker_1.MetricsTracker(serviceName, this.config.apiEndpoint, this.config.apiKey);
137
+ }
138
+ return this.metricsTracker.middleware();
139
+ }
140
+ handleError(error) {
141
+ if (this.config.onError) {
142
+ this.config.onError(error);
143
+ }
144
+ else {
145
+ console.error('Lattice error:', error);
146
+ }
147
+ }
148
+ getPackageJson() {
149
+ try {
150
+ const fs = require('fs');
151
+ const path = require('path');
152
+ const pkgPath = path.join(process.cwd(), 'package.json');
153
+ if (fs.existsSync(pkgPath)) {
154
+ return JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
155
+ }
156
+ }
157
+ catch (error) {
158
+ }
159
+ return null;
160
+ }
161
+ getEmptyMetadata() {
162
+ return {
163
+ service: {
164
+ id: (0, core_1.generateId)(),
165
+ name: 'disabled',
166
+ language: 'typescript',
167
+ framework: 'express',
168
+ status: core_1.ServiceStatus.Unknown,
169
+ firstSeen: new Date(),
170
+ lastSeen: new Date(),
171
+ discoveredBy: {
172
+ pluginName: '@lattice/plugin-express',
173
+ pluginVersion: '0.1.0',
174
+ schemaVersion: '1.0.0',
175
+ },
176
+ },
177
+ routes: [],
178
+ dependencies: [],
179
+ };
180
+ }
181
+ }
182
+ exports.LatticePlugin = LatticePlugin;
183
+ tslib_1.__exportStar(require("./config/types"), exports);
184
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ export interface RequestMetrics {
3
+ method: string;
4
+ path: string;
5
+ statusCode: number;
6
+ responseTime: number;
7
+ timestamp: Date;
8
+ serviceName?: string;
9
+ }
10
+ export declare class MetricsTracker {
11
+ private serviceName;
12
+ private apiEndpoint;
13
+ private apiKey;
14
+ private metrics;
15
+ private maxMetrics;
16
+ constructor(serviceName: string, apiEndpoint: string, apiKey: string);
17
+ middleware(): (req: Request, res: Response, next: NextFunction) => void;
18
+ private storeMetric;
19
+ private submitMetrics;
20
+ getStats(): {
21
+ totalRequests: number;
22
+ avgResponseTime: number;
23
+ errorCount: number;
24
+ errorRate: string;
25
+ recentRequests: RequestMetrics[];
26
+ };
27
+ }
28
+ //# sourceMappingURL=metrics-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-tracker.d.ts","sourceRoot":"","sources":["../../src/middleware/metrics-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IAKvB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,UAAU,CAAQ;gBAGhB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM;IAGxB,UAAU,KAGA,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY;IAkCzD,OAAO,CAAC,WAAW;YAUL,aAAa;IA2B3B,QAAQ;;;;;;;CAcT"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MetricsTracker = void 0;
4
+ const core_1 = require("@caryyon/core");
5
+ class MetricsTracker {
6
+ serviceName;
7
+ apiEndpoint;
8
+ apiKey;
9
+ metrics = [];
10
+ maxMetrics = 1000;
11
+ constructor(serviceName, apiEndpoint, apiKey) {
12
+ this.serviceName = serviceName;
13
+ this.apiEndpoint = apiEndpoint;
14
+ this.apiKey = apiKey;
15
+ }
16
+ middleware() {
17
+ const self = this;
18
+ console.log('[MetricsTracker] middleware() called - returning handler function');
19
+ return (req, res, next) => {
20
+ console.log(`[MetricsTracker] MIDDLEWARE INVOKED: ${req.method} ${req.path}`);
21
+ const startTime = Date.now();
22
+ const originalEnd = res.end;
23
+ res.end = function (...args) {
24
+ const responseTime = Date.now() - startTime;
25
+ const metric = {
26
+ method: req.method,
27
+ path: req.path,
28
+ statusCode: res.statusCode,
29
+ responseTime,
30
+ timestamp: new Date(),
31
+ serviceName: req.get('X-Service-Name'),
32
+ };
33
+ self.storeMetric(metric);
34
+ self.submitMetrics();
35
+ return originalEnd.apply(this, args);
36
+ };
37
+ next();
38
+ };
39
+ }
40
+ storeMetric(metric) {
41
+ this.metrics.push(metric);
42
+ console.log(`[MetricsTracker] Stored metric ${this.metrics.length}: ${metric.method} ${metric.path} - ${metric.statusCode} (${metric.responseTime}ms)`);
43
+ if (this.metrics.length > this.maxMetrics) {
44
+ this.metrics.shift();
45
+ }
46
+ }
47
+ async submitMetrics() {
48
+ if (this.metrics.length % 10 === 0) {
49
+ const metricsToSend = [...this.metrics];
50
+ console.log(`[MetricsTracker] Submitting ${metricsToSend.length} metrics to ${this.apiEndpoint}/metrics`);
51
+ try {
52
+ const response = await fetch(`${this.apiEndpoint}/metrics`, {
53
+ method: 'POST',
54
+ headers: {
55
+ 'Content-Type': 'application/json',
56
+ ...(this.apiKey && { [core_1.HTTP_HEADERS.API_KEY]: this.apiKey }),
57
+ },
58
+ body: JSON.stringify({
59
+ serviceName: this.serviceName,
60
+ metrics: metricsToSend.slice(-10),
61
+ }),
62
+ });
63
+ const result = await response.json();
64
+ console.log(`[MetricsTracker] Submission result:`, result);
65
+ }
66
+ catch (error) {
67
+ console.error('[MetricsTracker] Failed to submit metrics:', error);
68
+ }
69
+ }
70
+ }
71
+ getStats() {
72
+ const totalRequests = this.metrics.length;
73
+ const avgResponseTime = this.metrics.reduce((sum, m) => sum + m.responseTime, 0) / totalRequests || 0;
74
+ const errorCount = this.metrics.filter(m => m.statusCode >= 400).length;
75
+ const errorRate = totalRequests > 0 ? (errorCount / totalRequests) * 100 : 0;
76
+ return {
77
+ totalRequests,
78
+ avgResponseTime: Math.round(avgResponseTime),
79
+ errorCount,
80
+ errorRate: errorRate.toFixed(2),
81
+ recentRequests: this.metrics.slice(-10),
82
+ };
83
+ }
84
+ }
85
+ exports.MetricsTracker = MetricsTracker;
86
+ //# sourceMappingURL=metrics-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-tracker.js","sourceRoot":"","sources":["../../src/middleware/metrics-tracker.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@caryyon/plugin-express",
3
+ "version": "0.1.0",
4
+ "description": "Lattice plugin for Express.js service discovery",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "test": "vitest run",
11
+ "test:watch": "vitest",
12
+ "lint": "eslint src --ext .ts",
13
+ "clean": "rm -rf dist"
14
+ },
15
+ "dependencies": {
16
+ "@caryyon/core": "*",
17
+ "express-list-endpoints": "^6.0.0",
18
+ "fast-glob": "^3.3.2"
19
+ },
20
+ "devDependencies": {
21
+ "@types/express": "^4.17.21",
22
+ "@types/express-list-endpoints": "^6.0.3",
23
+ "@types/node": "^20.10.0",
24
+ "express": "^4.18.2",
25
+ "typescript": "^5.3.0",
26
+ "vitest": "^1.0.0"
27
+ },
28
+ "peerDependencies": {
29
+ "express": "^4.0.0 || ^5.0.0"
30
+ },
31
+ "keywords": [
32
+ "lattice",
33
+ "express",
34
+ "service-discovery",
35
+ "microservices",
36
+ "api-discovery"
37
+ ],
38
+ "files": [
39
+ "dist",
40
+ "README.md"
41
+ ],
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/Caryyon/lattice.git",
48
+ "directory": "packages/plugin-express"
49
+ }
50
+ }