@lanetix/odata-ast-transformations

Perform AST transformations on OData 4.0 AST parsed with @lanetix/odata-parser.

Usage no npm install needed!

<script type="module">
  import lanetixOdataAstTransformations from 'https://cdn.skypack.dev/@lanetix/odata-ast-transformations';
</script>

README

CircleCI codecov js-standard-style

odata-ast-transformations

An AST transformation adaptor, intended for use with ASTs produced from https://github.com/lanetix/node-odata-parser.

Installation

npm install @lanetix/odata-ast-transformations

Usage

  1. parse uri
  2. apply chosen ast transformation (with proper args)

Example with context.

import parser from '@lanetix/odata-parser'
import astTransformer from '@lanetix/odata-ast-transformations'

// parse into AST
const ast = parser.parse("$top=10&$skip=5&$select=foo,bar")

// this ast transformation requires a context object
const context = {
  securityRules: {
    recordTypeBaz: [ "$select=bar"] // only bar is selectable
  }
}
const securedAst = astTransformer.addSecurity(ast, context)

Example with different arg requirements.

import parser from '@lanetix/odata-parser'
import astTransformer from '@lanetix/odata-ast-transformations'

// parse into AST
const ast = parser.parse("$top=10&$skip=5&$select=foo,bar")

// this ast transformation requires a list of filters
const filtersToAdd = [
  "$select=name&$filter=lanetix/id ne 456 and name ne 'bozo'",
  "$filter=favorite/id eq 123",
  "$filter=parent/favorite/name ne 'harry'"
]
const unifiedAst = astTransformer.intersectFilters(ast, filtersToAdd)

Currently supported AST transformations

Common transformations:

Security Squad:

Condition Builder:

REPL

npm run repl

Commands in this module are of the format: methodName(ast, otherArgs).

The repl may be used by either:

  1. Set the ast first, then call the withAst.methodName(otherArgs).
  2. Set the uri first, then call the withUri.methodName(otherArgs).

In order to set the ast, you may use 2 approaches:

  • setAstJSON({"tag":"yes"}) // must be a minified JSON format
  • setAstFILE('./test-ast.json')

In order to set the uri, you may use 2 approaches:

  • setUriTEXT("$select=id,lanetix/archived,lanetix/id&$filter=name eq 'Antwan'")
  • setUriFILE('./test-uri.json')

Resulting AST can be shown in 2 formats. Default is prettyPrint. Here are the commands to switch:

  • makePretty
  • makeNormal // returns minified JSON. Useful for outputs to use in test fixtures.

Usage of the REPL (e.g. which args you can use) are detailed in each transformation's own README. See links above.

How do I add my own AST transformations?

  1. add a method in the src/index.js
    • set your visitMethods object in the context
    • add anything else you need into the context
    • build your acc (optional)
export const addSecurity = (ast: AstRoot, context: MapperContext): AstRoot => {
  const acc = { insideExpand: false, expandRT: '' }
  const { recordType, securityRules } = context

  const visitMethods = {
    $select: securityTransformations.visitSelect,
    $filter: securityTransformations.visitFilter,
    $expand: securityTransformations.visitExpand,
    $apply: securityTransformations.visitApply,
    $orderby: securityTransformations.visitOrderby
  }
  // FIXME: security rules should already be in the mapperContext
  const newContext = { recordType, securityRules, visitMethods }

  return visitQueryOptions(acc, ast, newContext)
}
  1. make your method available in the external interface, via src/index.js
export default { addSecurity, yourNewMethodName }
  1. write out the execution of your visitMethods in a separate js file
import * as securityTransformations from './transformations/security/add-security'
// see the `src/transformations/security/add-security.js` for example methods.

Note: if you do not define a visit method for a given query option, then this query option will be returned untransformed (unchanged).

// no changes to $top, $skip, $search
const visitMethods = {
  $select: securityTransformations.visitSelect,
  $filter: securityTransformations.visitFilter,
  $expand: securityTransformations.visitExpand,
  $apply: securityTransformations.visitApply,
  $orderby: securityTransformations.visitOrderby
}
  1. maintain flow typing.

Changelog

To update the changelog, first npm publish <version> then npm run build:changelog and push to master.

Issue Reporting

This is an internal Lanetix module. Report to Lanetix internal issue tracking.

Future Feature Plans

This module is a pre-walker of an AST parsed by the @lanetix/odata-parser. Additional transformations may include:

(A) transformations based on odata parameter-aliases

(B) planned future updates to security rules

(C) Any application which integrates >=2 odata uri into a single output.