@hyperdrive.bot/gut 0.1.3
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 +809 -0
- package/bin/dev +16 -0
- package/bin/run +5 -0
- package/dist/base-command.d.ts +21 -0
- package/dist/base-command.js +110 -0
- package/dist/commands/add.d.ts +13 -0
- package/dist/commands/add.js +73 -0
- package/dist/commands/affected.d.ts +23 -0
- package/dist/commands/affected.js +326 -0
- package/dist/commands/audit.d.ts +33 -0
- package/dist/commands/audit.js +593 -0
- package/dist/commands/back.d.ts +6 -0
- package/dist/commands/back.js +29 -0
- package/dist/commands/commit.d.ts +11 -0
- package/dist/commands/commit.js +113 -0
- package/dist/commands/context.d.ts +6 -0
- package/dist/commands/context.js +36 -0
- package/dist/commands/contexts.d.ts +7 -0
- package/dist/commands/contexts.js +92 -0
- package/dist/commands/deps.d.ts +10 -0
- package/dist/commands/deps.js +104 -0
- package/dist/commands/entity/add.d.ts +16 -0
- package/dist/commands/entity/add.js +105 -0
- package/dist/commands/entity/clone-all.d.ts +17 -0
- package/dist/commands/entity/clone-all.js +135 -0
- package/dist/commands/entity/clone.d.ts +15 -0
- package/dist/commands/entity/clone.js +109 -0
- package/dist/commands/entity/list.d.ts +11 -0
- package/dist/commands/entity/list.js +82 -0
- package/dist/commands/entity/remove.d.ts +12 -0
- package/dist/commands/entity/remove.js +58 -0
- package/dist/commands/focus.d.ts +19 -0
- package/dist/commands/focus.js +139 -0
- package/dist/commands/graph.d.ts +18 -0
- package/dist/commands/graph.js +238 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.js +84 -0
- package/dist/commands/insights.d.ts +21 -0
- package/dist/commands/insights.js +434 -0
- package/dist/commands/patterns.d.ts +40 -0
- package/dist/commands/patterns.js +412 -0
- package/dist/commands/pull.d.ts +11 -0
- package/dist/commands/pull.js +121 -0
- package/dist/commands/push.d.ts +11 -0
- package/dist/commands/push.js +101 -0
- package/dist/commands/quick-setup.d.ts +20 -0
- package/dist/commands/quick-setup.js +422 -0
- package/dist/commands/recent.d.ts +9 -0
- package/dist/commands/recent.js +55 -0
- package/dist/commands/related.d.ts +23 -0
- package/dist/commands/related.js +257 -0
- package/dist/commands/repos.d.ts +14 -0
- package/dist/commands/repos.js +185 -0
- package/dist/commands/stack.d.ts +10 -0
- package/dist/commands/stack.js +83 -0
- package/dist/commands/status.d.ts +14 -0
- package/dist/commands/status.js +246 -0
- package/dist/commands/sync.d.ts +11 -0
- package/dist/commands/sync.js +142 -0
- package/dist/commands/unfocus.d.ts +6 -0
- package/dist/commands/unfocus.js +23 -0
- package/dist/commands/used-by.d.ts +10 -0
- package/dist/commands/used-by.js +111 -0
- package/dist/commands/workspace.d.ts +20 -0
- package/dist/commands/workspace.js +365 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/models/entity.model.d.ts +81 -0
- package/dist/models/entity.model.js +2 -0
- package/dist/services/config.service.d.ts +34 -0
- package/dist/services/config.service.js +230 -0
- package/dist/services/entity.service.d.ts +19 -0
- package/dist/services/entity.service.js +130 -0
- package/dist/services/focus.service.d.ts +70 -0
- package/dist/services/focus.service.js +587 -0
- package/dist/services/git.service.d.ts +37 -0
- package/dist/services/git.service.js +180 -0
- package/dist/utils/display.d.ts +25 -0
- package/dist/utils/display.js +150 -0
- package/dist/utils/filesystem.d.ts +32 -0
- package/dist/utils/filesystem.js +220 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/validation.d.ts +22 -0
- package/dist/utils/validation.js +196 -0
- package/oclif.manifest.json +1463 -0
- package/package.json +76 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationUtils = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
|
+
class ValidationUtils {
|
|
8
|
+
static isValidEntityName(name) {
|
|
9
|
+
// Entity names should be alphanumeric with hyphens/underscores
|
|
10
|
+
const pattern = /^[a-zA-Z0-9]([a-zA-Z0-9-_]*[a-zA-Z0-9])?$/;
|
|
11
|
+
return pattern.test(name) && name.length <= 50;
|
|
12
|
+
}
|
|
13
|
+
static isValidEntityType(type) {
|
|
14
|
+
const validTypes = ['delivery', 'module', 'service', 'tool'];
|
|
15
|
+
return validTypes.includes(type);
|
|
16
|
+
}
|
|
17
|
+
static isValidPath(inputPath) {
|
|
18
|
+
try {
|
|
19
|
+
// Check if path is valid
|
|
20
|
+
path.parse(inputPath);
|
|
21
|
+
// Check for dangerous patterns
|
|
22
|
+
const dangerous = ['..', '~', '$', '`', '|', '&', ';', '>', '<'];
|
|
23
|
+
return !dangerous.some(pattern => inputPath.includes(pattern));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
static isGitRepository(dirPath) {
|
|
30
|
+
return fs.existsSync(path.join(dirPath, '.git'));
|
|
31
|
+
}
|
|
32
|
+
static isValidGitUrl(url) {
|
|
33
|
+
const patterns = [
|
|
34
|
+
/^https?:\/\/.+\.git$/,
|
|
35
|
+
/^git@.+:.+\.git$/,
|
|
36
|
+
/^ssh:\/\/.+\.git$/,
|
|
37
|
+
/^https:\/\/github\.com\/.+\/.+$/,
|
|
38
|
+
/^https:\/\/gitlab\.com\/.+\/.+$/,
|
|
39
|
+
/^https:\/\/bitbucket\.org\/.+\/.+$/,
|
|
40
|
+
];
|
|
41
|
+
return patterns.some(pattern => pattern.test(url));
|
|
42
|
+
}
|
|
43
|
+
static isValidBranch(branch) {
|
|
44
|
+
// Git branch naming rules
|
|
45
|
+
const invalidPatterns = [
|
|
46
|
+
/^\./, // Cannot start with .
|
|
47
|
+
/\.$/, // Cannot end with .
|
|
48
|
+
/\.\./, // Cannot contain ..
|
|
49
|
+
/\/\//, // Cannot contain //
|
|
50
|
+
/\s/, // Cannot contain spaces
|
|
51
|
+
/[\x00-\x1f\x7f]/, // Cannot contain control characters
|
|
52
|
+
/[~^:?*\[\\]/, // Cannot contain special characters
|
|
53
|
+
];
|
|
54
|
+
return !invalidPatterns.some(pattern => pattern.test(branch)) &&
|
|
55
|
+
branch.length > 0 &&
|
|
56
|
+
branch.length <= 255;
|
|
57
|
+
}
|
|
58
|
+
static isNodeProject(dirPath) {
|
|
59
|
+
return fs.existsSync(path.join(dirPath, 'package.json'));
|
|
60
|
+
}
|
|
61
|
+
static isPythonProject(dirPath) {
|
|
62
|
+
return fs.existsSync(path.join(dirPath, 'requirements.txt')) ||
|
|
63
|
+
fs.existsSync(path.join(dirPath, 'setup.py')) ||
|
|
64
|
+
fs.existsSync(path.join(dirPath, 'pyproject.toml'));
|
|
65
|
+
}
|
|
66
|
+
static isGoProject(dirPath) {
|
|
67
|
+
return fs.existsSync(path.join(dirPath, 'go.mod'));
|
|
68
|
+
}
|
|
69
|
+
static isRustProject(dirPath) {
|
|
70
|
+
return fs.existsSync(path.join(dirPath, 'Cargo.toml'));
|
|
71
|
+
}
|
|
72
|
+
static isJavaProject(dirPath) {
|
|
73
|
+
return fs.existsSync(path.join(dirPath, 'pom.xml')) ||
|
|
74
|
+
fs.existsSync(path.join(dirPath, 'build.gradle')) ||
|
|
75
|
+
fs.existsSync(path.join(dirPath, 'build.gradle.kts'));
|
|
76
|
+
}
|
|
77
|
+
static detectProjectType(dirPath) {
|
|
78
|
+
if (this.isNodeProject(dirPath))
|
|
79
|
+
return 'node';
|
|
80
|
+
if (this.isPythonProject(dirPath))
|
|
81
|
+
return 'python';
|
|
82
|
+
if (this.isGoProject(dirPath))
|
|
83
|
+
return 'go';
|
|
84
|
+
if (this.isRustProject(dirPath))
|
|
85
|
+
return 'rust';
|
|
86
|
+
if (this.isJavaProject(dirPath))
|
|
87
|
+
return 'java';
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
static validateEntityData(data) {
|
|
91
|
+
const errors = [];
|
|
92
|
+
if (!data.name) {
|
|
93
|
+
errors.push('Entity name is required');
|
|
94
|
+
}
|
|
95
|
+
else if (!this.isValidEntityName(data.name)) {
|
|
96
|
+
errors.push('Invalid entity name format');
|
|
97
|
+
}
|
|
98
|
+
if (!data.type) {
|
|
99
|
+
errors.push('Entity type is required');
|
|
100
|
+
}
|
|
101
|
+
else if (!this.isValidEntityType(data.type)) {
|
|
102
|
+
errors.push('Invalid entity type');
|
|
103
|
+
}
|
|
104
|
+
if (!data.path) {
|
|
105
|
+
errors.push('Entity path is required');
|
|
106
|
+
}
|
|
107
|
+
else if (!this.isValidPath(data.path)) {
|
|
108
|
+
errors.push('Invalid entity path');
|
|
109
|
+
}
|
|
110
|
+
if (data.repository && !this.isValidGitUrl(data.repository)) {
|
|
111
|
+
errors.push('Invalid repository URL');
|
|
112
|
+
}
|
|
113
|
+
return errors;
|
|
114
|
+
}
|
|
115
|
+
static validateFocusEntities(entities, availableEntities) {
|
|
116
|
+
const errors = [];
|
|
117
|
+
if (entities.length === 0) {
|
|
118
|
+
errors.push('At least one entity must be specified');
|
|
119
|
+
}
|
|
120
|
+
const unavailable = entities.filter(e => !availableEntities.includes(e));
|
|
121
|
+
if (unavailable.length > 0) {
|
|
122
|
+
errors.push(`Unknown entities: ${unavailable.join(', ')}`);
|
|
123
|
+
}
|
|
124
|
+
const duplicates = entities.filter((e, i) => entities.indexOf(e) !== i);
|
|
125
|
+
if (duplicates.length > 0) {
|
|
126
|
+
errors.push(`Duplicate entities: ${[...new Set(duplicates)].join(', ')}`);
|
|
127
|
+
}
|
|
128
|
+
return errors;
|
|
129
|
+
}
|
|
130
|
+
static sanitizePath(inputPath) {
|
|
131
|
+
// Remove trailing slashes
|
|
132
|
+
let sanitized = inputPath.replace(/\/+$/, '');
|
|
133
|
+
// Normalize path separators
|
|
134
|
+
sanitized = sanitized.replace(/\\/g, '/');
|
|
135
|
+
// Remove redundant slashes
|
|
136
|
+
sanitized = sanitized.replace(/\/+/g, '/');
|
|
137
|
+
return sanitized;
|
|
138
|
+
}
|
|
139
|
+
static sanitizeGitUrl(url) {
|
|
140
|
+
// Ensure .git extension for common providers
|
|
141
|
+
if (!url.endsWith('.git')) {
|
|
142
|
+
const providers = ['github.com', 'gitlab.com', 'bitbucket.org'];
|
|
143
|
+
if (providers.some(p => url.includes(p))) {
|
|
144
|
+
url += '.git';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return url;
|
|
148
|
+
}
|
|
149
|
+
static isEmptyDirectory(dirPath) {
|
|
150
|
+
try {
|
|
151
|
+
const files = fs.readdirSync(dirPath);
|
|
152
|
+
return files.length === 0 ||
|
|
153
|
+
(files.length === 1 && files[0] === '.git');
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
static hasUncommittedChanges(dirPath) {
|
|
160
|
+
if (!this.isGitRepository(dirPath)) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const { execSync } = require('child_process');
|
|
165
|
+
const status = execSync('git status --porcelain', {
|
|
166
|
+
cwd: dirPath,
|
|
167
|
+
encoding: 'utf-8',
|
|
168
|
+
stdio: 'pipe',
|
|
169
|
+
});
|
|
170
|
+
return status.trim().length > 0;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
static validateConfig(config) {
|
|
177
|
+
const errors = [];
|
|
178
|
+
if (!config.workspace) {
|
|
179
|
+
errors.push('Workspace configuration is missing');
|
|
180
|
+
}
|
|
181
|
+
if (!config.entities || typeof config.entities !== 'object') {
|
|
182
|
+
errors.push('Entities configuration is invalid');
|
|
183
|
+
}
|
|
184
|
+
if (config.focus) {
|
|
185
|
+
if (!Array.isArray(config.focus.entities)) {
|
|
186
|
+
errors.push('Focus entities must be an array');
|
|
187
|
+
}
|
|
188
|
+
if (!Array.isArray(config.focus.history)) {
|
|
189
|
+
errors.push('Focus history must be an array');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return errors;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
exports.ValidationUtils = ValidationUtils;
|
|
196
|
+
exports.default = ValidationUtils;
|