-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
179 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/** | ||
* Serialize JSON | ||
* @param {any} arg any object to be serialized | ||
* @param {boolean} pretty whether to indent json | ||
* @returns | ||
*/ | ||
export function json(arg, pretty = false) { | ||
return pretty? JSON.stringify(arg, null, 2) : JSON.stringify(arg) | ||
} | ||
|
||
/** | ||
* Format date | ||
* @param {string|Date|number} date | ||
* @param {Intl.DateTimeFormatOptions} options | ||
* @param {Intl.LocalesArgument} locales the locale (default: 'en-US') | ||
* @returns {string} formatted date | ||
*/ | ||
export function date(date, options = null, locales = 'en-US') { | ||
return new Intl.DateTimeFormat(locales, options).format(typeof date === 'string' ? Date.parse(date): date) | ||
} | ||
|
||
/** | ||
* Format as currency. | ||
* @param {number} amount | ||
* @param {string?} currency | ||
* @param {Intl.LocalesArgument} locales | ||
* @returns | ||
*/ | ||
export function currency(amount, currency = 'usd', locales = 'en-US') { | ||
return new Intl.NumberFormat(locales, {style: 'currency', currency}).format(amount); | ||
} | ||
|
||
/** | ||
* Format number | ||
* @param {number} value | ||
* @param {Intl.NumberFormatOptions} options | ||
* @param {Intl.LocalesArgument} locales | ||
* @returns {string} formatted number | ||
*/ | ||
export function numberFormat(value, options, locales) { | ||
return new Intl.NumberFormat(locales || getEnvLocale(), options).format(value); | ||
} | ||
|
||
/** | ||
* Select a first N elements of an array | ||
* @param {Iterable} array | ||
* @param {number} limit | ||
* @returns | ||
*/ | ||
export function limit(array, limit) { | ||
if (limit < 0) { | ||
throw new Error(`Negative limits are not allowed: ${limit}.`); | ||
} | ||
return Array.from(array).slice(0, limit); | ||
}; | ||
|
||
/** | ||
* Copy an array and reverse | ||
* @param {Iterable} array | ||
* @returns new array, revered | ||
*/ | ||
export function reverse(array) { | ||
return Array.from(array).reverse(); | ||
} | ||
|
||
/** | ||
* Return a sorted copy of an array | ||
* @param {Iterable} array | ||
* @returns new array, sorted | ||
*/ | ||
export function sort(array) { | ||
const result = Array.from(array); | ||
result.sort(); | ||
return result; | ||
} | ||
|
||
/** | ||
* Return the last N elements, in reverse order | ||
* @param {Iterable} array | ||
* @param {number} amount | ||
*/ | ||
export function last(amount = 1) { | ||
return Array.from(array).reverse().slice(0, amount); | ||
} | ||
|
||
/** | ||
* Escape HTML (replace angle brackets and ampersands with entities) | ||
* @param {string} str | ||
* @returns escaped html | ||
*/ | ||
export function htmlentities(str) { | ||
return str.replace(/\&/, '&').replace(/</gm, '<').replace(/>/gm, '>'); | ||
} | ||
|
||
/** | ||
* URL-encode | ||
* @param {string} str | ||
* @returns encoded string | ||
*/ | ||
export function urlencode(str) { | ||
return encodeURIComponent(str); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { describe, it } from 'node:test' | ||
import assert from 'node:assert/strict'; | ||
import path from 'node:path' | ||
import { handleTemplateFile } from '../src/transforms/template-data.js'; | ||
import { SissiConfig } from '../src/sissi-config.js'; | ||
describe('builtin filters', () => { | ||
|
||
const dummyResolver = (map) => (...paths) => map.get(path.normalize(path.join(...paths))); | ||
|
||
it('should format numbers', async () => { | ||
const config = new SissiConfig(); | ||
|
||
const vFS = new Map(); | ||
vFS.set('index.html', '{{ thousandPi | numberFormat: numberFormatOptions, "de-DE" }}'); | ||
|
||
config.resolve = dummyResolver(vFS); | ||
|
||
const data = { thousandPi: Math.PI * 1e3, numberFormatOptions: {maximumFractionDigits: 2, minimumFractionDigits: 2} }; | ||
|
||
const result = await handleTemplateFile(config, data, 'index.html'); | ||
|
||
assert.equal(result.content, '3.141,59'); | ||
}); | ||
|
||
it('should format currencies', async () => { | ||
const config = new SissiConfig(); | ||
|
||
const vFS = new Map(); | ||
vFS.set('index.html', '{{ million | currency: "eur", "de-DE" }}'); | ||
|
||
config.resolve = dummyResolver(vFS); | ||
|
||
const data = { million: 1e6 }; | ||
|
||
const result = await handleTemplateFile(config, data, 'index.html'); | ||
|
||
assert.equal(result.content, '1.000.000,00 €'); | ||
}); | ||
|
||
it('should format dates', async () => { | ||
const config = new SissiConfig(); | ||
|
||
const vFS = new Map(); | ||
vFS.set('index.html', '{{ newYear | date: dateFormatOptions, "de-DE" }}'); | ||
|
||
config.resolve = dummyResolver(vFS); | ||
|
||
const data = { newYear: new Date('2025-04-01'), dateFormatOptions: {"day": "2-digit", "month": "2-digit", "year": "numeric"} }; | ||
|
||
const result = await handleTemplateFile(config, data, 'index.html'); | ||
|
||
assert.equal(result.content, '01.04.2025'); | ||
}); | ||
|
||
it('should serialize json', async () => { | ||
const config = new SissiConfig(); | ||
|
||
const vFS = new Map(); | ||
vFS.set('index.html', '{{ answer | json }}'); | ||
|
||
config.resolve = dummyResolver(vFS); | ||
|
||
const data = { answer: {result: 42} }; | ||
|
||
const result = await handleTemplateFile(config, data, 'index.html'); | ||
|
||
assert.equal(result.content, '{"result":42}'); | ||
}); | ||
}); |