Add new encoding type to template tag args

This commit is contained in:
Gregory Schier 2019-05-08 13:36:55 -04:00
parent f48a6469aa
commit 7c63132a85
4 changed files with 69 additions and 6 deletions

View File

@ -158,3 +158,24 @@ describe('unTokenizeTag()', () => {
expect(result).toEqual(`{% name 'foo/bar/baz', 'foo' %}`);
});
});
describe('encodeEncoding()', () => {
beforeEach(globalBeforeEach);
it('encodes things', () => {
expect(utils.encodeEncoding('hello', 'base64')).toBe('b64::aGVsbG8=::46b');
expect(utils.encodeEncoding(null, 'base64')).toBe(null);
expect(utils.encodeEncoding('hello', 'unknown')).toBe('hello');
expect(utils.encodeEncoding('hello')).toBe('hello');
expect(utils.encodeEncoding('hello', 'utf8')).toBe('hello');
});
});
describe('decodeEncoding()', () => {
beforeEach(globalBeforeEach);
it('encodes things', () => {
expect(utils.decodeEncoding('b64::aGVsbG8=::46b')).toBe('hello');
expect(utils.decodeEncoding('aGVsbG8=')).toBe('aGVsbG8=');
expect(utils.decodeEncoding('hello')).toBe('hello');
expect(utils.decodeEncoding(null)).toBe(null);
});
});

View File

@ -2,6 +2,7 @@ import * as models from '../models/index';
import * as templating from './index';
import * as pluginContexts from '../plugins/context';
import * as db from '../common/database';
import { decodeEncoding } from './utils';
const EMPTY_ARG = '__EMPTY_NUNJUCKS_ARG__';
@ -74,7 +75,10 @@ export default class BaseExtension {
const environmentId = renderContext.getEnvironmentId ? renderContext.getEnvironmentId() : 'n/a';
// Extract the rest of the args
const args = runArgs.slice(0, runArgs.length - 1).filter(a => a !== EMPTY_ARG);
const args = runArgs
.slice(0, runArgs.length - 1)
.filter(a => a !== EMPTY_ARG)
.map(decodeEncoding);
// Define a helper context with utils
const helperContext = {

View File

@ -13,6 +13,7 @@ export type NunjucksParsedTagArg = {
| 'enum'
| 'file'
| 'model',
encoding?: 'base64',
value: string | number | boolean,
defaultValue?: string | number | boolean,
forceVariable?: boolean,
@ -208,3 +209,29 @@ export function getDefaultFill(name: string, args: Array<NunjucksParsedTagArg>):
return `${name} ${stringArgs.join(', ')}`;
}
export function encodeEncoding(value: string, encoding: 'base64'): string {
if (typeof value !== 'string') {
return value;
}
if (encoding === 'base64') {
const encodedValue = Buffer.from(value, 'utf8').toString('base64');
return `b64::${encodedValue}::46b`;
}
return value;
}
export function decodeEncoding(value: string): string {
if (typeof value !== 'string') {
return value;
}
const results = value.match(/^b64::(.+)::46b$/);
if (results) {
return Buffer.from(results[1], 'base64').toString('utf8');
}
return value;
}

View File

@ -117,7 +117,7 @@ class TagEditor extends React.PureComponent<Props, State> {
this.setState({ allDocs, loadingDocs: false });
}
_updateArg(
async _updateArg(
argValue: string | number | boolean,
argIndex: number,
forceNewType: string | null = null,
@ -167,7 +167,7 @@ class TagEditor extends React.PureComponent<Props, State> {
Object.assign((argData: any), { type: forceNewType }, patch);
}
this._update(tagDefinitions, activeTagDefinition, tagData, false);
await this._update(tagDefinitions, activeTagDefinition, tagData, false);
}
async _handleChangeArgVariable(options: { argIndex: number, variable: boolean }) {
@ -208,6 +208,15 @@ class TagEditor extends React.PureComponent<Props, State> {
argIndex = typeof index === 'string' ? parseInt(index, 10) : -1;
}
// Handle special types
if (e.currentTarget.getAttribute('data-encoding') === 'base64') {
return this._updateArg(
templateUtils.encodeEncoding(e.currentTarget.value, 'base64'),
argIndex,
);
}
// Handle normal types
if (e.currentTarget.type === 'number') {
return this._updateArg(parseFloat(e.currentTarget.value), argIndex);
} else if (e.currentTarget.type === 'checkbox') {
@ -342,13 +351,14 @@ class TagEditor extends React.PureComponent<Props, State> {
);
}
renderArgString(value: string, placeholder: string) {
renderArgString(value: string, placeholder: string, encoding: string) {
return (
<input
type="text"
defaultValue={value || ''}
placeholder={placeholder}
onChange={this._handleChange}
data-encoding={encoding || 'utf8'}
/>
);
}
@ -499,7 +509,7 @@ class TagEditor extends React.PureComponent<Props, State> {
return null;
}
const strValue = argData.value.toString();
const strValue = templateUtils.decodeEncoding(argData.value.toString());
const isVariable = argData.type === 'variable';
const argInputVariable = isVariable ? this.renderArgVariable(strValue) : null;
@ -508,7 +518,8 @@ class TagEditor extends React.PureComponent<Props, State> {
if (argDefinition.type === 'string') {
const placeholder =
typeof argDefinition.placeholder === 'string' ? argDefinition.placeholder : '';
argInput = this.renderArgString(strValue, placeholder);
const encoding = argDefinition.encoding || 'utf8';
argInput = this.renderArgString(strValue, placeholder, encoding);
} else if (argDefinition.type === 'enum') {
const { options } = argDefinition;
argInput = this.renderArgEnum(strValue, options || []);