@manojkmfsi/monodog 1.1.37 → 1.1.39
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/CHANGELOG.md +12 -0
- package/monodog-dashboard/dist/assets/index-C08ciT3A.js +20 -0
- package/monodog-dashboard/dist/assets/index-C08ciT3A.js.map +1 -0
- package/monodog-dashboard/dist/assets/index-Dc2vaUOq.css +1 -0
- package/monodog-dashboard/{index.html → dist/index.html} +2 -1
- package/monodog-dashboard/package.json +0 -3
- package/package.json +2 -2
- package/monodog-dashboard/THEME_SYSTEM.md +0 -309
- package/monodog-dashboard/__tests__/AuthCallbackPage.test.ts +0 -138
- package/monodog-dashboard/__tests__/ConfigInspector.test.ts +0 -33
- package/monodog-dashboard/__tests__/DependencyGraph.test.ts +0 -72
- package/monodog-dashboard/__tests__/HealthStatus.test.ts +0 -69
- package/monodog-dashboard/__tests__/LoginPage.test.ts +0 -79
- package/monodog-dashboard/__tests__/PackageDetail.test.ts +0 -22
- package/monodog-dashboard/__tests__/ReleaseManager.test.tsx +0 -510
- package/monodog-dashboard/__tests__/api-client.test.ts +0 -475
- package/monodog-dashboard/__tests__/components.test.ts +0 -117
- package/monodog-dashboard/__tests__/dashboard.utils.test.ts +0 -144
- package/monodog-dashboard/__tests__/dependency.utils.test.ts +0 -125
- package/monodog-dashboard/__tests__/monorepoService.unit.test.ts +0 -103
- package/monodog-dashboard/__tests__/packages.utils.test.ts +0 -37
- package/monodog-dashboard/__tests__/pages.test.ts +0 -103
- package/monodog-dashboard/package-lock.json +0 -4587
- package/monodog-dashboard/postcss.config.js +0 -6
- package/monodog-dashboard/src/components/App.tsx +0 -36
- package/monodog-dashboard/src/components/LoadingState.tsx +0 -18
- package/monodog-dashboard/src/components/PermissionGuard.tsx +0 -92
- package/monodog-dashboard/src/components/ProtectedRoute.tsx +0 -24
- package/monodog-dashboard/src/components/configuration/Configuration.tsx +0 -91
- package/monodog-dashboard/src/components/configuration/components/BrandingSettings.tsx +0 -128
- package/monodog-dashboard/src/components/configuration/components/ConfigurationHeader.tsx +0 -34
- package/monodog-dashboard/src/components/configuration/components/ConfigurationModal.tsx +0 -20
- package/monodog-dashboard/src/components/configuration/components/ConfigurationTabs.tsx +0 -30
- package/monodog-dashboard/src/components/configuration/components/FeatureToggles.tsx +0 -66
- package/monodog-dashboard/src/components/configuration/components/GeneralSettings.tsx +0 -77
- package/monodog-dashboard/src/components/configuration/components/MonorepoSettings.tsx +0 -179
- package/monodog-dashboard/src/components/configuration/components/index.ts +0 -8
- package/monodog-dashboard/src/components/configuration/types/config.types.ts +0 -52
- package/monodog-dashboard/src/components/configuration/utils/config.utils.tsx +0 -115
- package/monodog-dashboard/src/components/main-dashboard/Dashboard.tsx +0 -242
- package/monodog-dashboard/src/components/main-dashboard/Layout.tsx +0 -112
- package/monodog-dashboard/src/components/main-dashboard/components/Header.tsx +0 -47
- package/monodog-dashboard/src/components/main-dashboard/components/PackageDistribution.tsx +0 -35
- package/monodog-dashboard/src/components/main-dashboard/components/PackageSearchFilter.tsx +0 -47
- package/monodog-dashboard/src/components/main-dashboard/components/PackageTable.tsx +0 -87
- package/monodog-dashboard/src/components/main-dashboard/components/QuickActions.tsx +0 -60
- package/monodog-dashboard/src/components/main-dashboard/components/StatsCards.tsx +0 -73
- package/monodog-dashboard/src/components/main-dashboard/components/index.ts +0 -7
- package/monodog-dashboard/src/components/main-dashboard/types/dashboard.types.ts +0 -33
- package/monodog-dashboard/src/components/main-dashboard/utils/dashboard.utils.tsx +0 -70
- package/monodog-dashboard/src/components/modules/ci-integration/CIIntegration.tsx +0 -277
- package/monodog-dashboard/src/components/modules/ci-integration/components/BuildDetails.tsx +0 -228
- package/monodog-dashboard/src/components/modules/ci-integration/components/BuildList.tsx +0 -212
- package/monodog-dashboard/src/components/modules/ci-integration/components/BuildOverview.tsx +0 -158
- package/monodog-dashboard/src/components/modules/ci-integration/components/CIIntegrationHeader.tsx +0 -38
- package/monodog-dashboard/src/components/modules/ci-integration/components/ErrorState.tsx +0 -25
- package/monodog-dashboard/src/components/modules/ci-integration/components/LoadingState.tsx +0 -16
- package/monodog-dashboard/src/components/modules/ci-integration/components/PipelineStatus.tsx +0 -223
- package/monodog-dashboard/src/components/modules/ci-integration/components/index.ts +0 -8
- package/monodog-dashboard/src/components/modules/ci-integration/types/ci.types.ts +0 -97
- package/monodog-dashboard/src/components/modules/ci-integration/utils/ci.utils.tsx +0 -264
- package/monodog-dashboard/src/components/modules/config-inspector/ConfigInspector.tsx +0 -324
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigEditor.tsx +0 -93
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigInspectorHeader.tsx +0 -36
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigPreview.tsx +0 -89
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigSidebar.tsx +0 -141
- package/monodog-dashboard/src/components/modules/config-inspector/components/ConfigToolbar.tsx +0 -184
- package/monodog-dashboard/src/components/modules/config-inspector/components/ErrorState.tsx +0 -25
- package/monodog-dashboard/src/components/modules/config-inspector/components/LoadingState.tsx +0 -16
- package/monodog-dashboard/src/components/modules/config-inspector/components/ValidationPanel.tsx +0 -155
- package/monodog-dashboard/src/components/modules/config-inspector/components/index.ts +0 -9
- package/monodog-dashboard/src/components/modules/config-inspector/types/config.types.ts +0 -100
- package/monodog-dashboard/src/components/modules/config-inspector/utils/config.utils.tsx +0 -704
- package/monodog-dashboard/src/components/modules/dependency-graph/DependencyGraph.tsx +0 -224
- package/monodog-dashboard/src/components/modules/dependency-graph/components/CircularDependencies.tsx +0 -177
- package/monodog-dashboard/src/components/modules/dependency-graph/components/DependencyDetails.tsx +0 -192
- package/monodog-dashboard/src/components/modules/dependency-graph/components/DependencyGraphHeader.tsx +0 -30
- package/monodog-dashboard/src/components/modules/dependency-graph/components/DependencyList.tsx +0 -177
- package/monodog-dashboard/src/components/modules/dependency-graph/components/ErrorState.tsx +0 -25
- package/monodog-dashboard/src/components/modules/dependency-graph/components/GraphLegend.tsx +0 -89
- package/monodog-dashboard/src/components/modules/dependency-graph/components/GraphStats.tsx +0 -141
- package/monodog-dashboard/src/components/modules/dependency-graph/components/GraphToolbar.tsx +0 -107
- package/monodog-dashboard/src/components/modules/dependency-graph/components/GraphVisualization.tsx +0 -179
- package/monodog-dashboard/src/components/modules/dependency-graph/components/LoadingState.tsx +0 -16
- package/monodog-dashboard/src/components/modules/dependency-graph/components/index.ts +0 -11
- package/monodog-dashboard/src/components/modules/dependency-graph/types/dependency.types.ts +0 -105
- package/monodog-dashboard/src/components/modules/dependency-graph/utils/dependency.utils.tsx +0 -433
- package/monodog-dashboard/src/components/modules/health-status/HealthStatus.tsx +0 -739
- package/monodog-dashboard/src/components/modules/health-status/components/ErrorState.tsx +0 -25
- package/monodog-dashboard/src/components/modules/health-status/components/HealthActions.tsx +0 -122
- package/monodog-dashboard/src/components/modules/health-status/components/HealthAlerts.tsx +0 -151
- package/monodog-dashboard/src/components/modules/health-status/components/HealthMetrics.tsx +0 -132
- package/monodog-dashboard/src/components/modules/health-status/components/HealthStatusHeader.tsx +0 -30
- package/monodog-dashboard/src/components/modules/health-status/components/LoadingState.tsx +0 -16
- package/monodog-dashboard/src/components/modules/health-status/components/OverallHealthScore.tsx +0 -122
- package/monodog-dashboard/src/components/modules/health-status/components/PackageHealthList.tsx +0 -195
- package/monodog-dashboard/src/components/modules/health-status/types/health.types.ts +0 -80
- package/monodog-dashboard/src/components/modules/health-status/utils/health.utils.tsx +0 -220
- package/monodog-dashboard/src/components/modules/packages/PackageDetail.tsx +0 -255
- package/monodog-dashboard/src/components/modules/packages/PackagesOverview.tsx +0 -166
- package/monodog-dashboard/src/components/modules/packages/components/ConfigurationTab.tsx +0 -311
- package/monodog-dashboard/src/components/modules/packages/components/DependenciesTab.tsx +0 -154
- package/monodog-dashboard/src/components/modules/packages/components/ErrorState.tsx +0 -21
- package/monodog-dashboard/src/components/modules/packages/components/HealthMetricsTab.tsx +0 -275
- package/monodog-dashboard/src/components/modules/packages/components/LoadingState.tsx +0 -14
- package/monodog-dashboard/src/components/modules/packages/components/PackageDetailHeader.tsx +0 -167
- package/monodog-dashboard/src/components/modules/packages/components/PackageDetailTabs.tsx +0 -49
- package/monodog-dashboard/src/components/modules/packages/components/PackageStats.tsx +0 -70
- package/monodog-dashboard/src/components/modules/packages/components/PackagesTable.tsx +0 -163
- package/monodog-dashboard/src/components/modules/packages/components/RecentCommitsTab.tsx +0 -90
- package/monodog-dashboard/src/components/modules/packages/components/SearchAndFilter.tsx +0 -66
- package/monodog-dashboard/src/components/modules/packages/components/index.ts +0 -12
- package/monodog-dashboard/src/components/modules/packages/types/packages.types.ts +0 -101
- package/monodog-dashboard/src/components/modules/packages/utils/packages.utils.tsx +0 -178
- package/monodog-dashboard/src/components/pipeline/JobsList.tsx +0 -83
- package/monodog-dashboard/src/components/pipeline/LogViewer.tsx +0 -392
- package/monodog-dashboard/src/components/pipeline/PipelineManager.tsx +0 -562
- package/monodog-dashboard/src/components/pipeline/WorkflowRunsList.tsx +0 -272
- package/monodog-dashboard/src/components/pipeline/WorkflowTrigger.tsx +0 -182
- package/monodog-dashboard/src/components/pipeline/utils/pipeline.utils.tsx +0 -11
- package/monodog-dashboard/src/components/publish-control/PublishControl.tsx +0 -229
- package/monodog-dashboard/src/components/publish-control/components/ChangelogViewer.tsx +0 -103
- package/monodog-dashboard/src/components/publish-control/components/ErrorState.tsx +0 -23
- package/monodog-dashboard/src/components/publish-control/components/LoadingState.tsx +0 -10
- package/monodog-dashboard/src/components/publish-control/components/PackageReleaseTable.tsx +0 -140
- package/monodog-dashboard/src/components/publish-control/components/PublishHeader.tsx +0 -30
- package/monodog-dashboard/src/components/publish-control/components/QuickActionCards.tsx +0 -56
- package/monodog-dashboard/src/components/publish-control/components/ReleaseSchedule.tsx +0 -104
- package/monodog-dashboard/src/components/publish-control/components/index.ts +0 -8
- package/monodog-dashboard/src/components/publish-control/types/publish.types.ts +0 -39
- package/monodog-dashboard/src/components/publish-control/utils/publish.utils.ts +0 -59
- package/monodog-dashboard/src/components/release-manager/ReleaseManager.tsx +0 -342
- package/monodog-dashboard/src/components/release-manager/components/ChangesetPreview.tsx +0 -123
- package/monodog-dashboard/src/components/release-manager/components/ErrorState.tsx +0 -38
- package/monodog-dashboard/src/components/release-manager/components/LoadingState.tsx +0 -18
- package/monodog-dashboard/src/components/release-manager/components/PackageSelector.tsx +0 -137
- package/monodog-dashboard/src/components/release-manager/components/PublishConfirmation.tsx +0 -150
- package/monodog-dashboard/src/components/release-manager/components/ReleaseValidation.tsx +0 -138
- package/monodog-dashboard/src/components/release-manager/components/VersionBumpSelector.tsx +0 -142
- package/monodog-dashboard/src/components/release-manager/types/index.ts +0 -9
- package/monodog-dashboard/src/components/release-manager/types/release-manager.types.ts +0 -29
- package/monodog-dashboard/src/components/setup-guide/SetupGuide.tsx +0 -96
- package/monodog-dashboard/src/components/setup-guide/components/SetupHeader.tsx +0 -24
- package/monodog-dashboard/src/components/setup-guide/components/SetupModal.tsx +0 -24
- package/monodog-dashboard/src/components/setup-guide/components/SetupProgress.tsx +0 -29
- package/monodog-dashboard/src/components/setup-guide/components/StepContent.tsx +0 -272
- package/monodog-dashboard/src/components/setup-guide/components/StepNavigation.tsx +0 -62
- package/monodog-dashboard/src/components/setup-guide/components/index.ts +0 -6
- package/monodog-dashboard/src/components/setup-guide/types/setup.types.ts +0 -38
- package/monodog-dashboard/src/components/setup-guide/utils/setup.utils.ts +0 -79
- package/monodog-dashboard/src/constants/api-config.ts +0 -81
- package/monodog-dashboard/src/constants/index.ts +0 -9
- package/monodog-dashboard/src/constants/messages.ts +0 -40
- package/monodog-dashboard/src/icons/heroicons.ts +0 -65
- package/monodog-dashboard/src/icons/index.tsx +0 -1788
- package/monodog-dashboard/src/index.css +0 -175
- package/monodog-dashboard/src/main.tsx +0 -9
- package/monodog-dashboard/src/pages/AuthCallbackPage.tsx +0 -103
- package/monodog-dashboard/src/pages/CIPage.tsx +0 -6
- package/monodog-dashboard/src/pages/ConfigPage.tsx +0 -6
- package/monodog-dashboard/src/pages/DashboardPage.tsx +0 -6
- package/monodog-dashboard/src/pages/DependenciesPage.tsx +0 -6
- package/monodog-dashboard/src/pages/HealthPage.tsx +0 -6
- package/monodog-dashboard/src/pages/LoginPage.tsx +0 -77
- package/monodog-dashboard/src/pages/PackageDetailPage.tsx +0 -6
- package/monodog-dashboard/src/pages/PackagesPage.tsx +0 -6
- package/monodog-dashboard/src/pages/PipelinePage.tsx +0 -22
- package/monodog-dashboard/src/pages/PublishPage.tsx +0 -6
- package/monodog-dashboard/src/pages/ReleaseManagerPage.tsx +0 -9
- package/monodog-dashboard/src/pages/index.ts +0 -28
- package/monodog-dashboard/src/routes/AppRouter.tsx +0 -89
- package/monodog-dashboard/src/routes/AppRouterPages.tsx +0 -56
- package/monodog-dashboard/src/routes/index.ts +0 -10
- package/monodog-dashboard/src/routes/routes.config.ts +0 -94
- package/monodog-dashboard/src/services/api/api-client.ts +0 -189
- package/monodog-dashboard/src/services/api/index.ts +0 -30
- package/monodog-dashboard/src/services/api/types/api.types.ts +0 -63
- package/monodog-dashboard/src/services/auth-context.tsx +0 -344
- package/monodog-dashboard/src/services/monorepoService.ts +0 -733
- package/monodog-dashboard/src/services/permission-context.tsx +0 -193
- package/monodog-dashboard/src/theme/COMPONENT_UPDATES.md +0 -273
- package/monodog-dashboard/src/theme/INTEGRATION.md +0 -381
- package/monodog-dashboard/src/theme/README.md +0 -239
- package/monodog-dashboard/src/theme/examples.tsx +0 -386
- package/monodog-dashboard/src/theme/index.ts +0 -402
- package/monodog-dashboard/src/theme/migration-guide.md +0 -335
- package/monodog-dashboard/src/types/auth-context.types.ts +0 -51
- package/monodog-dashboard/src/types/component.types.ts +0 -96
- package/monodog-dashboard/src/types/icons.types.ts +0 -13
- package/monodog-dashboard/src/types/index.ts +0 -68
- package/monodog-dashboard/src/types/monorepo-service.types.ts +0 -53
- package/monodog-dashboard/src/types/permission-context.types.ts +0 -49
- package/monodog-dashboard/src/types/pipeline.types.ts +0 -89
- package/monodog-dashboard/src/types/routes.types.ts +0 -12
- package/monodog-dashboard/src/utils/cookies.ts +0 -47
- package/monodog-dashboard/tailwind.config.js +0 -68
- package/monodog-dashboard/tsconfig.app.json +0 -14
- package/monodog-dashboard/tsconfig.json +0 -17
- package/monodog-dashboard/tsconfig.node.json +0 -10
- package/monodog-dashboard/vite.config.ts +0 -9
|
@@ -1,704 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ConfigFile,
|
|
3
|
-
ConfigFilters,
|
|
4
|
-
ValidationResult,
|
|
5
|
-
} from '../types/config.types';
|
|
6
|
-
import yaml from 'js-yaml';
|
|
7
|
-
import { FolderIcon } from '../../../../icons/heroicons';
|
|
8
|
-
import { Cog6ToothIcon } from '../../../../icons/heroicons';
|
|
9
|
-
import { DocumentIcon } from '../../../../icons/heroicons';
|
|
10
|
-
|
|
11
|
-
// Get status color classes
|
|
12
|
-
export const getStatusColor = (status: string): string => {
|
|
13
|
-
switch (status) {
|
|
14
|
-
case 'active':
|
|
15
|
-
return 'bg-green-100 text-green-800';
|
|
16
|
-
case 'inactive':
|
|
17
|
-
return 'bg-gray-100 text-gray-800';
|
|
18
|
-
case 'error':
|
|
19
|
-
return 'bg-red-100 text-red-800';
|
|
20
|
-
default:
|
|
21
|
-
return 'bg-gray-100 text-gray-800';
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
// Get type color classes
|
|
26
|
-
export const getTypeColor = (type: string): string => {
|
|
27
|
-
switch (type) {
|
|
28
|
-
case 'workspace':
|
|
29
|
-
return 'bg-blue-100 text-blue-800';
|
|
30
|
-
case 'package':
|
|
31
|
-
return 'bg-green-100 text-green-800';
|
|
32
|
-
case 'environment':
|
|
33
|
-
return 'bg-purple-100 text-purple-800';
|
|
34
|
-
case 'tool':
|
|
35
|
-
return 'bg-orange-100 text-orange-800';
|
|
36
|
-
default:
|
|
37
|
-
return 'bg-gray-100 text-gray-800';
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// Get validation status color
|
|
42
|
-
export const getValidationColor = (status: string): string => {
|
|
43
|
-
switch (status) {
|
|
44
|
-
case 'valid':
|
|
45
|
-
return 'bg-green-100 text-green-800';
|
|
46
|
-
case 'warning':
|
|
47
|
-
return 'bg-yellow-100 text-yellow-800';
|
|
48
|
-
case 'error':
|
|
49
|
-
return 'bg-red-100 text-red-800';
|
|
50
|
-
default:
|
|
51
|
-
return 'bg-gray-100 text-gray-800';
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// Filter configurations based on criteria
|
|
56
|
-
export const filterConfigs = (
|
|
57
|
-
configs: ConfigFile[],
|
|
58
|
-
filters: ConfigFilters
|
|
59
|
-
): ConfigFile[] => {
|
|
60
|
-
return configs.filter(config => {
|
|
61
|
-
const matchesSection =
|
|
62
|
-
filters.section === 'all' || config.id === filters.section;
|
|
63
|
-
const matchesType = filters.type === 'all' || config.type === filters.type;
|
|
64
|
-
const matchesStatus =
|
|
65
|
-
filters.status === 'all' ||
|
|
66
|
-
(filters.status === 'secrets' && config.hasSecrets) ||
|
|
67
|
-
(filters.status === 'standard' && !config.hasSecrets);
|
|
68
|
-
const matchesSearch =
|
|
69
|
-
!filters.search ||
|
|
70
|
-
config.name.toLowerCase().includes(filters.search.toLowerCase()) ||
|
|
71
|
-
config.path.toLowerCase().includes(filters.search.toLowerCase());
|
|
72
|
-
|
|
73
|
-
return matchesSection && matchesType && matchesStatus && matchesSearch;
|
|
74
|
-
});
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// Get unique values for filter options
|
|
78
|
-
export const getUniqueTypes = (configs: ConfigFile[]): string[] => {
|
|
79
|
-
return [...new Set(configs.map(config => config.type))];
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
// Format file size
|
|
83
|
-
export const formatFileSize = (bytes: number): string => {
|
|
84
|
-
if (bytes === 0) return '0 Bytes';
|
|
85
|
-
const k = 1024;
|
|
86
|
-
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
87
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
88
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// Format date
|
|
92
|
-
export const formatDate = (dateString: string): string => {
|
|
93
|
-
const date = new Date(dateString);
|
|
94
|
-
return date.toLocaleDateString('en-US', {
|
|
95
|
-
year: 'numeric',
|
|
96
|
-
month: 'short',
|
|
97
|
-
day: 'numeric',
|
|
98
|
-
hour: '2-digit',
|
|
99
|
-
minute: '2-digit',
|
|
100
|
-
});
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// Enhanced language detection
|
|
104
|
-
export const detectLanguage = (filename: string): string => {
|
|
105
|
-
const extension = filename.split('.').pop()?.toLowerCase();
|
|
106
|
-
|
|
107
|
-
const languageMap: { [key: string]: string } = {
|
|
108
|
-
json: 'json',
|
|
109
|
-
yaml: 'yaml',
|
|
110
|
-
yml: 'yaml',
|
|
111
|
-
js: 'javascript',
|
|
112
|
-
mjs: 'javascript',
|
|
113
|
-
cjs: 'javascript',
|
|
114
|
-
ts: 'typescript',
|
|
115
|
-
mts: 'typescript',
|
|
116
|
-
cts: 'typescript',
|
|
117
|
-
env: 'env',
|
|
118
|
-
config: 'text',
|
|
119
|
-
rc: 'text',
|
|
120
|
-
lock: 'text',
|
|
121
|
-
md: 'markdown',
|
|
122
|
-
txt: 'text',
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
// Special case for known config files
|
|
126
|
-
if (filename === 'package.json') return 'json';
|
|
127
|
-
if (filename === 'docker-compose.yml' || filename === 'docker-compose.yaml')
|
|
128
|
-
return 'yaml';
|
|
129
|
-
if (filename === '.eslintrc.js' || filename === '.prettierrc.js')
|
|
130
|
-
return 'javascript';
|
|
131
|
-
if (filename === 'tsconfig.json') return 'json';
|
|
132
|
-
|
|
133
|
-
return languageMap[extension || ''] || 'text';
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
// Check if content contains secrets
|
|
137
|
-
export const containsSecrets = (content: string): boolean => {
|
|
138
|
-
const secretPatterns = [
|
|
139
|
-
/password/i,
|
|
140
|
-
/secret/i,
|
|
141
|
-
/key/i,
|
|
142
|
-
/token/i,
|
|
143
|
-
/auth/i,
|
|
144
|
-
/credential/i,
|
|
145
|
-
/api_key/i,
|
|
146
|
-
/private_key/i,
|
|
147
|
-
];
|
|
148
|
-
|
|
149
|
-
return secretPatterns.some(pattern => pattern.test(content));
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
// Mask sensitive values
|
|
153
|
-
export const maskSecrets = (content: string): string => {
|
|
154
|
-
// Common patterns for secrets in different formats
|
|
155
|
-
const patterns = [
|
|
156
|
-
// Environment variables: KEY=value
|
|
157
|
-
/^([A-Z_]+(?:PASSWORD|SECRET|KEY|TOKEN|AUTH)[A-Z_]*)\s*=\s*(.+)$/gim,
|
|
158
|
-
// JSON: "key": "value"
|
|
159
|
-
/"([^"]*(?:password|secret|key|token|auth)[^"]*)"\s*:\s*"([^"]+)"/gi,
|
|
160
|
-
// YAML: key: value
|
|
161
|
-
/^(\s*[^:\s]*(?:password|secret|key|token|auth)[^:\s]*)\s*:\s*(.+)$/gim,
|
|
162
|
-
];
|
|
163
|
-
|
|
164
|
-
let maskedContent = content;
|
|
165
|
-
patterns.forEach(pattern => {
|
|
166
|
-
maskedContent = maskedContent.replace(pattern, (match, key, value) => {
|
|
167
|
-
const maskedValue = '*'.repeat(Math.min(value.length, 8));
|
|
168
|
-
return match.replace(value, maskedValue);
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
return maskedContent;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// Validate configuration content
|
|
176
|
-
// export const validateConfig = (
|
|
177
|
-
// content: string,
|
|
178
|
-
// filename: string
|
|
179
|
-
// ): ValidationResult[] => {
|
|
180
|
-
// const results: ValidationResult[] = [];
|
|
181
|
-
// const language = detectLanguage(filename);
|
|
182
|
-
|
|
183
|
-
// try {
|
|
184
|
-
// switch (language) {
|
|
185
|
-
// case 'json':
|
|
186
|
-
// JSON.parse(content);
|
|
187
|
-
// results.push({
|
|
188
|
-
// field: filename,
|
|
189
|
-
// status: 'valid',
|
|
190
|
-
// message: 'Valid JSON syntax',
|
|
191
|
-
// });
|
|
192
|
-
// break;
|
|
193
|
-
// case 'yaml':
|
|
194
|
-
// // Basic YAML validation (would use a proper YAML parser in real implementation)
|
|
195
|
-
// if (content.includes('\t')) {
|
|
196
|
-
// results.push({
|
|
197
|
-
// field: filename,
|
|
198
|
-
// status: 'warning',
|
|
199
|
-
// message: 'YAML files should use spaces instead of tabs',
|
|
200
|
-
// });
|
|
201
|
-
// } else {
|
|
202
|
-
// results.push({
|
|
203
|
-
// field: filename,
|
|
204
|
-
// status: 'valid',
|
|
205
|
-
// message: 'Valid YAML syntax',
|
|
206
|
-
// });
|
|
207
|
-
// }
|
|
208
|
-
// break;
|
|
209
|
-
// default:
|
|
210
|
-
// results.push({
|
|
211
|
-
// field: filename,
|
|
212
|
-
// status: 'valid',
|
|
213
|
-
// message: 'File format appears valid',
|
|
214
|
-
// });
|
|
215
|
-
// }
|
|
216
|
-
// } catch (error) {
|
|
217
|
-
// results.push({
|
|
218
|
-
// field: filename,
|
|
219
|
-
// status: 'error',
|
|
220
|
-
// message: `Invalid ${language.toUpperCase()} syntax: ${error}`,
|
|
221
|
-
// });
|
|
222
|
-
// }
|
|
223
|
-
|
|
224
|
-
// // Check for security issues
|
|
225
|
-
// if (containsSecrets(content) && !filename.includes('.env')) {
|
|
226
|
-
// results.push({
|
|
227
|
-
// field: filename,
|
|
228
|
-
// status: 'warning',
|
|
229
|
-
// message: 'File may contain sensitive information',
|
|
230
|
-
// });
|
|
231
|
-
// }
|
|
232
|
-
|
|
233
|
-
// // Check for common issues
|
|
234
|
-
// if (content.includes('TODO') || content.includes('FIXME')) {
|
|
235
|
-
// results.push({
|
|
236
|
-
// field: filename,
|
|
237
|
-
// status: 'warning',
|
|
238
|
-
// message: 'File contains TODO or FIXME comments',
|
|
239
|
-
// });
|
|
240
|
-
// }
|
|
241
|
-
|
|
242
|
-
// return results;
|
|
243
|
-
// };
|
|
244
|
-
|
|
245
|
-
export const validateConfig = (
|
|
246
|
-
content: string,
|
|
247
|
-
filename: string
|
|
248
|
-
): ValidationResult[] => {
|
|
249
|
-
const results: ValidationResult[] = [];
|
|
250
|
-
const language = detectLanguage(filename);
|
|
251
|
-
|
|
252
|
-
try {
|
|
253
|
-
switch (language) {
|
|
254
|
-
case 'json':
|
|
255
|
-
validateJSON(content, filename, results);
|
|
256
|
-
break;
|
|
257
|
-
case 'yaml':
|
|
258
|
-
validateYAML(content, filename, results);
|
|
259
|
-
break;
|
|
260
|
-
case 'javascript':
|
|
261
|
-
case 'typescript':
|
|
262
|
-
validateJavaScript(content, filename, results);
|
|
263
|
-
break;
|
|
264
|
-
case 'env':
|
|
265
|
-
validateEnv(content, filename, results);
|
|
266
|
-
break;
|
|
267
|
-
default:
|
|
268
|
-
validateGeneric(content, filename, results);
|
|
269
|
-
}
|
|
270
|
-
} catch (error) {
|
|
271
|
-
results.push({
|
|
272
|
-
field: filename,
|
|
273
|
-
status: 'error',
|
|
274
|
-
message: `Validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Common validations for all file types
|
|
279
|
-
validateCommonIssues(content, filename, results);
|
|
280
|
-
|
|
281
|
-
return results;
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
// JSON Validation
|
|
285
|
-
const validateJSON = (
|
|
286
|
-
content: string,
|
|
287
|
-
filename: string,
|
|
288
|
-
results: ValidationResult[]
|
|
289
|
-
) => {
|
|
290
|
-
try {
|
|
291
|
-
const parsed = JSON.parse(content);
|
|
292
|
-
|
|
293
|
-
// Basic syntax validation
|
|
294
|
-
results.push({
|
|
295
|
-
field: filename,
|
|
296
|
-
status: 'valid',
|
|
297
|
-
message: 'Valid JSON syntax',
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
// Package.json specific validations
|
|
301
|
-
if (filename === 'package.json') {
|
|
302
|
-
validatePackageJSON(parsed, results);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Additional JSON structure validations
|
|
306
|
-
if (typeof parsed === 'object') {
|
|
307
|
-
validateJSONStructure(parsed, filename, results);
|
|
308
|
-
}
|
|
309
|
-
} catch (error) {
|
|
310
|
-
results.push({
|
|
311
|
-
field: filename,
|
|
312
|
-
status: 'error',
|
|
313
|
-
message: `Invalid JSON: ${error instanceof Error ? error.message : 'Syntax error'}`,
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
// Package.json specific validations
|
|
319
|
-
const validatePackageJSON = (pkg: Record<string, unknown>, results: ValidationResult[]) => {
|
|
320
|
-
const requiredFields = ['name', 'version'];
|
|
321
|
-
|
|
322
|
-
requiredFields.forEach(field => {
|
|
323
|
-
if (!pkg[field]) {
|
|
324
|
-
results.push({
|
|
325
|
-
field: field,
|
|
326
|
-
status: 'error',
|
|
327
|
-
message: `Required field '${field}' is missing`,
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
// Validate name format
|
|
333
|
-
if (pkg.name && typeof pkg.name === 'string') {
|
|
334
|
-
if (
|
|
335
|
-
!/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(pkg.name)
|
|
336
|
-
) {
|
|
337
|
-
results.push({
|
|
338
|
-
field: 'name',
|
|
339
|
-
status: 'warning',
|
|
340
|
-
message: 'Package name may not follow npm naming conventions',
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Validate version format
|
|
346
|
-
if (pkg.version && typeof pkg.version === 'string') {
|
|
347
|
-
if (!/^\d+\.\d+\.\d+(-[a-z0-9.-]+)?$/.test(pkg.version)) {
|
|
348
|
-
results.push({
|
|
349
|
-
field: 'version',
|
|
350
|
-
status: 'warning',
|
|
351
|
-
message: 'Version format may not follow semver conventions',
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Validate scripts
|
|
357
|
-
if (pkg.scripts && typeof pkg.scripts === 'object') {
|
|
358
|
-
Object.entries(pkg.scripts).forEach(([scriptName, command]) => {
|
|
359
|
-
if (typeof command !== 'string') {
|
|
360
|
-
results.push({
|
|
361
|
-
field: `scripts.${scriptName}`,
|
|
362
|
-
status: 'error',
|
|
363
|
-
message: `Script '${scriptName}' must be a string`,
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// Validate dependencies
|
|
370
|
-
['dependencies', 'devDependencies', 'peerDependencies'].forEach(depType => {
|
|
371
|
-
if (pkg[depType] && typeof pkg[depType] === 'object') {
|
|
372
|
-
Object.entries(pkg[depType]).forEach(([depName, version]) => {
|
|
373
|
-
if (typeof version !== 'string') {
|
|
374
|
-
results.push({
|
|
375
|
-
field: `${depType}.${depName}`,
|
|
376
|
-
status: 'error',
|
|
377
|
-
message: `Dependency version for '${depName}' must be a string`,
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
// YAML Validation
|
|
386
|
-
const validateYAML = (
|
|
387
|
-
content: string,
|
|
388
|
-
filename: string,
|
|
389
|
-
results: ValidationResult[]
|
|
390
|
-
) => {
|
|
391
|
-
try {
|
|
392
|
-
const parsed = yaml.load(content);
|
|
393
|
-
|
|
394
|
-
results.push({
|
|
395
|
-
field: filename,
|
|
396
|
-
status: 'valid',
|
|
397
|
-
message: 'Valid YAML syntax',
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
// Check for tabs (YAML should use spaces)
|
|
401
|
-
if (content.includes('\t')) {
|
|
402
|
-
results.push({
|
|
403
|
-
field: filename,
|
|
404
|
-
status: 'warning',
|
|
405
|
-
message: 'YAML files should use spaces instead of tabs',
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// Check for common YAML issues
|
|
410
|
-
if (content.match(/^[ ]*\t+/m)) {
|
|
411
|
-
results.push({
|
|
412
|
-
field: filename,
|
|
413
|
-
status: 'error',
|
|
414
|
-
message: 'Mixed tabs and spaces in indentation',
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// Validate specific YAML file types
|
|
419
|
-
if (
|
|
420
|
-
filename.includes('docker-compose') ||
|
|
421
|
-
filename === 'compose.yaml' ||
|
|
422
|
-
filename === 'compose.yml'
|
|
423
|
-
) {
|
|
424
|
-
validateDockerCompose(parsed, results);
|
|
425
|
-
}
|
|
426
|
-
} catch (error) {
|
|
427
|
-
results.push({
|
|
428
|
-
field: filename,
|
|
429
|
-
status: 'error',
|
|
430
|
-
message: `Invalid YAML: ${error instanceof Error ? error.message : 'Syntax error'}`,
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
};
|
|
434
|
-
|
|
435
|
-
// Docker Compose specific validation
|
|
436
|
-
const validateDockerCompose = (compose: Record<string, unknown>, results: ValidationResult[]) => {
|
|
437
|
-
if (compose && typeof compose === 'object') {
|
|
438
|
-
if (!compose.version && !compose.services) {
|
|
439
|
-
results.push({
|
|
440
|
-
field: 'structure',
|
|
441
|
-
status: 'warning',
|
|
442
|
-
message:
|
|
443
|
-
'Docker Compose file may be missing version or services section',
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
const services = compose.services as Record<string, unknown> | undefined;
|
|
448
|
-
if (services && typeof services === 'object') {
|
|
449
|
-
Object.keys(services).forEach(serviceName => {
|
|
450
|
-
const service = services[serviceName];
|
|
451
|
-
if (service && typeof service === 'object') {
|
|
452
|
-
if (!service.image && !service.build) {
|
|
453
|
-
results.push({
|
|
454
|
-
field: `services.${serviceName}`,
|
|
455
|
-
status: 'warning',
|
|
456
|
-
message: `Service '${serviceName}' should have either 'image' or 'build' defined`,
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
// JavaScript/TypeScript Validation (basic syntax)
|
|
466
|
-
const validateJavaScript = (
|
|
467
|
-
content: string,
|
|
468
|
-
filename: string,
|
|
469
|
-
results: ValidationResult[]
|
|
470
|
-
) => {
|
|
471
|
-
try {
|
|
472
|
-
// Basic syntax check - in a real implementation, you might use a proper parser
|
|
473
|
-
if (content.trim() && !content.match(/console\.log/)) {
|
|
474
|
-
results.push({
|
|
475
|
-
field: filename,
|
|
476
|
-
status: 'valid',
|
|
477
|
-
message: 'JavaScript/TypeScript syntax appears valid',
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Check for common issues
|
|
482
|
-
const lines = content.split('\n');
|
|
483
|
-
lines.forEach((line, index) => {
|
|
484
|
-
// Check for == instead of ===
|
|
485
|
-
if (line.includes(' == ') && !line.includes(' === ')) {
|
|
486
|
-
results.push({
|
|
487
|
-
field: `Line ${index + 1}`,
|
|
488
|
-
status: 'warning',
|
|
489
|
-
message: 'Consider using === instead of == for strict equality',
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// Check for console.log in production configs
|
|
494
|
-
if (line.includes('console.log') && filename.includes('config')) {
|
|
495
|
-
results.push({
|
|
496
|
-
field: `Line ${index + 1}`,
|
|
497
|
-
status: 'warning',
|
|
498
|
-
message: 'console.log found in configuration file',
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
} catch (error) {
|
|
503
|
-
results.push({
|
|
504
|
-
field: filename,
|
|
505
|
-
status: 'error',
|
|
506
|
-
message: `JavaScript validation error: ${error instanceof Error ? error.message : 'Syntax error'}`,
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
// Environment file validation
|
|
512
|
-
const validateEnv = (
|
|
513
|
-
content: string,
|
|
514
|
-
filename: string,
|
|
515
|
-
results: ValidationResult[]
|
|
516
|
-
) => {
|
|
517
|
-
const lines = content
|
|
518
|
-
.split('\n')
|
|
519
|
-
.filter(line => line.trim() && !line.trim().startsWith('#'));
|
|
520
|
-
|
|
521
|
-
let isValid = true;
|
|
522
|
-
|
|
523
|
-
lines.forEach((line, index) => {
|
|
524
|
-
// Basic env format validation: KEY=VALUE
|
|
525
|
-
if (!line.includes('=')) {
|
|
526
|
-
results.push({
|
|
527
|
-
field: `Line ${index + 1}`,
|
|
528
|
-
status: 'error',
|
|
529
|
-
message: 'Invalid environment variable format (missing =)',
|
|
530
|
-
});
|
|
531
|
-
isValid = false;
|
|
532
|
-
} else {
|
|
533
|
-
const [key] = line.split('=');
|
|
534
|
-
if (!key || !key.trim()) {
|
|
535
|
-
results.push({
|
|
536
|
-
field: `Line ${index + 1}`,
|
|
537
|
-
status: 'error',
|
|
538
|
-
message: 'Environment variable key is empty',
|
|
539
|
-
});
|
|
540
|
-
isValid = false;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
if (isValid && lines.length > 0) {
|
|
546
|
-
results.push({
|
|
547
|
-
field: filename,
|
|
548
|
-
status: 'valid',
|
|
549
|
-
message: 'Valid environment file format',
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
// Generic file validation
|
|
555
|
-
const validateGeneric = (
|
|
556
|
-
content: string,
|
|
557
|
-
filename: string,
|
|
558
|
-
results: ValidationResult[]
|
|
559
|
-
) => {
|
|
560
|
-
// Basic file content checks
|
|
561
|
-
if (content.trim().length === 0) {
|
|
562
|
-
results.push({
|
|
563
|
-
field: filename,
|
|
564
|
-
status: 'warning',
|
|
565
|
-
message: 'File appears to be empty',
|
|
566
|
-
});
|
|
567
|
-
} else {
|
|
568
|
-
results.push({
|
|
569
|
-
field: filename,
|
|
570
|
-
status: 'valid',
|
|
571
|
-
message: 'File content appears valid',
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
};
|
|
575
|
-
|
|
576
|
-
// Common issues across all file types
|
|
577
|
-
const validateCommonIssues = (
|
|
578
|
-
content: string,
|
|
579
|
-
filename: string,
|
|
580
|
-
results: ValidationResult[]
|
|
581
|
-
) => {
|
|
582
|
-
// Security checks
|
|
583
|
-
if (containsSecrets(content) && !filename.includes('.env')) {
|
|
584
|
-
results.push({
|
|
585
|
-
field: filename,
|
|
586
|
-
status: 'warning',
|
|
587
|
-
message: 'File may contain sensitive information (secrets detected)',
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// TODO/FIXME comments
|
|
592
|
-
const todoMatches = content.match(/(TODO|FIXME|HACK|XXX):?\s*(.*)/gi);
|
|
593
|
-
if (todoMatches) {
|
|
594
|
-
results.push({
|
|
595
|
-
field: filename,
|
|
596
|
-
status: 'warning',
|
|
597
|
-
message: `File contains ${todoMatches.length} TODO/FIXME comment(s)`,
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
};
|
|
602
|
-
|
|
603
|
-
// JSON structure validation
|
|
604
|
-
const validateJSONStructure = (
|
|
605
|
-
obj: Record<string, unknown>,
|
|
606
|
-
filename: string,
|
|
607
|
-
results: ValidationResult[]
|
|
608
|
-
) => {
|
|
609
|
-
// Check for circular references (basic check)
|
|
610
|
-
try {
|
|
611
|
-
JSON.stringify(obj);
|
|
612
|
-
} catch (error) {
|
|
613
|
-
if (error instanceof Error && error.message.includes('circular')) {
|
|
614
|
-
results.push({
|
|
615
|
-
field: filename,
|
|
616
|
-
status: 'error',
|
|
617
|
-
message: 'JSON contains circular references',
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
// Check for duplicate keys (basic check)
|
|
623
|
-
const jsonString = JSON.stringify(obj);
|
|
624
|
-
const keyCounts: Record<string, number> = {};
|
|
625
|
-
|
|
626
|
-
const countKeys = (obj: Record<string, unknown>, path: string = ''): void => {
|
|
627
|
-
if (obj && typeof obj === 'object') {
|
|
628
|
-
Object.keys(obj).forEach(key => {
|
|
629
|
-
const fullPath = path ? `${path}.${key}` : key;
|
|
630
|
-
keyCounts[fullPath] = (keyCounts[fullPath] || 0) + 1;
|
|
631
|
-
const value = obj[key];
|
|
632
|
-
if (value && typeof value === 'object') {
|
|
633
|
-
countKeys(value as Record<string, unknown>, fullPath);
|
|
634
|
-
}
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
};
|
|
638
|
-
|
|
639
|
-
countKeys(obj);
|
|
640
|
-
|
|
641
|
-
Object.entries(keyCounts).forEach(([key, count]) => {
|
|
642
|
-
if (count > 1) {
|
|
643
|
-
results.push({
|
|
644
|
-
field: key,
|
|
645
|
-
status: 'warning',
|
|
646
|
-
message: `Key appears multiple times in structure`,
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
// Pretty print JSON
|
|
653
|
-
export const formatJson = (content: string): string => {
|
|
654
|
-
try {
|
|
655
|
-
const parsed = JSON.parse(content);
|
|
656
|
-
return JSON.stringify(parsed, null, 2);
|
|
657
|
-
} catch {
|
|
658
|
-
return content;
|
|
659
|
-
}
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
// Get config file icon
|
|
663
|
-
export const getConfigIcon = (filename: string): string => {
|
|
664
|
-
const language = detectLanguage(filename);
|
|
665
|
-
switch (language) {
|
|
666
|
-
case 'json':
|
|
667
|
-
return <DocumentIcon className="w-6 h-6 text-primary-600" />;
|
|
668
|
-
case 'yaml':
|
|
669
|
-
return <DocumentIcon className="w-6 h-6 text-primary-600" />;
|
|
670
|
-
case 'javascript':
|
|
671
|
-
case 'typescript':
|
|
672
|
-
return <Cog6ToothIcon className="w-6 h-6 text-primary-600" />;
|
|
673
|
-
case 'env':
|
|
674
|
-
return '🔐';
|
|
675
|
-
case 'markdown':
|
|
676
|
-
return '📝';
|
|
677
|
-
default:
|
|
678
|
-
return <FolderIcon className="w-6 h-6 text-primary-600" />;
|
|
679
|
-
}
|
|
680
|
-
};
|
|
681
|
-
|
|
682
|
-
// Sort configurations
|
|
683
|
-
export const sortConfigs = (
|
|
684
|
-
configs: ConfigFile[],
|
|
685
|
-
sortBy: 'name' | 'type' | 'size' | 'modified'
|
|
686
|
-
): ConfigFile[] => {
|
|
687
|
-
return [...configs].sort((a, b) => {
|
|
688
|
-
switch (sortBy) {
|
|
689
|
-
case 'name':
|
|
690
|
-
return a.name.localeCompare(b.name);
|
|
691
|
-
case 'type':
|
|
692
|
-
return a.type.localeCompare(b.type);
|
|
693
|
-
case 'size':
|
|
694
|
-
return b.size - a.size;
|
|
695
|
-
case 'modified':
|
|
696
|
-
return (
|
|
697
|
-
new Date(b.lastModified).getTime() -
|
|
698
|
-
new Date(a.lastModified).getTime()
|
|
699
|
-
);
|
|
700
|
-
default:
|
|
701
|
-
return 0;
|
|
702
|
-
}
|
|
703
|
-
});
|
|
704
|
-
};
|