diff --git a/docs/usage/templates.md b/docs/usage/templates.md index 70de8c64e9143cbc0b676a5d0db9996ac7d6b2d1..5a8e602feb88f73b4fdcc1dc594c5877c537a3d8 100644 --- a/docs/usage/templates.md +++ b/docs/usage/templates.md @@ -39,6 +39,24 @@ If you want to print pretty JSON with Handlebars you can use the built-in functi In the example above `myvar` is a variable/field, that has valid JSON. +### toArray + +If you want to convert elements to an array, use `toArray`, e.g., + +`{{{ toJSON (toArray 'value1' 'value2' 'value3') }}}` will render `["value1","value2","value3"]`. + +### toJSON + +If you want to convert an object to a JSON string, you can use the built-in function `toJSON` like this: + +`{{{ toJSON upgrades }}}` + +### toObject + +If you want to convert key-value pairs to an object, use `toObject`, e.g., + +`{{{ toJSON (toObject 'key1' 'value1' 'key2' 'value2') }}}` will render `{"key1":"value1","key2":"value2"}`. + ### encodeURIComponent If you want to convert a string to a valid URI, use the built-in function `encodeURIComponent` like this: diff --git a/lib/util/template/index.spec.ts b/lib/util/template/index.spec.ts index e6a4b732afce93f7d2eb6c2dc4be852e87837c6e..123040edabed9e781685179c29c708b5486b0586 100644 --- a/lib/util/template/index.spec.ts +++ b/lib/util/template/index.spec.ts @@ -96,6 +96,58 @@ describe('util/template/index', () => { expect(output).toMatchSnapshot(); }); + it('to JSON', () => { + const userTemplate = '{{{ toJSON upgrades }}}'; + const input = { + upgrades: [ + { + depName: 'foo-lib', + currentVersion: '1.0.0', + newVersion: '1.0.1', + }, + ], + }; + const output = template.compile(userTemplate, input); + expect(JSON.parse(output)).toEqual(input.upgrades); + }); + + it('to JSON empty array', () => { + const userTemplate = '{{{ toJSON (toArray) }}}'; + const output = template.compile(userTemplate, {}); + expect(JSON.parse(output)).toEqual([]); + }); + + it('to JSON empty object', () => { + const userTemplate = '{{{ toJSON (toObject) }}}'; + const output = template.compile(userTemplate, {}); + expect(JSON.parse(output)).toEqual({}); + }); + + it('to Object passing illegal number of elements', () => { + const userTemplate = "{{{ toJSON (toObject 'foo') }}}"; + const outputFunc = () => template.compile(userTemplate, {}); + expect(outputFunc).toThrow(); + }); + + it('build complex json', () => { + const userTemplate = + "{{{ toJSON (toObject 'upgrades' upgrades 'array' (toArray platform isMajor 'foo')) }}}"; + const input = { + platform: 'github', + isMajor: true, + upgrades: [ + { + depName: 'foo-lib', + }, + ], + }; + const output = template.compile(userTemplate, input); + expect(JSON.parse(output)).toEqual({ + upgrades: input.upgrades, + array: [input.platform, input.isMajor, 'foo'], + }); + }); + it('lowercase', () => { const userTemplate = "{{{ lowercase 'FOO'}}}"; const output = template.compile(userTemplate, undefined as never); diff --git a/lib/util/template/index.ts b/lib/util/template/index.ts index e489e2c8df101360f452a30483a4473da3e3b0af..6164b1b15acd76f9c5549d92cb2a2aa38a9d7571 100644 --- a/lib/util/template/index.ts +++ b/lib/util/template/index.ts @@ -16,6 +16,32 @@ handlebars.registerHelper('stringToPrettyJSON', (input: string): string => JSON.stringify(JSON.parse(input), null, 2), ); +handlebars.registerHelper('toJSON', (input: unknown): string => + JSON.stringify(input), +); + +handlebars.registerHelper('toArray', (...args: unknown[]): unknown[] => { + // Need to remove the 'options', as last parameter + // https://handlebarsjs.com/api-reference/helpers.html + args.pop(); + return args; +}); + +handlebars.registerHelper('toObject', (...args: unknown[]): unknown => { + // Need to remove the 'options', as last parameter + // https://handlebarsjs.com/api-reference/helpers.html + args.pop(); + + if (args.length % 2 !== 0) { + throw new Error(`Must contain an even number of elements`); + } + + const keys = args.filter((_, index) => index % 2 === 0); + const values = args.filter((_, index) => index % 2 === 1); + + return Object.fromEntries(keys.map((key, index) => [key, values[index]])); +}); + handlebars.registerHelper('replace', (find, replace, context) => (context ?? '').replace(regEx(find, 'g'), replace), );