Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

liquidless

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

liquidless - npm Package Compare versions

Comparing version 1.2.3 to 1.3.0

7

dist/filters.d.ts

@@ -1,7 +0,8 @@

export declare type Filters = {
export type Filters = {
[key: string]: FilterFunction;
};
export declare type FilterFunction = {
(value: any, args: any[] | undefined, variable: string): any;
export type FilterFunction = {
(value: any, args: any, variable: string): any;
};
export declare const defaultFilters: Filters;
export declare const parseArgs: (args: string) => any[];
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultFilters = void 0;
exports.parseArgs = exports.defaultFilters = void 0;
exports.defaultFilters = {

@@ -12,1 +12,9 @@ upcase: (value) => value.toUpperCase(),

};
const QUOTED_STRING_REGEX = /^(["'])(?<string>.+)\1$/;
const parseArgs = (args) => args.length > 0
? args
.split(',')
.map((arg) => arg.trim())
.map((arg) => QUOTED_STRING_REGEX.test(arg) ? arg.slice(1, -1) : JSON.parse(arg))
: [];
exports.parseArgs = parseArgs;
import { Filters } from './filters';
declare type RenderOptions = {
export type RenderOptions = {
filters?: Filters;
delimiters?: string[];
};
export declare function renderString(template: string, props: object, options?: RenderOptions): string;
export declare function renderObject<T>(object: object, props: object, options?: RenderOptions): T;
export {};
export declare function renderString(template: string, props: Record<string, any>, options?: RenderOptions): string | any;
export declare function renderObject<T extends object>(object: object, props: object, options?: RenderOptions): T;

@@ -8,51 +8,50 @@ "use strict";

const flat_1 = __importDefault(require("flat"));
const rfdc_1 = __importDefault(require("rfdc"));
const filters_1 = require("./filters");
function isNumeric(value) {
return /^-?\d+$/.test(value);
}
const getType = (value) => Array.isArray(value) ? 'array' : value === null ? 'null' : typeof value;
function renderString(template, props, options) {
const flatProps = (0, flat_1.default)(props);
let delimiters = ['{{', '}}'];
if (options?.delimiters)
delimiters = options.delimiters;
return template.replaceAll(new RegExp(`\\${delimiters[0]}(.+?)${delimiters[1]}`, 'g'), (_, match) => {
const [variable, ...filters] = match.split('|');
const combinedFilters = { ...filters_1.defaultFilters, ...options?.filters };
let variableValue = flatProps[variable.trim()];
filters
.map(filter => filter.trim())
.forEach(filter => {
const [filterMethod, ...args] = filter.split(':');
let parsedArgs;
if (args.length > 0) {
parsedArgs = args[0].split(',')
.map(arg => arg.trim())
.map(arg => isNumeric(arg) ? parseInt(arg) : arg);
}
variableValue = combinedFilters[filterMethod]
? combinedFilters[filterMethod](variableValue, parsedArgs, variable.trim())
const delimiters = options?.delimiters ?? ['{{', '}}'];
const expressions = template.split(new RegExp(`\\${delimiters[0]}(.+?)${delimiters[1]}`, 'g'));
const combinedFilters = { ...filters_1.defaultFilters, ...options?.filters };
for (let i = 1; i < expressions.length; i += 2) {
const [variable, ...filters] = expressions[i]
.split('|')
.map((s) => s.trim());
const variableValue = props[variable];
expressions[i] = filters.reduce((variableValue, filter) => {
const [filterMethod, args] = filter.split(':');
const parsedArgs = (0, filters_1.parseArgs)(args ?? '');
return combinedFilters[filterMethod]
? combinedFilters[filterMethod](variableValue, parsedArgs, variable)
: variableValue;
});
return variableValue
? variableValue.toString()
: "undefined";
});
}, variableValue);
}
// if there are no other expressions, return the first one which can be of any type, for example a number
if (expressions.length === 3 &&
expressions[0] === '' &&
expressions[2] === '') {
return expressions[1];
}
return expressions.join('');
}
exports.renderString = renderString;
function renderObject(object, props, options) {
const cloned = (0, rfdc_1.default)()(object);
function recursive(obj) {
for (const key in obj) {
if (typeof obj[key] === 'object') {
recursive(obj[key]);
const flatProps = (0, flat_1.default)(props);
const transform = (obj) => {
const transformedNode = new (Object.getPrototypeOf(obj).constructor)();
for (const [key, value] of Object.entries(obj)) {
const nodeType = getType(value);
if (nodeType === 'object' || nodeType === 'array') {
transformedNode[key] = transform(value);
}
else if (typeof obj[key] === 'string') {
obj[key] = renderString(obj[key], props, options);
else if (nodeType === 'string') {
transformedNode[key] = renderString(value, flatProps, options);
}
else {
transformedNode[key] = value;
}
}
}
recursive(cloned);
return cloned;
return transformedNode;
};
return transform(object);
}
exports.renderObject = renderObject;
{
"name": "liquidless",
"version": "1.2.3",
"version": "1.3.0",
"description": "Shopify's Liquid template engine, but less powerful",

@@ -12,3 +12,4 @@ "main": "dist/index.js",

"build:watch": "tsc -w -p tsconfig.json",
"test": "ts-node ./tests/test.ts"
"test": "vitest --coverage",
"test:ui": "vitest --coverage --ui"
},

@@ -31,4 +32,3 @@ "repository": {

"dependencies": {
"flat": "^5.0.2",
"rfdc": "^1.3.0"
"flat": "^5.0.2"
},

@@ -39,5 +39,8 @@ "devDependencies": {

"@types/node": "^18.7.18",
"@vitest/coverage-v8": "^1.1.3",
"@vitest/ui": "^1.1.3",
"ts-node": "^10.9.1",
"typescript": "^4.8.3"
"typescript": "^4.8.3",
"vitest": "^1.1.3"
}
}

@@ -58,3 +58,3 @@ # liquidless

```
Hello, world 1, 2, 3 (world)!
Hello, world! 1, 2, 3 (world)
```

@@ -61,0 +61,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc