@skyhook-io/k8s-ui 1.1.0 → 1.1.1

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.
@@ -6,14 +6,65 @@ import type { SelectedResource, ResourceRef } from '../types/core'
6
6
  */
7
7
  export type NavigateToResource = (resource: SelectedResource) => void
8
8
 
9
+ // Known plural API resource names → singular PascalCase kind.
10
+ // Shared between kindToPlural (idempotency guard) and pluralToKind (reverse lookup).
11
+ const PLURAL_TO_KIND: Record<string, string> = {
12
+ pods: 'Pod',
13
+ services: 'Service',
14
+ deployments: 'Deployment',
15
+ daemonsets: 'DaemonSet',
16
+ statefulsets: 'StatefulSet',
17
+ replicasets: 'ReplicaSet',
18
+ ingresses: 'Ingress',
19
+ gateways: 'Gateway',
20
+ httproutes: 'HTTPRoute',
21
+ grpcroutes: 'GRPCRoute',
22
+ tcproutes: 'TCPRoute',
23
+ tlsroutes: 'TLSRoute',
24
+ configmaps: 'ConfigMap',
25
+ secrets: 'Secret',
26
+ namespaces: 'Namespace',
27
+ events: 'Event',
28
+ nodes: 'Node',
29
+ jobs: 'Job',
30
+ cronjobs: 'CronJob',
31
+ horizontalpodautoscalers: 'HorizontalPodAutoscaler',
32
+ persistentvolumeclaims: 'PersistentVolumeClaim',
33
+ persistentvolumes: 'PersistentVolume',
34
+ storageclasses: 'StorageClass',
35
+ poddisruptionbudgets: 'PodDisruptionBudget',
36
+ rollouts: 'Rollout',
37
+ applications: 'Application',
38
+ kustomizations: 'Kustomization',
39
+ helmreleases: 'HelmRelease',
40
+ gitrepositories: 'GitRepository',
41
+ certificates: 'Certificate',
42
+ roles: 'Role',
43
+ clusterroles: 'ClusterRole',
44
+ rolebindings: 'RoleBinding',
45
+ clusterrolebindings: 'ClusterRoleBinding',
46
+ serviceaccounts: 'ServiceAccount',
47
+ networkpolicies: 'NetworkPolicy',
48
+ verticalpodautoscalers: 'VerticalPodAutoscaler',
49
+ virtualservices: 'VirtualService',
50
+ destinationrules: 'DestinationRule',
51
+ serviceentries: 'ServiceEntry',
52
+ peerauthentications: 'PeerAuthentication',
53
+ authorizationpolicies: 'AuthorizationPolicy',
54
+ }
55
+
9
56
  /**
10
57
  * Convert a singular kind (e.g., "Deployment") to plural API resource name (e.g., "deployments").
11
58
  * Single source of truth — uses English pluralization rules with a small alias map for
12
59
  * abbreviations and special mappings that aren't simple plurals.
60
+ * Idempotent: already-plural inputs (e.g., "secrets") are returned as-is.
13
61
  */
14
62
  export function kindToPlural(kind: string): string {
15
63
  const kindLower = kind.toLowerCase()
16
64
 
65
+ // Already a known plural — return as-is to prevent double-pluralization
66
+ if (kindLower in PLURAL_TO_KIND) return kindLower
67
+
17
68
  // Aliases: abbreviations or mappings to a different resource name
18
69
  const aliases: Record<string, string> = {
19
70
  horizontalpodautoscaler: 'horizontalpodautoscalers',
@@ -40,53 +91,7 @@ export function kindToPlural(kind: string): string {
40
91
  export function pluralToKind(plural: string): string {
41
92
  const lower = plural.toLowerCase()
42
93
 
43
- // Explicit reverse mappings for irregular/aliased plurals
44
- const reverseMap: Record<string, string> = {
45
- pods: 'Pod',
46
- services: 'Service',
47
- deployments: 'Deployment',
48
- daemonsets: 'DaemonSet',
49
- statefulsets: 'StatefulSet',
50
- replicasets: 'ReplicaSet',
51
- ingresses: 'Ingress',
52
- gateways: 'Gateway',
53
- httproutes: 'HTTPRoute',
54
- grpcroutes: 'GRPCRoute',
55
- tcproutes: 'TCPRoute',
56
- tlsroutes: 'TLSRoute',
57
- configmaps: 'ConfigMap',
58
- secrets: 'Secret',
59
- namespaces: 'Namespace',
60
- events: 'Event',
61
- nodes: 'Node',
62
- jobs: 'Job',
63
- cronjobs: 'CronJob',
64
- horizontalpodautoscalers: 'HorizontalPodAutoscaler',
65
- persistentvolumeclaims: 'PersistentVolumeClaim',
66
- persistentvolumes: 'PersistentVolume',
67
- storageclasses: 'StorageClass',
68
- poddisruptionbudgets: 'PodDisruptionBudget',
69
- rollouts: 'Rollout',
70
- applications: 'Application',
71
- kustomizations: 'Kustomization',
72
- helmreleases: 'HelmRelease',
73
- gitrepositories: 'GitRepository',
74
- certificates: 'Certificate',
75
- roles: 'Role',
76
- clusterroles: 'ClusterRole',
77
- rolebindings: 'RoleBinding',
78
- clusterrolebindings: 'ClusterRoleBinding',
79
- serviceaccounts: 'ServiceAccount',
80
- networkpolicies: 'NetworkPolicy',
81
- verticalpodautoscalers: 'VerticalPodAutoscaler',
82
- virtualservices: 'VirtualService',
83
- destinationrules: 'DestinationRule',
84
- serviceentries: 'ServiceEntry',
85
- peerauthentications: 'PeerAuthentication',
86
- authorizationpolicies: 'AuthorizationPolicy',
87
- }
88
-
89
- if (reverseMap[lower]) return reverseMap[lower]
94
+ if (PLURAL_TO_KIND[lower]) return PLURAL_TO_KIND[lower]
90
95
 
91
96
  // If it already looks like a singular PascalCase kind (starts with uppercase), return as-is
92
97
  if (plural[0] === plural[0].toUpperCase() && plural[0] !== plural[0].toLowerCase()) {