ucn 3.0.0

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.

Potentially problematic release.


This version of ucn might be problematic. Click here for more details.

Files changed (45) hide show
  1. package/.claude/skills/ucn/SKILL.md +77 -0
  2. package/LICENSE +21 -0
  3. package/README.md +135 -0
  4. package/cli/index.js +2437 -0
  5. package/core/discovery.js +513 -0
  6. package/core/imports.js +558 -0
  7. package/core/output.js +1274 -0
  8. package/core/parser.js +279 -0
  9. package/core/project.js +3261 -0
  10. package/index.js +52 -0
  11. package/languages/go.js +653 -0
  12. package/languages/index.js +267 -0
  13. package/languages/java.js +826 -0
  14. package/languages/javascript.js +1346 -0
  15. package/languages/python.js +667 -0
  16. package/languages/rust.js +950 -0
  17. package/languages/utils.js +457 -0
  18. package/package.json +42 -0
  19. package/test/fixtures/go/go.mod +3 -0
  20. package/test/fixtures/go/main.go +257 -0
  21. package/test/fixtures/go/service.go +187 -0
  22. package/test/fixtures/java/DataService.java +279 -0
  23. package/test/fixtures/java/Main.java +287 -0
  24. package/test/fixtures/java/Utils.java +199 -0
  25. package/test/fixtures/java/pom.xml +6 -0
  26. package/test/fixtures/javascript/main.js +109 -0
  27. package/test/fixtures/javascript/package.json +1 -0
  28. package/test/fixtures/javascript/service.js +88 -0
  29. package/test/fixtures/javascript/utils.js +67 -0
  30. package/test/fixtures/python/main.py +198 -0
  31. package/test/fixtures/python/pyproject.toml +3 -0
  32. package/test/fixtures/python/service.py +166 -0
  33. package/test/fixtures/python/utils.py +118 -0
  34. package/test/fixtures/rust/Cargo.toml +3 -0
  35. package/test/fixtures/rust/main.rs +253 -0
  36. package/test/fixtures/rust/service.rs +210 -0
  37. package/test/fixtures/rust/utils.rs +154 -0
  38. package/test/fixtures/typescript/main.ts +154 -0
  39. package/test/fixtures/typescript/package.json +1 -0
  40. package/test/fixtures/typescript/repository.ts +149 -0
  41. package/test/fixtures/typescript/types.ts +114 -0
  42. package/test/parser.test.js +3661 -0
  43. package/test/public-repos-test.js +477 -0
  44. package/test/systematic-test.js +619 -0
  45. package/ucn.js +8 -0
