diff --git a/doc/output/json-formula-specification-2.0.0-beta.1.html b/doc/output/json-formula-specification-2.0.0-beta.1.html index 746ae936..4f75ff60 100644 --- a/doc/output/json-formula-specification-2.0.0-beta.1.html +++ b/doc/output/json-formula-specification-2.0.0-beta.1.html @@ -4,7 +4,7 @@ - + json-formula Specification @@ -117,7 +117,6 @@ :not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed} pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit} -pre>code{display:block} pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal} em em{font-style:normal} strong strong{font-weight:400} @@ -141,7 +140,7 @@ #content::before{content:none} #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf} -#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} +#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px} #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap} #header .details span:first-child{margin-left:-.125em} #header .details span.email a{color:rgba(0,0,0,.85)} @@ -163,6 +162,7 @@ #toctitle{color:#7a2518;font-size:1.2em} @media screen and (min-width:768px){#toctitle{font-size:1.375em} body.toc2{padding-left:15em;padding-right:0} +body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} #toc.toc2>ul{font-size:.9em;margin-bottom:0} @@ -209,19 +209,17 @@ .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere} .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} .exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px} -.exampleblock>.content>:first-child{margin-top:0} -.exampleblock>.content>:last-child{margin-bottom:0} .sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px} -.sidebarblock>:first-child{margin-top:0} -.sidebarblock>:last-child{margin-bottom:0} .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} -.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} +.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0} +.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} .literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em} @media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}} @media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}} .literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8} .literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)} .listingblock>.content{position:relative} +.listingblock pre>code{display:block} .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5} .listingblock:hover code[data-lang]::before{display:block} .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5} @@ -331,7 +329,7 @@ a.image object{pointer-events:none} sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} sup.footnote a,sup.footnoteref a{text-decoration:none} -sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline} +sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline} #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} @@ -394,7 +392,7 @@ dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em} p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} -p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem} +p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem} p{margin-bottom:1.25rem} .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} .exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc} @@ -443,7 +441,7 @@

json-formula Specification

PDF Association Forms Technical Working Group
version 2.0.0-beta.1, -2025-04-04 +2025-11-11
@@ -544,7 +542,7 @@

Scope

-

The intended audience are both end-users of json-formula as well as implementors; the contents are then both a user guide and a specification.

+

The intended audience are both end-users of json-formula as well as implementers; the contents are then both a user guide and a specification.

@@ -552,7 +550,7 @@

Scope

1. Notation

-

In the specification, examples are shown through the use of a search function. The syntax for this function is:

+

In the specification, examples are shown through the use of a search function called eval. The syntax for this function is:

@@ -601,8 +599,7 @@

2. Data Types

-

There is an additional type that is not a JSON type that’s used in -json-formula functions:

+

