Skip to content

feat: changes to incorporate oc schema updates - #6335

Merged
helloanoop merged 2 commits into
mainfrom
feature/oc-schema-updates
Dec 7, 2025
Merged

helloanoop merged 2 commits into
mainfrom
feature/oc-schema-updates

Conversation

@helloanoop

@helloanoop helloanoop commented Dec 7, 2025 •

Copy link
Copy Markdown
Contributor

Changes to incorporate opencollection schema updates

Summary by CodeRabbit

  • New Features

    • Support for secret environment variables (keeps secrets hidden and marks them disabled appropriately).
  • Enhancements / Refactor

    • Reorganized request data shapes across HTTP, GraphQL, gRPC, and WebSocket for more consistent metadata/runtime grouping.
    • Headers handling improved: preserves descriptions, supports response headers, and respects enabled/disabled flags.
    • Scripts representation normalized (array-based).
    • OAuth2 resource-owner-password flow identifier updated for compatibility.
    • YAML output formatting now inserts clearer blank-line block separation.

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

Copilot AI review requested due to automatic review settings December 7, 2025 00:05
@coderabbitai

coderabbitai Bot commented Dec 7, 2025 •

Copy link
Copy Markdown
Contributor

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Restructures OpenCollection YAML object shapes from flat properties to nested blocks (info, type-specific block, runtime) across request/folder serialization and parsing. Adds secret variable support, refines header types to HttpRequestHeader, refactors scripts to array form, tweaks YAML string formatting, and bumps a dev dependency.

Changes

