SpEL2JS Parser
spel2js is a JavaScript library designed to parse and evaluate Spring Expression Language (SpEL) expressions within a defined context. Its primary purpose is to allow single-page applications to mirror server-side authorization logic, reducing duplication and inconsistencies in UI-related permissions. The library provides a JavaScript implementation of the SpEL parser, aiming to mimic the behavior documented for Spring Framework. It exports a singleton object containing `StandardContext` for creating evaluation contexts (which manage `authentication` and `principal` objects) and `SpelExpressionEvaluator` for compiling and executing SpEL expressions. The latest published version is 0.2.9, but significant development activity appears to have ceased around 2016 (judging by the release notes and `bower` references), indicating it is not actively maintained. It targets Node.js environments `>=8` but its age suggests potential compatibility challenges with modern JavaScript ecosystems and build tools.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use CommonJS `require()` syntax in a pure ES module environment (e.g., in a modern Node.js project with `"type": "module"` in `package.json` or in a browser via modern bundlers).fixChange `const spel2js = require('spel2js');` to `import spel2js from 'spel2js';` and `const { StandardContext, SpelExpressionEvaluator } = require('spel2js');` to `import { StandardContext, SpelExpressionEvaluator } from 'spel2js';`. -
TypeError: spel2js is not a constructor
cause Attempting to instantiate `spel2js` using `new spel2js()`. The library exports a pre-made singleton object, not a class or constructor.fixRemove `new` keyword. Access its members directly, e.g., `spel2js.StandardContext` or `spel2js.SpelExpressionEvaluator`. -
Error: Invalid argument type: null. Expected: [object Object]
cause Passing `null` or `undefined` for `authentication` or `principal` arguments to `StandardContext.create()` when the SpEL expression expects properties from these objects, or when the library internally expects object references.fixEnsure that `authentication` and `principal` passed to `StandardContext.create()` are always valid object structures, even if empty, to avoid type validation errors within the library. Initialize them as `{}` if no specific data is available.
Warnings
- breaking The license for spel2js was changed from MIT to Apache License. This change affects how the software can be used and distributed, requiring adherence to the Apache License 2.0 terms.
- gotcha SpEL2JS aims to replicate Java SpEL behavior but may exhibit subtle differences for complex expressions due to inherent differences between Java and JavaScript runtimes. The project maintainer explicitly states, 'if you come accross an expression that behaves differently than you would expect then please open an issue.'
- gotcha The project appears to be unmaintained, with the last significant release activity around 2016. This means it may not be compatible with modern JavaScript features, build tools, or Node.js versions beyond `8.x` (as specified in `engines`). It also implies potential unaddressed security vulnerabilities or bugs.
- gotcha The `StandardContext.create()` method expects `authentication` and `principal` arguments that mimic Spring Security's `Authentication` class and a principal object. Developers must construct these JavaScript objects manually to match the expected structure, which can be error-prone if not accurately replicated.
Install
-
npm install spel2js -
yarn add spel2js -
pnpm add spel2js
Imports
- spel2js
import { spel2js } from 'spel2js';import spel2js from 'spel2js';
- StandardContext, SpelExpressionEvaluator
const { StandardContext, SpelExpressionEvaluator } = require('spel2js');import { StandardContext, SpelExpressionEvaluator } from 'spel2js'; - require('spel2js')
import spel2js from 'spel2js';
const spel2js = require('spel2js');
Quickstart
import { StandardContext, SpelExpressionEvaluator } from 'spel2js';
// Mock Spring Security Authentication object and a principal object
const mockAuthentication = {
details: {
name: 'Darth Vader'
},
isAuthenticated: true
};
const mockPrincipal = {
username: 'dvader',
roles: ['SITH_LORD', 'EMPIRE_ADMIRAL']
};
// Locals represent specific objects in the expression context
const locals = {
toDoList: {
owner: 'Darth Vader',
items: ['Destroy Alderaan', 'Build Death Star']
}
};
const expression = '#toDoList.owner == authentication.details.name && authentication.isAuthenticated';
// Create an evaluation context with mock data
const spelContext = StandardContext.create(mockAuthentication, mockPrincipal);
// Evaluate the expression directly
const result = SpelExpressionEvaluator.eval(expression, spelContext, locals);
console.log(`Expression: "${expression}"`);
console.log(`Result: ${result}`); // Expected: true
// Example of pre-compiling an expression for reuse
const compiledExpression = SpelExpressionEvaluator.compile('#toDoList.items.size() > 1');
const compiledResult = compiledExpression.eval(spelContext, locals);
console.log(`Compiled expression result: ${compiledResult}`); // Expected: true