Repository navigation
Conversation
|
Warning Rate limit exceeded@ryoppippi has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 59 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📥 CommitsReviewing files that changed from the base of the PR and between 8fc6713f379b30d6bf6779e76f1d5f9d8e57607f and 659ae08. 📒 Files selected for processing (3)
WalkthroughThe updates introduce branded types and Zod schemas for domain-specific strings such as dates, IDs, model names, and versions. Factory functions and schema validations are used throughout the codebase and tests to enforce type safety. Test data and schemas are refactored to utilize these branded types, without altering core logic or control flow. Changes
Sequence Diagram(s)sequenceDiagram
participant TestCase
participant FactoryFunc as Factory Function
participant BrandedType
TestCase->>FactoryFunc: Pass raw string (e.g., date, id, model name)
FactoryFunc->>BrandedType: Validate and brand value
BrandedType-->>TestCase: Return branded type for use in test/schema
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Summary of Changes
Hello @ryoppippi, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request focuses on a significant performance enhancement by optimizing the handling of branded types within the application. By strategically replacing repetitive Zod parsing operations in performance-critical loops with type assertions and initial parsing, the changes achieve a measurable improvement in runtime efficiency while rigorously maintaining the integrity and safety of the type system. This refactoring also centralizes and formalizes type definitions, contributing to a more robust and maintainable codebase.
Highlights
- Performance Optimization: Replaced expensive
zod.parse()calls with more efficient type assertions or singlecreate*function calls in data processing loops, resulting in approximately a 4% runtime performance improvement for data processing. - Branded Types Implementation: Introduced a comprehensive set of Zod branded types (
ModelName,ISOTimestamp,Version,SessionId, etc.) and their corresponding creation helper functions insrc/types.internal.tsto enforce stricter type safety and enable the performance optimizations. - Schema and Data Alignment: Updated existing Zod schemas in
src/data-loader.tsto leverage the new branded types, ensuring that validated data is correctly typed. Test data acrosssrc/calculate-cost.tsandsrc/data-loader.tswas also updated to use these new branded types and their creation methods for consistency.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
src/types.internal.ts (2)
47-50:versionSchemaallows unwanted suffixes
Without an end-anchor the pattern matches1.2.3betaor2.0.0-rc.1, which defeats strict semver validation. If you intend to accept onlyMAJOR.MINOR.PATCH, terminate the regex:- .regex(/^\d+\.\d+\.\d+/, 'Invalid version format') + .regex(/^\d+\.\d+\.\d+$/, 'Invalid version format')If prerelease/build metadata should be allowed, consider a dedicated semver regex instead.
69-78: Helper functions still parse on every call – defeats the “perf” objective
The PR description emphasises replacing expensive parsing inside hot loops with type assertions. These helpers still invoke.parse, so any caller using them inside a loop will regress performance.Consider providing lightweight “unsafe*” cast helpers (clearly named) that do
value as ModelNameetc., and mandate their use only after a single upfront validation step.src/calculate-cost.ts (2)
2-9: Import list can be pruned to what the file actually uses
createProjectPathandcreateVersionare only referenced inside test blocks behindimport.meta.vitest. If this file is built for production, the extra imports add to bundle size. Either:
- Move test utilities to a
*.test.tsfile, or- Lazy-import them inside the
if (import.meta.vitest)guard.Not critical but keeps runtime code lean.
96-115: Validation in test data adds unnecessary runtime cost
Each call tocreateDailyDate/createModelNameruns a regex parse. While acceptable in tests, it slightly slows the suite and obscures the literals. Consider validating once in a helper or using the new type-assertion pattern for test fixtures:- date: createDailyDate('2024-01-01'), + date: '2024-01-01' as DailyDate,Same applies to the other branded fields in fixtures.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📥 Commits
Reviewing files that changed from the base of the PR and between 880cea0 and 369706626a01e1a48532e20bbfb1223092d56268.
📒 Files selected for processing (3)
src/calculate-cost.ts(3 hunks)src/data-loader.ts(72 hunks)src/types.internal.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/calculate-cost.ts (1)
src/types.internal.ts (6)
createDailyDate(74-74)createModelName(69-69)createSessionId(70-70)createProjectPath(77-77)createISOTimestamp(73-73)createVersion(78-78)
🪛 ESLint
src/calculate-cost.ts
[error] 96-96: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 106-106: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 128-128: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 129-129: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 135-135: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 141-141: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 142-142: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 148-148: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
src/types.internal.ts
[error] 9-11: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 9-11: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 9-10: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 9-9: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 9-9: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 10-10: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 11-11: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 13-15: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 13-15: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 13-14: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 13-13: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 13-13: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 14-14: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 15-15: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 17-19: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 17-19: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 17-18: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 17-17: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 17-17: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 18-18: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 19-19: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 21-23: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 21-23: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 21-22: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 21-21: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 21-21: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 22-22: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 23-23: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 26-28: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 26-28: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-27: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-26: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-26: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 27-27: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 28-28: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 30-32: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 30-32: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 30-31: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 30-30: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 30-30: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 31-31: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 32-32: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 34-36: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 34-36: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 34-35: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 34-34: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 34-34: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 35-35: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 36-36: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 38-40: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 38-40: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 38-39: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 38-38: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 38-38: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 39-39: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 40-40: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 43-45: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 43-45: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 43-44: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 43-43: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 43-43: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 44-44: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 45-45: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 47-49: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 47-49: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 47-48: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 47-47: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 47-47: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 48-48: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 49-49: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 69-69: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 69-69: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 70-70: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 70-70: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 71-71: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 71-71: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 72-72: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 72-72: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 73-73: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 73-73: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 74-74: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 74-74: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 75-75: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 75-75: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 76-76: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 76-76: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 77-77: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 77-77: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 78-78: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 78-78: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
src/data-loader.ts
[error] 86-86: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 87-87: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 87-87: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 87-87: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 88-97: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 88-88: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 88-88: Unsafe member access .object on an error typed value.
(ts/no-unsafe-member-access)
[error] 89-94: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 89-89: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 89-89: Unsafe member access .object on an error typed value.
(ts/no-unsafe-member-access)
[error] 90-90: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 90-90: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 90-90: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 91-91: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 91-91: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 91-91: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 92-92: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 92-92: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 92-92: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 92-92: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 92-92: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 93-93: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 93-93: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 93-93: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 93-93: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 93-93: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 95-95: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 95-95: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 95-95: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 96-96: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 96-96: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 96-96: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 98-98: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 98-98: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 98-98: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 98-98: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 98-98: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 99-99: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 99-99: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 99-99: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 111-111: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 128-128: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 129-129: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 129-129: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 129-129: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 130-130: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 130-130: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 130-130: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 131-131: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 131-131: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 131-131: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 132-132: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 132-132: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 132-132: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 133-133: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 133-133: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 133-133: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 134-134: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 134-134: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 134-134: Unsafe member access .array on an error typed value.
(ts/no-unsafe-member-access)
[error] 147-147: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 148-148: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 149-149: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 149-149: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 149-149: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 150-150: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 150-150: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 150-150: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 151-151: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 151-151: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 151-151: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 152-152: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 152-152: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 152-152: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 153-153: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 153-153: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 153-153: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 154-154: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 155-155: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 155-155: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 155-155: Unsafe member access .array on an error typed value.
(ts/no-unsafe-member-access)
[error] 156-156: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 156-156: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 156-156: Unsafe member access .array on an error typed value.
(ts/no-unsafe-member-access)
[error] 169-169: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 170-170: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 170-170: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 170-170: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 171-171: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 171-171: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 171-171: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 172-172: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 172-172: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 172-172: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 173-173: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 173-173: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 173-173: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 174-174: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 174-174: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 174-174: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 175-175: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 175-175: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 175-175: Unsafe member access .array on an error typed value.
(ts/no-unsafe-member-access)
[error] 280-280: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 683-683: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 845-845: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 845-845: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 845-845: Unsafe member access .sessionId on an error typed value.
(ts/no-unsafe-member-access)
[error] 846-846: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 846-846: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 846-846: Unsafe member access .projectPath on an error typed value.
(ts/no-unsafe-member-access)
[error] 848-848: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 848-848: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 848-848: Unsafe member access .timestamp on an error typed value.
(ts/no-unsafe-member-access)
[error] 917-917: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1153-1153: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1158-1158: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1165-1165: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1194-1194: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1225-1225: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1230-1230: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1235-1235: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1265-1265: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1270-1270: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1275-1275: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1301-1301: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1306-1306: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1311-1311: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1341-1341: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1346-1346: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1351-1351: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1438-1438: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1443-1443: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1448-1448: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1516-1516: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1521-1521: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1562-1562: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1567-1567: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1572-1572: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1577-1577: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1602-1602: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1607-1607: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1612-1612: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1617-1617: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1645-1645: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1650-1650: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1655-1655: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1660-1660: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1696-1696: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1701-1701: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1706-1706: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1737-1737: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1749-1749: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1792-1792: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1826-1826: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1838-1838: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1878-1878: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1880-1880: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1884-1884: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1886-1886: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1890-1890: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1892-1892: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1918-1918: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1926-1926: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1934-1934: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1964-1964: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1972-1972: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 1980-1980: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2013-2013: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2021-2021: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2029-2029: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2062-2062: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2070-2070: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2078-2078: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2111-2111: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2145-2145: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2185-2185: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2222-2222: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2228-2228: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2231-2231: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2236-2236: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2264-2264: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2291-2291: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2297-2297: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2300-2300: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2334-2334: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2363-2363: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2371-2371: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2400-2400: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2439-2439: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2445-2445: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2448-2448: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2473-2473: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2476-2476: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2503-2503: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2506-2506: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2512-2512: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2515-2515: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2541-2541: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2544-2544: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2578-2578: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2581-2581: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2608-2608: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2611-2611: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2639-2639: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2642-2642: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2669-2669: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2672-2672: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2699-2699: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2734-2734: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2742-2742: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2775-2775: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2781-2781: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2816-2816: Unsafe assignment of an any value.
(ts/no-unsafe-assignment)
[error] 2816-2816: Unsafe member access .message on an error typed value.
(ts/no-unsafe-member-access)
[error] 2816-2816: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2830-2830: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2836-2836: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2860-2860: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2866-2866: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2984-2984: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2988-2988: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 2998-2998: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3002-3002: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3012-3012: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3016-3016: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3047-3047: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3051-3051: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3090-3090: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3094-3094: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3101-3101: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3105-3105: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3112-3112: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3116-3116: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3159-3159: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3163-3163: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3170-3170: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3174-3174: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3210-3210: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3214-3214: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3222-3222: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3226-3226: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3253-3253: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3257-3257: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3279-3279: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3281-3281: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3287-3287: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3296-3296: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3303-3303: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3312-3312: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3314-3314: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3330-3330: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3331-3331: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3332-3332: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3360-3360: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3414-3414: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3416-3416: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3422-3422: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3428-3428: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3430-3430: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3436-3436: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3460-3460: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3462-3462: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3468-3468: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3472-3472: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3474-3474: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3480-3480: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3506-3506: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3508-3508: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3514-3514: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3520-3520: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3522-3522: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 3528-3528: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
🪛 GitHub Actions: CI
src/data-loader.ts
[error] 1872-1872: Test failure: expected '' to be '2024-01-01' (Object.is equality) in loadSessionData > aggregates session usage data.
[error] 2103-2103: Test failure: expected '' to be '2024-01-15' (Object.is equality) in loadSessionData > filters by date range based on last activity.
[error] 2353-2353: Test failure: expected [] to have a length of 1 but got 0 in data-loader cost calculation with real pricing > loadSessionData with mixed schemas > should handle unknown models gracefully.
[error] 2726-2726: Test failure: expected [] to have a length of 1 but got 0 in data-loader cost calculation with real pricing > pricing data fetching optimization > display mode should work without network access.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Socket Security: Pull Request Alerts
🔇 Additional comments (1)
src/data-loader.ts (1)
169-176: Monthly aggregation inherits unsoundmodelsUsedcastThe
modelsSetmay contain raw strings; casting toModelName[]without checks repeats the previous issue.- modelsUsed: Array.from(modelsSet) as ModelName[], + modelsUsed: Array.from(modelsSet).map(createModelName),A single pass here is not performance-sensitive.
There was a problem hiding this comment.
🛠️ Refactor suggestion
ISO-8601 regex is too restrictive – offsets like “+00:00” will be rejected
The current pattern only accepts the trailing Z notation. Valid ISO-8601 timestamps that include an explicit offset (2024-01-01T00:00:00+00:00, 2024-01-01T00:00:00-05:00, etc.) will fail to parse and force callers to strip the offset or coerce the value, defeating the purpose of validation.
- .regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/, 'Invalid ISO timestamp')
+ .regex(
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})$/,
+ 'Invalid ISO-8601 timestamp',
+ )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const isoTimestampSchema = z.string() | |
| .regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/, 'Invalid ISO timestamp') | |
| .brand<'ISOTimestamp'>(); | |
| export const isoTimestampSchema = z.string() | |
| .regex( | |
| /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})$/, | |
| 'Invalid ISO-8601 timestamp', | |
| ) | |
| .brand<'ISOTimestamp'>(); |
🧰 Tools
🪛 ESLint
[error] 26-28: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 26-28: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-27: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-26: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-26: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 27-27: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 28-28: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
🤖 Prompt for AI Agents
In src/types.internal.ts around lines 26 to 29, the regex for isoTimestampSchema
only accepts timestamps ending with 'Z' and rejects valid ISO-8601 timestamps
with offsets like '+00:00' or '-05:00'. Update the regex to allow either a 'Z'
or a timezone offset in the format ±HH:MM at the end of the string, ensuring it
matches all valid ISO-8601 timestamp formats including those with explicit
offsets.
There was a problem hiding this comment.
🛠️ Refactor suggestion
Over-strict model validation is dropping legitimate records
Changing message.model from z.string() to modelNameSchema means every log line whose model name does not match the branded-type regex is now rejected by usageDataSchema.safeParse.
Tests that intentionally feed unknown-model-xyz now fail (results.length === 0). In production this will silently discard usage coming from future/experimental models and break cost reports.
- model: modelNameSchema.optional(), // Model is inside message object
+ // Accept any string → keep record, brand later if recognised
+ model: z.string().optional(),If you still want strong typing for known models, brand after parsing:
const model = isKnownModel(data.message.model)
? (data.message.model as ModelName)
: data.message.model ?? 'unknown';This preserves data while retaining the optimisation goal of avoiding zod.parse() inside hot paths.
🧰 Tools
🪛 ESLint
[error] 88-97: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 95-95: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 95-95: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 95-95: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 96-96: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 96-96: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 96-96: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
🤖 Prompt for AI Agents
In src/data-loader.ts around lines 95 to 97, the current validation uses
modelNameSchema for the model field, which is too strict and causes legitimate
records with unknown or experimental model names to be dropped. To fix this,
revert the model field validation to a more permissive type like z.string().
Then, after parsing, apply branding or type narrowing by checking if the model
is known and casting it accordingly, defaulting to 'unknown' if not. This
approach preserves all data while maintaining strong typing where possible.
There was a problem hiding this comment.
lastActivity now returns an ISO timestamp – breaks API contract & tests
Previously lastActivity was a plain YYYY-MM-DD date (see failing tests).
Switching to createISOTimestamp() returns the full timestamp, which:
- Violates callers that expect a date string.
- Makes
filterByDateRange()do an unnecessary substring on an ISO value. - Causes CI failures (
expected '2024-01-01', got '').
Use the branded daily date instead:
- lastActivity: createISOTimestamp(latestEntry.timestamp),
+ lastActivity: createDailyDate(formatDate(latestEntry.timestamp)),This restores the previous behaviour while still avoiding expensive validation in loops.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sessionId: createSessionId(latestEntry.sessionId), | |
| projectPath: createProjectPath(latestEntry.projectPath), | |
| ...totals, | |
| lastActivity: formatDate(latestEntry.timestamp), | |
| versions: Array.from(versionSet).sort(), | |
| modelsUsed, | |
| lastActivity: createISOTimestamp(latestEntry.timestamp), | |
| versions: Array.from(versionSet).sort() as Version[], | |
| sessionId: createSessionId(latestEntry.sessionId), | |
| projectPath: createProjectPath(latestEntry.projectPath), | |
| ...totals, | |
| - lastActivity: createISOTimestamp(latestEntry.timestamp), | |
| + lastActivity: createDailyDate(formatDate(latestEntry.timestamp)), | |
| versions: Array.from(versionSet).sort() as Version[], |
🧰 Tools
🪛 ESLint
[error] 845-845: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 845-845: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 845-845: Unsafe member access .sessionId on an error typed value.
(ts/no-unsafe-member-access)
[error] 846-846: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 846-846: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 846-846: Unsafe member access .projectPath on an error typed value.
(ts/no-unsafe-member-access)
[error] 848-848: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 848-848: Unsafe argument of type error typed assigned to a parameter of type string.
(ts/no-unsafe-argument)
[error] 848-848: Unsafe member access .timestamp on an error typed value.
(ts/no-unsafe-member-access)
🤖 Prompt for AI Agents
In src/data-loader.ts around lines 845 to 849, the lastActivity field is
currently set using createISOTimestamp(latestEntry.timestamp), which returns a
full ISO timestamp string instead of the expected plain YYYY-MM-DD date string.
This breaks the API contract and causes test failures. To fix this, replace
createISOTimestamp(latestEntry.timestamp) with a function or method that returns
the branded daily date string (YYYY-MM-DD) format, restoring the previous
behavior and ensuring compatibility with filterByDateRange and existing tests.
commit: |
There was a problem hiding this comment.
Actionable comments posted: 6
♻️ Duplicate comments (1)
src/types.internal.ts (1)
26-28: ISO-8601 regex is still too restrictiveThe regex still mandates a trailing
Z, disallowing valid ISO-8601 timestamps with an explicit offset (+00:00,-05:00, etc.). This was raised earlier and hasn’t been addressed. Consider the previously suggested, more permissive pattern:- .regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/, 'Invalid ISO timestamp') + .regex( + /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?(?:Z|[+-]\d{2}:\d{2})$/, + 'Invalid ISO-8601 timestamp', + )
🧹 Nitpick comments (4)
src/calculate-cost.ts (2)
2-9: Imports for test-only helpers are pulled into the production bundle
createActivityDate,createDailyDate, … are only referenced inside theif (import.meta.vitest)block, yet they are imported at module-top scope. Depending on the bundler / tree-shaker settings these runtime-heavy helpers (each performs azod.parse) may leak into the production chunk even though they are never executed.-import { - createActivityDate, - createDailyDate, - createModelName, - createProjectPath, - createSessionId, - createVersion, -} from './types.internal.ts'; +if (import.meta.vitest != null) { + const { + createActivityDate, + createDailyDate, + createModelName, + createProjectPath, + createSessionId, + createVersion, + } = await import('./types.internal.ts'); + // … tests … +}This keeps the helpers completely out of the production graph while preserving type safety inside tests.
94-113: ESLintno-unsafe-assignmentflags everycreate*()usage
zodSchema.parse()returnsunknown, so each assignment is considered unsafe. A tiny wrapper fixes this without disabling the rule:function safeParse<T>(schema: z.ZodType<T>, value: unknown): T { return schema.parse(value) as T; } export const createDailyDate = (v: string) => safeParse(dailyDateSchema, v); export const createModelName = (v: string) => safeParse(modelNameSchema, v);Alternatively, cast at call-site:
date: createDailyDate('2024-01-01') as DailyDate,Either silence the ESLint noise or adopt the helper to keep the codebase warning-free.
src/types.internal.ts (2)
51-53: AnchorversionSchemaregex to avoid partial matches
/^\d+\.\d+\.\d+/allows extras after the patch number (1.2.3foo). Anchoring the end removes false positives:- .regex(/^\d+\.\d+\.\d+/, 'Invalid version format') + .regex(/^\d+\.\d+\.\d+$/, 'Invalid version format')
30-37: Redundant daily vs. activity date schemas
dailyDateSchemaandactivityDateSchemashare an identical pattern. Unless their semantics diverge later, you can DRY this up to reduce maintenance overhead:const yyyyMmDd = z.string() .regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format'); export const dailyDateSchema = yyyyMmDd.brand<'DailyDate'>(); export const activityDateSchema = yyyyMmDd.brand<'ActivityDate'>();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📥 Commits
Reviewing files that changed from the base of the PR and between f6a0f82340b6384670ef8f4ec5e33ac6630fa8c6 and 8fc6713f379b30d6bf6779e76f1d5f9d8e57607f.
📒 Files selected for processing (3)
src/calculate-cost.ts(3 hunks)src/data-loader.ts(6 hunks)src/types.internal.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/calculate-cost.ts (1)
src/types.internal.ts (6)
createDailyDate(79-79)createModelName(74-74)createSessionId(75-75)createProjectPath(83-83)createActivityDate(80-80)createVersion(84-84)
src/data-loader.ts (1)
src/types.internal.ts (9)
isoTimestampSchema(26-28)versionSchema(51-53)modelNameSchema(9-11)messageIdSchema(21-23)requestIdSchema(17-19)dailyDateSchema(30-32)sessionIdSchema(13-15)projectPathSchema(47-49)monthlyDateSchema(38-40)
🪛 ESLint
src/calculate-cost.ts
[error] 96-96: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 106-106: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 128-128: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 129-129: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 135-135: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 141-141: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 142-142: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 148-148: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
src/data-loader.ts
[error] 73-73: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 74-74: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 74-74: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 74-74: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 75-84: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 75-75: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 75-75: Unsafe member access .object on an error typed value.
(ts/no-unsafe-member-access)
[error] 76-81: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 76-76: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 76-76: Unsafe member access .object on an error typed value.
(ts/no-unsafe-member-access)
[error] 77-77: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 77-77: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 77-77: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 78-78: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 78-78: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 78-78: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 79-79: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 79-79: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 79-79: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 79-79: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 79-79: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 80-80: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 80-80: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 80-80: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 80-80: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 80-80: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 82-82: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 82-82: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 82-82: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 83-83: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 83-83: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 83-83: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 85-85: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 85-85: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 85-85: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 85-85: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 85-85: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 86-86: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 86-86: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 86-86: Unsafe member access .optional on an error typed value.
(ts/no-unsafe-member-access)
[error] 98-98: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 115-115: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 116-116: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 116-116: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 116-116: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 117-117: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 117-117: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 117-117: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 118-118: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 118-118: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 118-118: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 119-119: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 119-119: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 119-119: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 120-120: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 120-120: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 120-120: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 121-121: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 121-121: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 121-121: Unsafe member access .array on an error typed value.
(ts/no-unsafe-member-access)
[error] 134-134: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 135-135: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 136-136: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 136-136: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 136-136: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 137-137: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 137-137: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 137-137: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 138-138: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 138-138: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 138-138: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 139-139: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 139-139: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 139-139: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 140-140: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 140-140: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 140-140: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 141-141: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 142-142: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 142-142: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 142-142: Unsafe member access .array on an error typed value.
(ts/no-unsafe-member-access)
[error] 143-143: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 143-143: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 143-143: Unsafe member access .array on an error typed value.
(ts/no-unsafe-member-access)
[error] 156-156: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 157-157: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 157-157: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 157-157: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 158-158: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 158-158: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 158-158: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 159-159: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 159-159: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 159-159: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 160-160: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 160-160: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 160-160: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 161-161: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 161-161: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 161-161: Unsafe member access .number on an error typed value.
(ts/no-unsafe-member-access)
[error] 162-162: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 162-162: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 162-162: Unsafe member access .array on an error typed value.
(ts/no-unsafe-member-access)
src/types.internal.ts
[error] 9-11: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 9-11: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 9-10: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 9-9: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 9-9: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 10-10: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 11-11: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 13-15: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 13-15: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 13-14: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 13-13: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 13-13: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 14-14: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 15-15: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 17-19: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 17-19: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 17-18: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 17-17: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 17-17: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 18-18: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 19-19: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 21-23: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 21-23: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 21-22: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 21-21: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 21-21: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 22-22: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 23-23: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 26-28: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 26-28: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-27: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-26: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 26-26: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 27-27: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 28-28: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 30-32: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 30-32: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 30-31: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 30-30: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 30-30: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 31-31: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 32-32: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 34-36: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 34-36: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 34-35: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 34-34: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 34-34: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 35-35: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 36-36: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 38-40: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 38-40: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 38-39: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 38-38: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 38-38: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 39-39: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 40-40: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 42-44: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 42-44: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 42-43: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 42-42: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 42-42: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 43-43: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 44-44: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 47-49: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 47-49: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 47-48: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 47-47: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 47-47: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 48-48: Unsafe member access .min on an error typed value.
(ts/no-unsafe-member-access)
[error] 49-49: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 51-53: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 51-53: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 51-52: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 51-51: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 51-51: Unsafe member access .string on an error typed value.
(ts/no-unsafe-member-access)
[error] 52-52: Unsafe member access .regex on an error typed value.
(ts/no-unsafe-member-access)
[error] 53-53: Unsafe member access .brand on an error typed value.
(ts/no-unsafe-member-access)
[error] 74-74: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 74-74: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 75-75: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 75-75: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 76-76: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 76-76: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 77-77: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 77-77: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 78-78: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 78-78: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 79-79: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 79-79: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 80-80: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 80-80: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 81-81: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 81-81: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 82-82: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 82-82: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 83-83: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 83-83: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
[error] 84-84: Unsafe call of a(n) error type typed value.
(ts/no-unsafe-call)
[error] 84-84: Unsafe member access .parse on an error typed value.
(ts/no-unsafe-member-access)
🪛 GitHub Actions: CI
src/calculate-cost.ts
[error] 135-135: TypeScript TS2322: Type 'string & BRAND<"ActivityDate">' is not assignable to type 'string & BRAND<"ISOTimestamp">'. Property 'ISOTimestamp' is missing in type '{ ActivityDate: true; }' but required in type '{ ISOTimestamp: true; }'.
[error] 148-148: TypeScript TS2322: Type 'string & BRAND<"ActivityDate">' is not assignable to type 'string & BRAND<"ISOTimestamp">'. Property 'ISOTimestamp' is missing in type '{ ActivityDate: true; }' but required in type '{ ISOTimestamp: true; }'.
src/data-loader.ts
[error] 265-265: TypeScript TS2322: Type '{ inputTokens: number; outputTokens: number; cacheCreationTokens: number; cacheReadTokens: number; cost: number; modelName: string; }[]' is not assignable to type '{ modelName: string & BRAND<"ModelName">; inputTokens: number; outputTokens: number; cacheCreationTokens: number; cacheReadTokens: number; cost: number; }[]'. Property 'modelName' type mismatch: 'string' is not assignable to 'string & BRAND<"ModelName">'.
[error] 682-682: TypeScript TS2322: Type '{ inputTokens: number; outputTokens: number; cacheCreationTokens: number; cacheReadTokens: number; cost: number; totalCost: number; date: string; modelsUsed: string[]; modelBreakdowns: { modelName: string & BRAND<"ModelName">; ... }[]; }[]' is not assignable to type '{ date: string & BRAND<"DailyDate">; inputTokens: number; outputTokens: number; cacheCreationTokens: number; cacheReadTokens: number; totalCost: number; modelsUsed: (string & BRAND<"ModelName">)[]; modelBreakdowns: { ... }[]; }[]'. Property 'date' type mismatch: 'string' is not assignable to 'string & BRAND<"DailyDate">'.
[error] 846-846: TypeScript TS2322: Type '{ inputTokens: number; outputTokens: number; cacheCreationTokens: number; cacheReadTokens: number; cost: number; totalCost: number; sessionId: string; projectPath: string; lastActivity: string; versions: string[]; modelsUsed: string[]; modelBreakdowns: { ... }[]; }[]' is not assignable to type '{ sessionId: string & BRAND<"SessionId">; projectPath: string & BRAND<"ProjectPath">; inputTokens: number; outputTokens: number; cacheCreationTokens: number; cacheReadTokens: number; ... }[]'. Property 'sessionId' type mismatch: 'string' is not assignable to 'string & BRAND<"SessionId">'.
[error] 904-904: TypeScript TS2322: Type 'string' is not assignable to type 'string & BRAND<"MonthlyDate">'. Property 'MonthlyDate' is missing in type 'string'.
[error] 910-910: TypeScript TS2322: Type 'string[]' is not assignable to type '(string & BRAND<"ModelName">)[]'. Property 'modelsUsed' type mismatch: 'string' is not assignable to 'string & BRAND<"ModelName">'.
[error] 1140-1140: TypeScript TS2322: Type 'string' is not assignable to type 'string & BRAND<"ISOTimestamp">'. Property 'ISOTimestamp' is missing in type 'string'.
[error] 1867-1867: TypeScript TS2322: Type 'string' is not assignable to type 'string & BRAND<"Version">'. Property 'Version' is missing in type 'string'.
[error] 1873-1873: TypeScript TS2322: Type 'string' is not assignable to type 'string & BRAND<"Version">'. Property 'Version' is missing in type 'string'.
[error] 2729-2729: TypeScript TS2322: Type 'string' is not assignable to type 'string & BRAND<"ModelName">'. Property 'ModelName' is missing in type 'string'.
[error] 2768-2768: TypeScript TS2322: Type 'string' is not assignable to type 'string & BRAND<"ModelName">'. Property 'ModelName' is missing in type 'string'.
[error] 2808-2808: TypeScript TS2345: Argument type mismatch in property 'message.model': 'string' is not assignable to 'string & BRAND<"ModelName">'.
[error] 2823-2823: TypeScript TS2322: Type 'string' is not assignable to type 'string & BRAND<"ModelName">'. Property 'ModelName' is missing in type 'string'.
[error] 2853-2853: TypeScript TS2322: Type 'string' is not assignable to type 'string & BRAND<"ModelName">'. Property 'ModelName' is missing in type 'string'.
[error] 3277-3277: TypeScript TS2345: Argument type mismatch in property 'timestamp': 'string' is not assignable to 'string & BRAND<"ISOTimestamp">'.
[error] 3293-3293: TypeScript TS2345: Argument type mismatch in property 'timestamp': 'string' is not assignable to 'string & BRAND<"ISOTimestamp">'.
[error] 3309-3309: TypeScript TS2345: Argument type mismatch in property 'timestamp': 'string' is not assignable to 'string & BRAND<"ISOTimestamp">'.
[error] 135-2721: Multiple TypeScript TS2322 errors: Numerous type mismatches where 'string' is assigned to branded string types such as 'ISOTimestamp', 'ModelName', 'Version', 'SessionId', 'MonthlyDate', 'DailyDate', etc. These errors indicate that plain strings are used where branded types are expected, causing type incompatibility.
🔇 Additional comments (1)
src/data-loader.ts (1)
73-87: Strict branding insideusageDataSchemacreates an asymmetry
isoTimestampSchema,versionSchema,modelNameSchema, … enforce branding on raw log lines, which is fine, but make sure:
lastActivitylater derived viaformatDate()is not re-parsed againstisoTimestampSchema(it isn’t a full ISO string anymore).- Synthetic or unknown model names still pass the relaxed
min(1)rule (they do).No immediate action required here, but keep the asymmetry in mind when fixing the aggregate builders.
There was a problem hiding this comment.
lastActivity now expects ActivityDate, but the public type still requires ISOTimestamp → compilation fails
CI shows TS2322 at these lines:
Type 'string & BRAND<"ActivityDate">' is not assignable to type 'string & BRAND<"ISOTimestamp">'.
SessionUsage.lastActivity is still branded as ISOTimestamp, yet the code supplies an ActivityDate. Align the two in one of the following ways:
-
Update the domain type
ChangeSessionUsage.lastActivity(and its zod schema) fromISOTimestamptoActivityDate, reflecting the PR’s intention to relax the format toYYYY-MM-DD. -
Keep the old type and adjust the test
Revert to the existing helper:
- lastActivity: createActivityDate('2024-01-01'),
+ lastActivity: createIsoTimestamp('2024-01-01T00:00:00Z'),Pick one direction and make it consistent across src/data-loader.ts, schemas, and all call-sites, otherwise the build will stay red.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sessionId: createSessionId('session-1'), | |
| projectPath: createProjectPath('project/path'), | |
| inputTokens: 100, | |
| outputTokens: 50, | |
| cacheCreationTokens: 25, | |
| cacheReadTokens: 10, | |
| totalCost: 0.01, | |
| lastActivity: '2024-01-01', | |
| versions: ['1.0.3'], | |
| modelsUsed: ['claude-sonnet-4-20250514'], | |
| lastActivity: createActivityDate('2024-01-01'), | |
| versions: [createVersion('1.0.3')], | |
| modelsUsed: [createModelName('claude-sonnet-4-20250514')], | |
| modelBreakdowns: [], | |
| }, | |
| { | |
| sessionId: 'session-2', | |
| projectPath: 'project/path', | |
| sessionId: createSessionId('session-2'), | |
| projectPath: createProjectPath('project/path'), | |
| inputTokens: 200, | |
| outputTokens: 100, | |
| cacheCreationTokens: 50, | |
| cacheReadTokens: 20, | |
| totalCost: 0.02, | |
| lastActivity: '2024-01-02', | |
| versions: ['1.0.3', '1.0.4'], | |
| modelsUsed: ['claude-opus-4-20250514'], | |
| lastActivity: createActivityDate('2024-01-02'), | |
| versions: [createVersion('1.0.3'), createVersion('1.0.4')], | |
| modelsUsed: [createModelName('claude-opus-4-20250514')], | |
| { | |
| sessionId: createSessionId('session-1'), | |
| projectPath: createProjectPath('project/path'), | |
| inputTokens: 100, | |
| outputTokens: 50, | |
| cacheCreationTokens: 25, | |
| cacheReadTokens: 10, | |
| totalCost: 0.01, | |
| - lastActivity: createActivityDate('2024-01-01'), | |
| + lastActivity: createIsoTimestamp('2024-01-01T00:00:00Z'), | |
| versions: [createVersion('1.0.3')], | |
| modelsUsed: [createModelName('claude-sonnet-4-20250514')], | |
| modelBreakdowns: [], | |
| }, | |
| { | |
| sessionId: createSessionId('session-2'), | |
| projectPath: createProjectPath('project/path'), | |
| inputTokens: 200, | |
| outputTokens: 100, | |
| cacheCreationTokens: 50, | |
| cacheReadTokens: 20, | |
| totalCost: 0.02, | |
| lastActivity: createActivityDate('2024-01-02'), | |
| versions: [createVersion('1.0.3'), createVersion('1.0.4')], | |
| modelsUsed: [createModelName('claude-opus-4-20250514')], |
🧰 Tools
🪛 ESLint
[error] 128-128: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 129-129: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 135-135: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 141-141: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 142-142: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
[error] 148-148: Unsafe assignment of an error typed value.
(ts/no-unsafe-assignment)
🪛 GitHub Actions: CI
[error] 135-135: TypeScript TS2322: Type 'string & BRAND<"ActivityDate">' is not assignable to type 'string & BRAND<"ISOTimestamp">'. Property 'ISOTimestamp' is missing in type '{ ActivityDate: true; }' but required in type '{ ISOTimestamp: true; }'.
[error] 148-148: TypeScript TS2322: Type 'string & BRAND<"ActivityDate">' is not assignable to type 'string & BRAND<"ISOTimestamp">'. Property 'ISOTimestamp' is missing in type '{ ActivityDate: true; }' but required in type '{ ISOTimestamp: true; }'.
🤖 Prompt for AI Agents
In src/calculate-cost.ts around lines 128 to 150, the lastActivity field is
assigned an ActivityDate type but the SessionUsage.lastActivity property and its
schema still expect an ISOTimestamp type, causing a type mismatch error TS2322.
To fix this, choose one approach: either update the SessionUsage.lastActivity
type and its zod schema to ActivityDate to match the new relaxed date format, or
revert the lastActivity assignments to use ISOTimestamp format consistently.
Ensure this change is applied consistently in src/data-loader.ts, all relevant
schemas, and all call-sites to resolve the compilation error.
- Add core branded types: ModelName, SessionId, ProjectPath, Version - Add date-specific branded types: DailyDate, ActivityDate, MonthlyDate, ISOTimestamp, FilterDate - Add identifier types: RequestId, MessageId for message tracking - Create validation schemas with appropriate format constraints (regex, length) - Add helper functions for safe type construction (createModelName, createActivityDate, etc.) - Relax model name validation to support synthetic/unknown models for backward compatibility - Maintain existing CostMode and SortOrder types This establishes the foundation for compile-time type safety across the application.
**Schema Integration:** - Update usageDataSchema to use branded types (modelNameSchema, isoTimestampSchema, etc.) - Update dailyUsageSchema, sessionUsageSchema, monthlyUsageSchema with branded fields - Change sessionUsage.lastActivity from ISOTimestamp to ActivityDate for YYYY-MM-DD format **Performance Optimizations:** - Use type assertions (as ModelName[]) for array mapping in hot paths - Optimize modelsUsed.map(createModelName) → modelsUsed as ModelName[] - Optimize versions array mapping and model breakdown creation - Balance type safety with runtime performance in aggregation loops **Import & Type Updates:** - Add comprehensive imports for branded types and create functions - Update type imports for ActivityDate, ModelName, Version, etc. - Add proper error handling for branded type validation This maintains full type safety while optimizing performance-critical paths.
**Test Data Standardization:** - Replace direct string assignments with proper branded type constructors - Use createModelName() for all Claude model references in tests - Use createActivityDate() for lastActivity fields (YYYY-MM-DD format) - Use createDailyDate(), createSessionId(), createProjectPath() in test scenarios **Type Safety in Tests:** - Ensure all test data validates through branded type schemas - Update test expectations to work with branded types - Maintain test coverage while enforcing type constraints **Model Updates:** - Update test models to use current Claude 4 naming (claude-sonnet-4-20250514, claude-opus-4-20250514) - Ensure backward compatibility testing with various model name formats This ensures tests validate the same type constraints as production code.
There was a problem hiding this comment.
Pull Request Overview
This PR enhances type safety by introducing Zod branded types throughout the application while optimizing performance through selective use of type assertions.
- Introduces branded Zod schemas and helper functions in src/types.internal.ts.
- Refactors data parsing and aggregation in src/data-loader.ts to utilize branded types.
- Updates cost calculation tests in src/calculate-cost.ts to use branded type constructors.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/types.internal.ts | Implements branded Zod schemas and helper functions for type-safe string validation. |
| src/data-loader.ts | Integrates branded types into JSONL parsing and usage aggregation for improved safety. |
| src/calculate-cost.ts | Adjusts tests and cost calculations to leverage branded type helpers for improved clarity. |
| lastActivity: formatDate(latestEntry.timestamp), | ||
| versions: uniq(versions).sort(), | ||
| modelsUsed, | ||
| lastActivity: formatDate(latestEntry.timestamp) as ActivityDate, |
There was a problem hiding this comment.
Consider replacing the direct type assertion with a branded helper such as createActivityDate to ensure consistent runtime validation across date conversions.
| return { | ||
| date, | ||
| date: createDailyDate(date), | ||
| ...totals, |
There was a problem hiding this comment.
[nitpick] While using a type assertion here is effective for performance, adding a brief inline comment to clarify that the data has been pre-validated could improve code clarity for future maintainers.
| ...totals, | |
| ...totals, | |
| // `modelsUsed` has been pre-validated to match the `ModelName[]` type. |
feat: enhance type safety with Zod branded types and performance optimizations
Summary
This comprehensive implementation introduces branded types for enhanced type safety while maintaining performance through strategic optimizations.
🎯 Key Features
Branded Types Implementation
Performance Optimizations
Backward Compatibility
📊 Performance Analysis
Bundle Size Impact
Runtime Performance (hyperfine benchmarks, offline mode)
Daily Command Performance
```bash
Main Branch
Time (mean ± σ): 612.7 ms ± 20.9 ms
Range (min … max): 590.7 ms … 684.4 ms
Brand Types Branch
Time (mean ± σ): 631.3 ms ± 7.0 ms
Range (min … max): 618.5 ms … 645.3 ms
Result: ~3% slower (18.6ms difference)
```
Session Command Performance
```bash
Main Branch
Time (mean ± σ): 606.0 ms ± 9.8 ms
Range (min … max): 593.1 ms … 630.4 ms
Brand Types Branch
Time (mean ± σ): 620.7 ms ± 6.0 ms
Range (min … max): 608.5 ms … 630.9 ms
Result: ~2.4% slower (14.7ms difference)
```
Monthly Command Performance
```bash
Main Branch
Time (mean ± σ): 607.9 ms ± 6.4 ms
Range (min … max): 597.5 ms … 618.9 ms
Brand Types Branch
Time (mean ± σ): 622.9 ms ± 7.4 ms
Range (min … max): 611.1 ms … 637.7 ms
Result: ~2.5% slower (15.0ms difference)
```
Performance Trade-off Analysis
🔧 Technical Implementation
Before (Performance Issues)
```typescript
// Expensive regex validation in loops
modelsUsed: modelsUsed.map(createModelName), // Validates each model with regex
versions: Array.from(versionSet).sort().map(createVersion), // Validates each version
modelName: createModelName(modelName), // Individual validation calls
```
After (Optimized Approach)
```typescript
// Type assertions for already-validated data
modelsUsed: modelsUsed as ModelName[], // Direct assertion, no re-validation
versions: Array.from(versionSet).sort() as Version[], // Direct assertion
modelName: modelName as ModelName, // Direct assertion in aggregation
```
Safety Guarantees
✅ Input Validation: All data validated by Zod schemas during initial JSONL parsing
✅ Type Safety: Branded types prevent identifier mix-ups at compile time
✅ Runtime Safety: Type assertions only used after validation, not before
✅ IDE Support: Enhanced autocomplete, refactoring, and error detection
📝 Key Changes
Core Files Modified
New Branded Types
```typescript
type ModelName = string & { readonly brand: ModelName };
type SessionId = string & { readonly brand: SessionId };
type ActivityDate = string & { readonly brand: ActivityDate }; // YYYY-MM-DD
type DailyDate = string & { readonly brand: DailyDate }; // YYYY-MM-DD
type Version = string & { readonly brand: Version }; // SemVer format
```
Validation Strategy
🧪 Test Plan
💡 Benefits
Developer Experience
Runtime Benefits
Future-Proofing
🔄 Migration Notes
This change is backward compatible - no user action required:
Trade-off Summary: ~3% performance cost for significant type safety improvements - excellent value proposition for a development tool prioritizing reliability and maintainability.
Summary by CodeRabbit
New Features
Refactor
Tests