There is an additional type that is not a JSON type that’s used in json-formula functions:

    @@ -2516,8 +2513,7 @@

    9.2. Function evaluation

    Functions are evaluated in applicative order: - Each argument must be an expression -- Each argument expression must be evaluated before evaluating the -function +- Each argument expression must be evaluated before evaluating the function - Each argument expression result must be coerced to the expected type - If coercion is not possible, a TypeError error is raised - The function is then called with the evaluated function arguments.

    @@ -3000,9 +2996,9 @@

    9.3.8. casefold

    Description
    -

    Generates a lower-case string of the input string using -locale-specific mappings. e.g. Strings with German letter ß (eszett) can -be compared to "ss"

    +

    Generates a lower-case string of the input string +using locale-specific mappings. e.g. Strings with German letter ß +(eszett) can be compared to “ss”

    Returns
    @@ -3053,8 +3049,8 @@

    9.3.9. ceil

    Description
    -

    Finds the next highest integer value of the argument num -by rounding up if necessary. i.e. ceil() rounds toward positive +

    Finds the next highest integer value of the argument +num by rounding up if necessary. i.e. ceil() rounds toward positive infinity.

    Returns
    @@ -3158,10 +3154,10 @@

    9.3.11. contains

    Description
    -

    Determines if the given subject contains search. If -subject is an array, this function returns true if one of the elements -in the array is equal to the search value. If subject is a string, -return true if the string contains the search value.

    +

    Determines if the given subject contains search. +If subject is an array, this function returns true if one of the +elements in the array is equal to the search value. If subject +is a string, return true if the string contains the search value.

    Returns
    @@ -3278,21 +3274,24 @@

    9.3.13. datedif

    • -

      y the number of whole years between start_date and end_date

      +

      y the number of whole years between start_date and +end_date

    • -

      m the number of whole months between start_date and end_date.

      +

      m the number of whole months between start_date and +end_date.

    • d the number of days between start_date and end_date

    • -

      ym the number of whole months between start_date and end_date -after subtracting whole years.

      +

      ym the number of whole months between start_date and +end_date after subtracting whole years.

    • -

      yd the number of days between start_date and end_date, assuming -start_date and end_date were no more than one year apart

      +

      yd the number of days between start_date and end_date, +assuming start_date and end_date were no more than one year +apart

    @@ -3626,9 +3625,9 @@

    9.3.17. deepScan

    name

    string | integer

    The name (or index position) of the -elements to find. If name is a string, search for nested objects with -a matching key. If name is an integer, search for nested arrays with a -matching index.

    +elements to find. If name is a string, search for nested objects +with a matching key. If name is an integer, search for nested arrays +with a matching index.

    @@ -3658,8 +3657,8 @@

    9.3.18. endsWith

    Returns
    -

    boolean | Array.<boolean> - true if the suffix value -is at the end of the subject

    +

    boolean | Array.<boolean> - true if the suffix +value is at the end of the subject

    Parameters
    @@ -3712,9 +3711,9 @@

    9.3.19. entries

    Description
    -

    Returns an array of [key, value] pairs from an object or -array. The fromEntries() function may be used to convert an array to -an object.

    +

    Returns an array of [key, value] pairs from an object +or array. The fromEntries() function may be used to convert an array +to an object.

    Returns
    @@ -3882,7 +3881,7 @@

    9.3.22. false

    Description

    Return constant boolean false value. Expressions may also -use the JSON literal: `false`

    +use the JSON literal: \'false\'

    Returns
    @@ -3944,8 +3943,8 @@

    9.3.23. find

    integer | Array.<integer>

    0

    zero-based position to -start searching. If specified, start must be greater than or equal to -0

    +start searching. If specified, start must be greater than or equal +to 0

    @@ -3974,8 +3973,8 @@

    9.3.24. floor

    Description

    Calculates the next lowest integer value of the argument -num by rounding down if necessary. i.e. floor() rounds toward negative -infinity.

    +num by rounding down if necessary. i.e. floor() rounds toward +negative infinity.

    Returns
    @@ -4082,8 +4081,8 @@

    9.3.26. fromEntries

    Returns an object by transforming a list of key-value pairs into an object. fromEntries() is the inverse operation of -entries(). If the nested arrays are not of the form: [key, value] -(where key is a string), an error will be thrown.

    +entries(). If the nested arrays are not of the form: +[key, value] (where key is a string), an error will be thrown.

    Returns
    @@ -4224,8 +4223,8 @@

    9.3.28. hasProperty

    name

    string | integer

    The name (or index position) of the -element to find. if subject is an array, name must be an integer; if -subject is an object, name must be a string.

    +element to find. if subject is an array, name must be an +integer; if subject is an object, name must be a string.

    @@ -4307,8 +4306,8 @@

    9.3.30. if

    Description
    -

    Return one of two values result1 or result2, depending -on the condition

    +

    Return one of two values result1 or result2, +depending on the condition

    Returns
    @@ -5024,8 +5023,8 @@

    9.3.42. mid

    length

    integer

    The number of code points or elements to return from -the string or array. If greater then the length of subject the length -of the subject is used.

    +the string or array. If greater then the length of subject the +length of the subject is used.

    @@ -5281,8 +5280,8 @@

    9.3.47. mod

    Returns

    number | Array.<number> - Computes the remainder of -dividend/divisor. If dividend is negative, the result will also be -negative. If dividend is zero, an error is thrown.

    +dividend/divisor. If dividend is negative, the result will +also be negative. If dividend is zero, an error is thrown.

    Parameters
    @@ -5444,10 +5443,10 @@

    9.3.50. notNull

    Description
    -

    Finds the first argument that does not resolve to null. -This function accepts one or more arguments, and will evaluate them in -order until a non-null argument is encountered. If all arguments values -resolve to null, then return a null value.

    +

    Finds the first argument that does not resolve to +null. This function accepts one or more arguments, and will evaluate +them in order until a non-null argument is encountered. If all arguments +values resolve to null, then return a null value.

    Parameters
    @@ -5510,7 +5509,7 @@

    9.3.52. null

    Description

    Return constant null value. Expressions may also use the -JSON literal: `null`

    +JSON literal: \'null\'

    Returns
    @@ -5835,10 +5834,10 @@

    9.3.58. register

    functionName

    string

    -

    Name of the function to register. functionName -must begin with an underscore or uppercase letter and follow the regular -expression pattern: -^[_A-Z][_a-zA-Z0-9$]*$

    +

    Name of the function to register. +functionName must begin with an underscore or uppercase letter and +follow the regular expression pattern: +{caret}{startsb}_A-Z{endsb}{startsb}_a-zA-Z0-9${endsb}{asterisk}$

    expr

    @@ -5898,10 +5897,10 @@

    9.3.59. registerWithParams

    functionName

    string

    -

    Name of the function to register. functionName -must begin with an underscore or uppercase letter and follow the regular -expression pattern: -^[_A-Z][_a-zA-Z0-9$]*$

    +

    Name of the function to register. +functionName must begin with an underscore or uppercase letter and +follow the regular expression pattern: +{caret}{startsb}_A-Z{endsb}{startsb}_a-zA-Z0-9${endsb}{asterisk}$

    expr

    @@ -5976,18 +5975,19 @@

    9.3.60. replace

    length

    integer

    number of code points to be replaced. If start
    -length is greater than the length of subject, all text past start -will be replaced.

    +length is greater than the length of subject, all text past +start will be replaced.

    replacement

    any

    Replacement to insert at the start index. If -subject is an array, and replacement is an array, the replacement -array elements will be inserted into the subject array. If subject -is an array and replacement is not an array, the replacement will be -inserted as a single element in subject If subject is a string, the -replacement will be coerced to a string.

    +subject is an array, and replacement is an array, the +replacement array elements will be inserted into the subject +array. If subject is an array and replacement is not an array, the +replacement will be inserted as a single element in subject If +subject is a string, the replacement will be coerced to a +string.

    @@ -6191,14 +6191,15 @@

    9.3.64. round

    • -

      If precision is greater than zero, round to the specified number of -decimal places.

      +

      If precision is greater than zero, round to the specified number +of decimal places.

    • If precision is 0, round to the nearest integer.

    • -

      If precision is less than 0, round to the left of the decimal point.

      +

      If precision is less than 0, round to the left of the decimal +point.

    @@ -6269,12 +6270,12 @@
    Description

    Perform a wildcard search. The search is case-sensitive -and supports two forms of wildcards: * finds a sequence of -code points and ? finds a single code point. To use * or -? or \ as text values, precede them with an escape -(\) character. Note that the wildcard search is not greedy. -e.g. search("a*b", "abb") will return [0, "ab"] Not -[0, "abb"]

    +and supports two forms of wildcards: {asterisk} finds a sequence of +code points and ? finds a single code point. To use {asterisk} +or ? or {backslash} as text values, precede them with an escape +({backslash}) character. Note that the wildcard search is not +greedy. e.g. search("a{asterisk}b", "abb") will return [0, "ab"] +Not [0, "abb"]

    Returns
    @@ -6465,8 +6466,8 @@

    9.3.68. sin

    Returns
    -

    number | Array.<number> - The sine of angle, between --1 and 1, inclusive

    +

    number | Array.<number> - The sine of angle, +between -1 and 1, inclusive

    Parameters
    @@ -6975,8 +6976,8 @@

    9.3.77. stdevp

    Description

    Calculates standard deviation based on the entire -population given as arguments. stdevpA assumes that its arguments are -the entire population. If your data represents a sample of the +population given as arguments. stdevpA assumes that its arguments +are the entire population. If your data represents a sample of the population, then compute the standard deviation using [_stdevA]. Nested arrays are flattened. Null values are ignored. All other parameters are converted to number. If conversion to @@ -7032,10 +7033,10 @@

    9.3.78. substitute

    Description
    -

    Generates a string from the input text, with text old -replaced by text new (when searching from the left). If there is no -match, or if old has length 0, text is returned unchanged. Note that -old and new may have different lengths.

    +

    Generates a string from the input text, with text +old replaced by text new (when searching from the left). If +there is no match, or if old has length 0, text is returned +unchanged. Note that old and new may have different lengths.

    Returns
    @@ -7071,16 +7072,16 @@

    9.3.78. substitute

    new

    string | Array.<string>

    -

    The text to replace old with. If -new is an empty string, then occurrences of old are removed from -text.

    +

    The text to replace old with. +If new is an empty string, then occurrences of old are removed +from text.

    [which]

    integer | Array.<integer>

    The zero-based occurrence of -old text to replace with new text. If which parameter is omitted, -every occurrence of old is replaced with new.

    +old text to replace with new text. If which parameter is +omitted, every occurrence of old is replaced with new.

    @@ -7377,7 +7378,7 @@

    9.3.83. toDate

    ISO8601 formatted string. (limited to the RFC 3339 profile) If the string does not include a timezone offset (or -trailing `Z'), it will be assumed to be local time

    +trailing ‘Z’), it will be assumed to be local time

    @@ -7611,7 +7612,7 @@

    9.3.88. true

    Description

    Return constant boolean true value. Expressions may also -use the JSON literal: `true`

    +use the JSON literal: \'true\'

    Returns
    @@ -7900,10 +7901,10 @@

    9.3.93. value

    index

    string | integer

    -

    if subject is an object, index must -be a string indicating the key name to search for. If subject is an -array, then index must be an integer indicating the offset into the -array

    +

    if subject is an object, index +must be a string indicating the key name to search for. If subject +is an array, then index must be an integer indicating the offset into +the array

    @@ -8271,7 +8272,7 @@

    10.6. Tracking

    diff --git a/doc/output/json-formula-specification-2.0.0-beta.1.pdf b/doc/output/json-formula-specification-2.0.0-beta.1.pdf index a0294ebd..f57b0d19 100644 Binary files a/doc/output/json-formula-specification-2.0.0-beta.1.pdf and b/doc/output/json-formula-specification-2.0.0-beta.1.pdf differ diff --git a/doc/scripts/makeDocs.sh b/doc/scripts/makeDocs.sh old mode 100644 new mode 100755 diff --git a/doc/spec.adoc b/doc/spec.adoc index 7186b062..0c8f152a 100644 --- a/doc/spec.adoc +++ b/doc/spec.adoc @@ -1,6 +1,6 @@ = json-formula Specification PDF Association Forms Technical Working Group -0.2.0, {docdate}: +2.0.0, {docdate}: :toc: macro :outlinelevels: 3 :appendix-caption: Appendix @@ -26,13 +26,13 @@ The grammar borrows from * https://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part2.html[OpenFormula] for spreadsheet operators and function * https://jmespath.org/[JMESPath] for JSON query semantics -The intended audience are both end-users of json-formula as well as implementors; the contents are then both a user guide and a specification. +The intended audience are both end-users of json-formula as well as implementers; the contents are then both a user guide and a specification. // start numbering the sections from here... :sectnums: == Notation -In the specification, examples are shown through the use of a `search` function. The syntax for this function is: +In the specification, examples are shown through the use of a `search` function called `eval`. The syntax for this function is: [source%unbreakable] ---- @@ -59,8 +59,7 @@ json-formula supports all the JSON types: * object: an unordered collection of key value pairs * `null` -There is an additional type that is not a JSON type that's used in -json-formula functions: +There is an additional type that is not a JSON type that's used in json-formula functions: * expression: A string prefixed with an ampersand (`&`) character @@ -1250,8 +1249,7 @@ With nested arrays: Functions are evaluated in applicative order: - Each argument must be an expression -- Each argument expression must be evaluated before evaluating the -function +- Each argument expression must be evaluated before evaluating the function - Each argument expression result must be coerced to the expected type - If coercion is not possible, a `TypeError` error is raised - The function is then called with the evaluated function arguments. diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index bd8ee1dd..a8eee117 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@adobe/json-formula", - "version": "1.1.1", + "version": "2.0.0-beta.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@adobe/json-formula", - "version": "1.1.1", + "version": "2.0.0-beta.1", "license": "Apache-2.0", "devDependencies": { "@babel/core": "^7.23.6", @@ -27,7 +27,7 @@ "html-webpack-plugin": "^5.6.0", "jest": "^29.3.1", "jest-cli": "^29.7.0", - "jsdoc": "^4.0.2", + "jsdoc": "^4.0.5", "jsdoc-to-markdown": "^8.0.0", "webpack": "^5.89.0", "webpack-cli": "^5.0.0", @@ -3225,26 +3225,29 @@ "dev": true }, "node_modules/@types/linkify-it": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", - "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true, + "license": "MIT" }, "node_modules/@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, + "license": "MIT", "dependencies": { - "@types/linkify-it": "*", - "@types/mdurl": "*" + "@types/linkify-it": "^5", + "@types/mdurl": "^2" } }, "node_modules/@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true, + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", @@ -9868,21 +9871,22 @@ } }, "node_modules/jsdoc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", - "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.5.tgz", + "integrity": "sha512-P4C6MWP9yIlMiK8nwoZvxN84vb6MsnXcHuy7XzVOvQoCizWX5JFCBsWIIWKXBltpoRZXddUOVQmCTOZt9yDj9g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@babel/parser": "^7.20.15", "@jsdoc/salty": "^0.2.1", - "@types/markdown-it": "^12.2.3", + "@types/markdown-it": "^14.1.1", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", - "markdown-it": "^12.3.2", - "markdown-it-anchor": "^8.4.1", + "markdown-it": "^14.1.0", + "markdown-it-anchor": "^8.6.7", "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", @@ -10086,12 +10090,13 @@ "dev": true }, "node_modules/linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, + "license": "MIT", "dependencies": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" } }, "node_modules/loader-runner": { @@ -10210,19 +10215,21 @@ } }, "node_modules/markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "bin": { - "markdown-it": "bin/markdown-it.js" + "markdown-it": "bin/markdown-it.mjs" } }, "node_modules/markdown-it-anchor": { @@ -10235,6 +10242,19 @@ "markdown-it": "*" } }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", @@ -10248,10 +10268,11 @@ } }, "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" }, "node_modules/media-typer": { "version": "0.3.0", @@ -11114,6 +11135,16 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -12783,10 +12814,11 @@ "dev": true }, "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" }, "node_modules/uglify-js": { "version": "3.17.4", diff --git a/package.json b/package.json index 01bd4dd7..239905da 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "html-webpack-plugin": "^5.6.0", "jest": "^29.3.1", "jest-cli": "^29.7.0", - "jsdoc": "^4.0.2", + "jsdoc": "^4.0.5", "jsdoc-to-markdown": "^8.0.0", "webpack": "^5.89.0", "webpack-cli": "^5.0.0", diff --git a/src/json-formula.js b/src/json-formula.js index 6dc45615..8ddc925f 100644 --- a/src/json-formula.js +++ b/src/json-formula.js @@ -13,6 +13,59 @@ import Formula from './interpreter.js'; export { dataTypes } from './dataTypes.js'; +/** +// data type constants re-exported from dataTypes.js +// which represent the various data types supported by json-formula function params +@enum {Number} + // Type constants used to define functions. + const dataTypes = { + TYPE_NUMBER: 0, + TYPE_ANY: 1, + TYPE_STRING: 2, + TYPE_ARRAY: 3, + TYPE_OBJECT: 4, + TYPE_BOOLEAN: 5, + TYPE_EXPREF: 6, + TYPE_NULL: 7, + TYPE_ARRAY_NUMBER: 8, + TYPE_ARRAY_STRING: 9, + TYPE_ARRAY_ARRAY: 10, + TYPE_EMPTY_ARRAY: 11, + }; + */ + +/** + * @typedef {object} CustomFunctionDefinition + * @property {Function} _func - The function implementation + * @property {array} [_signature] - Function signature metadata + * @example + // simple custom functions definition + const customFunctions = { + true_fn: { + _func: () => true, + _signature: [], + }, + false_fn: { + _func: () => false, + _signature: [], + }, + }; + + @example + // complex custom function with a signature (for its parameters) + customEval: { + // eslint-disable-next-line no-underscore-dangle + _func: ([str, fn]) => customFunctions.customEval._runtime.interpreter.visit(fn, str), + _signature: [{ types: [TYPE_STRING] }, { types: [TYPE_EXPREF] }], + }, + + **NOTE:** Another way to register custom functions is via the `register` method + given two strings - name and code - register the function with that name using that code + const regFormula = 'register("' + name + '", &' + code + ')'; + this.search(regFormula, {}, globals); // Run the registration formula with empty data and globals + + */ + /** * Class represents an instance of a JsonFormula Expression that can be executed later on with * multiple instances of JSON Data. The instance of the class has a search @@ -23,7 +76,6 @@ class JsonFormula { * @param {object} [customFunctions={}] custom functions needed by a hosting application. * @param {function} [stringToNumber='null'] A function that converts string values to numbers. * Can be used to convert currencies/dates to numbers - * @param {string} [language=en-US] * @param {array} [debug=[]] will be populated with any errors/warnings */ constructor( @@ -37,10 +89,23 @@ class JsonFormula { this.formula = new Formula(debug, customFunctions, stringToNumber); } + /** + * @typedef {object} globals + * An object where each key **MUST** begin with a `$` character, representing global variables + * that can be accessed inside a json-formula expression. + * The value of each key can be of any data type supported by json. + * + * @example + * $foo: true, $bar: 42, $baz: 'hello', $arr: [1, 2, 3], '$days': [ + 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] + */ + /** * Evaluates the JsonFormula on a particular json payload and return the result + * @param {string} expression the json-formula expression to evaluate * @param {object|array} json the json data on which the expression needs to be evaluated * @param {object} [globals={}] global objects that can be accessed via custom functions. + * @param {string} [language=en-US] BCP-47 language tag * @returns {*} the result of the expression being evaluated */ search(expression, json, globals = {}, language = 'en-US') { @@ -50,6 +115,8 @@ class JsonFormula { /** * Execute a previously compiled expression against a json object and return the result + * + * @deprecated since version 2.0.0. Use search() method instead. * @param {object} ast The abstract syntax tree returned from compile() * @param {object|array} json the json data on which the expression needs to be evaluated * @param globals {*} set of objects available in global scope @@ -66,7 +133,9 @@ class JsonFormula { /** * Creates a compiled expression that can be executed later on with some data. - * @param {string} expression the expression to evaluate + * + * @deprecated since version 2.0.0, since it is just used with `run()` + * @param {string} expression the json-formula expression to evaluate * @param {string[]} [allowedGlobalNames=[]] A list of names of the global variables * being used in the expression. * @param {array} [debug=[]] will be populated with any errors/warnings @@ -83,12 +152,12 @@ class JsonFormula { * class instance of {JsonFormula} and call the search method multiple times. * @param {object|array} json the json data on which the expression needs to be evaluated * @param {object} globals global objects that can be accessed via custom functions. -* @param {string} expression the expression to evaluate +* @param {string} expression the json-formula expression to evaluate * @param {object} [customFunctions={}] custom functions needed by a hosting application. * @param {function} [stringToNumber='null'] A function that converts string values to numbers. * Can be used to convert currencies/dates to numbers -* @param {string} [language=en-US] * @param {array} [debug=[]] will be populated with any errors/warnings +* @param {string} [language=en-US] BCP-47 language tag * @returns {*} the result of the expression being evaluated */