{"id":26018559,"url":"https://github.com/swaggerexpert/arazzo-runtime-expression","last_synced_at":"2026-02-09T00:16:19.764Z","repository":{"id":278069414,"uuid":"934422099","full_name":"swaggerexpert/arazzo-runtime-expression","owner":"swaggerexpert","description":"Arazzo Runtime Expressions parser, validator and extractor.","archived":false,"fork":false,"pushed_at":"2026-01-21T14:02:05.000Z","size":538,"stargazers_count":5,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-22T01:30:43.898Z","etag":null,"topics":["arazzo","arazzo-specification","expression","extractor","parser","runtime","validator"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swaggerexpert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":"GOVERNANCE.md","roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["char0n"],"tidelift":"npm/@swaggerexpert%2Farazzo-runtime-expression","patreon":"char0n","ko_fi":"char0n","liberapay":"char0n","issuehunt":"char0n"}},"created_at":"2025-02-17T20:02:15.000Z","updated_at":"2026-01-21T14:05:36.000Z","dependencies_parsed_at":"2025-02-17T21:19:50.201Z","dependency_job_id":"0b0f258f-6909-4f19-af0b-f1edbde3b259","html_url":"https://github.com/swaggerexpert/arazzo-runtime-expression","commit_stats":null,"previous_names":["swaggerexpert/arazzo-runtime-expression"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/swaggerexpert/arazzo-runtime-expression","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Farazzo-runtime-expression","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Farazzo-runtime-expression/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Farazzo-runtime-expression/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Farazzo-runtime-expression/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swaggerexpert","download_url":"https://codeload.github.com/swaggerexpert/arazzo-runtime-expression/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Farazzo-runtime-expression/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28880823,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-29T10:31:27.438Z","status":"ssl_error","status_checked_at":"2026-01-29T10:31:01.017Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arazzo","arazzo-specification","expression","extractor","parser","runtime","validator"],"created_at":"2025-03-06T06:30:18.386Z","updated_at":"2026-02-09T00:16:19.750Z","avatar_url":"https://github.com/swaggerexpert.png","language":"JavaScript","funding_links":["https://github.com/sponsors/char0n","https://tidelift.com/funding/github/npm/@swaggerexpert%2Farazzo-runtime-expression","https://patreon.com/char0n","https://ko-fi.com/char0n","https://liberapay.com/char0n","https://issuehunt.io/r/char0n","https://tidelift.com/badges/package/npm/@swaggerexpert%2Farazzo-runtime-expression","https://tidelift.com/subscription/pkg/npm-.swaggerexpert-arazzo-runtime-expression?utm_source=npm-swaggerexpert-arazzo-runtime-expression\u0026utm_medium=referral\u0026utm_campaign=readme"],"categories":[],"sub_categories":[],"readme":"# @swaggerexpert/arazzo-runtime-expression\n\n[![npmversion](https://img.shields.io/npm/v/%40swaggerexpert%2Farazzo-runtime-expression?style=flat-square\u0026label=npm%20package\u0026color=%234DC81F\u0026link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2F%40swaggerexpert%2Farazzo-runtime-expression)](https://www.npmjs.com/package/@swaggerexpert/arazzo-runtime-expression)\n[![npm](https://img.shields.io/npm/dm/@swaggerexpert/arazzo-runtime-expression)](https://www.npmjs.com/package/@swaggerexpert/arazzo-runtime-expression)\n[![Test workflow](https://github.com/swaggerexpert/arazzo-runtime-expression/actions/workflows/test.yml/badge.svg)](https://github.com/swaggerexpert/arazzo-runtime-expression/actions)\n[![Dependabot enabled](https://img.shields.io/badge/Dependabot-enabled-blue.svg)](https://dependabot.com/)\n[![try on RunKit](https://img.shields.io/badge/try%20on-RunKit-brightgreen.svg?style=flat)](https://npm.runkit.com/@swaggerexpert/arazzo-runtime-expression)\n[![Tidelift](https://tidelift.com/badges/package/npm/@swaggerexpert%2Farazzo-runtime-expression)](https://tidelift.com/subscription/pkg/npm-.swaggerexpert-arazzo-runtime-expression?utm_source=npm-swaggerexpert-arazzo-runtime-expression\u0026utm_medium=referral\u0026utm_campaign=readme)\n\n[Arazzo Runtime Expressions](https://spec.openapis.org/arazzo/latest.html#runtime-expressions) allows values to be defined based on information that will be available within the HTTP message in an actual API call,\nor within objects serialized from the Arazzo document such as [workflows](https://spec.openapis.org/arazzo/latest.html#workflow-object) or [steps](https://spec.openapis.org/arazzo/latest.html#step-object).\n\n`@swaggerexpert/arazzo-runtime-expression` is a **parser**, **validator** and **extractor** for Arazzo Runtime Expressions.\n\nIt supports Runtime Expressions defined in following Arazzo specification versions:\n\n- [Arazzo 1.0.0](https://spec.openapis.org/arazzo/v1.0.0.html)\n- [Arazzo 1.0.1](https://spec.openapis.org/arazzo/v1.0.1.html)\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"right\" valign=\"middle\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/swaggerexpert/arazzo-runtime-expression/main/assets/tidelift.webp\" alt=\"Tidelift\" width=\"60\" /\u003e\n      \u003c/td\u003e\n      \u003ctd valign=\"middle\"\u003e\n        \u003ca href=\"https://tidelift.com/subscription/pkg/npm-.swaggerexpert-arazzo-runtime-expression?utm_source=npm-swaggerexpert-arazzo-runtime-expression\u0026utm_medium=referral\u0026utm_campaign=readme\"\u003e\n            Get professionally supported @swaggerexpert/arazzo-runtime-expression with Tidelift Subscription.\n        \u003c/a\u003e\n      \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Table of Contents\n\n- [Getting started](#getting-started)\n  - [Installation](#installation)\n  - [Usage](#usage)\n    - [Extraction](#extraction)\n    - [Parsing](#parsing)\n      - [Translators](#translators)\n      - [Statistics](#statistics)\n      - [Tracing](#tracing)\n    - [Validation](#validation)\n    - [Errors](#errors)\n    - [Grammar](#grammar)\n- [More about Arazzo runtime expressions](#more-about-arazzo-runtime-expressions)\n- [License](#license)\n\n\n## Getting started\n\n### Installation\n\nYou can install `@swaggerexpert/arazzo-runtime-expression` using `npm`:\n\n```sh\n $ npm install @swaggerexpert/arazzo-runtime-expression\n```\n\n### Usage\n\n`@swaggerexpert/arazzo-runtime-expression` currently supports **extraction**, **parsing** and **validation**.\nBoth parser and validator are based on a superset of [ABNF](https://www.rfc-editor.org/rfc/rfc5234) ([SABNF](https://cs.github.com/ldthomas/apg-js2/blob/master/SABNF.md))\nand use [apg-lite](https://github.com/ldthomas/apg-lite) parser generator.\n\n#### Extraction\n\nArazzo embeds Runtime Expressions into string values surrounded with `{}` curly braces.\nTo extract Runtime Expressions from this embedded form, use the **extract** function.\nThe function returns an array of all extracted expressions, which can be used for further parsing or validation.\n\n```js\nimport { extract, test, parse } from '@swaggerexpert/arazzo-runtime-expression';\n\n// Extract single expression\nextract('{$request.header.accept}'); // =\u003e ['$request.header.accept']\n\n// Extract multiple expressions from a template string\nextract('client_id={$inputs.clientId}\u0026grant_type={$inputs.grantType}');\n// =\u003e ['$inputs.clientId', '$inputs.grantType']\n\n// No expressions found\nextract('no expressions here'); // =\u003e []\n\n// Use extracted expressions\nconst expressions = extract('{$url}');\ntest(expressions[0]); // =\u003e true\nparse(expressions[0]); // =\u003e { result, tree }\n```\n\n**Known limitation:** `$request.body#/...` and `$response.body#/...` expressions with JSON pointers cannot be reliably\nextracted from `{expression}` syntax. This is because [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)\n(JSON Pointer) allows the `}` character in pointer paths, making it impossible to determine where the expression ends.\nUse `parse()` directly on the raw expression for these cases.\n\n#### Parsing\n\nParsing a Runtime Expression is as simple as importing the **parse** function and calling it.\n\n```js\nimport { parse } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst parseResult = parse('$request.header.accept');\n```\n\n**parseResult** variable has the following shape:\n\n```\n{\n  result: \u003cParseResult['result']\u003e,\n  tree: \u003cParseResult['tree']\u003e,\n  stats: \u003cParseResult['stats']\u003e,\n  trace: \u003cParseResult['trace']\u003e,\n}\n```\n\n[TypeScript typings](https://github.com/swaggerexpert/arazzo-runtime-expression/blob/main/types/index.d.ts) are available for all fields attached to parse result object returned by the `parse` function.\n\n##### Translators\n\n`@swaggerexpert/arazzo-runtime-expression` provides several translators to convert the parse result into different tree representations.\n\n###### CST translator\n\n[Concrete Syntax Tree](https://en.wikipedia.org/wiki/Parse_tree) (Parse tree) representation is available on parse result\nwhen instance of `CSTTranslator` is provided via a `translator` option to the `parse` function.\nCST is suitable to be consumed by other tools like IDEs, editors, etc...\n\n```js\nimport { parse, CSTTranslator } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst { tree: cst } = parse('$request.header.accept', { translator: new CSTTranslator() });\n```\n\nCST tree has a shape documented by [TypeScript typings (CSTNode)](https://github.com/swaggerexpert/arazzo-runtime-expression/blob/main/types/index.d.ts).\n\n###### AST translator\n\n**Default translator**. [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) representation is available on parse result\nby default or when instance of `ASTTranslator` is provided via a `translator` option to the `parse` function.\nAST is suitable to be consumed by implementations that need to analyze the structure of the runtime expression.\n\n```js\nimport { parse } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst { tree: ast } = parse('$request.header.accept');\n```\n\nor\n\n```js\nimport { parse, ASTTranslator } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst { tree: ast } = parse('$request.header.accept', { translator: new ASTTranslator() });\n```\n\nAST tree has a shape documented by [TypeScript typings (ASTNode)](https://github.com/swaggerexpert/arazzo-runtime-expression/blob/main/types/index.d.ts).\n\n###### XML translator\n\n```js\nimport { parse, XMLTranslator } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst { tree: xml } = parse('$request.header.accept', { translator: new XMLTranslator() });\n```\n\n##### Statistics\n\n`parse` function returns additional statistical information about the parsing process.\nCollection of the statistics can be enabled by setting `stats` option to `true`.\n\n```js\nimport { parse } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst { stats } = parse('$request.header.accept', { stats: true });\n\nstats.displayStats(); // returns operator statistics as string\n```\n\n##### Tracing\n\n`parse` function returns additional tracing information about the parsing process.\nTracing can be enabled by setting `trace` option to `true`. Tracing is essential\nfor debugging failed parses or analyzing rule execution flow.\n\n```js\nimport { parse } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst { result, trace } = parse('$invalid', { trace: true });\n\nresult.success; // false\ntrace.displayTrace(); // returns trace information as string\n```\n\nTracing also allows you to infer expected tokens at a failure point. This is useful for generating meaningful syntax error messages.\n\n```js\nimport { parse } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst { trace } = parse('$invalid', { trace: true });\n\nconst expectations = trace.inferExpectations();\nconsole.log(expectations.toString()); // e.g., \"expected '$url', '$method', '$statusCode', '$request.', ...\"\n```\n\n#### Validation\n\nValidating a Runtime Expression is as simple as importing the **test** function and calling it.\n\n```js\nimport { test } from '@swaggerexpert/arazzo-runtime-expression';\n\ntest('$request.header.accept'); // =\u003e true\ntest('nonsensical string'); // =\u003e false\n```\n\n#### Errors\n\n`@swaggerexpert/arazzo-runtime-expression` provides a structured error class hierarchy,\nenabling precise error handling across runtime expression operations.\n\n```js\nimport { ArazzoRuntimeExpressionError, ArazzoRuntimeExpressionParseError } from '@swaggerexpert/arazzo-runtime-expression';\n```\n\n**ArazzoRuntimeExpressionError** is the base class for all errors. **ArazzoRuntimeExpressionParseError** is thrown when parsing fails\nand includes additional context about the expression that failed to parse.\n\n```js\nimport { parse, ArazzoRuntimeExpressionParseError } from '@swaggerexpert/arazzo-runtime-expression';\n\ntry {\n  parse(123); // non-string input\n} catch (error) {\n  if (error instanceof ArazzoRuntimeExpressionParseError) {\n    console.log(error.runtimeExpression); // the expression that failed\n  }\n}\n```\n\n#### Grammar\n\nNew grammar instance can be created in following way:\n\n```js\nimport { Grammar } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst grammar = new Grammar();\n```\n\nTo obtain original ABNF (SABNF) grammar as a string:\n\n```js\nimport { Grammar } from '@swaggerexpert/arazzo-runtime-expression';\n\nconst grammar = new Grammar();\n\ngrammar.toString();\n// or\nString(grammar);\n```\n\n## More about Arazzo runtime expressions\n\nThe runtime expression is defined by the following [ABNF](https://tools.ietf.org/html/rfc5234) syntax\n\n```abnf\n; Arazzo runtime expression ABNF syntax\nexpression       = ( \"$url\" / \"$method\" / \"$statusCode\" / \"$request.\" source / \"$response.\" source / \"$inputs.\" name / \"$outputs.\" name / \"$steps.\" name / \"$workflows.\" name / \"$sourceDescriptions.\" name / \"$components.\" name )\nsource           = ( header-reference / query-reference / path-reference / body-reference )\nheader-reference = \"header.\" token\nquery-reference  = \"query.\" name\npath-reference   = \"path.\" name\nbody-reference   = \"body\" [\"#\" json-pointer ]\nname             = *( CHAR )\n\n; Grammar for parsing template strings with embedded expressions\nexpression-string    = *( literal-char / embedded-expression )\nembedded-expression  = \"{\" expression \"}\"\nliteral-char         = %x00-7A / %x7C / %x7E-10FFFF  ; anything except { (%x7B) and } (%x7D)\n\n; Secondary grammar for parsing $steps name part\n; Format: {stepId}.{field}.{subField}[#/{jsonPointer}]\nsteps-name       = steps-id \".\" steps-field \".\" steps-sub-field [\"#\" json-pointer]\nsteps-id         = 1*(ALPHA / DIGIT / \"_\" / \"-\")\nsteps-field      = \"outputs\"\nsteps-sub-field  = 1*(ALPHA / DIGIT / \".\" / \"-\" / \"_\")\n\n; Secondary grammar for parsing $workflows name part\n; Format: {workflowId}.{field}.{subField}[#/{jsonPointer}]\nworkflows-name       = workflows-id \".\" workflows-field \".\" workflows-sub-field [\"#\" json-pointer]\nworkflows-id         = 1*(ALPHA / DIGIT / \"_\" / \"-\")\nworkflows-field      = \"inputs\" / \"outputs\"\nworkflows-sub-field  = 1*(ALPHA / DIGIT / \".\" / \"-\" / \"_\")\n\n; Secondary grammar for parsing $sourceDescriptions name part\n; Format: {sourceName}.{reference}\n; reference can be operationId (unconstrained) or workflowId (constrained)\nsource-descriptions-name        = source-descriptions-source-name \".\" source-descriptions-reference\nsource-descriptions-source-name = 1*(ALPHA / DIGIT / \"_\" / \"-\")\nsource-descriptions-reference   = 1*CHAR\n\n; Secondary grammar for parsing $components name part\n; Format: {field}.{subField}\n; Allowed fields: parameters, successActions, failureActions\ncomponents-name      = components-field \".\" components-sub-field\ncomponents-field     = \"parameters\" / \"successActions\" / \"failureActions\"\ncomponents-sub-field = 1*(ALPHA / DIGIT / \".\" / \"-\" / \"_\")\n\n; https://datatracker.ietf.org/doc/html/rfc6901#section-3\njson-pointer     = *( \"/\" reference-token )\nreference-token  = *( unescaped / escaped )\nunescaped        = %x00-2E / %x30-7D / %x7F-10FFFF\n                 ; %x2F ('/') and %x7E ('~') are excluded from 'unescaped'\nescaped          = \"~\" ( \"0\" / \"1\" )\n                 ; representing '~' and '/', respectively\n\n; https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6\ntoken          = 1*tchar\ntchar          = \"!\" / \"#\" / \"$\" / \"%\" / \"\u0026\" / \"'\" / \"*\"\n               / \"+\" / \"-\" / \".\" / \"^\" / \"_\" / \"`\" / \"|\" / \"~\"\n               / DIGIT / ALPHA\n               ; any VCHAR, except delimiters\n\n; https://www.rfc-editor.org/rfc/rfc7159#section-7\nCHAR = unescape /\n    escape (\n        %x22 /          ; \"    quotation mark  U+0022\n        %x5C /          ; \\    reverse solidus U+005C\n        %x2F /          ; /    solidus         U+002F\n        %x62 /          ; b    backspace       U+0008\n        %x66 /          ; f    form feed       U+000C\n        %x6E /          ; n    line feed       U+000A\n        %x72 /          ; r    carriage return U+000D\n        %x74 /          ; t    tab             U+0009\n        %x75 4HEXDIG )  ; uXXXX                U+XXXX\nescape         = %x5C   ; \\\nunescape       = %x20-21 / %x23-5B / %x5D-7A / %x7C / %x7E-10FFFF\n               ; %x7B ('{') and %x7D ('}') are excluded from 'unescape'\n\n; https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1\nHEXDIG         =  DIGIT / \"A\" / \"B\" / \"C\" / \"D\" / \"E\" / \"F\"\nDIGIT          =  %x30-39   ; 0-9\nALPHA          =  %x41-5A / %x61-7A   ; A-Z / a-z\n```\n\nThe `name` identifier is case-sensitive, whereas `token` is not.\n\nThe table below provides examples of runtime expressions and examples of their use in a value:\n\n#### Examples\n\nSource Location | example expression  | notes\n---|:---|:---|\nHTTP Method            | `$method`         | The allowable values for the `$method` will be those for the HTTP operation.\nRequested media type | `$request.header.accept`        |\nRequest parameter      | `$request.path.id`        | Request parameters MUST be declared in the `parameters` section of the parent operation or they cannot be evaluated. This includes request headers.\nRequest body property   | `$request.body#/user/uuid`   | In operations which accept payloads, references may be made to portions of the `requestBody` or the entire body.\nRequest URL            | `$url`            |\nResponse value         | `$response.body#/status`       |  In operations which return payloads, references may be made to portions of the response body or the entire body.\nResponse header        | `$response.header.Server` |  Single header values only are available\nworkflow input        | `$inputs.username` or `$workflows.foo.inputs.username` |  Single input values only are available\nStep output value        | `$steps.someStepId.outputs.pets` |  In situations where the output named property return payloads, references may be made to portions of the response body (e.g., `$steps.someStepId.outputs.pets#/0/id`) or the entire body.\nWorkflow output value | `$outputs.bar` or `$workflows.foo.outputs.bar` |  In situations where the output named property return payloads, references may be made to portions of the response body (e.g., `$workflows.foo.outputs.mappedResponse#/name`) or the entire body.\nComponents parameter | `$components.parameters.foo` | Accesses a foo parameter defined within the Components Object.\n\nRuntime expressions preserve the type of the referenced value.\nExpressions can be embedded into string values by surrounding the expression with `{}` curly braces.\n\n## License\n\n`@swaggerexpert/arazzo-runtime-expression` is licensed under [Apache 2.0 license](https://github.com/swaggerexpert/arazzo-runtime-expression/blob/main/LICENSE).\n`@swaggerexpert/arazzo-runtime-expression` comes with an explicit [NOTICE](https://github.com/swaggerexpert/arazzo-runtime-expression/blob/main/NOTICE) file\ncontaining additional legal notices and information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswaggerexpert%2Farazzo-runtime-expression","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswaggerexpert%2Farazzo-runtime-expression","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswaggerexpert%2Farazzo-runtime-expression/lists"}