Cohort / File(s) Summary
Dependency & OAuth2
packages/bruno-filestore/package.json, packages/bruno-filestore/src/formats/yml/common/auth-oauth2.ts
Bumped @opencollection/types devDependency to 0.2.0; changed OAuth2 resource owner password flow identifier to resource_owner_password_credentials.
Header types & response headers
packages/bruno-filestore/src/formats/yml/common/headers.ts, packages/bruno-filestore/src/formats/yml/stringifyCollection.ts, packages/bruno-filestore/src/formats/yml/stringifyFolder.ts
Replaced HttpHeader with HttpRequestHeader; toOpenCollectionHttpHeaders now returns HttpRequestHeader[]; added toOpenCollectionResponseHeaders; toBrunoHttpHeaders accepts request or response header types and derives enabled/disabled robustly.
Scripts refactor
packages/bruno-filestore/src/formats/yml/common/scripts.ts
Converted scripts representation to an array with explicit type entries (before-request, after-response, tests) and adjusted parsing/stringifying accordingly.
Parsing: requests & items
packages/bruno-filestore/src/formats/yml/items/parseHttpRequest.ts, .../parseGraphQLRequest.ts, .../parseGrpcRequest.ts, .../parseWebsocketRequest.ts, packages/bruno-filestore/src/formats/yml/parseItem.ts
Moved data extraction to nested info, request-type blocks (http/graphql/grpc/websocket) and runtime; use optional chaining/fallbacks; parseItem uses getItemType and typed dispatch; errors rethrown after logging.
Stringifying: requests & scripts
packages/bruno-filestore/src/formats/yml/items/stringifyHttpRequest.ts, .../stringifyGraphQLRequest.ts, .../stringifyGrpcRequest.ts, .../stringifyWebsocketRequest.ts, packages/bruno-filestore/src/formats/yml/items/stringifyScript.ts
Build nested info, request-type, and conditional runtime blocks instead of flat properties; move auth/scripts/variables into runtime; updated Script -> ScriptFile type imports.
Script parsing/type updates
packages/bruno-filestore/src/formats/yml/items/parseScript.ts, packages/bruno-filestore/src/formats/yml/items/stringifyScript.ts
Switched imported/used Script -> ScriptFile for script file types; updated function parameter typings accordingly.
Environment variable secret support
packages/bruno-filestore/src/formats/yml/parseEnvironment.ts, packages/bruno-filestore/src/formats/yml/stringifyEnvironment.ts
Parsing now accepts SecretVariable union and emits Bruno variables with secret: true and empty value; stringifier emits `(Variable
Folder & collection shape changes
packages/bruno-filestore/src/formats/yml/parseFolder.ts, packages/bruno-filestore/src/formats/yml/stringifyFolder.ts, packages/bruno-filestore/src/formats/yml/stringifyCollection.ts
Folder/collection objects now use info block for name/seq/type; headers typed as HttpRequestHeader[]; docs handling updated to accept string/object forms.
YAML formatting utility
packages/bruno-filestore/src/formats/yml/utils.ts
Added BLOCK_KEYS and post-processes YAML output to insert blank lines before top-level blocks for readability.
Type resolution
packages/bruno-filestore/tsconfig.json
Adjusted TS path mappings to resolve @opencollection/types from package-local node_modules dist paths.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay special attention to:
    • stringify/parse pairs for HTTP, GraphQL, gRPC, and WebSocket to ensure field round-trips and conditional runtime inclusion match.
    • Header conversions between request and response types and the enabled/disabled logic in toBrunoHttpHeaders.
    • Secret variable round-trip semantics (value omission, secret flag, disabled handling).
    • Script array transformation and mapping of type values to Bruno pre/post/tests slots.
    • YAML post-processing to ensure no accidental whitespace-sensitive changes to emitted YAML.

Suggested labels

size/XXL

Suggested reviewers

  • lohit-bruno
  • naman-bruno
  • bijin-bruno

Poem

✨ From flat fields into tidy blocks we go,

info, runtime, requests all in row.
Headers, secrets, scripts rearranged,
YAML breathes with gaps neatly exchanged,
A refactor waltz — compact, consistent, slow.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary purpose: incorporating OpenCollection schema updates across multiple files in the codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/oc-schema-updates

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a2cfd1 and 03ec2fa.

📒 Files selected for processing (1)
  • packages/bruno-filestore/tsconfig.json (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: CLI Tests
  • GitHub Check: Unit Tests
  • GitHub Check: Playwright E2E Tests
🔇 Additional comments (1)
packages/bruno-filestore/tsconfig.json (1)

25-26: Verify local node_modules resolution doesn't cause type conflicts.

The @opencollection/types paths now resolve from local node_modules, while @usebruno/schema-types still uses workspace packages. This inconsistency could cause issues if @opencollection/types is also installed in the workspace node_modules, resulting in duplicate type definitions.

Confirm that:

  1. @opencollection/types is only installed in packages/bruno-filestore/node_modules/, not in workspace node_modules/
  2. Type resolution doesn't cause conflicts or duplicate type identity issues
  3. This local-only pattern is intentional (per the AI summary mentioning devDependency bumps)

If the pattern is intentional but @opencollection/types needs to be shared across multiple packages, consider aligning with the @usebruno/schema-types pattern (workspace-wide resolution from packages/ instead of local node_modules).


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

@github-actions

github-actions Bot commented Dec 7, 2025 •

Copy link
Copy Markdown

CLI Test Results

  1 files  ±0  140 suites  ±0   47s ⏱️ -34s
234 tests ±0  234 ✅ ±0  0 💤 ±0  0 ❌ ±0 
300 runs  ±0  299 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit 03ec2fa. ± Comparison against base commit 4ffb447.

♻️ This comment has been updated with latest results.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This pull request updates the bruno-filestore package to align with OpenCollection schema version 0.2.0, implementing significant structural changes to how requests, folders, and other entities are serialized and deserialized.

Key changes include:

  • Restructuring request types to use nested blocks (info, http/graphql/grpc/websocket, runtime) instead of flat properties
  • Converting Scripts from object format to array format with typed script entries
  • Updating type names (HttpHeader → HttpRequestHeader/HttpResponseHeader, Script → ScriptFile) to be more specific
  • Enhancing secret variable handling with dedicated SecretVariable type
  • Correcting OAuth2 flow naming (resource_owner_password → resource_owner_password_credentials)

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/bruno-filestore/src/formats/yml/utils.ts Adds YAML formatting logic to insert blank lines before major top-level blocks for better readability
packages/bruno-filestore/src/formats/yml/stringifyFolder.ts Restructures folder serialization to use info block; updates header type to HttpRequestHeader
packages/bruno-filestore/src/formats/yml/stringifyEnvironment.ts Updates environment variable handling to support SecretVariable type; fixes typo in comment ("neither" instead of "neithwe")
packages/bruno-filestore/src/formats/yml/stringifyCollection.ts Updates header type from HttpHeader to HttpRequestHeader
packages/bruno-filestore/src/formats/yml/parseItem.ts Adds getItemType helper to extract type from info block; updates type imports and casting
packages/bruno-filestore/src/formats/yml/parseFolder.ts Updates folder parsing to extract metadata from info block; enhances docs parsing to handle both string and object formats
packages/bruno-filestore/src/formats/yml/parseEnvironment.ts Adds SecretVariable support with type guard; updates variable parsing to handle secret variables
packages/bruno-filestore/src/formats/yml/items/stringifyWebsocketRequest.ts Restructures WebSocket requests into info, websocket, and runtime blocks; updates header type
packages/bruno-filestore/src/formats/yml/items/stringifyScript.ts Renames Script type to ScriptFile
packages/bruno-filestore/src/formats/yml/items/stringifyHttpRequest.ts Restructures HTTP requests into info, http, and runtime blocks; separates request and response header handling
packages/bruno-filestore/src/formats/yml/items/stringifyGrpcRequest.ts Restructures gRPC requests into info, grpc, and runtime blocks
packages/bruno-filestore/src/formats/yml/items/stringifyGraphQLRequest.ts Restructures GraphQL requests into info, graphql, and runtime blocks
packages/bruno-filestore/src/formats/yml/items/parseWebsocketRequest.ts Updates WebSocket request parsing to extract data from info, websocket, and runtime blocks
packages/bruno-filestore/src/formats/yml/items/parseScript.ts Updates to use ScriptFile type
packages/bruno-filestore/src/formats/yml/items/parseHttpRequest.ts Updates HTTP request parsing to extract data from info, http, and runtime blocks
packages/bruno-filestore/src/formats/yml/items/parseGrpcRequest.ts Updates gRPC request parsing to extract data from info, grpc, and runtime blocks
packages/bruno-filestore/src/formats/yml/items/parseGraphQLRequest.ts Updates GraphQL request parsing to extract data from info, graphql, and runtime blocks
packages/bruno-filestore/src/formats/yml/common/scripts.ts Converts Scripts from object to array format with typed entries (before-request, after-response, tests)
packages/bruno-filestore/src/formats/yml/common/headers.ts Splits HttpHeader into HttpRequestHeader and HttpResponseHeader types; adds separate conversion functions
packages/bruno-filestore/src/formats/yml/common/auth-oauth2.ts Updates OAuth2 flow name from resource_owner_password to resource_owner_password_credentials
packages/bruno-filestore/package.json Updates @opencollection/types dependency from 0.1.0 to 0.2.0
package-lock.json Updates lockfile to reflect new @opencollection/types version

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

enabled: header.disabled !== true
enabled: ('disabled' in header) ? header.disabled !== true : true
};

Copilot AI Dec 7, 2025

Copy link

Choose a reason for hiding this comment

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

The toBrunoHttpHeaders function doesn't preserve the description field when converting from HttpRequestHeader to BrunoKeyValue. HttpRequestHeader can have an optional description field that should be mapped to BrunoKeyValue's description field when present (similar to how toOpenCollectionHttpHeaders handles it on line 16-18).

Suggested change
if ('description' in header && typeof header.description === 'string' && header.description.trim().length) {
brunoHeader.description = header.description;
}

Copilot uses AI. Check for mistakes.
Comment on lines +13 to 15
// todo: currently neither bru lang nor bruno app supports non-string values
// update this when bruno app supports non-string values
return typeof v.value === 'string';

Copilot AI Dec 7, 2025

Copy link

Choose a reason for hiding this comment

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

The filter on line 12-15 filters out variables where typeof v.value !== 'string'. However, for secret variables (v.secret === true), the value may not be a string or may be undefined/empty. This will incorrectly filter out secret variables. The filter should allow secret variables to pass through regardless of their value type, since SecretVariable doesn't include the value property.

Suggested change
// todo: currently neither bru lang nor bruno app supports non-string values
// update this when bruno app supports non-string values
return typeof v.value === 'string';
// Allow secret variables regardless of value type; non-secret must have string value
return v.secret === true || typeof v.value === 'string';

Copilot uses AI. Check for mistakes.
headers: toBrunoHttpHeaders(http?.headers) || [],
params: toBrunoParams(http?.params) || [],
auth: toBrunoAuth(runtime?.auth),
body: toBrunoBody(http?.body as HttpRequestBody) || {

Copilot AI Dec 7, 2025

Copy link

Choose a reason for hiding this comment

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

This call to toBrunoBody always evaluates to true.

Copilot uses AI. Check for mistakes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (9)
packages/bruno-filestore/src/formats/yml/parseEnvironment.ts (2)

7-9: Simplify the type guard check.

The 'secret' in v check is redundant if SecretVariable strictly defines the secret property. TypeScript's type narrowing will work with just v.secret === true when using union types.

Apply this diff to simplify:

-const isSecretVariable = (v: Variable | SecretVariable): v is SecretVariable => {
-  return 'secret' in v && v.secret === true;
-};
+const isSecretVariable = (v: Variable | SecretVariable): v is SecretVariable => {
+  return v.secret === true;
+};

30-30: Remove redundant fallback operator.

The ternary expression already returns '' when v.value is not a string, making the trailing || '' redundant.

Apply this diff:

-      value: (typeof v.value === 'string' ? v.value : '') || '',
+      value: typeof v.value === 'string' ? v.value : '',
packages/bruno-filestore/src/formats/yml/common/scripts.ts (2)

1-1: Unused type import.

Script is imported but not referenced in this file. Consider removing it to keep imports clean.

-import type { Scripts, Script } from '@opencollection/types/common/scripts';
+import type { Scripts } from '@opencollection/types/common/scripts';

45-61: Consider using else if for mutually exclusive type checks.

The current structure uses separate if statements, but since each script entry has a single type, else if would be more semantically correct and marginally more efficient.

   for (const script of scripts) {
     if (script.type === 'before-request' && script.code) {
       if (!brunoScripts.script) {
         brunoScripts.script = {};
       }
       brunoScripts.script.req = script.code;
-    }
-    if (script.type === 'after-response' && script.code) {
+    } else if (script.type === 'after-response' && script.code) {
       if (!brunoScripts.script) {
         brunoScripts.script = {};
       }
       brunoScripts.script.res = script.code;
-    }
-    if (script.type === 'tests' && script.code) {
+    } else if (script.type === 'tests' && script.code) {
       brunoScripts.tests = script.code;
     }
   }
packages/bruno-filestore/src/formats/yml/items/stringifyWebsocketRequest.ts (2)

52-67: Minor: Redundant length check on messages.

Line 52 already checks brunoRequest.body.ws?.length, so the inner if (messages.length) on line 57 is always true when reached.

     if (brunoRequest.body?.mode === 'ws' && brunoRequest.body.ws?.length) {
       const messages = brunoRequest.body.ws;

-      // todo: bruno app supports only one message for now
-      // update this when bruno app supports multiple messages
-      if (messages.length) {
-        const msg = messages[0];
+      // todo: bruno app supports only one message for now
+      // update this when bruno app supports multiple messages
+      const msg = messages[0];
+      if (msg) {
         const message: WebSocketMessage = {
           type: (msg.type as 'text' | 'json' | 'xml' | 'binary') || 'text',
           data: msg.content || ''
         };
         if (message.data.trim().length) {
           websocket.message = message;
         }
       }
     }

100-108: Settings always attached, even when wsSettings is undefined.

Unlike the runtime block which is conditionally attached, settings creates an empty block at line 103 even if wsSettings is undefined. Consider adding a guard or only attaching when meaningful values exist.

     // settings
     const wsSettings = item.settings as Record<string, number | string | undefined> | undefined;
     if (wsSettings) {
-      ocRequest.settings = {};
-      const timeout = Number(wsSettings.timeout);
-      ocRequest.settings.timeout = !isNaN(timeout) ? timeout : 0;
-      const keepAliveInterval = Number(wsSettings.keepAliveInterval);
-      ocRequest.settings.keepAliveInterval = !isNaN(keepAliveInterval) ? keepAliveInterval : 0;
+      const timeout = Number(wsSettings.timeout);
+      const keepAliveInterval = Number(wsSettings.keepAliveInterval);
+      ocRequest.settings = {
+        timeout: !isNaN(timeout) ? timeout : 0,
+        keepAliveInterval: !isNaN(keepAliveInterval) ? keepAliveInterval : 0
+      };
     }
packages/bruno-filestore/src/formats/yml/items/stringifyGraphQLRequest.ts (1)

112-145: Settings block is always attached unconditionally.

Unlike the runtime block, this always attaches ocRequest.settings with default values. This is intentional behavior but differs from WebSocket which conditionally attaches settings. Verify this is the desired schema behavior.

Also, consider simplifying the encodeUrl and followRedirects logic:

     // settings
     const httpSettings = item.settings as BrunoHttpItemSettings | undefined;
-    const settings: GraphQLRequestSettings = {};
-    if (httpSettings?.encodeUrl === true) {
-      settings.encodeUrl = true;
-    } else if (httpSettings?.encodeUrl === false) {
-      settings.encodeUrl = false;
-    } else {
-      settings.encodeUrl = true;
-    }
+    const settings: GraphQLRequestSettings = {
+      encodeUrl: httpSettings?.encodeUrl ?? true,
+      timeout: isNumber(httpSettings?.timeout) ? httpSettings.timeout : 0,
+      followRedirects: httpSettings?.followRedirects ?? true,
+      maxRedirects: isNumber(httpSettings?.maxRedirects) ? httpSettings.maxRedirects : 5
+    };

-    const timeout = httpSettings?.timeout;
-    if (isNumber(timeout)) {
-      settings.timeout = timeout;
-    } else {
-      settings.timeout = 0;
-    }
-
-    if (httpSettings?.followRedirects === true) {
-      settings.followRedirects = true;
-    } else if (httpSettings?.followRedirects === false) {
-      settings.followRedirects = false;
-    } else {
-      settings.followRedirects = true;
-    }
-
-    const maxRedirects = httpSettings?.maxRedirects;
-    if (isNumber(maxRedirects)) {
-      settings.maxRedirects = maxRedirects;
-    } else {
-      settings.maxRedirects = 5;
-    }
-
     ocRequest.settings = settings;
packages/bruno-filestore/src/formats/yml/parseFolder.ts (2)

14-20: Confirm backward compatibility when moving meta to info

Reading name/seq exclusively from ocFolder.info keeps defaults intact, but any legacy folders that only had top-level name/seq will now resolve to 'Untitled Folder' and 1. If you still need to parse older flat schemas, consider adding a fallback from the old locations when info is missing so existing data retains its title and ordering.


72-78: Harden docs parsing and reuse isNonEmptyString

The new root-level docs handling looks good, but ocFolder.docs.content?.trim() assumes content is always a string. If the shape ever widens, that could throw at runtime. You already import isNonEmptyString; using it here both tightens the guard and centralizes the “non-empty string” logic:

-    // docs (now at root level)
-    if (ocFolder.docs) {
-      if (typeof ocFolder.docs === 'string' && ocFolder.docs.trim().length) {
-        folderRoot.docs = ocFolder.docs;
-      } else if (typeof ocFolder.docs === 'object' && ocFolder.docs.content?.trim().length) {
-        folderRoot.docs = ocFolder.docs.content;
-      }
-    }
+    // docs (now at root level)
+    if (ocFolder.docs) {
+      if (typeof ocFolder.docs === 'string' && isNonEmptyString(ocFolder.docs)) {
+        folderRoot.docs = ocFolder.docs;
+      } else if (typeof ocFolder.docs === 'object' && isNonEmptyString(ocFolder.docs.content)) {
+        folderRoot.docs = ocFolder.docs.content;
+      }
+    }

This keeps behavior the same for valid inputs while avoiding assumptions about content being a string.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ffb447 and 8a2cfd1.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (21)
  • packages/bruno-filestore/package.json (1 hunks)
  • packages/bruno-filestore/src/formats/yml/common/auth-oauth2.ts (2 hunks)
  • packages/bruno-filestore/src/formats/yml/common/headers.ts (2 hunks)
  • packages/bruno-filestore/src/formats/yml/common/scripts.ts (2 hunks)
  • packages/bruno-filestore/src/formats/yml/items/parseGraphQLRequest.ts (5 hunks)
  • packages/bruno-filestore/src/formats/yml/items/parseGrpcRequest.ts (4 hunks)
  • packages/bruno-filestore/src/formats/yml/items/parseHttpRequest.ts (4 hunks)
  • packages/bruno-filestore/src/formats/yml/items/parseScript.ts (1 hunks)
  • packages/bruno-filestore/src/formats/yml/items/parseWebsocketRequest.ts (5 hunks)
  • packages/bruno-filestore/src/formats/yml/items/stringifyGraphQLRequest.ts (3 hunks)
  • packages/bruno-filestore/src/formats/yml/items/stringifyGrpcRequest.ts (4 hunks)
  • packages/bruno-filestore/src/formats/yml/items/stringifyHttpRequest.ts (4 hunks)
  • packages/bruno-filestore/src/formats/yml/items/stringifyScript.ts (1 hunks)
  • packages/bruno-filestore/src/formats/yml/items/stringifyWebsocketRequest.ts (4 hunks)
  • packages/bruno-filestore/src/formats/yml/parseEnvironment.ts (1 hunks)
  • packages/bruno-filestore/src/formats/yml/parseFolder.ts (2 hunks)
  • packages/bruno-filestore/src/formats/yml/parseItem.ts (1 hunks)
  • packages/bruno-filestore/src/formats/yml/stringifyCollection.ts (2 hunks)
  • packages/bruno-filestore/src/formats/yml/stringifyEnvironment.ts (1 hunks)
  • packages/bruno-filestore/src/formats/yml/stringifyFolder.ts (2 hunks)
  • packages/bruno-filestore/src/formats/yml/utils.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-filestore/src/formats/yml/items/parseGrpcRequest.ts
  • packages/bruno-filestore/src/formats/yml/items/stringifyScript.ts
  • packages/bruno-filestore/src/formats/yml/stringifyCollection.ts
  • packages/bruno-filestore/src/formats/yml/items/stringifyGraphQLRequest.ts
  • packages/bruno-filestore/src/formats/yml/utils.ts
  • packages/bruno-filestore/src/formats/yml/common/auth-oauth2.ts
  • packages/bruno-filestore/src/formats/yml/stringifyEnvironment.ts
  • packages/bruno-filestore/src/formats/yml/parseFolder.ts
  • packages/bruno-filestore/src/formats/yml/items/parseWebsocketRequest.ts
  • packages/bruno-filestore/src/formats/yml/items/parseGraphQLRequest.ts
  • packages/bruno-filestore/src/formats/yml/parseItem.ts
  • packages/bruno-filestore/src/formats/yml/items/stringifyWebsocketRequest.ts
  • packages/bruno-filestore/src/formats/yml/items/stringifyGrpcRequest.ts
  • packages/bruno-filestore/src/formats/yml/items/parseScript.ts
  • packages/bruno-filestore/src/formats/yml/parseEnvironment.ts
  • packages/bruno-filestore/src/formats/yml/common/headers.ts
  • packages/bruno-filestore/src/formats/yml/common/scripts.ts
  • packages/bruno-filestore/src/formats/yml/items/stringifyHttpRequest.ts
  • packages/bruno-filestore/src/formats/yml/items/parseHttpRequest.ts
  • packages/bruno-filestore/src/formats/yml/stringifyFolder.ts
🧠 Learnings (2)
📚 Learning: 2025-12-02T07:24:50.299Z
Learnt from: bijin-bruno
Repo: usebruno/bruno PR: 6263
File: packages/bruno-requests/src/auth/oauth2-helper.ts:249-249
Timestamp: 2025-12-02T07:24:50.299Z
Learning: In OAuth2 Basic Auth headers for Bruno, clientSecret is optional and can be omitted. When constructing the Authorization header in `packages/bruno-requests/src/auth/oauth2-helper.ts`, use `clientSecret || ''` instead of `clientSecret!` to properly handle cases where only clientId is provided, per community requests.

Applied to files:

  • packages/bruno-filestore/src/formats/yml/items/parseGrpcRequest.ts
  • packages/bruno-filestore/src/formats/yml/stringifyCollection.ts
  • packages/bruno-filestore/src/formats/yml/items/stringifyGraphQLRequest.ts
  • packages/bruno-filestore/src/formats/yml/common/auth-oauth2.ts
  • packages/bruno-filestore/src/formats/yml/items/stringifyGrpcRequest.ts
  • packages/bruno-filestore/src/formats/yml/common/headers.ts
📚 Learning: 2025-12-03T06:32:11.721Z
Learnt from: sanish-bruno
Repo: usebruno/bruno PR: 6090
File: packages/bruno-js/src/runtime/hooks-runtime.js:8-135
Timestamp: 2025-12-03T06:32:11.721Z
Learning: vm2 runtime is being removed from the Bruno application and QuickJS will become the default runtime for script execution.

Applied to files:

  • packages/bruno-filestore/src/formats/yml/items/parseWebsocketRequest.ts
  • packages/bruno-filestore/src/formats/yml/items/parseGraphQLRequest.ts
  • packages/bruno-filestore/src/formats/yml/items/parseHttpRequest.ts
🧬 Code graph analysis (6)
packages/bruno-filestore/src/formats/yml/items/parseGrpcRequest.ts (4)
packages/bruno-filestore/src/formats/yml/common/auth.ts (1)
  • toBrunoAuth (150-245)
packages/bruno-filestore/src/formats/yml/common/scripts.ts (1)
  • toBrunoScripts (32-64)
packages/bruno-filestore/src/formats/yml/common/variables.ts (1)
  • toBrunoVariables (48-83)
packages/bruno-filestore/src/formats/yml/common/assertions.ts (1)
  • toBrunoAssertions (115-146)
packages/bruno-filestore/src/formats/yml/stringifyCollection.ts (1)
packages/bruno-filestore/src/formats/yml/common/headers.ts (1)
  • toOpenCollectionHttpHeaders (6-26)
packages/bruno-filestore/src/formats/yml/items/stringifyGraphQLRequest.ts (7)
packages/bruno-filestore/src/utils/index.ts (2)
  • isNonEmptyString (7-7)
  • isNumber (5-5)
packages/bruno-filestore/src/formats/yml/common/headers.ts (1)
  • toOpenCollectionHttpHeaders (6-26)
packages/bruno-filestore/src/formats/yml/common/params.ts (1)
  • toOpenCollectionParams (5-29)
packages/bruno-filestore/src/formats/yml/common/variables.ts (1)
  • toOpenCollectionVariables (6-46)
packages/bruno-filestore/src/formats/yml/common/scripts.ts (1)
  • toOpenCollectionScripts (7-30)
packages/bruno-filestore/src/formats/yml/common/assertions.ts (1)
  • toOpenCollectionAssertions (87-113)
packages/bruno-filestore/src/formats/yml/common/auth.ts (1)
  • toOpenCollectionAuth (118-148)
packages/bruno-filestore/src/formats/yml/parseFolder.ts (1)
packages/bruno-schema-types/src/collection/folder.ts (1)
  • FolderRoot (19-23)
packages/bruno-filestore/src/formats/yml/items/parseWebsocketRequest.ts (5)
packages/bruno-filestore/src/formats/yml/common/headers.ts (1)
  • toBrunoHttpHeaders (41-58)
packages/bruno-filestore/src/formats/yml/common/auth.ts (1)
  • toBrunoAuth (150-245)
packages/bruno-schema-types/src/requests/websocket.ts (1)
  • WebSocketMessage (3-7)
packages/bruno-filestore/src/formats/yml/common/scripts.ts (1)
  • toBrunoScripts (32-64)
packages/bruno-filestore/src/formats/yml/common/variables.ts (1)
  • toBrunoVariables (48-83)
packages/bruno-filestore/src/formats/yml/common/headers.ts (1)
packages/bruno-filestore/src/utils/index.ts (1)
  • uuid (9-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Agent
  • GitHub Check: CLI Tests
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: Unit Tests
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
🔇 Additional comments (44)
packages/bruno-filestore/src/formats/yml/parseEnvironment.ts (2)

17-26: LGTM! Intentional security design for secret variables.

Setting value to an empty string for secret variables is the correct approach—secret values should not be persisted in the Bruno format, only metadata is preserved.


33-33: Good practice: explicit secret: false for non-secret variables.

Explicitly setting secret: false improves clarity and ensures consistent structure across all variable types.

packages/bruno-filestore/src/formats/yml/stringifyEnvironment.ts (2)

18-27: LGTM! Correct secret variable serialization.

Secret variables are properly serialized with only name and secret metadata—no value field is included. This mirrors the parsing logic in parseEnvironment.ts and maintains the security posture of not persisting secret values to disk.


6-6: Type signatures correctly updated for secret variable support.

The function signature and return types properly reflect the union (Variable | SecretVariable)[], ensuring type safety for the new secret variable handling.

Also applies to: 11-11, 17-17

packages/bruno-filestore/src/formats/yml/utils.ts (2)

3-4: LGTM! Well-defined block keys for enhanced YAML readability.

The constant clearly defines which top-level keys should have preceding blank lines, improving the structure of generated YAML files for the OpenCollection schema.


6-34: LGTM! Solid implementation of blank-line formatting.

The post-processing logic correctly identifies top-level keys and adds blank lines before major blocks while avoiding duplicates. The implementation handles edge cases appropriately (empty lines, comments, lines without colons) and maintains the original YAML structure.

packages/bruno-filestore/package.json (1)

25-25: LGTM!

The dependency version update from 0.1.0 to 0.2.0 enables the new type system used throughout this PR. The changes are well-coordinated across all affected files.

packages/bruno-filestore/src/formats/yml/items/parseScript.ts (1)

2-2: LGTM!

The type update from Script to ScriptFile aligns with the new schema in @opencollection/types 0.2.0. The change is consistent with the corresponding update in stringifyScript.ts.

Also applies to: 5-5

packages/bruno-filestore/src/formats/yml/stringifyCollection.ts (1)

3-3: LGTM!

The type refinement from HttpHeader to HttpRequestHeader improves type precision and aligns with the updated return type of toOpenCollectionHttpHeaders. This change is consistent with the header handling updates across the codebase.

Also applies to: 131-131

packages/bruno-filestore/src/formats/yml/items/stringifyScript.ts (1)

2-2: LGTM!

The type update to ScriptFile maintains round-trip consistency with parseScript.ts. The implementation correctly sets type: 'script' and populates the script content from item.fileContent.

Also applies to: 7-9

packages/bruno-filestore/src/formats/yml/common/auth-oauth2.ts (1)

166-166: LGTM!

The OAuth2 flow rename from resource_owner_password to resource_owner_password_credentials normalizes the terminology to match RFC 6749. Both forward and reverse mappings are updated consistently, maintaining proper round-trip conversion with Bruno's internal password grant type.

Also applies to: 397-398

packages/bruno-filestore/src/formats/yml/items/parseGrpcRequest.ts (4)

31-34: LGTM!

The introduction of local aliases (info, grpc, runtime) for the nested structure is clean and improves readability. This aligns with the broader schema refactoring to separate metadata, protocol-specific data, and runtime configuration.


36-41: LGTM!

The field mappings from the nested structure are well-implemented with proper optional chaining and sensible defaults. This ensures backward compatibility while adopting the new schema.


60-64: LGTM!

The nested data access patterns for message, scripts, variables, and assertions are consistent and properly guarded with optional chaining. The fallback logic preserves existing behavior.

Also applies to: 68-89


100-102: LGTM!

The item metadata extraction from info with appropriate defaults (seq: 1, name: 'Untitled Request', tags: []) ensures robustness when optional fields are missing.

packages/bruno-filestore/src/formats/yml/items/parseGraphQLRequest.ts (3)

13-16: LGTM!

The nested structure aliases are consistent with the pattern established in parseGrpcRequest.ts, maintaining uniformity across the codebase.


18-22: LGTM!

The field mappings correctly source data from the nested graphql block. The type assertion for GraphQLBody on lines 32-33 is appropriate given the body mode check and aligns with the GraphQL request schema.

Also applies to: 32-34


51-72: LGTM!

The runtime data extraction (scripts, variables, assertions) and metadata handling maintain the same robust pattern with optional chaining and sensible defaults seen in other parse functions.

Also applies to: 83-85

packages/bruno-filestore/src/formats/yml/items/parseWebsocketRequest.ts (3)

18-21: LGTM!

The nested structure pattern is consistently applied, using websocket for protocol-specific data alongside info and runtime blocks.


23-25: LGTM!

The field mappings and message handling correctly source data from the nested websocket block. The type assertion for WebSocketMessage on line 45 is appropriate and the message data extraction with default type 'text' is well-implemented.

Also applies to: 44-53


56-71: LGTM!

The runtime data extraction and metadata handling maintain consistency with the patterns established in the GraphQL and gRPC parsers. The fallback values ensure robustness.

Also applies to: 97-99

packages/bruno-filestore/src/formats/yml/parseItem.ts (2)

14-24: LGTM on the getItemType helper.

Clean extraction logic that handles both the new nested info.type structure and the legacy root-level type for ScriptFile. The type guard pattern is appropriate.


35-49: Type assertions are acceptable given the validated itemType.

The switch-case logic validates the type string before casting, so each as cast is safe. Structure is consistent across request types.

packages/bruno-filestore/src/formats/yml/items/stringifyGrpcRequest.ts (2)

18-32: Good restructuring to nested blocks.

The info block pattern with conditional seq and tags is clean and consistent with the new schema. Default handling for name is appropriate.


90-124: Runtime block conditional attachment is well implemented.

The hasRuntime flag pattern prevents emitting an empty runtime object. Each field properly sets the flag when populated.

packages/bruno-filestore/src/formats/yml/items/parseHttpRequest.ts (2)

14-46: Clean migration to nested structure extraction.

Proper use of optional chaining with sensible defaults. The expanded body default structure aligns with the Bruno schema requirements.


77-92: Extended brunoItem initialization looks correct.

New fields (root, items, examples, filename, pathname) are initialized appropriately. Info block extraction for seq, name, and tags with fallbacks is solid.

packages/bruno-filestore/src/formats/yml/stringifyFolder.ts (2)

35-43: Folder info block aligns with the new schema structure.

Consistent pattern with request info blocks. Default fallbacks for name and seq are appropriate.


82-88: Good docs handling with content type metadata.

Wrapping docs content with type: 'text/markdown' provides proper content type information for consumers.

packages/bruno-filestore/src/formats/yml/common/headers.ts (2)

28-39: New toOpenCollectionResponseHeaders helper is well-structured.

Response headers correctly omit the disabled field since response headers don't have enable/disable state. Good separation of concerns.


41-55: Robust enabled flag derivation.

The 'disabled' in header check correctly handles the union type, defaulting to enabled: true when the property doesn't exist (response headers case).

packages/bruno-filestore/src/formats/yml/items/stringifyHttpRequest.ts (4)

24-35: Info block construction is consistent with other request types.

Proper handling of optional seq and tags fields. Name defaults to 'Untitled Request' when absent.


63-97: Runtime block pattern matches gRPC implementation.

The hasRuntime flag approach is consistent across request types. Auth inclusion in runtime aligns with the schema changes.


176-179: Correct use of toOpenCollectionResponseHeaders for example responses.

Response headers properly use the new helper that omits the disabled field.


99-132: Settings are always emitted, unlike runtime.

The runtime block is conditionally assigned only when hasRuntime is true, but settings are always constructed with defaults and unconditionally assigned to ocRequest.settings. This pattern is consistent across stringify functions (both stringifyHttpRequest.ts and stringifyGraphQLRequest.ts follow the same approach). This appears to be intentional—settings require explicit defaults even when user-provided values are absent, whereas the runtime block is optional.

packages/bruno-filestore/src/formats/yml/items/stringifyWebsocketRequest.ts (4)

22-38: LGTM - Info block construction is clean.

Proper fallback to 'Untitled Request' for empty names, and conditional inclusion of seq and tags follows best practices for avoiding empty fields in the output.


40-69: LGTM - WebSocket block handles URL, headers, and message appropriately.

Good conditional checks before assigning headers and message to avoid empty arrays/objects in output.


71-98: LGTM - Runtime block with conditional attachment.

Using hasRuntime flag to only attach the runtime block when it has content is a good pattern for keeping output clean.


110-118: LGTM - Docs and error handling are appropriate.

Docs are conditionally added, and the catch block properly logs and rethrows for upstream handling.

packages/bruno-filestore/src/formats/yml/items/stringifyGraphQLRequest.ts (5)

18-34: LGTM - Info block follows the same pattern as WebSocket.

Consistent handling of name, type, seq, and tags with proper fallbacks.


36-74: LGTM - GraphQL block construction is well-structured.

Proper conditional inclusion of headers, params, and body. The hasBody flag ensures we don't emit an empty body object.


76-110: LGTM - Runtime block pattern consistent with WebSocket.

Variables, scripts, assertions, and auth all conditionally added with the hasRuntime guard.


147-156: LGTM - Docs and error handling.

Consistent with WebSocket stringify.


36-40: Type compatibility is correct; no changes needed.

brunoRequest.method is properly narrowed to a string by the isNonEmptyString type guard, and the ternary operator always returns a string (either the narrowed method or the 'POST' literal). With strict TypeScript checking enabled in the project, any actual type incompatibility would be caught at build time. The code compiles and runs without errors.

Likely an incorrect or invalid review comment.

@helloanoop
helloanoop merged commit facdf32 into main Dec 7, 2025
9 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Dec 8, 2025
5 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Jan 22, 2026
6 tasks
maxenceleblanc pushed a commit to maxenceleblanc/curly_cats2 that referenced this pull request Jul 20, 2026
* feat: changes to incorporate oc schema updates
* chore: fixed oc types resolution issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants