Skip to content

Conversation

@sorccu
Copy link
Member

@sorccu sorccu commented Mar 17, 2025

See CodeRabbit's comment below, it is a decent description. Copied here:

This change introduces a comprehensive import and code generation system for Checkly CLI, enabling users to import existing Checkly resources into their projects. It adds new CLI commands for managing import plans (plan, apply, commit, cancel), updates help documentation and package exports, and extends the REST API client for import plan operations. The update implements a modular code generation framework with builders for arrays, objects, arguments, and expressions, and introduces a context system for managing variable mappings and file paths. Numerous code generators for Checkly resource types (checks, groups, alert channels, dashboards, status pages, etc.) are added, each capable of generating TypeScript code representations. The constructs system is extended to support references to existing resources, and new tests are included to verify uniqueness and reference behaviors.

Affected Components

  • CLI
  • Create CLI
  • Test
  • Docs
  • Examples
  • Other

Notes for the Reviewer

Resolves #[issue-number]

New Dependency Submission

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2025

Walkthrough

This change introduces a comprehensive import and code generation system for Checkly CLI, enabling users to import existing Checkly resources into their projects. It adds new CLI commands for managing import plans (plan, apply, commit, cancel), updates help documentation and package exports, and extends the REST API client for import plan operations. The update implements a modular code generation framework with builders for arrays, objects, arguments, and expressions, and introduces a context system for managing variable mappings and file paths. Numerous code generators for Checkly resource types (checks, groups, alert channels, dashboards, status pages, etc.) are added, each capable of generating TypeScript code representations. The constructs system is extended to support references to existing resources, and new tests are included to verify uniqueness and reference behaviors.

Changes

File(s) / Path(s) Change Summary
packages/cli/e2e/__tests__/help.spec.ts Added tests for the new import command and updated help output tests to include the import feature.
packages/cli/package.json Added new export for ./util, introduced an "import" topic in the CLI topics section, and added execa, semver, and their types as dependencies.
packages/cli/tsconfig.json Updated TypeScript target from es2019 to es2022.
packages/cli/src/rest/projects.ts Added interfaces and methods to manage import plans (create, list, apply, commit, cancel) in the Projects class, and improved error handling with ProjectNotFoundError.
packages/cli/src/util/index.ts Introduced a secret utility function for environment-based secret retrieval.
packages/cli/src/commands/import/apply.ts
.../cancel.ts
.../commit.ts
.../plan.ts
Implemented new CLI commands for managing import plans: apply, cancel, commit, and plan, with interactive prompts and API integration.
packages/cli/src/constructs/alert-channel.ts
.../check-group.ts
.../check.ts
.../private-location.ts
Added and documented reference classes (Ref) for existing resources; updated property types to accept references.
packages/cli/src/constructs/telegram-alert-channel.ts
.../incidentio-alert-channel.ts
.../msteams-alert-channel.ts
Extended alert channel constructs to support custom payload templates and default payloads.
packages/cli/src/constructs/project.ts Modified resource addition logic to allow multiple uses of the same non-member resource by physical ID.
packages/cli/src/constructs/__tests__/alert-channel.spec.ts
.../check-group.spec.ts
.../private-location.spec.ts
Added tests to verify uniqueness constraints and reference behaviors for constructs.
packages/cli/src/constructs/alert-channel-codegen.ts
.../alert-channel-subscription-codegen.ts
.../alert-escalation-policy-codegen.ts
.../api-check-codegen.ts
.../browser-check-codegen.ts
.../check-codegen.ts
.../check-group-codegen.ts
.../construct-codegen.ts
.../dashboard-codegen.ts
.../email-alert-channel-codegen.ts
.../frequency-codegen.ts
.../heartbeat-check-codegen.ts
.../incidentio-alert-channel-codegen.ts
.../internal/assertion-codegen.ts
.../key-value-pair-codegen.ts
.../maintenance-window-codegen.ts
.../msteams-alert-channel-codegen.ts
.../multi-step-check-codegen.ts
.../opsgenie-alert-channel-codegen.ts
.../pagerduty-alert-channel-codegen.ts
.../phone-call-alert-channel-codegen.ts
.../playwright-config-codegen.ts
.../private-location-check-assignment-codegen.ts
.../private-location-codegen.ts
.../private-location-group-assignment-codegen.ts
.../ref-codegen.ts
.../retry-strategy-codegen.ts
.../slack-alert-channel-codegen.ts
.../sms-alert-channel-codegen.ts
.../status-page-codegen.ts
.../status-page-service-codegen.ts
.../tcp-check-codegen.ts
.../telegram-alert-channel-codegen.ts
.../webhook-alert-channel-codegen.ts
Added code generator classes and functions for all Checkly resource types, supporting both code preparation and generation for import/export workflows.
packages/cli/src/constructs/internal/codegen/codegen.ts
.../context.ts
.../index.ts
Introduced an abstract codegen class, a context system for variable and file management, and centralized exports for codegen utilities.
packages/cli/src/sourcegen/args.ts
.../argsbuilder.ts
.../array.ts
.../arraybuilder.ts
.../boolean.ts
.../case.ts
.../decl.ts
.../declbuilder.ts
.../expr.ts
.../exprbuilder.ts
.../identifier.ts
.../index.ts
.../null.ts
.../number.ts
.../object.ts
.../objectbuilder.ts
.../output.ts
.../program.ts
.../string.ts
.../undefined.ts
.../unknown.ts
Introduced a modular source generation system with builder patterns for arguments, arrays, objects, expressions, identifiers, declarations, and output management.
packages/cli/src/sourcegen/__tests__/case.spec.ts Added tests for the string casing utility functions to verify correct transformation to various case styles.
packages/cli/src/constructs/playwright-config.ts Removed unused import of CheckProps.
packages/cli/src/constructs/telegram-alert-channel.ts
.../incidentio-alert-channel.ts
.../msteams-alert-channel.ts
Added optional payload property and default payload constant; constructor uses provided or default payload for template.
packages/cli/src/constructs/alert-channel.ts Added default value documentation for alert channel props; renamed AlertChannelWrapper to AlertChannelRef and updated fromId accordingly.
packages/cli/src/constructs/check-group.ts Added CheckGroupRef class for referencing existing check groups; updated fromId method and property types to accept refs.
packages/cli/src/constructs/check.ts Updated property types in CheckProps and Check to accept PrivateLocationRef, CheckGroupRef, and AlertChannelRef alongside existing types.
packages/cli/src/constructs/private-location.ts Renamed PrivateLocationWrapper to PrivateLocationRef with documentation; updated fromId method accordingly.
packages/cli/src/constructs/status-page-service.ts Added StatusPageServiceRef class for referencing existing status page services; added static fromId method.
packages/cli/src/helpers/wrap.ts Added a utility function to wrap text content to a specified line length with optional prefix and trimming.
packages/cli/src/services/checkly-config-codegen.ts Added codegen for Checkly configuration files supporting nested defaults and references.
packages/cli/src/services/checkly-config-loader.ts Added ConfigNotFoundError for missing config files and updated error handling accordingly.
packages/cli/src/services/check-parser/package-files/__tests__/package-json-file.spec.ts Added tests for package.json devDependencies upsert method covering insertion and version updates.
packages/cli/src/services/check-parser/package-files/json-source-file.ts Changed constructor visibility from private to public in JsonSourceFile class.
packages/cli/src/services/check-parser/package-files/package-json-file.ts Extended PackageJsonFile with dependency management, version-aware updates, and serialization.
packages/cli/src/services/check-parser/package-files/resolver.ts Refactored directory walking logic with walkUp utility; added method to load single package.json file.
packages/cli/src/services/check-parser/package-files/source-file.ts Changed constructor visibility from private to public in SourceFile class.
packages/cli/src/constructs/internal/codegen/snippet.ts Added snippet validation, legacy handlebars detection, dependency parsing, and related error handling.
packages/cli/src/services/check-parser/parser.ts Extended TypeScript AST visitor to detect require() calls for dependency parsing.
packages/cli/src/constructs/internal/codegen/safety.ts Added ImportSafetyViolation error class for import safety enforcement.
packages/cli/src/sourcegen/comment.ts Added comment classes and utilities for block, line, and doc comments with rendering support.
packages/cli/src/sourcegen/value.ts Added abstract Value class defining render interface for sourcegen values.
packages/cli/src/constructs/__tests__/status-page-service.spec.ts Added tests verifying uniqueness and reference behavior for StatusPageService.
packages/cli/src/constructs/status-page-service.ts Added StatusPageServiceRef class and static fromId method.
packages/cli/src/helpers/command-style.ts Added CommandStyle class for styled CLI output with success, info, warning, error, and fatal methods, integrating with oclif ux actions.
packages/cli/src/commands/baseCommand.ts Added style property to BaseCommand initialized with CommandStyle.
packages/cli/src/helpers/wrap.ts Added wrap function to format text with line length, prefix, and trimming options.

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sorccu sorccu marked this pull request as ready for review March 25, 2025 10:28
@sorccu sorccu changed the title feat: add Construct -> AST-like source code generation for all constructs [sc-23506] feat: new import command to import your existing Checkly resources to the CLI [sc-23506] Mar 25, 2025
Copy link
Contributor

@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: 6

🧹 Nitpick comments (38)
packages/cli/src/sourcegen/undefined.ts (1)

4-8: Implementation looks good.

The UndefinedValue class correctly implements the rendering of the JavaScript undefined literal. The class follows a clean pattern by extending the base Value class and implementing the required render method.

Consider adding a JSDoc comment to document the purpose of this class for better code maintainability.

packages/cli/src/sourcegen/null.ts (1)

4-8: Implementation looks good.

The NullValue class correctly implements the rendering of the JavaScript null literal. It follows the same clean pattern as the other value classes by extending the base Value class and implementing the required render method.

Consider adding a JSDoc comment to document the purpose of this class for better code maintainability and consistency with other value classes.

packages/cli/src/sourcegen/boolean.ts (1)

4-15: Implementation looks good.

The BooleanValue class correctly implements the rendering of boolean values. It properly:

  1. Stores the boolean value as a property
  2. Calls super() in the constructor before accessing 'this'
  3. Uses toString() to convert the boolean to a string representation

This implementation is consistent with the value class pattern in this codebase.

Consider adding a JSDoc comment to document the purpose of this class for better code maintainability.

packages/cli/src/sourcegen/number.ts (1)

4-15: Implementation looks good with minor considerations.

The NumberValue class correctly implements the rendering of number values, following the same pattern as the other value classes. It properly:

  1. Stores the number value as a property
  2. Calls super() in the constructor
  3. Uses toString() to convert the number to a string representation

Consider handling special number cases like NaN, Infinity, or very large numbers that might produce unexpected string representations. You might want to add special handling for these cases if they need to be represented in a specific format in the generated code.

Also, consider adding a JSDoc comment to document the purpose of this class for better code maintainability.

packages/cli/src/constructs/ref-codegen.ts (1)

4-13: Clean implementation of reference value generation.

This function effectively generates the AST for a Ref.from(...) expression, adding the necessary import and building the expression tree. This approach will work well for code generation use cases.

Consider adding a brief documentation comment describing the expected output format of this function (e.g., Ref.from('ref-id')). This would improve clarity for maintainers unfamiliar with this part of the codebase.

+/**
+ * Creates an expression representing a reference lookup using Ref.from('ref')
+ * @param program - The program to add imports to
+ * @param ref - The reference to generate a value for
+ * @returns A Value representing the Ref.from('ref') expression
+ */
 export function valueForRef (program: Program, ref: Ref): Value {
packages/cli/src/sourcegen/array.ts (1)

21-25: Consider handling trailing commas more explicitly.

Currently, the render method adds a comma after each array element, including the last one. While trailing commas are valid in modern JavaScript/TypeScript, you might want to consider making this behavior configurable or more explicit for better clarity.

  render (output: Output): void {
    if (this.value.length === 0) {
      output.append('[]')
      return
    }

    output.append('[')
    output.increaseIndent()

-    for (const value of this.value) {
+    for (let i = 0; i < this.value.length; i++) {
+      const value = this.value[i];
      output.endLine()
      value.render(output)
-      output.append(',')
+      if (i < this.value.length - 1) {
+        output.append(',')
+      }
    }

    output.decreaseIndent()
    output.endLine()
    output.append(']')
  }
packages/cli/src/sourcegen/object.ts (1)

26-33: Consider handling trailing commas more explicitly for object properties.

Similar to the array implementation, the render method adds a comma after each property, including the last one. While trailing commas are valid in modern JavaScript/TypeScript, you might want to consider making this behavior configurable or more explicit for consistency and clarity.

  render (output: Output): void {
    output.append('{')
    output.increaseIndent()

-    for (const { name, value } of this.value) {
+    for (let i = 0; i < this.value.length; i++) {
+      const { name, value } = this.value[i];
      output.endLine()
      output.append(name)
      output.append(':')
      output.cosmeticWhitespace()
      value.render(output)
-      output.append(',')
+      if (i < this.value.length - 1) {
+        output.append(',')
+      }
    }

    output.decreaseIndent()
    output.endLine()
    output.append('}')
  }
packages/cli/src/constructs/internal/codegen/codegen.ts (1)

11-13: Consider documenting the purpose of the prepare method

The prepare method is currently a no-op, but it might be intended for subclasses to override. Adding a comment explaining its purpose and when/how subclasses should use it would improve clarity.

 prepare (logicalId: string, resource: T, context: Context): void {
-    // No-op
+    // No-op by default. Subclasses can override this method to perform
+    // setup or validation before code generation.
 }
packages/cli/src/sourcegen/string.ts (1)

19-22: Clarify the comment about using inspect()

The comment notes that using inspect() is "not ideal" but doesn't explain why or suggest a better approach. Consider adding more context to guide future improvements.

-  // Not ideal but for now inspect() works.
+  // Not ideal because inspect() includes Node.js-specific formatting that may change 
+  // between versions, but it works for now. A more robust solution would be to implement
+  // proper string escaping for JavaScript/TypeScript syntax.
  return inspect(value)
packages/cli/src/sourcegen/unknown.ts (1)

19-26: Consider adding a default case to handle all types

The switch statement handles string, boolean, and number primitives, but doesn't explicitly handle other types like Symbol, BigInt, or functions. Adding a default case would make it more robust.

 switch (typeof value) {
   case 'string':
     return new StringValue(value)
   case 'boolean':
     return new BooleanValue(value)
   case 'number':
     return new NumberValue(value)
+   default:
+     // For symbols, functions, bigints or other types we can't directly represent
+     // Convert to string representation as a fallback
+     return new StringValue(String(value))
 }
packages/cli/src/sourcegen/program.ts (2)

11-17: Simplify import method by removing redundant optional chaining

Since you've already checked if the map has the key with this.#imports.has(from), the optional chaining in this.#imports.get(from)?.add(type) is unnecessary.

 import (type: string, from: string) {
   if (this.#imports.has(from)) {
-    this.#imports.get(from)?.add(type)
+    this.#imports.get(from)!.add(type)
   } else {
     this.#imports.set(from, new Set([type]))
   }
 }

23-45: Consider refactoring the import rendering logic for better readability

The complex rendering logic for imports could be extracted into a separate method to improve readability and maintainability.

 render (output: Output): void {
   if (this.#imports.size > 0) {
-    for (const [pkg, types] of this.#imports.entries()) {
-      output.append('import')
-      output.cosmeticWhitespace()
-      output.append('{')
-      let first = true
-      for (const type of Array.from(types).sort()) {
-        if (!first) {
-          output.append(',')
-        }
-        output.cosmeticWhitespace()
-        first = false
-        output.append(type)
-      }
-      output.cosmeticWhitespace()
-      output.append('}')
-      output.significantWhitespace()
-      output.append('from')
-      output.significantWhitespace()
-      output.append(`'${pkg}'`)
-    }
+    this.#renderImports(output)
   }

   // ...rest of method...
 }
+
+ #renderImports(output: Output): void {
+   for (const [pkg, types] of this.#imports.entries()) {
+     output.append('import')
+     output.cosmeticWhitespace()
+     output.append('{')
+     let first = true
+     for (const type of Array.from(types).sort()) {
+       if (!first) {
+         output.append(',')
+       }
+       output.cosmeticWhitespace()
+       first = false
+       output.append(type)
+     }
+     output.cosmeticWhitespace()
+     output.append('}')
+     output.significantWhitespace()
+     output.append('from')
+     output.significantWhitespace()
+     output.append(`'${pkg}'`)
+   }
+ }
packages/cli/src/constructs/browser-check-codegen.ts (1)

25-32: TODO comment needs a more detailed plan.

The TODO comment does not provide enough context about what exactly needs to be separated into a file and why. This makes it difficult for future developers to understand the intention.

Consider replacing the comment with a more detailed explanation:

- // TODO separate file
+ // TODO: Extract script content to a separate file in the repository
+ // and reference it via the entrypoint path for better maintainability
packages/cli/src/commands/import/commit.ts (2)

70-75: Misleading plan title for multiple plans.

The plan title is hardcoded as "Plan #1" which is confusing when there are multiple plans being displayed in the list.

Update the title to include the plan's index or ID:

- const choices: prompts.Choice[] = plans.map(plan => ({
-   title: `Plan #1 from ${new Date(plan.createdAt)}`,
+ const choices: prompts.Choice[] = plans.map((plan, index) => ({
+   title: `Plan #${index + 1} from ${new Date(plan.createdAt)}`,
    value: plan.id,
    description: `ID: ${plan.id}`,
  }))

52-65: Error handling could be improved with more specific error messages.

The current error handling just rethrows the error without providing context about what was being attempted.

Consider adding more context to the error:

  try {
    await api.projects.commitImportPlan(plan.id)

    if (this.fancy) {
      ux.action.stop('✅ ')
    }
  } catch (err) {
    if (this.fancy) {
      ux.action.stop('❌')
    }

-   throw err
+   throw new Error(`Failed to commit plan ${plan.id}: ${err.message}`, { cause: err })
  }
packages/cli/src/commands/import/cancel.ts (2)

66-71: Misleading plan title for multiple plans.

Similar to the commit command, the plan title is hardcoded as "Plan #1" which is confusing when there are multiple plans being displayed in the list.

Update the title to include the plan's index or ID:

- const choices: prompts.Choice[] = plans.map(plan => ({
-   title: `Plan #1 from ${new Date(plan.createdAt)}`,
+ const choices: prompts.Choice[] = plans.map((plan, index) => ({
+   title: `Plan #${index + 1} from ${new Date(plan.createdAt)}`,
    value: plan.id,
    description: `ID: ${plan.id}`,
  }))

47-63: Improved error handling would provide better context.

When an error occurs during the cancellation of a plan, the current error handling just rethrows the error without context about which plan failed.

Consider modifying the error handling:

  try {
    for (const plan of plans) {
-     await api.projects.cancelImportPlan(plan.id)
-     this.log(`${logSymbols.success} Canceled plan ${plan.id}`)
+     try {
+       await api.projects.cancelImportPlan(plan.id)
+       this.log(`${logSymbols.success} Canceled plan ${plan.id}`)
+     } catch (err) {
+       throw new Error(`Failed to cancel plan ${plan.id}: ${err.message}`, { cause: err })
+     }
    }

    if (this.fancy) {
      ux.action.stop('✅ ')
    }
  } catch (err) {
    if (this.fancy) {
      ux.action.stop('❌')
    }

    throw err
  }
packages/cli/src/constructs/dashboard-codegen.ts (1)

119-121: TODO comment about file separation needs more detail.

The TODO comment is vague and doesn't provide specifics about when or why this refactoring should occur.

Consider adding more context:

-            // TODO: Consider creating a separate file with the content
-            // and referring to it via entrypoint instead.
+            // TODO: For large CSS content, consider creating a separate .css file
+            // in the repository and referring to it via entrypoint instead to improve
+            // readability and enable proper syntax highlighting.
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (2)

12-17: Consider making the API key extraction more robust

The regex pattern assumes a specific URL format from Telegram's API. If their URL structure changes in the future, this extraction might fail.

-function apiKeyFromUrl (url: string): string | undefined {
-  const match = /https:\/\/api.telegram.org\/bot([^/]+)\/sendMessage/.exec(url)
-  if (match) {
-    return match[1]
-  }
-}
+function apiKeyFromUrl (url: string): string | undefined {
+  // Extract token between /bot and next slash from Telegram API URLs
+  const match = /api\.telegram\.org\/bot([^/]+)/.exec(url)
+  if (match) {
+    return match[1]
+  }
+}

19-24: Consider adding validation for chat ID format

The current implementation extracts any numeric string as a chat ID. Consider validating that it's a valid Telegram chat ID format.

 function chatIdFromTemplate (template: string): string | undefined {
   const match = /chatId=(-?[0-9]+)/.exec(template)
   if (match) {
+    // Telegram chat IDs are numeric values and can be negative for groups
     return match[1]
   }
 }
packages/cli/src/constructs/maintenance-window-codegen.ts (1)

16-64: Consider validating date strings or adding time-zone awareness.

Since the code instantiates Date objects based on unverified string inputs, it may be beneficial to inspect or validate these date strings. This could prevent unexpected runtime errors when the input is invalid or incorrectly formatted. Additionally, ensuring proper time-zone handling yields more predictable outcomes in different environments.

Do you want me to propose a quick solution or add optional date parsing checks?

packages/cli/src/constructs/multi-step-check-codegen.ts (1)

16-41: Follow up on the TODO in the script handling.

At line 25, there's a // TODO separate file comment. Separating script logic into its own module or file can promote cleaner organization and improved maintainability.

Do you want me to open a tracking issue or propose a refactor for extracting the script logic?

packages/cli/src/sourcegen/decl.ts (1)

22-24: Consider expanding VariableDeclarationOptions.

Right now, it's limited to a single mutable flag. In the future, additional styling or scoping options (e.g., const enums) might be warranted for broader use.

packages/cli/src/sourcegen/output.ts (1)

40-85: Consider adding validation to decreaseIndent method.

While the Output class implementation is generally good, the decreaseIndent method doesn't check whether the level would become negative. Although this might not be an issue in the current implementation if calls to decreaseIndent are always balanced with increaseIndent, adding validation would make the code more robust.

Also, the methods significantWhitespace and cosmeticWhitespace currently do the same thing - they both append a single space. This suggests they might be intended to be differentiated in the future.

decreaseIndent () {
+  if (this.#level > 0) {
    this.#level -= 1
+  } else {
+    console.warn('Attempted to decrease indent below 0')
+  }
}
packages/cli/src/commands/import/apply.ts (1)

22-60: Consider adding validation for configFilename.

The run method implementation is good, but it doesn't validate whether configFilename is defined. If a user doesn't provide the --config flag, this could lead to errors in the subsequent operations.

Also, there's no handling for the case where no unapplied plans are found. Consider providing a clear message to the user in this scenario.

async run (): Promise<void> {
  const { flags } = await this.parse(ImportApplyCommand)
  const {
    config: configFilename,
  } = flags

+  if (!configFilename) {
+    this.error('No configuration file specified. Use --config flag to specify a configuration file.')
+    return
+  }

  const { configDirectory, configFilenames } = splitConfigFilePath(configFilename)
  // Rest of the method...

  const { data: unappliedPlans } = await api.projects.findImportPlans(logicalId, {
    onlyUnapplied: true,
  })

+  if (unappliedPlans.length === 0) {
+    this.log('No unapplied import plans found.')
+    return
+  }

  const plan = await this.#selectPlan(unappliedPlans)
  // Rest of the method...
}
packages/cli/src/constructs/api-check-codegen.ts (2)

110-123: Handling setup scripts from string content or file paths.
Defining separate objects for localSetupScript and setupScriptPath is fine. However, if both are provided, we’ll end up with two setupScript objects in the final output. It might be beneficial to enforce a mutual exclusion or define a preference.

Would you like help adding a fallback or merging these properties to avoid potential conflicts?


125-138: Symmetrical teardown script logic.
Mirroring the approach from the setup script is consistent. Keep in mind the same mutual-exclusion considerations if both localTearDownScript and tearDownScriptPath are set.

packages/cli/src/constructs/check-codegen.ts (1)

164-181: Lint warnings about returning a value from a void function.
The switch statements immediately return calls to other .gencode() methods. If these are typed to return void, removing return would align better with certain lint rules:

- return this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+ this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)

And similarly for lines 171, 173, 175, and 177.

🧰 Tools
🪛 Biome (1.9.4)

[error] 169-169: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 171-171: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 173-173: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 175-175: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 177-177: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

packages/cli/src/commands/import/plan.ts (3)

52-82: Handle additional HTTP error codes gracefully.
Currently, only 404 status codes have a custom error message. Consider adding user-friendly messages for other common errors such as 401 or 403 to improve the developer experience.


86-129: Allow user-specified output paths for generated code.
The generated file path is currently hardcoded. Offering a user-configurable file/directory path can enhance flexibility.

Would you like help implementing a solution that accepts an output path?


130-223: Improve partial cancellation flow for existing plans.
When canceling multiple plans, an error in one plan halts the entire cancellation loop. Consider allowing partial cancellation or a rollback mechanism for unprocessed plans.

packages/cli/src/constructs/tcp-check-codegen.ts (1)

7-12: Validate response time fields.
Consider enforcing a logical constraint (e.g., degradedResponseTime <= maxResponseTime) to avoid confusion or invalid configurations.

packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)

13-25: API key extraction could be improved with early returns

The apiKeyFromHeaders function extracts the API key from the Authorization header, but the implementation could be simplified using early returns for better readability.

function apiKeyFromHeaders (headers: HttpHeader[]): string | undefined {
  for (const header of headers) {
-    if (header.key.toLocaleLowerCase() !== 'authorization') {
-      continue
-    }
-
-    if (!header.value.startsWith('Bearer ')) {
-      continue
-    }
-
-    return header.value.replace('Bearer ', '')
+    if (header.key.toLocaleLowerCase() === 'authorization' && header.value.startsWith('Bearer ')) {
+      return header.value.replace('Bearer ', '')
+    }
  }
+  return undefined
}
packages/cli/src/constructs/construct-codegen.ts (1)

25-29: Resource interface is minimal yet effective.
payload: any does reduce type safety. In future, consider parameterizing the interface or introducing type refinements per resource type.

-interface Resource {
-  type: ResourceType
-  logicalId: string
-  payload: any
-}
+interface Resource<TPayload = unknown> {
+  type: ResourceType
+  logicalId: string
+  payload: TPayload
+}
packages/cli/src/rest/projects.ts (1)

85-92: Minor improvement for filtering logic
The usage of optional parameters for onlyUnapplied and onlyUncommitted is correct. Consider whether the server should handle contradictory filters or if you want to guard them here.

packages/cli/src/sourcegen/expr.ts (1)

42-57: Consider bracket notation for invalid identifiers
The comment at line 55 hints at handling property names that require bracket syntax. Consider adding logic to detect such cases and use bracket notation when needed.

packages/cli/src/constructs/check-group-codegen.ts (1)

43-227: Consider better error handling for context lookups
The function currently swallows errors when looking up private locations or alert channels (lines 72–77, 110–115). Logging or graceful fallback might be preferable. Also consider splitting this function into smaller parts for easier maintainability.

packages/cli/src/constructs/internal/codegen/context.ts (1)

3-4: Consider adding a more descriptive error message.
Throwing a bare MissingContextVariableMappingError can make debugging harder. Including the requested ID or a custom message aids in tracing the missing mapping.

-export class MissingContextVariableMappingError extends Error {}
+export class MissingContextVariableMappingError extends Error {
+  constructor(message?: string) {
+    super(message || 'Context variable mapping not found.')
+    this.name = 'MissingContextVariableMappingError'
+  }
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04de119 and 8e0a955.

📒 Files selected for processing (65)
  • packages/cli/e2e/__tests__/help.spec.ts (2 hunks)
  • packages/cli/package.json (1 hunks)
  • packages/cli/src/commands/import/apply.ts (1 hunks)
  • packages/cli/src/commands/import/cancel.ts (1 hunks)
  • packages/cli/src/commands/import/commit.ts (1 hunks)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group.ts (1 hunks)
  • packages/cli/src/constructs/construct-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/email-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/frequency-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/assertion-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/index.ts (1 hunks)
  • packages/cli/src/constructs/key-value-pair-codegen.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config.ts (0 hunks)
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/ref-codegen.ts (1 hunks)
  • packages/cli/src/constructs/retry-strategy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/rest/projects.ts (3 hunks)
  • packages/cli/src/sourcegen/args.ts (1 hunks)
  • packages/cli/src/sourcegen/argsbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/array.ts (1 hunks)
  • packages/cli/src/sourcegen/arraybuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/boolean.ts (1 hunks)
  • packages/cli/src/sourcegen/decl.ts (1 hunks)
  • packages/cli/src/sourcegen/declbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/expr.ts (1 hunks)
  • packages/cli/src/sourcegen/exprbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/identifier.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
  • packages/cli/src/sourcegen/null.ts (1 hunks)
  • packages/cli/src/sourcegen/number.ts (1 hunks)
  • packages/cli/src/sourcegen/object.ts (1 hunks)
  • packages/cli/src/sourcegen/objectbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/output.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
  • packages/cli/src/sourcegen/string.ts (1 hunks)
  • packages/cli/src/sourcegen/undefined.ts (1 hunks)
  • packages/cli/src/sourcegen/unknown.ts (1 hunks)
  • packages/cli/src/sourcegen/value.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/cli/src/constructs/playwright-config.ts
🧰 Additional context used
🧬 Code Definitions (42)
packages/cli/src/sourcegen/undefined.ts (2)
packages/cli/src/sourcegen/index.ts (3)
  • UndefinedValue (31-31)
  • Value (33-33)
  • Output (28-28)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/sourcegen/null.ts (2)
packages/cli/src/sourcegen/index.ts (3)
  • NullValue (24-24)
  • Value (33-33)
  • Output (28-28)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/sourcegen/boolean.ts (2)
packages/cli/src/sourcegen/index.ts (3)
  • BooleanValue (5-5)
  • Value (33-33)
  • Output (28-28)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/e2e/__tests__/help.spec.ts (1)
packages/cli/e2e/run-checkly.ts (1)
  • runChecklyCli (7-77)
packages/cli/src/sourcegen/value.ts (1)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/sourcegen/array.ts (2)
packages/cli/src/sourcegen/index.ts (3)
  • ArrayValue (3-3)
  • Value (33-33)
  • Output (28-28)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/sourcegen/object.ts (4)
packages/cli/src/sourcegen/index.ts (3)
  • Value (33-33)
  • ObjectValue (26-26)
  • Output (28-28)
packages/cli/src/sourcegen/arraybuilder.ts (1)
  • value (62-65)
packages/cli/src/sourcegen/objectbuilder.ts (1)
  • value (57-60)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/sourcegen/unknown.ts (7)
packages/cli/src/sourcegen/arraybuilder.ts (4)
  • value (62-65)
  • array (12-16)
  • array (50-52)
  • object (54-56)
packages/cli/src/sourcegen/objectbuilder.ts (4)
  • value (57-60)
  • array (45-47)
  • object (12-16)
  • object (49-51)
packages/cli/src/sourcegen/null.ts (1)
  • NullValue (4-8)
packages/cli/src/sourcegen/undefined.ts (1)
  • UndefinedValue (4-8)
packages/cli/src/sourcegen/string.ts (1)
  • StringValue (6-17)
packages/cli/src/sourcegen/boolean.ts (1)
  • BooleanValue (4-15)
packages/cli/src/sourcegen/number.ts (1)
  • NumberValue (4-15)
packages/cli/src/constructs/email-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/multi-step-check-codegen.ts (4)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (15-33)
  • buildCheckProps (35-144)
packages/cli/src/constructs/playwright-config-codegen.ts (2)
  • PlaywrightConfigResource (4-4)
  • valueForPlaywrightConfig (6-8)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/private-location-check-assignment-codegen.ts (2)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/sourcegen/output.ts (3)
packages/cli/src/sourcegen/arraybuilder.ts (1)
  • value (62-65)
packages/cli/src/sourcegen/objectbuilder.ts (1)
  • value (57-60)
packages/cli/src/sourcegen/index.ts (1)
  • Output (28-28)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (2)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/browser-check-codegen.ts (4)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (15-33)
  • buildCheckProps (35-144)
packages/cli/src/constructs/playwright-config-codegen.ts (2)
  • PlaywrightConfigResource (4-4)
  • valueForPlaywrightConfig (6-8)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/sourcegen/identifier.ts (4)
packages/cli/src/sourcegen/index.ts (4)
  • IdentifierValue (23-23)
  • Value (33-33)
  • Output (28-28)
  • ident (23-23)
packages/cli/src/sourcegen/arraybuilder.ts (2)
  • value (62-65)
  • ident (46-48)
packages/cli/src/sourcegen/objectbuilder.ts (2)
  • value (57-60)
  • ident (41-43)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/constructs/api-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (15-33)
  • buildCheckProps (35-144)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/sourcegen/string.ts (4)
packages/cli/src/sourcegen/index.ts (3)
  • StringValue (30-30)
  • Value (33-33)
  • Output (28-28)
packages/cli/src/sourcegen/arraybuilder.ts (1)
  • value (62-65)
packages/cli/src/sourcegen/objectbuilder.ts (1)
  • value (57-60)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/constructs/tcp-check-codegen.ts (4)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (15-33)
  • buildCheckProps (35-144)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForGeneralAssertion (45-146)
  • valueForNumericAssertion (4-43)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/dashboard-codegen.ts (2)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/sourcegen/declbuilder.ts (2)
packages/cli/src/sourcegen/index.ts (6)
  • decl (11-11)
  • IdentifierValue (23-23)
  • DeclarationBuilder (12-12)
  • Value (33-33)
  • VariableDeclaration (7-7)
  • ExportDeclaration (8-8)
packages/cli/src/sourcegen/decl.ts (4)
  • IdentifierDeclaration (9-20)
  • VariableDeclarationOptions (22-24)
  • VariableDeclaration (26-52)
  • ExportDeclaration (54-66)
packages/cli/src/constructs/construct-codegen.ts (12)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • AlertChannelCodegen (53-101)
packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1)
  • AlertChannelSubscriptionCodegen (9-24)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckCodegen (146-182)
packages/cli/src/constructs/check-group-codegen.ts (1)
  • CheckGroupCodegen (231-252)
packages/cli/src/constructs/dashboard-codegen.ts (1)
  • DashboardCodegen (31-140)
packages/cli/src/constructs/maintenance-window-codegen.ts (1)
  • MaintenanceWindowCodegen (16-64)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • PrivateLocationCodegen (14-44)
packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1)
  • PrivateLocationCheckAssignmentCodegen (8-17)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1)
  • PrivateLocationGroupAssignmentCodegen (8-17)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/maintenance-window-codegen.ts (2)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/check-codegen.ts (6)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/api-check-codegen.ts (1)
  • ApiCheckResource (8-19)
packages/cli/src/sourcegen/decl.ts (3)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/sourcegen/index.ts (6)
  • Output (28-28)
  • IdentifierValue (23-23)
  • VariableDeclaration (7-7)
  • Value (33-33)
  • ExportDeclaration (8-8)
  • decl (11-11)
packages/cli/src/sourcegen/declbuilder.ts (1)
  • decl (5-9)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/private-location-codegen.ts (2)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (3)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/sourcegen/expr.ts (3)
packages/cli/src/sourcegen/index.ts (10)
  • ExpressionValue (15-15)
  • Value (33-33)
  • NewExpressionValue (16-16)
  • ArgumentsValue (1-1)
  • args (2-2)
  • Output (28-28)
  • CallExpressionValue (17-17)
  • MemberExpressionValue (18-18)
  • BinaryExpressionValue (19-19)
  • UnaryExpressionValue (20-20)
packages/cli/src/sourcegen/args.ts (1)
  • ArgumentsValue (4-27)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/constructs/check-group-codegen.ts (7)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/api-check-codegen.ts (1)
  • valueForAssertion (21-38)
packages/cli/src/constructs/heartbeat-check-codegen.ts (3)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (15-33)
  • buildCheckProps (35-144)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (7)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)
  • IncidentioAlertChannelCodegen (29-62)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)
  • MSTeamsAlertChannelCodegen (14-40)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)
  • TelegramAlertChannelCodegen (28-67)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/sourcegen/argsbuilder.ts (2)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/args.ts (1)
  • ArgumentsValue (4-27)
packages/cli/src/sourcegen/arraybuilder.ts (9)
packages/cli/src/sourcegen/objectbuilder.ts (7)
  • array (45-47)
  • build (62-64)
  • value (57-60)
  • ObjectValueBuilder (18-65)
  • object (12-16)
  • object (49-51)
  • expr (53-55)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/array.ts (1)
  • ArrayValue (4-31)
packages/cli/src/sourcegen/string.ts (1)
  • StringValue (6-17)
packages/cli/src/sourcegen/boolean.ts (1)
  • BooleanValue (4-15)
packages/cli/src/sourcegen/number.ts (1)
  • NumberValue (4-15)
packages/cli/src/sourcegen/null.ts (1)
  • NullValue (4-8)
packages/cli/src/sourcegen/undefined.ts (1)
  • UndefinedValue (4-8)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (4-15)
packages/cli/src/sourcegen/objectbuilder.ts (9)
packages/cli/src/sourcegen/arraybuilder.ts (7)
  • object (54-56)
  • build (71-73)
  • value (62-65)
  • ArrayValueBuilder (18-74)
  • array (12-16)
  • array (50-52)
  • expr (58-60)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/object.ts (2)
  • ObjectProperty (4-12)
  • ObjectValue (14-39)
packages/cli/src/sourcegen/string.ts (1)
  • StringValue (6-17)
packages/cli/src/sourcegen/boolean.ts (1)
  • BooleanValue (4-15)
packages/cli/src/sourcegen/number.ts (1)
  • NumberValue (4-15)
packages/cli/src/sourcegen/null.ts (1)
  • NullValue (4-8)
packages/cli/src/sourcegen/undefined.ts (1)
  • UndefinedValue (4-8)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (4-15)
🪛 Biome (1.9.4)
packages/cli/src/constructs/check-codegen.ts

[error] 169-169: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 171-171: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 173-173: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 175-175: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 177-177: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

packages/cli/src/constructs/webhook-alert-channel-codegen.ts

[error] 102-102: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 114-114: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

🔇 Additional comments (158)
packages/cli/src/sourcegen/value.ts (1)

3-5: Well-designed base class for value type hierarchy.

The abstract Value class establishes a clean, polymorphic interface through the render method that all subclasses must implement. This approach provides flexibility while ensuring consistent rendering behavior throughout the source generation system.

packages/cli/src/constructs/internal/codegen/index.ts (1)

1-2: Follows standard module export pattern.

This index file efficiently re-exports classes from their respective modules, creating a clean API surface and simplifying imports throughout the codebase. This is a good practice for maintainable TypeScript modules.

packages/cli/src/sourcegen/args.ts (1)

4-27: Clean implementation of arguments value rendering.

The ArgumentsValue implementation correctly extends the Value class and provides a well-structured render method. The code properly handles parentheses, comma separation, and whitespace between arguments, including the edge case of the first item.

packages/cli/src/constructs/playwright-config-codegen.ts (1)

1-8: Clean and focused implementation of a Playwright config transformer.

This code aligns with the source code generation pattern, providing a straightforward way to transform Playwright configurations into the AST-like representation required by the sourcegen system. The implementation is minimal and follows the same pattern used elsewhere in the codebase.

packages/cli/src/constructs/key-value-pair-codegen.ts (1)

4-17: Good implementation of conditional property handling.

The function correctly implements conditional logic for optional properties (locked and secret), only including them when they're defined. This prevents undefined values from appearing in the generated code and follows best practices for optional fields.

packages/cli/src/constructs/check-group.ts (1)

16-17: Import syntax modernization.

The change from import type { X } to import { type X } reflects a more modern TypeScript import style. This doesn't affect functionality but helps standardize the codebase's import syntax.

packages/cli/package.json (1)

63-65: CLI feature addition for importing resources.

The new "import" topic entry in the package.json file properly documents the new import functionality for users. This matches the PR's objective of adding AST-like source code generation capabilities, likely for the purpose of importing existing resources into a project.

packages/cli/src/sourcegen/identifier.ts (1)

1-19: Implementation looks correct and well-structured.

The IdentifierValue class extending Value along with the ident helper function provides a clean implementation for handling identifier values in the source generation process. The code follows good practices with proper type definitions and clear responsibilities.

packages/cli/src/sourcegen/array.ts (1)

1-31: Implementation looks correct and consistent with the source generation pattern.

The ArrayValue class properly extends Value and provides appropriate rendering logic for arrays, with special handling for empty arrays.

packages/cli/e2e/__tests__/help.spec.ts (2)

26-36: Test coverage for the new import command looks good.

The test case properly verifies that the CLI provides appropriate help text for the new import command and its subcommands.


51-52: Additional commands section is correctly updated.

The addition of the import command to the additional commands section ensures that users can discover the new functionality through the main help output.

packages/cli/src/sourcegen/object.ts (1)

1-39: Implementation of ObjectValue looks correct and well-structured.

The ObjectProperty and ObjectValue classes provide a clean implementation for handling object structures in the source generation process.

packages/cli/src/constructs/internal/codegen/codegen.ts (1)

4-16: Well-structured abstract class for code generation

This abstract class serves as a solid foundation for implementing various code generators, with a clear interface for subclasses to follow. The generic type parameter T provides flexibility for different resource types.

packages/cli/src/sourcegen/string.ts (1)

1-23: LGTM! StringValue implementation is clean and follows the Value pattern

The implementation properly extends the Value class and provides appropriate rendering functionality. It follows the same pattern as other Value implementations in the system.

packages/cli/src/sourcegen/unknown.ts (1)

1-41: Well-designed recursive value conversion utility

This function provides a robust way to convert arbitrary JavaScript values into the appropriate Value objects. The recursive handling of arrays and objects is particularly well-implemented.

packages/cli/src/sourcegen/program.ts (1)

1-54: LGTM! Program class provides a good foundation for code generation

The Program class effectively manages imports and code sections, with a clean render method to produce the final output. Overall, this is a well-designed central component for the source generation system.

packages/cli/src/constructs/browser-check-codegen.ts (2)

6-12: Clear and well-structured interface definition.

The BrowserCheckResource interface properly extends CheckResource and defines all necessary properties for browser checks. The typings are appropriate, and optional properties are correctly marked.


16-46: Implementation of the code generation is complete and follows established patterns.

The BrowserCheckCodegen class correctly extends the base Codegen class and implements the gencode method as expected. The method properly imports the necessary construct, builds the program structure, and includes all the required properties. The call to buildCheckProps ensures that all properties from the base CheckResource interface are included.

packages/cli/src/commands/import/commit.ts (1)

12-68: Well-structured implementation of the commit command.

The overall structure of the ImportCommitCommand class is well designed. It extends AuthCommand, defines appropriate flags, and implements a clear workflow for selecting and committing import plans. The use of prompts for user interaction is well implemented, and there's appropriate error handling for the case where a plan ID is missing from the plan map.

packages/cli/src/commands/import/cancel.ts (1)

12-112: Well-designed command implementation with good user experience.

The ImportCancelCommand class is well structured and provides a good user experience with clear options and feedback. The implementation correctly handles cancellation of multiple plans, exiting without changes, and error scenarios. The addition of an "all plans" option is especially useful.

packages/cli/src/constructs/dashboard-codegen.ts (3)

4-27: Comprehensive interface with well-defined properties.

The DashboardResource interface defines a complete set of dashboard properties with appropriate types and optionality markers. The interface is well-organized and should cover all needed dashboard configuration options.


31-139: Clean and consistent implementation of the dashboard code generation.

The DashboardCodegen class follows the established pattern for code generation in this codebase. It properly handles all the properties defined in the interface, checking if each is defined before adding it to the generated code. The use of the builder pattern makes the code structure clear and maintainable.


84-136: Consistent handling of boolean properties.

The code uses !== undefined checks for boolean properties, which is the correct approach since it allows for explicitly set false values to be included in the generated code.

packages/cli/src/constructs/frequency-codegen.ts (1)

1-54: Well-structured implementation for frequency code generation

The implementation cleanly handles both numeric frequency values and Frequency objects, with proper detection of predefined constants. Good use of type safety with the union type FrequencyResource.

packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)

26-67: Well-structured implementation for Telegram alert channel generation

The implementation correctly extracts necessary information from config, handles conditional properties appropriately, and follows the Codegen pattern established in the codebase.

packages/cli/src/constructs/retry-strategy-codegen.ts (3)

39-58: 'FIXED' and 'LINEAR' strategies have identical implementations

Both strategies are using the fixedStrategy builder. This might be intentional but could be confusing without a comment explaining why LINEAR uses fixedStrategy.

Are 'FIXED' and 'LINEAR' retry strategies expected to have identical implementations? If intentional, consider adding a comment explaining this design choice.

    case 'LINEAR':
      return expr(ident('RetryStrategyBuilder'), builder => {
+       // LINEAR strategy uses fixedStrategy internally as they share the same implementation
        builder.member(ident('fixedStrategy'))
        builder.call(builder => {
          builder.object(builder => {
            buildCommonOptions(strategy, builder)
          })
        })
      })

6-38: Well-structured implementation with good handling of edge cases

The implementation correctly handles null/undefined cases and provides a helper function for common options, making the code more maintainable.


59-77: Good error handling for unsupported types

The implementation provides appropriate error handling for unsupported strategy types, which helps with debugging and prevents silent failures.

packages/cli/src/constructs/heartbeat-check-codegen.ts (1)

1-29: Clean implementation of heartbeat check code generation

The implementation correctly extends the Codegen class, properly sets required properties, and reuses code through the buildCheckProps utility. The structure follows the established patterns in the codebase.

packages/cli/src/constructs/maintenance-window-codegen.ts (1)

4-12: Well-structured resource interface.

This interface clearly defines all the necessary fields for maintaining a maintenance window resource in code generation, ensuring a strong contract for future usage.

packages/cli/src/constructs/multi-step-check-codegen.ts (1)

6-11: Extending from CheckResource is a good approach.

Including multi-step specifics on top of a shared base streamlines code generation for checks, reducing duplication.

packages/cli/src/sourcegen/decl.ts (4)

5-7: Proper use of an abstract class.

Having an abstract Declaration base class provides a clean extension point for specialized declarations.


9-20: No immediate concerns with IdentifierDeclaration.

The straightforward rendering of the identifier looks consistent with the rest of the code generation framework.


26-52: Variable declaration logic is clear and succinct.

Using let or const based on a mutable flag cleanly handles different assignment scenarios without introducing unnecessary complexity.


54-66: ExportDeclaration usage is consistent.

Wrapping a declaration with export logic is a neat way to keep declaration rendering separate from export handling.

packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1)

1-17: Clean implementation of the private location group assignment code generation.

The implementation correctly registers private location group assignments in the context and appropriately indicates that there's no code to generate for this resource type. The class extends Codegen with proper typing and follows the established pattern for resource codegen classes.

packages/cli/src/sourcegen/output.ts (2)

1-11: OutputBuffer implementation looks good.

The OutputBuffer class provides a clean way to accumulate string chunks and combine them. The implementation is straightforward and effective.


13-38: OutputLine implementation is well structured.

The OutputLine class properly manages line content and indentation. The collect method correctly handles indentation by repeating spaces based on the level.

packages/cli/src/constructs/alert-escalation-policy-codegen.ts (3)

1-8: Good setup of alert escalation resource type and imports.

The file properly imports necessary components from sourcegen and defines the AlertEscalationResource type.


9-35: Well structured helper function for common arguments.

The appendCommonArguments helper function nicely encapsulates the common configuration options for both escalation types, avoiding code duplication. The function correctly handles undefined checks for the optional properties.


37-65: Comprehensive handling of different escalation types.

The switch statement properly handles the different escalation types with appropriate error handling for unsupported types. The implementation generates the correct expressions based on the escalation type and its properties.

packages/cli/src/commands/import/apply.ts (1)

1-21: Command setup looks good.

The ImportApplyCommand class correctly extends AuthCommand and provides appropriate configuration for the command description and flags.

packages/cli/src/constructs/api-check-codegen.ts (9)

1-7: Imports and basic setup look correct.
No issues stand out here. The usage of Codegen, Context, and other imports is consistent, and the structure follows typical TypeScript conventions.


8-19: Interface design is clear and extensible.
The ApiCheckResource interface cleanly extends CheckResource and adds API-specific fields. The commented-out TODO lines for script dependencies indicate future expansion.


21-38: Robust assertion value generator.
Your switch handles each assertion source thoroughly, and unrecognized sources are rejected with a clear error. This ensures strong type safety and error handling. Great job tying into the existing numeric vs. general assertion logic.


40-42: Constant declaration is straightforward.
Declaring construct as 'ApiCheck' is clear and easy to understand for subsequent usage.


43-73: Well-structured request property builder.
Within gencode, constructing the request object is done via a clear builder pattern. Optional fields like ipFamily, followRedirects, and skipSSL are handled gracefully. The loop for assertions is also intuitive and consistent with your assertion codegen logic.


75-99: Body, headers, and query parameters inclusion is consistent.
Leveraging valueForKeyValuePair to handle headers and query parameters ensures DRY logic. Everything is straightforward in building up these properties.


101-108: Basic auth integration is simple but lacks validation.
While the code currently allows empty Username/Password fields, this might be acceptable depending on your requirements. If you require non-empty credentials, consider adding a quick check or warning.

Do we expect any specific constraints (e.g., non-empty credentials)? If so, verifying this before code generation would prevent error-prone configurations.


140-146: Degraded and max response times handled well.
Using optional checks for resource.degradedResponseTime and resource.maxResponseTime ensures these fields are only set when relevant.


148-149: Seamless integration with shared check props.
Invoking buildCheckProps finalizes the API check resource generation without redundant logic. This indicates a good separation of concerns.

packages/cli/src/constructs/internal/assertion-codegen.ts (2)

4-43: Comprehensive numeric assertion builder.
Your switch statement covers all numeric comparison cases. Parsing the target as an integer prevents unexpected type mismatches. The default case ensures unknown comparisons are rejected early.


45-146: Flexible general assertion builder.
You’ve addressed a wide range of comparison types (like key/value checks, null checks, emptiness checks). The fallback error handling for unknown comparisons is robust. This uniform approach simplifies expansions if new assertions emerge.

packages/cli/src/constructs/private-location-check-assignment-codegen.ts (3)

3-6: Resource interface is minimal and focused.
The PrivateLocationCheckAssignmentResource interface precisely captures the two key fields. This keeps it straightforward for downstream logic.


8-11: Preparation phase registers the assignment.
Using registerPrivateLocationCheckAssignment ensures the context is immediately aware of the relationship between private location and check, which keeps everything in sync.


13-16: No code generation needed for this resource.
Having a no-op gencode is acceptable here, given it’s purely a relational mapping. This is clean and unambiguous.

packages/cli/src/constructs/slack-alert-channel-codegen.ts (3)

5-11: Interface structure looks correct and consistent.
The SlackAlertChannelResource interface cleanly extends AlertChannelResource and mandates url, which is essential for Slack integrations. The inclusion of an optional channel maintains flexibility across different Slack workspaces.


16-18: Registration prefix is consistent with other alert channel codegens.
Using 'slackAlert' as a prefix aligns with the standard naming convention seen in sister classes (e.g., emailAlert). This ensures that variable naming in the context remains coherent and predictable.


20-43: Sufficient usage of shared alert channel properties.
Calling buildAlertChannelProps(builder, resource) guarantees that common alert channel behaviors (like SSL expiry checks) are uniformly applied. This design is consistent with the overall codegen architecture.

packages/cli/src/constructs/email-alert-channel-codegen.ts (3)

5-10: Interface mirrors standard patterns for alert channels.
The EmailAlertChannelResource neatly extends AlertChannelResource with a type and a simple config object. This design follows the pattern established by other alert channel resource interfaces.


15-17: Consistent registration of email alert channels.
Registering the resource with a 'emailAlert' prefix keeps it parallel with Slack and future channels, simplifying the context lookups.


19-36: Proper layering via shared builder logic.
Leveraging buildAlertChannelProps(builder, resource) ensures consistent handling of universal alert channel fields (like recovery/failure flags). The overall code generation approach is coherent and maintainable.

packages/cli/src/constructs/alert-channel-subscription-codegen.ts (3)

3-7: Flexible subscription resource structure.
Allowing both groupId and checkId to be optional ensures that subscriptions can be created for individual checks or entire groups. This design is flexible for different alerting needs.


9-18: Accurate registration logic but consider edge cases.
Registering check and/or group subscriptions in prepare is appropriate. However, if both groupId and checkId are defined, ensure that subscribing an alert channel to both simultaneously is intended and doesn’t cause duplication.

Would you like to confirm that subscribing the same channel to a check and a group is desired, or should we prevent double-subscriptions?


20-23: No generation required.
Leaving gencode empty is valid since no code needs to be generated for mere subscriptions. This approach separates side effects (subscriptions) from code emission.

packages/cli/src/constructs/check-codegen.ts (2)

15-33: Comprehensive check resource interface.
The CheckResource includes a thorough set of optional fields, handling advanced configurations (e.g., frequency, alertSettings, retryStrategy). This design cleanly accommodates multiple check types in one interface.


35-144: Robust property construction with graceful error handling.

  1. The buildCheckProps function systematically covers all check fields.
  2. The try-catch blocks for privateLocationIds and alertChannelIds allow for non-blocking fallback behavior, though silently ignoring errors could mask unexpected issues.

Consider logging or clarifying such errors to avoid confusion in future debugging scenarios.

packages/cli/src/commands/import/plan.ts (1)

18-27: No immediate issues with the command definition.
The class definition correctly sets flags and description.

packages/cli/src/constructs/tcp-check-codegen.ts (2)

14-25: Logic is consistent with existing assertion code.
This function correctly integrates with other assertion-generating utilities.


29-71: Well-structured TCP check code generation.
Using buildCheckProps keeps property handling consistent across different check types.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (2)

5-11: Consider phone number validation for SMS alert channels.
You may want to validate or sanitize the phone number before generating code to prevent errors or logs containing invalid PII.

Would you like a script to check for existing phone number validation code or relevant tests?


20-43: Implementation is consistent with other alert channel codegen classes.
No issues detected in the approach for generating the SMS alert channel.

packages/cli/src/sourcegen/declbuilder.ts (3)

1-4: Well-structured imports

The imports are clean and focused, bringing in only the necessary components from related files.


5-9: Good implementation of the builder pattern

The decl function provides a clean API for creating declarations using a builder pattern. The function signature is clear and the implementation is concise.


11-33: Well-designed builder class with proper encapsulation

The DeclarationBuilder class follows good design principles:

  • Uses private fields (with # prefix) for proper encapsulation
  • Implements a fluent interface by returning this from modifier methods
  • Clear and focused methods that handle specific aspects of declaration building
  • Clean separation of concerns between variable declaration and export functionality
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (3)

6-10: Clean interface extension

The interface properly extends WebhookAlertChannelResource and correctly specifies the webhook type as 'WEBHOOK_MSTEAMS'.


14-18: Consistent registration pattern in prepare method

The prepare method follows the established pattern of registering the alert channel with a descriptive prefix ('teamsAlert'), which helps maintain consistency across different alert channel types.


19-39: Well-structured code generation

The gencode method implements a clean approach to generating code for MS Teams alert channels:

  • Imports the necessary construct
  • Retrieves the context-managed identifier
  • Uses the declaration builder in a consistent manner
  • Correctly includes the required properties (name, url)
  • Reuses the common buildAlertChannelProps function for shared alert properties
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (4)

5-11: Well-defined resource interface

The interface clearly defines the structure for phone call alert channels with appropriate types and property requirements. The optional name property is correctly marked with a question mark.


15-18: Consistent alert channel registration

The prepare method maintains consistency with other alert channel implementations by using a descriptive prefix ('phoneCallAlert') when registering.


32-34: Proper handling of optional properties

The code correctly handles the optional name property with a conditional block, ensuring it's only included in the generated code when present.


20-43: Consistent code generation pattern

The overall code generation follows the established pattern across alert channel types, making the codebase more maintainable and predictable.

packages/cli/src/constructs/private-location-codegen.ts (4)

4-10: Clean resource interface definition

The interface clearly defines all required properties for a private location with appropriate types. Optional properties (icon and proxyUrl) are correctly marked with question marks.


14-17: Simple and clear registration

The prepare method follows a consistent pattern with other codegen classes, registering the private location with its ID.


32-38: Proper handling of multiple optional properties

The code correctly handles both optional properties (icon and proxyUrl) with separate conditional blocks, ensuring they're only included in the generated code when present.


19-43: Consistent code generation implementation

The gencode method maintains the same structure and approach used across other codegen classes, enhancing maintainability through consistent patterns:

  • Imports the necessary construct
  • Retrieves the context-managed identifier
  • Builds declarations with the same pattern
  • Properly handles required and optional properties
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)

1-13: Well-structured interface definition

The OpsgenieAlertChannelResource interface correctly extends AlertChannelResource and includes all the necessary configuration properties for an OpsGenie alert channel. The type is properly defined as a string literal 'OPSGENIE', which ensures type safety when working with different alert channel types.


17-20: Consistent alert channel registration pattern

The prepare method follows the established pattern for alert channel registration, using a descriptive prefix 'opsgenieAlert' which will help generate readable variable names in the output code.


22-44: Well-structured code generation implementation

The gencode method follows a consistent pattern for generating source code for OpsGenie alert channels. The implementation correctly:

  1. Imports the required construct
  2. Looks up the alert channel ID from the context
  3. Extracts the configuration
  4. Generates the appropriate AST nodes using the builder pattern
  5. Includes all required configuration properties
  6. Applies the common alert channel properties

This implementation will produce clean, consistent code for OpsGenie alert channels.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (3)

5-12: Properly defined interface with optional properties

The PagerdutyAlertChannelResource interface is well-structured, correctly extending the base AlertChannelResource and defining the required 'PAGERDUTY' type. The config object properly marks account and serviceName as optional while making serviceKey required.


16-19: Consistent alert channel registration pattern

The prepare method correctly registers the alert channel with the 'pagerdutyAlert' prefix, which maintains consistency with other alert channel implementations.


21-48: Robust code generation with proper handling of optional properties

The gencode method correctly handles both required and optional configuration properties:

  1. It only includes account and serviceName when they are defined
  2. It always includes the required serviceKey property
  3. It properly applies the common alert channel properties using buildAlertChannelProps

This conditional approach ensures that the generated code is clean and only includes relevant properties.

packages/cli/src/sourcegen/exprbuilder.ts (2)

5-9: Well-designed expression builder factory function

The expr function provides a clean way to create and configure expression values using the builder pattern. This approach enables fluent, readable code when generating expressions.


11-41: Comprehensive expression building capabilities

The ExpressionValueBuilder class provides a complete set of methods for building different types of expressions:

  • new for constructing new expressions
  • call for method calls
  • member for property access
  • context and build for managing the builder state

The implementation properly handles the builder context throughout method chaining and supports all the core expression types needed for code generation.

packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (3)

7-11: Clear webhook type constraint with proper interface extension

The IncidentioAlertChannelResource interface correctly extends the WebhookAlertChannelResource and constrains the webhookType to specifically be 'WEBHOOK_INCIDENTIO', ensuring type safety when working with Incident.io webhooks.


29-32: Consistent alert channel registration pattern

The prepare method follows the established pattern for alert channel registration, using a descriptive prefix 'incidentioAlert' for clear variable naming.


34-61: Clean implementation with proper API key extraction

The gencode method correctly:

  1. Imports the necessary construct
  2. Retrieves the alert channel ID from the context
  3. Extracts the configuration
  4. Conditionally includes the API key when it's available
  5. Applies common alert channel properties

The code is well-structured and follows established patterns from other alert channel implementations while handling the specific requirements of Incident.io integration.

packages/cli/src/constructs/alert-channel-codegen.ts (9)

1-3: Imports look appropriate.
They properly fetch the Codegen and Context classes from internal modules and the Program and ObjectValueBuilder from sourcegen. No immediate issues.


4-10: Channel-specific codegen imports are well-organized.
Importing each channel’s codegen in a separate statement is clear and maintainable.


12-19: Union type enumeration is clear.
The defined AlertChannelType union accurately captures the channel options. If additional channels are introduced in the future, be sure to update both this type and the corresponding codegens.


21-29: Interface structure is cohesive.
All relevant fields (sendRecovery, sendFailure, etc.) are included, and numeric/boolean fields are adequately represented. The id: number property is good for internal reference.


31-51: Property builder function is consistent.
By conditionally checking for undefined, the code avoids generating superfluous fields. The logic is readable and avoids confusion between falsey booleans and the truly undefined case.


53-62: Class definition extends common codegen pattern.
Declaring channel-specific codegens and grouping them into codegensByType simplifies lookups. No issues noted.


63-82: Constructor initialization is well-structured.
Each channel codegen is instantiated and correctly indexed in codegensByType. This is straightforward and maintainable.


84-91: prepare method design is intuitive.
The method properly dispatches to the relevant channel codegen based on resource type, throwing a clear error if unsupported.


93-100: gencode dispatch method is straightforward.
Mirrors the prepare flow, ensuring the correct codegen is used. This consistent structure helps ensure minimal duplication.

packages/cli/src/sourcegen/index.ts (1)

1-33: Central re-exports are well-managed.
This “barrel” file conveniently consolidates exports for the various Value and builder classes. The naming scheme is consistent, and the exports are straightforward.

packages/cli/src/constructs/construct-codegen.ts (9)

1-3: Imports from internal and source modules are correct.
They align with the recognized class interfaces (Codegen, Context, Program). No concerns here.


4-12: Resource-specific codegen imports are clear.
Bringing in each specialized codegen for top-level resource handling is well-structured.


14-23: ResourceType union is extensible.
Similar to AlertChannelType, it’s straightforward to add new resource types. Keep it updated if new resource categories are added.


31-41: resourceOrder improves sorting but inverts typical ascending logic.
return bo - ao; sorts resources in descending order. If that’s intended for an internal ordering priority, it’s fine. Otherwise, confirm the desired sort direction.

Do you intend to sort from highest to lowest priority or would ascending order be preferable?


43-49: sortResources is straightforward.
The function leverages resourceOrder and returns a consistently sorted list. The logic is readable and easy to extend when new resource types are introduced.


51-61: Class fields centralize resource codegens.
The constructor references them. No immediate issues. This design fosters single entry for all resource type code generation.


63-86: Constructor organizes specialized codegens properly.
Objects are instantiated for each resource type and stored in a clear record mapping. Straightforward approach.


88-96: prepare method logic is consistent.
Ensures the correct codegen is used based on resource.type, relying on a uniform signature. The error message is descriptive.


97-105: gencode dispatch is symmetrical to prepare.
Handles the same resource-based codegen lookup for generation. The uniform pattern keeps logic consistent across methods.

packages/cli/src/rest/projects.ts (7)

27-27: No code to review
No content was added besides a blank line. Nothing to discuss.


39-49: Looks good!
The new interfaces for import plan changes and import plans look structurally sound.


81-84: Consider handling potential errors
Creating import plans is straightforward, but consider how to handle or log errors if the server responds with failures.


94-101: Listing import plans appears correct
This implementation is consistent with the findImportPlans approach and remains straightforward.


103-105: Looks good
The DELETE request approach for canceling an import plan is well-structured.


107-109: No issues spotted
The method is straightforward and consistent with typical REST design patterns for applying an import plan.


111-113: Implementation is appropriate
Similarly, committing an import plan aligns well with established patterns.

packages/cli/src/sourcegen/expr.ts (5)

5-7: Base abstract class is fine
The abstract ExpressionValue provides a good foundation for specialized expressions.


8-24: Clean 'new' Expression Implementation
This neatly constructs a 'new' expression, combining the callee and arguments with appropriate spacing.


26-40: Function call expression is correct
Implementation is consistent with typical call patterns. The render method is straightforward.


59-80: Binary expression operator coverage
The chosen operators cover many common scenarios. Adding parentheses for complex nesting might be beneficial in certain contexts, but this approach is acceptable for now.


82-98: Unary expression checks out
Implementation follows standard patterns for unary operators and rendering.

packages/cli/src/constructs/check-group-codegen.ts (2)

1-41: Resource interfaces look comprehensive
Interfaces for BrowserCheckConfigResource, MultiStepCheckConfigResource, and CheckGroupResource are well-defined and align with the overall check structure.


229-253: Code generation logic is well-structured
The class cleanly registers the resource and generates the final code snippet using the builder pattern. No major issues identified.

packages/cli/src/constructs/webhook-alert-channel-codegen.ts (5)

1-11: Good use of imports and type definitions
The initial imports cleanly separate concerns for building alert channel props and advanced code generation. Everything appears consistent.


12-31: Interfaces provide clear structure
Defining WebhookAlertChannelResourceConfig and extending AlertChannelResource for WebhookAlertChannelResource looks coherent and keeps the data model consistent with other alert channel resources.


33-74: Streamlined config builder
buildWebhookAlertChannelConfig follows a consistent pattern to conditionally set fields. This approach is modular and maintainable.


76-83: Construct naming
Using const construct = 'WebhookAlertChannel' ensures the final code references a consistent resource name.


84-95: Delegation to specialized codegens
Mapping distinct webhook types to their specialized classes is a sound approach that promotes separation of concerns.

packages/cli/src/sourcegen/objectbuilder.ts (3)

1-11: Imports and class references
All imports are relevant for building objects, expressions, and handling special value types. Code is nicely organized.


12-16: Reusable object construction
The object(...) helper function effectively encapsulates object building and returns a fully realized Value.


18-65: Fluent interface for object creation
ObjectValueBuilder’s methods handle varied property types cleanly. This approach improves readability and modularity.

packages/cli/src/sourcegen/arraybuilder.ts (3)

1-11: Imports set the stage for array building
All dependencies align well with generating arrays of different Value subclasses.


12-16: array(...) factory
Encapsulating ArrayValueBuilder creation behind array(...) fosters a clean, fluent interface.


18-74: Fluent array builder
ArrayValueBuilder provides a robust, chainable way to add various value types. The empty() approach is a nice convenience.

packages/cli/src/sourcegen/argsbuilder.ts (16)

1-11: Imports look good.
They provide all necessary dependencies for this builder pattern without introducing unused references or circular dependencies.


13-17: The args function is concise and straightforward.
This function effectively encapsulates the builder instantiation and usage, returning the constructed ArgumentsValue. No issues identified.


19-19: Comment on circular dependency avoidance.
It's good practice to avoid extending ArrayValueBuilder here to prevent circular imports. This provides a clear separation of responsibilities for argument values versus array values.


20-21: Private field for builder elements is well-scoped.
Using a private array #elements keeps the implementation details hidden while providing a controlled interface for adding and retrieving values.


23-26: empty() method ensures a quick reset.
This is a convenient way to clear the builder state without re-instantiating the class.


28-34: String & boolean value additions.
The code is straightforward, and calling this.value(...) maintains a consistent pattern for pushing new values into #elements.


36-38: Number value addition is correct.
No off-by-one or type issues spotted.


40-42: Null value handling is correct.
This method properly adds a NullValue instance into the builder.


44-46: Undefined value handling is consistent.
Maintains the same approach as the null() method.


48-50: Identifier values are properly supported.
This ensures references to named identifiers (e.g., variable names) are added to the builder array.


52-54: array(build: ...) usage.
Delegating array construction to array(build) helps keep the code modular and avoids duplication.


56-58: object(build: ...) usage.
Similar to array(), nicely delegates object construction to a dedicated builder function.


60-62: expr method is a neat way to build expressions.
Leverages the expr helper, allowing for more complex expressions within arguments.


64-67: value() acts as a generic insertion point.
This gives maximum flexibility for pushing any Value implementation into the builder.


69-71: elements getter provides read-only access.
Useful for external examination or debugging without exposing direct writes to #elements.


73-75: build() method finalizes the argument values.
Returns a new ArgumentsValue instance containing the accumulated values. This completes the builder pattern cleanly.

packages/cli/src/constructs/internal/codegen/context.ts (1)

5-121: Overall Context class design is clear and maintains good data integrity.

  • Each register/lookup method pairs well, storing and retrieving identifiers in private Map fields.
  • The usage of numeric vs. string keys is consistent with the domain logic.
  • Error handling on undefined mappings is correct, though a more descriptive error (see above) is recommended.

Comment on lines 29 to 796
async run (): Promise<void> {
const { flags } = await this.parse(ImportPlanCommand)
const {
config: configFilename,
} = flags

const { configDirectory, configFilenames } = splitConfigFilePath(configFilename)
const {
config: checklyConfig,
} = await loadChecklyConfig(configDirectory, configFilenames)

const {
logicalId,
} = checklyConfig

const { data: existingPlans } = await api.projects.findImportPlans(logicalId, {
onlyUncommitted: true,
})

if (existingPlans.length !== 0) {
await this.#handleExistingPlans(existingPlans)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Add unit tests to handle existing import plans scenario.
Consider verifying the user flow when existing plans are detected and the user chooses different prompt options.

Run the following script to locate relevant tests:


🏁 Script executed:

#!/bin/bash
rg -A 15 "ImportPlanCommand" tests

Length of output: 80


Action Required: Add Unit Tests for Handling Existing Import Plans

The changes in packages/cli/src/commands/import/plan.ts (lines 29–51) currently have no accompanying tests. We need to add unit tests to validate the code paths when existing import plans are detected. In particular, please verify that:

  • The flow through #handleExistingPlans is correctly triggered when there are non-zero existingPlans.
  • Different user prompt responses (e.g., accepting, canceling, or modifying actions) yield the expected outcomes.
  • Edge cases and potential error conditions are properly handled.

The earlier search using rg -A 15 "ImportPlanCommand" tests did not find any test files (indicating a missing tests directory). Please address this by creating relevant tests to ensure robustness.

@sorccu sorccu force-pushed the simokinnunen/sc-23506/cli-import-existing-resources branch from 8e0a955 to 470b019 Compare March 25, 2025 16:38
Copy link
Contributor

@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: 5

🧹 Nitpick comments (37)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (2)

12-17: Consider making the API key extraction more robust

The apiKeyFromUrl function uses a specific regex pattern that assumes a fixed URL format. This might be brittle if the Telegram API URL structure changes in the future.

Consider adding:

  1. More comprehensive regex pattern matching
  2. Error handling for malformed URLs
  3. Documentation about the expected URL format
function apiKeyFromUrl (url: string): string | undefined {
-  const match = /https:\/\/api.telegram.org\/bot([^/]+)\/sendMessage/.exec(url)
+  // Match both standard and custom domain Telegram bot API URLs
+  const match = /https:\/\/(?:api\.telegram\.org|[^/]+)\/bot([^/]+)\/sendMessage/.exec(url)
  if (match) {
    return match[1]
  }
+  // Log warning or return specific error value for debugging
}

19-24: Add error handling for chatId extraction

The chatIdFromTemplate function extracts the chat ID without validating if it's a valid Telegram chat ID format.

function chatIdFromTemplate (template: string): string | undefined {
  const match = /chatId=(-?[0-9]+)/.exec(template)
  if (match) {
+    // Ensure we have a valid chat ID format (group IDs are negative numbers, user IDs are positive)
+    const chatId = match[1]
+    if (!/^-?[0-9]+$/.test(chatId)) {
+      return undefined
+    }
    return match[1]
  }
}
packages/cli/src/sourcegen/decl.ts (1)

38-52: Consider centralizing whitespace handling

The render method in VariableDeclaration has several calls to manage whitespace that could be abstracted to reduce duplication and improve consistency across the codebase.

Consider refactoring the whitespace handling into helper methods:

render (output: Output): void {
  if (this.options?.mutable) {
    output.append('let')
  } else {
    output.append('const')
  }
  output.significantWhitespace()
  this.identifier.render(output)
-  output.cosmeticWhitespace()
-  output.append('=')
-  output.cosmeticWhitespace()
+  output.appendWithSpacing('=')  // A new helper method that adds spaces around a token
  this.value.render(output)
  output.endLine()
}
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1)

13-16: Consider adding documentation for the empty implementation

The gencode method has an eslint-disable comment to suppress unused variable warnings, but it would be helpful to add more context about why this resource doesn't generate code.

// eslint-disable-next-line @typescript-eslint/no-unused-vars
gencode (logicalId: string, resource: PrivateLocationGroupAssignmentResource, context: Context): void {
-  // Nothing to generate for this resource.
+  // This resource only establishes a relationship in the context
+  // but doesn't generate standalone code. The relationship will be used
+  // when generating code for associated private locations and groups.
}
packages/cli/src/constructs/internal/assertion-codegen.ts (1)

45-146: Consolidate duplicate code between assertion functions

The valueForGeneralAssertion and valueForNumericAssertion functions contain significant duplication in their structure and many comparison operations. Consider refactoring to reduce duplication.

You could create a common helper function to handle the shared logic:

function createAssertionValue(
  klass: string,
  method: string,
  comparison: string,
  target: string | number,
  property?: string,
  isNumeric = false
): Value {
  return expr(ident(klass), builder => {
    builder.member(ident(method))
    builder.call(builder => {
      if (property) {
        builder.string(property)
      }
    })
    
    // Handle the comparison methods
    const methodMap: Record<string, string> = {
      'EQUALS': 'equals',
      'NOT_EQUALS': 'notEquals',
      // Add all other mappings
    }
    
    const methodName = methodMap[comparison]
    if (!methodName) {
      throw new Error(`Unsupported comparison ${comparison}`)
    }
    
    builder.member(ident(methodName))
    builder.call(builder => {
      if (['IS_EMPTY', 'NOT_EMPTY', 'IS_NULL', 'NOT_NULL'].includes(comparison)) {
        builder.empty()
      } else if (isNumeric) {
        builder.number(Number(target))
      } else {
        builder.string(target.toString())
      }
    })
  })
}

Then refactor both functions to use this helper.

packages/cli/src/commands/import/apply.ts (2)

37-39: Handle scenarios with zero unapplied plans.

When unappliedPlans is empty, calling this.#selectPlan(unappliedPlans) may lead to a confusing prompt or an index-out-of-bounds error. Consider short-circuiting if unappliedPlans.length === 0, displaying a message, and returning early.


84-87: Permit an alternate flow after exit selection.

After the user selects "Exit without applying," the command terminates abruptly. Consider providing an option for the user to return to the main menu or reselect, if consistent with the CLI design.

packages/cli/src/constructs/api-check-codegen.ts (1)

8-19: Validate optional script fields with caution.

localSetupScript, setupScriptPath, localTearDownScript, and tearDownScriptPath are optional but may overlap. Consider clarifying in documentation or code whether both scripts and script paths can coexist and how each is prioritized.

packages/cli/src/constructs/slack-alert-channel-codegen.ts (2)

5-11: Ensure user-provided Slack URL is valid.

config.url is mandatory, but there's no validation to ensure it is a valid Slack webhook URL. If relevant to your product's usage, consider validating or error handling for malformed URLs.


20-43: Consider user feedback on Slack channel configuration.

While the code properly sets the channel field, some Slack webhooks may ignore non-default channels if the incoming webhook is restricted. It might be beneficial to add a note or fallback if the Slack response indicates that the specified channel is invalid or restricted.

packages/cli/src/constructs/tcp-check-codegen.ts (1)

7-12: Clarify optional response time properties.

degradedResponseTime and maxResponseTime are optional. Be sure to document how the default behavior works when these fields are unspecified, e.g., no performance-based alerts.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)

20-43: Consider adding a fallback or error handling for invalid phone numbers.
Right now, the code writes config.number as phoneNumber without verifying whether config.number meets any format requirements. While it may be sufficient as-is, you could include optional formatting or at least a note in the code to handle potential invalid inputs.

If you’d like, here’s a potential snippet to indicate a naive check (though you may replace it with a more robust validator later):

 builder.string('phoneNumber', config.number)
+ // Example naive check (not necessarily recommended for production)
+ // if (!/^\+?\d+$/.test(config.number)) {
+ //   throw new Error('Invalid phone number format')
+ // }
packages/cli/src/sourcegen/declbuilder.ts (1)

20-23: Overwriting behavior may lead to confusion.
Each time .variable(...) is called, the existing declaration in #decl is replaced. Ensure this is always the desired behavior, as one might accidentally chain multiple .variable(...) calls expecting them to accumulate rather than overwrite.

packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1)

16-19: Unused parameter “logicalId”.

The logicalId parameter is never used in the prepare method. If it's not necessary for registration in future enhancements, consider removing it for clarity.

-  prepare (logicalId: string, resource: PhoneCallAlertChannelResource, context: Context): void {
+  prepare (_logicalId: string, resource: PhoneCallAlertChannelResource, context: Context): void {
    context.registerAlertChannel(resource.id, 'phoneCallAlert')
  }
packages/cli/src/constructs/check-codegen.ts (1)

35-144: Consider breaking up the large function into smaller helpers.

buildCheckProps method is quite expansive. Partitioning sections (e.g., location handling, alert channel lookups) into smaller helpers can improve maintainability.

 function buildCheckProps (
   program: Program,
   builder: ObjectValueBuilder,
   resource: CheckResource,
   context: Context,
 ): void {
+  // Example: create a "buildLocationProps" helper to handle lines 59-66 & 68-82
+  // create a "buildAlertProps" helper to handle lines 115-129
   ...
 }
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)

5-13: Potential risk in storing API keys.

The apiKey field is stored in plain text. If you plan to generate code that includes this key, consider storing secrets securely or providing usage instructions that clarify the risks of embedding sensitive data.


17-20: Unused parameter “logicalId”.

Similar to other codegen classes, the logicalId parameter is not used here. Remove it or rename it for clarity if not needed for future expansions.

-  prepare (logicalId: string, resource: OpsgenieAlertChannelResource, context: Context): void {
+  prepare (_logicalId: string, resource: OpsgenieAlertChannelResource, context: Context): void {
    context.registerAlertChannel(resource.id, 'opsgenieAlert')
  }

22-44: Add codegen test coverage for Opsgenie channels.

Introducing a test that verifies the generated OpsgenieAlertChannel code will help detect future regressions. You can mock or stub out any secret data like apiKey.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (2)

5-12: Consider adding JSDoc for clarity
The interface is straightforward, but adding a short doc comment (e.g., describing the config fields) could help future contributors understand its usage.


21-48: Ensure sensitive keys are handled securely
While generating code for the serviceKey, confirm that storing secrets in plain text is acceptable. Consider referencing environment variables or a secrets manager to avoid exposing sensitive credentials.

packages/cli/src/sourcegen/exprbuilder.ts (4)

5-9: Add documentation
The expr function is central to building and chaining expressions. A brief docstring could help clarify its usage and parameters.


18-22: Method name 'new' may be confusing
Using “new” as a method name can overshadow the language keyword. Consider renaming it to something like createNew for clarity.

Here’s a possible diff:

-  new (build: (builder: ArgumentsValueBuilder) => void): this {
+  createNew (build: (builder: ArgumentsValueBuilder) => void): this {
     const builder = new ArgumentsValueBuilder()
     build(builder)
     return this.context(new NewExpressionValue(this.#context, builder.build()))
 }

30-32: Nested expressions
The member method looks good, but consider adding tests for multi-level member calls to ensure chaining works as expected.


34-37: Potential naming conflict
context(value) might be confused with the existing context parameter in the top-level expr function. A more specific name could improve readability.

packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (2)

13-25: Consider using toLowerCase()
Instead of toLocaleLowerCase(), which may behave differently across locales, using toLowerCase() is often clearer for case-insensitive matching of “authorization” headers.

Here’s a possible diff:

-    if (header.key.toLocaleLowerCase() !== 'authorization') {
+    if (header.key.toLowerCase() !== 'authorization') {
       continue
     }

34-61: Handling the apiKey
Embedding the extracted apiKey directly in generated code can pose security risks if it’s sensitive. Consider referencing environment variables or a secrets manager to keep credentials out of source control.

packages/cli/src/constructs/check-group-codegen.ts (2)

72-77: Error is ignored when private location lookup fails.
Catching and ignoring errors may be intentional, but it risks silent failures if contexts are not properly registered. Consider logging or rethrowing for better traceability, if that’s a concern.


110-115: Similar pattern with alert channels.
As with private locations, catching and ignoring context lookup errors is consistent but could mask issues. Logging such errors may improve diagnostics.

packages/cli/src/constructs/construct-codegen.ts (1)

43-49: sortResources function is straightforward.
Sorting logic is easy to follow, but a small comment clarifying the reversed ranking would reduce confusion.

packages/cli/src/rest/projects.ts (3)

39-49: Consider adding documentation for these interfaces.
Adding brief doc comments can help clarify the intended usage of ImportPlan and ImportPlanChanges.


85-92: Optional parameter documentation.
Consider documenting onlyUnapplied and onlyUncommitted to help clarify their effect for future maintainers.


94-101: Potential shared logic with findImportPlans.
listImportPlans is very similar to findImportPlans; consider extracting common logic if you foresee further expansions in filtering or parameters.

packages/cli/src/sourcegen/expr.ts (1)

42-57: Handle bracket notation for member expressions.
A TODO note implies there may be tricky cases with dynamic property names. Let me know if you need assistance implementing bracket notation vs dot notation.

packages/cli/src/sourcegen/arraybuilder.ts (1)

18-74: ArrayValueBuilder implementation is consistent and flexible.

  1. Methods for adding different value types (e.g., null(), undefined(), ident()) are clear.
  2. The empty() method is a helpful convenience for re-initializing the builder.
  3. Consider adding doc comments for each method to maintain clarity on usage and side effects.
packages/cli/src/sourcegen/argsbuilder.ts (1)

19-76: ArgumentsValueBuilder is thorough and readable.

  1. The method suite (string(), object(), expr(), etc.) covers a broad range of argument types.
  2. The empty() method allows for resetting the argument list seamlessly.
  3. As with other builders, doc comments would be useful for describing each method’s intended usage.
packages/cli/src/constructs/internal/codegen/context.ts (2)

3-4: Provide a default error message or accept a custom one.

Although this error class extends Error, the constructor does not supply any default or custom message. Providing a descriptive message can aid in troubleshooting and enhance clarity for debugging.

Here’s a possible revision:

-export class MissingContextVariableMappingError extends Error {}
+export class MissingContextVariableMappingError extends Error {
+  constructor(message?: string) {
+    super(message || 'Missing context variable mapping')
+    this.name = 'MissingContextVariableMappingError'
+  }
+}

6-16: Consider adding documentation for private fields.

All your private maps look good in terms of scoping, but adding JSDoc comments specifying their purpose would improve maintainability and help readers understand at a glance how each mapping is used.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e0a955 and 470b019.

📒 Files selected for processing (65)
  • packages/cli/e2e/__tests__/help.spec.ts (2 hunks)
  • packages/cli/package.json (1 hunks)
  • packages/cli/src/commands/import/apply.ts (1 hunks)
  • packages/cli/src/commands/import/cancel.ts (1 hunks)
  • packages/cli/src/commands/import/commit.ts (1 hunks)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group.ts (1 hunks)
  • packages/cli/src/constructs/construct-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/email-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/frequency-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/assertion-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/index.ts (1 hunks)
  • packages/cli/src/constructs/key-value-pair-codegen.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config.ts (0 hunks)
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/ref-codegen.ts (1 hunks)
  • packages/cli/src/constructs/retry-strategy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/rest/projects.ts (3 hunks)
  • packages/cli/src/sourcegen/args.ts (1 hunks)
  • packages/cli/src/sourcegen/argsbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/array.ts (1 hunks)
  • packages/cli/src/sourcegen/arraybuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/boolean.ts (1 hunks)
  • packages/cli/src/sourcegen/decl.ts (1 hunks)
  • packages/cli/src/sourcegen/declbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/expr.ts (1 hunks)
  • packages/cli/src/sourcegen/exprbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/identifier.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
  • packages/cli/src/sourcegen/null.ts (1 hunks)
  • packages/cli/src/sourcegen/number.ts (1 hunks)
  • packages/cli/src/sourcegen/object.ts (1 hunks)
  • packages/cli/src/sourcegen/objectbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/output.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
  • packages/cli/src/sourcegen/string.ts (1 hunks)
  • packages/cli/src/sourcegen/undefined.ts (1 hunks)
  • packages/cli/src/sourcegen/unknown.ts (1 hunks)
  • packages/cli/src/sourcegen/value.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/cli/src/constructs/playwright-config.ts
🚧 Files skipped from review as they are similar to previous changes (37)
  • packages/cli/src/sourcegen/number.ts
  • packages/cli/src/sourcegen/null.ts
  • packages/cli/src/sourcegen/undefined.ts
  • packages/cli/e2e/tests/help.spec.ts
  • packages/cli/src/constructs/ref-codegen.ts
  • packages/cli/src/sourcegen/args.ts
  • packages/cli/src/sourcegen/boolean.ts
  • packages/cli/src/sourcegen/identifier.ts
  • packages/cli/src/constructs/internal/codegen/index.ts
  • packages/cli/src/sourcegen/value.ts
  • packages/cli/package.json
  • packages/cli/src/constructs/check-group.ts
  • packages/cli/src/constructs/playwright-config-codegen.ts
  • packages/cli/src/commands/import/cancel.ts
  • packages/cli/src/sourcegen/object.ts
  • packages/cli/src/sourcegen/string.ts
  • packages/cli/src/constructs/key-value-pair-codegen.ts
  • packages/cli/src/sourcegen/unknown.ts
  • packages/cli/src/commands/import/commit.ts
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/constructs/internal/codegen/codegen.ts
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts
  • packages/cli/src/constructs/heartbeat-check-codegen.ts
  • packages/cli/src/commands/import/plan.ts
  • packages/cli/src/constructs/frequency-codegen.ts
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/src/constructs/maintenance-window-codegen.ts
  • packages/cli/src/sourcegen/output.ts
  • packages/cli/src/constructs/retry-strategy-codegen.ts
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts
  • packages/cli/src/sourcegen/program.ts
  • packages/cli/src/constructs/email-alert-channel-codegen.ts
  • packages/cli/src/sourcegen/index.ts
  • packages/cli/src/sourcegen/array.ts
  • packages/cli/src/constructs/alert-channel-subscription-codegen.ts
  • packages/cli/src/constructs/private-location-codegen.ts
🧰 Additional context used
🧬 Code Definitions (21)
packages/cli/src/constructs/api-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (15-33)
  • buildCheckProps (35-144)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/sourcegen/decl.ts (3)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/sourcegen/index.ts (6)
  • Output (28-28)
  • IdentifierValue (23-23)
  • VariableDeclaration (7-7)
  • Value (33-33)
  • ExportDeclaration (8-8)
  • decl (11-11)
packages/cli/src/sourcegen/declbuilder.ts (1)
  • decl (5-9)
packages/cli/src/constructs/check-group-codegen.ts (7)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/api-check-codegen.ts (1)
  • valueForAssertion (21-38)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/construct-codegen.ts (12)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • AlertChannelCodegen (53-101)
packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1)
  • AlertChannelSubscriptionCodegen (9-24)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckCodegen (146-182)
packages/cli/src/constructs/check-group-codegen.ts (1)
  • CheckGroupCodegen (231-252)
packages/cli/src/constructs/dashboard-codegen.ts (1)
  • DashboardCodegen (31-140)
packages/cli/src/constructs/maintenance-window-codegen.ts (1)
  • MaintenanceWindowCodegen (16-64)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • PrivateLocationCodegen (14-44)
packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1)
  • PrivateLocationCheckAssignmentCodegen (8-17)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1)
  • PrivateLocationGroupAssignmentCodegen (8-17)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/tcp-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (15-33)
  • buildCheckProps (35-144)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForGeneralAssertion (45-146)
  • valueForNumericAssertion (4-43)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (2)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (9)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1)
  • PhoneCallAlertChannelCodegen (15-44)
packages/cli/src/constructs/email-alert-channel-codegen.ts (1)
  • EmailAlertChannelCodegen (14-37)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1)
  • OpsgenieAlertChannelCodegen (17-45)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1)
  • PagerdutyAlertChannelCodegen (16-49)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)
  • SlackAlertChannelCodegen (15-44)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)
  • SmsAlertChannelCodegen (15-44)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1)
  • WebhookAlertChannelCodegen (78-134)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/sourcegen/expr.ts (2)
packages/cli/src/sourcegen/args.ts (1)
  • ArgumentsValue (4-27)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/constructs/check-codegen.ts (5)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/sourcegen/argsbuilder.ts (3)
packages/cli/src/sourcegen/index.ts (8)
  • args (2-2)
  • ArgumentsValueBuilder (2-2)
  • ArgumentsValue (1-1)
  • Value (33-33)
  • array (4-4)
  • object (27-27)
  • ExpressionValueBuilder (22-22)
  • expr (22-22)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/args.ts (1)
  • ArgumentsValue (4-27)
packages/cli/src/sourcegen/objectbuilder.ts (9)
packages/cli/src/sourcegen/arraybuilder.ts (7)
  • object (54-56)
  • build (71-73)
  • value (62-65)
  • ArrayValueBuilder (18-74)
  • array (12-16)
  • array (50-52)
  • expr (58-60)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/object.ts (2)
  • ObjectProperty (4-12)
  • ObjectValue (14-39)
packages/cli/src/sourcegen/string.ts (1)
  • StringValue (6-17)
packages/cli/src/sourcegen/boolean.ts (1)
  • BooleanValue (4-15)
packages/cli/src/sourcegen/number.ts (1)
  • NumberValue (4-15)
packages/cli/src/sourcegen/null.ts (1)
  • NullValue (4-8)
packages/cli/src/sourcegen/undefined.ts (1)
  • UndefinedValue (4-8)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (4-15)
packages/cli/src/sourcegen/exprbuilder.ts (3)
packages/cli/src/sourcegen/index.ts (8)
  • expr (22-22)
  • Value (33-33)
  • ExpressionValueBuilder (22-22)
  • ExpressionValue (15-15)
  • ArgumentsValueBuilder (2-2)
  • NewExpressionValue (16-16)
  • CallExpressionValue (17-17)
  • MemberExpressionValue (18-18)
packages/cli/src/sourcegen/argsbuilder.ts (4)
  • expr (60-62)
  • build (73-75)
  • value (64-67)
  • ArgumentsValueBuilder (20-76)
packages/cli/src/sourcegen/expr.ts (3)
  • NewExpressionValue (8-24)
  • CallExpressionValue (26-40)
  • MemberExpressionValue (42-57)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/internal/codegen/context.ts (1)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • MissingContextVariableMappingError (2-2)
  • Context (2-2)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (8)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)
  • IncidentioAlertChannelCodegen (29-62)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)
  • MSTeamsAlertChannelCodegen (14-40)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)
  • TelegramAlertChannelCodegen (28-67)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
🪛 Biome (1.9.4)
packages/cli/src/constructs/check-codegen.ts

[error] 169-169: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 171-171: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 173-173: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 175-175: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 177-177: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

packages/cli/src/constructs/webhook-alert-channel-codegen.ts

[error] 102-102: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 114-114: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (76)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1)

9-11: LGTM: Appropriate use of context registration

The prepare method correctly registers the private location group assignment with the context using the provided resource properties.

packages/cli/src/commands/import/apply.ts (2)

22-31: Consider verifying the presence or validity of the config file before proceeding.

If flags.config is not provided or points to an invalid file, splitConfigFilePath and loadChecklyConfig may throw an error. Consider either adding a default value or handling this case more gracefully with a user-friendly warning.

Would you like me to generate a script to confirm whether flags.config is being passed and properly validated in other parts of the codebase?


62-65: Fix hardcoded plan numbering.

All plans are labeled with "Plan #1 from ...". This creates ambiguity when multiple plans exist. Update the loop to reference the index or use data from the plan to label them uniquely.

Apply a diff similar to the past review comment:

-  title: `Plan #1 from ${new Date(plan.createdAt)}`,
+  title: `Plan #${index + 1} from ${new Date(plan.createdAt)}`,
packages/cli/src/constructs/api-check-codegen.ts (2)

21-38: Good use of a switch to handle various assertion sources.

The function cleanly maps each assertion.source to an appropriate builder call, and it throws an error for unsupported sources. This is a robust, maintainable approach.


42-153: Check for concurrency or parallel codegen usage.

While not strictly an issue here, ensure that this code generation logic will not produce race conditions when used in parallel with other codegen tasks. If codegen resources share state, such as referencing a single Program instance across threads, consider adding synchronization or clarifying concurrency assumptions.

packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)

15-19: Registering the alert channel at prepare time looks correct.

This approach correctly associates the alert channel physicalId with a contextual variable prefix slackAlert. No issues found in the logic.

packages/cli/src/constructs/tcp-check-codegen.ts (2)

14-25: Robust error handling for unsupported TCP assertion sources.

Throwing an error for an unsupported source ensures undefined behavior is caught early. This is a solid approach.


29-71: Handle edge cases in the request object.

If resource.request.port or resource.request.hostname is omitted or invalid, the code might break. Ensure that these fields are required or handle them gracefully.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (2)

1-4: Imports look clean and follow the established source generation structure.


5-11: Confirm mandatory vs. optional fields for phone number.
It may be beneficial to ensure that config.number is never empty or null. Since a valid phone number is crucial for SMS-based alerts, consider adding a validation or at least a safeguard to avoid runtime errors.

Would you like me to generate a script that searches for references to this interface to confirm that every usage provides a valid number field?

packages/cli/src/sourcegen/declbuilder.ts (1)

1-9: Straightforward declaration builder pattern.
This approach nicely encapsulates the creation of declarations, improving readability and maintainability of generated code.

packages/cli/src/constructs/msteams-alert-channel-codegen.ts (3)

1-3: Imports look aligned with the existing codegen architecture.


6-10: Resource extension appears appropriate.
Using a WebhookAlertChannelResource base for MS Teams is suitable, given it’s a type of webhook with a specific webhookType.


19-39: Validate the MS Teams webhook details.
Given that webhookType is 'WEBHOOK_MSTEAMS', consider verifying the URL domain format or at least that the URL is not empty to avoid sending incomplete or invalid requests.

Would you like me to generate a search script to identify how url is used in other places, ensuring consistent handling of webhook URLs for MS Teams?

packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (2)

5-13: Interface structure appears correct.

The PhoneCallAlertChannelResource interface is suitably extending AlertChannelResource and specifying a unique 'CALL' type. This aligns well with the existing alert channel setup.


20-43: Recommend adding test coverage.

To ensure correctness and prevent regressions, it’s best to add codegen tests for this new alert channel type. You can validate code blocks are correctly generated (logical ID usage, phone number, optional name, etc.).

Would you like me to generate a sample test file to verify the generated code structure for PhoneCallAlertChannelCodegen?

packages/cli/src/constructs/check-codegen.ts (1)

15-33: Interface provides clear coverage of check properties.

All relevant fields (e.g., activated, muted, etc.) are included. This is comprehensive and easy to extend.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1)

16-19: Looks good
The prepare method correctly registers the alert channel in the context with a clear, descriptive prefix.

packages/cli/src/sourcegen/exprbuilder.ts (2)

24-28: LGTM
The call method’s structure is intuitive and aligns well with the builder pattern.


39-41: Completes the builder pattern
Returning the private #context state neatly finishes the expression building flow.

packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (2)

7-11: Interface usage
Extending WebhookAlertChannelResource with a specialized webhookType is a clean approach that maintains generic properties while customizing the incident.io configuration.


29-32: Consistent pattern
The prepare method follows the established approach to register alert channels using a recognizable prefix.

packages/cli/src/constructs/alert-channel-codegen.ts (6)

1-10: Imports look consistent and modular.
All imported modules and references appear valid. No issues found with structure or syntax.


12-19: Enum-like union type is clear and exhaustive.
Defining all possible alert channel types in a single union is straightforward and helps prevent invalid inputs at compile time.


21-29: Interface is well-structured.
All required and optional properties are clearly defined. This clearly captures the attributes needed for each alert channel resource.


31-51: Utility function enables easy extension.
buildAlertChannelProps properly checks for undefined fields before building them. This is a good pattern to avoid missing or extraneous properties.


53-82: Comprehensive initialization of codegen instances.
Each specific codegen class is instantiated and mapped properly in codegensByType. This enforces full coverage for all supported alert channels.


84-101: Appropriate error handling for unsupported alert channel types.
Throwing an error when encountering an undefined type ensures that silent failures do not occur. This is a robust design decision.

packages/cli/src/constructs/check-group-codegen.ts (9)

1-10: Imports refer to relevant modules.
No issues with referencing or structuring these imported classes and functions. They align with the rest of the codebase.


11-19: Config resources capture essential properties.
The browser and multi-step check config resources reflect the expected shape, including optional frequency. This is flexible and future-proof.


21-41: CheckGroupResource thoroughly covers all properties for check groups.
All known attributes (loyalty, environment variables, concurrency, etc.) are well-defined. Optional fields are properly indicated.


43-48: Function signature is self-explanatory.
buildCheckGroupProps uses (program, builder, resource, context) as parameters, cleanly separating logic from data.


88-95: Tag array logic is clear.
Looping through tags elegantly handles the possibility of zero or multiple tags.


126-128: Alert escalation policy is clearly integrated.
Using valueForAlertEscalation nicely decouples the escalation-specific logic from the main flow.


130-168: Browser and multi-step checks follow consistent patterns.
Frequency and testMatch arrays are properly handled. The code reads cleanly.


222-222: Defaulting retry strategy to valueForRetryStrategy is robust.
Even if the resource doesn’t specify a retryStrategy, this logic ensures a stable default.


231-253: CheckGroupCodegen extends a solid base.
Using context.registerCheckGroup ensures consistent ID tracking. Importing the main construct is done only at gencode time.

packages/cli/src/constructs/construct-codegen.ts (6)

1-12: Imports reference the correct codegeneration modules.
No syntactic or logical issues apparent.


14-24: ResourceType union enumerates recognized resource categories.
Useful for controlling the resource handling logic, preventing partial or ambiguous resource types.


31-41: Resource ordering is reversed for higher numbers.
return bo - ao sorts descending by default. Confirm that this reversed order is entirely intentional. If you meant an ascending sort, consider swapping.


51-85: Constructor sets up all known resource codegens.
Mapping these resources ensures coverage, just like the approach used in alert-channel-codegen.


88-95: Consistent error-handling approach for unsupported resource types.
By failing fast, you guarantee that the calling code must handle or correct an unknown resource type.


97-104: Delegated generation approach fosters clarity.
Calls to the underlying codegens keep this class minimal and maintainable, avoiding duplication.

packages/cli/src/rest/projects.ts (4)

81-83: Looks good.
Creating an import plan with a simple POST request seems straightforward.


103-105: Straightforward cancellation endpoint.
No issues found; the code is concise and clear.


107-109: Straightforward apply endpoint.
Implementation looks correct.


111-113: Straightforward commit endpoint.
Implementation looks correct.

packages/cli/src/sourcegen/expr.ts (7)

5-6: Base class approach looks good.
The ExpressionValue class extends Value and seems ready for new expression types.


8-24: Constructor and rendering for 'new' expressions.
Implementation is straightforward and consistent with typical AST generation patterns.


26-40: Call expression rendering is correct.
Logic is clean, with the callee followed by arguments.


59-59: Binary operator definition is concise.
Expanding this list in the future is straightforward if you need more operators.


61-80: Binary expression rendering is clear.
No concerns with the spacing and operator usage.


82-82: Unary operator definition is concise.
Additional unary operators can easily be added as needed.


84-98: Unary expression rendering is correct.
Looks good with straightforward usage of the op property.

packages/cli/src/constructs/webhook-alert-channel-codegen.ts (8)

1-16: New type and interfaces look good.
The introduction of WebhookType is clean, supporting extension with additional webhook integrations in the future.


17-26: Interfaces are well-structured.
WebhookAlertChannelResourceConfig captures necessary details for different webhook types.


28-31: Extends AlertChannelResource clearly.
No issues; the WebhookAlertChannelResource definition is concise and easy to maintain.


33-74: Configuration builder is well-implemented.
Conditional checks for optional fields are cleanly handled, and the usage of ObjectValueBuilder is idiomatic.


76-76: Constant declaration is fine.
No concerns with naming or usage of construct.


78-95: Class construction logic is clear.
The mapping of codegensByWebhookType ensures easy extensibility for new webhook types.


97-107: Duplicate comment: remove return in a void function.
As noted previously, returning codegen.prepare(...) from a void function triggers a static analysis warning. Either remove the return or change the function signature.

-        return codegen.prepare(logicalId, resource, context)
+        codegen.prepare(logicalId, resource, context)
+        return
🧰 Tools
🪛 Biome (1.9.4)

[error] 102-102: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


109-133: Duplicate comment: remove return in a void function.
As noted previously, returning codegen.gencode(...) from a void function triggers a static analysis warning. Either remove the return or change the function signature.

-        return codegen.gencode(logicalId, resource, context)
+        codegen.gencode(logicalId, resource, context)
+        return
🧰 Tools
🪛 Biome (1.9.4)

[error] 114-114: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

packages/cli/src/sourcegen/objectbuilder.ts (3)

1-10: Good import organization and usage.

All imported modules appear relevant and are used appropriately to construct different value types. No redundant or missing imports detected.


12-16: Fluent interface for object(...) is clear and concise.

The builder pattern here allows for clean and intuitive object creation. This method effectively initializes the builder, invokes the consumer's custom logic, and returns the final ObjectValue.


18-65:

✅ Verification successful

Builder pattern implementation is robust. Consider documenting usage.

  1. The ObjectValueBuilder provides a solid API for adding various property types, from primitives to nested objects.
  2. Adding short doc comments or JSDoc annotations for each method could improve maintainability and clarify usage.
  3. The use of private class fields (#properties) is modern ES syntax. Validate that your Node/TypeScript environment supports it to avoid unexpected runtime issues.

🌐 Web query:

Which Node.js versions natively support JavaScript private class fields (#private)?

💡 Result:

Private class fields using the # syntax are natively supported in Node.js starting from version 12 and later, enabled by default without requiring command-line flags or transpilers like Babel[1][4][7]. This support was introduced through updates to the V8 JavaScript engine (v7.4+), which powers Node.js[4].

Key details:

  • Node.js 12 (April 2019): First version with native support for private fields[1][7].
  • Node.js 14+: Continues support as the feature became standardized (ES2022)[8].
  • Runtime behavior: Private fields are enforced at the language level, making them inaccessible via Object.keys() or other reflection methods[1][5].
class Example {
  #privateField = 42; // Supported in Node.js ≥12
  
  getValue() {
    return this.#privateField; 
  }
}

Earlier Node.js versions (≤11) lack support, and attempts to use the syntax will throw syntax errors. Private fields remain experimental in JavaScript until ES2022 standardization, but Node.js implementations have been stable since v12[4][7].

Citations:


Enhance Documentation & Verify Runtime Environment Compatibility

The implementation of the builder pattern is solid and uses modern ES syntax (e.g., private class fields are supported natively in Node.js v12 and later). To improve maintainability and clarify intended usage:

  • Consider adding inline JSDoc or doc comments for each method (e.g., string, boolean, number, etc.) to clearly explain parameters and functionality.
  • Verify that your development/production environments are running on Node.js v12 or later to ensure full support for private class fields.
packages/cli/src/sourcegen/arraybuilder.ts (2)

1-10: Imports look coherent.

They align well with the intended functionality (building arrays with various value types).


12-16: array(...) function is well-designed.

It mirrors the same fluent pattern found in object(...), ensuring consistency across builders.

packages/cli/src/sourcegen/argsbuilder.ts (2)

1-12: Imports and references are consistent with the builder pattern.

The references to ArgumentsValue, ArrayValueBuilder, ObjectValueBuilder, and others establish a unified approach to constructing arguments.


13-17: The args(...) function cleanly encapsulates argument construction.

It provides a straightforward interface for generating an ArgumentsValue instance, mirroring the style of your other builders.

packages/cli/src/constructs/internal/codegen/context.ts (7)

17-30: Looks correct for registering and looking up check groups.

The logic for generating a sequential variable name (e.g., group1, group2, ...) and retrieving it later is straightforward and consistent with the class’s intended design.


32-45: Alert channel registration and lookup logic appears sound.

No significant concerns: the pattern is consistent with how check groups are handled. The variable prefix parameter is a nice touch for naming clarity.


47-60: Code for private location registration and lookup is well-structured.

The approach of assigning a simple sequential name for each private location is clear and matches the pattern used above.


62-75: Registering and retrieving private locations for check groups is straightforward.

No functional issues spotted. Error handling is consistently done by throwing MissingContextVariableMappingError when needed.


77-90: Registering and retrieving private locations for checks is consistent.

Good reuse of the approach in the previous method. No immediate issues with performance or correctness.


92-105: Alert channel check subscription logic looks clean.

The pattern of appending to an array and retrieving it later is consistent with the existing approach.


107-120: Group alert channel subscription is implemented consistently.

The logic closely mirrors earlier patterns, ensuring a uniform API for lookups and assignments. No further concerns.

Comment on lines +106 to +117
case 'LESS_THAN':
builder.member(ident('lessThan'))
builder.call(builder => {
builder.string(assertion.target)
})
break
case 'GREATER_THAN':
builder.member(ident('greaterThan'))
builder.call(builder => {
builder.string(assertion.target)
})
break
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Handle numeric comparison types correctly in general assertions

The valueForGeneralAssertion function handles LESS_THAN and GREATER_THAN comparisons as string comparisons, which may produce unexpected results when comparing numeric values.

case 'LESS_THAN':
  builder.member(ident('lessThan'))
  builder.call(builder => {
-    builder.string(assertion.target)
+    // Try to determine if target should be treated as a number
+    const numValue = Number(assertion.target)
+    if (!isNaN(numValue)) {
+      builder.number(numValue)
+    } else {
+      builder.string(assertion.target)
+    }
  })
  break

Apply the same approach to the GREATER_THAN case.

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

Copy link
Contributor

@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: 2

🧹 Nitpick comments (6)
packages/cli/src/commands/import/apply.ts (2)

22-60: Improve error handling for non-fancy output.

The catch block properly handles error visualization for fancy output, but lacks any messaging or feedback for non-fancy mode. Consider adding a log message before throwing the error.

    } catch (err) {
      if (this.fancy) {
        ux.action.stop('❌')
+     } else {
+       this.log('❌ Failed to apply plan')
      }

      throw err
    }

64-65: Use a more user-friendly date format.

The date is currently displayed using the default Date formatting, which can vary by locale. Consider using a more consistent and readable format.

-      title: `Plan #${index + 1} from ${new Date(plan.createdAt)}`,
+      title: `Plan #${index + 1} from ${new Date(plan.createdAt).toLocaleString()}`,
       value: plan.id,
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (4)

79-79: Fix typo in property name.

The property name indicentioCodegen appears to have a typo - it should be incidentioCodegen (missing 't').

-  indicentioCodegen: IncidentioAlertChannelCodegen
+  incidentioCodegen: IncidentioAlertChannelCodegen

82-82: Improve type safety by avoiding any.

Using Codegen<any> loses type safety. Consider using a union type of the specific codegen types.

-  codegensByWebhookType: Record<WebhookType, Codegen<any>>
+  codegensByWebhookType: Record<WebhookType, IncidentioAlertChannelCodegen | MSTeamsAlertChannelCodegen | TelegramAlertChannelCodegen>

43-43: Remove unnecessary toString() conversion.

The config.url is defined as a string in the interface, so calling .toString() is redundant.

-  builder.string('url', config.url.toString())
+  builder.string('url', config.url)

97-108: Consider creating a helper method for webhook type codegen lookup.

Both prepare() and gencode() methods have similar code patterns for looking up and delegating to the appropriate codegen. Consider extracting this logic to a helper method.

+  private getCodegenForWebhookType(webhookType?: WebhookType): Codegen<any> | undefined {
+    if (!webhookType) {
+      return undefined
+    }
+    return this.codegensByWebhookType[webhookType]
+  }

   prepare (logicalId: string, resource: WebhookAlertChannelResource, context: Context): void {
     const { webhookType } = resource.config
-    if (webhookType) {
-      const codegen = this.codegensByWebhookType[webhookType]
-      if (codegen) {
-        codegen.prepare(logicalId, resource, context)
-        return
-      }
+    const codegen = this.getCodegenForWebhookType(webhookType)
+    if (codegen) {
+      codegen.prepare(logicalId, resource, context)
+      return
     }

     context.registerAlertChannel(resource.id, 'webhookAlert')
   }

Similarly, update the gencode() method to use this helper.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 470b019 and a26db98.

📒 Files selected for processing (3)
  • packages/cli/src/commands/import/apply.ts (1 hunks)
  • packages/cli/src/commands/import/commit.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/cli/src/commands/import/commit.ts
🧰 Additional context used
🧬 Code Definitions (1)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (7)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)
  • IncidentioAlertChannelCodegen (29-62)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)
  • MSTeamsAlertChannelCodegen (14-40)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)
  • TelegramAlertChannelCodegen (28-67)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test - windows-latest

Copy link
Contributor

@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: 0

🧹 Nitpick comments (5)
packages/cli/src/constructs/check-codegen.ts (1)

68-82: Consider adding error logging for failed private location lookups

The code silently ignores errors when looking up private locations. While this might be intentional to make private locations optional, consider at least logging a warning to help with debugging when something unexpected fails.

const privateLocationIds = (() => {
  try {
    return context.lookupCheckPrivateLocations(resource.id)
  } catch (err) {
+   console.warn(`Failed to lookup private locations for check ${resource.id}:`, err)
  }
})()
packages/cli/src/sourcegen/object.ts (2)

8-18: Consider property name and value validation.
The constructor doesn’t validate the property name or value. For added robustness, ensure that invalid or unexpected values do not slip in.


58-88: Watch for trailing commas in rendered output.
The generated code includes a comma after each property. If this output is parsed by tools that disallow trailing commas (e.g., strict JSON parsers), consider conditionally omitting the last comma.

packages/cli/src/sourcegen/objectbuilder.ts (2)

12-16: Public helper function is well-structured.
object(...) uses a builder function internally, improving code readability and reusability.


72-74: Consider clarifying structure immutability post-build.
Returning a new ObjectValue after build is typical. Include a note in docs if the resulting object is intended to be immutable or if further modifications can be made.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a26db98 and 064f700.

📒 Files selected for processing (4)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/retry-strategy-codegen.ts (1 hunks)
  • packages/cli/src/sourcegen/object.ts (1 hunks)
  • packages/cli/src/sourcegen/objectbuilder.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/cli/src/constructs/retry-strategy-codegen.ts
🧰 Additional context used
🧬 Code Definitions (2)
packages/cli/src/constructs/check-codegen.ts (5)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/sourcegen/object.ts (3)
packages/cli/src/sourcegen/index.ts (3)
  • Value (33-33)
  • ObjectValue (26-26)
  • Output (28-28)
packages/cli/src/sourcegen/objectbuilder.ts (1)
  • value (67-70)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
🪛 Biome (1.9.4)
packages/cli/src/constructs/check-codegen.ts

[error] 169-169: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 171-171: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 173-173: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 175-175: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 177-177: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

🔇 Additional comments (26)
packages/cli/src/constructs/check-codegen.ts (7)

15-33: Well-structured interface for check resources

The CheckResource interface provides a clean and comprehensive structure for representing different types of check resources. Good use of optional properties to handle various configuration options that might be present in different check types.


35-40: Well-defined function signature with clear parameters

The buildCheckProps function has a clear purpose with well-typed parameters. The void return type is appropriate since it mutates the passed builder object.


106-113: Good error handling for missing check groups

I appreciate the explicit error handling when a check references a group that isn't being imported. This will provide clear guidance to users about the dependency issue rather than failing silently.


115-143: Robust implementation of alert channel lookup and configuration

The code correctly handles the lookup of alert channels with proper error handling, and conditionally adds configuration properties only when they're defined in the resource.


164-181: Remove "return" statements in a void function

The function should not return values as its return type is declared as void. This issue was also identified by static analysis.

gencode (logicalId: string, resource: CheckResource, context: Context): void {
  const { checkType } = resource

  switch (checkType) {
    case 'BROWSER':
-     return this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+     this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+     break
    case 'API':
-     return this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+     this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+     break
    case 'TCP':
-     return this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+     this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+     break
    case 'MULTI_STEP':
-     return this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+     this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+     break
    case 'HEARTBEAT':
-     return this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+     this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+     break
    default:
      throw new Error(`Unable to generate code for unsupported check type '${checkType}'.`)
  }
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 169-169: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 171-171: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 173-173: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 175-175: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 177-177: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


154-162: Clean initialization of code generators in constructor

The initialization of all the required code generators in the constructor is clean and follows the dependency injection pattern well. This approach makes the code more maintainable and testable.


41-144: Property builder is comprehensive and handles edge cases

The implementation covers all properties from the interface definition and handles conditional properties well. The code is robust in dealing with optional values and includes proper error handling for lookups.

packages/cli/src/sourcegen/object.ts (7)

1-3: Imports look good.
No issues found with these import statements.


4-6: Interface is straightforward.
Defining order?: number as an optional property is a clear way to store sorting order.


20-21: Sorter type definition is appropriate.
Declaring a dedicated type for your property sorter helps maintain clarity.


22-24: Options interface is concise.
Optional sort property is well-defined for customizing sorting strategy.


26-36: Name-based comparator is correct.
Simple string comparison logic is fine for alphabetical sorting.


38-51: Order-based comparator is well-implemented.
Leverages the optional order property and defaults to 0 if missing. This is good.


53-56: Order-then-name sorting is coherent.
Clear fallback to name-based sorting when orders match.

packages/cli/src/sourcegen/objectbuilder.ts (12)

1-10: Imports are consistent.
No issues found with module references or import paths.


18-25: Builder constructor is clear.
Storing ObjectValueOptions in a private field is straightforward for controlling how the object is built.


26-28: String property method is concise.
Uses StringValue to encapsulate string data.


30-32: Boolean property method is consistent.
Follows the same pattern, ensuring consistent usage of typed value classes.


34-36: Number property handling is good.
No issues found here; straightforward numeric value usage.


38-40: Null property creation is clear.
Sufficiently indicates a null value.


42-44: Undefined value usage is correct.
Allows for explicit undefined representation in the generated object.


46-48: Identifier reference is well-handled.
Encapsulating an identifier in its own Value type is a good practice.


50-52: Array building integration is neat.
Supports nested structures by delegating array creation to arraybuilder.


54-56: Object building integration is straightforward.
Consistently delegates nested object creation to the object(...) helper.


58-65: Expr building is well-structured.
Uses a dedicated expr(...) builder for expressions, aligning with the rest of the pattern.


67-70: Value assignment method looks solid.
Pushing a new ObjectProperty fosters consistent property handling across the builder.

Copy link
Contributor

@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: 1

🧹 Nitpick comments (6)
packages/cli/src/constructs/private-location-codegen.ts (1)

1-56: Consider adding documentation to public API elements.

While the code is well-structured, adding JSDoc comments to the interface, function, and class would improve developer experience and make the code more maintainable.

+/**
+ * Interface representing a Private Location resource.
+ */
 export interface PrivateLocationResource {
   id: string
   name: string
   slugName: string
   icon?: string
   proxyUrl?: string
 }

 const construct = 'PrivateLocation'

+/**
+ * Creates a reference to an existing Private Location using its ID.
+ * @param program - The program to add imports to
+ * @param physicalId - The physical ID of the private location
+ * @returns A Value representing the expression to reference the private location
+ */
 export function valueForPrivateLocationFromId (program: Program, physicalId: string): Value {
   program.import(construct, 'checkly/constructs')

   return expr(ident(construct), builder => {
     builder.member(ident('fromId'))
     builder.call(builder => {
       builder.string(physicalId)
     })
   })
 }

+/**
+ * Code generator for Private Location resources.
+ * Handles the generation of TypeScript code for creating Private Location instances.
+ */
 export class PrivateLocationCodegen extends Codegen<PrivateLocationResource> {
packages/cli/src/constructs/check-codegen.ts (2)

121-126: Consider enhancing error handling in the lookupCheckAlertChannels call.

The current implementation silently catches errors when looking up check alert channels. Consider adding logging or more explicit error handling to help with debugging, especially since this pattern is used for private locations too.

  const alertChannelIds = (() => {
    try {
      return context.lookupCheckAlertChannels(resource.id)
    } catch (err) {
+     // Log or handle the error more explicitly
+     // console.debug(`No alert channels found for check ${resource.id}`)
    }
  })()

70-75: Consider enhancing error handling in the lookupCheckPrivateLocations call.

Similar to the alert channels lookup, this code silently catches errors. Adding more explicit error handling or logging would improve debuggability.

  const privateLocationIds = (() => {
    try {
      return context.lookupCheckPrivateLocations(resource.id)
    } catch (err) {
+     // Log or handle the error more explicitly
+     // console.debug(`No private locations found for check ${resource.id}`)
    }
  })()
packages/cli/src/constructs/alert-channel-codegen.ts (2)

12-19: Consider using an enum for AlertChannelType.

Using a TypeScript enum could help prevent typos and make refactoring or adding new alert channel types more maintainable.


66-95: Consider extracting a helper for retrieving alert channel codegen.

Both the prepare and gencode methods duplicate the lookup logic in this.codegensByType[...]. Factoring out a small helper function could simplify code and reduce repetition.

packages/cli/src/constructs/check-group-codegen.ts (1)

74-79: Avoid silently ignoring context lookup errors.

The code swallows possible MissingContextVariableMappingError without logging. If these lookups fail unexpectedly, debugging might be difficult. Consider logging or handling the error more explicitly to surface issues earlier.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 064f700 and 4021e4a.

📒 Files selected for processing (4)
  • packages/cli/src/constructs/alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
packages/cli/src/constructs/check-codegen.ts (8)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (2)
  • ApiCheckCodegen (42-153)
  • ApiCheckResource (8-19)
packages/cli/src/constructs/alert-channel-codegen.ts (10)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1)
  • PhoneCallAlertChannelCodegen (15-44)
packages/cli/src/constructs/email-alert-channel-codegen.ts (1)
  • EmailAlertChannelCodegen (14-37)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1)
  • OpsgenieAlertChannelCodegen (17-45)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1)
  • PagerdutyAlertChannelCodegen (16-49)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)
  • SlackAlertChannelCodegen (15-44)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)
  • SmsAlertChannelCodegen (15-44)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1)
  • WebhookAlertChannelCodegen (78-136)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/check-group-codegen.ts (9)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (1)
  • valueForAssertion (21-38)
packages/cli/src/constructs/private-location-codegen.ts (3)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
🪛 Biome (1.9.4)
packages/cli/src/constructs/check-codegen.ts

[error] 179-179: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 181-181: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 183-183: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 185-185: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 187-187: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

🔇 Additional comments (11)
packages/cli/src/constructs/private-location-codegen.ts (6)

1-3: Imports look good!

The imports correctly bring in the necessary dependencies from internal code generation utilities and source generation modules.


4-10: Well-defined interface for private location resources.

The interface properly defines the required and optional properties for a private location resource, making it clear what data is needed for code generation.


12-12: Good use of constant for construct name.

Using a constant for the construct name prevents string duplication and makes maintenance easier.


14-23: Utility function looks good!

This utility function correctly generates code to reference an existing private location by ID. It properly imports the necessary construct and builds the expression using the builder pattern.


25-29: Preparation method correctly registers resources.

The prepare method correctly registers the private location ID in the context, which will be used later during code generation.


30-54: Code generation implementation is well structured.

The gencode method:

  • Imports the necessary construct
  • Looks up the registered private location
  • Generates code with proper conditional handling of optional properties

The code follows the builder pattern consistently and handles the optional properties (icon and proxyUrl) correctly.

packages/cli/src/constructs/check-codegen.ts (3)

174-191: Remove "return" statements in a void function.

Static analysis indicates returning from a function with return type void is unnecessary. Instead of returning the sub-codegen calls, simply invoke them and break out of the switch.

  gencode (logicalId: string, resource: CheckResource, context: Context): void {
    const { checkType } = resource

    switch (checkType) {
      case 'BROWSER':
-       return this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+       this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+       break
      case 'API':
-       return this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+       this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+       break
      case 'TCP':
-       return this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+       this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+       break
      case 'MULTI_STEP':
-       return this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+       this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+       break
      case 'HEARTBEAT':
-       return this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+       this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+       break
      default:
        throw new Error(`Unable to generate code for unsupported check type '${checkType}'.`)
    }
  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 179-179: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 181-181: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 183-183: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 185-185: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 187-187: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


37-154: Well-structured property building function.

The buildCheckProps function is well-organized, handling all required and optional properties of a check resource appropriately. It properly deals with different types of properties (boolean, string, arrays) and includes good error handling for resource lookups.


17-35: Well-defined interface with complete check properties.

The CheckResource interface provides a comprehensive definition of common check properties with appropriate optional markers. This creates a solid foundation for specific check type interfaces to extend.

packages/cli/src/constructs/alert-channel-codegen.ts (1)

97-113: Add test coverage for unsupported channel types.

Although there’s a runtime error thrown for unsupported alert channel types, consider adding tests to confirm this error path behaves correctly. This ensures future channel additions don't accidentally break or bypass this check.

packages/cli/src/constructs/check-group-codegen.ts (1)

1-263: Overall Implementation Appears Strong.

No concurrency or security concerns are evident, and the modular code design aligns well with the existing codegen framework.

@sorccu sorccu force-pushed the simokinnunen/sc-23506/cli-import-existing-resources branch from 4021e4a to a252605 Compare March 28, 2025 09:00
Copy link
Contributor

@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: 1

🧹 Nitpick comments (41)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1)

3-17: Looks good—consider additional validation or tests
This code successfully registers the private location group assignment. Optionally, you could verify whether both privateLocationId and groupId point to valid, registered entities and add corresponding test coverage.

Would you like help creating a test snippet or a helper method to check resource validity before registering?

packages/cli/src/constructs/api-check-codegen.ts (2)

110-123: Avoid potential overwrite of the setupScript property
If both localSetupScript and setupScriptPath are defined, two separate objects for setupScript will be generated, which may lead to unexpected behavior. Consider using an else if for one or defining a clear precedence.

if (resource.localSetupScript) {
  // ...
} else if (resource.setupScriptPath) {
  // ...
}

125-138: Clarify precedence for the tearDownScript property
Similar to the setup script, defining both localTearDownScript and tearDownScriptPath will build two tearDownScript objects. Using an else if or a deliberate override strategy can reduce confusion.

if (resource.localTearDownScript) {
  // ...
} else if (resource.tearDownScriptPath) {
  // ...
}
packages/cli/src/commands/import/apply.ts (2)

22-40: Handle Zero-Plan Scenario Gracefully.

If unappliedPlans is empty, the user receives a prompt referencing "0 unapplied plan(s)" with only an Exit option. Consider an early exit or a user-friendly message indicating no plans exist, which would improve the user experience.

 if (unappliedPlans.length === 0) {
+  this.log('No unapplied plans found. Exiting without making any changes.')
+  this.exit(0)
 }

47-59: Provide Additional Error Context When Plan Application Fails.

If applyImportPlan(plan.id) fails, adding details about the failing plan (e.g. plan ID, creation time) can simplify troubleshooting.

try {
  await api.projects.applyImportPlan(plan.id)
} catch (err) {
+  this.warn(`Failed to apply plan #${plan.id}.`)
  throw err
}
packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)

5-11: Consider Validating Slack URL and Channel.

While the resource interface is straightforward, additional validation (or user feedback on invalid props) could improve reliability, especially if the URL or channel is malformed.

packages/cli/src/constructs/email-alert-channel-codegen.ts (1)

5-10: Consider Email Address Validation.

Currently, any string is accepted as the address. Providing basic format checks or user feedback on invalid addresses can enhance the robustness of the generator.

packages/cli/src/commands/import/plan.ts (4)

18-28: Consider adding a brief doc comment for the ImportPlanCommand class.

A short description of the class purpose, key steps performed in the run method, and usage notes can improve maintainability and help other collaborators.


66-79: Handle other HTTP error codes for plan creation.

At present, the code specifically checks for a 404 status. Consider handling other status codes (e.g., 401, 403) or providing a default human-readable message to guide end-users. This ensures more complete error handling and improves the user experience.


112-117: Allow customization of the generated output filename.

The generated code is written to ./generated.check.ts by default. For improved flexibility, consider adding a flag or configuration parameter to specify a custom filename or directory path.


130-223: Check for batched cancellation to increase performance.

The existing approach cancels each plan in sequence. If performance or rate-limiting becomes a concern, consider a batched API or parallel cancellation strategy (if supported by the backend) to handle multiple cancellations more efficiently.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)

20-43: Validate phone number formats.

Optionally, you could validate or normalize the phone number prior to code generation to prevent invalid phone entries. Although not strictly required, it can help reduce errors in downstream usage.

packages/cli/src/sourcegen/declbuilder.ts (2)

20-23: Consider handling multiple variable calls.
Current design overwrites #decl each time variable() is called. If the builder is meant to allow multiple variable declarations before a final build, this would discard prior declarations. Clarify if only one variable creation per DeclarationBuilder is intended.


25-28: export() chaining caution.
Wrapping the existing declaration in ExportDeclaration repeatedly could cause nested exports if export() is called multiple times. Confirm whether repeated calls should either be disallowed or replaced with a single export operation.

packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)

19-39: Ensure config integrity before code generation.
While code generation proceeds smoothly, consider validating config (e.g., name, url) before generating the block to avoid runtime issues.

packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1)

20-43: Validate critical fields in config.
Consider basic checks or user-friendly error messages for missing or invalid phone numbers (config.number) before generating code, preventing potential runtime failures.

packages/cli/src/constructs/check-codegen.ts (3)

70-75: Improve error handling for privateLocationIds lookup.

The function silently ignores errors when looking up privateLocationIds. This makes debugging harder if something goes wrong.

Consider adding proper error handling:

  const privateLocationIds = (() => {
    try {
      return context.lookupCheckPrivateLocations(resource.id)
    } catch (err) {
+     // If this is not a MissingContextVariableMappingError, rethrow
+     if (!(err instanceof MissingContextVariableMappingError)) {
+       throw err
+     }
+     // Otherwise, return undefined to indicate no private locations
    }
  })()

121-126: Improve error handling for alertChannelIds lookup.

Similar to the privateLocationIds lookup, errors are silently ignored when looking up alertChannelIds.

Consider adding proper error handling:

  const alertChannelIds = (() => {
    try {
      return context.lookupCheckAlertChannels(resource.id)
    } catch (err) {
+     // If this is not a MissingContextVariableMappingError, rethrow
+     if (!(err instanceof MissingContextVariableMappingError)) {
+       throw err
+     }
+     // Otherwise, return undefined to indicate no alert channels
    }
  })()

112-119: Enhance error message for group lookup failure.

The current error message when a check belongs to a group that is not being imported could be more descriptive to help with troubleshooting.

Provide a more informative error message:

    try {
      const groupVariable = context.lookupCheckGroup(resource.groupId)
      builder.value('group', groupVariable)
    } catch (err) {
-     throw new Error('Check belongs to a group that is not being imported.')
+     throw new Error(`Check "${resource.name}" (ID: ${resource.id}) belongs to group ${resource.groupId} which is not being imported. Please include this group in your import selection.`)
    }
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (2)

13-25: Consider adding a return type annotation to apiKeyFromHeaders.

Adding a type annotation would improve TypeScript's ability to catch potential issues.

-function apiKeyFromHeaders (headers: HttpHeader[]): string | undefined {
+function apiKeyFromHeaders (headers: HttpHeader[]): string | undefined {

49-54: Consider adding a dedicated function for API key extraction.

The implementation extracts the API key from headers but embeds this logic directly within the gencode method. Consider refactoring for better testability and reusability.

  if (config.headers) {
    const apiKey = apiKeyFromHeaders(config.headers)
    if (apiKey) {
      builder.string('apiKey', apiKey)
    }
  }

The extraction logic is already in a dedicated function, which is good. Consider adding unit tests for the apiKeyFromHeaders function to ensure it behaves as expected with different input formats.

packages/cli/src/sourcegen/object.ts (3)

4-7: Optional order property
It might be helpful to add a docstring clarifying how order is intended to be used if there's a default ordering mechanism.


38-51: sortObjectPropertiesByOrder
Provides a straightforward numeric sort. Consider clarifying that 0 is the default priority.


68-88: render method
Nicely handles indentation and sorting. Consider whether trailing commas are acceptable in the generated output.

packages/cli/src/constructs/construct-codegen.ts (3)

25-29: Resource interface
Properties are sufficiently generic. Potentially add doc comments describing payload.


88-95: prepare method usage
Unused parameter logicalId overshadowed by resource.logicalId. Consider removing or using the passed-in logicalId to avoid confusion.

-prepare (logicalId: string, resource: Resource, context: Context): void {
-  codegen.prepare(resource.logicalId, resource.payload, context)
+prepare (_: string, resource: Resource, context: Context): void {
+  codegen.prepare(resource.logicalId, resource.payload, context)
}

97-104: gencode method
Same overshadowing of logicalId. Consistency with prepare method changes is recommended.

packages/cli/src/rest/projects.ts (3)

43-49: ImportPlan interface
Adequately covers creation, apply, and commit timestamps. Consider clarifying how changes is updated.


85-92: findImportPlans method
Filtering with onlyUnapplied and onlyUncommitted is a clear approach. Ensure pagination if the resource set grows large.


94-101: listImportPlans method
Global listing with optional filters is consistent with findImportPlans. Possibly unify code for DRY principle.

packages/cli/src/constructs/private-location-codegen.ts (1)

4-10: Consider adding doc comments to clarify usage.

The PrivateLocationResource interface is succinct and clear. However, adding JSDoc comments or TypeScript doc comments for each property can help other contributors understand the intended usage and constraints (especially for slugName, icon, and proxyUrl).

packages/cli/src/constructs/check-group-codegen.ts (4)

45-92: Error swallowing in private location lookup.

In lines 77-78, an error from lookupCheckGroupPrivateLocations is caught but silently ignored. Consider at least logging a warning to help diagnose missing context if the ID is invalid.


103-114: Check secret environment variables usage.

The environmentVariables array is appended without further logic to handle secrets. If secrets require special handling, consider clarifying or enforcing additional constraints here.


116-134: Similar fallback approach for alert channels.

Like the private location logic, the code here also swallows errors when looking up alert channels. Evaluate whether silent failure is appropriate or if a warning/log statement can be beneficial.


180-229: Optional expansions for apiCheckDefaults.

The property coverage is good, including headers, query parameters, and basic auth. While it appears sufficient, verify if advanced handlers (like OAuth flows) might need future expansions.

packages/cli/src/sourcegen/expr.ts (2)

42-57: Handle bracket notation for non-identifier properties.

The comment suggests a future enhancement (line 55). Consider adding logic to decide whether to use dot or bracket notation, enabling usage with invalid identifier characters.


82-99: Potential expansion for more unary operators.

At the moment, only '!' is supported. Evaluate whether unary plus, minus, or bitwise operators are relevant for your use cases.

packages/cli/src/constructs/alert-channel-codegen.ts (1)

21-29: Consider aligning optional checks with interface fields.

All boolean fields are typed as required, yet the code checks for !== undefined in buildAlertChannelProps. If sendRecovery, sendFailure, etc., can indeed be omitted, mark them optional in the interface to avoid confusion.

packages/cli/src/sourcegen/argsbuilder.ts (2)

19-62: Use tests to confirm value correctness
All the methods for building arguments appear well-structured. Ensure there is test coverage for each method to confirm that these different value types (strings, booleans, numbers, etc.) are emitted and rendered correctly.


64-76: Evaluate immutability or stricter usage
Consider whether mutating the same builder instance across multiple steps might introduce edge cases in complex codegen flows. An alternative pattern is returning a fresh builder when calling value() or marking the collection as read-only after building.

packages/cli/src/constructs/internal/codegen/context.ts (1)

17-120: Validate potential re-registration cases
Each register method overwrites or adds new entries without verifying the existence of a previous mapping. If re-registering a resource with a different identifier is undesired, consider adding checks or warnings.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4021e4a and a252605.

📒 Files selected for processing (65)
  • packages/cli/e2e/__tests__/help.spec.ts (2 hunks)
  • packages/cli/package.json (1 hunks)
  • packages/cli/src/commands/import/apply.ts (1 hunks)
  • packages/cli/src/commands/import/cancel.ts (1 hunks)
  • packages/cli/src/commands/import/commit.ts (1 hunks)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group.ts (1 hunks)
  • packages/cli/src/constructs/construct-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/email-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/frequency-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/assertion-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/index.ts (1 hunks)
  • packages/cli/src/constructs/key-value-pair-codegen.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config.ts (0 hunks)
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/ref-codegen.ts (1 hunks)
  • packages/cli/src/constructs/retry-strategy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/rest/projects.ts (3 hunks)
  • packages/cli/src/sourcegen/args.ts (1 hunks)
  • packages/cli/src/sourcegen/argsbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/array.ts (1 hunks)
  • packages/cli/src/sourcegen/arraybuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/boolean.ts (1 hunks)
  • packages/cli/src/sourcegen/decl.ts (1 hunks)
  • packages/cli/src/sourcegen/declbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/expr.ts (1 hunks)
  • packages/cli/src/sourcegen/exprbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/identifier.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
  • packages/cli/src/sourcegen/null.ts (1 hunks)
  • packages/cli/src/sourcegen/number.ts (1 hunks)
  • packages/cli/src/sourcegen/object.ts (1 hunks)
  • packages/cli/src/sourcegen/objectbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/output.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
  • packages/cli/src/sourcegen/string.ts (1 hunks)
  • packages/cli/src/sourcegen/undefined.ts (1 hunks)
  • packages/cli/src/sourcegen/unknown.ts (1 hunks)
  • packages/cli/src/sourcegen/value.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/cli/src/constructs/playwright-config.ts
🚧 Files skipped from review as they are similar to previous changes (36)
  • packages/cli/src/sourcegen/undefined.ts
  • packages/cli/src/sourcegen/null.ts
  • packages/cli/src/sourcegen/boolean.ts
  • packages/cli/e2e/tests/help.spec.ts
  • packages/cli/src/sourcegen/number.ts
  • packages/cli/src/constructs/internal/codegen/index.ts
  • packages/cli/src/sourcegen/value.ts
  • packages/cli/package.json
  • packages/cli/src/sourcegen/program.ts
  • packages/cli/src/sourcegen/args.ts
  • packages/cli/src/constructs/playwright-config-codegen.ts
  • packages/cli/src/constructs/check-group.ts
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/src/sourcegen/identifier.ts
  • packages/cli/src/commands/import/cancel.ts
  • packages/cli/src/sourcegen/array.ts
  • packages/cli/src/sourcegen/unknown.ts
  • packages/cli/src/sourcegen/string.ts
  • packages/cli/src/constructs/ref-codegen.ts
  • packages/cli/src/constructs/frequency-codegen.ts
  • packages/cli/src/commands/import/commit.ts
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/constructs/internal/codegen/codegen.ts
  • packages/cli/src/constructs/retry-strategy-codegen.ts
  • packages/cli/src/constructs/key-value-pair-codegen.ts
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/sourcegen/output.ts
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts
  • packages/cli/src/constructs/maintenance-window-codegen.ts
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts
  • packages/cli/src/sourcegen/exprbuilder.ts
  • packages/cli/src/constructs/heartbeat-check-codegen.ts
  • packages/cli/src/sourcegen/decl.ts
  • packages/cli/src/sourcegen/index.ts
  • packages/cli/src/constructs/alert-channel-subscription-codegen.ts
🧰 Additional context used
🧬 Code Definitions (17)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/api-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-154)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (2)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/email-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/private-location-codegen.ts (3)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (7)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)
  • IncidentioAlertChannelCodegen (29-62)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)
  • MSTeamsAlertChannelCodegen (14-40)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)
  • TelegramAlertChannelCodegen (28-67)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (3)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/tcp-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-154)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForGeneralAssertion (45-146)
  • valueForNumericAssertion (4-43)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/sourcegen/object.ts (3)
packages/cli/src/sourcegen/index.ts (3)
  • Value (33-33)
  • ObjectValue (26-26)
  • Output (28-28)
packages/cli/src/sourcegen/objectbuilder.ts (1)
  • value (67-70)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/construct-codegen.ts (12)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • AlertChannelCodegen (66-114)
packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1)
  • AlertChannelSubscriptionCodegen (9-24)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckCodegen (156-192)
packages/cli/src/constructs/check-group-codegen.ts (1)
  • CheckGroupCodegen (241-262)
packages/cli/src/constructs/dashboard-codegen.ts (1)
  • DashboardCodegen (31-140)
packages/cli/src/constructs/maintenance-window-codegen.ts (1)
  • MaintenanceWindowCodegen (16-64)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • PrivateLocationCodegen (25-55)
packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1)
  • PrivateLocationCheckAssignmentCodegen (8-17)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1)
  • PrivateLocationGroupAssignmentCodegen (8-17)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/check-codegen.ts (14)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/sourcegen/objectbuilder.ts (1)
  • ObjectValueBuilder (18-75)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (2)
  • ApiCheckCodegen (42-153)
  • ApiCheckResource (8-19)
packages/cli/src/constructs/check-group-codegen.ts (1)
  • CheckGroupCodegen (241-262)
packages/cli/src/constructs/heartbeat-check-codegen.ts (2)
  • HeartbeatCheckCodegen (11-29)
  • HeartbeatCheckResource (6-9)
packages/cli/src/constructs/multi-step-check-codegen.ts (2)
  • MultiStepCheckCodegen (15-42)
  • MultiStepCheckResource (6-11)
packages/cli/src/constructs/tcp-check-codegen.ts (2)
  • TcpCheckCodegen (29-72)
  • TcpCheckResource (7-12)
packages/cli/src/constructs/alert-channel-codegen.ts (9)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1)
  • PhoneCallAlertChannelCodegen (15-44)
packages/cli/src/constructs/email-alert-channel-codegen.ts (1)
  • EmailAlertChannelCodegen (14-37)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1)
  • OpsgenieAlertChannelCodegen (17-45)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1)
  • PagerdutyAlertChannelCodegen (16-49)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)
  • SlackAlertChannelCodegen (15-44)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)
  • SmsAlertChannelCodegen (15-44)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1)
  • WebhookAlertChannelCodegen (78-136)
packages/cli/src/constructs/check-group-codegen.ts (9)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (1)
  • valueForAssertion (21-38)
packages/cli/src/sourcegen/argsbuilder.ts (2)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/args.ts (1)
  • ArgumentsValue (4-27)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
🪛 Biome (1.9.4)
packages/cli/src/constructs/check-codegen.ts

[error] 179-179: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 181-181: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 183-183: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 185-185: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 187-187: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

🔇 Additional comments (61)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)

15-38: Potential float precision issue when parsing numbers
This section uses parseInt for numeric comparisons, which may cause precision issues if floating-point values are involved. A previous review comment suggested using Number(...) instead of parseInt.

-          builder.number(parseInt(assertion.target, 10))
+          builder.number(Number(assertion.target))

106-117: String-based numeric comparisons could cause unexpected results
Performing 'LESS_THAN' and 'GREATER_THAN' checks with string inputs can be incorrect for numeric comparisons. This was raised in a previous review. Consider dynamically checking if the target is numeric first and using .number(...) when appropriate.

case 'LESS_THAN':
  builder.member(ident('lessThan'))
  builder.call(builder => {
-    builder.string(assertion.target)
+    const numValue = Number(assertion.target)
+    if (!isNaN(numValue)) {
+      builder.number(numValue)
+    } else {
+      builder.string(assertion.target)
+    }
  })
  break
packages/cli/src/constructs/api-check-codegen.ts (1)

21-38: Straightforward assertion handling
The valueForAssertion function consistently delegates numeric and general assertions to the respective handlers. The error handling for unsupported sources appears robust. Nice work.

packages/cli/src/commands/import/apply.ts (1)

62-95: Plan Selection Logic Appears Robust.

The method correctly maps plans to distinct choices, handles cancellation scenarios, and exits cleanly if the user selects "Exit." No further concerns.

packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)

15-45: Implementation Successfully Integrates Slack Alert Channel.

The code correctly uses the context to register the alert channel and generate the Slack construct. Looks good overall.

packages/cli/src/constructs/email-alert-channel-codegen.ts (1)

14-36: Code Generation Logic for Email Alert Channel Looks Solid.

Registration in Context and subsequent generation with buildAlertChannelProps is implemented cleanly. No issues found here.

packages/cli/src/commands/import/plan.ts (1)

29-51: [Duplicate of previous feedback] Add unit tests for existing plan handling.

A prior review comment already highlighted insufficient test coverage regarding existing import plans. Specifically, lines 29–51 should be tested to ensure the workflow is correct when existing plans are found. Please add these tests or confirm they already exist to address past feedback.

packages/cli/src/constructs/tcp-check-codegen.ts (3)

7-12: Confirm property naming and data types in TcpCheckResource.

The fields degradedResponseTime and maxResponseTime are optional numeric values. Ensure consuming code (e.g., resource import or plan application) uses consistent naming and handles undefined values gracefully.


14-25: Good use of a default case for unknown assertion sources.

The default branch in valueForTcpAssertion appropriately throws an error for unsupported sources, preventing silent failures.


29-71: Overall implementation is clear and maintainable.

The class effectively imports the TcpCheck construct, sets up resource requests, and extends the base code generation approach. No critical issues noted.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)

16-19: Consider verifying test coverage for prepare method.

This method registers the alert channel in the context. Be sure to add or confirm the presence of tests that verify the mapping is set correctly in various scenarios (e.g., multiple SMS channels, duplicates).

packages/cli/src/sourcegen/declbuilder.ts (2)

1-3: Imports look consistent with usage.
All imported entities (Declaration, IdentifierDeclaration, etc.) are properly utilized and help maintain strong typing.


5-9: Builder pattern is straightforward and adaptable.
The decl function succinctly captures and applies the builder logic, keeping the implementation simple and readable.

packages/cli/src/constructs/msteams-alert-channel-codegen.ts (2)

6-10: Interface properly extends the webhook resource.
Ensures the MSTeamsAlertChannelResource inherits all relevant webhook fields while enforcing a fixed webhookType.


15-17: Alert channel registration aligns with existing context usage.
Registering the channel with a teamsAlert prefix is consistent with naming strategies for other alert types.

packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (2)

5-11: Resource interface is clear and minimal.
Defines only the necessary properties (type, config) to represent a phone call alert channel.


16-18: Intentional naming for channel prefix.
Registering the alert channel with 'phoneCallAlert' ensures consistent variable naming across the codebase.

packages/cli/src/constructs/check-codegen.ts (1)

174-191: Remove "return" statements in a void function.

The gencode method is declared with a return type of void, but it's returning values from the function calls in the switch statement. This is flagged by Biome as a correctness issue.

Apply this diff to fix the issues:

  gencode (logicalId: string, resource: CheckResource, context: Context): void {
    const { checkType } = resource

    switch (checkType) {
      case 'BROWSER':
-       return this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+       this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+       break
      case 'API':
-       return this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+       this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+       break
      case 'TCP':
-       return this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+       this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+       break
      case 'MULTI_STEP':
-       return this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+       this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+       break
      case 'HEARTBEAT':
-       return this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+       this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+       break
      default:
        throw new Error(`Unable to generate code for unsupported check type '${checkType}'.`)
    }
  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 179-179: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 181-181: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 183-183: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 185-185: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 187-187: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1)

1-45: LGTM! Well-structured OpsGenie alert channel codegen implementation.

The implementation is clean and follows the established pattern for alert channel codegen classes, with proper use of the builder pattern and error handling.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1)

1-49: LGTM! Well-structured PagerDuty alert channel codegen implementation.

The implementation correctly handles optional fields with conditional inclusion, follows the established pattern for alert channel codegen classes, and properly uses the builder pattern.

packages/cli/src/sourcegen/object.ts (8)

1-3: Imports look good
Straightforward imports from local modules. No issues spotted.


8-18: Class ObjectProperty is well-structured
All fields and constructor usage look clean.


20-21: Sorter type
Defining a dedicated type for the sorter enhances readability and maintainability.


22-24: Optional sorter in ObjectValueOptions
Having a configurable sorter is a nice design for flexible property ordering.


26-36: sortObjectPropertiesByName
Clear, simple string comparison. No issues found.


53-56: sortObjectPropertiesByOrderAndName
Combines sorting logic well. Implementation is concise and correct.


58-61: ObjectValue extends Value
Good extension approach. The additional properties and options are well-defined here.


62-66: ObjectValue constructor
Successfully delegates setup to super() and sets optional fields. No concerns.

packages/cli/src/constructs/construct-codegen.ts (4)

14-24: Introduction of ResourceType
Enumerating resource types in a string union helps clarify valid resource kinds.


43-49: sortResources function
Descending sort logic is correct (return bo - ao).


51-86: ConstructCodegen class fields
Declaring multiple codegen fields is tidy. The map-based approach in codegensByType is easy to maintain.


31-41:

✅ Verification successful

resourceOrder object
Straightforward numeric ordering. Confirm that no resource type is missing.


🏁 Script executed:

#!/bin/bash
# Check if all ResourceTypes are in the resourceOrder object
rg "type ResourceType" -A 10
rg "const resourceOrder" -A 20

Length of output: 2471


ResourceOrder Definition Verified
The verification confirms that every resource type declared in the ResourceType union is correctly represented in the resourceOrder object. No resource type is missing, and the numeric ordering appears complete and consistent.

packages/cli/src/rest/projects.ts (6)

27-27: ResourceSync interface
No immediate issues. Ensure that member is consistently used.


39-41: ImportPlanChanges interface
Defines an array of ResourceSync objects. Straightforward structure.


103-105: cancelImportPlan method
Straightforward DELETE request. Check that partial cancellations are handled or if there's a progress lock.


107-109: applyImportPlan method
Applies an import plan. Consider verifying if a plan can only be applied once.


111-113: commitImportPlan method
Finish the import plan lifecycle. Good separation of responsibilities.


81-83:

❓ Verification inconclusive

createImportPlan method
POST request to create a plan. Please confirm error handling in case of invalid logicalId.


🏁 Script executed:

#!/bin/bash
# Searching for error-handling references in createImportPlan usage
rg "createImportPlan"

Length of output: 207


Attention: Confirm Error Handling for Invalid LogicalId in Import Plan Creation

The createImportPlan method (in packages/cli/src/rest/projects.ts) simply wraps the POST request and does not itself implement explicit error handling. The only usage we found—in packages/cli/src/commands/import/plan.ts—calls the method directly without a surrounding try/catch block. This indicates that error handling for an invalid logicalId is likely expected to be managed upstream or via a global error handler.

  • Verify that the calling code or global middleware properly catches and handles errors from this API call.
  • If not already in place, consider adding explicit error handling (e.g., try/catch or promise rejection handling) around the call in packages/cli/src/commands/import/plan.ts.
packages/cli/src/constructs/private-location-codegen.ts (3)

14-23: Ensure error handling for invalid IDs.

valueForPrivateLocationFromId simply invokes PrivateLocation.fromId without handling potential errors if the physical ID is invalid. Confirm whether your codebase expects such an exception upstream or if you should handle it more gracefully.


25-29: Looks good!

The prepare method properly registers the private location. This approach is consistent with the rest of the context registration pattern.


30-54: Implementation is solid.

Creating a new instance of PrivateLocation conditionally includes optional parameters, maintaining a clear and straightforward code generation flow.

packages/cli/src/constructs/check-group-codegen.ts (6)

13-22: Browser and multi-step check interfaces look good.

BrowserCheckConfigResource and MultiStepCheckConfigResource well-encapsulate their respective fields. Future expansions (e.g., advanced configuration) can be easily added.


23-43: Review required for concurrency and runParallel parameters.

The CheckGroupResource interface contains concurrency and runParallel fields separately, which might overlap in meaning. Validate if both should coexist or if they can be unified to prevent confusion.


136-158: Validate additional browser check fields beyond frequency.

Currently, only testMatch and frequency are handled for browser checks. Confirm if other fields (e.g., runtimeId, timeouts) could be relevant and missed here.


160-178: Multi-step checks logic parallels browser checks nicely.

No immediate issues. The approach reuses the same pattern to handle testMatch and frequency, providing consistency across check types.


232-236: Default retry strategy properly conveyed.

valueForRetryStrategy covers multiple strategies, ensuring a safe default of no retries. This is a clean way to preserve extension capability.


239-262: Class design is consistent.

The prepare and gencode methods parallel the rest of the codegen modules, promoting clarity and uniformity across resource types.

packages/cli/src/sourcegen/expr.ts (4)

5-7: Abstract class is appropriately minimal.

ExpressionValue sets the foundation for subclass expression types. The current design is straightforward and flexible.


8-24: Constructor-based approach is clean.

NewExpressionValue straightforwardly manages the 'new' keyword, keeping the code maintainable and easily extensible.


26-40: No improvements needed.

CallExpressionValue logically captures function calls. Ensuring argument rendering is consistent with the rest of the expression model.


59-80: Limited operator support.

Currently only +, -, &&, and || are supported in BinaryOperator. If you need other operators (e.g., *, /, comparison operators), extending this type is straightforward.

packages/cli/src/constructs/alert-channel-codegen.ts (3)

53-64: Function valueForAlertChannelFromId is well-designed.

This utility neatly encapsulates the logic for retrieving an alert channel from its physical ID, and the import ensures that the relevant construct is used. No issues found.


66-95: Constructor logic with typed codegens is clear and organized.

The record codegensByType cleanly maps each AlertChannelType to a specialized codegen instance. This pattern is easy to extend for future alert channel types.


97-114: prepare and gencode methods handle unsupported types gracefully.

Throwing an error on an unknown resource.type is an effective safeguard. The forward calls to the correct specialized codegen are well-structured.

packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)

79-80: Typographical mismatch in indicentioCodegen vs. IncidentioAlertChannelCodegen.

This was raised before. Consider renaming the property to align with the class name (“incidentio”) for clarity.


97-135: Granular delegation in prepare and gencode is consistent.

The conditional logic properly routes each webhook type to its respective specialized codegen. Registering the alert channel in context if no specialized codegen is found is a sensible fallback.

packages/cli/src/sourcegen/arraybuilder.ts (1)

1-75: Array builder API is comprehensive and well-structured.

Each method (e.g. string, boolean, ident) is intuitive, ensuring readability and extensibility. No concerns found with performance or correctness.

packages/cli/src/sourcegen/argsbuilder.ts (1)

13-17: Implementation is straightforward
No issues found with the args function. The approach of delegating to the builder is clean and consistent with typical builder patterns.

packages/cli/src/sourcegen/objectbuilder.ts (2)

12-16: Straightforward object builder entrypoint
The top-level object function nicely encapsulates the builder usage. This pattern is consistent with your approach in argsbuilder.ts.


18-76: Consider detection of duplicate property names
There is no check for accidentally adding the same property multiple times. If silent overwriting is unintentional, consider adding a guard or logging to alert developers when a property is already present.

packages/cli/src/constructs/internal/codegen/context.ts (1)

5-15: Good use of private maps
Storing context variables in private maps helps encapsulate resource-specific tracking and prevents direct external mutation. No immediate concerns here.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1)

33-74: Consider removing redundant toString() call.
config.url is already a string, so calling toString() is not strictly necessary. You can safely omit it or convert it only if some special string formatting is required.

-  builder.string('url', config.url.toString())
+  builder.string('url', config.url)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a252605 and 57927ef.

📒 Files selected for processing (1)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (7)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)
  • IncidentioAlertChannelCodegen (29-62)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)
  • MSTeamsAlertChannelCodegen (14-40)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)
  • TelegramAlertChannelCodegen (28-67)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (5)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (5)

1-16: Imports and WebhookType look consistent.
These imports and the WebhookType definition align well with the other alert channel codegens. No issues found here.


17-31: Optional webhookType usage is clear.
Making webhookType optional provides flexibility for fallback generation when webhookType is not specified.


76-95: Codegen constructors look valid.
The constructor properly initializes subtype codegens and keeps a neat mapping in codegensByWebhookType.


97-108: No concerns with the prepare implementation.
The fallback path of registering a generic “webhookAlert” is a good approach for unrecognized or missing webhookType.


110-135: Request tests for fallback scenario.
When webhookType is missing or unrecognized, the code uses the fallback path. Consider adding a dedicated test to ensure the resulting resource is generated as expected.

Would you like me to generate a test to verify the fallback generation scenario?

Copy link
Contributor

@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: 0

🧹 Nitpick comments (7)
packages/cli/src/constructs/api-check-codegen.ts (2)

118-132: Consider refactoring duplicated script handling logic

The setup and teardown script handling code is nearly identical, with only naming differences. This could be extracted into a helper method to avoid code duplication.

+ private buildScriptContent(
+   builder: any,
+   propertyName: string,
+   localScript?: string,
+   scriptResource?: SnippetResource
+ ): void {
+   if (localScript) {
+     const content = localScript;
+     builder.object(propertyName, builder => {
+       builder.string('content', content);
+     });
+   } else if (scriptResource?.script) {
+     const script = scriptResource.script;
+     builder.object(propertyName, builder => {
+       // TODO: Move to a separate file and use entrypoint instead.
+       builder.string('content', script);
+     });
+   }
+ }

  gencode (logicalId: string, resource: ApiCheckResource, context: Context): void {
    // ... existing code ...

-   if (resource.localSetupScript) {
-     const content = resource.localSetupScript
-     builder.object('setupScript', builder => {
-       builder.string('content', content)
-     })
-   } else if (resource.setupScript) {
-     const snippet = resource.setupScript
-     if (snippet.script !== undefined) {
-       const script = snippet.script
-       builder.object('setupScript', builder => {
-         // TODO: Move to a separate file and use entrypoint instead.
-         builder.string('content', script)
-       })
-     }
-   }
+   this.buildScriptContent(
+     builder,
+     'setupScript',
+     resource.localSetupScript,
+     resource.setupScript
+   );

-   if (resource.localTearDownScript) {
-     const content = resource.localTearDownScript
-     builder.object('tearDownScript', builder => {
-       builder.string('content', content)
-     })
-   } else if (resource.tearDownScript) {
-     const snippet = resource.tearDownScript
-     if (snippet.script !== undefined) {
-       const script = snippet.script
-       builder.object('tearDownScript', builder => {
-         // TODO: Move to a separate file and use entrypoint instead.
-         builder.string('content', script)
-       })
-     }
-   }
+   this.buildScriptContent(
+     builder,
+     'tearDownScript',
+     resource.localTearDownScript,
+     resource.tearDownScript
+   );

Also applies to: 134-148


108-115: Validate empty strings in basicAuth check

The code checks if the username and password are not empty strings before including basicAuth. Consider using a more robust validation that also checks for undefined/null values.

- if (basicAuth.username !== '' && basicAuth.password !== '') {
+ if (basicAuth.username && basicAuth.password) {
packages/cli/src/constructs/private-location-codegen.ts (2)

4-10: Well-defined interface with appropriate optional properties

The PrivateLocationResource interface clearly defines the structure with required fields (id, name, slugName) and optional fields (icon, proxyUrl) properly marked with the optional operator ?.

Consider adding JSDoc comments to document the purpose of this interface and its properties for better developer experience.


30-56: Code generation method with proper structure and conditional properties

The gencode method:

  1. Imports the necessary construct
  2. Looks up the previously registered ID
  3. Generates appropriate code with conditional properties
  4. Properly exports the generated variable

The conditional inclusion of optional properties (icon and proxyUrl) only when they are provided is a good practice.

I would recommend adding error handling for the context lookup operation, as it will throw if the resource ID is not found.

  gencode (logicalId: string, resource: PrivateLocationResource, context: Context): void {
    this.program.import(construct, 'checkly/constructs')

-   const id = context.lookupPrivateLocation(resource.id)
+   let id;
+   try {
+     id = context.lookupPrivateLocation(resource.id)
+   } catch (error) {
+     throw new Error(`Failed to lookup private location with ID ${resource.id}: ${error.message}`)
+   }

    this.program.section(decl(id, builder => {
packages/cli/src/constructs/check-group-codegen.ts (1)

45-237: Consider splitting buildCheckGroupProps into smaller, focused functions.

The current function spans nearly 200 lines, handling many conditionals and sub-structures. Breaking it into smaller helper functions (e.g., populateLocations, populatePrivateLocations, populateAlertChannels, etc.) would improve readability and maintainability.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (2)

5-11: Property naming inconsistency between interface and implementation.

The interface defines the SMS number property as number in the config, but in the implementation it's referred to as phoneNumber (line 36). This naming inconsistency could cause confusion.

Consider making the property names consistent:

export interface SmsAlertChannelResource extends AlertChannelResource {
  type: 'SMS'
  config: {
-    number: string
+    phoneNumber: string
    name?: string
  }
}

36-36: Property names should match interface definition.

This line uses phoneNumber but the interface defines it as number.

-            builder.string('phoneNumber', config.number)
+            builder.string('phoneNumber', config.phoneNumber)

Alternatively, if you want to keep the interface as is:

-            builder.string('phoneNumber', config.number)
+            builder.string('phoneNumber', config.number)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57927ef and 33e0344.

📒 Files selected for processing (14)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/email-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/key-value-pair-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/cli/src/constructs/key-value-pair-codegen.ts
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts
  • packages/cli/src/constructs/email-alert-channel-codegen.ts
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts
🧰 Additional context used
🧬 Code Definitions (8)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/api-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-154)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/private-location-codegen.ts (3)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/check-group-codegen.ts (8)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (1)
  • valueForAssertion (27-44)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-121)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (25)
packages/cli/src/constructs/api-check-codegen.ts (6)

8-12: Well-structured interface for snippet resources

The SnippetResource interface provides a clear structure for script snippets with appropriate optional fields.


14-25: Good design for API check resources

The ApiCheckResource interface properly extends CheckResource and provides comprehensive fields for API checks. The flexibility in specifying setup and teardown scripts gives users multiple options.


27-44: Well-implemented assertion value handler

The valueForAssertion function properly maps assertion sources to appropriate builder methods with good error handling for unsupported assertion sources.


128-128: Address TODOs with an issue or implementation plan

There are TODO comments about moving scripts to separate files and using entrypoints. Consider addressing these with a tracked issue or implementation plan.

Since these TODOs appear to be related to architectural improvements, could you provide more context on when and how these improvements will be implemented? You might want to create tracked issues for these improvements to ensure they're not forgotten.

Also applies to: 144-144


48-163: Well-implemented code generation for API checks

The ApiCheckCodegen class thoroughly handles all aspects of API check configuration with proper conditional handling of optional properties. The use of the builder pattern ensures clean code generation.


1-7: Well-organized imports

The imports are properly structured, importing only what's needed from the relevant modules.

packages/cli/src/constructs/private-location-codegen.ts (5)

1-3: Imports follow the project's module structure

The imports correctly reference internal modules for code generation utilities, showing good organization.


12-12: Good use of constant for construct name

Using a constant for the construct name avoids string duplication and enables easier refactoring.


14-23: Well-structured utility function for generating PrivateLocation references

The function properly:

  1. Adds the necessary import
  2. Returns an expression that creates a reference to an existing PrivateLocation by ID

This will be useful when linking resources that reference private locations.


25-29: Codegen class extends base class with proper type parameter

The prepare method correctly registers the private location ID in the context for later reference, following the pattern established in other codegen classes.


1-58:

❓ Verification inconclusive

Overall implementation fits well in the import command architecture

This code generator follows the established patterns for other resource types, maintaining consistency with the rest of the codebase. It will allow users to import their existing private locations as part of the new CLI import command.

Consider implementing tests for this code generator to ensure it produces the expected output for various input configurations.


🏁 Script executed:

#!/bin/bash
# Look for tests of similar codegen classes to understand test patterns
echo "Searching for existing codegen test files..."
fd -e ts test.*codegen packages/cli/src

Length of output: 142


Attention: Consistency and Test Coverage Verification

The implementation is consistent with established patterns for CLI import commands. However, the codebase does not currently include tests for similar code generation classes (as indicated by the absence of matching test files in the search). To ensure ongoing reliability and correctness, please implement tests for this code generator that validate its output for various input configurations.

  • File Impacted: packages/cli/src/constructs/private-location-codegen.ts
  • Recommendation: Add tests modeled on testing patterns from similar features or resource types to cover edge cases and generated output.
packages/cli/src/constructs/check-group-codegen.ts (3)

13-27: Solid introduction of new resource interfaces.

The interfaces BrowserCheckConfigResource, MultiStepCheckConfigResource, and CheckGroupResource comprehensively capture the properties needed for check group configurations, leveraging typed fields to ensure clarity in usage.


28-33: doubleCheck and concurrency remain unused in the code generation.

Despite being defined in the CheckGroupResource, these properties are never set in buildCheckGroupProps. This can lead to incomplete code generation.

As a follow-up, apply this diff in buildCheckGroupProps to include these properties:

+  if (resource.doubleCheck !== undefined) {
+    builder.boolean('doubleCheck', resource.doubleCheck)
+  }

+  if (resource.concurrency !== undefined) {
+    builder.number('concurrency', resource.concurrency)
+  }

75-79: Empty catch blocks swallow potential errors silently.

In both the lookupCheckGroupPrivateLocations and lookupCheckGroupAlertChannels calls, any lookup errors are caught and ignored. This behavior might make diagnosing errors more difficult, as issues could fail silently.

Could you confirm if this is intentional? If not, consider logging or handling these errors more explicitly to surface potential problems.

Also applies to: 116-121

packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)

1-47: Implementation looks good with a well-structured code generation pattern.

The code follows a clean pattern for generating Slack alert channel code. The interface properly extends AlertChannelResource, and the code generation logic correctly handles both required and optional properties.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)

15-47: Overall implementation follows the standard alert channel code generation pattern.

The code is well-structured with proper separation of preparation and code generation phases. The conditional property handling for the optional name property is implemented correctly.

packages/cli/src/constructs/msteams-alert-channel-codegen.ts (2)

6-10: Clean extension of WebhookAlertChannelResource for MS Teams.

The interface properly constrains the webhook type to 'WEBHOOK_MSTEAMS', ensuring type safety for MS Teams alert channels.


14-42: Well-structured code generation for MS Teams alert channel.

The implementation follows the standard pattern and properly generates the MS Teams alert channel code with the required properties.

packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)

5-13: Comprehensive config properties for Opsgenie integration.

The interface properly defines all required properties for Opsgenie integration including name, apiKey, region, and priority.


33-40: All Opsgenie properties correctly mapped in the generated code.

The implementation properly maps all the configuration properties needed for the Opsgenie alert channel.


17-47: Overall implementation follows consistent alert channel pattern.

The class implements the standard alert channel code generation pattern with proper preparation and code generation phases.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (2)

5-12: Interface definition looks sound.

The optional fields and required serviceKey property are appropriately declared, and their types appear correct.


21-50: Ensure test coverage for new alert channel code generation.

While the logic here is straightforward, consider adding or verifying tests to ensure that gencode correctly generates a PagerdutyAlertChannel with various valid and edge-case input configurations.

packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (2)

13-25: API key extraction logic appears correct.

This function cleanly filters headers and extracts the Bearer token. It should work well for the intended use case.


47-47: Redundant .toString() call on config.url.

@sorccu sorccu force-pushed the simokinnunen/sc-23506/cli-import-existing-resources branch from 15ca798 to 2c43245 Compare April 3, 2025 06:13
Copy link
Contributor

@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: 4

♻️ Duplicate comments (1)
packages/cli/src/commands/import/apply.ts (1)

77-83: ⚠️ Potential issue

Handle prompt cancellation scenarios

The current implementation doesn't account for what happens if the user cancels the prompt (by pressing Esc). In such cases, planId would be undefined and execution would proceed with a potential error.

  const { planId } = await prompts({
    name: 'planId',
    type: 'select',
    message: `Found ${plans.length} unapplied plan(s). Which one to apply?`,
    choices,
+   onCancel: () => {
+     this.log('Operation cancelled by user')
+     this.exit(0)
+     return false
+   }
  })

+ if (planId === undefined) {
+   this.log('Operation cancelled')
+   this.exit(0)
+ }
🧹 Nitpick comments (32)
packages/cli/src/commands/import/apply.ts (1)

47-59: Add error handling for empty unapplied plans list

The code doesn't handle the case where unappliedPlans is empty (but not encountering the existing code path for zero length). Consider adding error handling for this scenario.

  const { data: unappliedPlans } = await api.projects.findImportPlans(logicalId, {
    onlyUnapplied: true,
  })

+ if (unappliedPlans.length === 0) {
+   this.log('No unapplied plans found. Please create a plan first using `checkly import plan`')
+   this.exit(0)
+ }

  const plan = await this.#selectPlan(unappliedPlans)

  if (this.fancy) {
    ux.action.start('Applying plan')
  }
packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)

32-37: Add type checking for channel property before usage

While the code correctly checks if the channel property exists before using it, there's no validation that the channel is a non-empty string. This could lead to unexpected behavior if the channel is provided but is an empty string.

if (config.channel) {
+ // Ensure channel is a non-empty string
+ if (typeof config.channel === 'string' && config.channel.trim() !== '') {
    builder.string('channel', config.channel)
+ }
}
packages/cli/src/commands/import/plan.ts (3)

97-105: Avoid type assertions with 'any'

Using as any type assertions can lead to type safety issues and potential runtime errors. Consider defining proper types for the resources.

- sortResources(plan.changes.resources as any)
+ // Define a proper type or interface for resources
+ interface ResourceWithLogicalId {
+   logicalId: string;
+   [key: string]: any;
+ }
+ sortResources(plan.changes.resources as ResourceWithLogicalId[])

for (const resource of plan.changes.resources) {
-  codegen.prepare(resource.logicalId, resource as any, context)
+  codegen.prepare(resource.logicalId, resource as ResourceWithLogicalId, context)
}

for (const resource of plan.changes.resources) {
-  codegen.gencode(resource.logicalId, resource as any, context)
+  codegen.gencode(resource.logicalId, resource as ResourceWithLogicalId, context)
}

115-116: Address the TODO comment about file structure

There's a pending TODO comment about file structure, but the code directly writes to ./generated.check.ts. Consider implementing a more flexible file structure or removing the TODO if the current approach is intentional.

- // TODO: file structure
- const filename = './generated.check.ts'
+ // Generate output with a structured path based on config
+ const filename = `${configDirectory}/generated.check.ts`

130-223: Add prompt cancellation handling in #handleExistingPlans

Similar to the issue in the apply command, this method doesn't handle the case where the user cancels the prompt using Esc key, which would leave action as undefined.

Add appropriate cancellation handlers to the prompts:

const { action } = await prompts({
  name: 'action',
  type: 'select',
  message: `Found ${plans.length} existing uncommitted plan(s). How do you want to proceed?`,
  choices,
+ onCancel: () => {
+   this.log('Operation cancelled by user')
+   this.exit(0)
+   return false
+ }
})

+ if (action === undefined) {
+   this.log('Operation cancelled')
+   this.exit(0)
+   return
+ }

Apply similar changes to the second prompt at line 172.

packages/cli/src/constructs/api-check-codegen.ts (1)

48-163: Potential improvement for script handling.
While gencode properly accounts for local vs. snippet scripts, the logic is fairly dense. Consider extracting repeated script-building logic into helper methods for maintainability.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)

20-45: Export logic is neatly implemented.
gencode composes the SmsAlertChannel object with extra props from buildAlertChannelProps. Consider input validation for the phone number if the constructor is user-facing.

packages/cli/src/constructs/status-page-codegen.ts (2)

6-10: Consider adding JSDoc comments for clarity.
Interfaces are essential for readability and maintainability. Adding brief JSDoc comments describing each field—especially arrays like services—helps provide context for future contributors.


37-53: Improve error messaging when referencing missing services.
Currently, the error message 'Status page refers to a service that is not being imported.' does not specify which service ID caused the issue. Including the missing service.id in the message can expedite debugging.

- throw new Error('Status page refers to a service that is not being imported.')
+ throw new Error(`Status page refers to a missing service with ID: ${service.id}`)
packages/cli/src/sourcegen/declbuilder.ts (4)

5-9: Ensure type checks for builder functions.
The decl function relies on the user-provided builder to modify state. Consider enforcing type checks or error handling to prevent misuse in more complex scenarios.


15-18: Add JSDoc or docstring for the constructor.
Providing a docstring explaining the purpose of #identifier and #decl will help maintainers follow your logic more easily.


20-23: Consider allowing multiple variable declarations.
If future enhancements require multiple variables within the same builder, you might refactor to handle an array of variables or a chainable approach, instead of replacing the current declaration.


25-28: Optional: Provide an unexport or revert mechanism.
Once you apply export(), there’s no way to revert. If a future codegen scenario requires toggling export state, consider adding an unexport() method or keeping track of prior states.

packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)

19-41: Ensure the CLI usage is documented.
This generation logic looks correct for producing an MSTeams alert channel resource. However, confirm that end-users know how to specify webhookType: 'WEBHOOK_MSTEAMS' in the CLI or config file.

packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (2)

5-11: Clarify the type: 'CALL' usage.
Explicitly documenting what 'CALL' signifies (e.g., phone calls, including acceptable country codes) ensures new contributors can quickly adopt or extend this resource type.


20-45: Confirm phone number format validation.
Although the code sets phoneNumber, consider validating or normalizing the phone string. If the code is used in production, it might need to handle user input robustly.

packages/cli/src/constructs/check-codegen.ts (2)

70-85: Consider adding error logging in empty catch blocks.

The empty catch block silently ignores any errors that occur during the lookup of private locations. While it appears to be intentional based on the following conditional logic, adding a debug log could help with troubleshooting.

  try {
    return context.lookupCheckPrivateLocations(resource.id)
  } catch (err) {
+   // Silently continue if no private locations found for this check
  }

121-126: Consider adding error logging in empty catch blocks.

Similar to the previous comment, the empty catch block silently ignores any errors during alert channel lookup. While this appears to be intentional based on the following conditional logic, adding a debug log could help with troubleshooting.

  try {
    return context.lookupCheckAlertChannels(resource.id)
  } catch (err) {
+   // Silently continue if no alert channels found for this check
  }
packages/cli/src/sourcegen/exprbuilder.ts (1)

11-42: Consider renaming the new method to avoid confusion.

Naming a method as new might be confusing given that it clashes with the new keyword in JavaScript/TypeScript. A more explicit name such as newExpression or createNew can improve clarity and maintainability.

Here's a sample diff to rename and update references:

-  new (build: (builder: ArgumentsValueBuilder) => void): this {
+  newExpression(build: (builder: ArgumentsValueBuilder) => void): this {
     const builder = new ArgumentsValueBuilder()
     build(builder)
     return this.context(new NewExpressionValue(this.#context, builder.build()))
 }
packages/cli/src/rest/projects.ts (1)

94-101: Possible need for pagination on listImportPlans.
If the number of import plans grows large, consider supporting server-side pagination or other limiting mechanisms.

packages/cli/src/constructs/check-group-codegen.ts (1)

45-237: buildCheckGroupProps is large but logical.
All relevant fields (frequency, tags, environment variables, etc.) are handled in a systematic manner. Consider modularizing some sections if the function grows further.

packages/cli/src/constructs/alert-channel-codegen.ts (1)

12-19: Consider using an enum for alert channel types.
Defining AlertChannelType as a string-literal union is perfectly valid. However, using a TypeScript enum can enhance readability and minimize string typos.

packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1)

43-43: Redundant call to .toString().
Since config.url is already typed as string, toString() is unnecessary. You can safely remove it for clarity.

-  builder.string('url', config.url.toString())
+  builder.string('url', config.url)
packages/cli/src/sourcegen/argsbuilder.ts (4)

19-22: Avoid potential confusion with the comment.
The comment "Avoid extending ArrayValueBuilder due to circular dependencies" is helpful but could be expanded. Consider briefly explaining the reason, e.g., which modules or references would cause the cycle, to guide future maintainers.


23-26: Consider clarifying the purpose of empty().
The empty() method reinitializes #elements. It might be beneficial to clarify its intended usage in comments or docs, particularly if chained with other methods.


52-54: Consider advanced validation for nested builders.
For array, object, and expr calls, it may be beneficial to validate the resulting objects or expressions if misuse is possible. Currently, there's no defense if the build callback is malformed. Might be acceptable given expected usage.

Also applies to: 56-58, 60-62


64-67: Method naming clarity.
The method value is direct and works well, but a more explicit name such as pushValue or addValue could be more descriptive of its operation. This is optional but might improve readability.

packages/cli/src/sourcegen/objectbuilder.ts (3)

12-16: Add usage guidance for the object function.
This top-level function is a convenient entry point for creating object values. For clarity, consider adding a short doc comment to explain its purpose and typical usage, similar to the args function pattern.


18-21: Optional: clarify object building options.
Storing #options is helpful for advanced rendering (e.g., sorting). Verifying that future expansions to ObjectValueOptions properly integrate into ObjectValueBuilder would be wise.


58-65: Expression property handling might need error context.
expr(name, context, build) raises no errors by default if something goes wrong in build. Consider capturing or testing potential errors since expressions can get complex.

packages/cli/src/constructs/internal/codegen/context.ts (2)

3-4: Provide an error message in MissingContextVariableMappingError.
Consider including a descriptive message or the missing ID in the error. Right now, it throws a blank error, which might hinder debugging in large codebases.


5-138: Overall context management appears correct.
The Context class effectively manages mappings for various physical IDs. Each register* method sets up a new identifier or association, and each lookup* method throws if the mapping doesn't exist. This is a straightforward and organized approach.

  1. Redundant registration checks: Re-registering the same ID doesn't appear to be disallowed, possibly causing unexpected overshadowing. Consider clarifying expected usage or adding checks.
  2. Custom error messages: As noted, referencing physical IDs in the thrown error can help with debugging.
  3. Future expansions: Because the approach is Map-based, you might want to ensure cleaning or disposal steps if the context grows large, though that may be scenario-dependent.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15ca798 and 2c43245.

📒 Files selected for processing (67)
  • packages/cli/e2e/__tests__/help.spec.ts (2 hunks)
  • packages/cli/package.json (1 hunks)
  • packages/cli/src/commands/import/apply.ts (1 hunks)
  • packages/cli/src/commands/import/cancel.ts (1 hunks)
  • packages/cli/src/commands/import/commit.ts (1 hunks)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group.ts (1 hunks)
  • packages/cli/src/constructs/construct-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/email-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/frequency-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/assertion-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/index.ts (1 hunks)
  • packages/cli/src/constructs/key-value-pair-codegen.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config.ts (0 hunks)
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/ref-codegen.ts (1 hunks)
  • packages/cli/src/constructs/retry-strategy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-service-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/rest/projects.ts (3 hunks)
  • packages/cli/src/sourcegen/args.ts (1 hunks)
  • packages/cli/src/sourcegen/argsbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/array.ts (1 hunks)
  • packages/cli/src/sourcegen/arraybuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/boolean.ts (1 hunks)
  • packages/cli/src/sourcegen/decl.ts (1 hunks)
  • packages/cli/src/sourcegen/declbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/expr.ts (1 hunks)
  • packages/cli/src/sourcegen/exprbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/identifier.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
  • packages/cli/src/sourcegen/null.ts (1 hunks)
  • packages/cli/src/sourcegen/number.ts (1 hunks)
  • packages/cli/src/sourcegen/object.ts (1 hunks)
  • packages/cli/src/sourcegen/objectbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/output.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
  • packages/cli/src/sourcegen/string.ts (1 hunks)
  • packages/cli/src/sourcegen/undefined.ts (1 hunks)
  • packages/cli/src/sourcegen/unknown.ts (1 hunks)
  • packages/cli/src/sourcegen/value.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/cli/src/constructs/playwright-config.ts
🚧 Files skipped from review as they are similar to previous changes (39)
  • packages/cli/src/sourcegen/undefined.ts
  • packages/cli/src/sourcegen/number.ts
  • packages/cli/src/sourcegen/args.ts
  • packages/cli/src/sourcegen/value.ts
  • packages/cli/src/sourcegen/boolean.ts
  • packages/cli/src/constructs/key-value-pair-codegen.ts
  • packages/cli/src/sourcegen/null.ts
  • packages/cli/src/commands/import/commit.ts
  • packages/cli/package.json
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/src/constructs/ref-codegen.ts
  • packages/cli/src/sourcegen/string.ts
  • packages/cli/src/sourcegen/array.ts
  • packages/cli/e2e/tests/help.spec.ts
  • packages/cli/src/constructs/internal/codegen/codegen.ts
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/sourcegen/unknown.ts
  • packages/cli/src/constructs/check-group.ts
  • packages/cli/src/constructs/playwright-config-codegen.ts
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts
  • packages/cli/src/sourcegen/identifier.ts
  • packages/cli/src/commands/import/cancel.ts
  • packages/cli/src/sourcegen/program.ts
  • packages/cli/src/sourcegen/output.ts
  • packages/cli/src/constructs/frequency-codegen.ts
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/constructs/alert-channel-subscription-codegen.ts
  • packages/cli/src/constructs/private-location-group-assignment-codegen.ts
  • packages/cli/src/sourcegen/decl.ts
  • packages/cli/src/constructs/heartbeat-check-codegen.ts
  • packages/cli/src/constructs/internal/codegen/index.ts
  • packages/cli/src/constructs/retry-strategy-codegen.ts
  • packages/cli/src/constructs/maintenance-window-codegen.ts
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts
  • packages/cli/src/constructs/email-alert-channel-codegen.ts
  • packages/cli/src/sourcegen/object.ts
  • packages/cli/src/sourcegen/expr.ts
🧰 Additional context used
🧬 Code Definitions (22)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/api-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-154)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/sourcegen/exprbuilder.ts (3)
packages/cli/src/sourcegen/index.ts (8)
  • expr (22-22)
  • Value (33-33)
  • ExpressionValueBuilder (22-22)
  • ExpressionValue (15-15)
  • ArgumentsValueBuilder (2-2)
  • NewExpressionValue (16-16)
  • CallExpressionValue (17-17)
  • MemberExpressionValue (18-18)
packages/cli/src/sourcegen/argsbuilder.ts (4)
  • expr (60-62)
  • build (73-75)
  • value (64-67)
  • ArgumentsValueBuilder (20-76)
packages/cli/src/sourcegen/expr.ts (3)
  • NewExpressionValue (8-24)
  • CallExpressionValue (26-40)
  • MemberExpressionValue (42-57)
packages/cli/src/constructs/check-codegen.ts (8)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (2)
  • ApiCheckCodegen (48-163)
  • ApiCheckResource (14-25)
packages/cli/src/constructs/status-page-service-codegen.ts (1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/tcp-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-154)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForGeneralAssertion (45-146)
  • valueForNumericAssertion (4-43)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/alert-channel-codegen.ts (8)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1)
  • PhoneCallAlertChannelCodegen (15-46)
packages/cli/src/constructs/email-alert-channel-codegen.ts (1)
  • EmailAlertChannelCodegen (14-39)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1)
  • OpsgenieAlertChannelCodegen (17-47)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1)
  • PagerdutyAlertChannelCodegen (16-51)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)
  • SlackAlertChannelCodegen (15-46)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)
  • SmsAlertChannelCodegen (15-46)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1)
  • WebhookAlertChannelCodegen (78-138)
packages/cli/src/constructs/check-group-codegen.ts (8)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (1)
  • valueForAssertion (27-44)
packages/cli/src/sourcegen/declbuilder.ts (2)
packages/cli/src/sourcegen/index.ts (6)
  • decl (11-11)
  • IdentifierValue (23-23)
  • DeclarationBuilder (12-12)
  • Value (33-33)
  • VariableDeclaration (7-7)
  • ExportDeclaration (8-8)
packages/cli/src/sourcegen/decl.ts (4)
  • IdentifierDeclaration (9-20)
  • VariableDeclarationOptions (22-24)
  • VariableDeclaration (26-51)
  • ExportDeclaration (53-65)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/commands/import/plan.ts (4)
packages/cli/src/rest/projects.ts (1)
  • ImportPlan (43-49)
packages/cli/src/sourcegen/index.ts (2)
  • Program (29-29)
  • Output (28-28)
packages/cli/src/constructs/construct-codegen.ts (2)
  • ConstructCodegen (57-117)
  • sortResources (49-55)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (7)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)
  • IncidentioAlertChannelCodegen (29-64)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)
  • MSTeamsAlertChannelCodegen (14-42)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)
  • TelegramAlertChannelCodegen (28-69)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/private-location-codegen.ts (3)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/sourcegen/arraybuilder.ts (7)
packages/cli/src/sourcegen/array.ts (1)
  • ArrayValue (4-31)
packages/cli/src/sourcegen/string.ts (1)
  • StringValue (6-17)
packages/cli/src/sourcegen/boolean.ts (1)
  • BooleanValue (4-15)
packages/cli/src/sourcegen/number.ts (1)
  • NumberValue (4-15)
packages/cli/src/sourcegen/null.ts (1)
  • NullValue (4-8)
packages/cli/src/sourcegen/undefined.ts (1)
  • UndefinedValue (4-8)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (4-15)
packages/cli/src/constructs/construct-codegen.ts (14)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • AlertChannelCodegen (66-114)
packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1)
  • AlertChannelSubscriptionCodegen (9-24)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckCodegen (156-192)
packages/cli/src/constructs/check-group-codegen.ts (1)
  • CheckGroupCodegen (241-264)
packages/cli/src/constructs/dashboard-codegen.ts (1)
  • DashboardCodegen (31-140)
packages/cli/src/constructs/maintenance-window-codegen.ts (1)
  • MaintenanceWindowCodegen (16-64)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • PrivateLocationCodegen (25-57)
packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1)
  • PrivateLocationCheckAssignmentCodegen (8-17)
packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1)
  • PrivateLocationGroupAssignmentCodegen (8-17)
packages/cli/src/constructs/status-page-codegen.ts (1)
  • StatusPageCodegen (26-78)
packages/cli/src/constructs/status-page-service-codegen.ts (1)
  • StatusPageServiceCodegen (11-34)
packages/cli/src/sourcegen/program.ts (1)
  • Program (7-53)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (4)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/sourcegen/objectbuilder.ts (9)
packages/cli/src/sourcegen/arraybuilder.ts (7)
  • object (54-56)
  • build (71-73)
  • value (62-65)
  • ArrayValueBuilder (18-74)
  • array (12-16)
  • array (50-52)
  • expr (58-60)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/object.ts (3)
  • ObjectValueOptions (22-24)
  • ObjectProperty (8-18)
  • ObjectValue (58-88)
packages/cli/src/sourcegen/string.ts (1)
  • StringValue (6-17)
packages/cli/src/sourcegen/boolean.ts (1)
  • BooleanValue (4-15)
packages/cli/src/sourcegen/number.ts (1)
  • NumberValue (4-15)
packages/cli/src/sourcegen/null.ts (1)
  • NullValue (4-8)
packages/cli/src/sourcegen/undefined.ts (1)
  • UndefinedValue (4-8)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (4-15)
packages/cli/src/constructs/internal/codegen/context.ts (1)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • MissingContextVariableMappingError (2-2)
  • Context (2-2)
packages/cli/src/sourcegen/argsbuilder.ts (2)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/args.ts (1)
  • ArgumentsValue (4-27)
🪛 Biome (1.9.4)
packages/cli/src/constructs/check-codegen.ts

[error] 179-179: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 181-181: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 183-183: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 185-185: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 187-187: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test - windows-latest
🔇 Additional comments (69)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)

4-43: Convert string to number with Number() instead of parseInt()

The valueForNumericAssertion function uses parseInt(assertion.target, 10) for numeric conversions, which may cause precision issues with floating-point values. Using Number(assertion.target) would be more appropriate.

case 'EQUALS':
  builder.member(ident('equals'))
  builder.call(builder => {
-   builder.number(parseInt(assertion.target, 10))
+   builder.number(Number(assertion.target))
  })
  break

Apply the same change to all other cases in this function (lines 24, 30, and 36).


106-117: Handle numeric comparison types correctly in general assertions

The valueForGeneralAssertion function handles LESS_THAN and GREATER_THAN comparisons as string comparisons, which may produce unexpected results when comparing numeric values.

case 'LESS_THAN':
  builder.member(ident('lessThan'))
  builder.call(builder => {
-   builder.string(assertion.target)
+   // Try to determine if target should be treated as a number
+   const numValue = Number(assertion.target)
+   if (!isNaN(numValue)) {
+     builder.number(numValue)
+   } else {
+     builder.string(assertion.target)
+   }
  })
  break

Apply the same approach to the GREATER_THAN case below.

packages/cli/src/constructs/slack-alert-channel-codegen.ts (2)

5-11: LGTM - SlackAlertChannelResource interface is well defined

The interface extends AlertChannelResource properly and clearly defines the expected structure for Slack alert channel configurations, with appropriate type specification and optional fields.


16-18: LGTM - Alert channel registration is well implemented

The prepare method correctly registers the alert channel using a consistent naming convention with the resource ID.

packages/cli/src/commands/import/plan.ts (1)

18-28: Add unit tests for ImportPlanCommand

Based on past review comments, there are no unit tests for handling existing import plans. Please add tests to verify the user flow and ensure all code paths are covered.

#!/bin/bash
# Check for existing tests for ImportPlanCommand
find packages/cli/tests -type f -name "*.ts" -o -name "*.js" | xargs grep -l "ImportPlanCommand"

# Find test patterns in the codebase
find packages/cli/tests -type f -name "*.ts" -o -name "*.js" | xargs grep -l "Command.*test"
packages/cli/src/constructs/tcp-check-codegen.ts (4)

1-6: Imports and baseline setup look good.
The new imports are consistent with other codegen references, ensuring the necessary modules are brought into scope.


7-12: Consider clarifying the checkType derivation.
While hardcoding 'TCP' in the interface ensures consistency, verify that it's correctly set throughout the codebase and that no dynamic assignment is needed.


14-25: Well-structured assertion mapping.
valueForTcpAssertion properly delegates to existing numeric and general assertion builders. This approach is consistent and concise.


29-73: Confirm behavior for empty or undefined request fields.
TcpCheckCodegen method gencode relies on resource.request having valid fields. Consider verifying or guarding against empty hostname or port.

Would you like a quick check or script to scan usage sites and confirm that request is always defined?

packages/cli/src/constructs/api-check-codegen.ts (3)

8-12: SnippetResource interface is neatly defined.
This structure is straightforward and readable. No issues found.


14-25: Interface structure aligns with existing check patterns.
ApiCheckResource extends CheckResource cleanly, incorporating optional scripts and thresholds.


27-44: Comprehensive assertion coverage.
valueForAssertion handles multiple sources correctly, including status codes, headers, JSON body, etc. and throws for unsupported.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (2)

5-11: SMS configuration is straightforward.
Properties are minimal and typed. Make sure number is always a valid phone number string.


15-19: Context registration aligns with other alert channels.
prepare effectively ties the alert channel ID to the context. No immediate concerns.

packages/cli/src/constructs/status-page-codegen.ts (1)

55-73:

❓ Verification inconclusive

Verify theme applicability.
The defaultTheme property is conditionally added but not validated or used elsewhere. Confirm whether additional logic is required to properly set themes in the generated code or if the property alone suffices.


🏁 Script executed:

#!/bin/bash
# Searching for usage references to 'defaultTheme' to confirm it is properly handled.
rg -A 5 "defaultTheme" 

Length of output: 2535


Attention: Verify proper handling of defaultTheme.
The code in packages/cli/src/constructs/status-page-codegen.ts conditionally adds defaultTheme using builder.string('defaultTheme', resource.defaultTheme), and the property is subsequently assigned and forwarded in packages/cli/src/constructs/status-page.ts. TypeScript ensures that only values of type StatusPageTheme are allowed, but no additional runtime validation is performed. Please confirm whether this behavior is intentional—that is, if basic type-checking is sufficient—or if additional validation or transformation logic is needed to ensure that the generated theme configuration is correct.

  • Location: packages/cli/src/constructs/status-page-codegen.ts (conditional addition of defaultTheme)
  • Location: packages/cli/src/constructs/status-page.ts (assignment and propagation in synthesis)
packages/cli/src/sourcegen/declbuilder.ts (1)

30-32: build() method is well-structured.
This straightforward design keeps the builder logic clean and final. No issues found here.

packages/cli/src/constructs/msteams-alert-channel-codegen.ts (2)

15-17: Great use of prepare for registration.
This method properly registers the alert channel. A straightforward approach that improves the maintainability and organization of the code.


6-10:

✅ Verification successful

Align naming conventions with other alert channels.
Confirm that the webhookType: 'WEBHOOK_MSTEAMS' naming and field structure are consistent with similarly implemented alert channels (e.g., Slack). This helps maintain uniformity in the codebase.


🏁 Script executed:

#!/bin/bash
# Searching for other alert channels with 'webhookType'
rg -A 5 "webhookType"

Length of output: 9313


Naming Conventions are Consistent Across Alert Channels
The MSTeamsAlertChannelResource interface’s configuration of webhookType: 'WEBHOOK_MSTEAMS' follows the same pattern as seen in the incident.io (WEBHOOK_INCIDENTIO) and Telegram (WEBHOOK_TELEGRAM) implementations. This uniform naming via the WEBHOOK_ prefix ensures consistency across alert channels. No changes are required here.

packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1)

15-18: Good approach to generating phone call alert identifiers.
The prepare method effectively differentiates phone alert channels by registering them with 'phoneCallAlert'.

packages/cli/src/constructs/check-codegen.ts (3)

17-35: Good interface design for CheckResource.

The CheckResource interface is well-structured with clear property definitions. The optional properties are appropriately marked, making it easy for consumers to understand what's required and what's optional.


112-119: Good error handling for missing check groups.

The error message clearly communicates the issue when a check references a group that's not part of the import, which will help users understand what's missing and how to fix it.


174-191: Remove "return" statements in a void function.

Static analysis indicates returning from a function with return type void is unnecessary. Instead of returning the sub-codegen calls, simply invoke them and break out of the switch.

  gencode (logicalId: string, resource: CheckResource, context: Context): void {
    const { checkType } = resource

    switch (checkType) {
      case 'BROWSER':
-       return this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+       this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+       break
      case 'API':
-       return this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+       this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+       break
      case 'TCP':
-       return this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+       this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+       break
      case 'MULTI_STEP':
-       return this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+       this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+       break
      case 'HEARTBEAT':
-       return this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+       this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+       break
      default:
        throw new Error(`Unable to generate code for unsupported check type '${checkType}'.`)
    }
  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 179-179: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 181-181: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 183-183: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 185-185: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)


[error] 187-187: The function should not return a value because its return type is void.

The function is here:

'void' signals the absence of value. The returned value is likely to be ignored by the caller.

(lint/correctness/noVoidTypeReturn)

packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)

5-13: Good interface design for OpsgenieAlertChannelResource.

The interface properly extends AlertChannelResource and defines the Opsgenie-specific configuration with appropriate required properties.


17-20: Well-implemented preparation method.

The prepare method correctly registers the alert channel with a descriptive prefix that will help identify the variable in the generated code.


22-46: Clean and consistent gencode implementation.

The gencode method follows a good pattern for code generation:

  1. Importing necessary constructs
  2. Looking up the registered alert channel
  3. Destructuring the config object
  4. Building and exporting the code section with proper configuration

This implementation aligns well with other alert channel codegen classes.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (3)

5-12: Good interface design with appropriate optional properties.

The interface correctly extends AlertChannelResource and properly marks account and serviceName as optional while keeping serviceKey required.


33-39: Well-handled optional properties.

The code correctly checks for the existence of optional properties before adding them to the builder, ensuring clean generated code without undefined values.


16-51: Consistent implementation with other alert channel codegens.

The implementation follows the same pattern as other alert channel codegen classes, maintaining consistency across the codebase which improves maintainability.

packages/cli/src/constructs/status-page-service-codegen.ts (2)

4-7: Simple and clear resource interface.

The StatusPageServiceResource interface is concise with just the essential properties needed.


11-34: Clean implementation of the codegen class.

The StatusPageServiceCodegen follows the established pattern for code generation, with proper integration with the Context system for registration and lookup.

packages/cli/src/sourcegen/exprbuilder.ts (2)

1-3: Imports usage approved.

All imported entities appear to be referenced correctly in the code below. No issues found in these import statements.


5-9: Builder approach is clear and concise.

The expr function neatly encapsulates creation of an expression builder. No major concerns here.

packages/cli/src/sourcegen/index.ts (1)

1-34: Export entries are consistent.

All exports cleanly re-export the necessary classes and helpers. Nothing problematic here.

packages/cli/src/constructs/construct-codegen.ts (6)

1-14: Import statements look good.

No issues with the imported modules; they are all used appropriately later in the code.


16-27: ResourceType union is well-defined.

The union type clearly enumerates all recognized resource types. Looks good.


29-33: Resource interface is straightforward.

This simple interface for Resource is clear and effective. No improvements needed.


35-47: Confirm the ordering logic.

The resourceOrder object assigns a higher numeric value for resources that appear earlier when sorted, given the descending sort logic. Verify that this is the intended priority/design (i.e., higher numeric values come first).


49-55: Descending sort verification.

Because the sort function subtracts ao from bo, resources with higher numeric values will appear first. Ensure this is the desired order of generation.


57-98: Aggregator constructor is well-structured.

Constructors for each resource codegen are properly initialized and neatly stored in codegensByType.

packages/cli/src/rest/projects.ts (7)

39-41: Use of ResourceSync[] is straightforward.
No immediate issues spotted; the property name resources is clear, and the type matches the existing ResourceSync interface.


43-49: Consider typing date fields.
Currently, createdAt, appliedAt, and committedAt are typed as string. If these values always represent ISO date/time strings or timestamps from the backend, you might consider using Date objects or clarifying that these are strictly ISO strings for improved type safety.


81-83: createImportPlan method looks good.
The POST call and endpoint path appear consistent.


85-92: findImportPlans method appears correct.
Filtering via query parameters is well-structured. Handle potential pagination or large result sets in the future if needed.


103-105: cancelImportPlan method is straightforward.
No issues detected.


107-109: applyImportPlan method looks fine.
No issues detected.


111-113: commitImportPlan method is consistent.
Implementation aligns with the existing pattern.

packages/cli/src/constructs/private-location-codegen.ts (5)

1-2: Import statements are correct.
No issues with module references or naming.


4-10: PrivateLocationResource interface definition is clear.
Optional properties icon and proxyUrl are properly indicated, and fields match typical usage.


12-12: Constant naming is consistent.
Using 'PrivateLocation' here aligns with the codegen pattern.


14-23: valueForPrivateLocationFromId logic mirrors the existing pattern.
No issues found. The function imports the construct, invokes fromId, and calls it with the correct parameter.


25-58: PrivateLocationCodegen correctly registers and generates code.
Implementation follows the established prepare/gencode pattern, and the usage of context.registerPrivateLocation is consistent.

packages/cli/src/constructs/check-group-codegen.ts (3)

28-32: Properties doubleCheck and concurrency remain unused.
This issue was noted in a previous review. If these properties are meant to be part of the generated check group props, ensure they are applied in buildCheckGroupProps; otherwise, consider removing them if they are not needed.


13-43: Interfaces for browser, multi-step, and check-group resources are comprehensive.
They cover the key fields needed for configuration.


239-264: CheckGroupCodegen matches the existing codegen pattern well.
Implementation follows the typical “prepare” + “gencode” flow, with correct usage of context lookups and the builder pattern.

packages/cli/src/constructs/alert-channel-codegen.ts (4)

31-51: Validate presence of optional fields before building.
Though this function checks for undefined before setting properties, it might be beneficial to confirm that any upstream or default values are validated correctly elsewhere (e.g., for numeric fields like sslExpiryThreshold).


66-95: Good modular design mapping alert channel types to codegens.
This dictionary-based approach cleanly extends support for new alert channel types without code duplication.


97-104: Exception thrown for unsupported alert channel types is appropriate.
Returning early for valid channel types, then throwing an error for unsupported types, is consistent. No changes needed.


106-113: Consistent pattern in 'gencode' method.
Mirroring the 'prepare' method with a dictionary lookup keeps the code DRY and straightforward.

packages/cli/src/constructs/webhook-alert-channel-codegen.ts (3)

28-31: Appropriate use of interface extension for 'WEBHOOK' resource.
Defining WebhookAlertChannelResource to extend AlertChannelResource clarifies required and optional fields for this channel type.


97-108: 'prepare' method properly avoids returning a value in void function.
This implementation complies with TypeScript's type signature and addresses previous concerns about returning the nested call.


110-137: Fallback path for unrecognized webhook type is well-handled.
If the webhookType is absent or undefined, the code gracefully sets up a generic webhook alert channel.

packages/cli/src/sourcegen/arraybuilder.ts (2)

12-16: Builder function cleanly abstracts array creation.
Using the array(...) top-level function to drive the ArrayValueBuilder fosters readability and modularity.


18-74: Robust suite of typed builder methods for array elements.
Exposing methods for different data types (e.g., string, boolean, ident) ensures flexible and type-safe array construction.

packages/cli/src/sourcegen/argsbuilder.ts (3)

13-17: Validate the builder callback usage.
The args function entirely relies on the build callback. If the callback fails or is not provided, this could raise runtime errors. Consider adding a brief safety check or default noop function for robustness.


28-30: Builder methods are straightforward and consistent.
All the typed builder methods (string, boolean, number, null, undefined, ident) neatly return this for chaining and push their respective value objects into #elements. This design appears both consistent and extensible.

Also applies to: 32-34, 36-38, 40-42, 44-46, 48-50


73-75: Potential usage note for build().
The builder pattern is well-implemented. However, ensure callers understand that once build() is called, further modifications to the builder’s state do not affect the returned ArgumentsValue instance.

packages/cli/src/sourcegen/objectbuilder.ts (3)

26-28: Builder methods look correct and consistent.
String, boolean, number, null, undefined, and identifier property methods consistently forward to this.value(). This is consistent with typical builder patterns. No issues found.

Also applies to: 30-32, 34-36, 38-40, 42-44, 46-48


50-52: Support for nested arrays and objects is well-designed.
The array and object methods enable nesting within objects, which seems essential for your codegen requirements. Good job ensuring a uniform approach consistent with the other builders.

Also applies to: 54-56


72-74: Finalize object creation.
The build() method is straightforward and returns a new ObjectValue. Just note that modifying #properties afterward won't affect the returned ObjectValue. That approach is consistent with typical builder patterns.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (4)
packages/cli/src/commands/import/plan.ts (3)

66-79: Consider covering additional error codes for better resilience.

You currently handle 404 errors by printing specific messages. However, server responses like 401 and 403 can also occur. Consider adding similar handling for these error codes to offer clearer feedback and gracefully exit or retry.


116-118: Warn users before overwriting the output file.

Writing the code to ./generated.check.ts without confirmation might overwrite an existing file. Consider adding checks or a user prompt if the file already exists.

 const filename = './generated.check.ts'
+// Consider checking if the file exists. If yes, prompt the user for confirmation
 writeFileSync(filename, output.finalize())

216-217: Remove the useless switch case for 'exit'.

The 'exit' case falls through to the default branch, which already handles exiting. This is flagged by the linter as a useless case.

-       case 'exit':
-         // falls through
         default: {
           this.log('Exiting without making any changes.')
           this.exit(0)
         }
🧰 Tools
🪛 Biome (1.9.4)

[error] 216-217: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

packages/cli/src/commands/import/cancel.ts (1)

67-71: Differentiate plan titles in the user prompt.

All plans are labeled "Plan #1 from …," which may confuse users if multiple plans exist. Include an index or other unique identifier to differentiate each plan.

-const choices: prompts.Choice[] = plans.map(plan => ({
-  title: `Plan #1 from ${new Date(plan.createdAt)}`,
+const choices: prompts.Choice[] = plans.map((plan, index) => ({
+  title: `Plan #${index + 1} from ${new Date(plan.createdAt)}`,
   value: plan.id,
   description: `ID: ${plan.id}`,
}))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c43245 and 80fe570.

📒 Files selected for processing (4)
  • packages/cli/src/commands/import/apply.ts (1 hunks)
  • packages/cli/src/commands/import/cancel.ts (1 hunks)
  • packages/cli/src/commands/import/commit.ts (1 hunks)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/cli/src/commands/import/commit.ts
🧰 Additional context used
🧬 Code Definitions (1)
packages/cli/src/commands/import/plan.ts (4)
packages/cli/src/rest/projects.ts (1)
  • ImportPlan (43-49)
packages/cli/src/sourcegen/index.ts (2)
  • Program (29-29)
  • Output (28-28)
packages/cli/src/constructs/construct-codegen.ts (2)
  • ConstructCodegen (57-117)
  • sortResources (49-55)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
🪛 Biome (1.9.4)
packages/cli/src/commands/import/plan.ts

[error] 216-217: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (2)
packages/cli/src/commands/import/plan.ts (1)

29-51: Add unit tests to handle existing import plans scenario.

This comment matches a previously raised concern about missing tests when existing import plans are detected. Please ensure that you thoroughly test the flow through #handleExistingPlans, covering all user interactions and edge cases.

packages/cli/src/commands/import/apply.ts (1)

62-95: Great job addressing previous feedback.

You have correctly differentiated plan titles and handle the planId === undefined scenario. This makes the user experience clearer and avoids accidental errors.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (6)
packages/cli/src/constructs/check-codegen.ts (4)

70-75: Improve error handling for context lookups.

This code silently catches errors from lookupCheckPrivateLocations without logging or handling them. This could hide issues where context lookups fail, making debugging difficult.

Consider adding logging or a more explicit error handling strategy:

  const privateLocationIds = (() => {
    try {
      return context.lookupCheckPrivateLocations(resource.id)
    } catch (err) {
+     // Explicitly return undefined when no private locations found
+     // console.debug(`No private locations found for check ${resource.id}`)
      return undefined
    }
  })()

121-126: Improve error handling for alert channel lookups.

Similar to private location lookups, this code silently catches errors without any logging or explicit handling. Consider a more robust error handling approach.

Add explicit return and optional logging:

  const alertChannelIds = (() => {
    try {
      return context.lookupCheckAlertChannels(resource.id)
    } catch (err) {
+     // Explicitly return undefined when no alert channels found
+     // console.debug(`No alert channels found for check ${resource.id}`)
+     return undefined
    }
  })()

177-193: Add runtime type validation before casting resources.

The code assumes resources can be safely cast to specific check types. Consider validating the resource structure before casting to ensure type safety at runtime.

Consider adding validation before casting:

  switch (checkType) {
    case 'BROWSER':
+     // Validate resource has browser-specific properties before casting
+     if ('script' in resource || 'scriptPath' in resource) {
        this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
        return
+     } else {
+       throw new Error(`Invalid BROWSER check: missing required properties`)
+     }
    case 'API':

The same approach can be applied to other check types to ensure they have the required properties before casting.


149-149: Handle case when retryStrategy is undefined.

The retryStrategy property is optional in the CheckResource interface, but the code always calls valueForRetryStrategy without checking if it's undefined.

Consider making this conditional:

- builder.value('retryStrategy', valueForRetryStrategy(program, resource.retryStrategy))
+ if (resource.retryStrategy !== undefined || resource.retryStrategy === null) {
+   builder.value('retryStrategy', valueForRetryStrategy(program, resource.retryStrategy))
+ }

However, if the implementation of valueForRetryStrategy already handles undefined values properly, this change may not be necessary.

packages/cli/src/sourcegen/objectbuilder.ts (2)

26-28: Consider validating property names as JavaScript identifiers.

The builder doesn't validate that property names are valid JavaScript identifiers, which could lead to generated code that doesn't compile.

Add validation for property names:

  string (name: string, value: string, options?: ObjectPropertyOptions): this {
+   this.validatePropertyName(name);
    return this.value(name, new StringValue(value), options)
  }

+ private validatePropertyName(name: string): void {
+   // Basic validation for JS identifiers or string literals
+   if (!/^[a-zA-Z_$][\w$]*$/.test(name) && !name.startsWith("'") && !name.startsWith('"')) {
+     console.warn(`Warning: '${name}' may not be a valid JavaScript property identifier`);
+   }
+ }

This suggestion applies to all property-adding methods, so the validation should be centralized in one place.


18-75: Consider supporting computed property names.

The current implementation does not support computed property names (e.g., [expression]: value), which might be needed for some code generation use cases.

Add support for computed property names:

computedProperty(
  expression: Value, 
  value: Value, 
  options?: ObjectPropertyOptions
): this {
  // Create a special type of property that renders as [expression]: value
  this.#properties.set(`__computed_${this.#properties.size}`, {
    name: expression,
    value,
    isComputed: true,
    options
  });
  return this;
}

This would require extending the ObjectProperty class to support computed names.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3f66f9 and 32da294.

📒 Files selected for processing (3)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/sourcegen/decl.ts (1 hunks)
  • packages/cli/src/sourcegen/objectbuilder.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/cli/src/sourcegen/decl.ts
🧰 Additional context used
🧬 Code Definitions (2)
packages/cli/src/constructs/check-codegen.ts (12)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (2)
  • ApiCheckCodegen (48-163)
  • ApiCheckResource (14-25)
packages/cli/src/constructs/check-group-codegen.ts (1)
  • CheckGroupCodegen (241-264)
packages/cli/src/constructs/heartbeat-check-codegen.ts (2)
  • HeartbeatCheckCodegen (11-29)
  • HeartbeatCheckResource (6-9)
packages/cli/src/constructs/multi-step-check-codegen.ts (2)
  • MultiStepCheckCodegen (15-42)
  • MultiStepCheckResource (6-11)
packages/cli/src/constructs/tcp-check-codegen.ts (2)
  • TcpCheckCodegen (29-72)
  • TcpCheckResource (7-12)
packages/cli/src/sourcegen/objectbuilder.ts (8)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/object.ts (3)
  • ObjectValueOptions (22-24)
  • ObjectProperty (8-18)
  • ObjectValue (58-88)
packages/cli/src/sourcegen/string.ts (1)
  • StringValue (6-17)
packages/cli/src/sourcegen/boolean.ts (1)
  • BooleanValue (4-15)
packages/cli/src/sourcegen/number.ts (1)
  • NumberValue (4-15)
packages/cli/src/sourcegen/null.ts (1)
  • NullValue (4-8)
packages/cli/src/sourcegen/undefined.ts (1)
  • UndefinedValue (4-8)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (4-15)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (3)
packages/cli/src/constructs/check-codegen.ts (1)

174-196: Remove "return" statements in a void function.

The gencode method is declared to return void but uses return statements after delegating to specific check codegen methods. Since the function doesn't return a value, these return statements are unnecessary.

Apply this diff to fix the issue:

  gencode (logicalId: string, resource: CheckResource, context: Context): void {
    const { checkType } = resource

    switch (checkType) {
      case 'BROWSER':
-       this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
-       return
+       this.browserCheckCodegen.gencode(logicalId, resource as BrowserCheckResource, context)
+       break
      case 'API':
-       this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
-       return
+       this.apiCheckCodegen.gencode(logicalId, resource as ApiCheckResource, context)
+       break
      case 'TCP':
-       this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
-       return
+       this.tcpCheckCodegen.gencode(logicalId, resource as TcpCheckResource, context)
+       break
      case 'MULTI_STEP':
-       this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
-       return
+       this.multiStepCheckCodegen.gencode(logicalId, resource as MultiStepCheckResource, context)
+       break
      case 'HEARTBEAT':
-       this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
-       return
+       this.heartbeatCheckCodegen.gencode(logicalId, resource as HeartbeatCheckResource, context)
+       break
      default:
        throw new Error(`Unable to generate code for unsupported check type '${checkType}'.`)
    }
  }
packages/cli/src/sourcegen/objectbuilder.ts (2)

67-70: LGTM: Property overwriting behavior is appropriate.

The implementation correctly overwrites properties with the same name when they're added multiple times. This follows JavaScript's object property behavior and allows for property overrides in a builder pattern.


12-16: Support for immutability and method chaining.

The builder pattern implementation follows good practices for fluent interfaces with method chaining and appropriate immutability. The factory function object() provides a clean API for creating object values.

Copy link
Contributor

@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: 0

♻️ Duplicate comments (2)
packages/cli/src/constructs/status-page-codegen.ts (1)

12-22: Validate optional properties with fallback defaults.

While customDomain, logo, redirectTo, etc., are marked optional, consider adding basic validation or fallback handling. For example, you might ensure that any absent optional properties have safe defaults to avoid runtime errors.

packages/cli/src/constructs/check-group-codegen.ts (1)

23-43: Inconsistent usage of doubleCheck and concurrency.

These fields are declared in the CheckGroupResource interface but never used inside buildCheckGroupProps. This can lead to incomplete or incorrect code generation.

🧹 Nitpick comments (7)
packages/cli/src/constructs/status-page-codegen.ts (4)

43-49: Improve error handling in service lookup.

The try-catch block catches all errors but doesn't distinguish between a missing service and other potential errors that might occur during lookup. Consider adding more specific error handling or validating the service existence before attempting to look it up.

- try {
-   const serviceVariable = context.lookupStatusPageService(service.id)
-   builder.value(serviceVariable)
- } catch (err) {
-   throw new Error(`Status page '${resource.id}' refers to service '${service.id}' which is not being imported.`)
- }
+ if (context.hasStatusPageService(service.id)) {
+   const serviceVariable = context.lookupStatusPageService(service.id)
+   builder.value(serviceVariable)
+ } else {
+   throw new Error(`Status page '${resource.id}' refers to service '${service.id}' which is not being imported.`)
+ }

This assumes a hasStatusPageService method exists or could be added to the Context class.


71-73: Validate the defaultTheme value.

The code doesn't validate if the provided defaultTheme value is one of the allowed themes from the StatusPageTheme enum. Consider adding validation to ensure the theme is valid before using it.

if (resource.defaultTheme) {
+  // Ensure the theme is valid
+  if (!Object.values(StatusPageTheme).includes(resource.defaultTheme)) {
+    throw new Error(`Invalid theme '${resource.defaultTheme}' for status page '${resource.id}'.`)
+  }
  builder.string('defaultTheme', resource.defaultTheme)
}

55-73: Consider refactoring conditional property assignments.

The repeated conditional blocks for optional properties follow the same pattern and could be refactored to reduce duplication. This would make the code more maintainable if additional optional properties are added in the future.

- if (resource.customDomain) {
-   builder.string('customDomain', resource.customDomain)
- }
-
- if (resource.logo) {
-   builder.string('logo', resource.logo)
- }
-
- if (resource.redirectTo) {
-   builder.string('redirectTo', resource.redirectTo)
- }
-
- if (resource.favicon) {
-   builder.string('favicon', resource.favicon)
- }
-
- if (resource.defaultTheme) {
-   builder.string('defaultTheme', resource.defaultTheme)
- }
+ // Handle optional properties
+ const optionalProps = [
+   { key: 'customDomain', value: resource.customDomain },
+   { key: 'logo', value: resource.logo },
+   { key: 'redirectTo', value: resource.redirectTo },
+   { key: 'favicon', value: resource.favicon },
+   { key: 'defaultTheme', value: resource.defaultTheme },
+ ]
+
+ for (const { key, value } of optionalProps) {
+   if (value !== undefined) {
+     builder.string(key, value)
+   }
+ }

27-77: Consider breaking down the gencode method.

The gencode method is quite long and handles multiple responsibilities. Consider extracting parts of it into helper methods for better readability and maintainability, such as a separate method for generating the cards section.

gencode (logicalId: string, resource: StatusPageResource, context: Context): void {
  this.program.import(construct, 'checkly/constructs')

  this.program.section(expr(ident(construct), builder => {
    builder.new(builder => {
      builder.string(logicalId)
      builder.object(builder => {
        builder.string('name', resource.name)
        builder.string('url', resource.url)

-       builder.array('cards', builder => {
-         for (const card of resource.cards) {
-           builder.object(builder => {
-             builder.string('name', card.name)
-             builder.array('services', builder => {
-               for (const service of card.services) {
-                 try {
-                   const serviceVariable = context.lookupStatusPageService(service.id)
-                   builder.value(serviceVariable)
-                 } catch (err) {
-                   throw new Error(`Status page '${resource.id}' refers to service '${service.id}' which is not being imported.`)
-                 }
-               }
-             })
-           })
-         }
-       })
+       this.generateCards(builder, resource, context)

        // Handle optional properties
        if (resource.customDomain) {
          builder.string('customDomain', resource.customDomain)
        }
        // ... other optional properties
      })
    })
  }))
}

+ /**
+  * Generate the cards section of the status page
+  */
+ private generateCards(builder: any, resource: StatusPageResource, context: Context): void {
+   builder.array('cards', builder => {
+     for (const card of resource.cards) {
+       builder.object(builder => {
+         builder.string('name', card.name)
+         builder.array('services', builder => {
+           for (const service of card.services) {
+             try {
+               const serviceVariable = context.lookupStatusPageService(service.id)
+               builder.value(serviceVariable)
+             } catch (err) {
+               throw new Error(`Status page '${resource.id}' refers to service '${service.id}' which is not being imported.`)
+             }
+           }
+         })
+       })
+     }
+   })
+ }
packages/cli/src/constructs/tcp-check-codegen.ts (1)

29-73: Optional validation for TCP port
The gencode method correctly constructs a TCP check object. As a minor improvement, consider validating resource.request.port or defaulting if the port is out of typical range to safeguard user errors.

packages/cli/src/constructs/check-codegen.ts (1)

162-204: Check routing via gencode
The CheckCodegen class routes checks to specific code generators based on the checkType. This design is modular and maintainable. However, note that returning early from a function typed as void can conflict with certain static analyzers.

Consider removing the early return statements and use break clauses in the switch to align with “no-return-in-void” guidelines.

packages/cli/src/constructs/check-group-codegen.ts (1)

45-251: Consider splitting the function into smaller subroutines.

The buildCheckGroupProps function is quite large (~200 lines). Splitting it into separate helper functions (e.g. buildLocationProps, buildApiCheckDefaultsProps, etc.) would improve readability and make future maintenance more manageable.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32da294 and 5fc5147.

📒 Files selected for processing (8)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/sourcegen/objectbuilder.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts
🧰 Additional context used
🧬 Code Graph Analysis (5)
packages/cli/src/constructs/tcp-check-codegen.ts (3)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckResource (17-35)
packages/cli/src/constructs/tcp-check.ts (2)
  • TcpRequest (20-46)
  • TcpAssertion (8-8)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForGeneralAssertion (45-146)
  • valueForNumericAssertion (4-43)
packages/cli/src/constructs/api-check-codegen.ts (5)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckResource (17-35)
packages/cli/src/constructs/api-check.ts (2)
  • Request (79-95)
  • headers (29-31)
packages/cli/src/constructs/internal/assertion-codegen.ts (1)
  • valueForNumericAssertion (4-43)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/check-codegen.ts (12)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (5-138)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/api-check-codegen.ts (2)
  • ApiCheckCodegen (48-169)
  • ApiCheckResource (14-25)
packages/cli/src/constructs/check-group-codegen.ts (1)
  • CheckGroupCodegen (255-278)
packages/cli/src/constructs/heartbeat-check-codegen.ts (2)
  • HeartbeatCheckCodegen (11-29)
  • HeartbeatCheckResource (6-9)
packages/cli/src/constructs/multi-step-check-codegen.ts (2)
  • MultiStepCheckCodegen (15-42)
  • MultiStepCheckResource (6-11)
packages/cli/src/constructs/tcp-check-codegen.ts (2)
  • TcpCheckCodegen (29-74)
  • TcpCheckResource (7-12)
packages/cli/src/constructs/check-group-codegen.ts (5)
packages/cli/src/constructs/frequency-codegen.ts (1)
  • FrequencyResource (4-4)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1)
  • AlertEscalationResource (4-4)
packages/cli/src/constructs/api-check.ts (2)
  • ApiCheckDefaultConfig (71-77)
  • headers (29-31)
packages/cli/src/constructs/retry-strategy-codegen.ts (1)
  • RetryStrategyResource (4-4)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/sourcegen/objectbuilder.ts (9)
packages/cli/src/sourcegen/object.ts (4)
  • ObjectValueOptions (22-24)
  • ObjectProperty (8-18)
  • ObjectPropertyOptions (4-6)
  • ObjectValue (58-88)
packages/cli/src/sourcegen/arraybuilder.ts (7)
  • object (54-56)
  • build (71-73)
  • value (62-65)
  • ArrayValueBuilder (18-74)
  • array (12-16)
  • array (50-52)
  • expr (58-60)
packages/cli/src/sourcegen/exprbuilder.ts (4)
  • build (39-41)
  • context (34-37)
  • ExpressionValueBuilder (11-42)
  • expr (5-9)
packages/cli/src/sourcegen/string.ts (1)
  • StringValue (6-17)
packages/cli/src/sourcegen/boolean.ts (1)
  • BooleanValue (4-15)
packages/cli/src/sourcegen/number.ts (1)
  • NumberValue (4-15)
packages/cli/src/sourcegen/null.ts (1)
  • NullValue (4-8)
packages/cli/src/sourcegen/undefined.ts (1)
  • UndefinedValue (4-8)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (4-15)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (21)
packages/cli/src/sourcegen/objectbuilder.ts (9)

1-11: Imports are well-structured.
All imported modules appear relevant to this file’s builder logic. No concerns.


12-16: Effective extension of ObjectValueOptions.
The additional implicitOrder properties cleanly enable auto-ordering of object properties. This design is flexibly optional, so no immediate suggestions.


18-22: Builder pattern elegantly initiated.
The object function provides a concise entry point for constructing a wrapped ObjectValue. Good approach for consistent usage throughout the codebase.


24-30: Solid private fields for builder state.
Storing properties in #properties avoids duplication and leverages a Map’s overwrite behavior. No issues found.


31-47: Constructor is clear and extensible.
Merging user-provided options and setting defaults is straightforward. Consider whether negative or zero step values need special handling; otherwise, this is well done.

Would you like to verify that negative or zero implicitOrderStep works as intended?


49-79: Type-specific property setters are well-defined.
These methods reinforce clarity and strongly type the object’s properties. The fluid chainable design is consistent.


81-88: Expression builder integration looks sound.
Exposing expr with a context value plus a builder function seamlessly aligns with the rest of the pattern. No concerns.


90-103: Overwriting existing properties addresses prior feedback.
Using Map.set ensures each key is unique, resolving the older concern about stacking multiple ObjectProperty instances. Nicely handled.


105-108: build() finalizes correctly.
Returning an ObjectValue with sorted properties is consistent with other sourcegen patterns. This sealed approach is maintainable.

packages/cli/src/constructs/tcp-check-codegen.ts (2)

7-12: Adequate extension of CheckResource for TCP checks
The TcpCheckResource interface properly extends CheckResource and designates the checkType as 'TCP', which aligns with how checkType is handled in the central code generation logic.


14-25: Assertion source coverage verification
The function gracefully covers 'RESPONSE_DATA' and 'RESPONSE_TIME' sources. Confirm that these are the only necessary assertion sources for TCP checks.

Do you plan to add support for any additional assertion sources in TCP? If not, this coverage is fine.

packages/cli/src/constructs/api-check-codegen.ts (4)

8-12: SnippetResource interface design
The SnippetResource interface is straightforward and captures snippet details correctly.


14-25: Robust API check interface
ApiCheckResource extends the base CheckResource well, adding essential fields like request configs and optional scripts. The naming is intuitive.


27-44: Comprehensive assertion handling
valueForAssertion handles numeric and general assertions. This logic is consistent with the underlying assertion-codegen pattern and covers typical assertion sources (e.g., STATUS_CODE, JSON_BODY, HEADERS, TEXT_BODY, RESPONSE_TIME).


48-169: Well-structured code generation for API checks
The ApiCheckCodegen class thoroughly constructs API check objects with optional script references, request headers, query parameters, and authentication. This design is consistent across other check codegen classes. No major improvements are needed.

packages/cli/src/constructs/check-codegen.ts (2)

17-35: Clear base check interface
CheckResource provides a robust and consistent base for all check types. The optional fields align well with the different check type requirements.


37-160: Sound assembly of check properties
buildCheckProps correctly assembles all relevant fields, including groups, locations, environment variables, tags, and alert settings, while gracefully handling missing resources with well-defined error messages. This approach effectively centralizes shared property logic.

packages/cli/src/constructs/check-group-codegen.ts (4)

76-81: Avoid silently ignoring errors.

Catching the error here without logging or further handling may mask possible issues. Consider either logging the error or re-throwing it.


122-127: Avoid silently ignoring errors.

Similar to the earlier try-catch block, consider logging or handling the error in some way to keep visibility into unexpected failures.


223-231: Validate partial basicAuth instead of skipping it entirely.

Currently, if either username or password is blank, the entire basicAuth block is unused. Confirm whether this is intentional or if partial credentials need to be supported or flagged.


256-279: Confirm error handling for lookupCheckGroup.

context.lookupCheckGroup(resource.id) may throw if resource.id is invalid or not found. Verify that the calling code or upstream logic guarantees a valid ID, or consider adding error handling here.

Copy link
Contributor

@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: 7

♻️ Duplicate comments (3)
packages/cli/src/constructs/status-page-codegen.ts (1)

12-22: Validate optional properties with fallback defaults.

While customDomain, logo, redirectTo, etc., are marked optional, consider adding basic validation or fallback handling. For example, you might ensure that any absent optional properties have safe defaults to avoid runtime errors.

packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)

51-51: Remove redundant .toString() call.

This comment mirrors a previous review remark: since config.url is already a string, calling .toString() introduces unnecessary overhead and potential confusion.

packages/cli/src/constructs/check-group-codegen.ts (1)

28-33: Unused properties doubleCheck and concurrency.

These properties appear in the CheckGroupResource interface but aren’t used in buildCheckGroupProps. If they’re needed, include them in the generated object; otherwise, remove them. This reiterates a prior suggestion.

🧹 Nitpick comments (21)
packages/cli/src/constructs/retry-strategy-codegen.ts (1)

30-37: Consider consolidating duplicate no-retries logic.

There's code duplication between this null/undefined handling block and the 'NO_RETRIES' case later in the switch statement. Consider extracting this logic to a helper function.

 if (strategy === null || strategy === undefined) {
-  return expr(ident('RetryStrategyBuilder'), builder => {
-    builder.member(ident('noRetries'))
-    builder.call(builder => {
-      builder.empty()
-    })
-  })
+  return buildNoRetriesExpression()
 }

+function buildNoRetriesExpression(): Value {
+  return expr(ident('RetryStrategyBuilder'), builder => {
+    builder.member(ident('noRetries'))
+    builder.call(builder => {
+      builder.empty()
+    })
+  })
+}
packages/cli/src/constructs/maintenance-window-codegen.ts (3)

4-12: Remove unnecessary comma after tags property for consistency.

There's an inconsistent use of commas in the interface definition. The property tags has a trailing comma while other properties don't.

 export interface MaintenanceWindowResource {
   name: string
-  tags: Array<string>,
+  tags: Array<string>
   startsAt: string
   endsAt: string
   repeatInterval?: number
   repeatUnit?: string
   repeatEndsAt?: string
 }

54-61: Simplify by removing unnecessary variable assignment.

The temporary repeatEndsAt variable doesn't add value and can be removed to simplify the code.

 if (resource.repeatEndsAt) {
-  const repeatEndsAt = resource.repeatEndsAt
   builder.expr('repeatEndsAt', ident('Date'), builder => {
     builder.new(builder => {
-      builder.string(repeatEndsAt)
+      builder.string(resource.repeatEndsAt)
     })
   })
 }

34-44: Consider validating date string formats.

The code assumes that startsAt and endsAt are valid date strings that can be parsed by the Date constructor. Consider adding validation to ensure these are in a valid format to prevent runtime issues.

+ // Add at the beginning of the gencode method
+ function validateDateString(value: string, fieldName: string): void {
+   const date = new Date(value)
+   if (isNaN(date.getTime())) {
+     throw new Error(`Invalid date format for ${fieldName}: ${value}`)
+   }
+ }
+ 
+ validateDateString(resource.startsAt, 'startsAt')
+ validateDateString(resource.endsAt, 'endsAt')
+ if (resource.repeatEndsAt) {
+   validateDateString(resource.repeatEndsAt, 'repeatEndsAt')
+ }
packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)

5-11: Consider adding validation for the Slack url.

Although this interface is part of the generation logic, you might still consider throwing an error if url is empty or malformed. This can prevent accidental misconfigurations.

packages/cli/src/constructs/status-page-codegen.ts (1)

44-53: Consider extracting the service lookup logic to a separate method.

The try-catch block for service lookup could be extracted to a helper method to improve code maintainability and readability.

+ private lookupServiceWithErrorHandling(context: Context, statusPageId: string, service: StatusPageServiceResource): VariableLocator {
+   try {
+     const serviceVariable = context.lookupStatusPageService(service.id)
+     return serviceVariable
+   } catch (err) {
+     throw new Error(`Status page '${statusPageId}' refers to service '${service.id}' which is not being imported. Please ensure the service is included in your import plan or remove it from the status page.`)
+   }
+ }

  gencode (logicalId: string, resource: StatusPageResource, context: Context): void {
    // ...existing code...
    
    builder.array('cards', builder => {
      for (const card of resource.cards) {
        builder.object(builder => {
          builder.string('name', card.name)
          builder.array('services', builder => {
            for (const service of card.services) {
-             try {
-               const serviceVariable = context.lookupStatusPageService(service.id)
-               context.importVariable(serviceVariable, file)
-               builder.value(serviceVariable.id)
-             } catch (err) {
-               throw new Error(`Status page '${resource.id}' refers to service '${service.id}' which is not being imported.`)
-             }
+             const serviceVariable = this.lookupServiceWithErrorHandling(context, resource.id, service)
+             context.importVariable(serviceVariable, file)
+             builder.value(serviceVariable.id)
            }
          })
        })
      }
    })
packages/cli/src/commands/import/plan.ts (2)

237-239: Remove useless case clause.

The case 'exit': is immediately followed by a fall-through to the default case, making it redundant.

- case 'exit':
-   // falls through
  default: {
    this.log('Exiting without making any changes.')
    this.exit(0)
  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 238-238: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)


167-244: Add a safety mechanism to prevent infinite loops.

The while loop used for handling user interactions has no explicit termination condition other than returning or exiting. Consider adding a maximum iteration count or a more explicit way to break out of the loop.

+ let attempts = 0;
+ const MAX_ATTEMPTS = 5;
  while (true) {
+   if (attempts >= MAX_ATTEMPTS) {
+     this.log('Maximum number of attempts reached. Exiting without making changes.');
+     this.exit(1);
+     return;
+   }
+   attempts++;
    
    const { action } = await prompts({
      // ...existing code...
    })
    
    // ...existing code...
  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 238-238: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)

6-10: Consider using a more specific type for webhookType.

The webhookType property is set to the string literal 'WEBHOOK_MSTEAMS', but it could be more flexible and type-safe to use a predefined enum or string union type that includes 'WEBHOOK_MSTEAMS'.

+ // Add this where WebhookType is defined or import it
+ export type MSTeamsWebhookType = 'WEBHOOK_MSTEAMS';

export interface MSTeamsAlertChannelResource extends WebhookAlertChannelResource {
  config: WebhookAlertChannelResourceConfig & {
-   webhookType: 'WEBHOOK_MSTEAMS'
+   webhookType: MSTeamsWebhookType
  }
}
packages/cli/src/constructs/check-codegen.ts (3)

75-77: Avoid silently swallowing errors.
The empty catch block makes debugging difficult. At minimum, log the error or handle it explicitly so that unexpected issues do not pass silently.

  const privateLocationIds = (() => {
    try {
      return context.lookupCheckPrivateLocations(resource.id)
    } catch (err) {
-     
+      console.error("Failed to lookup private locations:", err);
    }
  })()

129-133: Repeated silent error handling.
Similar to the previous comment, consider logging or handling the error to maintain visibility into the resolution path for missing alert channels.

  const alertChannelIds = (() => {
    try {
      return context.lookupCheckAlertChannels(resource.id)
    } catch (err) {
-     
+      console.warn("Could not retrieve alert channels:", err);
    }
  })()

186-202: Consider a consistent approach to flow control.
Multiple return statements in a void method are valid but can reduce readability. As an alternative, each case could end with break. Continue returning if you prefer the early exit style, but be aware of potential confusion in larger functions.

packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1)

26-50: Validate config fields if used outside codegen.
Everything looks fine for generating code, but be sure name, apiKey, region, and priority align with Opsgenie’s requirements if your tooling later depends on them being non-empty or valid enumerations.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1)

25-54: Consider optional validation for the 'serviceKey' property.
If your code depends on a valid non-empty key, ensure a presence check or additional validations happen upstream to avoid misconfiguration.

packages/cli/src/constructs/status-page-service-codegen.ts (1)

4-7: Consider adding JSDoc comments.

While the StatusPageServiceResource interface is straightforward, adding JSDoc comments or usage examples can improve clarity for future maintainers and consumers of this interface.

packages/cli/src/constructs/check-group-codegen.ts (2)

76-81: Avoid silently swallowing errors.

The try/catch blocks in these ranges discard errors without logging or handling them. This can obscure debugging efforts and create uncertainty about the presence of genuine failures. At a minimum, consider logging or otherwise managing the caught errors.

Also applies to: 123-128


45-253: Consider splitting buildCheckGroupProps for readability.

The function spans over 200 lines and handles a wide array of properties and logic. Splitting it into smaller helper functions (e.g., dedicated handling for alerts, private locations, environment variables, etc.) would improve maintainability and test coverage.

packages/cli/src/constructs/alert-channel-codegen.ts (1)

31-51: Consider default handling for optional fields.
While this function conditionally sets properties, consider documenting or handling defaults for boolean and numeric fields when undefined, if needed.

packages/cli/src/sourcegen/program.ts (1)

52-78: Consider error handling on file writes.
If writeFile fails (e.g., due to permissions or disk errors), the process will throw, but the code does not handle it. Consider adding logging or structured error handling to provide robust feedback.

packages/cli/src/constructs/internal/codegen/context.ts (2)

31-35: Watch out for duplicate imports.
When calling importVariable, if a file is repeatedly imported from multiple places, it may accumulate references in #imports. Not necessarily harmful, but it’s worth noting if duplicates become large. You can consider checking if an import is already present before adding it again.


37-51: Group ID collisions.
registerCheckGroup generates an identifier based on the map’s size. If a re-registration for the same ID occurs, it might produce inconsistent results. Ensure each group is registered exactly once or handle collisions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fc5147 and 8558b04.

📒 Files selected for processing (32)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/codegen.nots (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/email-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/frequency-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/ref-codegen.ts (1 hunks)
  • packages/cli/src/constructs/retry-strategy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-service-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts
  • packages/cli/src/constructs/frequency-codegen.ts
  • packages/cli/src/constructs/heartbeat-check-codegen.ts
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts
  • packages/cli/src/sourcegen/index.ts
🧰 Additional context used
🧬 Code Graph Analysis (20)
packages/cli/src/constructs/ref-codegen.ts (3)
packages/cli/src/sourcegen/index.ts (4)
  • GeneratedFile (29-29)
  • Value (33-33)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (92-151)
packages/cli/src/constructs/ref.ts (1)
  • Ref (1-10)
packages/cli/src/constructs/maintenance-window-codegen.ts (3)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/index.ts (2)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/api-check-codegen.ts (9)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckResource (17-35)
packages/cli/src/constructs/api-check.ts (2)
  • Request (79-95)
  • headers (29-31)
packages/cli/src/sourcegen/index.ts (3)
  • GeneratedFile (29-29)
  • Value (33-33)
  • expr (22-22)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (92-151)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/sourcegen/exprbuilder.ts (1)
  • context (34-37)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/tcp-check-codegen.ts (6)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-163)
packages/cli/src/constructs/tcp-check.ts (2)
  • TcpRequest (20-46)
  • TcpAssertion (8-8)
packages/cli/src/sourcegen/index.ts (4)
  • GeneratedFile (29-29)
  • Value (33-33)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForGeneralAssertion (45-146)
  • valueForNumericAssertion (4-43)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (4)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/index.ts (3)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/retry-strategy-codegen.ts (3)
packages/cli/src/constructs/retry-strategy.ts (3)
  • RetryStrategy (3-21)
  • RetryStrategyOptions (23-23)
  • RetryStrategyType (1-1)
packages/cli/src/sourcegen/index.ts (5)
  • GeneratedFile (29-29)
  • Value (33-33)
  • ObjectValueBuilder (27-27)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (92-151)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (4)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/index.ts (3)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/commands/import/plan.ts (5)
packages/cli/src/services/util.ts (1)
  • splitConfigFilePath (126-138)
packages/cli/src/services/checkly-config-loader.ts (1)
  • loadChecklyConfig (123-149)
packages/cli/src/rest/projects.ts (1)
  • ImportPlan (43-49)
packages/cli/src/sourcegen/program.ts (1)
  • Program (15-78)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/constructs/status-page-codegen.ts (5)
packages/cli/src/constructs/status-page-service-codegen.ts (1)
  • StatusPageServiceResource (4-7)
packages/cli/src/constructs/status-page.ts (1)
  • StatusPageTheme (17-17)
packages/cli/src/constructs/internal/codegen/index.ts (1)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/index.ts (2)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/check-codegen.ts (7)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/sourcegen/index.ts (3)
  • GeneratedFile (29-29)
  • ObjectValueBuilder (27-27)
  • Program (29-29)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/private-location-codegen.ts (1)
  • valueForPrivateLocationFromId (14-23)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • valueForAlertChannelFromId (55-64)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (3)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/sourcegen/index.ts (3)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/status-page-service-codegen.ts (3)
packages/cli/src/constructs/internal/codegen/index.ts (1)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/index.ts (3)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/email-alert-channel-codegen.ts (4)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/index.ts (3)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/private-location-codegen.ts (4)
packages/cli/src/sourcegen/index.ts (5)
  • GeneratedFile (29-29)
  • Value (33-33)
  • expr (22-22)
  • ident (23-23)
  • decl (11-11)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (92-151)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/program.ts (2)
packages/cli/src/sourcegen/index.ts (5)
  • Value (33-33)
  • Program (29-29)
  • GeneratedFile (29-29)
  • AuxiliaryFile (29-29)
  • Output (28-28)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (4)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/index.ts (3)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/check-group-codegen.ts (7)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/api-check.ts (2)
  • ApiCheckDefaultConfig (71-77)
  • headers (29-31)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/sourcegen/index.ts (5)
  • GeneratedFile (29-29)
  • ObjectValueBuilder (27-27)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (4-17)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
packages/cli/src/sourcegen/index.ts (6)
  • ObjectValueBuilder (27-27)
  • GeneratedFile (29-29)
  • Value (33-33)
  • expr (22-22)
  • ident (23-23)
  • Program (29-29)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (5)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (2)
  • WebhookAlertChannelResource (28-31)
  • WebhookAlertChannelResourceConfig (17-26)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-160)
packages/cli/src/sourcegen/index.ts (3)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/alert-channel-codegen.ts (1)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/context.ts (3)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • MissingContextVariableMappingError (2-2)
  • Context (2-2)
packages/cli/src/sourcegen/index.ts (2)
  • IdentifierValue (23-23)
  • GeneratedFile (29-29)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (92-151)
🪛 Biome (1.9.4)
packages/cli/src/commands/import/plan.ts

[error] 238-238: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

🔇 Additional comments (58)
packages/cli/src/constructs/private-location-codegen.ts (4)

1-10: Interface definition for PrivateLocationResource looks good.

The interface properly defines the structure with required and optional properties. This will serve well as the contract for private location resources.


14-23: Well-structured utility function for referencing private locations by ID.

This function follows the established pattern for value generators, correctly importing the necessary construct and building the expression with proper nesting.


25-31: LGTM: Prepare method handles registration correctly.

The prepare method properly registers the private location in the context, allowing it to be referenced later in the import process.


33-59:

❓ Verification inconclusive

Consider adding error handling for missing resource lookups.

The gencode method currently doesn't handle potential errors if lookupPrivateLocation fails to find the resource by ID. While the Context class likely throws an error, it would be good to handle this case explicitly or document the expected behavior.


🏁 Script executed:

#!/bin/bash
# Check how Context.lookupPrivateLocation handles errors
ast-grep --pattern 'lookupPrivateLocation(physicalId: string): VariableLocator {
  $$$
  if ($$ === undefined) {
    $$$
  }
  $$$
}'

Length of output: 135


Explicit error handling for missing resource lookups in gencode

In packages/cli/src/constructs/private-location-codegen.ts (lines 33–59), the gencode method immediately destructures the result of context.lookupPrivateLocation(resource.id) without verifying that a valid lookup occurred. Even if the Context class is designed to throw an error when a lookup fails, it would improve code clarity and robustness to either explicitly handle a potential undefined result or document that error behavior clearly. Please manually verify that the lookupPrivateLocation method includes sufficient error handling and consider adding an explicit check (or appropriate documentation) if it does not.

packages/cli/src/constructs/ref-codegen.ts (1)

1-13: Clean implementation for generating reference values.

The function correctly imports the Ref construct and builds an expression to create a reference using Ref.from(). This follows the same pattern as other value generators in the codebase and doesn't have any obvious issues.

packages/cli/src/constructs/retry-strategy-codegen.ts (3)

4-5: Type alias for RetryStrategy is appropriate.

This provides a clear separation between the domain model and the codegen resource, which could be useful if they diverge in the future.


9-28: Helper function efficiently reuses common option setup.

The buildCommonOptions function correctly handles conditional properties, only adding them to the builder when they exist. This reduces code duplication when used across different strategy types.


39-76: Comprehensive handling of all retry strategy types.

The switch statement correctly handles all defined retry strategy types and throws an appropriate error for unsupported types. This makes the code robust to changes in the enum.

packages/cli/src/constructs/maintenance-window-codegen.ts (1)

16-24:

❓ Verification inconclusive

Missing prepare method that might be needed for resource registration.

Unlike PrivateLocationCodegen, this class doesn't have a prepare method. Consider whether maintenance windows need to be registered in the context for later reference by other resources.


🏁 Script executed:

#!/bin/bash
# Check if other resources reference maintenance windows
rg "maintenanceWindow|maintenance-window" --type ts

Length of output: 1556


Attention: Verify Resource Registration for Maintenance Windows

The current implementation of MaintenanceWindowCodegen (in packages/cli/src/constructs/maintenance-window-codegen.ts, lines 16–24) doesn’t contain a prepare method like PrivateLocationCodegen does. While our search confirms that maintenance window resources are referenced in various parts of the codebase, there is no evidence that a prepare method is invoked or necessary for their registration in the context. Please double-check whether maintenance windows should be registered (as with other resource types) and, if so, consider adding a prepare method to ensure consistency with resource registration logic.

packages/cli/src/constructs/slack-alert-channel-codegen.ts (4)

1-4: Imports look correct.

These imports are coherent with the rest of the codebase, and they properly reference the code generation utilities and context.


13-13: Construct naming is clear.

Declaring a distinct constant for the construct name aids readability and consistency.


15-22: prepare method usage is consistent.

The prepare method correctly registers the alert channel in the context. This approach is consistent with the rest of the codebase’s pattern for scanning resource IDs and references.


24-49: Leverage optional Slack channel property.

The logic clearly sets the channel property only when it is defined, which aligns with Slack's optional usage of channels. The usage of buildAlertChannelProps is also coherent with AlertChannelResource expansions.

packages/cli/src/constructs/tcp-check-codegen.ts (5)

1-6: Imports look consistent.

The references to Codegen, Context, and the source generation utilities are appropriate.


7-12: Sufficient extension of CheckResource.

TcpCheckResource captures the TCP-specific fields for this check type without overlap.


14-25: Switch statement for TCP assertions is thorough.

The valueForTcpAssertion function handles the supported assertion sources (RESPONSE_DATA, RESPONSE_TIME) and clearly errors out if something unexpected arises. This design ensures explicit coverage of valid assertion sources.


27-29: Construct naming aligns with usage.

Designating 'TcpCheck' as the construct name is consistent with the rest of the codegen approach.


30-75: gencode method effectively builds the resource.

  1. The creation of a dedicated file for these TCP checks under resources/tcp-checks/${logicalId} is clear.
  2. Conditionals for optional fields (ipFamily, data, assertions, etc.) properly exclude unused fields.
  3. Inclusion of buildCheckProps ensures consistent coverage of base check properties.

Everything looks solid.

packages/cli/src/constructs/email-alert-channel-codegen.ts (5)

1-4: Imports and references are correct.

No issues with referencing the codegen and context files.


5-11: EmailAlertChannelResource approach is straightforward.

This interface properly extends AlertChannelResource and defines the email-specific config.


12-13: Clear naming for the EmailAlertChannel.

Consistent naming with the rest of the alert channel codegen files.


14-22: prepare method usage.

It matches the established pattern for registering an alert channel with the 'emailAlert' variable prefix.


23-42: gencode method is consistent with existing patterns.

  1. Accurately imports the construct and retrieves the file and ID from the context.
  2. Correctly references address and applies buildAlertChannelProps for optional attributes.
  3. Code remains clear and follows the standard builder pattern.
packages/cli/src/constructs/api-check-codegen.ts (10)

1-7: Imports are well-structured.

References to context, expr, ident, and the assertion helpers are aligned with common usage.


8-12: SnippetResource is a helpful abstraction.

Centralizing snippet metadata (including id and script) makes code generation more flexible.


14-25: ApiCheckResource extension is correct.

Adding fields for scripts and response time parameters extends CheckResource suitably for API checks.


27-44: valueForAssertion is robust.

Correctly delegates to numeric or general assertion builders based on the assertion.source. Unrecognized sources throw an error, preventing silent failures.


46-47: Descriptive construct name.

ApiCheck is a fitting construct identifier.


48-54: Class definition and gencode method signature.

The structure extends Codegen<ApiCheckResource> consistently, matching the typical pattern.


55-72: Clarity in the outer new builder.

Creating a new check instance with ApiCheck and storing it in a dedicated generated file (resources/api-checks/${logicalId}) is a clean and consistent approach.


74-124: Comprehensive handling of request fields.

  1. Optional fields are correctly guarded by conditionals.
  2. Headers and query parameters are assembled using valueForKeyValuePair.
  3. Basic auth is validated to avoid empty credentials.

All are well-handled for a robust API check definition.


126-164: Setup and teardown script logic is clear.

  1. You toggle between local inline scripts and snippet references properly.
  2. The TODO remark for eventually storing scripts in a separate file is a good note for future refactoring.

166-170: Additional fields and final build.

Degraded and max response times are conditionally set, followed by a standardized call to buildCheckProps. This ensures consistent final property population for the check.

packages/cli/src/constructs/check-codegen.ts (1)

17-35: Interface definition looks solid.
The structure of CheckResource provides clear optional and required fields for different check attributes. This is well-organized for code generation needs.

packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (2)

5-13: Interface structure is consistent and clear.
The OpsgenieAlertChannelResource extends AlertChannelResource cleanly, ensuring type distinctions while inheriting common fields.


17-24:

✅ Verification successful

Verify alert channel variable naming.
When registering the alert channel with variablePrefix: 'opsgenieAlert', confirm that no other codegen uses the same prefix to avoid naming collisions.


🏁 Script executed:

#!/bin/bash
# Searching for existing code that uses the same prefix "opsgenieAlert"
rg "opsgenieAlert"

Length of output: 103


Unique variable naming verified for Opsgenie alert channel
The search shows that the prefix 'opsgenieAlert' is used only in packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts. No naming collisions exist.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (2)

5-12: Interface extension is appropriate.
PagerdutyAlertChannelResource properly extends AlertChannelResource and specializes the configuration for PagerDuty.


17-23:

✅ Verification successful

Confirm unique variable naming.
Similar to other alert-channel codegens, ensure 'pagerdutyAlert' is unique and does not conflict with other variables in the context.


🏁 Script executed:

#!/bin/bash
# Searching for existing code that uses the same prefix "pagerdutyAlert"
rg "pagerdutyAlert"

Length of output: 106


Unique Identifier Confirmed
The search confirms that 'pagerdutyAlert' is only used within packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts. There are no duplicate occurrences or conflicts with other alert-channel implementations.

packages/cli/src/constructs/status-page-service-codegen.ts (2)

12-17: Well-structured registration logic.

The prepare method cleanly registers the resource in the code generation context. No issues spotted regarding correctness or maintainability.


19-36: Implementation looks good.

The gencode method properly looks up the resource, imports the required construct, and declares the new status page service. This adheres to the established code generation patterns.

packages/cli/src/constructs/codegen.nots (1)

1-23: All exports appear appropriate.

These exports neatly consolidate different code generation classes. No issues spotted regarding performance, correctness, or maintainability.

packages/cli/src/constructs/alert-channel-codegen.ts (6)

1-2: Imports look clean and consistent.
No issues identified with the import locations or references.


12-20: Enum-like union type is well-defined.
All alert channel types are clearly enumerated, making it less prone to typos or invalid values.


21-29: Interface captures all necessary fields.
The AlertChannelResource interface looks comprehensive. Just ensure the numeric id field aligns with the rest of the codebase’s schema (e.g., the same IDs used elsewhere).


66-95: Centralizing codegen instances is a solid approach.
The constructor neatly aggregates specialized code generators for each alert channel type, reducing repetition and improving maintainability.


97-114: Delegation logic is clear and cohesive.
Using prepare and gencode methods on the respective codegen instance is clean and keeps the code organized.


55-64:

❓ Verification inconclusive

Validate named import.
Verify that 'AlertChannel' is indeed the correct export from 'checkly/constructs'. Otherwise, consider adjusting the import logic or rename to match the actual identifier.


🏁 Script executed:

#!/bin/bash
rg -A 5 "export class AlertChannel" 

Length of output: 1880


Action: Verify the Imported Alert Channel Identifier

It appears that the module 'checkly/constructs' does not export an identifier named AlertChannel—instead, classes such as AlertChannelCodegen (and related ones) are being exported. Please double-check if the intended export should actually be AlertChannel or whether the import/usage should be updated to reference the correct, existing export (e.g., AlertChannelCodegen). Adjust the import logic accordingly.

packages/cli/src/sourcegen/program.ts (7)

1-2: Imports are straightforward and necessary.
No concerns with basic Node.js imports.


10-13: Program options are concise.
The ProgramOptions interface is minimal and readable.


15-41: Paths gathering is efficient and well-scoped.
The paths getter returns a sorted list, which can simplify file operations. Implementation appears correct.


42-50: Confirm parallel usage handling.
If multiple calls to generatedFile happen in parallel for the same path, the code might race while creating or retrieving the same file. Verify if concurrency is relevant or if the usage is strictly sequential.


80-86: Base program file implementation is correct.
Maintaining a path property is enough for usage by derived classes.


92-151: Import logic and rendering appear sound.
The approach ensures imports are aggregated neatly, and direct .ts extensions are converted to .js. This is consistent with modern JS bundling requirements.


153-161: Auxiliary file class is straightforward.
Storing raw content in a separate file class is a good separation of concerns.

packages/cli/src/constructs/internal/codegen/context.ts (4)

5-5: Custom error class is appropriate.
MissingContextVariableMappingError cleanly expresses the missing context variable scenario.


7-15: Locator design is clear.
Encapsulating both the identifier and file into VariableLocator helps maintain cohesive references in code generation.


53-67: Alert channel registration is straightforward.
Mapping a physical ID to a code generation variable is consistent with the approach taken for check groups and private locations.


69-160: Overall context design is cohesive.
The repeated pattern for private locations, checks, status pages, and alert channels maintains consistency. All lookups and registrations appear systematically handled.

const context = new Context()

if (plan.changes) {
sortResources(plan.changes.resources as any)
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid using any type for better type safety.

Using any for type casting loses TypeScript's type checking benefits and can lead to runtime errors. Consider creating a proper type or interface for the resources.

- sortResources(plan.changes.resources as any)
+ // Define an appropriate interface for your resources
+ type ImportPlanResource = {
+   logicalId: string;
+   // Add other properties as needed
+ };
+ sortResources(plan.changes.resources as ImportPlanResource[])
📝 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.

Suggested change
sortResources(plan.changes.resources as any)
// Define an appropriate interface for your resources
type ImportPlanResource = {
logicalId: string;
// Add other properties as needed
};
sortResources(plan.changes.resources as ImportPlanResource[])

Comment on lines 32 to 932
async run (): Promise<void> {
const { flags } = await this.parse(ImportPlanCommand)
const {
config: configFilename,
root: rootDirectory,
} = flags

const { configDirectory, configFilenames } = splitConfigFilePath(configFilename)
const {
config: checklyConfig,
} = await loadChecklyConfig(configDirectory, configFilenames)

const {
logicalId,
} = checklyConfig

const { data: existingPlans } = await api.projects.findImportPlans(logicalId, {
onlyUncommitted: true,
})

if (existingPlans.length !== 0) {
await this.#handleExistingPlans(existingPlans)
}

if (this.fancy) {
ux.action.start('Creating a new plan', undefined, { stdout: true })
}

let plan: ImportPlan

try {
const { data } = await api.projects.createImportPlan(logicalId)
plan = data

if (this.fancy) {
ux.action.stop('✅ ')
}
} catch (err) {
if (this.fancy) {
ux.action.stop('❌')
}

if (isAxiosError(err)) {
if (err.response?.status === 404) {
const message = err.response?.data.message
if (message) {
this.log(chalk.red(message))
return
}
}
}

throw err
}

const program = new Program({
rootDirectory,
ext: '.check.ts',
})

this.#generateCode(plan, program)

if (this.fancy) {
ux.action.start('Writing files', undefined, { stdout: true })
}

try {
await program.realize()

if (this.fancy) {
ux.action.stop('✅ ')
}
} catch (err) {
if (this.fancy) {
ux.action.stop('❌')
}

throw err
}

this.log(`${logSymbols.success} Successfully generated the following files for your import plan:`)
for (const filePath of program.paths) {
this.log(` - ${chalk.green(filePath)}`)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Add unit tests for handling existing import plans.

The code for handling existing import plans is complex with multiple paths, but there's no indication of unit tests to verify that all scenarios work as expected.

Would you like me to help create unit tests for the various paths in the #handleExistingPlans method?


🏁 Script executed:

#!/bin/bash
# Search for existing tests related to this command
echo "Searching for tests related to ImportPlanCommand..."
rg -A 5 "ImportPlanCommand" --type ts

echo "Searching for test files related to import functionality..."
rg -l "import.*plan" --type ts tests

Length of output: 1203


Action Required: Implement comprehensive unit tests for handling existing import plans

The logic for managing existing import plans (specifically within the #handleExistingPlans method) involves multiple execution paths—error handling (e.g., the 404 response from api.projects.createImportPlan), conditional logging, and the behavior of the fancy UX actions. Our codebase search did not return any related unit tests, so it appears this functionality isn’t currently covered by tests.

  • Missing unit tests: There are no unit tests present for this command or for verifying the multiple conditions in the existing plans handling logic.
  • Key areas to cover:
    • The scenario where existingPlans.length !== 0 triggers the handling routine.
    • Error responses, particularly when Axios returns a 404 with a valid message.
    • The UX feedback (using ux.action.start and ux.action.stop) in both success and error cases.

Would you like assistance in creating unit tests that cover these scenarios?

Comment on lines 69 to 831
} catch (err) {
if (this.fancy) {
ux.action.stop('❌')
}

if (isAxiosError(err)) {
if (err.response?.status === 404) {
const message = err.response?.data.message
if (message) {
this.log(chalk.red(message))
return
}
}
}

throw err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance error handling with specific error messages.

The error handling in the catch block could be improved by providing more specific error messages for different types of errors, not just 404s.

try {
  // ...existing code...
} catch (err) {
  if (this.fancy) {
    ux.action.stop('❌')
  }

  if (isAxiosError(err)) {
    if (err.response?.status === 404) {
      const message = err.response?.data.message
      if (message) {
        this.log(chalk.red(message))
        return
      }
    }
+   // Handle other status codes
+   if (err.response?.status === 401) {
+     this.log(chalk.red('Authentication error. Please check your API credentials.'))
+     return
+   }
+   if (err.response?.status === 403) {
+     this.log(chalk.red('You do not have permission to create import plans.'))
+     return
+   }
+   // Log other response errors
+   if (err.response?.data?.message) {
+     this.log(chalk.red(`API error: ${err.response.data.message}`))
+     return
+   }
  }
+ 
+ // Log non-API errors in a user-friendly way
+ this.log(chalk.red(`Failed to create import plan: ${err.message || 'Unknown error'}`))

  throw err
}
📝 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.

Suggested change
} catch (err) {
if (this.fancy) {
ux.action.stop('❌')
}
if (isAxiosError(err)) {
if (err.response?.status === 404) {
const message = err.response?.data.message
if (message) {
this.log(chalk.red(message))
return
}
}
}
throw err
}
} catch (err) {
if (this.fancy) {
ux.action.stop('❌')
}
if (isAxiosError(err)) {
if (err.response?.status === 404) {
const message = err.response?.data.message
if (message) {
this.log(chalk.red(message))
return
}
}
// Handle other status codes
if (err.response?.status === 401) {
this.log(chalk.red('Authentication error. Please check your API credentials.'))
return
}
if (err.response?.status === 403) {
this.log(chalk.red('You do not have permission to create import plans.'))
return
}
// Log other response errors
if (err.response?.data?.message) {
this.log(chalk.red(`API error: ${err.response.data.message}`))
return
}
}
// Log non-API errors in a user-friendly way
this.log(chalk.red(`Failed to create import plan: ${err.message || 'Unknown error'}`))
throw err
}

Copy link
Contributor

@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: 4

♻️ Duplicate comments (3)
packages/cli/src/commands/import/plan.ts (1)

119-150: Usage of any type for resources in code generation.
As previously advised in older review comments, consider defining a proper interface (e.g., ImportPlanResource) to avoid losing type safety and to reduce the risk of runtime errors.

packages/cli/src/constructs/check-codegen.ts (1)

166-207: Return statements in a void function.
Past reviews mention removing return statements in gencode after each case to align with typical TypeScript patterns. If continuing to use return, ensure style consistency across check-type codegens.

packages/cli/src/constructs/check-group-codegen.ts (1)

28-32: Double-check and concurrency fields are never used in props.
This repeats a previous review comment about these properties. They are defined in the CheckGroupResource interface but never mapped into the constructed object. To avoid confusion and possible incomplete generation, consider adding them to the buildCheckGroupProps function or removing them from the interface if no longer required.

🧹 Nitpick comments (12)
packages/cli/src/constructs/internal/codegen/context.ts (1)

5-6: Enhance error messages for MissingContextVariableMappingError.

Currently, the error class does not provide any contextual detail. Consider accepting an argument (e.g., the missing ID) in the constructor to make debugging easier.

-export class MissingContextVariableMappingError extends Error {}
+export class MissingContextVariableMappingError extends Error {
+  constructor(message?: string) {
+    super(message)
+    this.name = 'MissingContextVariableMappingError'
+  }
+}
packages/cli/src/util/index.ts (1)

1-26: Consider sanitizing or validating the secret name.

Implementation is straightforward and works as intended for environment variable lookups. However, if name contains unexpected characters, it may cause confusion. A simple regex check or normalization step could be beneficial.

packages/cli/src/constructs/key-value-pair-codegen.ts (1)

5-54: Consider sanitizing kv.key for secrets.

If kv.key contains invalid characters, the generated identifier or environment variable might break. Applying a simple transformation (e.g., replacing invalid characters with underscores) can improve robustness.

packages/cli/src/sourcegen/identifier.ts (2)

21-30: PascalCase handling is missing.
Currently, only 'camelCase' and 'SCREAMING_SNAKE_CASE' are supported in this function. If 'PascalCase' is specified, it falls back to the original string. Consider explicitly handling 'PascalCase' for consistency.

Here’s a diff to fill in the missing logic:

} else if (format === 'SCREAMING_SNAKE_CASE') {
  value = screamingSnakeCase(value)
} else if (format === 'PascalCase') {
+ value = pascalCase(value)
}

32-76: Remove the unnecessary continue statement at line 67.
Per the static analysis hint, this continue is redundant and can be removed for cleaner control flow.

Proposed update:

  if (word.length !== 0) {
    words.push(word)
-   word = ''
-   small = false
-   continue
+   word = ''
+   small = false
  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 67-67: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/cli/src/constructs/api-check-codegen.ts (3)

14-25: Interface extends pattern is well-structured.
ApiCheckResource leverages the shared CheckResource and adds step-specific properties. Ensure that consumers handle or test all optional fields (localSetupScript, tearDownScript, etc.) for consistent usage.


27-44: Thorough coverage of assertion sources.
The valueForAssertion function comprehensively handles various sources. If additional sources like COOKIES or BODY_SIZE are anticipated, consider extending the switch statement in future.


48-170: Implementation of ApiCheckCodegen.gencode is comprehensive.

  1. The incremental builder approach is well-organized and easy to follow.
  2. The inline embedding of setup/tearDown scripts using the content field is convenient but note the existing // TODO: Move to a separate file. If large scripts are common, external files might improve maintainability.
  3. Consider validating or logging unsupported ipFamily values for stricter type safety.
packages/cli/src/commands/import/plan.ts (1)

152-246: Remove the redundant 'exit' case.
Static analysis flags line 239 (case 'exit':) as redundant because the default clause covers the same logic. Removing the 'exit' case clarifies the switch flow.

-      case 'exit':
-        // falls through
       default: {
         this.log('Exiting without making any changes.')
         this.exit(0)
       }
🧰 Tools
🪛 Biome (1.9.4)

[error] 239-239: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

packages/cli/src/constructs/check-codegen.ts (1)

37-164: Graceful fallbacks in buildCheckProps.

  1. The tactic of catching errors when looking up private locations or alert channels and then using fallback values is a thoughtful approach. However, confirm that skipping or silently swallowing errors is the desired outcome. In some cases, exposing a warning might help with debugging missing references.
  2. The function is lengthy. Consider small extraction methods for clearer logic and improved readability if it grows further.
packages/cli/src/constructs/check-group-codegen.ts (1)

127-128: Silent catch of alert channel lookup errors.
Similar to the private locations catch block, this empty catch statement might conceal root causes. Consider logging or handling the error.

packages/cli/src/sourcegen/program.ts (1)

73-102: Consider enhanced error handling in realize.
While the current logic tries to write files and directories, an error in one write might not stop subsequent writes. It can be beneficial to aggregate errors or stop on the first failure to prevent partial generation states.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8558b04 and 0ab674f.

📒 Files selected for processing (16)
  • packages/cli/package.json (2 hunks)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/key-value-pair-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/sourcegen/identifier.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
  • packages/cli/src/util/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/package.json
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/sourcegen/index.ts
🧰 Additional context used
🧬 Code Graph Analysis (9)
packages/cli/src/constructs/tcp-check-codegen.ts (6)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-164)
packages/cli/src/constructs/tcp-check.ts (2)
  • TcpRequest (20-46)
  • TcpAssertion (8-8)
packages/cli/src/sourcegen/index.ts (4)
  • GeneratedFile (29-29)
  • Value (33-33)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForGeneralAssertion (45-146)
  • valueForNumericAssertion (4-43)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/constructs/check-codegen.ts (12)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/sourcegen/index.ts (3)
  • Program (29-29)
  • GeneratedFile (29-29)
  • ObjectValueBuilder (27-27)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (5-54)
packages/cli/src/constructs/api-check-codegen.ts (2)
  • ApiCheckCodegen (48-171)
  • ApiCheckResource (14-25)
packages/cli/src/constructs/browser-check-codegen.ts (2)
  • BrowserCheckCodegen (16-49)
  • BrowserCheckResource (6-12)
packages/cli/src/constructs/check-group-codegen.ts (1)
  • CheckGroupCodegen (258-284)
packages/cli/src/constructs/heartbeat-check-codegen.ts (2)
  • HeartbeatCheckCodegen (11-31)
  • HeartbeatCheckResource (6-9)
packages/cli/src/constructs/multi-step-check-codegen.ts (2)
  • MultiStepCheckCodegen (15-44)
  • MultiStepCheckResource (6-11)
packages/cli/src/constructs/tcp-check-codegen.ts (2)
  • TcpCheckCodegen (29-76)
  • TcpCheckResource (7-12)
packages/cli/src/sourcegen/identifier.ts (4)
packages/cli/src/sourcegen/index.ts (4)
  • IdentifierValue (23-23)
  • Value (33-33)
  • Output (28-28)
  • ident (23-23)
packages/cli/src/sourcegen/objectbuilder.ts (2)
  • value (90-103)
  • ident (69-71)
packages/cli/src/sourcegen/arraybuilder.ts (2)
  • value (62-65)
  • ident (46-48)
packages/cli/src/sourcegen/output.ts (1)
  • Output (40-85)
packages/cli/src/constructs/heartbeat-check-codegen.ts (6)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-164)
packages/cli/src/constructs/heartbeat-check.ts (1)
  • Heartbeat (8-25)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/sourcegen/index.ts (2)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/sourcegen/identifier.ts (1)
  • ident (21-30)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (9)
packages/cli/src/constructs/http-header.ts (1)
  • HttpHeader (2-2)
packages/cli/src/constructs/query-param.ts (1)
  • QueryParam (2-2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/sourcegen/index.ts (6)
  • Program (29-29)
  • GeneratedFile (29-29)
  • ObjectValueBuilder (27-27)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (5-54)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)
  • IncidentioAlertChannelCodegen (29-68)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)
  • MSTeamsAlertChannelCodegen (14-46)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)
  • TelegramAlertChannelCodegen (28-73)
packages/cli/src/constructs/check-group-codegen.ts (7)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/api-check.ts (2)
  • ApiCheckDefaultConfig (71-77)
  • headers (29-31)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/sourcegen/index.ts (6)
  • Program (29-29)
  • GeneratedFile (29-29)
  • ObjectValueBuilder (27-27)
  • decl (11-11)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (5-54)
packages/cli/src/constructs/api-check-codegen.ts (8)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckResource (17-35)
packages/cli/src/constructs/api-check.ts (2)
  • Request (79-95)
  • headers (29-31)
packages/cli/src/sourcegen/index.ts (4)
  • GeneratedFile (29-29)
  • Value (33-33)
  • expr (22-22)
  • ident (23-23)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (118-184)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (5-54)
packages/cli/src/constructs/internal/codegen/context.ts (3)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (4-15)
packages/cli/src/sourcegen/index.ts (2)
  • IdentifierValue (23-23)
  • GeneratedFile (29-29)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (118-184)
packages/cli/src/commands/import/plan.ts (3)
packages/cli/src/rest/projects.ts (1)
  • ImportPlan (43-49)
packages/cli/src/sourcegen/program.ts (1)
  • Program (20-103)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
🪛 Biome (1.9.4)
packages/cli/src/sourcegen/identifier.ts

[error] 67-67: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/cli/src/commands/import/plan.ts

[error] 239-239: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (26)
packages/cli/src/constructs/internal/codegen/context.ts (5)

1-4: Imports look good.

No immediate issues identified in these lines.


7-15: VariableLocator implementation is straightforward.

The constructor and property assignments are clean and readable.


17-31: Private fields in Context are well-organized.

No concerns regarding naming or usage.


33-122: Methods for registering and looking up check groups, alert channels, and private locations look consistent.

Maps are updated correctly, and thrown errors are handled in a uniform manner. Aside from the note on more descriptive error messages, the implementation appears sound.


124-170: Methods for handling additional alert channel and status page mappings are consistent.

All core registrations and lookups for group-alert-channel assignments and secrets operate correctly. The structure is solid.

packages/cli/src/constructs/key-value-pair-codegen.ts (1)

1-4: Imports are correctly organized.

No issues identified here.

packages/cli/src/constructs/heartbeat-check-codegen.ts (2)

1-5: Imports are concise and appropriate.
The referenced modules align well with the intended code generation features.


6-9: Interface extension looks consistent.
By extending CheckResource, this interface neatly adds the heartbeat property while enforcing checkType: 'HEARTBEAT'.

packages/cli/src/sourcegen/identifier.ts (3)

4-15: Class structure is clear.
The IdentifierValue class properly extends Value and cleanly appends the identifier string to the Output.


17-19: Interface for formatting options is straightforward.
The optional format field is a good extensibility point for custom naming conventions.


78-102: Case conversion helpers look complete.
The camelCase, pascalCase, and screamingSnakeCase implementations appear logically correct and helpful for label formatting.

packages/cli/src/constructs/tcp-check-codegen.ts (2)

7-12: Resource interface extends common check fields effectively.
Defining checkType: 'TCP' plus optional response time props keeps TCP checks aligned with the shared CheckResource.


14-25: TCP assertion handling is robust.
The switch statement provides explicit coverage for known assertion types (RESPONSE_DATA and RESPONSE_TIME) and cleanly throws an error for unsupported ones.

packages/cli/src/constructs/api-check-codegen.ts (2)

1-6: Imports look good.
Properly organizing imports helps readability, and all dependencies appear relevant to the functionality.


8-12: Interface usage is clear.
SnippetResource neatly encapsulates optional script data with a numeric ID, providing good clarity for snippet-like usage.

packages/cli/src/commands/import/plan.ts (2)

1-16: Imports are well-structured.
All external modules and internal APIs appear correctly referenced, ensuring clarity.


17-31: Flags initialization is concise.
Good usage of OClif’s Flags. The short flag -c for config is a practical choice.

packages/cli/src/constructs/check-codegen.ts (2)

1-16: Import statements and references.
All relevant codegen modules are imported, ensuring modular separation of functionalities.


17-35: CheckResource interface design is consistent.
The properties match other check codegens, ensuring cross-check consistency. Make sure downstream consumers handle optional properties safely.

packages/cli/src/constructs/check-group-codegen.ts (1)

258-284: Overall code generation approach looks good.
The CheckGroupCodegen class thoroughly registers and generates the resource with minimal redundancy. The approach of deferring logic to buildCheckGroupProps keeps concerns separated.

packages/cli/src/constructs/webhook-alert-channel-codegen.ts (4)

28-31: Resource interface correctly restricts the type property.
Defining type: 'WEBHOOK' clarifies usage and ensures compile-time checks.


67-75: Concise handling of optional query parameters.
The code correctly checks for a non-empty array before building the queryParameters property, optimizing for minimal generated output.


104-119: Request coverage for fallback behavior in prepare.
When webhookType is either undefined or not recognized, the code defaults to registering a generic webhook alert channel. Ensure there's a test or manual verification for this fallback path to confirm it behaves as intended.


121-148: The gencode logic is well-structured.
The generation logic delegates to specialized codegens when possible and otherwise uses a standard builder approach. This provides a clean separation of responsibilities for each webhook type.

packages/cli/src/sourcegen/program.ts (2)

52-63: Language-based file extension handling is clear.
The switch statement correctly appends .ts or .js. No issues observed.


138-141: Automatic .ts.js import adjustment might need caution.
If your build pipeline generates different artifacts or relies on .d.ts files, stripping the .ts extension may cause confusion. Revisit if you foresee advanced TypeScript usage or mixed bundling scenarios.

Comment on lines 32 to 932
async run (): Promise<void> {
const { flags } = await this.parse(ImportPlanCommand)
const {
config: configFilename,
root: rootDirectory,
} = flags

const { configDirectory, configFilenames } = splitConfigFilePath(configFilename)
const {
config: checklyConfig,
} = await loadChecklyConfig(configDirectory, configFilenames)

const {
logicalId,
} = checklyConfig

const { data: existingPlans } = await api.projects.findImportPlans(logicalId, {
onlyUncommitted: true,
})

if (existingPlans.length !== 0) {
await this.#handleExistingPlans(existingPlans)
}

if (this.fancy) {
ux.action.start('Creating a new plan', undefined, { stdout: true })
}

let plan: ImportPlan

try {
const { data } = await api.projects.createImportPlan(logicalId)
plan = data

if (this.fancy) {
ux.action.stop('✅ ')
}
} catch (err) {
if (this.fancy) {
ux.action.stop('❌')
}

if (isAxiosError(err)) {
if (err.response?.status === 404) {
const message = err.response?.data.message
if (message) {
this.log(chalk.red(message))
return
}
}
}

throw err
}

const program = new Program({
rootDirectory,
constructFileSuffix: '.check',
language: 'typescript',
})

this.#generateCode(plan, program)

if (this.fancy) {
ux.action.start('Writing files', undefined, { stdout: true })
}

try {
await program.realize()

if (this.fancy) {
ux.action.stop('✅ ')
}
} catch (err) {
if (this.fancy) {
ux.action.stop('❌')
}

throw err
}

this.log(`${logSymbols.success} Successfully generated the following files for your import plan:`)
for (const filePath of program.paths) {
this.log(` - ${chalk.green(filePath)}`)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Error handling for non-404 responses.
When creating a new plan, only 404 is specifically handled. Consider logging more granular error messages for other HTTP statuses (401, 403, 500, etc.) to improve debugging and user feedback.

Copy link
Contributor

@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: 2

🧹 Nitpick comments (2)
packages/cli/src/sourcegen/index.ts (1)

1-34: The index.ts file provides a clean, organized export interface for the sourcegen module.

This well-structured index file exports all necessary components for code generation, including value types, builders, expressions, and declarations. The organization facilitates access to these utilities for the new import command functionality.

However, I have a few suggestions for improvement:

Consider grouping related exports together rather than listing them individually. This would improve readability and make the relationships between related components more apparent:

- export { ArgumentsValue } from './args'
- export { args, ArgumentsValueBuilder } from './argsbuilder'
- export { ArrayValue } from './array'
- export { array, ArrayValueBuilder } from './arraybuilder'
+ // Values
+ export { ArgumentsValue } from './args'
+ export { ArrayValue } from './array'
+ export { BooleanValue } from './boolean'
+ export { NullValue } from './null'
+ export { NumberValue } from './number'
+ export { ObjectValue } from './object'
+ export { StringValue } from './string'
+ export { UndefinedValue } from './undefined'
+ export { Value } from './value'
+
+ // Builders
+ export { args, ArgumentsValueBuilder } from './argsbuilder'
+ export { array, ArrayValueBuilder } from './arraybuilder'
+ export { object, ObjectValueBuilder } from './objectbuilder'

Add a brief module documentation comment at the top of the file explaining the purpose of these utilities in relation to the import functionality:

+/**
+ * Sourcegen module provides utilities for generating TypeScript code
+ * for the CLI import feature. This includes value representations,
+ * expression builders, and declaration utilities.
+ */
export { ArgumentsValue } from './args'
packages/cli/src/sourcegen/case.ts (1)

21-35: Consider reducing duplication between pascalCase and trainCase.

Both pascalCase and trainCase share the same word transformation logic but differ only in the join character. Consider refactoring to reduce duplication.

+function capitalizeWords(words: string[]): string[] {
+  return words.map(word => {
+    const initial = word.slice(0, 1).toUpperCase()
+    const rest = word.slice(1).toLowerCase()
+    return initial + rest
+  })
+}

export function pascalCase(value: string): string {
-  return wordify(value).map(word => {
-    const initial = word.slice(0, 1).toUpperCase()
-    const rest = word.slice(1).toLowerCase()
-    return initial + rest
-  }).join('')
+  return capitalizeWords(wordify(value)).join('')
}

export function trainCase(value: string): string {
-  return wordify(value).map(word => {
-    const initial = word.slice(0, 1).toUpperCase()
-    const rest = word.slice(1).toLowerCase()
-    return initial + rest
-  }).join('-')
+  return capitalizeWords(wordify(value)).join('-')
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ab674f and 03fe10d.

📒 Files selected for processing (3)
  • packages/cli/src/sourcegen/case.ts (1 hunks)
  • packages/cli/src/sourcegen/identifier.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/cli/src/sourcegen/identifier.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/cli/src/sourcegen/case.ts (1)
packages/cli/src/sourcegen/index.ts (2)
  • CaseFormat (6-6)
  • cased (6-6)
🪛 Biome (1.9.4)
packages/cli/src/sourcegen/case.ts

[error] 109-109: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (4)
packages/cli/src/sourcegen/case.ts (4)

1-8: Good type definition for case formats.

The CaseFormat type clearly defines all the supported case formats in a readable manner.


10-19: LGTM: camelCase implementation is correct.

The camelCase function correctly handles the first word being lowercase and subsequent words having their first letter capitalized.


37-51: LGTM: Snake and kebab case implementations look good.

The implementations for snake_case, SCREAMING_SNAKE_CASE, kebab-case, and SCREAMING-KEBAB-CASE are all correct and concise.


53-72: LGTM: The cased function is well-structured.

The cased function effectively routes to the appropriate case conversion function based on the format parameter. Good job including a default case.

Copy link
Contributor

@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: 4

♻️ Duplicate comments (5)
packages/cli/src/commands/import/plan.ts (2)

132-138: Use a specific resource type instead of any.

This feedback repeats a previous suggestion to remove the any cast in code generation. Defining a properly typed interface for import-plan resources would prevent type-related issues downstream.


153-247: Add unit tests to validate the existing import plans flow.

The logic in #handleExistingPlans has multiple user choices and error scenarios that aren’t clearly tested. This recommendation was previously raised; comprehensive tests will ensure each path is covered (e.g., showing plan details, canceling plans, creating a new plan).

🧰 Tools
🪛 Biome (1.9.4)

[error] 240-240: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)

51-51: Redundant .toString() call on a string
Since config.url in WebhookAlertChannelResourceConfig is already declared as a string, .toString() is unnecessary. This duplicates a prior review comment.

- builder.string('url', config.url.toString())
+ builder.string('url', config.url)
packages/cli/src/constructs/check-group-codegen.ts (2)

28-33: Properties doubleCheck and concurrency remain unused.
These fields are defined in CheckGroupResource but never set on the constructed object in buildCheckGroupProps. This is consistent with a past suggestion.

Consider adding them:

 if (resource.doubleCheck !== undefined) {
   builder.boolean('doubleCheck', resource.doubleCheck)
 }

 if (resource.concurrency !== undefined) {
   builder.number('concurrency', resource.concurrency)
 }

77-82: Swallowed error in private locations lookup.
Catching an error without logging or rethrowing might mask underlying issues, as previously noted.

} catch (err) {
-  
+  console.error('Failed to look up private locations:', err)
}
🧹 Nitpick comments (17)
packages/cli/src/constructs/api-check-codegen.ts (1)

67-73: Unify boolean defaults for better clarity.

Currently, the code conditionally sets followRedirects and skipSSL only when false or true is explicitly provided. Consider applying defaults (e.g., true for followRedirects) to ensure clarity about the intended behavior if these properties are not set.

packages/cli/src/commands/import/plan.ts (1)

239-240: Remove the redundant case 'exit' clause.

The case 'exit' label falls through to default directly, making it redundant. Simplify the switch statement by removing the unused case:

-        case 'exit':
-          // falls through
         default: {
           this.log('Exiting without making any changes.')
           this.exit(0)
         }
🧰 Tools
🪛 Biome (1.9.4)

[error] 240-240: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)

13-25: Handle variations in 'Authorization' header.
Currently, you only extract the Bearer token when the header starts exactly with "Bearer ". You might consider case-insensitive or more flexible checks for Bearer if hosting environments provide varied headers.

 if (header.key.toLocaleLowerCase() !== 'authorization') {
   continue
 }
-
-if (!header.value.startsWith('Bearer ')) {
+if (!/^Bearer\s+/i.test(header.value)) {
   continue
 }
packages/cli/src/constructs/alert-channel-codegen.ts (2)

21-29: Consider default values for optional booleans.
The AlertChannelResource interface seems fine, but you may consider defaulting booleans like sendRecovery, sendFailure, etc., to false during resource creation to avoid undefined scenarios.


31-51: buildAlertChannelProps is well structured.
The conditional checks for each property are straightforward. For large-scale usage, consider grouping these booleans or using a dynamic approach to reduce repeated conditions.

packages/cli/src/sourcegen/case.ts (2)

21-35: pascalCase and trainCase have similar patterns.
These specialized transformations are straightforward, but note the repeated logic for initial + rest. Consider a helper to DRY up these transformations if more variants appear.


74-120: wordify function could remove the unnecessary continue at line 111.
According to the static analysis hint, the continue at line 111 is redundant. Removing it simplifies control flow without changing behavior.

107     if (word.length !== 0) {
108       words.push(word)
109       word = ''
110       small = false
-111       continue
112     }
🧰 Tools
🪛 Biome (1.9.4)

[error] 111-111: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/cli/src/sourcegen/program.ts (1)

103-132: realize method handles async file creation well.
Error handling is minimal, but likely sufficient for a CLI context. Consider logging any I/O errors if needed for troubleshooting.

packages/cli/src/constructs/internal/codegen/context.ts (9)

5-5: Consider providing a descriptive error message.
The MissingContextVariableMappingError class lacks a constructor that sets a meaningful message. A more descriptive message can ease debugging when mappings are missing.

-export class MissingContextVariableMappingError extends Error {}
+export class MissingContextVariableMappingError extends Error {
+  constructor (message?: string) {
+    super(message ?? 'Context variable mapping not found.')
+    this.name = 'MissingContextVariableMappingError'
+  }
+}

7-15: Add class-level documentation.
A brief docstring for VariableLocator would clarify its role in linking an identifier to a generated file.


55-69: Avoid repeated registrations for the same alert channel.
Similar to check groups, calling registerAlertChannel multiple times for the same physicalId generates new variables rather than reusing an existing one. Consider checking the map before creating a new locator.


87-100: Consider restricting duplicates in assignments.
Current logic allows multiple identical privateLocationPhysicalId entries for the same group. If duplicates are unintended, consider switching to a Set to avoid repetition.

- const all = this.#checkGroupPrivateLocationPhysicalIdsByPhysicalId.get(groupPhysicalId) ?? []
- all.push(privateLocationPhysicalId)
- this.#checkGroupPrivateLocationPhysicalIdsByPhysicalId.set(groupPhysicalId, all)
+ const all = this.#checkGroupPrivateLocationPhysicalIdsByPhysicalId.get(groupPhysicalId) ?? new Set()
+ all.add(privateLocationPhysicalId)
+ this.#checkGroupPrivateLocationPhysicalIdsByPhysicalId.set(groupPhysicalId, [...all])

102-115: Duplicate handling in check assignments.
registerPrivateLocationCheckAssignment also appends new entries without checking for duplicates. If uniqueness is desired, consider using a Set.


117-130: Confirm desired behavior for multiple alert channel subscriptions.
Registering the same alertChannelPhysicalId with the same checkPhysicalId can produce duplicates in the array. If that’s undesired, a Set would help.


132-145: Same approach for alert channel group subscriptions.
Repeated registerAlertChannelGroupSubscription calls with the same IDs may add duplicates. Ensure whether duplicates are wanted; otherwise, consider using a Set.


147-161: Provide an error message for missing status page services.
In lookupStatusPageService, we throw a MissingContextVariableMappingError without a detailed message. Consider adding contextual info like the physicalId to streamline debugging.

- throw new MissingContextVariableMappingError()
+ throw new MissingContextVariableMappingError(`No StatusPageService found for physical ID: ${physicalId}`)

163-171: Expand on secret registration.
registerKnownSecret tracks secrets in a Set, returning false if already known. If needed, consider storing more metadata about each secret (like usage or date added) for better debugging.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03fe10d and f621fdf.

📒 Files selected for processing (32)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/email-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/frequency-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/key-value-pair-codegen.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/ref-codegen.ts (1 hunks)
  • packages/cli/src/constructs/retry-strategy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-service-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/sourcegen/case.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (16)
  • packages/cli/src/constructs/ref-codegen.ts
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts
  • packages/cli/src/constructs/frequency-codegen.ts
  • packages/cli/src/constructs/maintenance-window-codegen.ts
  • packages/cli/src/constructs/tcp-check-codegen.ts
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/constructs/status-page-codegen.ts
  • packages/cli/src/constructs/heartbeat-check-codegen.ts
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts
  • packages/cli/src/constructs/key-value-pair-codegen.ts
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts
  • packages/cli/src/constructs/retry-strategy-codegen.ts
  • packages/cli/src/constructs/email-alert-channel-codegen.ts
  • packages/cli/src/sourcegen/index.ts
🧰 Additional context used
🧬 Code Graph Analysis (12)
packages/cli/src/constructs/api-check-codegen.ts (7)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckResource (17-35)
packages/cli/src/constructs/api-check.ts (2)
  • Request (79-95)
  • headers (29-31)
packages/cli/src/sourcegen/index.ts (5)
  • GeneratedFile (40-40)
  • Value (44-44)
  • kebabCase (14-14)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (5-52)
packages/cli/src/constructs/status-page-service-codegen.ts (4)
packages/cli/src/constructs/internal/codegen/index.ts (1)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/sourcegen/index.ts (4)
  • kebabCase (14-14)
  • decl (22-22)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/sourcegen/case.ts (1)
  • kebabCase (45-47)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (4)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/sourcegen/index.ts (3)
  • decl (22-22)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (4)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/sourcegen/index.ts (3)
  • decl (22-22)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/alert-channel-codegen.ts (9)
packages/cli/src/sourcegen/index.ts (6)
  • ObjectValueBuilder (38-38)
  • GeneratedFile (40-40)
  • Value (44-44)
  • expr (33-33)
  • ident (34-34)
  • Program (40-40)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1)
  • PhoneCallAlertChannelCodegen (15-50)
packages/cli/src/constructs/email-alert-channel-codegen.ts (1)
  • EmailAlertChannelCodegen (14-43)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1)
  • OpsgenieAlertChannelCodegen (17-51)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1)
  • PagerdutyAlertChannelCodegen (16-55)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (1)
  • SlackAlertChannelCodegen (15-50)
packages/cli/src/constructs/sms-alert-channel-codegen.ts (1)
  • SmsAlertChannelCodegen (15-50)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1)
  • WebhookAlertChannelCodegen (85-149)
packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (4)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/sourcegen/index.ts (3)
  • decl (22-22)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (4)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/sourcegen/index.ts (3)
  • decl (22-22)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/private-location-codegen.ts (4)
packages/cli/src/sourcegen/index.ts (6)
  • GeneratedFile (40-40)
  • Value (44-44)
  • expr (33-33)
  • ident (34-34)
  • kebabCase (14-14)
  • decl (22-22)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (168-255)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (1)
  • Context (17-171)
packages/cli/src/constructs/webhook-alert-channel-codegen.ts (9)
packages/cli/src/constructs/http-header.ts (1)
  • HttpHeader (2-2)
packages/cli/src/constructs/query-param.ts (1)
  • QueryParam (2-2)
packages/cli/src/constructs/alert-channel-codegen.ts (2)
  • AlertChannelResource (21-29)
  • buildAlertChannelProps (31-51)
packages/cli/src/sourcegen/index.ts (6)
  • Program (40-40)
  • GeneratedFile (40-40)
  • ObjectValueBuilder (38-38)
  • decl (22-22)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (5-52)
packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1)
  • IncidentioAlertChannelCodegen (29-68)
packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1)
  • MSTeamsAlertChannelCodegen (14-46)
packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1)
  • TelegramAlertChannelCodegen (28-73)
packages/cli/src/constructs/check-group-codegen.ts (7)
packages/cli/src/constructs/frequency-codegen.ts (2)
  • FrequencyResource (4-4)
  • valueForFrequency (6-54)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (2)
  • AlertEscalationResource (4-4)
  • valueForAlertEscalation (6-65)
packages/cli/src/constructs/api-check.ts (2)
  • ApiCheckDefaultConfig (71-77)
  • headers (29-31)
packages/cli/src/constructs/retry-strategy-codegen.ts (2)
  • RetryStrategyResource (4-4)
  • valueForRetryStrategy (6-77)
packages/cli/src/sourcegen/index.ts (7)
  • Program (40-40)
  • GeneratedFile (40-40)
  • ObjectValueBuilder (38-38)
  • kebabCase (14-14)
  • decl (22-22)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (5-52)
packages/cli/src/sourcegen/case.ts (1)
packages/cli/src/sourcegen/index.ts (9)
  • CaseFormat (8-8)
  • camelCase (9-9)
  • pascalCase (10-10)
  • trainCase (11-11)
  • snakeCase (12-12)
  • screamingSnakeCase (13-13)
  • kebabCase (14-14)
  • screamingKebabCase (15-15)
  • cased (7-7)
packages/cli/src/constructs/internal/codegen/context.ts (4)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • MissingContextVariableMappingError (2-2)
  • Context (2-2)
packages/cli/src/sourcegen/index.ts (2)
  • IdentifierValue (34-34)
  • GeneratedFile (40-40)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (5-16)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (168-255)
🪛 Biome (1.9.4)
packages/cli/src/sourcegen/case.ts

[error] 111-111: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/cli/src/commands/import/plan.ts

[error] 240-240: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (44)
packages/cli/src/constructs/slack-alert-channel-codegen.ts (2)

24-49: Implementation appears consistent with the base codegen class.

The usage of buildAlertChannelProps and the structured approach to Slack configuration align well with existing alert channel resources. The code logic to conditionally include channel is straightforward and maintainable.


5-11:

❓ Verification inconclusive

Consider adding coverage for the optional channel property.

The interface correctly extends AlertChannelResource and supports Slack-specific fields, but you may want to add tests verifying correct handling when channel is absent or specified.

To confirm test coverage, run the following script to look for references to "SlackAlertChannel" within your test files:


🏁 Script executed:

#!/bin/bash
rg "SlackAlertChannel" -A 5 tests

Length of output: 79


Attention: Manual Verification Needed for Slack Alert Channel Test Coverage

  • The command executed did not find a tests directory, so we could not confirm if tests cover the optional channel property.
  • Please verify if tests for SlackAlertChannelResource exist in an alternative location (e.g., within the packages/cli directory or as part of an integrated test suite).
  • If such tests are absent, consider adding tests to cover both cases—when the optional channel property is provided and when it is omitted.
packages/cli/src/constructs/api-check-codegen.ts (1)

115-124: Assertions block is well-structured.

The logic for building an array of assertions is robust, and the usage of valueForAssertion ensures each assertion type is handled appropriately. No issues found here.

packages/cli/src/constructs/sms-alert-channel-codegen.ts (3)

1-11: Implementation looks good for SMS alert channel resource interface

The interface correctly extends AlertChannelResource and properly defines the SMS-specific config properties with appropriate types. The optional name property is correctly marked with the optional modifier.


15-22: Implementation of prepare method looks correct

The prepare method correctly registers the alert channel in the context with appropriate ID, variable prefix, and file path. The method follows the pattern used in other alert channel codegen implementations.


24-49: Implementation of gencode method is well-structured

The gencode method correctly:

  1. Looks up the alert channel in the context
  2. Imports the necessary construct
  3. Conditionally adds the name property only if it exists
  4. Adds the required phoneNumber property
  5. Includes common alert channel properties via buildAlertChannelProps
  6. Exports the variable

This implementation follows good practices for code generation.

packages/cli/src/constructs/msteams-alert-channel-codegen.ts (3)

1-10: MS Teams alert channel interface looks good

The interface correctly extends WebhookAlertChannelResource and appropriately defines the MS Teams-specific webhook type.


15-21: Implementation of prepare method looks correct

The prepare method correctly registers the alert channel in the context with appropriate ID, variable prefix, and file path for MS Teams alerts.


23-45:

❌ Incorrect review comment

Consider adding null check for name property

The gencode method looks well-structured, but unlike the SMS implementation, it doesn't verify if the name exists before adding it. The name property seems to be assumed as mandatory in the MS Teams implementation. If this is intentional, it's fine - but if name could be optional, consider adding a conditional check similar to how it's done in the SMS implementation.

 builder.object(builder => {
-  builder.string('name', config.name)
+  if (config.name) {
+    builder.string('name', config.name)
+  }
   builder.string('url', config.url)

Run the following script to check if there are any MS Teams alert channels without a name property in existing usage:


🏁 Script executed:

#!/bin/bash
# Check for MS Teams alert channels in the codebase and how they're used
rg -A 5 "MSTeamsAlertChannel" --type typescript

Length of output: 82


🏁 Script executed:

#!/bin/bash
# Re-run the search for MSTeamsAlertChannel usage in TypeScript files,
# using the correct file type alias instead of "typescript".
rg -A 5 "MSTeamsAlertChannel" --type ts

Length of output: 6756


No changes required for MSTeams alert channel null-check

After verifying the codebase, it’s clear that the MSTeams alert channel interface defines the name property as a mandatory string, and all usages (e.g., in the e2e tests) consistently supply a valid name. Therefore, unlike the SMS implementation, adding a null check for name is unnecessary.

Likely an incorrect or invalid review comment.

packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (3)

1-13: Opsgenie alert channel resource interface is well-defined

The interface correctly extends AlertChannelResource and defines all the necessary properties for Opsgenie configuration (name, apiKey, region, and priority).


17-24: Implementation of prepare method looks correct

The prepare method correctly registers the alert channel in the context with appropriate ID, variable prefix, and file path for Opsgenie alerts.


26-50:

✅ Verification successful

Implementation of gencode method is well-structured

The gencode method correctly implements the code generation logic for Opsgenie alert channels, including all required properties and common alert channel properties.

One observation: unlike the SMS implementation where name is optional, here all properties (name, apiKey, region, priority) are treated as mandatory without conditional checks. This is likely intentional based on the Opsgenie API requirements, but worth verifying.

Run the following script to check the Opsgenie construct definition to verify if all these properties are indeed required:


🏁 Script executed:

#!/bin/bash
# Look for the OpsgenieAlertChannel definition to confirm required properties
rg -A 15 "class OpsgenieAlertChannel" --type typescript

Length of output: 92


Below is a revised follow-up review comment that requests a re-run of the verification script with corrected parameters:


Opsgenie Alert Channel Required Properties Verification

The implementation of the gencode method remains well-structured. However, to address the observation regarding the mandatory fields (name, apiKey, region, and priority), we need to confirm whether these are indeed required by the Opsgenie API—as opposed to the SMS implementation where name is optional.

The initial script failed due to an unrecognized file type with the --type typescript flag. Please re-run the verification with adjusted file matching:

Once you confirm from the output that the Opsgenie API requires all these properties without optional checks, the current implementation can remain as is. If not, then further adjustments should be considered.


🏁 Script executed:

#!/bin/bash
# Search for the OpsgenieAlertChannel class definition in TypeScript files
rg -A 15 "class OpsgenieAlertChannel" -g "*.ts"

Length of output: 3222


Opsgenie API Properties Confirmation
After verifying the OpsgenieAlertChannel class definition, it's clear that the properties (name, apiKey, region, and priority) are explicitly declared as required. This aligns with the Opsgenie API expectations and justifies the absence of conditional checks in the gencode implementation. The contrast with the SMS implementation—where name is optional—is intentional based on these API requirements. No changes are necessary.

packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (3)

1-12: PagerDuty alert channel resource interface is correctly defined

The interface properly extends AlertChannelResource and defines appropriate config properties with correct optionality for account and serviceName, while serviceKey is required.


16-23: Implementation of prepare method looks correct

The prepare method correctly registers the alert channel in the context with appropriate ID, variable prefix, and file path for PagerDuty alerts.


25-54: Implementation of gencode method handles optional properties correctly

The gencode method correctly:

  1. Looks up the alert channel in the context
  2. Imports the necessary construct
  3. Conditionally adds optional properties (account, serviceName) only if they exist
  4. Always adds the required serviceKey property
  5. Includes common alert channel properties via buildAlertChannelProps
  6. Exports the variable

The implementation appropriately handles both required and optional properties, following the same pattern seen in other alert channel implementations.

packages/cli/src/constructs/status-page-service-codegen.ts (1)

19-36: LGTM for core logic.
The gencode method follows a consistent pattern with other constructs, creating a new StatusPageService instance with minimal but clear properties.

packages/cli/src/constructs/private-location-codegen.ts (1)

33-59: All good with code structure.
The gencode method closely mirrors other codegen constructs, ensuring consistency across the codebase for PrivateLocation. Good job.

packages/cli/src/constructs/check-group-codegen.ts (1)

258-283: Overall structure looks good.
Creating the CheckGroup construct with buildCheckGroupProps is consistent with the approach used in other codegen files. The separation of prepare and gencode remains clean and modular.

packages/cli/src/constructs/alert-channel-codegen.ts (6)

1-3: Ensure consistent import ordering or grouping only if required by lint rules.
No issues found here; just noting potential for grouping imports by external vs. internal if mandated by style guidelines.


12-19: Typedef for AlertChannelType looks good.
Enumerating all possible channel types ensures clarity. No issues here.


53-64: valueForAlertChannelFromId is concise and effective.
It properly constructs the expression for retrieving an alert channel by ID. Implementation is strong.


66-95: AlertChannelCodegen constructor cleanly initializes codegens.
This structured approach of mapping each channel type is well done. No immediate issues.


97-105: prepare method’s dynamic dispatch is correct.
Throws an error when an unsupported type is encountered, which is consistent with robust error handling.


106-114: gencode method’s dynamic dispatch is correct.
Similar to prepare, it cleanly delegates code generation to the correct codegen. No concerns.

packages/cli/src/sourcegen/case.ts (4)

1-8: CaseFormat type covers key naming patterns.
This enumerated set is broad enough for common naming conventions. Keep the typed-based approach for clarity.


10-19: camelCase logic is valid.
Converts first word to lowercase, subsequent words to title case. Looks correct.


37-51: snakeCase, screamingSnakeCase, kebabCase, screamingKebabCase
All appear correct. Thoroughly covers the textual transformations with typical naming conventions.


53-72: cased function: central switch-based approach is clear.
No immediate issues. If you plan to expand more case types in the future, be sure to keep them in sync with this switch block.

packages/cli/src/constructs/webhook-alert-channel-codegen.ts (7)

1-5: Imports are well-structured.
No concerns; references appear necessary and appropriately grouped.


12-16: WebhookType enumeration is sufficiently granular.
If more webhook providers are expected, you can easily extend this type. No issues.


17-26: WebhookAlertChannelResourceConfig interface is well-defined.
Optional fields are clearly marked, which aligns with typical usage patterns.


33-81: buildWebhookAlertChannelConfig handles property assignments nicely.
Logic is straightforward. Consider verifying if method is valid (e.g., GET/POST/etc.) to handle potential misconfigurations.

Would you like to add a small runtime check or an enum for allowed methods?


85-102: WebhookAlertChannelCodegen constructor’s multi-codegen approach
The mapping approach for each webhookType is consistent with the design from AlertChannelCodegen. No issues.


104-119: prepare method gracefully delegates to sub-codegens if available.
Approach ensures specialized logic for each webhook subtype. No immediate concerns.


121-149: gencode method respects sub-codegens and fallback.
Properly builds a new section if a specialized codegen is unavailable. Implementation looks correct.

packages/cli/src/sourcegen/program.ts (9)

1-3: Using node:fs/promises and path is appropriate.
Asynchronous file operations are recommended for performance in CLI tools.


4-9: Output, Value, Declaration imports
These suggest a clear separation of concerns for code generation. No issues found.


17-38: Program constructor logic is robust.
It covers valid languages, defaults the file extension accordingly. This is well-designed.


40-54: paths getter helps track generated vs. static auxiliary files.
Sorting the array is a neat feature. Implementation is straightforward.


56-79: generatedConstructFile and generatedSupportFile methods
These effectively cache or create new GeneratedFile instances. The approach is sound.


135-161: ProgramFile base class and posixPath utility
Useful for consistent path handling across different environments (Windows vs. Unix). Implementation looks good.


163-166: ImportOptions interface
A flexible approach for relative imports. No concerns here.


168-255: GeneratedFile manages sections and imports efficiently.
The logic for .ts to .js path rewriting is interesting. Ensure it aligns with your build pipeline expectations (especially if supporting TS in source but distributing JS).

Can you confirm that the .ts.js rewriting is always desired for your runtime or bundling toolchain?


257-265: StaticAuxiliaryFile
Straightforward container for static content. Implementation is approved.

Comment on lines 26 to 39
prepare (logicalId: string, resource: PrivateLocationResource, context: Context): void {
context.registerPrivateLocation(
resource.id,
this.program.generatedConstructFile(`resources/private-locations/${kebabCase(resource.slugName)}`),
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Validate resource slug usage.
If resource.slugName can be empty, kebabCase might return an empty string, potentially generating an invalid file path.

Add a safe check or fallback to ensure a valid slug:

 if (!resource.slugName) {
   throw new Error('slugName is required for PrivateLocationResource')
 }
📝 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.

Suggested change
prepare (logicalId: string, resource: PrivateLocationResource, context: Context): void {
context.registerPrivateLocation(
resource.id,
this.program.generatedConstructFile(`resources/private-locations/${kebabCase(resource.slugName)}`),
)
}
prepare (logicalId: string, resource: PrivateLocationResource, context: Context): void {
+ if (!resource.slugName) {
+ throw new Error('slugName is required for PrivateLocationResource')
+ }
context.registerPrivateLocation(
resource.id,
this.program.generatedConstructFile(`resources/private-locations/${kebabCase(resource.slugName)}`),
)
}

Comment on lines 17 to 153
export class Context {
#alertChannelVariablesByPhysicalId = new Map<number, VariableLocator>()

#checkAlertChannelPhysicalIdsByPhysicalId = new Map<string, number[]>()
#checkPrivateLocationPhysicalIdsByPhysicalId = new Map<string, string[]>()

#checkGroupAlertChannelPhysicalIdsByPhysicalId = new Map<number, number[]>()
#checkGroupPrivateLocationPhysicalIdsByPhysicalId = new Map<number, string[]>()
#checkGroupVariablesByPhysicalId = new Map<number, VariableLocator>()

#privateLocationVariablesByPhysicalId = new Map<string, VariableLocator>()

#statusPageServiceVariablesByPhysicalId = new Map<string, VariableLocator>()

#knownSecrets = new Set<string>()

importVariable (locator: VariableLocator, file: GeneratedFile): void {
file.namedImport(locator.id.value, locator.file.path, {
relativeTo: dirname(file.path),
})
}

Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Ensure unique named imports.
If multiple variables share the same identifier value, this method may cause name collisions in the generated file. Consider either verifying uniqueness or generating a fallback name.

To confirm no collisions occur, you could scan all variable names in your code generation flow:


🏁 Script executed:

#!/bin/bash
# Checking potential collisions of imported identifiers
rg 'new IdentifierValue\('

Length of output: 847


Ensure unique named imports in code generation

The importVariable method in packages/cli/src/constructs/internal/codegen/context.ts uses locator.id.value directly for named imports without any collision check. A repository scan shows multiple invocations of new IdentifierValue(...) (for instance, generating identifiers like group${nth}, ${variablePrefix}${nth}, privateLocation${nth}, and service${nth}) across different files. This raises the risk that if two parts of the code generation flow produce the same identifier value, name collisions may occur in the generated file.

  • Action Items:
    • Verify that the naming strategy (using template literals and counters) guarantees uniqueness across the entire codebase.
    • Consider implementing a validation check within the code generation flow to catch duplicate identifiers or generate a fallback name when a collision is detected.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (4)
packages/cli/src/sourcegen/program.ts (4)

56-79: Refactor duplicated logic for generated files.
Both generatedConstructFile and generatedSupportFile repeat a similar “check if cached, else create” pattern. Consider extracting this into a helper function to reduce code duplication.

- generatedConstructFile (path: string): GeneratedFile {
-   ...
-   if (file === undefined) {
-     file = new GeneratedFile(path)
-     this.#generatedFiles.set(path, file)
-   }
-   ...
- }
-
- generatedSupportFile (path: string): GeneratedFile {
-   ...
-   if (file === undefined) {
-     file = new GeneratedFile(path)
-     this.#generatedFiles.set(path, file)
-   }
-   ...
- }

+ private getOrCreateGeneratedFile(path: string): GeneratedFile {
+   let file = this.#generatedFiles.get(path)
+   if (!file) {
+     file = new GeneratedFile(path)
+     this.#generatedFiles.set(path, file)
+   }
+   return file
+ }

+ generatedConstructFile (path: string): GeneratedFile {
+   const finalPath = path + this.#options.constructFileSuffix + this.#ext
+   return this.getOrCreateGeneratedFile(finalPath)
+ }

+ generatedSupportFile (path: string): GeneratedFile {
+   const finalPath = path + this.#ext
+   return this.getOrCreateGeneratedFile(finalPath)
+ }

81-101: Consolidate the static file creation methods.
The methods staticSpecFile, staticStyleFile, and staticSupportFile also share similar patterns of concatenating file extensions and constructing StaticAuxiliaryFile. You could unify these to reduce repetition and centralize logic.


103-132: Add error handling for file writes.
The realize() method writes files without try/catch. While the Node.js promises will reject on failure, consider logging or handling errors more gracefully to inform users if writing files fails.

async realize (): Promise<void> {
  for (const file of this.#generatedFiles.values()) {
    const fullFilePath = path.join(this.#options.rootDirectory, file.path)
    try {
      ...
      await writeFile(fullFilePath, output.finalize())
    } catch (err) {
+     console.error(`Error writing generated file at ${fullFilePath}:`, err)
+     throw err
    }
  }
  ...
}

159-161: Consider using path.posix for cross-platform consistency.
The helper function posixPath() re-implements path normalization. Switching to path.posix methods could further eliminate edge cases.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b85745e and f745a50.

📒 Files selected for processing (1)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (6)
packages/cli/src/sourcegen/program.ts (6)

1-16: Initial imports look good.
No issues found regarding syntax or references. The dependencies from node:fs/promises and node:path are suitably imported, and the auxiliary imports (Output, Value, Declaration) are semantically relevant.


17-38: Consider support for additional file extensions.
Currently, ProgramOptions.language only handles 'typescript' | 'javascript'. If you plan to support other JS/TS variants (e.g., .mjs, .cjs, .jsx, .tsx), consider extending this switch or clarifying constraints in documentation.


40-54: Paths getter implementation.
Collecting all file paths from both generated and static files is straightforward and well-organized, and the sorting ensures a predictable ordering. No changes required here.


135-157: Solid abstraction in ProgramFile.
This base class neatly provides path utilities (directory name, base name, relative path). The approach is clean, and the use of posixPath for path normalization is helpful.


168-255: Verify behavior for other file extensions.
In #processImportFrom, the logic strips .ts or .js extensions. If .mjs, .cjs, .jsx, or .tsx appear, they may cause unexpected behavior. Confirm whether this is intentional or broaden this approach if these file types could appear in your use case.


257-265: Static file class is straightforward.
This class correctly stores the content for the specified path without extra overhead. Implementation is succinct and self-contained.

Copy link
Contributor

@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: 0

♻️ Duplicate comments (7)
packages/cli/src/constructs/status-page-codegen.ts (2)

12-22: Validate optional properties with fallback defaults.

While customDomain, logo, redirectTo, etc., are marked optional, consider adding basic validation or fallback handling. For example, you might ensure that any absent optional properties have safe defaults to avoid runtime errors.


40-57: 🛠️ Refactor suggestion

Enhance error handling for missing services with more actionable guidance.

The current error message correctly indicates when a status page refers to a service that isn't being imported, but it doesn't provide guidance on how to resolve the issue.

- throw new Error(`Status page '${resource.id}' refers to service '${service.id}' which is not being imported.`)
+ throw new Error(`Status page '${resource.id}' refers to service '${service.id}' which is not being imported. Please ensure the service is included in your import plan or remove it from the status page.`)
packages/cli/src/constructs/internal/codegen/context.ts (2)

60-64: Ensure unique named imports to avoid collisions [duplicate comment].
Similar to prior feedback on potential identifier collisions, multiple variables with the same identifier value can lead to name collisions in the generated file. Consider a safeguard strategy (e.g., verifying uniqueness) in importVariable.


66-72: Handle duplicate registrations [duplicate comment].
As noted in previous reviews, repeated calls to register the same resource (physicalId) create a new variable name on every invocation. This can cause generation inconsistencies. Consider reusing existing mappings for the same physicalId to keep references in sync.

Also applies to: 82-88, 98-104, 114-119, 129-134, 144-149, 159-164, 174-180

packages/cli/src/constructs/tcp-check-codegen.ts (1)

29-78: Re-iterate port validation concerns.

Per prior feedback, there’s still no validation on lines 41–42 to ensure the port field is within the valid TCP range (1–65535), nor checks to confirm a valid or non-empty hostname. Please consider adding these validations to prevent potential misconfigurations.

packages/cli/src/constructs/check-group-codegen.ts (2)

28-32: doubleCheck and concurrency fields remain unused.
They’re declared in CheckGroupResource but never set in buildCheckGroupProps, mirroring a past review comment.

+  if (resource.doubleCheck !== undefined) {
+    builder.boolean('doubleCheck', resource.doubleCheck)
+  }

+  if (resource.concurrency !== undefined) {
+    builder.number('concurrency', resource.concurrency)
+  }

80-81: Silently swallowing errors in the catch block.
This catch block discards important error information, making debugging difficult, which has already been flagged in a prior review.

-  } catch (err) {
-  }
+  } catch (err) {
+    console.error('Failed to look up CheckGroup private locations:', err)
+  }
🧹 Nitpick comments (10)
packages/cli/src/sourcegen/program.ts (4)

23-38: Add docstrings or inline comments for constructor clarity.

While the constructor logic is straightforward, consider adding a brief JSDoc to document the purpose of each program option. This will improve readability for future maintainers.


118-147: Consider parallelizing file writes or adding error handling.

The loop in realize() writes each file sequentially, and errors are not fully managed (e.g., retry on failure). Consider using a parallelization approach like Promise.all() or adding a fallback error handling mechanism to improve reliability and performance.


218-224: Broaden extension removal logic.

Currently, #processImportFrom only strips .ts or .js extensions. If this code is intended to be extensible or if you expect .cjs, .mjs, .jsx, or .tsx, consider expanding this logic or making it configurable.


178-181: Clarify ImportOptions behavior when multiple fields are set.

ImportOptions has both relativeTo and relativeToSelf. If both are provided, the code defaults to relativeTo. Document or assert that scenario to prevent mismatched usage.

packages/cli/src/constructs/status-page-codegen.ts (2)

59-78: Consider consolidating optional property handling.

The conditional blocks for optional properties follow a consistent pattern. Consider refactoring to reduce repetition using a helper function.

+ // Helper function to add optional string properties
+ const addOptionalString = (propName: string, value?: string) => {
+   if (value) {
+     builder.string(propName, value);
+   }
+ };
+
- if (resource.customDomain) {
-   builder.string('customDomain', resource.customDomain)
- }
-
- if (resource.logo) {
-   builder.string('logo', resource.logo)
- }
-
- if (resource.redirectTo) {
-   builder.string('redirectTo', resource.redirectTo)
- }
-
- if (resource.favicon) {
-   builder.string('favicon', resource.favicon)
- }
-
- if (resource.defaultTheme) {
-   builder.string('defaultTheme', resource.defaultTheme)
- }
+ addOptionalString('customDomain', resource.customDomain);
+ addOptionalString('logo', resource.logo);
+ addOptionalString('redirectTo', resource.redirectTo);
+ addOptionalString('favicon', resource.favicon);
+ addOptionalString('defaultTheme', resource.defaultTheme);

26-82: Add a method to validate resources before code generation.

Consider adding a validation method to ensure the status page resource is valid before generating code. This would help catch issues early and provide better error messages.

// Add this method to the StatusPageCodegen class
private validateResource(resource: StatusPageResource): void {
  if (!resource.name) {
    throw new Error(`Status page '${resource.id}' is missing a name.`);
  }
  if (!resource.url) {
    throw new Error(`Status page '${resource.id}' is missing a URL.`);
  }
  if (!resource.cards || resource.cards.length === 0) {
    throw new Error(`Status page '${resource.id}' has no cards defined.`);
  }
  
  // Validate each card
  for (const card of resource.cards) {
    if (!card.name) {
      throw new Error(`Card '${card.id}' in status page '${resource.id}' is missing a name.`);
    }
    if (!card.services || card.services.length === 0) {
      throw new Error(`Card '${card.id}' in status page '${resource.id}' has no services defined.`);
    }
  }
}

// Then call this at the beginning of gencode:
// this.validateResource(resource);
packages/cli/src/constructs/internal/codegen/context.ts (1)

35-58: Consider handling filename collisions and special characters.
While kebabCase is a great start, if multiple resources share the same name or contain certain special characters, the generated filenames might conflict or break. You might add a uniqueness suffix or sanitize disallowed characters to avoid filesystem-level collisions.

packages/cli/src/constructs/tcp-check-codegen.ts (1)

7-12: Consider enforcing non-negative response times.

degradedResponseTime and maxResponseTime can be set to arbitrary numbers, including negatives. You might want to ensure these fields are either optional or strictly positive to align with domain expectations and avoid nonsensical configurations.

packages/cli/src/constructs/api-check-codegen.ts (2)

14-25: Consider validating response time thresholds.

Similar to the TCP check resource, degradedResponseTime and maxResponseTime can be set to arbitrary values. Consider restricting or validating them to avoid negative or clearly out-of-range inputs that could lead to confusion.


48-180: Potential opportunity to streamline script handling.

The current logic for local vs. snippet scripts is correct but somewhat repetitive (e.g., lines 127–146 vs. 147–165). Consider extracting a helper function to reduce duplication and enhance maintainability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f745a50 and b890874.

📒 Files selected for processing (13)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-service-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/constructs/heartbeat-check-codegen.ts
  • packages/cli/src/constructs/status-page-service-codegen.ts
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/src/constructs/private-location-codegen.ts
  • packages/cli/src/constructs/maintenance-window-codegen.ts
🧰 Additional context used
🧬 Code Graph Analysis (5)
packages/cli/src/constructs/status-page-codegen.ts (5)
packages/cli/src/constructs/status-page-service-codegen.ts (1)
  • StatusPageServiceResource (4-7)
packages/cli/src/constructs/status-page.ts (1)
  • StatusPageTheme (17-17)
packages/cli/src/constructs/internal/codegen/index.ts (1)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (2)
  • Context (19-198)
  • filename (35-58)
packages/cli/src/sourcegen/index.ts (2)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/tcp-check-codegen.ts (7)
packages/cli/src/constructs/check-codegen.ts (2)
  • CheckResource (17-35)
  • buildCheckProps (37-164)
packages/cli/src/constructs/tcp-check.ts (2)
  • TcpRequest (20-46)
  • TcpAssertion (8-8)
packages/cli/src/sourcegen/index.ts (4)
  • GeneratedFile (40-40)
  • Value (44-44)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/sourcegen/exprbuilder.ts (1)
  • context (34-37)
packages/cli/src/constructs/internal/codegen/context.ts (2)
  • Context (19-198)
  • filename (35-58)
packages/cli/src/sourcegen/identifier.ts (1)
  • ident (22-29)
packages/cli/src/constructs/check-group-codegen.ts (6)
packages/cli/src/constructs/frequency-codegen.ts (1)
  • FrequencyResource (4-4)
packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1)
  • AlertEscalationResource (4-4)
packages/cli/src/constructs/api-check.ts (2)
  • ApiCheckDefaultConfig (71-77)
  • headers (29-31)
packages/cli/src/constructs/retry-strategy-codegen.ts (1)
  • RetryStrategyResource (4-4)
packages/cli/src/sourcegen/index.ts (3)
  • Program (40-40)
  • GeneratedFile (40-40)
  • ObjectValueBuilder (38-38)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Context (2-2)
  • Codegen (1-1)
packages/cli/src/constructs/api-check-codegen.ts (8)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckResource (17-35)
packages/cli/src/constructs/api-check.ts (2)
  • Request (79-95)
  • headers (29-31)
packages/cli/src/sourcegen/index.ts (4)
  • GeneratedFile (40-40)
  • Value (44-44)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/sourcegen/exprbuilder.ts (1)
  • context (34-37)
packages/cli/src/constructs/internal/codegen/context.ts (2)
  • Context (19-198)
  • filename (35-58)
packages/cli/src/sourcegen/identifier.ts (1)
  • ident (22-29)
packages/cli/src/constructs/internal/codegen/context.ts (5)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • MissingContextVariableMappingError (2-2)
  • Context (2-2)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (5-16)
packages/cli/src/sourcegen/index.ts (3)
  • IdentifierValue (34-34)
  • GeneratedFile (40-40)
  • kebabCase (14-14)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (183-270)
packages/cli/src/sourcegen/case.ts (1)
  • kebabCase (45-47)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (14)
packages/cli/src/constructs/status-page-codegen.ts (5)

1-5: Imports are well-organized and appropriately scoped.

The imports provide all the necessary dependencies for the StatusPage code generation, with clear module paths and specific imports rather than using wildcards.


6-10: Interface definition for StatusPageCardResource is clean and well-structured.

The interface provides a clear schema for status page cards with appropriate types for each property.


24-24: LGTM: Constant defined at module level.

Good practice defining the construct name as a constant to avoid hardcoding strings in multiple places.


26-32: Class declaration and file creation look good.

The StatusPageCodegen class properly extends the Codegen base class with the correct type parameter. The file creation and import statement are appropriately structured.


33-39: Builder pattern implementation is clean and readable.

The code uses the builder pattern effectively to construct the StatusPage instance with the required properties.

packages/cli/src/constructs/internal/codegen/context.ts (1)

7-15: Implementation for VariableLocator looks clear and concise.
This class effectively encapsulates an identifier and associated source file without adding unnecessary complexity.

packages/cli/src/constructs/tcp-check-codegen.ts (2)

1-6: Imports look good.

No issues found regarding correctness or maintainability in the import statements.


14-25: Comprehensive handling of TCP assertion sources.

This function properly switches on known sources and throws for unsupported ones, which is a reliable approach. The naming and usage are also consistent with the rest of the codegen utilities.

packages/cli/src/constructs/api-check-codegen.ts (3)

1-6: Imports are well-organized.

All necessary modules and types are imported from appropriate locations.


8-12: Straightforward snippet resource model.

The SnippetResource interface is concise and clearly structured. No issues found.


27-44: Assertion logic is consistent.

All recognized assertion sources are handled with a default error fallback, which is best practice for maintaining safe and predictable behavior.

packages/cli/src/constructs/check-group-codegen.ts (3)

1-12: Imports look good.

Overall, the import statements are well-structured and clear.


256-287: Final code generation logic looks solid.

The class properly registers the check group in prepare() and constructs the code in gencode() using the builder pattern. No major issues identified.


249-249:

✅ Verification successful

Confirm undefined handling for valueForRetryStrategy.

If resource.retryStrategy is undefined, this call might result in unintended output or errors depending on the implementation of valueForRetryStrategy. Please verify if the helper safely handles undefined.


🏁 Script executed:

#!/bin/bash
# Searching for the function definition to ensure it handles undefined reliably
rg -A 10 'function valueForRetryStrategy'

Length of output: 1047


Undefined handling in valueForRetryStrategy appears to be appropriately managed

The function signature in
packages/cli/src/constructs/retry-strategy-codegen.ts
declares the parameter as optional (strategy?: RetryStrategyResource | null), which indicates that passing undefined is an expected scenario. This suggests that the internal logic of valueForRetryStrategy is designed to safely handle cases when resource.retryStrategy is undefined. If your tests also confirm that the output or default behavior is as intended when undefined is passed, then no further changes are required.

Copy link
Contributor

@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: 4

♻️ Duplicate comments (2)
packages/cli/src/constructs/internal/codegen/context.ts (1)

147-153: Handle duplicate physicalId registrations.
This is a repeat of a past suggestion to prevent generating new variables for already-registered physicalIds in registerCheckGroup. Consider returning the existing locator if the map contains the physicalId.

packages/cli/src/constructs/status-page-service-codegen.ts (1)

12-21: Add validation for resource ID before registration

The prepare method should validate that resource.id exists and is non-empty before using it to register the status page service. Without validation, passing an undefined or empty ID could lead to unexpected behavior.

  prepare (logicalId: string, resource: StatusPageServiceResource, context: Context): void {
+   if (!resource.id) {
+     throw new Error('StatusPageServiceResource must have a valid id');
+   }
    const filePath = context.filePath('resources/status-pages/services', resource.name, {
      unique: true,
    })

    context.registerStatusPageService(
      resource.id,
      this.program.generatedConstructFile(filePath.fullPath),
    )
  }
🧹 Nitpick comments (4)
packages/cli/src/constructs/internal/codegen/context.ts (1)

67-139: Consider addressing the constant condition flagged by static analysis in the do { ... } while (true) loop.
Although this loop is intentional for generating unique file names, it triggers a lint warning regarding the literal true condition. You could address the lint error by rewriting it as a while loop with a meaningful condition or disabling the rule if you are certain that this infinite loop pattern is your preferred approach.

-    } while (true)
+    } while (!uniqueFileFound)
🧰 Tools
🪛 Biome (1.9.4)

[error] 138-138: Unexpected constant condition.

(lint/correctness/noConstantCondition)

packages/cli/src/constructs/status-page-service-codegen.ts (2)

32-34: Consider supporting additional StatusPageService properties

The current implementation only sets the name property, but the StatusPageService construct might support additional configuration options that could be exposed through the StatusPageServiceResource interface.

Consider expanding the resource interface and the object builder to support other relevant properties that users might want to configure when importing status page services.


1-41: Add JSDoc comments for better code documentation

The file would benefit from JSDoc comments for the class, interface, and methods to explain their purpose, parameters, and return values. This would make the code more maintainable and easier to understand for other developers.

For example:

/**
 * Interface representing a Status Page Service resource to be imported
 */
export interface StatusPageServiceResource {
  /** Unique identifier of the status page service */
  id: string
  /** Display name of the status page service */
  name: string
}

/**
 * Generates code for Status Page Service resources
 */
export class StatusPageServiceCodegen extends Codegen<StatusPageServiceResource> {
  /**
   * Prepares the context for code generation
   * @param logicalId - Logical identifier for the resource
   * @param resource - The status page service resource
   * @param context - The code generation context
   */
  prepare (logicalId: string, resource: StatusPageServiceResource, context: Context): void {
    // ...
  }
  
  // ...
}
packages/cli/src/constructs/maintenance-window-codegen.ts (1)

1-12: Interface design looks solid, but consider stricter date types.
Currently, startsAt and endsAt are typed as strings. This is perfectly valid in many contexts, but you might consider using more specific date-like types or validating date formats to reduce the risk of invalid values.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b890874 and 84cd0a3.

📒 Files selected for processing (12)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-service-codegen.ts (1 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/src/constructs/private-location-codegen.ts
  • packages/cli/src/constructs/tcp-check-codegen.ts
  • packages/cli/src/constructs/status-page-codegen.ts
  • packages/cli/src/constructs/heartbeat-check-codegen.ts
  • packages/cli/src/constructs/check-group-codegen.ts
🧰 Additional context used
🧬 Code Graph Analysis (4)
packages/cli/src/constructs/maintenance-window-codegen.ts (3)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/internal/codegen/context.ts (2)
  • Context (48-279)
  • filePath (67-139)
packages/cli/src/sourcegen/index.ts (2)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/api-check-codegen.ts (7)
packages/cli/src/constructs/check-codegen.ts (1)
  • CheckResource (17-35)
packages/cli/src/constructs/api-check.ts (2)
  • Request (79-95)
  • headers (29-31)
packages/cli/src/sourcegen/program.ts (1)
  • GeneratedFile (183-270)
packages/cli/src/sourcegen/index.ts (4)
  • GeneratedFile (40-40)
  • Value (44-44)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/internal/assertion-codegen.ts (2)
  • valueForNumericAssertion (4-43)
  • valueForGeneralAssertion (45-146)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • Codegen (1-1)
  • Context (2-2)
packages/cli/src/constructs/key-value-pair-codegen.ts (1)
  • valueForKeyValuePair (5-52)
packages/cli/src/constructs/status-page-service-codegen.ts (3)
packages/cli/src/constructs/internal/codegen/index.ts (1)
  • Codegen (1-1)
packages/cli/src/constructs/internal/codegen/context.ts (2)
  • Context (48-279)
  • filePath (67-139)
packages/cli/src/sourcegen/index.ts (3)
  • decl (22-22)
  • expr (33-33)
  • ident (34-34)
packages/cli/src/constructs/internal/codegen/context.ts (5)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • MissingContextVariableMappingError (2-2)
  • Context (2-2)
packages/cli/src/sourcegen/index.ts (3)
  • IdentifierValue (34-34)
  • GeneratedFile (40-40)
  • kebabCase (14-14)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (5-16)
packages/cli/src/sourcegen/program.ts (3)
  • GeneratedFile (183-270)
  • path (113-116)
  • dirname (157-159)
packages/cli/src/sourcegen/case.ts (1)
  • kebabCase (45-47)
🪛 Biome (1.9.4)
packages/cli/src/constructs/internal/codegen/context.ts

[error] 138-138: Unexpected constant condition.

(lint/correctness/noConstantCondition)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (7)
packages/cli/src/constructs/internal/codegen/context.ts (3)

1-4: No issues found in the import statements.


7-15: Well-structured locator class.
No issues detected with the VariableLocator design. The mapping of an IdentifierValue and a GeneratedFile is clear and consistent.


155-279: Overall approach appears sound.
All register/lookup methods for alert channels, private locations, check groups, and status page services are consistent in maintaining the necessary context mappings. No further issues identified.

packages/cli/src/constructs/maintenance-window-codegen.ts (1)

16-70: Overall implementation is coherent and aligns with the existing code generation pattern.
The gencode method correctly handles property creation and includes optional fields (repeatInterval, repeatEndsAt, etc.) in a clear, modular style. No critical issues detected.

packages/cli/src/constructs/api-check-codegen.ts (3)

1-44: Good structure and assertion handling.
The SnippetResource, ApiCheckResource interfaces, and valueForAssertion function appear cohesive and maintain consistency with other check-related files.


48-109: Code generation logic is thorough.
The request object’s fields (URL, method, headers, etc.) are conditionally set, promoting clarity in the generated output. This approach helps avoid cluttering the final code with unused properties.


120-190: Scripts handling logic is well-structured.
Your approach for either local scripts or snippet-based scripts, including generating a separate file for each scenario, keeps the flow of code generation organized.

Comment on lines +141 to +152
importVariable (locator: VariableLocator, file: GeneratedFile): void {
file.namedImport(locator.id.value, locator.file.path, {
relativeTo: dirname(file.path),
})
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Check for named import collisions in importVariable.
Multiple imports could end up with the same identifier name if locator.id.value reoccurs. Consider verifying that each new import name is unique, or handle collisions gracefully to avoid potentially overwriting named imports in the generated file.

Comment on lines +13 to +30
const filePath = context.filePath('resources/status-pages/services', resource.name, {
unique: true,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider validating the resource name

The name property is used to generate the file path, but there's no validation to ensure it's a valid and safe value for a filename. Invalid characters in the name could potentially cause issues.

  prepare (logicalId: string, resource: StatusPageServiceResource, context: Context): void {
    if (!resource.id) {
      throw new Error('StatusPageServiceResource must have a valid id');
    }
+   if (!resource.name || resource.name.trim() === '') {
+     throw new Error('StatusPageServiceResource must have a valid name');
+   }
    const filePath = context.filePath('resources/status-pages/services', resource.name, {
      unique: true,
    })
📝 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.

Suggested change
const filePath = context.filePath('resources/status-pages/services', resource.name, {
unique: true,
})
prepare (logicalId: string, resource: StatusPageServiceResource, context: Context): void {
if (!resource.id) {
throw new Error('StatusPageServiceResource must have a valid id');
}
if (!resource.name || resource.name.trim() === '') {
throw new Error('StatusPageServiceResource must have a valid name');
}
const filePath = context.filePath('resources/status-pages/services', resource.name, {
unique: true,
})
// ... rest of the method
}

Comment on lines +23 to +39
gencode (logicalId: string, resource: StatusPageServiceResource, context: Context): void {
const { id, file } = context.lookupStatusPageService(resource.id)
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Validate resource ID before lookup

Similar to the prepare method, you should validate resource.id before calling lookupStatusPageService to prevent potential errors when looking up a service with an empty or undefined ID.

  gencode (logicalId: string, resource: StatusPageServiceResource, context: Context): void {
+   if (!resource.id) {
+     throw new Error('StatusPageServiceResource must have a valid id');
+   }
    const { id, file } = context.lookupStatusPageService(resource.id)
📝 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.

Suggested change
gencode (logicalId: string, resource: StatusPageServiceResource, context: Context): void {
const { id, file } = context.lookupStatusPageService(resource.id)
gencode (logicalId: string, resource: StatusPageServiceResource, context: Context): void {
if (!resource.id) {
throw new Error('StatusPageServiceResource must have a valid id');
}
const { id, file } = context.lookupStatusPageService(resource.id)

@sorccu sorccu added the build Issue regarding building and packaging label Apr 22, 2025
@github-actions

This comment has been minimized.

@sorccu sorccu force-pushed the simokinnunen/sc-23506/cli-import-existing-resources branch from 0c53741 to 979484b Compare April 22, 2025 14:35
@sorccu sorccu added build Issue regarding building and packaging and removed build Issue regarding building and packaging labels Apr 22, 2025
sorccu added 24 commits May 15, 2025 23:53
Previously you'd be shown a select with no options.
The process is explained along the way. Explanations are shared between
commands.
Auto complete still works for known values. Values that are not known can
still be entered. Useful because the UI supports some icon types that the
CLI type has not been updated for.
@sorccu sorccu force-pushed the simokinnunen/sc-23506/cli-import-existing-resources branch from f993c12 to cfbb25b Compare May 15, 2025 14:53
Copy link
Contributor

@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: 1

♻️ Duplicate comments (7)
packages/cli/src/sourcegen/case.ts (1)

77-121: wordify still lacks documentation & edge-case tests

A previous review already asked for JSDoc and unit tests covering tricky inputs (empty strings, all-caps acronyms like HTTPRequest, numeric-only strings, special-character separators, etc.). These are important to guarantee the correctness of every downstream case-conversion helper that relies on wordify.

Consider:

  • Adding a concise JSDoc comment describing the splitting rules.
  • Extending case.spec.ts with the missing edge-cases.

This will make future maintenance easier and prevent silent regressions.

🧰 Tools
🪛 Biome (1.9.4)

[error] 112-112: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/cli/src/services/checkly-config-codegen.ts (1)

70-81: Logical-ID alert-channel references still unsupported

As previously flagged in the alert-channel-codegen review, generation bails out unless alertChannel.physicalId is a number. Users often reference alert channels by logical ID inside the same project, so this will break legitimate configs.

Either resolve the logical ID via the Context or emit a clearer message guiding the user to import/define the channel first.

packages/cli/src/constructs/internal/codegen/context.ts (5)

148-152: 🛠️ Refactor suggestion

Prevent named import collisions.

The importVariable method uses locator.id.value directly without checking for potential collisions in the named imports. Multiple imports could end up with the same identifier name if different locators happen to have the same ID value.

Apply this change to track and ensure uniqueness of imported variable names:

importVariable (locator: VariableLocator, file: GeneratedFile): void {
+  // Keep track of imported variables to avoid name collisions
+  if (!file.hasNamedImport(locator.id.value, locator.file.path)) {
    file.namedImport(locator.id.value, locator.file.path, {
      relativeTo: dirname(file.path),
    })
+  }
}

This assumes adding a hasNamedImport method to GeneratedFile class, or you could alternatively implement the tracking directly within the Context class.


154-160: 🛠️ Refactor suggestion

Handle duplicate registrations in check group registration.

The method lacks a check for existing mappings, which could lead to inconsistencies when the same physical ID is registered multiple times.

Apply this change to reuse existing variable locators:

registerCheckGroup (physicalId: number, file: GeneratedFile): VariableLocator {
+  if (this.#checkGroupVariablesByPhysicalId.has(physicalId)) {
+    return this.#checkGroupVariablesByPhysicalId.get(physicalId)!
+  }
  const nth = this.#checkGroupVariablesByPhysicalId.size + 1
  const id = new IdentifierValue(`group${nth}`)
  const locator = new VariableLocator(id, file)
  this.#checkGroupVariablesByPhysicalId.set(physicalId, locator)
  return locator
}

170-176: 🛠️ Refactor suggestion

Handle duplicate registrations in alert channel registration.

The method lacks a check for existing mappings, which could lead to inconsistencies when the same physical ID is registered multiple times.

Apply this change to reuse existing variable locators:

registerAlertChannel (physicalId: number, variablePrefix: string, file: GeneratedFile): VariableLocator {
+  if (this.#alertChannelVariablesByPhysicalId.has(physicalId)) {
+    return this.#alertChannelVariablesByPhysicalId.get(physicalId)!
+  }
  const nth = this.#alertChannelVariablesByPhysicalId.size + 1
  const id = new IdentifierValue(`${variablePrefix}${nth}`)
  const locator = new VariableLocator(id, file)
  this.#alertChannelVariablesByPhysicalId.set(physicalId, locator)
  return locator
}

186-192: 🛠️ Refactor suggestion

Handle duplicate registrations in private location registration.

The method lacks a check for existing mappings, which could lead to inconsistencies when the same physical ID is registered multiple times.

Apply this change to reuse existing variable locators:

registerPrivateLocation (physicalId: string, file: GeneratedFile): VariableLocator {
+  if (this.#privateLocationVariablesByPhysicalId.has(physicalId)) {
+    return this.#privateLocationVariablesByPhysicalId.get(physicalId)!
+  }
  const nth = this.#privateLocationVariablesByPhysicalId.size + 1
  const id = new IdentifierValue(`privateLocation${nth}`)
  const locator = new VariableLocator(id, file)
  this.#privateLocationVariablesByPhysicalId.set(physicalId, locator)
  return locator
}

262-268: 🛠️ Refactor suggestion

Handle duplicate registrations in status page service registration.

The method lacks a check for existing mappings, which could lead to inconsistencies when the same physical ID is registered multiple times.

Apply this change to reuse existing variable locators:

registerStatusPageService (physicalId: string, file: GeneratedFile): VariableLocator {
+  if (this.#statusPageServiceVariablesByPhysicalId.has(physicalId)) {
+    return this.#statusPageServiceVariablesByPhysicalId.get(physicalId)!
+  }
  const nth = this.#statusPageServiceVariablesByPhysicalId.size + 1
  const id = new IdentifierValue(`service${nth}`)
  const locator = new VariableLocator(id, file)
  this.#statusPageServiceVariablesByPhysicalId.set(physicalId, locator)
  return locator
}
🧹 Nitpick comments (8)
packages/cli/src/sourcegen/case.ts (1)

108-113: Remove redundant continue to silence linter & reduce noise

Biome already flags this continue as unnecessary because control flow naturally loops back after the if-block. Dropping it keeps the code terser and avoids future lint suppressions.

-      word = ''
-      small = false
-      continue
+      word = ''
+      small = false
🧰 Tools
🪛 Biome (1.9.4)

[error] 112-112: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/cli/src/constructs/alert-channel-subscription-codegen.ts (2)

10-12: Mark unused param in describe to satisfy linters

resource is not referenced inside describe.
Either prefix it with an underscore or remove it to avoid the “unused variable” warning:

-  describe (resource: AlertChannelSubscriptionResource): string {
+  // `resource` isn’t needed for the static label – mark it intentionally unused
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
+  describe (_resource: AlertChannelSubscriptionResource): string {
🧰 Tools
🪛 GitHub Check: lint

[warning] 10-10:
'resource' is defined but never used


14-22: Validate that exactly one of checkId or groupId is provided

Right now the code happily accepts:

  1. both properties (checkId + groupId) – ambiguous;
  2. or neither property – a no-op subscription.

Add a guard to enforce the expected invariant and surface a helpful error:

   prepare (logicalId: string, resource: AlertChannelSubscriptionResource, context: Context): void {
+    const hasCheck = resource.checkId !== undefined
+    const hasGroup = resource.groupId !== undefined
+
+    if (hasCheck === hasGroup) { // both or neither
+      throw new Error(
+        `AlertChannelSubscription '${logicalId}' must reference exactly one of 'checkId' or 'groupId'.`,
+      )
+    }
+
     if (resource.checkId !== undefined) {
       context.registerAlertChannelCheckSubscription(resource.alertChannelId, resource.checkId)
     }
packages/cli/src/services/check-parser/package-files/package-json-file.ts (2)

70-90: upsertDependencies / upsertDevDependencies share identical logic – extract common helper

Both methods differ only by the target field. Duplicating the same update-&-sort sequence increases maintenance overhead and the chance of diverging behaviour.

A small refactor could unify them:

-  upsertDependencies (dependencies: Record<string, string>): boolean {
-    const result = updateDependencies(this.jsonFile.data.dependencies, dependencies)
+  #upsert (field: 'dependencies' | 'devDependencies', deps: Record<string, string>): boolean {
+    const result = updateDependencies(this.jsonFile.data[field], deps)
     if (!result.changed) {
       return false
     }
-
-    this.jsonFile.data.dependencies = sortDependencies(result.dependencies)
+    this.jsonFile.data[field] = sortDependencies(result.dependencies)
     return true
   }
-
-  upsertDevDependencies (dependencies: Record<string, string>): boolean {
-    const result = updateDependencies(this.jsonFile.data.devDependencies, dependencies)
-    ...
-  }
+  upsertDependencies (deps: Record<string, string>): boolean {
+    return this.#upsert('dependencies', deps)
+  }
+
+  upsertDevDependencies (deps: Record<string, string>): boolean {
+    return this.#upsert('devDependencies', deps)
+  }

Keeps behaviour identical while reducing duplication.


97-136: Gracefully handle unparsable new semver ranges

updateDependencies throws if newVersion fails semver.minVersion. A malformed range would therefore crash the entire import flow instead of simply skipping the bad entry and reporting it.

Consider returning { changed: false } for that dependency and logging a warning instead of a hard error. This prevents one bad version string from aborting an otherwise valid update.

packages/cli/src/constructs/internal/codegen/context.ts (3)

145-146: Add a breaking condition to prevent potential infinite loops.

The current implementation uses an infinite loop with while (true) which is flagged by static analysis. While there is a return path, adding an explicit breaking condition would make the code more robust.

- // eslint-disable-next-line no-constant-condition
- } while (true)
+ // Add a safety limit to prevent infinite loops
+ const maxAttempts = 1000
+ counter++
+ } while (counter < maxAttempts)
+ 
+ // If we reached this point, we couldn't find a suitable filename
+ throw new Error(`Couldn't generate a unique file path for ${hint} after ${maxAttempts} attempts`)
🧰 Tools
🪛 Biome (1.9.4)

[error] 145-145: Unexpected constant condition.

(lint/correctness/noConstantCondition)


296-323: Consider optimizing the snippet file matching logic.

The current implementation tries multiple variations of filenames when finding script snippet files. This approach might be brittle if naming conventions change.

Consider normalizing filenames during registration and lookup to reduce the complexity of matching. For example, you could store normalized keys (without extensions) and use them for lookups.

registerAuxiliarySnippetFile (physicalId: number, snippetFile: ProgramFile) {
  this.#auxiliarySnippetFilesByPhysicalId.set(physicalId, snippetFile)
+  // Store with normalized keys for easier lookup
  this.#auxiliarySnippetFilesByFilename.set(snippetFile.basename, snippetFile)
+  const normalizedName = path.parse(snippetFile.basename).name
+  if (!this.#auxiliarySnippetFilesByFilename.has(normalizedName)) {
+    this.#auxiliarySnippetFilesByFilename.set(normalizedName, snippetFile)
+  }
}

Then you could simplify the findScriptSnippetFiles method to reduce the number of lookups.


73-146: Add documentation for the file path generation logic.

The filePath method contains complex logic for generating unique file paths with various options. Adding documentation for each parameter and how they affect the generated path would make this code more maintainable.

Consider adding JSDoc comments that explain:

  • What each option does (tags, isolate, unique, contentKey, case)
  • How the content key is used to differentiate files
  • How uniqueness is enforced
  • What the return value represents
🧰 Tools
🪛 Biome (1.9.4)

[error] 145-145: Unexpected constant condition.

(lint/correctness/noConstantCondition)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f993c12 and cfbb25b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (98)
  • packages/cli/e2e/__tests__/help.spec.ts (2 hunks)
  • packages/cli/package.json (6 hunks)
  • packages/cli/src/commands/baseCommand.ts (2 hunks)
  • packages/cli/src/commands/import/apply.ts (1 hunks)
  • packages/cli/src/commands/import/cancel.ts (1 hunks)
  • packages/cli/src/commands/import/commit.ts (1 hunks)
  • packages/cli/src/commands/import/plan.ts (1 hunks)
  • packages/cli/src/constructs/__tests__/alert-channel.spec.ts (1 hunks)
  • packages/cli/src/constructs/__tests__/check-group.spec.ts (1 hunks)
  • packages/cli/src/constructs/__tests__/private-location.spec.ts (1 hunks)
  • packages/cli/src/constructs/__tests__/status-page-service.spec.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel-subscription-codegen.ts (1 hunks)
  • packages/cli/src/constructs/alert-channel.ts (2 hunks)
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/api-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/browser-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group-codegen.ts (1 hunks)
  • packages/cli/src/constructs/check-group.ts (6 hunks)
  • packages/cli/src/constructs/check.ts (4 hunks)
  • packages/cli/src/constructs/construct-codegen.ts (1 hunks)
  • packages/cli/src/constructs/dashboard-codegen.ts (1 hunks)
  • packages/cli/src/constructs/email-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/frequency-codegen.ts (1 hunks)
  • packages/cli/src/constructs/heartbeat-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/incidentio-alert-channel.ts (3 hunks)
  • packages/cli/src/constructs/internal/assertion-codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/codegen.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/context.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/index.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/safety.ts (1 hunks)
  • packages/cli/src/constructs/internal/codegen/snippet.ts (1 hunks)
  • packages/cli/src/constructs/key-value-pair-codegen.ts (1 hunks)
  • packages/cli/src/constructs/maintenance-window-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/msteams-alert-channel.ts (3 hunks)
  • packages/cli/src/constructs/multi-step-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config-codegen.ts (1 hunks)
  • packages/cli/src/constructs/playwright-config.ts (0 hunks)
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location-group-assignment-codegen.ts (1 hunks)
  • packages/cli/src/constructs/private-location.ts (3 hunks)
  • packages/cli/src/constructs/project.ts (1 hunks)
  • packages/cli/src/constructs/ref-codegen.ts (1 hunks)
  • packages/cli/src/constructs/retry-strategy-codegen.ts (1 hunks)
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-service-codegen.ts (1 hunks)
  • packages/cli/src/constructs/status-page-service.ts (2 hunks)
  • packages/cli/src/constructs/tcp-check-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/constructs/telegram-alert-channel.ts (3 hunks)
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts (1 hunks)
  • packages/cli/src/helpers/command-style.ts (1 hunks)
  • packages/cli/src/helpers/wrap.ts (1 hunks)
  • packages/cli/src/rest/projects.ts (5 hunks)
  • packages/cli/src/services/check-parser/package-files/__tests__/package-json-file.spec.ts (1 hunks)
  • packages/cli/src/services/check-parser/package-files/json-source-file.ts (1 hunks)
  • packages/cli/src/services/check-parser/package-files/package-json-file.ts (2 hunks)
  • packages/cli/src/services/check-parser/package-files/package-manager.ts (1 hunks)
  • packages/cli/src/services/check-parser/package-files/resolver.ts (1 hunks)
  • packages/cli/src/services/check-parser/package-files/source-file.ts (1 hunks)
  • packages/cli/src/services/check-parser/parser.ts (1 hunks)
  • packages/cli/src/services/checkly-config-codegen.ts (1 hunks)
  • packages/cli/src/services/checkly-config-loader.ts (2 hunks)
  • packages/cli/src/sourcegen/__tests__/case.spec.ts (1 hunks)
  • packages/cli/src/sourcegen/args.ts (1 hunks)
  • packages/cli/src/sourcegen/argsbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/array.ts (1 hunks)
  • packages/cli/src/sourcegen/arraybuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/boolean.ts (1 hunks)
  • packages/cli/src/sourcegen/case.ts (1 hunks)
  • packages/cli/src/sourcegen/comment.ts (1 hunks)
  • packages/cli/src/sourcegen/decl.ts (1 hunks)
  • packages/cli/src/sourcegen/declbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/expr.ts (1 hunks)
  • packages/cli/src/sourcegen/exprbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/identifier.ts (1 hunks)
  • packages/cli/src/sourcegen/index.ts (1 hunks)
  • packages/cli/src/sourcegen/null.ts (1 hunks)
  • packages/cli/src/sourcegen/number.ts (1 hunks)
  • packages/cli/src/sourcegen/object.ts (1 hunks)
  • packages/cli/src/sourcegen/objectbuilder.ts (1 hunks)
  • packages/cli/src/sourcegen/output.ts (1 hunks)
  • packages/cli/src/sourcegen/program.ts (1 hunks)
  • packages/cli/src/sourcegen/string.ts (1 hunks)
  • packages/cli/src/sourcegen/undefined.ts (1 hunks)
  • packages/cli/src/sourcegen/unknown.ts (1 hunks)
  • packages/cli/src/sourcegen/value.ts (1 hunks)
  • packages/cli/src/util/index.ts (1 hunks)
  • packages/cli/tsconfig.json (2 hunks)
💤 Files with no reviewable changes (1)
  • packages/cli/src/constructs/playwright-config.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/cli/src/constructs/tests/check-group.spec.ts
  • packages/cli/src/constructs/tests/private-location.spec.ts
🚧 Files skipped from review as they are similar to previous changes (86)
  • packages/cli/src/constructs/tests/alert-channel.spec.ts
  • packages/cli/tsconfig.json
  • packages/cli/src/commands/baseCommand.ts
  • packages/cli/src/sourcegen/null.ts
  • packages/cli/src/services/check-parser/package-files/source-file.ts
  • packages/cli/src/constructs/internal/codegen/safety.ts
  • packages/cli/src/sourcegen/undefined.ts
  • packages/cli/src/services/check-parser/package-files/json-source-file.ts
  • packages/cli/src/sourcegen/boolean.ts
  • packages/cli/e2e/tests/help.spec.ts
  • packages/cli/src/sourcegen/args.ts
  • packages/cli/src/constructs/ref-codegen.ts
  • packages/cli/src/services/checkly-config-loader.ts
  • packages/cli/src/sourcegen/unknown.ts
  • packages/cli/src/constructs/incidentio-alert-channel.ts
  • packages/cli/src/services/check-parser/package-files/tests/package-json-file.spec.ts
  • packages/cli/src/constructs/playwright-config-codegen.ts
  • packages/cli/src/constructs/project.ts
  • packages/cli/src/services/check-parser/parser.ts
  • packages/cli/src/sourcegen/identifier.ts
  • packages/cli/src/constructs/status-page-service.ts
  • packages/cli/src/sourcegen/number.ts
  • packages/cli/src/sourcegen/array.ts
  • packages/cli/src/helpers/wrap.ts
  • packages/cli/src/constructs/frequency-codegen.ts
  • packages/cli/src/sourcegen/tests/case.spec.ts
  • packages/cli/src/constructs/internal/codegen/index.ts
  • packages/cli/src/constructs/telegram-alert-channel.ts
  • packages/cli/src/sourcegen/value.ts
  • packages/cli/src/constructs/tests/status-page-service.spec.ts
  • packages/cli/src/util/index.ts
  • packages/cli/src/constructs/private-location.ts
  • packages/cli/src/sourcegen/string.ts
  • packages/cli/src/sourcegen/output.ts
  • packages/cli/src/constructs/alert-channel-codegen.ts
  • packages/cli/package.json
  • packages/cli/src/constructs/internal/codegen/codegen.ts
  • packages/cli/src/constructs/dashboard-codegen.ts
  • packages/cli/src/constructs/private-location-check-assignment-codegen.ts
  • packages/cli/src/helpers/command-style.ts
  • packages/cli/src/constructs/internal/assertion-codegen.ts
  • packages/cli/src/constructs/msteams-alert-channel.ts
  • packages/cli/src/constructs/key-value-pair-codegen.ts
  • packages/cli/src/constructs/private-location-group-assignment-codegen.ts
  • packages/cli/src/constructs/maintenance-window-codegen.ts
  • packages/cli/src/commands/import/cancel.ts
  • packages/cli/src/constructs/heartbeat-check-codegen.ts
  • packages/cli/src/constructs/check.ts
  • packages/cli/src/constructs/telegram-alert-channel-codegen.ts
  • packages/cli/src/constructs/phone-call-alert-channel-codegen.ts
  • packages/cli/src/constructs/alert-escalation-policy-codegen.ts
  • packages/cli/src/services/check-parser/package-files/resolver.ts
  • packages/cli/src/constructs/sms-alert-channel-codegen.ts
  • packages/cli/src/constructs/slack-alert-channel-codegen.ts
  • packages/cli/src/constructs/alert-channel.ts
  • packages/cli/src/constructs/status-page-codegen.ts
  • packages/cli/src/constructs/construct-codegen.ts
  • packages/cli/src/sourcegen/comment.ts
  • packages/cli/src/constructs/status-page-service-codegen.ts
  • packages/cli/src/constructs/multi-step-check-codegen.ts
  • packages/cli/src/constructs/email-alert-channel-codegen.ts
  • packages/cli/src/constructs/retry-strategy-codegen.ts
  • packages/cli/src/constructs/api-check-codegen.ts
  • packages/cli/src/constructs/opsgenie-alert-channel-codegen.ts
  • packages/cli/src/sourcegen/index.ts
  • packages/cli/src/constructs/check-codegen.ts
  • packages/cli/src/sourcegen/declbuilder.ts
  • packages/cli/src/commands/import/commit.ts
  • packages/cli/src/constructs/browser-check-codegen.ts
  • packages/cli/src/sourcegen/expr.ts
  • packages/cli/src/commands/import/apply.ts
  • packages/cli/src/sourcegen/decl.ts
  • packages/cli/src/constructs/tcp-check-codegen.ts
  • packages/cli/src/sourcegen/object.ts
  • packages/cli/src/sourcegen/exprbuilder.ts
  • packages/cli/src/constructs/pagerduty-alert-channel-codegen.ts
  • packages/cli/src/constructs/private-location-codegen.ts
  • packages/cli/src/constructs/incidentio-alert-channel-codegen.ts
  • packages/cli/src/constructs/internal/codegen/snippet.ts
  • packages/cli/src/constructs/webhook-alert-channel-codegen.ts
  • packages/cli/src/sourcegen/arraybuilder.ts
  • packages/cli/src/sourcegen/argsbuilder.ts
  • packages/cli/src/constructs/msteams-alert-channel-codegen.ts
  • packages/cli/src/constructs/check-group.ts
  • packages/cli/src/sourcegen/objectbuilder.ts
  • packages/cli/src/sourcegen/program.ts
🧰 Additional context used
🧠 Learnings (1)
packages/cli/src/commands/import/plan.ts (1)
Learnt from: sorccu
PR: checkly/checkly-cli#1045
File: packages/cli/src/commands/import/plan.ts:865-896
Timestamp: 2025-05-08T23:24:10.668Z
Learning: In the `parseFilter` function of the import command, filter specifications without a colon are valid and represent filtering for all resources of the specified type (without filtering by ID).
🧬 Code Graph Analysis (1)
packages/cli/src/constructs/internal/codegen/context.ts (5)
packages/cli/src/constructs/internal/codegen/index.ts (2)
  • MissingContextVariableMappingError (2-2)
  • Context (2-2)
packages/cli/src/sourcegen/index.ts (4)
  • IdentifierValue (44-44)
  • GeneratedFile (50-50)
  • CaseFormat (8-8)
  • cased (7-7)
packages/cli/src/sourcegen/identifier.ts (1)
  • IdentifierValue (5-16)
packages/cli/src/sourcegen/program.ts (3)
  • GeneratedFile (194-292)
  • path (120-123)
  • dirname (168-170)
packages/cli/src/constructs/internal/codegen/snippet.ts (1)
  • parseSnippetDependencies (46-59)
🪛 Biome (1.9.4)
packages/cli/src/commands/import/plan.ts

[error] 583-583: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)


[error] 926-926: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)


[error] 1139-1139: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)


[error] 1227-1227: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

packages/cli/src/services/check-parser/package-files/package-manager.ts

[error] 378-378: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/cli/src/constructs/internal/codegen/context.ts

[error] 145-145: Unexpected constant condition.

(lint/correctness/noConstantCondition)

packages/cli/src/sourcegen/case.ts

[error] 112-112: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

🪛 GitHub Check: lint
packages/cli/src/constructs/alert-channel-subscription-codegen.ts

[warning] 10-10:
'resource' is defined but never used

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test - windows-latest
  • GitHub Check: test - ubuntu-latest
🔇 Additional comments (9)
packages/cli/src/commands/import/plan.ts (4)

202-208: Wrap debug-file write in try/catch to avoid crashing on I/O errors

If the user passes --debug-import-plan and the fs.writeFile fails (e.g. path not writable) the command will reject before reaching the surrounding try/catch further below, causing an unhandled rejection and an ugly stack-trace.
Protect the UX with a dedicated guard:

-const output = JSON.stringify(plan, null, 2)
-await fs.writeFile(debugImportPlanOutputFile, output, 'utf8')
-this.style.shortSuccess(
-  `Successfully wrote debug import plan to "${debugImportPlanOutputFile}".`,
-)
+try {
+  const output = JSON.stringify(plan, null, 2)
+  await fs.writeFile(debugImportPlanOutputFile, output, 'utf8')
+  this.style.shortSuccess(
+    `Successfully wrote debug import plan to "${debugImportPlanOutputFile}".`,
+  )
+} catch (err) {
+  this.style.longError(
+    `Failed to write the debug import plan to "${debugImportPlanOutputFile}".`,
+    (err as Error).message,
+  )
+  this.cancelAndExit()
+}

[ suggest_essential_refactor ]


942-946: resources may be undefined, leading to a crash

plan.changes?.resources is optional in the API contract.
If the backend returns a plan that only contains auxiliary files, the destructuring here assigns undefined to resources, yet later code blindly passes it to sortResources and iterates over it – throwing TypeError: undefined is not iterable.

-const { resources, auxiliary } = plan.changes
+const { resources = [], auxiliary } = plan.changes

Also guard calls to sortResources and the two loops below with if (resources.length) { … }.
This prevents the command from terminating before the user can retry.
[ raise_critical_issue ]


1015-1019: Type-safety & null-safety – stop using any for resources

Casting to any defeats the purpose of TypeScript and masks real errors.
Now that you already normalise resources to an array, introduce a proper interface and drop the casts:

-interface FailedResource {
-  resource: ResourceSync
-  cause: Error
-}
-
-type Resource = ResourceSync   // give it a shorter alias

-sortResources(resources as any)
+sortResources(resources)

-for (const resource of resources) {
-  codegen.prepare(resource.logicalId, resource as any, context)
+for (const resource of resources) {
+  codegen.prepare(resource.logicalId, resource, context)
 }

Same for the gencode loop.
[ suggest_essential_refactor ]


193-273: Potential infinite retry loop – add an escape hatch

while (true) keeps recreating plans until every resource succeeds.
If a non-recoverable failure occurs (e.g. unsupported resource type) the loop can run forever, forcing users to Ctrl-C.
Consider:

  • Limiting the number of retries (e.g. maxRetries = 3)
  • Aborting when failures.length does not shrink between iterations
  • Offering a “give up” prompt in #confirmRetryWithoutFailed

The UX will feel much safer.
[ duplicate_comment ][ suggest_optional_refactor ]

packages/cli/src/services/check-parser/package-files/package-manager.ts (2)

276-281: detectPresence awaits nothing – detection always “succeeds”

lookupPath is asynchronous, yet the result isn’t awaited.
Consequently foundPath is always a Promise, never undefined, so the method never throws and every detector reports a false positive.

-async detectPresence (executable: string): Promise<void> {
-  const foundPath = this.lookupPath(executable)
-  if (foundPath === undefined) {
-    throw new NotDetectedError()
-  }
+async detectPresence (executable: string): Promise<void> {
+  const foundPath = await this.lookupPath(executable)
+  if (foundPath === undefined) {
+    throw new NotDetectedError()
+  }
 }

Without this fix the CLI may assume a package manager exists and emit commands that fail at runtime.
[ raise_critical_issue ]


372-380: Nit: unnecessary continue

Inside the for…of loop you continue immediately after the catch, but the next iteration starts automatically.
Removing the continue simplifies the flow without changing behaviour.
[ suggest_nitpick ]

🧰 Tools
🪛 Biome (1.9.4)

[error] 378-378: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

packages/cli/src/rest/projects.ts (1)

153-160: listImportPlans lacks the error handling you added elsewhere

get, deleteProject, and findImportPlans all translate 404s into ProjectNotFoundError, but listImportPlans returns the raw Axios promise.
For API consistency and to avoid leaking Axios errors to callers, wrap it like the others (example shown):

- listImportPlans ({ onlyUnapplied = false, onlyUncommitted = false } = {}) {
-   return this.api.get<ImportPlan[]>('/next/projects/imports', {
+ async listImportPlans ({ onlyUnapplied = false, onlyUncommitted = false } = {}) {
+   try {
+     return await this.api.get<ImportPlan[]>('/next/projects/imports', {
       params: { onlyUnapplied, onlyUncommitted },
     })
+   } catch (err) {
+     if (isAxiosError(err) && err.response?.status === 404) {
+       throw new ProjectNotFoundError()
+     }
+     throw err
+   }
 }

[ duplicate_comment ]

packages/cli/src/constructs/check-group-codegen.ts (2)

54-77: doubleCheck and concurrency are still not emitted

The resource interface exposes doubleCheck and concurrency, but buildCheckGroupProps omits them, so the generated construct will silently ignore these settings.

   if (resource.muted !== undefined) {
     builder.boolean('muted', resource.muted)
   }

+  if (resource.doubleCheck !== undefined) {
+    builder.boolean('doubleCheck', resource.doubleCheck)
+  }
+
+  if (resource.concurrency !== undefined) {
+    builder.number('concurrency', resource.concurrency)
+  }

This was raised previously but remains unfixed.
[ duplicate_comment ]


257-257: Guard against undefined when emitting retryStrategy

When resource.retryStrategy is undefined this line writes retryStrategy: undefined, producing invalid TypeScript and breaking tsc.
Wrap the emission in a conditional:

-if (resource.retryStrategy !== undefined) {
-  builder.value('retryStrategy', valueForRetryStrategy(genfile, resource.retryStrategy))
-}
+if (resource.retryStrategy !== undefined) {
+  builder.value('retryStrategy', valueForRetryStrategy(genfile, resource.retryStrategy))
+}

[ duplicate_comment ]

Comment on lines +93 to +99
if (location.physicalId !== undefined && typeof location.physicalId === 'string') {
builder.value(valueForPrivateLocationFromId(file, location.physicalId))
continue
}

throw new Error(`Unable to generate configuration code for Private Location '${location.logicalId}'`)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add support for logical-ID private-location references

Similar to alert channels, this block only accepts a string physicalId. If users supply an object with logicalId, an exception is thrown, stopping config generation even though the location exists in the project graph.

Proposed approach:

  1. Look up the location in context when only logicalId is present.
  2. Fallback to the error if it truly cannot be resolved.
-        if (location.physicalId !== undefined && typeof location.physicalId === 'string') {
-          builder.value(valueForPrivateLocationFromId(file, location.physicalId))
-          continue
-        }
+        if (typeof location.physicalId === 'string') {
+          builder.value(valueForPrivateLocationFromId(file, location.physicalId))
+          continue
+        }
+
+        if (location.logicalId !== undefined) {
+          const id = context.lookupPrivateLocationId(location.logicalId)
+          if (id !== undefined) {
+            builder.value(valueForPrivateLocationFromId(file, id))
+            continue
+          }
+        }

This keeps the happy path seamless for users who work with logical identifiers.

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

🤖 Prompt for AI Agents
In packages/cli/src/services/checkly-config-codegen.ts around lines 93 to 99,
the code only handles private locations with a string physicalId and throws an
error if only a logicalId is provided. To fix this, add logic to check if
location.logicalId exists when physicalId is not a string, then look up the
corresponding location in the context using that logicalId. If the lookup
succeeds, generate the configuration code using the found location; otherwise,
throw the existing error. This will support logical-ID references without
breaking config generation.

@sorccu sorccu merged commit d12b1a4 into main May 15, 2025
4 checks passed
@sorccu sorccu deleted the simokinnunen/sc-23506/cli-import-existing-resources branch May 15, 2025 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Issue regarding building and packaging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants