heicat 0.1.2

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.
Files changed (37) hide show
  1. package/.eslintrc.js +29 -0
  2. package/README.md +346 -0
  3. package/examples/express-app/README.md +72 -0
  4. package/examples/express-app/contracts/auth.contract.json +38 -0
  5. package/examples/express-app/contracts/users.contract.json +49 -0
  6. package/examples/express-app/debug.js +13 -0
  7. package/examples/express-app/package-lock.json +913 -0
  8. package/examples/express-app/package.json +21 -0
  9. package/examples/express-app/server.js +116 -0
  10. package/jest.config.js +5 -0
  11. package/package.json +43 -0
  12. package/packages/cli/jest.config.js +7 -0
  13. package/packages/cli/package-lock.json +5041 -0
  14. package/packages/cli/package.json +37 -0
  15. package/packages/cli/src/cli.ts +49 -0
  16. package/packages/cli/src/commands/init.ts +103 -0
  17. package/packages/cli/src/commands/status.ts +75 -0
  18. package/packages/cli/src/commands/test.ts +188 -0
  19. package/packages/cli/src/commands/validate.ts +73 -0
  20. package/packages/cli/src/commands/watch.ts +655 -0
  21. package/packages/cli/src/index.ts +3 -0
  22. package/packages/cli/tsconfig.json +18 -0
  23. package/packages/core/jest.config.js +7 -0
  24. package/packages/core/package-lock.json +4581 -0
  25. package/packages/core/package.json +45 -0
  26. package/packages/core/src/__tests__/contract-loader.test.ts +112 -0
  27. package/packages/core/src/__tests__/validation-engine.test.ts +213 -0
  28. package/packages/core/src/contract-loader.ts +55 -0
  29. package/packages/core/src/engine.ts +95 -0
  30. package/packages/core/src/index.ts +9 -0
  31. package/packages/core/src/middleware.ts +97 -0
  32. package/packages/core/src/types/contract.ts +28 -0
  33. package/packages/core/src/types/options.ts +7 -0
  34. package/packages/core/src/types/violation.ts +19 -0
  35. package/packages/core/src/validation-engine.ts +157 -0
  36. package/packages/core/src/violation-store.ts +46 -0
  37. package/packages/core/tsconfig.json +18 -0
