Skip to content
This repository was archived by the owner on Mar 8, 2026. It is now read-only.

Migrate Orchestration Utils#2

Merged
JustAGhosT merged 1 commit intomasterfrom
tembo/migrate-orchestration-utils-repos
Dec 23, 2025
Merged

Migrate Orchestration Utils#2
JustAGhosT merged 1 commit intomasterfrom
tembo/migrate-orchestration-utils-repos

Conversation

@JustAGhosT
Copy link
Copy Markdown
Owner

@JustAGhosT JustAGhosT commented Dec 23, 2025

Summary

Migrated utility functions from orchestration to respective repositories:

  • Added new utility modules in packages/utils:

    • formatting: Date, number, and string formatting utilities
    • validation: URL, email, and input validation utilities
    • common: Retry, rate limiting, and error handling utilities
  • Updated package.json to include new export paths for:

    • ./validation
    • ./formatting
  • Synchronized Python utility package with new TypeScript utilities

    • Added corresponding modules in codeflow-utils-python
    • Updated package keywords and exports

Related Pull Requests


Want me to make any changes? Add a review or comment with @tembo and i'll get back to work!

tembo.io app.tembo.io

Summary by CodeRabbit

  • New Features
    • Introduced URL validation utilities with customizable scheme support and detailed error reporting
    • Added comprehensive formatting utilities for dates, times, numbers (including byte conversion and percentages), and strings (truncation, slug generation, case conversion, and case transformations)

✏️ Tip: You can customize this high-level summary in your review settings.

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 23, 2025

Walkthrough

This PR adds two new utility module namespaces to packages/utils: "formatting" and "validation". The formatting module provides utilities for date, number, and string formatting. The validation module offers URL validation functionality. Package exports and main index re-exports are updated accordingly.

Changes

Cohort / File(s) Summary
Package Configuration
packages/utils/package.json
Added "validation" and "formatting" to exports field with corresponding import and types entry points; updated keywords to include these new categories.
Formatting Module
packages/utils/src/formatting/date.ts, packages/utils/src/formatting/number.ts, packages/utils/src/formatting/string.ts, packages/utils/src/formatting/index.ts
Introduced three formatting utility files: date utilities (formatDateTime, formatRelativeTime), number utilities (formatNumber, formatBytes, formatPercentage), and string utilities (truncateString, slugify, camelToSnake, snakeToCamel). Index file re-exports all three modules.
Validation Module
packages/utils/src/validation/url.ts, packages/utils/src/validation/index.ts
Added URL validation utilities with UrlValidationResult interface, validateUrl function with optional scheme filtering, and isValidUrl convenience function. Index file re-exports url module.
Main Package Exports
packages/utils/src/index.ts
Added re-exports for validation and formatting modules to expose new utilities at package level.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hops through validation gates,
Formats dates and numbers with careful traits,
Slugifying strings, converting case with care,
Byte counts and percentages everywhere,
Utilities bundled, exports declare,
New utilities hop into the toolkit's lair! 🐰✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Migrate Orchestration Utils' is vague and generic, using a non-descriptive term that doesn't clearly convey what specific utilities are being migrated or the main change being introduced. Consider a more specific title such as 'Add formatting and validation utilities to packages/utils' to better reflect the primary changes (new formatting and validation modules with date, number, string, and URL utilities).
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch tembo/migrate-orchestration-utils-repos

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/utils/src/formatting/string.ts (1)

73-85: Consider handling consecutive underscores.

The function splits on "_" but doesn't handle consecutive underscores, which would create empty components. For example, "foo__bar" would result in an empty string in the components array, potentially causing unexpected output.

