Skip to content

Commit f897fea

Browse files
authored
fix(orchestrator): skip empty headers (#1229)
1 parent ae0ac74 commit f897fea

6 files changed

Lines changed: 37 additions & 4 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-orchestrator-form-widgets': patch
3+
---
4+
5+
If a fetch/validate body/headers field resolves to empty or undefined value, it is skipped from the HTTP request.

workspaces/orchestrator/docs/orchestratorFormWidgets.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,10 @@ Various selectors (like `fetch:response:*`) are processed by the [jsonata](https
446446
| ui:variant | So far specific for StaticText widget only. See [ActiveText props](#activetext-widget-uiprops) | |
447447
| ui:text | So far specific for StaticText widget only. Check the description there. See [ActiveText props](#activetext-widget-uiprops) | |
448448

449+
#### Specifics for templates in fetch:body, validate:body, fetch:headers or validate:headers
450+
451+
If a template for a field of one of those properties evaluates to just an empty or undefined value, the **field is skipped** from the HTTP request (body, headers).
452+
449453
### Authentication
450454

451455
To make the `identityApi` working, the [Backstage authentication](https://backstage.io/docs/auth/#sign-in-configuration) needs to be configured.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the for the specific language governing permissions and
14+
*/
15+
export const UNDEFINED_VALUE = '___undefined___';

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/evaluateTemplate.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ describe('evaluate template', () => {
7777

7878
it('can parse template template to units', async () => {
7979
const cases = [
80+
{ template: '', expected: '' },
8081
{ template: 'zz', expected: 'zz' },
8182
{ template: '}}', expected: '}}' },
8283
{ template: '${{foo}}', expected: '${{foo}}' },

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/evaluateTemplate.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { JsonObject, JsonPrimitive, JsonValue } from '@backstage/types';
1919
import { useTemplateUnitEvaluator } from './useTemplateUnitEvaluator';
2020
import { UiProps } from '../uiPropTypes';
2121
import { isJsonObject } from './applySelector';
22+
import { UNDEFINED_VALUE } from './constants';
2223

2324
export type evaluateTemplateProps = {
2425
template?: JsonValue;
@@ -82,7 +83,7 @@ export const evaluateTemplateString = async (
8283
uiProps,
8384
);
8485
if (evaluatedUnit === undefined) {
85-
evaluatedUnit = '___undefined___';
86+
evaluatedUnit = UNDEFINED_VALUE;
8687
}
8788

8889
if (

workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useRequestInit.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
evaluateTemplateString,
2323
} from './evaluateTemplate';
2424
import { useTemplateUnitEvaluator } from './useTemplateUnitEvaluator';
25+
import { UNDEFINED_VALUE } from './constants';
2526

2627
const ALLOWED_METHODS = ['GET', 'POST'];
2728

@@ -62,7 +63,10 @@ export const getRequestInit = async (
6263
),
6364
);
6465
keys.forEach((key, idx) => {
65-
evaluated[key] = values[idx];
66+
if (values[idx] && values[idx] !== UNDEFINED_VALUE) {
67+
// skip empty or undefined values
68+
evaluated[key] = values[idx];
69+
}
6670
});
6771

6872
const bodyInit: BodyInit = JSON.stringify(evaluated);
@@ -105,8 +109,11 @@ export const getRequestInit = async (
105109
keys.forEach((key, idx) => {
106110
// Header must be a string
107111
const value = values[idx];
108-
headersInit[key] =
109-
typeof value === 'string' ? value : JSON.stringify(value);
112+
if (value && value !== UNDEFINED_VALUE) {
113+
// skip empty or undefined values
114+
headersInit[key] =
115+
typeof value === 'string' ? value : JSON.stringify(value);
116+
}
110117
});
111118
} else {
112119
throw new Error('fetch:body must be object for POST requests');

0 commit comments

Comments
 (0)