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.
- package/.eslintrc.js +29 -0
- package/README.md +346 -0
- package/examples/express-app/README.md +72 -0
- package/examples/express-app/contracts/auth.contract.json +38 -0
- package/examples/express-app/contracts/users.contract.json +49 -0
- package/examples/express-app/debug.js +13 -0
- package/examples/express-app/package-lock.json +913 -0
- package/examples/express-app/package.json +21 -0
- package/examples/express-app/server.js +116 -0
- package/jest.config.js +5 -0
- package/package.json +43 -0
- package/packages/cli/jest.config.js +7 -0
- package/packages/cli/package-lock.json +5041 -0
- package/packages/cli/package.json +37 -0
- package/packages/cli/src/cli.ts +49 -0
- package/packages/cli/src/commands/init.ts +103 -0
- package/packages/cli/src/commands/status.ts +75 -0
- package/packages/cli/src/commands/test.ts +188 -0
- package/packages/cli/src/commands/validate.ts +73 -0
- package/packages/cli/src/commands/watch.ts +655 -0
- package/packages/cli/src/index.ts +3 -0
- package/packages/cli/tsconfig.json +18 -0
- package/packages/core/jest.config.js +7 -0
- package/packages/core/package-lock.json +4581 -0
- package/packages/core/package.json +45 -0
- package/packages/core/src/__tests__/contract-loader.test.ts +112 -0
- package/packages/core/src/__tests__/validation-engine.test.ts +213 -0
- package/packages/core/src/contract-loader.ts +55 -0
- package/packages/core/src/engine.ts +95 -0
- package/packages/core/src/index.ts +9 -0
- package/packages/core/src/middleware.ts +97 -0
- package/packages/core/src/types/contract.ts +28 -0
- package/packages/core/src/types/options.ts +7 -0
- package/packages/core/src/types/violation.ts +19 -0
- package/packages/core/src/validation-engine.ts +157 -0
- package/packages/core/src/violation-store.ts +46 -0
- package/packages/core/tsconfig.json +18 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "heicat-example",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Example Express app with Contract Studio",
|
|
5
|
+
"main": "server.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node server.js",
|
|
8
|
+
"dev": "node --watch server.js",
|
|
9
|
+
"init-contracts": "node ../../packages/cli/dist/cli.js init",
|
|
10
|
+
"validate-contracts": "node ../../packages/cli/dist/cli.js validate",
|
|
11
|
+
"status": "node ../../packages/cli/dist/cli.js status"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@heicat/core": "file:../../packages/core",
|
|
15
|
+
"cors": "^2.8.5",
|
|
16
|
+
"express": "^4.18.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@heicat/cli": "file:../../packages/cli"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const cors = require('cors');
|
|
3
|
+
const { contractMiddleware } = require('@contract-studio/core');
|
|
4
|
+
|
|
5
|
+
const app = express();
|
|
6
|
+
|
|
7
|
+
// Enable CORS for GUI requests
|
|
8
|
+
app.use(cors({
|
|
9
|
+
origin: ['http://localhost:3333', 'http://127.0.0.1:3333'],
|
|
10
|
+
credentials: true
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
app.use(express.json());
|
|
14
|
+
|
|
15
|
+
// Add Contract Studio middleware
|
|
16
|
+
app.use(
|
|
17
|
+
contractMiddleware({
|
|
18
|
+
contractsPath: './contracts',
|
|
19
|
+
mode: 'dev' // Use 'dev' for development, 'strict' for production
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// In-memory user store (for demo purposes)
|
|
24
|
+
let users = [];
|
|
25
|
+
let nextId = 1;
|
|
26
|
+
|
|
27
|
+
// Contract Studio API endpoints
|
|
28
|
+
app.get('/api/violations', (req, res) => {
|
|
29
|
+
const engine = req._contractEngine;
|
|
30
|
+
if (engine) {
|
|
31
|
+
res.json({
|
|
32
|
+
violations: engine.getViolations() || [],
|
|
33
|
+
stats: engine.getStats() || { total: 0, errors: 0, warnings: 0 }
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
res.json({
|
|
37
|
+
violations: [],
|
|
38
|
+
stats: { total: 0, errors: 0, warnings: 0 }
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Routes
|
|
44
|
+
app.post('/users', (req, res) => {
|
|
45
|
+
const { email, password, name } = req.body;
|
|
46
|
+
|
|
47
|
+
// Check if user already exists
|
|
48
|
+
const existingUser = users.find(u => u.email === email);
|
|
49
|
+
if (existingUser) {
|
|
50
|
+
return res.status(409).json({
|
|
51
|
+
message: 'User with this email already exists'
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Validate password length (this should be caught by contract validation)
|
|
56
|
+
if (!password || password.length < 8) {
|
|
57
|
+
return res.status(400).json({
|
|
58
|
+
message: 'Password must be at least 8 characters long'
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const user = {
|
|
63
|
+
id: nextId++,
|
|
64
|
+
email,
|
|
65
|
+
name: name || '',
|
|
66
|
+
createdAt: new Date().toISOString()
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
users.push(user);
|
|
70
|
+
|
|
71
|
+
res.status(201).json(user);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
app.get('/users', (req, res) => {
|
|
75
|
+
res.json(users);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
app.post('/auth/login', (req, res) => {
|
|
79
|
+
const { email, password } = req.body;
|
|
80
|
+
|
|
81
|
+
const user = users.find(u => u.email === email);
|
|
82
|
+
if (!user) {
|
|
83
|
+
return res.status(401).json({
|
|
84
|
+
message: 'Invalid credentials'
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// In a real app, you'd verify the password hash
|
|
89
|
+
// For demo, just check if password exists
|
|
90
|
+
if (!password) {
|
|
91
|
+
return res.status(401).json({
|
|
92
|
+
message: 'Invalid credentials'
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Return token and user info
|
|
97
|
+
res.json({
|
|
98
|
+
token: `jwt-token-for-${user.id}`,
|
|
99
|
+
user: {
|
|
100
|
+
id: user.id,
|
|
101
|
+
email: user.email
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Error handling middleware
|
|
107
|
+
app.use((err, req, res, next) => {
|
|
108
|
+
console.error(err);
|
|
109
|
+
res.status(500).json({ message: 'Internal server error' });
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const PORT = process.env.PORT || 3000;
|
|
113
|
+
app.listen(PORT, () => {
|
|
114
|
+
console.log(`🚀 Server running on http://localhost:${PORT}`);
|
|
115
|
+
console.log(`📋 Heicat monitoring enabled`);
|
|
116
|
+
});
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "heicat",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Runtime-enforced API contract system for Node.js",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "npm run build --workspaces",
|
|
8
|
+
"build:core": "npm run build --workspace=@heicat/core",
|
|
9
|
+
"build:cli": "npm run build --workspace=@heicat/cli",
|
|
10
|
+
"clean": "npm run clean --workspaces",
|
|
11
|
+
"test": "npm run test --workspaces",
|
|
12
|
+
"lint": "npm run lint --workspaces",
|
|
13
|
+
"dev": "npm run dev --workspaces",
|
|
14
|
+
"prepare": "npm run build",
|
|
15
|
+
"release": "npm version patch && npm publish --workspaces"
|
|
16
|
+
},
|
|
17
|
+
"workspaces": [
|
|
18
|
+
"packages/*"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"api",
|
|
22
|
+
"contract",
|
|
23
|
+
"validation",
|
|
24
|
+
"runtime",
|
|
25
|
+
"express",
|
|
26
|
+
"nodejs",
|
|
27
|
+
"middleware"
|
|
28
|
+
],
|
|
29
|
+
"author": "Backend Contract Studio",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/your-org/heicat.git"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/your-org/heicat/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/your-org/heicat#readme",
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.0.0",
|
|
41
|
+
"typescript": "^5.0.0"
|
|
42
|
+
}
|
|
43
|
+
}
|