@@ -0,0 +1,253 @@
1
+ //! Main Rust test fixtures.
2
+ //! Tests structs, traits, enums, and async functions.
3
+
4
+ mod service;
5
+ mod utils;
6
+
7
+ use std::collections::HashMap;
8
+ use std::sync::{Arc, Mutex};
9
+
10
+ /// Status enum representing task states.
11
+ #[derive(Debug, Clone, PartialEq)]
12
+ pub enum Status {
13
+ Pending,
14
+ Active,
15
+ Completed,
16
+ Failed,
17
+ }
18
+
19
+ /// Task struct representing a task entity.
20
+ #[derive(Debug, Clone)]
21
+ pub struct Task {
22
+ pub id: String,
23
+ pub name: String,
24
+ pub status: Status,
25
+ pub priority: i32,
26
+ pub metadata: HashMap<String, String>,
27
+ }
28
+
29
+ impl Task {
30
+ /// Create a new task.
31
+ pub fn new(id: String, name: String) -> Self {
32
+ Task {
33
+ id,
34
+ name,
35
+ status: Status::Pending,
36
+ priority: 1,
37
+ metadata: HashMap::new(),
38
+ }
39
+ }
40
+
41
+ /// Set the task priority.
42
+ pub fn with_priority(mut self, priority: i32) -> Self {
43
+ self.priority = priority;
44
+ self
45
+ }
46
+
47
+ /// Set the task status.
48
+ pub fn with_status(mut self, status: Status) -> Self {
49
+ self.status = status;
50
+ self
51
+ }
52
+
53
+ /// Check if the task is complete.
54
+ pub fn is_complete(&self) -> bool {
55
+ self.status == Status::Completed
56
+ }
57
+ }
58
+
59
+ /// Trait for entities with an ID.
60
+ pub trait Entity {
61
+ fn get_id(&self) -> &str;
62
+ }
63
+
64
+ impl Entity for Task {
65
+ fn get_id(&self) -> &str {
66
+ &self.id
67
+ }
68
+ }
69
+
70
+ /// Task manager that manages a collection of tasks.
71
+ pub struct TaskManager {
72
+ tasks: Arc<Mutex<Vec<Task>>>,
73
+ }
74
+
75
+ impl TaskManager {
76
+ /// Create a new task manager.
77
+ pub fn new() -> Self {
78
+ TaskManager {
79
+ tasks: Arc::new(Mutex::new(Vec::new())),
80
+ }
81
+ }
82
+
83
+ /// Add a task to the manager.
84
+ pub fn add_task(&self, task: Task) -> Result<(), String> {
85
+ validate_task(&task)?;
86
+ let mut tasks = self.tasks.lock().unwrap();
87
+ tasks.push(task);
88
+ Ok(())
89
+ }
90
+
91
+ /// Get a task by ID.
92
+ pub fn get_task(&self, id: &str) -> Option<Task> {
93
+ let tasks = self.tasks.lock().unwrap();
94
+ tasks.iter().find(|t| t.id == id).cloned()
95
+ }
96
+
97
+ /// Get all tasks, optionally filtered.
98
+ pub fn get_tasks<F>(&self, filter: Option<F>) -> Vec<Task>
99
+ where
100
+ F: Fn(&Task) -> bool,
101
+ {
102
+ let tasks = self.tasks.lock().unwrap();
103
+ match filter {
104
+ Some(f) => tasks.iter().filter(|t| f(t)).cloned().collect(),
105
+ None => tasks.clone(),
106
+ }
107
+ }
108
+
109
+ /// Update a task by ID.
110
+ pub fn update_task(&self, id: &str, name: Option<String>, status: Option<Status>) -> Option<Task> {
111
+ let mut tasks = self.tasks.lock().unwrap();
112
+ for task in tasks.iter_mut() {
113
+ if task.id == id {
114
+ if let Some(n) = name {
115
+ task.name = n;
116
+ }
117
+ if let Some(s) = status {
118
+ task.status = s;
119
+ }
120
+ return Some(task.clone());
121
+ }
122
+ }
123
+ None
124
+ }
125
+
126
+ /// Delete a task by ID.
127
+ pub fn delete_task(&self, id: &str) -> bool {
128
+ let mut tasks = self.tasks.lock().unwrap();
129
+ let len_before = tasks.len();
130
+ tasks.retain(|t| t.id != id);
131
+ tasks.len() < len_before
132
+ }
133
+
134
+ /// Get the count of tasks.
135
+ pub fn count(&self) -> usize {
136
+ let tasks = self.tasks.lock().unwrap();
137
+ tasks.len()
138
+ }
139
+ }
140
+
141
+ impl Default for TaskManager {
142
+ fn default() -> Self {
143
+ Self::new()
144
+ }
145
+ }
146
+
147
+ /// Validate a task.
148
+ pub fn validate_task(task: &Task) -> Result<(), String> {
149
+ if task.id.is_empty() {
150
+ return Err("Task ID is required".to_string());
151
+ }
152
+ if task.name.is_empty() {
153
+ return Err("Task name is required".to_string());
154
+ }
155
+ Ok(())
156
+ }
157
+
158
+ /// Create a new task with a generated ID.
159
+ pub fn create_task(name: &str, priority: i32) -> Task {
160
+ let id = generate_id();
161
+ Task::new(id, name.to_string()).with_priority(priority)
162
+ }
163
+
164
+ /// Generate a unique ID.
165
+ fn generate_id() -> String {
166
+ use std::sync::atomic::{AtomicUsize, Ordering};
167
+ static COUNTER: AtomicUsize = AtomicUsize::new(0);
168
+ let id = COUNTER.fetch_add(1, Ordering::SeqCst);
169
+ format!("task-{}", id)
170
+ }
171
+
172
+ /// Filter tasks by status.
173
+ pub fn filter_by_status(tasks: &[Task], status: Status) -> Vec<Task> {
174
+ tasks.iter().filter(|t| t.status == status).cloned().collect()
175
+ }
176
+
177
+ /// Filter tasks by minimum priority.
178
+ pub fn filter_by_priority(tasks: &[Task], min_priority: i32) -> Vec<Task> {
179
+ tasks.iter().filter(|t| t.priority >= min_priority).cloned().collect()
180
+ }
181
+
182
+ /// Task processor for processing tasks.
183
+ pub struct TaskProcessor {
184
+ manager: Arc<TaskManager>,
185
+ }
186
+
187
+ impl TaskProcessor {
188
+ /// Create a new task processor.
189
+ pub fn new(manager: Arc<TaskManager>) -> Self {
190
+ TaskProcessor { manager }
191
+ }
192
+
193
+ /// Process all tasks.
194
+ pub fn process_all(&self) -> Vec<HashMap<String, String>> {
195
+ let tasks = self.manager.get_tasks::<fn(&Task) -> bool>(None);
196
+ tasks.iter().map(|t| self.process_task(t)).collect()
197
+ }
198
+
199
+ /// Process only pending tasks.
200
+ pub fn process_pending(&self) -> Vec<HashMap<String, String>> {
201
+ let tasks = self.manager.get_tasks(Some(|t: &Task| t.status == Status::Pending));
202
+ tasks.iter().map(|t| self.process_task(t)).collect()
203
+ }
204
+
205
+ /// Process a single task.
206
+ fn process_task(&self, task: &Task) -> HashMap<String, String> {
207
+ format_task(task)
208
+ }
209
+ }
210
+
211
+ /// Format a task as a map.
212
+ pub fn format_task(task: &Task) -> HashMap<String, String> {
213
+ let mut map = HashMap::new();
214
+ map.insert("id".to_string(), task.id.clone());
215
+ map.insert("name".to_string(), task.name.clone());
216
+ map.insert("status".to_string(), format!("{:?}", task.status));
217
+ map.insert("priority".to_string(), task.priority.to_string());
218
+ map
219
+ }
220
+
221
+ /// Unused function for deadcode detection.
222
+ #[allow(dead_code)]
223
+ fn unused_function() -> &'static str {
224
+ "never used"
225
+ }
226
+
227
+ fn main() {
228
+ let manager = TaskManager::new();
229
+ let task = create_task("Test Task", 1);
230
+ manager.add_task(task).unwrap();
231
+ println!("Created {} tasks", manager.count());
232
+ }
233
+
234
+ #[cfg(test)]
235
+ mod tests {
236
+ use super::*;
237
+
238
+ #[test]
239
+ fn test_create_task() {
240
+ let task = create_task("Test", 1);
241
+ assert!(!task.id.is_empty());
242
+ assert_eq!(task.name, "Test");
243
+ assert_eq!(task.priority, 1);
244
+ }
245
+
246
+ #[test]
247
+ fn test_task_manager() {
248
+ let manager = TaskManager::new();
249
+ let task = create_task("Test", 1);
250
+ manager.add_task(task).unwrap();
251
+ assert_eq!(manager.count(), 1);
252
+ }
253
+ }
@@ -0,0 +1,210 @@
1
+ //! Service module for data operations.
2
+
3
+ use std::collections::HashMap;
4
+ use std::sync::{Arc, Mutex};
5
+ use std::time::{Duration, Instant};
6
+
7
+ /// Configuration for services.
8
+ #[derive(Debug, Clone)]
9
+ pub struct Config {
10
+ pub api_url: String,
11
+ pub timeout: Duration,
12
+ pub retries: u32,
13
+ pub debug: bool,
14
+ }
15
+
16
+ impl Default for Config {
17
+ fn default() -> Self {
18
+ Config {
19
+ api_url: "https://api.example.com".to_string(),
20
+ timeout: Duration::from_secs(5),
21
+ retries: 3,
22
+ debug: false,
23
+ }
24
+ }
25
+ }
26
+
27
+ /// Repository trait for data access.
28
+ pub trait Repository<T> {
29
+ fn save(&self, entity: T) -> Result<(), String>;
30
+ fn find(&self, id: &str) -> Option<T>;
31
+ fn find_all(&self) -> Vec<T>;
32
+ fn delete(&self, id: &str) -> bool;
33
+ }
34
+
35
+ /// Generic data service.
36
+ pub struct DataService<T: Clone> {
37
+ config: Config,
38
+ storage: Arc<Mutex<HashMap<String, T>>>,
39
+ }
40
+
41
+ impl<T: Clone> DataService<T> {
42
+ /// Create a new data service.
43
+ pub fn new(config: Config) -> Self {
44
+ DataService {
45
+ config,
46
+ storage: Arc::new(Mutex::new(HashMap::new())),
47
+ }
48
+ }
49
+
50
+ /// Create with default config.
51
+ pub fn with_defaults() -> Self {
52
+ Self::new(Config::default())
53
+ }
54
+
55
+ /// Get the config.
56
+ pub fn config(&self) -> &Config {
57
+ &self.config
58
+ }
59
+
60
+ /// Clear all stored entities.
61
+ pub fn clear(&self) {
62
+ let mut storage = self.storage.lock().unwrap();
63
+ storage.clear();
64
+ }
65
+ }
66
+
67
+ /// Cache entry with timestamp.
68
+ struct CacheEntry<T> {
69
+ value: T,
70
+ timestamp: Instant,
71
+ }
72
+
73
+ /// Caching service with TTL.
74
+ pub struct CacheService<T: Clone> {
75
+ ttl: Duration,
76
+ cache: Arc<Mutex<HashMap<String, CacheEntry<T>>>>,
77
+ }
78
+
79
+ impl<T: Clone> CacheService<T> {
80
+ /// Create a new cache service.
81
+ pub fn new(ttl: Duration) -> Self {
82
+ CacheService {
83
+ ttl,
84
+ cache: Arc::new(Mutex::new(HashMap::new())),
85
+ }
86
+ }
87
+
88
+ /// Get a value from cache.
89
+ pub fn get(&self, key: &str) -> Option<T> {
90
+ let cache = self.cache.lock().unwrap();
91
+ if let Some(entry) = cache.get(key) {
92
+ if entry.timestamp.elapsed() < self.ttl {
93
+ return Some(entry.value.clone());
94
+ }
95
+ }
96
+ None
97
+ }
98
+
99
+ /// Set a value in cache.
100
+ pub fn set(&self, key: String, value: T) {
101
+ let mut cache = self.cache.lock().unwrap();
102
+ cache.insert(key, CacheEntry {
103
+ value,
104
+ timestamp: Instant::now(),
105
+ });
106
+ }
107
+
108
+ /// Delete a value from cache.
109
+ pub fn delete(&self, key: &str) -> bool {
110
+ let mut cache = self.cache.lock().unwrap();
111
+ cache.remove(key).is_some()
112
+ }
113
+
114
+ /// Clear all values from cache.
115
+ pub fn clear(&self) {
116
+ let mut cache = self.cache.lock().unwrap();
117
+ cache.clear();
118
+ }
119
+
120
+ /// Remove expired entries.
121
+ pub fn cleanup_expired(&self) -> usize {
122
+ let mut cache = self.cache.lock().unwrap();
123
+ let expired: Vec<String> = cache
124
+ .iter()
125
+ .filter(|(_, entry)| entry.timestamp.elapsed() >= self.ttl)
126
+ .map(|(key, _)| key.clone())
127
+ .collect();
128
+ let count = expired.len();
129
+ for key in expired {
130
+ cache.remove(&key);
131
+ }
132
+ count
133
+ }
134
+ }
135
+
136
+ /// HTTP client for API requests.
137
+ pub struct ApiClient {
138
+ config: Config,
139
+ }
140
+
141
+ impl ApiClient {
142
+ /// Create a new API client.
143
+ pub fn new(config: Config) -> Self {
144
+ ApiClient { config }
145
+ }
146
+
147
+ /// Make a GET request.
148
+ pub async fn get(&self, path: &str) -> Result<HashMap<String, String>, String> {
149
+ let url = self.build_url(path);
150
+ self.request("GET", &url, None).await
151
+ }
152
+
153
+ /// Make a POST request.
154
+ pub async fn post(&self, path: &str, data: HashMap<String, String>) -> Result<HashMap<String, String>, String> {
155
+ let url = self.build_url(path);
156
+ self.request("POST", &url, Some(data)).await
157
+ }
158
+
159
+ /// Make a DELETE request.
160
+ pub async fn delete(&self, path: &str) -> Result<HashMap<String, String>, String> {
161
+ let url = self.build_url(path);
162
+ self.request("DELETE", &url, None).await
163
+ }
164
+
165
+ /// Build the full URL.
166
+ fn build_url(&self, path: &str) -> String {
167
+ if path.starts_with("http") {
168
+ path.to_string()
169
+ } else {
170
+ format!("{}{}", self.config.api_url, path)
171
+ }
172
+ }
173
+
174
+ /// Make an HTTP request.
175
+ async fn request(
176
+ &self,
177
+ method: &str,
178
+ url: &str,
179
+ _data: Option<HashMap<String, String>>,
180
+ ) -> Result<HashMap<String, String>, String> {
181
+ // Simulated request
182
+ let mut result = HashMap::new();
183
+ result.insert("status".to_string(), "200".to_string());
184
+ result.insert("method".to_string(), method.to_string());
185
+ result.insert("url".to_string(), url.to_string());
186
+ Ok(result)
187
+ }
188
+ }
189
+
190
+ /// Create a data service with defaults.
191
+ pub fn create_service<T: Clone>() -> DataService<T> {
192
+ DataService::with_defaults()
193
+ }
194
+
195
+ /// Create an API client with defaults.
196
+ pub fn create_api_client() -> ApiClient {
197
+ ApiClient::new(Config::default())
198
+ }
199
+
200
+ #[cfg(test)]
201
+ mod tests {
202
+ use super::*;
203
+
204
+ #[test]
205
+ fn test_cache_service() {
206
+ let cache: CacheService<String> = CacheService::new(Duration::from_secs(60));
207
+ cache.set("key".to_string(), "value".to_string());
208
+ assert_eq!(cache.get("key"), Some("value".to_string()));
209
+ }
210
+ }
@@ -0,0 +1,154 @@
1
+ //! Utility functions for data manipulation.
2
+
3
+ use std::collections::HashMap;
4
+
5
+ /// Format data as a string.
6
+ pub fn format_data<T: std::fmt::Debug>(data: &T) -> String {
7
+ format!("{:?}", data)
8
+ }
9
+
10
+ /// Validate that a value is not empty.
11
+ pub fn validate_not_empty(value: &str) -> Result<(), String> {
12
+ if value.is_empty() {
13
+ Err("Value cannot be empty".to_string())
14
+ } else {
15
+ Ok(())
16
+ }
17
+ }
18
+
19
+ /// Deep merge two HashMaps.
20
+ pub fn deep_merge(
21
+ base: HashMap<String, String>,
22
+ updates: HashMap<String, String>,
23
+ ) -> HashMap<String, String> {
24
+ let mut result = base;
25
+ for (key, value) in updates {
26
+ result.insert(key, value);
27
+ }
28
+ result
29
+ }
30
+
31
+ /// Flatten a nested vector.
32
+ pub fn flatten<T: Clone>(nested: Vec<Vec<T>>) -> Vec<T> {
33
+ nested.into_iter().flatten().collect()
34
+ }
35
+
36
+ /// Split a vector into chunks.
37
+ pub fn chunk<T: Clone>(items: Vec<T>, size: usize) -> Vec<Vec<T>> {
38
+ items.chunks(size).map(|c| c.to_vec()).collect()
39
+ }
40
+
41
+ /// Safely get a value from a HashMap.
42
+ pub fn safe_get<'a>(map: &'a HashMap<String, String>, key: &str) -> Option<&'a String> {
43
+ map.get(key)
44
+ }
45
+
46
+ /// Transform all keys in a HashMap.
47
+ pub fn transform_keys<F>(map: HashMap<String, String>, transformer: F) -> HashMap<String, String>
48
+ where
49
+ F: Fn(&str) -> String,
50
+ {
51
+ map.into_iter().map(|(k, v)| (transformer(&k), v)).collect()
52
+ }
53
+
54
+ /// Convert snake_case to camelCase.
55
+ pub fn snake_to_camel(name: &str) -> String {
56
+ let mut result = String::new();
57
+ let mut capitalize_next = false;
58
+
59
+ for ch in name.chars() {
60
+ if ch == '_' {
61
+ capitalize_next = true;
62
+ } else if capitalize_next {
63
+ result.push(ch.to_ascii_uppercase());
64
+ capitalize_next = false;
65
+ } else {
66
+ result.push(ch);
67
+ }
68
+ }
69
+
70
+ result
71
+ }
72
+
73
+ /// Convert camelCase to snake_case.
74
+ pub fn camel_to_snake(name: &str) -> String {
75
+ let mut result = String::new();
76
+
77
+ for ch in name.chars() {
78
+ if ch.is_uppercase() {
79
+ if !result.is_empty() {
80
+ result.push('_');
81
+ }
82
+ result.push(ch.to_ascii_lowercase());
83
+ } else {
84
+ result.push(ch);
85
+ }
86
+ }
87
+
88
+ result
89
+ }
90
+
91
+ /// Data transformer struct.
92
+ pub struct DataTransformer {
93
+ transformations: Vec<Box<dyn Fn(String) -> String>>,
94
+ }
95
+
96
+ impl DataTransformer {
97
+ /// Create a new data transformer.
98
+ pub fn new() -> Self {
99
+ DataTransformer {
100
+ transformations: Vec::new(),
101
+ }
102
+ }
103
+
104
+ /// Add a transformation.
105
+ pub fn add_transformation<F>(&mut self, f: F) -> &mut Self
106
+ where
107
+ F: Fn(String) -> String + 'static,
108
+ {
109
+ self.transformations.push(Box::new(f));
110
+ self
111
+ }
112
+
113
+ /// Apply all transformations.
114
+ pub fn transform(&self, data: String) -> String {
115
+ let mut result = data;
116
+ for f in &self.transformations {
117
+ result = f(result);
118
+ }
119
+ result
120
+ }
121
+
122
+ /// Clear all transformations.
123
+ pub fn clear(&mut self) {
124
+ self.transformations.clear();
125
+ }
126
+ }
127
+
128
+ impl Default for DataTransformer {
129
+ fn default() -> Self {
130
+ Self::new()
131
+ }
132
+ }
133
+
134
+ /// Process and format data.
135
+ pub fn process_and_format<T: std::fmt::Debug>(data: &T) -> String {
136
+ format_data(data)
137
+ }
138
+
139
+ #[cfg(test)]
140
+ mod tests {
141
+ use super::*;
142
+
143
+ #[test]
144
+ fn test_snake_to_camel() {
145
+ assert_eq!(snake_to_camel("hello_world"), "helloWorld");
146
+ assert_eq!(snake_to_camel("some_long_name"), "someLongName");
147
+ }
148
+
149
+ #[test]
150
+ fn test_camel_to_snake() {
151
+ assert_eq!(camel_to_snake("helloWorld"), "hello_world");
152
+ assert_eq!(camel_to_snake("someLongName"), "some_long_name");
153
+ }
154
+ }