🔎 Suggested enhancement
 export function snakeToCamel(
   value: string,
   capitalizeFirst: boolean = false
 ): string {
-  const components = value.split("_");
+  const components = value.split("_").filter(c => c.length > 0);
+  if (components.length === 0) {
+    return "";
+  }
   const first = capitalizeFirst
     ? components[0].charAt(0).toUpperCase() + components[0].slice(1)
     : components[0];
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 572adab and 21f6277.

📒 Files selected for processing (8)
  • packages/utils/package.json
  • packages/utils/src/formatting/date.ts
  • packages/utils/src/formatting/index.ts
  • packages/utils/src/formatting/number.ts
  • packages/utils/src/formatting/string.ts
  • packages/utils/src/index.ts
  • packages/utils/src/validation/index.ts
  • packages/utils/src/validation/url.ts
🧰 Additional context used
🪛 ast-grep (0.40.3)
packages/utils/src/formatting/string.ts

[warning] 48-48: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${separator}+, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 49-49: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${separator}|${separator}$, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🔇 Additional comments (13)
packages/utils/package.json (2)

17-25: LGTM! Clean export structure.

The new exports for validation and formatting follow the existing pattern and integrate well with the package structure. The export paths correctly point to the compiled JavaScript and TypeScript declaration files.


58-60: LGTM! Keywords appropriately updated.

The keywords have been correctly updated to reflect the new validation and formatting capabilities.

packages/utils/src/validation/url.ts (3)

5-8: LGTM! Clean interface design.

The UrlValidationResult interface provides a clear contract with an optional error field for detailed feedback.


52-54: LGTM! Useful convenience function.

The isValidUrl function provides a clean boolean interface for simple validation checks.


17-43: Scheme comparison is already case-insensitive.

The URL constructor automatically normalizes protocols to lowercase, regardless of input case. Testing confirms that new URL('HTTP://example.com').protocol returns 'http:', making the case-sensitive comparison at line 29 effectively case-insensitive. The suggested .toLowerCase() normalization is unnecessary.

Likely an incorrect or invalid review comment.

packages/utils/src/validation/index.ts (1)

1-5: LGTM! Clean module aggregation.

The validation index properly re-exports URL utilities, providing a clear entry point for validation functionality.

packages/utils/src/index.ts (1)

8-12: LGTM! Public API cleanly expanded.

The re-exports for validation and formatting follow the existing pattern and properly expose the new utility modules.

packages/utils/src/formatting/index.ts (1)

5-7: LGTM! Clean formatting module aggregation.

The formatting index properly aggregates date, number, and string utilities into a cohesive module.

packages/utils/src/formatting/date.ts (1)

34-60: Note: Relative time uses approximate calculations.

The month and year calculations use fixed approximations (30 days/month, 365 days/year) which may not match calendar expectations. For instance, "1 month ago" will be shown after exactly 30 days rather than calendar months. This is acceptable for display purposes but worth noting.

packages/utils/src/formatting/number.ts (3)

14-26: Consider locale handling approach.

The function hardcodes "en-US" locale then replaces separators, which works but may feel indirect. This approach ensures consistent decimal formatting before replacement, though users might expect the custom separators to be applied directly.


35-54: LGTM! Correct byte formatting implementation.

The function properly handles binary vs. decimal units with appropriate base conversion and edge cases like zero bytes.


63-66: LGTM! Smart percentage handling.

The auto-detection of fractional (0.0-1.0) vs. whole number (0-100) ranges is convenient, though callers should be aware of this behavior to avoid confusion.

packages/utils/src/formatting/string.ts (1)

59-64: LGTM! Clean camelCase to snake_case conversion.

The function correctly handles uppercase letters and removes leading underscores.

Comment on lines +12 to +25
export function formatDateTime(date: Date, format: string = "default"): string {
if (format === "iso") {
return date.toISOString();
}

const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");

return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify format parameter documentation.

The JSDoc at line 9 mentions "custom format" but the implementation only supports "iso" and a hardcoded default format. This could mislead users expecting format string capabilities (like "YYYY-MM-DD" patterns).

🔎 Suggested documentation fix
 /**
  * Format datetime to string.
  *
  * @param date - Date object to format
- * @param format - Format string ('iso' for ISO 8601, or custom format)
+ * @param format - Format type ('iso' for ISO 8601, 'default' for 'YYYY-MM-DD HH:mm:ss')
  * @returns Formatted datetime string
  */

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/utils/src/formatting/date.ts around lines 12 to 25, the JSDoc claims
a "custom format" but the function only supports "iso" and a hardcoded default;
update documentation to accurately describe supported values and behavior:
change the JSDoc to state that format accepts either "iso" (returns
date.toISOString()) or "default" (returns "YYYY-MM-DD HH:mm:ss") and that other
strings are ignored/treated as "default" (or alternatively validate and throw
for unknown formats). Also add a brief runtime guard to coerce/validate the
format parameter (e.g., if format !== "iso" && format !== "default" then set to
"default" or throw) and document that choice in the JSDoc.

Comment on lines +14 to +34
export function truncateString(
value: string,
maxLength: number,
suffix: string = "...",
preserveWords: boolean = true
): string {
if (value.length <= maxLength) {
return value;
}

if (preserveWords) {
const truncated = value.substring(0, maxLength - suffix.length);
const lastSpace = truncated.lastIndexOf(" ");
if (lastSpace > maxLength * 0.5) {
return truncated.substring(0, lastSpace) + suffix;
}
return truncated + suffix;
}

return value.substring(0, maxLength - suffix.length) + suffix;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix word boundary heuristic logic.

Line 27 compares lastSpace (an absolute character index) with maxLength * 0.5 (a threshold). This logic seems incorrect—it should likely check if the found space is reasonably close to the desired truncation point. For example, if maxLength=100 and the last space is at index 60, it would be accepted (60 > 50), but if lastSpace=40 it would be rejected, which may not reflect the intended behavior.

🔎 Suggested fix
   if (preserveWords) {
     const truncated = value.substring(0, maxLength - suffix.length);
     const lastSpace = truncated.lastIndexOf(" ");
-    if (lastSpace > maxLength * 0.5) {
+    const minAcceptableLength = (maxLength - suffix.length) * 0.5;
+    if (lastSpace > minAcceptableLength) {
       return truncated.substring(0, lastSpace) + suffix;
     }
     return truncated + suffix;
🤖 Prompt for AI Agents
In packages/utils/src/formatting/string.ts around lines 14 to 34, the heuristic
compares lastSpace (an absolute index in the truncated substring) to maxLength *
0.5 which is incorrect; change the comparison to use the truncated substring
length (or the effective limit maxLength - suffix.length) so you check proximity
relative to the actual truncated portion. Specifically, compute truncated =
value.substring(0, maxLength - suffix.length), then only accept the lastSpace if
lastSpace > truncated.length * 0.5 (and lastSpace !== -1) and return
truncated.substring(0, lastSpace) + suffix; otherwise fall back to truncated +
suffix.

Comment on lines +43 to +51
export function slugify(value: string, separator: string = "-"): string {
return value
.toLowerCase()
.trim()
.replace(/[\s_]+/g, separator)
.replace(/[^\w\-]+/g, "")
.replace(new RegExp(`${separator}+`, "g"), separator)
.replace(new RegExp(`^${separator}|${separator}$`, "g"), "");
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Address ReDoS vulnerability in dynamic RegExp construction.

Lines 49-50 construct regular expressions from the separator variable without escaping special regex characters. If a caller passes a separator containing regex metacharacters (e.g., ".", "*", "+"), this could cause incorrect behavior or ReDoS attacks.

As per static analysis hints.

🔎 Recommended fix to escape separator
+function escapeRegExp(str: string): string {
+  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+}
+
 export function slugify(value: string, separator: string = "-"): string {
+  const escapedSeparator = escapeRegExp(separator);
   return value
     .toLowerCase()
     .trim()
     .replace(/[\s_]+/g, separator)
     .replace(/[^\w\-]+/g, "")
-    .replace(new RegExp(`${separator}+`, "g"), separator)
-    .replace(new RegExp(`^${separator}|${separator}$`, "g"), "");
+    .replace(new RegExp(`${escapedSeparator}+`, "g"), separator)
+    .replace(new RegExp(`^${escapedSeparator}|${escapedSeparator}$`, "g"), "");
 }
🧰 Tools
🪛 ast-grep (0.40.3)

[warning] 48-48: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${separator}+, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 49-49: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${separator}|${separator}$, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🤖 Prompt for AI Agents
In packages/utils/src/formatting/string.ts around lines 43 to 51, the code
builds RegExp objects directly from the separator string which can contain regex
metacharacters and lead to incorrect behavior or ReDoS; fix by first escaping
all regex-special characters in the separator (e.g. replace characters like
-\/\\^$*+?.()|[]{} with a backslash-escaped version) and then use the escaped
separator when creating the RegExp instances (keep the existing "g" flag and
existing patterns but substitute the escaped separator), ensuring you don't
change other logic or return value.

@JustAGhosT JustAGhosT merged commit c453df4 into master Dec 23, 2025
1 check passed
@JustAGhosT JustAGhosT deleted the tembo/migrate-orchestration-utils-repos branch December 23, 2025 21:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant