@usageflow/core 0.2.5 → 0.3.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 +207 -26
- package/dist/base.d.ts +11 -6
- package/dist/base.js +150 -89
- package/dist/base.js.map +1 -1
- package/dist/types.d.ts +7 -1
- package/dist/types.js.map +1 -1
- package/jest.config.js +14 -0
- package/package.json +6 -7
- package/src/base.ts +216 -112
- package/src/types.ts +8 -1
- package/test/base.test.ts +290 -0
- package/test/socket.test.ts +72 -0
- package/test/src/base.d.ts +62 -0
- package/test/src/base.js +440 -0
- package/test/src/base.js.map +1 -0
- package/test/src/index.d.ts +3 -0
- package/test/src/index.js +20 -0
- package/test/src/index.js.map +1 -0
- package/test/src/socket.d.ts +26 -0
- package/test/src/socket.js +266 -0
- package/test/src/socket.js.map +1 -0
- package/test/src/types.d.ts +117 -0
- package/test/src/types.js +11 -0
- package/test/src/types.js.map +1 -0
- package/test/tsconfig.test.tsbuildinfo +1 -0
- package/test/types.test.ts +56 -0
- package/tsconfig.json +2 -1
- package/tsconfig.test.json +11 -0
- package/tsconfig.test.tsbuildinfo +1 -0
- package/tsconfig.tsbuildinfo +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Core functionality for UsageFlow API tracking. This package provides the base implementation for tracking API usage across different Node.js frameworks.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@usageflow/core)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
7
|
|
|
7
8
|
## Installation
|
|
8
9
|
|
|
@@ -10,46 +11,226 @@ Core functionality for UsageFlow API tracking. This package provides the base im
|
|
|
10
11
|
npm install @usageflow/core
|
|
11
12
|
```
|
|
12
13
|
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
`@usageflow/core` is the foundational package that provides core functionality for UsageFlow integrations. It includes:
|
|
17
|
+
|
|
18
|
+
- Base `UsageFlowAPI` class for framework-agnostic usage tracking
|
|
19
|
+
- WebSocket connection management with connection pooling
|
|
20
|
+
- Route pattern matching and ledger ID generation
|
|
21
|
+
- Request metadata collection and sanitization
|
|
22
|
+
- Configuration management and policy fetching
|
|
23
|
+
|
|
13
24
|
## Usage
|
|
14
25
|
|
|
15
|
-
This
|
|
26
|
+
This package is typically used indirectly through framework-specific implementations:
|
|
16
27
|
|
|
17
|
-
- [@usageflow/express](
|
|
18
|
-
- [@usageflow/fastify](
|
|
19
|
-
- [@usageflow/nestjs](
|
|
28
|
+
- [@usageflow/express](../express) for Express.js
|
|
29
|
+
- [@usageflow/fastify](../fastify) for Fastify
|
|
30
|
+
- [@usageflow/nestjs](../nestjs) for NestJS
|
|
31
|
+
|
|
32
|
+
If you need to extend UsageFlow for a different framework, you can extend the `UsageFlowAPI` class:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { UsageFlowAPI, UsageFlowAPIConfig } from '@usageflow/core';
|
|
20
36
|
|
|
21
|
-
|
|
37
|
+
class CustomFrameworkUsageFlowAPI extends UsageFlowAPI {
|
|
38
|
+
constructor(config: UsageFlowAPIConfig) {
|
|
39
|
+
super(config);
|
|
40
|
+
this.setWebServer('custom');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Implement framework-specific methods
|
|
44
|
+
}
|
|
45
|
+
```
|
|
22
46
|
|
|
23
47
|
## API Reference
|
|
24
48
|
|
|
49
|
+
### UsageFlowAPIConfig
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
interface UsageFlowAPIConfig {
|
|
53
|
+
apiKey: string; // Your UsageFlow API key
|
|
54
|
+
poolSize?: number; // Number of WebSocket connections (default: 5)
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### UsageFlowAPI
|
|
59
|
+
|
|
60
|
+
Base class for all UsageFlow implementations.
|
|
61
|
+
|
|
62
|
+
#### Constructor
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
constructor(config: UsageFlowAPIConfig)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Methods
|
|
69
|
+
|
|
70
|
+
##### `setWebServer(webServer: 'express' | 'fastify' | 'nestjs'): void`
|
|
71
|
+
|
|
72
|
+
Sets the web server type for route pattern extraction.
|
|
73
|
+
|
|
74
|
+
##### `getApiKey(): string | null`
|
|
75
|
+
|
|
76
|
+
Returns the configured API key.
|
|
77
|
+
|
|
78
|
+
##### `getUsageflowUrl(): string`
|
|
79
|
+
|
|
80
|
+
Returns the UsageFlow API URL.
|
|
81
|
+
|
|
82
|
+
##### `getRoutePattern(request: UsageFlowRequest): string`
|
|
83
|
+
|
|
84
|
+
Extracts the route pattern from a request object. Supports Express, Fastify, and NestJS.
|
|
85
|
+
|
|
86
|
+
##### `guessLedgerId(request: UsageFlowRequest, overrideUrl?: string): string`
|
|
87
|
+
|
|
88
|
+
Generates a ledger ID for tracking based on the request and configured policies.
|
|
89
|
+
|
|
90
|
+
##### `createRoutesMap(routes: Route[]): RoutesMap`
|
|
91
|
+
|
|
92
|
+
Converts an array of routes into a map for efficient lookup.
|
|
93
|
+
|
|
94
|
+
##### `shouldSkipRoute(method: string, url: string, whitelistMap: RoutesMap): boolean`
|
|
95
|
+
|
|
96
|
+
Checks if a route should be skipped based on the whitelist.
|
|
97
|
+
|
|
98
|
+
##### `shouldMonitorRoute(method: string, url: string, routesMap: RoutesMap): boolean`
|
|
99
|
+
|
|
100
|
+
Checks if a route should be monitored based on the routes map.
|
|
101
|
+
|
|
102
|
+
##### `sanitizeHeaders(headers: Headers): Headers`
|
|
103
|
+
|
|
104
|
+
Sanitizes sensitive information from headers (authorization tokens, API keys, etc.).
|
|
105
|
+
|
|
106
|
+
##### `extractBearerToken(authHeader?: string): string | null`
|
|
107
|
+
|
|
108
|
+
Extracts the bearer token from an Authorization header.
|
|
109
|
+
|
|
110
|
+
##### `decodeJwtUnverified(token: string): Record<string, any> | null`
|
|
111
|
+
|
|
112
|
+
Decodes a JWT token without verifying the signature.
|
|
113
|
+
|
|
114
|
+
##### `allocationRequest(request: UsageFlowRequest, payload: RequestForAllocation, metadata: RequestMetadata): Promise<void>`
|
|
115
|
+
|
|
116
|
+
Sends an allocation request via WebSocket.
|
|
117
|
+
|
|
118
|
+
##### `useAllocationRequest(payload: RequestForAllocation): Promise<void>`
|
|
119
|
+
|
|
120
|
+
Finalizes an allocation request.
|
|
121
|
+
|
|
122
|
+
##### `destroy(): void`
|
|
123
|
+
|
|
124
|
+
Cleans up resources including intervals and WebSocket connections.
|
|
125
|
+
|
|
126
|
+
### UsageFlowSocketManager
|
|
127
|
+
|
|
128
|
+
Manages WebSocket connections with connection pooling.
|
|
129
|
+
|
|
130
|
+
#### Constructor
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
constructor(apiKey: string, poolSize?: number)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### Methods
|
|
137
|
+
|
|
138
|
+
##### `connect(): Promise<void>`
|
|
139
|
+
|
|
140
|
+
Establishes WebSocket connections in the pool.
|
|
141
|
+
|
|
142
|
+
##### `sendAsync<T>(payload: UsageFlowSocketMessage): Promise<UsageFlowSocketResponse<T>>`
|
|
143
|
+
|
|
144
|
+
Sends a message and waits for a response.
|
|
145
|
+
|
|
146
|
+
##### `send(payload: UsageFlowSocketMessage): void`
|
|
147
|
+
|
|
148
|
+
Sends a message without waiting for a response.
|
|
149
|
+
|
|
150
|
+
##### `isConnected(): boolean`
|
|
151
|
+
|
|
152
|
+
Checks if at least one WebSocket connection is active.
|
|
153
|
+
|
|
154
|
+
##### `close(): void`
|
|
155
|
+
|
|
156
|
+
Closes all WebSocket connections.
|
|
157
|
+
|
|
158
|
+
##### `destroy(): void`
|
|
159
|
+
|
|
160
|
+
Cleans up all resources.
|
|
161
|
+
|
|
162
|
+
## Types
|
|
163
|
+
|
|
164
|
+
### Route
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
interface Route {
|
|
168
|
+
method: string; // HTTP method or '*' for all methods
|
|
169
|
+
url: string; // URL pattern or '*' for all URLs
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### RequestMetadata
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
interface RequestMetadata {
|
|
177
|
+
method: string;
|
|
178
|
+
url: string;
|
|
179
|
+
rawUrl: string;
|
|
180
|
+
clientIP: string;
|
|
181
|
+
userAgent?: string;
|
|
182
|
+
timestamp: string;
|
|
183
|
+
headers: Record<string, string>;
|
|
184
|
+
queryParams: Record<string, any> | null;
|
|
185
|
+
pathParams: Record<string, any> | null;
|
|
186
|
+
body?: any;
|
|
187
|
+
requestDuration?: number;
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### UsageFlowConfig
|
|
192
|
+
|
|
25
193
|
```typescript
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
url: string,
|
|
37
|
-
whitelistMap: Map<string, Set<string>>,
|
|
38
|
-
): boolean;
|
|
39
|
-
sanitizeHeaders(headers: Record<string, string>): Record<string, string>;
|
|
194
|
+
interface UsageFlowConfig {
|
|
195
|
+
url: string;
|
|
196
|
+
method: string;
|
|
197
|
+
identityFieldName?: string;
|
|
198
|
+
identityFieldLocation?:
|
|
199
|
+
| 'path_params'
|
|
200
|
+
| 'query_params'
|
|
201
|
+
| 'body'
|
|
202
|
+
| 'bearer_token'
|
|
203
|
+
| 'headers';
|
|
40
204
|
}
|
|
41
205
|
```
|
|
42
206
|
|
|
43
|
-
##
|
|
207
|
+
## Requirements
|
|
44
208
|
|
|
45
|
-
|
|
209
|
+
- Node.js >= 18.0.0
|
|
210
|
+
- TypeScript >= 5.0.0 (for TypeScript projects)
|
|
46
211
|
|
|
47
|
-
|
|
48
|
-
- Incomplete features
|
|
49
|
-
- Potential bugs
|
|
212
|
+
## Dependencies
|
|
50
213
|
|
|
51
|
-
|
|
214
|
+
- `axios`: HTTP client for API requests
|
|
215
|
+
- `ws`: WebSocket client library
|
|
216
|
+
|
|
217
|
+
## Development
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Install dependencies
|
|
221
|
+
npm install
|
|
222
|
+
|
|
223
|
+
# Build the package
|
|
224
|
+
npm run build
|
|
225
|
+
|
|
226
|
+
# Run tests
|
|
227
|
+
npm test
|
|
228
|
+
```
|
|
52
229
|
|
|
53
230
|
## License
|
|
54
231
|
|
|
55
232
|
MIT
|
|
233
|
+
|
|
234
|
+
## Support
|
|
235
|
+
|
|
236
|
+
For issues, questions, or contributions, please visit our [GitHub repository](https://github.com/usageflow/js-mongorepo).
|
package/dist/base.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Route, UsageFlowConfig, RoutesMap, Headers, RequestForAllocation, RequestMetadata, UsageFlowRequest, UsageFlowAPIConfig } from "./types";
|
|
2
|
-
import { UsageFlowSocketManger } from "./socket";
|
|
3
2
|
export declare abstract class UsageFlowAPI {
|
|
4
3
|
protected apiKey: string | null;
|
|
5
4
|
protected usageflowUrl: string;
|
|
6
|
-
protected webServer:
|
|
5
|
+
protected webServer: "express" | "fastify" | "nestjs";
|
|
7
6
|
protected apiConfigs: UsageFlowConfig[];
|
|
7
|
+
protected blockedEndpoints: string[];
|
|
8
8
|
private configUpdateInterval;
|
|
9
|
-
socketManager
|
|
9
|
+
private socketManager;
|
|
10
10
|
private applicationId;
|
|
11
|
+
private logger;
|
|
11
12
|
constructor(config?: UsageFlowAPIConfig);
|
|
12
13
|
/**
|
|
13
14
|
* Initialize the UsageFlow API with credentials
|
|
@@ -16,7 +17,7 @@ export declare abstract class UsageFlowAPI {
|
|
|
16
17
|
* @param poolSize - Number of WebSocket connections in the pool (default: 5)
|
|
17
18
|
*/
|
|
18
19
|
private init;
|
|
19
|
-
setWebServer(webServer:
|
|
20
|
+
setWebServer(webServer: "express" | "fastify" | "nestjs"): void;
|
|
20
21
|
getApiKey(): string | null;
|
|
21
22
|
getUsageflowUrl(): string;
|
|
22
23
|
/**
|
|
@@ -24,10 +25,14 @@ export declare abstract class UsageFlowAPI {
|
|
|
24
25
|
*/
|
|
25
26
|
private startConfigUpdater;
|
|
26
27
|
getRoutePattern(request: UsageFlowRequest): string;
|
|
27
|
-
guessLedgerId(request: UsageFlowRequest, overrideUrl?: string):
|
|
28
|
+
guessLedgerId(request: UsageFlowRequest, overrideUrl?: string): {
|
|
29
|
+
ledgerId: string;
|
|
30
|
+
hasLimit: boolean;
|
|
31
|
+
};
|
|
28
32
|
private fetchApiPolicies;
|
|
33
|
+
private fetchBlockedEndpoints;
|
|
29
34
|
useAllocationRequest(payload: RequestForAllocation): Promise<void>;
|
|
30
|
-
allocationRequest(request: UsageFlowRequest, payload: RequestForAllocation, metadata: RequestMetadata): Promise<void>;
|
|
35
|
+
allocationRequest(request: UsageFlowRequest, payload: RequestForAllocation, metadata: RequestMetadata, hasLimit: boolean): Promise<void>;
|
|
31
36
|
/**
|
|
32
37
|
* Convert routes list to a map for faster lookup
|
|
33
38
|
*/
|