Merge pull request #289 from keycloakify/some-minor-fixes
Some-minor-fixes
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
import "minimal-polyfills/Object.fromEntries";
|
import "minimal-polyfills/Object.fromEntries";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { join as pathJoin, relative as pathRelative, dirname as pathDirname } from "path";
|
import { join as pathJoin, relative as pathRelative, dirname as pathDirname, sep as pathSep } from "path";
|
||||||
import { crawl } from "../src/bin/tools/crawl";
|
import { crawl } from "../src/bin/tools/crawl";
|
||||||
import { downloadBuiltinKeycloakTheme } from "../src/bin/download-builtin-keycloak-theme";
|
import { downloadBuiltinKeycloakTheme } from "../src/bin/download-builtin-keycloak-theme";
|
||||||
import { getProjectRoot } from "../src/bin/tools/getProjectRoot";
|
import { getProjectRoot } from "../src/bin/tools/getProjectRoot";
|
||||||
@ -35,11 +35,10 @@ async function main() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
const baseThemeDirPath = pathJoin(tmpDirPath, "base");
|
const baseThemeDirPath = pathJoin(tmpDirPath, "base");
|
||||||
|
const re = new RegExp(`^([^\\${pathSep}]+)\\${pathSep}messages\\${pathSep}messages_([^.]+).properties$`);
|
||||||
|
|
||||||
crawl(baseThemeDirPath).forEach(filePath => {
|
crawl(baseThemeDirPath).forEach(filePath => {
|
||||||
const match =
|
const match = filePath.match(re);
|
||||||
filePath.match(/^([^/]+)\/messages\/messages_([^.]+)\.properties$/) ||
|
|
||||||
filePath.match(/^([^\\]+)\\messages\\messages_([^.]+)\.properties$/);
|
|
||||||
|
|
||||||
if (match === null) {
|
if (match === null) {
|
||||||
return;
|
return;
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
* Concatenate the string fragments and interpolated values
|
* Concatenate the string fragments and interpolated values
|
||||||
* to get a single string.
|
* to get a single string.
|
||||||
*/
|
*/
|
||||||
function populateTemplate(strings: TemplateStringsArray, ...args: any[]) {
|
function populateTemplate(strings: TemplateStringsArray, ...args: unknown[]) {
|
||||||
const chunks = [];
|
const chunks: string[] = [];
|
||||||
for (let i = 0; i < strings.length; i++) {
|
for (let i = 0; i < strings.length; i++) {
|
||||||
let lastStringLineLength = 0;
|
let lastStringLineLength = 0;
|
||||||
if (strings[i]) {
|
if (strings[i]) {
|
||||||
@ -14,38 +14,33 @@ function populateTemplate(strings: TemplateStringsArray, ...args: any[]) {
|
|||||||
if (args[i]) {
|
if (args[i]) {
|
||||||
// if the interpolation value has newlines, indent the interpolation values
|
// if the interpolation value has newlines, indent the interpolation values
|
||||||
// using the last known string indent
|
// using the last known string indent
|
||||||
chunks.push(args[i].replace(/([\r?\n])/g, "$1" + " ".repeat(lastStringLineLength)));
|
const chunk = String(args[i]).replace(/([\r?\n])/g, "$1" + " ".repeat(lastStringLineLength));
|
||||||
|
chunks.push(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return chunks.join("");
|
return chunks.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
function trimIndentPrivate(removeEmptyLeadingAndTrailingLines: boolean, strings: TemplateStringsArray, ...args: any[]) {
|
|
||||||
// Remove initial and final newlines
|
|
||||||
let string = populateTemplate(strings, ...args);
|
|
||||||
if (removeEmptyLeadingAndTrailingLines) string = string.replace(/^[\r\n]/, "").replace(/[^\S\r\n]*[\r\n]$/, "");
|
|
||||||
const dents = string.match(/^([ \t])+/gm)?.map(s => s.length) ?? [];
|
|
||||||
// No dents? no change required
|
|
||||||
if (!dents || dents.length == 0) return string;
|
|
||||||
const minDent = Math.min(...dents);
|
|
||||||
// The min indentation is 0, no change needed
|
|
||||||
if (!minDent) return string;
|
|
||||||
const dedented = string.replace(new RegExp(`^${" ".repeat(minDent)}`, "gm"), "");
|
|
||||||
return dedented;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shift all lines left by the *smallest* indentation level,
|
* Shift all lines left by the *smallest* indentation level,
|
||||||
* and remove initial newline and all trailing spaces.
|
* and remove initial newline and all trailing spaces.
|
||||||
*/
|
*/
|
||||||
export default function trimIndent(strings: TemplateStringsArray, ...args: any[]) {
|
export default function trimIndent(strings: TemplateStringsArray, ...args: any[]) {
|
||||||
return trimIndentPrivate(true, strings, ...args);
|
// Remove initial and final newlines
|
||||||
|
let string = populateTemplate(strings, ...args)
|
||||||
|
.replace(/^[\r\n]/, "")
|
||||||
|
.replace(/\r?\n *$/, "");
|
||||||
|
const dents =
|
||||||
|
string
|
||||||
|
.match(/^([ \t])+/gm)
|
||||||
|
?.filter(s => /^\s+$/.test(s))
|
||||||
|
?.map(s => s.length) ?? [];
|
||||||
|
// No dents? no change required
|
||||||
|
if (!dents || dents.length == 0) return string;
|
||||||
|
const minDent = Math.min(...dents);
|
||||||
|
// The min indentation is 0, no change needed
|
||||||
|
if (!minDent) return string;
|
||||||
|
const re = new RegExp(`^${" ".repeat(minDent)}`, "gm");
|
||||||
|
const dedented = string.replace(re, "");
|
||||||
|
return dedented;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Shift all lines left by the *smallest* indentation level,
|
|
||||||
* and _keep_ initial newline and all trailing spaces.
|
|
||||||
*/
|
|
||||||
trimIndent.keepLeadingAndTrailingNewlines = function (strings: TemplateStringsArray, ...args: any[]) {
|
|
||||||
return trimIndentPrivate(false, strings, ...args);
|
|
||||||
};
|
|
||||||
|
66
test/bin/tools/trimIndet.spec.ts
Normal file
66
test/bin/tools/trimIndet.spec.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import trimIndent from "keycloakify/bin/tools/trimIndent";
|
||||||
|
import { it, describe, assert } from "vitest";
|
||||||
|
|
||||||
|
describe("trimIndent", () => {
|
||||||
|
it("does not change a left-aligned string as expected", () => {
|
||||||
|
const txt = trimIndent`lorem
|
||||||
|
ipsum`;
|
||||||
|
assert.equal(txt, ["lorem", "ipsum"].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes leading and trailing empty lines from a left-aligned string", () => {
|
||||||
|
const txt = trimIndent`
|
||||||
|
lorem
|
||||||
|
ipsum
|
||||||
|
`;
|
||||||
|
assert.equal(txt, ["lorem", "ipsum"].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes indent from an aligned string", () => {
|
||||||
|
const txt = trimIndent`
|
||||||
|
lorem
|
||||||
|
ipsum
|
||||||
|
`;
|
||||||
|
assert.equal(txt, ["lorem", "ipsum"].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes indent from unaligned string", () => {
|
||||||
|
const txt = trimIndent`
|
||||||
|
lorem
|
||||||
|
ipsum
|
||||||
|
`;
|
||||||
|
assert.equal(txt, ["lorem", " ipsum"].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes only first and last empty line", () => {
|
||||||
|
const txt = trimIndent`
|
||||||
|
|
||||||
|
lorem
|
||||||
|
ipsum
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
assert.equal(txt, ["", "lorem", "ipsum", ""].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("interpolates non-strings", () => {
|
||||||
|
const d = new Date();
|
||||||
|
const txt = trimIndent`
|
||||||
|
lorem
|
||||||
|
${d}
|
||||||
|
ipsum`;
|
||||||
|
|
||||||
|
assert.equal(txt, ["lorem", String(d), "ipsum"].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("inderpolates preserving new-lines in the interpolated bits", () => {
|
||||||
|
const a = ["ipsum", "dolor", "sit"].join('\n')
|
||||||
|
const txt = trimIndent`
|
||||||
|
lorem
|
||||||
|
${a}
|
||||||
|
amet
|
||||||
|
`
|
||||||
|
assert.equal(txt, ['lorem', 'ipsum', 'dolor', 'sit', 'amet'].join('\n'))
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
Reference in New Issue
Block a user