diff --git a/ui/app/helpers/string-array-to-camel.js b/ui/app/helpers/string-array-to-camel.js new file mode 100644 index 000000000000..1e75d4f29dd9 --- /dev/null +++ b/ui/app/helpers/string-array-to-camel.js @@ -0,0 +1,38 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { helper as buildHelper } from '@ember/component/helper'; +import { assert } from '@ember/debug'; + +// This helper is similar to the Ember string camelize helper but it does some additional handling: +// it allows you to pass in an array of strings +// it lowercases the entire string before converting to camelCase preventing situations like IAM Endpoint -> iamEndpoint instead of iAMEndpoint +// it does not handle accented characters so try not use for user inputted strings. +export function stringArrayToCamelCase(str) { + if (!str) return; + if (Array.isArray(str)) { + return str.map((s) => { + assert(`must pass in a string or array of strings`, typeof s === 'string'); + // lower case the entire string to handle situations like IAM Endpoint -> iamEndpoint instead of iAMEndpoint + s = s.toLowerCase(); + return s + .replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) { + return index === 0 ? word.toLowerCase() : word.toUpperCase(); + }) + .replace(/\s+/g, ''); + }); + } else { + // lower case the entire string to handle situations like IAM Endpoint -> iamEndpoint instead of iAMEndpoint + assert(`must pass in a string or array of strings`, typeof str === 'string'); + str = str.toLowerCase(); + return str + .replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) { + return index === 0 ? word.toLowerCase() : word.toUpperCase(); + }) + .replace(/\s+/g, ''); + } +} + +export default buildHelper(stringArrayToCamelCase); diff --git a/ui/tests/integration/helpers/string-array-to-camel-test.js b/ui/tests/integration/helpers/string-array-to-camel-test.js new file mode 100644 index 000000000000..be71685d6f52 --- /dev/null +++ b/ui/tests/integration/helpers/string-array-to-camel-test.js @@ -0,0 +1,60 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'vault/tests/helpers'; +import { stringArrayToCamelCase } from 'vault/helpers/string-array-to-camel'; + +module('Integration | Helper | string-array-to-camel', function (hooks) { + setupRenderingTest(hooks); + + test('it returns camelCase string with all caps and two words separated by space', async function (assert) { + const string = 'FOO Bar'; + const expected = 'fooBar'; + const result = stringArrayToCamelCase(string); + + assert.strictEqual( + result, + expected, + 'camelCase string returned for call caps and two words separated by space' + ); + }); + + test('it returns an array of camelCased strings if an array of strings passed in', function (assert) { + const string = ['FOO Bar', 'Baz Qux', 'wibble wobble', 'wobble WIBBLes']; + const expected = ['fooBar', 'bazQux', 'wibbleWobble', 'wobbleWibbles']; + const result = stringArrayToCamelCase(string); + assert.deepEqual(result, expected, 'camelCase array of strings returned for all sorts of strings'); + }); + + test('it returns string if string is numbers', function (assert) { + const string = '123'; + const expected = '123'; + const result = stringArrayToCamelCase(string); + assert.strictEqual(result, expected, 'camelCase kind of handles strings with numbers'); + }); + + test('it returns error if str is not a string', function (assert) { + const string = { name: 'foo.bar*baz' }; + let result; + try { + result = stringArrayToCamelCase(string); + } catch (e) { + result = e.message; + } + assert.deepEqual(result, 'Assertion Failed: must pass in a string or array of strings'); + }); + + test('it returns error if str is not an array of string', function (assert) { + const string = [{ name: 'foo.bar*baz' }]; + let result; + try { + result = stringArrayToCamelCase(string); + } catch (e) { + result = e.message; + } + assert.deepEqual(result, 'Assertion Failed: must pass in a string or array of strings'); + }); +});