npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@pru-rt/spel2js

v0.2.1

Published

Parse Spring Expression Language in JavaScript

Downloads

45

Readme

spel2js

Build Status Test Coverage Dependency Status Bower Version NPM version

About

SpEL2JS is a plugin that will parse Spring Expression Language within a defined context in JavaScript. This is useful in single-page applications where duplication of authorization expressions for UI purposes can lead to inconsistencies. This library implements a JavaScript version of the parser based on the documentation in the link above. I did my best to followed the docs as closely as possible, but if you come accross an expression that behaves differently than you would expect then please open an issue.

Example

Say you are creating a shared to-do list, and you want to allow only the owner of the list to make changes, but anyone can view:

//ListController.java

@Controller
@RequestMapping('/todolists')
public class ListController {

  public static final String ADD_LIST_ITEM_PERMISSION = "#toDoList.owner == authentication.details.name";  
  ...
  
  @PreAuthorize(ADD_LIST_ITEM_PERMISSION)
  @RequestMapping(value="/{toDolistId}/items", method=RequestMethod.POST)
  public ResponseEntity<ListItem> addListItem(@MagicAnnotation ToDoList toDoList, @RequestBody ListItem newListItem) {
    //add the item to the list
    return new ResponseEntity<ListItem>(newListItem, HttpStatus.CREATED);
  }

  ...
}
//list-controller.js

angular.module('ToDo').controller('ListController', ['$http', '$scope', 'SpelService', function ($http, $scope, SpelService) {
  
  $http.get('/api/permissions').success(function (permissions) {
    angular.forEach(permissions, function (spelExpression, key) {
      $scope.permissions[key] = SpelService.compile(spelExpression);
    });
  });
  
  $scope.list = {
    name: 'My List',
    owner: 'Ben March',
    items: [
      {
        text: 'List item number 1!'
      }
    ]
  }
  
  $scope.addListItem = function (list, newListItem) {
    if ($scope.permissions.ADD_LIST_ITEM_PERMISSION.eval(SpelService.getContext(), $scope)) {
      $http.post('/todolists/' + list.id + '/items', item).success(function () {...});  
    }
  }
}]);
<!--list-controller.html-->

<div ng-controller="ListController">
  ...
  <li ng-repeat="listItem in list.items">
    <p>{{listItem.text}}</p>
  </li>
  <li class="list-actions">
    <input type="text" ng-model="newListItem.text" />
    <button ng-click="addListItem(list, newListItem)" spel-if="permissions.ADD_LIST_ITEM_PERMISSION">Add</button>
  </li>
  ...
</div>

Seems like it might be a lot of work for such a simple piece of functionality; however, what happens when you add role-based permissions as a new feature? If you already have this set up, it's as simple as adding " or hasRole('SuperUser')" to the SpEL, and exposing a minimal projection of the Authentication to the browser or Node app (which it probably already has access to.) Now the UI can always stay in sync with the server-side authorities.

Features

This is now in a stable state and will be released as 0.2.0. The following features are tested and working:

  • Primitive Literals
  • Property references
  • Compound expressions
  • Comparisons
  • Method references
  • Local variable reference ("#someVar")
  • Math
  • Ternary operators
  • Safe navigation
  • Assignment
  • Complex literals
  • Projection/selection
  • Increment/Decrement
  • Logical operators (and, or, not)
  • hasRole() (if you use spel2js.StandardContext)

The following are not implemented yet because I'm not sure of the best approach:

  • Qualified identifiers/Type references/Bean References
  • hasPermission() for custom permission evaluators

There are a few AngularJS directives (I just need to put them on GH):

  • spelShow
  • spelHide
  • spelIf

If someone wants to implement a REST-compliant way in Spring to expose the permissions (and maybe the custom PermissionEvaluators) that would be awesome.

Install Choices

Tasks

All tasks can be run by simply running grunt or with the npm test command, or individually:

  • grunt lint will lint source code for syntax errors and anti-patterns.
  • grunt test will run the jasmine unit tests against the source code.

Credits

Credit is given to all of the original authors of the Java SpEL implementation at the time of this library's creation:

  • Andy Clement
  • Juergen Hoeller
  • Giovanni Dall'Oglio Risso
  • Sam Brannen
  • Mark Fisher
  • Oliver Becker
  • Clark Duplichien
  • Phillip Webb
  • Stephane Nicoll
  • Ivo Smid

This repository was scaffolded with generator-microjs.

License

Since this was ported from the Spring Framework, this library is under version 2.0 of the Apache License.