Skip to content

Conversation

@chcederquist
Copy link
Contributor

…e not being merged

Fixes #2546

@melloware
Copy link
Collaborator

GitHub Copilot Chat Assistant

Replace the existing fragile string-manipulation block with the following safe, spread-based implementation:

const fetchMethodOption = `method: '${verb.toUpperCase()}'`;
const ignoreContentTypes = ['multipart/form-data'];

// Build global fetch options and header merging safely without fragile string slicing
let globalFetchOptions = '';
let fetchHeadersOption = '';

if (isObject(override.requestOptions)) {
  const stringifiedOverrideRequestOptions = stringify(override.requestOptions)?.trim();
  // Spread the whole override.requestOptions first. An explicit headers: { ... } entry added below
  // will override any headers property from the spread (so we don't need to remove headers here).
  const overrideOptionsSpread = stringifiedOverrideRequestOptions ? `...${stringifiedOverrideRequestOptions},` : '';

  const headerFragments: string[] = [];
  if (isObject(override.requestOptions.headers)) {
    const stringifiedOverrideHeaders = stringify(override.requestOptions.headers)?.trim();
    if (stringifiedOverrideHeaders) {
      // include as a spread of the literal object, e.g. ...{ a: 1 }
      headerFragments.push(`...${stringifiedOverrideHeaders}`);
    }
  }
  if (headers) headerFragments.push('...headers');
  if (isRequestOptions) headerFragments.push('...options?.headers');

  fetchHeadersOption = headerFragments.length > 0 ? `headers: { ${headerFragments.join(', ')} }` : '';
  // Put the override spread into globalFetchOptions (it may include many top-level options).
  // Note: trailing comma included to make concatenation in the template simpler.
  globalFetchOptions = overrideOptionsSpread;
} else {
  const headerFragments: string[] = [];
  if (headers) headerFragments.push('...headers');
  if (isRequestOptions) headerFragments.push('...options?.headers');
  fetchHeadersOption = headerFragments.length > 0 ? `headers: { ${headerFragments.join(', ')} }` : '';
  globalFetchOptions = '';
}

Notes:

  • This avoids slicing stringified JSON. We use object spreads in the generated output so header merging is explicit and deterministic.
  • The generated options object should spread globalFetchOptions first, then include the explicit headers (fetchHeadersOption) afterwards so the headers merge/order is clear and predictable.
  • If you need the opposite precedence (runtime options override override.requestOptions), swap the order where you place the spreads in the generated template.

@chcederquist
Copy link
Contributor Author

@melloware I've refactored the slice-trim-slice statement and made the global fetch options header the first part of the headers when merging.

@melloware melloware merged commit a5794ec into orval-labs:master Nov 13, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multiple header properties when adding headers in override.requestOptions

2 participants