Align with type declaration of template filter/global function by supporting undefined as return value.

Signed-off-by: Matt Benson <gudnabrsam@gmail.com>
This commit is contained in:
Matt Benson
2024-09-30 18:11:19 -05:00
parent 6c1ecf4576
commit e4f5d9596b
3 changed files with 20 additions and 6 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Align with type declaration of template filter/global function by supporting undefined as return value.
@@ -107,8 +107,9 @@ describe('SecureTemplater', () => {
const mockFilter1 = jest.fn(() => 'filtered text');
const mockFilter2 = jest.fn((var1, var2) => `${var1} ${var2}`);
const mockFilter3 = jest.fn((var1, var2) => ({ var1, var2 }));
const mockFilter4 = jest.fn(() => undefined);
const renderWith = await SecureTemplater.loadRenderer({
templateFilters: { mockFilter1, mockFilter2, mockFilter3 },
templateFilters: { mockFilter1, mockFilter2, mockFilter3, mockFilter4 },
});
const renderWithout = await SecureTemplater.loadRenderer();
@@ -131,6 +132,7 @@ describe('SecureTemplater', () => {
var2: 'another extra arg',
}),
);
expect(renderWith('${{ inputValue | mockFilter4 }}', ctx)).toBe('');
expect(() => renderWithout('${{ inputValue | mockFilter1 }}', ctx)).toThrow(
/Error: filter not found: mockFilter1/,
@@ -152,8 +154,9 @@ describe('SecureTemplater', () => {
const mockGlobal1 = jest.fn(() => 'awesome global function');
const mockGlobal2 = 'foo';
const mockGlobal3 = 123456;
const mockGlobal4 = jest.fn(() => undefined);
const renderWith = await SecureTemplater.loadRenderer({
templateGlobals: { mockGlobal1, mockGlobal2, mockGlobal3 },
templateGlobals: { mockGlobal1, mockGlobal2, mockGlobal3, mockGlobal4 },
});
const renderWithout = await SecureTemplater.loadRenderer();
@@ -164,6 +167,7 @@ describe('SecureTemplater', () => {
);
expect(renderWith('${{ mockGlobal2 }}', ctx)).toBe('foo');
expect(renderWith('${{ mockGlobal3 }}', ctx)).toBe('123456');
expect(renderWith('${{ mockGlobal4() }}', ctx)).toBe('');
expect(() => renderWithout('${{ mockGlobal1() }}', ctx)).toThrow(
/Error: Unable to call `mockGlobal1`/,
@@ -52,14 +52,17 @@ const { render, renderCompat } = (() => {
});
compatEnv.addFilter('jsonify', compatEnv.getFilter('dump'));
const handleFunctionResult = (value) => {
return value === '' ? undefined : JSON.parse(value);
};
for (const name of JSON.parse(availableTemplateFilters)) {
env.addFilter(name, (...args) => JSON.parse(callFilter(name, args)));
env.addFilter(name, (...args) => handleFunctionResult(callFilter(name, args)));
}
for (const [name, value] of Object.entries(JSON.parse(availableTemplateGlobals))) {
env.addGlobal(name, value);
}
for (const name of JSON.parse(availableTemplateCallbacks)) {
env.addGlobal(name, (...args) => JSON.parse(callGlobal(name, args)));
env.addGlobal(name, (...args) => handleFunctionResult(callGlobal(name, args)));
}
let uninstallCompat = undefined;
@@ -187,7 +190,8 @@ export class SecureTemplater {
if (!Object.hasOwn(templateFilters, filterName)) {
return '';
}
return JSON.stringify(templateFilters[filterName](...args));
const rz = templateFilters[filterName](...args);
return rz === undefined ? '' : JSON.stringify(rz);
},
);
@@ -201,7 +205,8 @@ export class SecureTemplater {
if (typeof global !== 'function') {
return '';
}
return JSON.stringify(global(...args));
const rz = global(...args);
return rz === undefined ? '' : JSON.stringify(rz);
},
);