package/.eslintrc.js ADDED
@@ -0,0 +1,29 @@
1
+ module.exports = {
2
+ env: {
3
+ node: true,
4
+ es2020: true
5
+ },
6
+ extends: [
7
+ 'eslint:recommended',
8
+ '@typescript-eslint/recommended'
9
+ ],
10
+ parser: '@typescript-eslint/parser',
11
+ parserOptions: {
12
+ ecmaVersion: 2020,
13
+ sourceType: 'module'
14
+ },
15
+ plugins: [
16
+ '@typescript-eslint'
17
+ ],
18
+ rules: {
19
+ '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
20
+ '@typescript-eslint/explicit-function-return-type': 'off',
21
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
22
+ '@typescript-eslint/no-explicit-any': 'off'
23
+ },
24
+ ignorePatterns: [
25
+ 'dist/',
26
+ 'node_modules/',
27
+ '*.js'
28
+ ]
29
+ };
package/README.md ADDED
@@ -0,0 +1,346 @@
1
+ # Heicat
2
+
3
+ Runtime-enforced API contract system for Node.js. Catches bugs that TypeScript cannot.
4
+
5
+ [![npm version](https://badge.fury.io/js/%40heicat%2Fcore.svg)](https://badge.fury.io/js/%40heicat%2Fcore)
6
+ [![npm version](https://badge.fury.io/js/%40heicat%2Fcli.svg)](https://badge.fury.io/js/%40heicat%2Fcli)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ## Quick Start
10
+
11
+ ### Installation
12
+
13
+ ```bash
14
+ # Install both packages
15
+ npm install @heicat/core @heicat/cli
16
+
17
+ # Or install individually
18
+ npm install @heicat/core
19
+ npm install -D @heicat/cli
20
+ ```
21
+
22
+ ### Setup
23
+
24
+ Initialize contracts in your project:
25
+
26
+ ```bash
27
+ npx heicat init
28
+ ```
29
+
30
+ Add middleware to your Express app:
31
+
32
+ ```typescript
33
+ import { contractMiddleware } from "@heicat/core";
34
+
35
+ app.use(
36
+ contractMiddleware({
37
+ contractsPath: "./contracts",
38
+ mode: "dev"
39
+ })
40
+ );
41
+ ```
42
+
43
+ That's it! Your API now has runtime contract enforcement.
44
+
45
+ ## What It Does
46
+
47
+ - **Validates requests** before they reach your handlers
48
+ - **Validates responses** before they're sent to clients
49
+ - **Validates errors** to ensure consistent error shapes
50
+ - **Logs violations** with clear, actionable messages
51
+ - **Works in dev, strict, and CI modes**
52
+
53
+ ## Example Violation
54
+
55
+ ```
56
+ ❌ POST /users: Response missing field: email
57
+ ```
58
+
59
+ ## CLI Commands
60
+
61
+ ```bash
62
+ # Initialize contracts in your project
63
+ heicat init [--contracts-path <path>]
64
+
65
+ # Validate contract files (syntax + schema)
66
+ heicat validate [--contracts-path <path>]
67
+
68
+ # Show contract status and statistics
69
+ heicat status [--contracts-path <path>]
70
+
71
+ # Watch contracts and validate in real-time
72
+ heicat watch [--contracts-path <path>] [--port <port>]
73
+
74
+ # Test contracts against running server
75
+ heicat test <url> [--contracts-path <path>]
76
+ ```
77
+
78
+ ## Contract Format
79
+
80
+ Contracts are simple JSON files:
81
+
82
+ ```json
83
+ {
84
+ "method": "POST",
85
+ "path": "/users",
86
+ "request": {
87
+ "body": {
88
+ "email": { "type": "string", "required": true },
89
+ "password": { "type": "string", "minLength": 8 }
90
+ }
91
+ },
92
+ "response": {
93
+ "200": {
94
+ "id": "string",
95
+ "email": "string"
96
+ }
97
+ },
98
+ "errors": {
99
+ "400": { "message": "string" }
100
+ }
101
+ }
102
+ ```
103
+
104
+ ## Modes
105
+
106
+ - **`dev`**: Logs warnings, doesn't block responses
107
+ - **`strict`**: Blocks invalid responses (implemented)
108
+ - **`ci`**: Fails process on violations (implemented)
109
+
110
+ ## Why This Works
111
+
112
+ TypeScript validates at compile time. This validates at runtime.
113
+
114
+ - Catches silent API drift
115
+ - Enforces backend behavior consistency
116
+ - Makes contracts the source of truth
117
+ - Requires almost zero adoption effort
118
+
119
+ ## Project Structure
120
+
121
+ ```
122
+ your-project/
123
+ ├─ contracts/
124
+ │ ├─ users.contract.json
125
+ │ ├─ auth.contract.json
126
+ ├─ src/
127
+ │ ├─ routes/
128
+ └─ package.json
129
+ ```
130
+
131
+ ## Testing
132
+
133
+ ### Testing Contracts
134
+
135
+ #### 1. Validate Contract Syntax
136
+ ```bash
137
+ # Validate all contract files
138
+ heicat validate
139
+
140
+ # Validate specific contracts directory
141
+ heicat validate --contracts-path ./my-contracts
142
+ ```
143
+
144
+ #### 2. Test Against Running Server
145
+ ```bash
146
+ # Start your server first
147
+ npm start
148
+
149
+ # Test all contracts against localhost:3000
150
+ heicat test http://localhost:3000
151
+
152
+ # Test specific contracts
153
+ heicat test http://localhost:3000 --contracts-path ./contracts
154
+ ```
155
+
156
+ #### 3. Watch Mode with Live GUI
157
+ ```bash
158
+ # Start watch mode with GUI dashboard
159
+ heicat watch
160
+
161
+ # Opens http://localhost:3333 with live violations dashboard
162
+ ```
163
+
164
+ ### Manual Testing
165
+
166
+ #### Testing the Middleware
167
+ 1. Start the example app:
168
+ ```bash
169
+ cd examples/express-app
170
+ npm install
171
+ npm start
172
+ ```
173
+
174
+ 2. Test valid request:
175
+ ```bash
176
+ curl -X POST http://localhost:3000/users \
177
+ -H "Content-Type: application/json" \
178
+ -d '{"email":"test@example.com","password":"password123","name":"Test User"}'
179
+ ```
180
+
181
+ 3. Test invalid request (missing required field):
182
+ ```bash
183
+ curl -X POST http://localhost:3000/users \
184
+ -H "Content-Type: application/json" \
185
+ -d '{"password":"password123"}'
186
+ # Should return 400 with validation error
187
+ ```
188
+
189
+ 4. Test login:
190
+ ```bash
191
+ curl -X POST http://localhost:3000/auth/login \
192
+ -H "Content-Type: application/json" \
193
+ -d '{"email":"test@example.com","password":"password123"}'
194
+ ```
195
+
196
+ ### Unit Testing
197
+
198
+ #### Running Tests
199
+ ```bash
200
+ # Test all packages
201
+ npm test
202
+
203
+ # Test specific package
204
+ cd packages/core
205
+ npm test
206
+
207
+ cd packages/cli
208
+ npm test
209
+ ```
210
+
211
+ #### Writing Tests
212
+ Tests use Jest and are located in `__tests__/` directories or `*.test.ts` files.
213
+
214
+ Example test structure:
215
+ ```
216
+ packages/core/
217
+ src/
218
+ __tests__/
219
+ validation-engine.test.ts
220
+ middleware.test.ts
221
+ ```
222
+
223
+ ### Integration Testing
224
+
225
+ #### End-to-End Testing
226
+ 1. Start the example server
227
+ 2. Run contract tests:
228
+ ```bash
229
+ contract-studio test http://localhost:3000
230
+ ```
231
+
232
+ #### CI/CD Testing
233
+ Add to your CI pipeline:
234
+ ```yaml
235
+ - name: Validate Contracts
236
+ run: npx heicat validate
237
+
238
+ - name: Test Contracts
239
+ run: |
240
+ npm start &
241
+ sleep 5
242
+ npx heicat test http://localhost:3000
243
+ ```
244
+
245
+ ## Local Developer GUI
246
+
247
+ Start the interactive dashboard for real-time contract monitoring:
248
+
249
+ ```bash
250
+ npx heicat watch --port 3333
251
+ ```
252
+
253
+ **Features:**
254
+ - **Dark Mode**: Modern ShadCN-inspired dark theme
255
+ - **Real-time Monitoring**: Auto-updates every 3 seconds
256
+ - **Violation Dashboard**: Live statistics and detailed violation logs
257
+ - **Contract Status**: Shows loaded contracts and monitoring status
258
+ - **Responsive Design**: Works on desktop and mobile devices
259
+
260
+ **Dashboard Includes:**
261
+ - **Statistics Cards**: Total violations, errors, and warnings with icons
262
+ - **Status Indicator**: Live monitoring status with animated pulse
263
+ - **Violation Details**: Formatted error messages with severity badges
264
+ - **Clear Function**: Reset violation logs for fresh monitoring
265
+ - **Auto-scroll**: Smooth scrolling for long violation lists
266
+
267
+ **Design System:**
268
+ - ShadCN-inspired components with proper dark mode colors
269
+ - Inter font for modern typography
270
+ - Consistent spacing and border radius
271
+ - Subtle shadows and hover effects
272
+ - Accessible focus states and keyboard navigation
273
+
274
+ Runs locally at `http://localhost:3333` with no authentication required.
275
+
276
+ ## Development
277
+
278
+ ### Monorepo Setup
279
+
280
+ This is a monorepo managed with NPM workspaces.
281
+
282
+ ```bash
283
+ # Install all dependencies
284
+ npm install
285
+
286
+ # Build all packages
287
+ npm run build
288
+
289
+ # Build individual packages
290
+ npm run build:core
291
+ npm run build:cli
292
+
293
+ # Run tests
294
+ npm test
295
+
296
+ # Clean build artifacts
297
+ npm run clean
298
+ ```
299
+
300
+ ### Publishing
301
+
302
+ ```bash
303
+ # Bump version and publish all packages
304
+ npm run release
305
+
306
+ # Or publish individually
307
+ cd packages/core && npm publish
308
+ cd packages/cli && npm publish
309
+ ```
310
+
311
+ ### Example App
312
+
313
+ ```bash
314
+ # Run the example Express app
315
+ cd examples/express-app
316
+ npm install
317
+ npm start
318
+
319
+ # Start GUI dashboard
320
+ npm run watch
321
+ ```
322
+
323
+ ## Project Structure
324
+
325
+ ```
326
+ heicat/
327
+ ├── packages/
328
+ │ ├── core/ # Runtime middleware package
329
+ │ └── cli/ # CLI tools package
330
+ ├── examples/
331
+ │ └── express-app/ # Example implementation
332
+ ├── package.json # Monorepo root
333
+ └── README.md
334
+ ```
335
+
336
+ ## Contributing
337
+
338
+ 1. Fork the repository
339
+ 2. Create a feature branch
340
+ 3. Make your changes
341
+ 4. Add tests
342
+ 5. Submit a pull request
343
+
344
+ ## License
345
+
346
+ MIT
@@ -0,0 +1,72 @@
1
+ # Contract Studio Example
2
+
3
+ A simple Express.js app demonstrating Backend Contract Studio.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ npm install
9
+ ```
10
+
11
+ ## Initialize Contracts
12
+
13
+ The contracts are already created, but you can regenerate them:
14
+
15
+ ```bash
16
+ npm run init-contracts
17
+ ```
18
+
19
+ ## Validate Contracts
20
+
21
+ Check that your contracts are valid:
22
+
23
+ ```bash
24
+ npm run validate-contracts
25
+ ```
26
+
27
+ ## View Status
28
+
29
+ See contract statistics:
30
+
31
+ ```bash
32
+ npm run status
33
+ ```
34
+
35
+ ## Run the App
36
+
37
+ ```bash
38
+ npm start
39
+ ```
40
+
41
+ Or for development with auto-restart:
42
+
43
+ ```bash
44
+ npm run dev
45
+ ```
46
+
47
+ ## Test the Contracts
48
+
49
+ Try these requests:
50
+
51
+ ### Create a user (valid):
52
+ ```bash
53
+ curl -X POST http://localhost:3000/users \
54
+ -H "Content-Type: application/json" \
55
+ -d '{"email":"user@example.com","password":"password123","name":"John Doe"}'
56
+ ```
57
+
58
+ ### Create a user (missing password - should fail):
59
+ ```bash
60
+ curl -X POST http://localhost:3000/users \
61
+ -H "Content-Type: application/json" \
62
+ -d '{"email":"user2@example.com","name":"Jane Doe"}'
63
+ ```
64
+
65
+ ### Login (valid):
66
+ ```bash
67
+ curl -X POST http://localhost:3000/auth/login \
68
+ -H "Content-Type: application/json" \
69
+ -d '{"email":"user@example.com","password":"password123"}'
70
+ ```
71
+
72
+ Watch the console for contract validation messages! ⚡
@@ -0,0 +1,38 @@
1
+ {
2
+ "method": "POST",
3
+ "path": "/auth/login",
4
+ "request": {
5
+ "body": {
6
+ "email": {
7
+ "type": "string",
8
+ "required": true
9
+ },
10
+ "password": {
11
+ "type": "string",
12
+ "required": true
13
+ }
14
+ }
15
+ },
16
+ "response": {
17
+ "200": {
18
+ "token": {
19
+ "type": "string"
20
+ },
21
+ "user": {
22
+ "id": {
23
+ "type": "string"
24
+ },
25
+ "email": {
26
+ "type": "string"
27
+ }
28
+ }
29
+ }
30
+ },
31
+ "errors": {
32
+ "401": {
33
+ "message": {
34
+ "type": "string"
35
+ }
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "method": "POST",
3
+ "path": "/users",
4
+ "auth": "jwt",
5
+ "request": {
6
+ "body": {
7
+ "email": {
8
+ "type": "string",
9
+ "required": true
10
+ },
11
+ "password": {
12
+ "type": "string",
13
+ "minLength": 8,
14
+ "required": true
15
+ },
16
+ "name": {
17
+ "type": "string"
18
+ }
19
+ }
20
+ },
21
+ "response": {
22
+ "201": {
23
+ "id": {
24
+ "type": "string"
25
+ },
26
+ "email": {
27
+ "type": "string"
28
+ },
29
+ "name": {
30
+ "type": "string"
31
+ },
32
+ "createdAt": {
33
+ "type": "string"
34
+ }
35
+ }
36
+ },
37
+ "errors": {
38
+ "400": {
39
+ "message": {
40
+ "type": "string"
41
+ }
42
+ },
43
+ "409": {
44
+ "message": {
45
+ "type": "string"
46
+ }
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,13 @@
1
+ const { loadContracts } = require('@contract-studio/core');
2
+
3
+ async function debug() {
4
+ try {
5
+ console.log('Loading contracts from ./contracts...');
6
+ const contracts = await loadContracts('./contracts');
7
+ console.log(`Found ${contracts.length} contracts:`, contracts.map(c => `${c.method} ${c.path}`));
8
+ } catch (error) {
9
+ console.error('Error loading contracts:', error);
10
+ }
11
+ }
12
+
13
+ debug();