fig-tree-evaluator 2.23.2 → 3.0.0-preview.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js ADDED
@@ -0,0 +1 @@
1
+ import{j as e,O as t,k as a,l as r,E as n,c as o,m as s,N as u,b as c,R as p,n as m,o as f,p as y,e as h,q as v,u as g,w,x as j,y as P,z as $,t as k,s as O,g as q,A,B as x}from"./chunks/engine.js";export{C as ARRAY,F as FigTree,D as OBJECT,G as compareValues,d as coreOperators,H as deepEqual,i as isTruthy}from"./chunks/engine.js";import{a as N,E,m as L,R as S,F as T,n as Q,r as R,e as z,D as J,o as U}from"./chunks/shared.js";export{W as WILDCARD,b as isFigTreeError,l as parsePath}from"./chunks/shared.js";const V=/*#__PURE__*/new Set(["failures","external","output"]),M=/*#__PURE__*/new Set(["code","parameter","when","options","may","overflow"]),B=t=>{if(null===t||["string","number","boolean"].includes(typeof t))return!0;if(!N(t))return!1;const a=Object.keys(t);if(1!==a.length)return!1;const r=t[a[0]];switch(a[0]){case"type":return e(r);case"below":return"number"==typeof r&&Number.isFinite(r);case"empty":case"invalid":return!0===r;case"supplied":return"boolean"==typeof r;case"some":case"not":return B(r);default:return!1}},I=["param","elementOf","kindOf","typeNamedBy","firstNonNull","sum","product","abs","min","max"],Y=e=>void 0===e||"number"==typeof e&&Number.isFinite(e),K=e=>void 0===e||Number.isInteger(e)&&e>=0,X=(e,t,...a)=>t in e&&Object.keys(e).every(e=>e===t||a.includes(e)),Z=(t,a)=>{if(e(t))return!0;if(!N(t))return!1;const r=Object.keys(t);return 1===r.length&&I.includes(r[0])?a(t[r[0]]):"type"in t?(e=>{const{type:t,min:a,max:r,minLength:n}=e;return"number"===t||"integer"===t?X(e,"type","min","max")&&Y(a)&&Y(r)&&!(a>r):("string"===t||"array"===t)&&X(e,"type","minLength")&&K(n)})(t):X(t,"difference")?Array.isArray(t.difference)&&2===t.difference.length&&t.difference.every(a):X(t,"arrayOf","minLength")?K(t.minLength)&&Z(t.arrayOf,a):X(t,"oneOf")?Array.isArray(t.oneOf)&&t.oneOf.length>0&&t.oneOf.every(e=>Z(e,a)):!(!X(t,"byParam","cases","otherwise")||!("cases"in t))&&(a(t.byParam)&&N(t.cases)&&Object.values(t.cases).every(e=>Z(e,a))&&(void 0===t.otherwise||Z(t.otherwise,a)))},_=/[a-z]Default$/,ee=/*#__PURE__*/new Set(["eager","race","lazy","lazyElements","lazyEntries","perElement","structural"]),te=/*#__PURE__*/new Set(t),ae=e=>"array"===e||"any"===e||!!Array.isArray(e)&&(e.includes("array")||e.includes("any")),re=e=>"array"===e||"object"===e||"any"===e||!!Array.isArray(e)&&(e.includes("array")||e.includes("object")||e.includes("any")),ne=(e,t)=>{const[a]=e,r=e.length-1,n=r>0?`${a.message} (+ ${r} more issue${1===r?"":"s"})`:a.message;throw new T({code:E.invalidDefinition,message:n,path:a.path,...void 0!==t?{operator:t}:{},issues:e})};function ie(t){if(a(t))return t;const i=[],l=N(t)?t.name:void 0,d="string"==typeof l?l:void 0,y=(e,t,a,r)=>{i.push({severity:"error",code:e,message:t,path:a,...void 0!==d?{operator:d}:{},...void 0!==r?{parameter:r}:{}})};N(t)||(y(E.invalidDefinition,"a definition must be a plain object",[]),ne(i));const h=t;"string"!=typeof h.name&&y(E.invalidDefinition,"'name' is required and must be a string",["name"]),"string"==typeof h.description&&""!==h.description||y(E.invalidDefinition,"'description' is required and must be non-empty",["description"]),N(h.parameters)||y(E.invalidDefinition,"'parameters' is required and must be an object of declarations (may be {})",["parameters"]),"function"!=typeof h.evaluate&&y(E.invalidDefinition,"'evaluate' is required and must be a function",["evaluate"]),i.length>0&&ne(i,d),"string"!=typeof h.category?y(E.invalidDefinition,`'category' is required and must be one of ${[...te].join(", ")}`,["category"]):te.has(h.category)||y(E.invalidDefinition,`'${h.category}' is not a category — expected one of ${[...te].join(", ")}`,["category"]),void 0!==h.alias&&"string"!=typeof h.alias&&y(E.invalidDefinition,"'alias' must be a string",["alias"]),void 0!==h.cache&&!0!==h.cache&&y(E.invalidDefinition,"'cache' must be the literal true",["cache"]),void 0===h.metadata||N(h.metadata)||y(E.invalidDefinition,"'metadata' must be a plain object",["metadata"]),void 0===h.positionalParams||Array.isArray(h.positionalParams)&&!h.positionalParams.some(e=>"string"!=typeof e)||y(E.invalidDefinition,"'positionalParams' must be an array of parameter names",["positionalParams"]),void 0!==h.timeoutParam&&"string"!=typeof h.timeoutParam&&y(E.invalidDefinition,"'timeoutParam' must be a parameter name",["timeoutParam"]),void 0!==h.validate&&"function"!=typeof h.validate&&y(E.invalidDefinition,"'validate' must be a function",["validate"]),void 0===h.returns||e(h.returns)||y(E.invalidDefinition,"'returns' must be a metadata-vocabulary type",["returns"]);const v=(e,t,a)=>{e===n?y(E.invalidDefinition,"the EvaluationData sentinel is legal only as a parameter 'default'",t,a):Array.isArray(e)&&e.forEach((e,r)=>{e===n&&v(e,[...t,r],a)})};for(const[e,t]of Object.entries(h))"parameters"!==e&&"metadata"!==e&&v(t,[e]);const b=(e,t)=>{const a=L(e);a.ok?Q.has(e)&&y(E.reservedName,`'${e}' is a reserved name`,t):y(E.invalidName,`'${e}': ${a.reason}`,t)};"string"==typeof h.name&&b(h.name,["name"]),"string"==typeof h.alias&&b(h.alias,["alias"]);const g=h.parameters,w={};for(const[e,t]of Object.entries(g)){const a=["parameters",e],r=L(e);r.ok?S.has(e)&&y(E.reservedName,`'${e}' is a reserved node key and cannot name a parameter`,a,e):y(E.invalidName,`'${e}': ${r.reason}`,a,e),N(t)?w[e]=t:y(E.invalidDefinition,`the declaration for '${e}' must be a plain object`,a,e)}const j={};for(const[t,a]of Object.entries(w)){const i=["parameters",t],l=e=>[...i,e],d=a;for(const[e,a]of Object.entries(d))"default"!==e&&"metadata"!==e&&v(a,l(e),t);let p=!0;void 0===d.type||e(d.type)||(y(E.invalidDefinition,"'type' must be a metadata-vocabulary type",l("type"),t),p=!1),p&&(j[t]=d.type??"any");let m=!1;if(void 0!==d.constraints){const e=r(d.constraints);e.ok?m=!0:y(E.invalidDefinition,`'constraints' is malformed: expected ${e.expected}, got ${e.actual}`,l("constraints"),t)}void 0!==d.required&&"boolean"!=typeof d.required&&y(E.invalidDefinition,"'required' must be a boolean",l("required"),t),void 0!==d.description&&"string"!=typeof d.description&&y(E.invalidDefinition,"'description' must be a string",l("description"),t),void 0===d.metadata||N(d.metadata)||y(E.invalidDefinition,"'metadata' must be a plain object",l("metadata"),t);const f="default"in d;if(f&&!0===d.required&&y(E.invalidDefinition,"a 'default' contradicts 'required: true' — a default implies the parameter is optional",l("default"),t),f&&d.default!==n){const e=j[t];if(void 0!==e){const a=o(d.default,e);if(a.ok){if(m&&void 0!==d.constraints){const e=s(d.default,d.constraints);e.ok||y(E.typeCheck,`'default' violates the declared constraints: expected ${e.expected}, got ${e.actual}`,l("default"),t)}}else y(E.typeCheck,`'default' does not satisfy the declared type: expected ${a.expected}, got ${a.actual}`,l("default"),t)}}if(void 0===d.evaluation||ee.has(d.evaluation)||y(E.invalidDefinition,`'evaluation' must be one of ${[...ee].join(", ")}`,l("evaluation"),t),void 0!==d.truthiness&&"boolean"!=typeof d.truthiness&&y(E.invalidDefinition,"'truthiness' must be a boolean",l("truthiness"),t),void 0!==d.over&&"string"!=typeof d.over&&y(E.invalidDefinition,"'over' must be a parameter name",l("over"),t),void 0===d.replacesNullAt||Array.isArray(d.replacesNullAt)&&!d.replacesNullAt.some(e=>"string"!=typeof e)||y(E.invalidDefinition,"'replacesNullAt' must be an array of sibling parameter names",l("replacesNullAt"),t),void 0!==d.nullPolicy){const e=d.nullPolicy;"function"==typeof e||u.has(e)||y(E.invalidNullPolicy,"'nullPolicy' must be 'propagate', 'value' or a conditional function",l("nullPolicy"),t);const a=j[t];void 0===a||c(a)||y(E.invalidNullPolicy,"'nullPolicy' is legal only where the declared type names 'null' — a type without 'null' is the reject declaration",l("nullPolicy"),t),!0===d.truthiness&&"propagate"===e&&y(E.invalidNullPolicy,"'truthiness' implies null policy 'value' (null is falsy) — declaring 'propagate' is a conflict",l("nullPolicy"),t)}if(void 0!==d.elementNullPolicy){u.has(d.elementNullPolicy)||y(E.invalidNullPolicy,"'elementNullPolicy' must be 'propagate' or 'value' — the conditional form is not admitted here",l("elementNullPolicy"),t);const e=j[t];void 0===e||re(e)||y(E.invalidNullPolicy,"'elementNullPolicy' applies to container parameters only",l("elementNullPolicy"),t)}}if(Array.isArray(h.positionalParams)&&h.positionalParams.every(e=>"string"==typeof e)){const e=new Set,t=h.positionalParams;t.forEach((a,r)=>{const n=a.startsWith(p),i=n?a.slice(p.length):a;n&&r!==t.length-1&&y(E.invalidDefinition,`the rest entry '${a}' must be the last positional entry`,["positionalParams",r]),i in w||y(E.invalidDefinition,`positional entry '${a}' names no declared parameter`,["positionalParams",r]),e.has(i)&&y(E.invalidDefinition,`duplicate positional entry '${a}'`,["positionalParams",r]),e.add(i)})}for(const[e,t]of Object.entries(w)){const a=["parameters",e],r="perElement"===t.evaluation;if(void 0!==t.over&&"string"==typeof t.over)if(r){const r=t.over;if(r in w&&r!==e){const t=j[r];void 0===t||ae(t)||y(E.invalidDefinition,`the 'over' target '${r}' must admit an array`,[...a,"over"],e)}else y(E.invalidDefinition,`'over' names no sibling parameter ('${r}')`,[...a,"over"],e)}else y(E.invalidDefinition,"'over' is legal only with evaluation: 'perElement'",[...a,"over"],e);else r&&y(E.invalidDefinition,"evaluation: 'perElement' requires 'over' to name the iterated sibling",[...a,"evaluation"],e)}for(const[e,t]of Object.entries(w)){if(void 0===t.replacesNullAt)continue;if(!Array.isArray(t.replacesNullAt)||t.replacesNullAt.some(e=>"string"!=typeof e))continue;const a=["parameters",e,"replacesNullAt"];"lazy"!==t.evaluation&&y(E.invalidDefinition,"a 'replacesNullAt' holder must declare evaluation: 'lazy'",a,e);(t.required??!("default"in t))&&y(E.invalidDefinition,"a 'replacesNullAt' holder must be optional",a,e),"default"in t&&y(E.invalidDefinition,"a 'replacesNullAt' holder may not carry a 'default' — it is presence-sensitive by construction",a,e),t.replacesNullAt.forEach((t,r)=>{t===e?y(E.invalidDefinition,"'replacesNullAt' may not target the holder itself",[...a,r],e):t in w||y(E.invalidDefinition,`'replacesNullAt' target '${t}' names no sibling parameter`,[...a,r],e)})}for(const[e,t]of Object.entries(w))_.test(e)&&"lazy"!==t.evaluation&&y(E.invalidDefinition,`'${e}' is named for the '…Default' family, so it must declare evaluation: 'lazy' — add 'replacesNullAt', read it as a LazyValue in the body, or rename it`,["parameters",e,"evaluation"],e);const P=m(w,j,y);if("string"==typeof h.timeoutParam){void 0===w[h.timeoutParam]?y(E.invalidDefinition,`'timeoutParam' names no declared parameter ('${h.timeoutParam}')`,["timeoutParam"]):"integer"!==j[h.timeoutParam]&&y(E.invalidDefinition,"the 'timeoutParam' target must be 'integer'-typed",["timeoutParam"])}return void 0!==h.analysis&&((e,t,a)=>{const r=(e,...t)=>a(E.invalidDefinition,e,["analysis",...t]);if(!N(e))return r("'analysis' must be a plain object");for(const t of Object.keys(e))V.has(t)||r(`'${t}' is not an analysis field`,t);const{failures:n,external:i,output:o}=e,s=e=>"string"==typeof e&&Object.hasOwn(t,e);if(void 0!==i&&!0!==i&&r("'external' must be the literal true","external"),void 0===o||Z(o,s)||r("'output' must be a type, or an output declaration naming declared parameters","output"),void 0!==n){if(!Array.isArray(n))return r("'failures' must be an array of rules","failures");!0===i&&r("an external operator declares no 'failures': it may fail whatever its inputs","failures"),n.forEach((e,t)=>{const a=(...e)=>["failures",t,...e];if(!N(e))return r("a rule must be a plain object",...a());for(const t of Object.keys(e))M.has(t)||r(`'${t}' is not a rule field`,...a(t));if("string"==typeof e.code&&""!==e.code||r("a rule's 'code' must be a non-empty string",...a("code")),void 0===e.parameter||s(e.parameter)||r("'parameter' names no declared parameter",...a("parameter")),void 0!==e.when)if(N(e.when))for(const[t,n]of Object.entries(e.when))s(t)?B(n)||r(`the test on '${t}' is malformed`,...a("when",t)):r(`'${t}' is not a declared parameter`,...a("when",t));else r("'when' must be an object of tests",...a("when"));void 0===e.options||N(e.options)||r("'options' must be a plain object",...a("options"));for(const t of["may","overflow"])void 0!==e[t]&&!0!==e[t]&&r(`'${t}' must be the literal true`,...a(t))})}})(h.analysis,w,(e,t,a)=>y(e,t,a)),i.length>0&&ne(i,d),f(h,P)}const oe=e=>new y(`request failed (${e.status}): ${e.url}`,{code:E.httpStatus,errorData:{status:e.status,statusText:e.statusText,url:e.url,response:de(e.response)}}),se=(e,t,a)=>new y(e,{code:E.invalidResponse,errorData:{url:t,response:de(a)}}),le=(e,t)=>{const a=t instanceof Error?t.message:String(t),r=t??{},n={driver:e};"string"==typeof r.code&&(n.driverCode=r.code);for(const e of["table","column","constraint"])"string"==typeof r[e]&&(n[e]=r[e]);return new y(`${e}: ${a}`,{code:E.sqlError,errorData:n})},ue={http:{"http-status":{status:"number",statusText:"string",url:"string",response:"any"},"invalid-response":{url:"string",response:"any"}},sql:{"sql-error":{driver:"string",driverCode:["string","null"]}}},ce=async(e,t)=>{try{return await e()}catch(e){throw((e,t)=>{const a=ue[t];if(h(e)&&void 0!==e.code&&Object.hasOwn(a,e.code)){const t=e.errorData??{},r=a[e.code];if(Object.entries(r).every(([e,a])=>o(t[e]??null,a).ok))return e}return new y(e instanceof Error?e.message:String(e),{code:E.requestFailure})})(e,t)}},de=(e,t=500)=>"string"!=typeof e||e.length<=t?e:`${e.slice(0,t)}… (${e.length} characters)`;class pe{supplied;constructor(e){if(void 0===e&&"function"!=typeof globalThis.fetch)throw new y("FetchClient(): this runtime has no global fetch — pass one, new FetchClient(myFetch), or use another client such as new AxiosClient(axios)");this.supplied=e}request=async e=>{const t=this.supplied??globalThis.fetch,a=await t.call(globalThis,e.url,{method:e.method.toUpperCase(),headers:e.headers,...void 0!==e.body?{body:JSON.stringify(e.body)}:{},signal:e.signal}),r=await a.text();if(!a.ok)throw oe({status:a.status,statusText:a.statusText,url:a.url||e.url,response:ye(r)});return fe(r,a.url||e.url,a.status)}}class me{axios;constructor(e){if(this.axios=e,"function"!=typeof e||"function"!=typeof e.isAxiosError)throw new y("AxiosClient(axios): pass the axios import itself — new AxiosClient(axios)")}request=async e=>{try{const t=await this.axios({url:e.url,method:e.method,headers:e.headers,...void 0!==e.body?{data:e.body}:{},signal:e.signal});return""===t.data||void 0===t.data?null:t.data}catch(t){if(this.axios.isAxiosError(t)&&t.response)throw oe({status:t.response.status,statusText:t.response.statusText,url:t.config?.url??e.url,response:t.response.data});throw t}}}const fe=(e,t,a)=>{if(""===e.trim())return null;try{return JSON.parse(e)}catch{throw se(`response was not JSON (${a}): ${t}`,t,e)}},ye=e=>{if(""===e.trim())return null;try{return JSON.parse(e)}catch{return e}},he=/^https?:\/\//i,ve=(e,t,a)=>{const r=he.test(e)?e:be(a,e),n=ge(t),i=""===n?r:`${r}${r.includes("?")?"&":"?"}${n}`;try{new URL(i)}catch{throw new y(`'${i}' is not a valid URL`,{code:E.typeCheck})}return i},be=(e,t)=>{if(void 0===e||""===e)throw new y(`'${t}' is a relative URL and no http.baseEndpoint is configured`,{code:E.typeCheck});return""===t?e:`${e.replace(/\/$/,"")}/${t.replace(/^\//,"")}`},ge=e=>{if(void 0===e)return"";const t=new URLSearchParams;for(const[a,r]of Object.entries(e))null!=r&&t.append(a,Pe(r,`query['${a}']`,"query"));return t.toString()},we=(...e)=>{const t={};for(const a of e)if(void 0!==a)for(const[e,r]of Object.entries(a))null!=r?t[e]=Pe(r,`headers['${e}']`,"header"):delete t[e];return t},je=e=>({Accept:"application/json",...e?{"Content-Type":"application/json"}:{}}),Pe=(e,t,a)=>{if("string"==typeof e||"number"==typeof e||"boolean"==typeof e)return g(e);throw new y(`${t} is ${w(e)} — a ${a} value must be a string, number or boolean; render it explicitly (join) or supply a fully-formed URL`,{code:E.typeCheck})},$e=e=>({method:e.method,url:e.url,headers:Object.fromEntries(Object.entries(e.headers).sort(([e],[t])=>e<t?-1:e>t?1:0)),...void 0!==e.body?{body:e.body}:{}}),ke=e=>Array.isArray(e)?e.length>0:N(e)?Object.keys(e).length>0:null!=e,De=(e,t)=>{if(void 0===t)return e;const a=R(e,v(t));return a.found?void 0===a.value?null:a.value:null},Oe=(e,t)=>{if(!N(e))throw new y("a row was not an object");const a=Object.values(e);if(1!==a.length)throw new y(`shape: '${t}' needs a single-column result — this row has ${a.length} columns; name the one column you want in the SQL`,{code:E.typeCheck});return a[0]},qe={type:"integer",required:!1,description:"Per-request deadline in ms; expiry is an ordinary failure this node’s fallback catches"},Ae={type:["string","array"],required:!1,description:"Dot/bracket path or segments array applied to the response; a miss is null"},xe=e=>P({name:"http",category:"io",description:"One HTTP request — GET or POST — returning the parsed JSON response",parameters:{url:{type:"string",description:"A full http(s) URL is used verbatim; anything else — including an empty string — joins http.baseEndpoint"},method:{type:{literal:["get","post"]},default:"get",description:"Lowercase; the mutating verbs are deliberately absent — an expression is a read"},query:{type:"object",required:!1,elementNullPolicy:"value",description:"Query-string pairs; a null value omits its pair, a composite one is an error"},body:{type:["string","number","boolean","array","object"],required:!1,description:"The JSON payload; a whole-null body means NO body, while nulls inside one are JSON nulls"},headers:{type:"object",required:!1,elementNullPolicy:"value",description:"Merged over the http.headers option per key; a null value removes an inherited pair"},returnPath:Ae,timeout:qe},positionalParams:["url"],timeoutParam:"timeout",cache:!0,returns:"any",validate:({returnPath:e,method:t,body:a})=>[...$(e,"returnPath"),...Ce(t,a)],evaluate:async({url:t,method:a,query:r,body:n,headers:i,returnPath:o},s)=>{if("get"===a&&void 0!==n)throw new y("a GET carries no body — did you mean method: 'post'?",{code:E.typeCheck});const l={method:a,url:ve(t,r,s.options.http?.baseEndpoint),headers:we(je(void 0!==n),s.options.http?.headers,i),...void 0!==n?{body:n}:{}},u=await s.cache.memo($e(l),()=>(Te(s,l),ce(()=>e.request({...l,signal:s.signal}),"http")));return De(u,o)}}),Ne=e=>P({name:"graphQL",category:"io",description:"One GraphQL query — a POST of { query, variables } — returning the data field",parameters:{query:{type:"string",description:"The GraphQL document — the protocol’s own word, as sql.query is"},variables:{type:"object",required:!1,elementNullPolicy:"value",description:"Query variables; a null value is CARRIED as JSON null, a nullable argument being meaningful GraphQL"},url:{type:"string",required:!1,description:"Per-node endpoint override; unset means the graphQL.endpoint option"},headers:{type:"object",required:!1,elementNullPolicy:"value",description:"Merged over http.headers then graphQL.headers; a null value removes a pair"},returnPath:Ae,timeout:qe},positionalParams:["query","variables"],timeoutParam:"timeout",cache:!0,returns:"any",validate:({returnPath:e})=>$(e,"returnPath"),evaluate:async({query:t,variables:a,url:r,headers:n,returnPath:i},o)=>{const s=r??o.options.graphQL?.endpoint;if(void 0===s)throw new y("no endpoint — supply url, or set the graphQL.endpoint option");const l={method:"post",url:ve(s,void 0,o.options.http?.baseEndpoint),headers:we(je(!0),o.options.http?.headers,o.options.graphQL?.headers,n),body:{query:t,...ke(a)?{variables:a}:{}}},u=await o.cache.memo($e(l),async()=>{Te(o,l);return((e,t)=>{if(!N(e))throw se("the GraphQL response was not an object",t,e);const a=e.errors;if(Array.isArray(a)&&a.length>0){const e=a[0]?.message;throw new y(`the GraphQL response carried ${a.length} error${1===a.length?"":"s"}`+("string"==typeof e?`: ${e}`:""),{code:E.graphQLErrors,errorData:{errors:a}})}if(!("data"in e))throw se("the GraphQL response carried neither data nor errors",t,e);return e.data??null})(await ce(()=>e.request({...l,signal:o.signal}),"http"),l.url)});return De(u,i)}}),Ee=e=>P({name:"sql",category:"io",description:"One SQL query against the registered connection. Expressions are READS — give the connection a read-only role and run mutations host-side",parameters:{query:{type:"string",description:"SQL text with the driver’s own placeholders — FigTree never parses SQL"},values:{type:["array","object"],required:!1,elementNullPolicy:"value",description:"Bind values — positional as an array, named as an object; a null binds SQL NULL"},shape:{type:{literal:["rows","firstRow","column","firstValue"]},default:"rows",description:"rows: every row object; firstRow: the first; column: one column’s values; firstValue: one scalar"},noRowDefault:{type:"any",required:!1,default:null,nullPolicy:"value",evaluation:"lazy",description:"The answer when firstRow / firstValue find no row — never for rows / column, never on failure"},timeout:qe},positionalParams:["query","...values"],timeoutParam:"timeout",cache:!0,returns:"any",evaluate:async({query:t,values:a,shape:r,noRowDefault:n},i)=>{const o={text:t,...ke(a)?{values:a}:{}};return(async(e,t,a)=>{switch(t){case"rows":return e;case"firstRow":return 0===e.length?a.evaluate():e[0];case"column":return e.map(e=>Oe(e,"column"));case"firstValue":return 0===e.length?a.evaluate():Oe(e[0],"firstValue")}})(await i.cache.memo(o,()=>(i.trace.note({type:"query",text:o.text}),ce(()=>e.query({...o,signal:i.signal}),"sql"))),r,n)}}),Ce=(e,t)=>void 0!==t&&"get"===e?[{severity:"error",parameter:"body",message:"a GET carries no body — add method: 'post', or drop the body"}]:[],Le=(e=new pe)=>[j(xe(e)),j(Ne(e))],Se=e=>[j(Ee(e))],Te=(e,t)=>{e.trace.note({type:"request",method:t.method,url:t.url,headers:Object.keys(t.headers)})};class Qe{client;constructor(e){if(this.client=e,"function"!=typeof e?.query)throw new y("PostgresConnection(client): pass a connected node-postgres Client or Pool")}query=async e=>{if(void 0!==e.values&&!Array.isArray(e.values))throw le("postgres","takes positional binds ($1, $2, …) — an object of named binds needs a driver that supports them");try{const t=await this.client.query({text:e.text,...void 0!==e.values?{values:e.values}:{}});return t?.rows??[]}catch(e){throw le("postgres",e)}}}class Re{db;constructor(e){if(this.db=e,"function"!=typeof e?.all)throw new y("SQLiteConnection(db): pass an open sqlite Database")}query=async e=>{try{return await this.db.all(e.text,e.values)??[]}catch(e){throw le("sqlite",e)}}}const Fe=e=>ze(e,0,new Set),ze=(e,t,a)=>{if(null===e||"boolean"==typeof e||"string"==typeof e)return e;if("number"==typeof e&&Number.isFinite(e)&&!Object.is(e,-0))return e;if("object"!=typeof e)return Ge(e);if(!Array.isArray(e)&&!z(e))return Je(e);if(a.has(e))return"[circular]";if(t>=J)return"[too deep]";a.add(e);const r=Array.isArray(e)?Array.from(e,e=>ze(e,t+1,a)):Object.fromEntries(Object.entries(e).map(([e,r])=>[e,ze(r,t+1,a)]));return a.delete(e),r},Ge=e=>{switch(typeof e){case"function":return""===e.name?"[function]":`[function ${e.name}]`;case"symbol":return`[${String(e)}]`;case"bigint":return`[bigint ${e}]`;case"number":return Object.is(e,-0)?"[-0]":`[${e}]`;default:return"[undefined]"}},Je=e=>{const t=Ue(e);try{const a=e.toJSON;if("function"==typeof a){const r=a.call(e);if("string"==typeof r)return`[${t} ${r}]`}}catch{}return`[${t}]`},Ue=e=>{try{const t=e.constructor?.name;return"string"==typeof t&&""!==t?t:"Object"}catch{return"Object"}},Ve=e=>{const t=new Map;for(const a of e.holes)void 0!==a.timeoutFallback&&t.set(a.node,a.timeoutFallback);const a=e=>Object.fromEntries(Object.entries(e).map(([e,t])=>[e,n(t)])),r=e=>{const a=t.get(e);return void 0===a?{}:{timeoutFallback:Fe(a.value)}},n=e=>{const t={order:e.order,kind:e.kind,path:k(e.path)},i="vars"in e&&void 0!==e.vars?{vars:a(e.vars)}:{};switch(e.kind){case"constant":return{...t,kind:e.kind,value:Fe(e.value)};case"reference":return{...t,kind:e.kind,reference:U(e.binding??e.namespace,e.segments),authored:e.raw,...void 0===e.binding?{}:{binding:e.binding}};case"operator":return{...t,kind:e.kind,...i,operator:e.name,params:a(e.params),...void 0===e.fallback?{}:{fallback:n(e.fallback)},...r(e),...void 0===e.noCache?{}:{noCache:e.noCache},...void 0===e.entry.hostDefaults?{}:{hostDefaults:Object.keys(e.entry.hostDefaults)}};case"fragmentCall":return{...t,kind:e.kind,...i,fragment:e.name,resolved:void 0!==e.entry,argumentsMode:e.argumentsMode,...void 0===e.parameters?{}:{parameters:"dynamic"===e.argumentsMode?n(e.parameters):a(e.parameters)},...void 0===e.fallback?{}:{fallback:n(e.fallback)},...r(e),...void 0===e.noCache?{}:{noCache:e.noCache}};case"skeleton":{const a=O(e.skeleton,e.holes,e.holes.map(()=>"<hole>"));return{...t,kind:e.kind,...i,shape:Fe(a),holes:e.holes.map(e=>({at:[...e.at],node:n(e.node)}))}}case"elements":return{...t,kind:e.kind,elements:e.nodes.map(n)};case"entries":return{...t,kind:e.kind,...i,entries:a(e.entries)};case"invalid":return{...t,kind:e.kind,raw:Fe(e.raw)}}};return n(e.root)},Me=(e,t)=>{const a=q(e,t);if(void 0===a)throw new TypeError("inspect() takes a CompiledExpression — the handle fig.compile() returns");const{expression:r,artifact:n,options:i}=a;return{version:A,expression:Fe(r),options:Ie(i),canonicalForm:Ve(n),issues:x(n,i,({issue:e,order:t})=>({order:t,...e,path:[...e.path]})),timeoutShielded:n.timeoutShielded,nodeCount:n.nodeCount,maxDepth:n.maxDepth,dependencies:Ye(n.dependencies),own:{nodeCount:n.own.nodeCount,maxDepth:n.own.maxDepth,dependencies:Ye(n.own.dependencies)}}},Be="[supplied]",Ie=e=>Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e).map(([e,t])=>[e,We(e,t)])),We=(e,t)=>{switch(e){case"data":{const e="object"==typeof t&&null!==t?Object.keys(t).length:0;return`[supplied: ${e} top-level key${1===e?"":"s"}]`}case"signal":return Be;case"http":case"graphQL":return He(t,"headers",e=>"object"==typeof e&&null!==e?Object.fromEntries(Object.keys(e).map(e=>[e,"[redacted]"])):Fe(e));case"cache":return He(t,"store",()=>Be);default:return Fe(t)}},He=(e,t,a)=>"object"==typeof e&&null!==e?Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e).map(([e,r])=>[e,e===t?a(r):Fe(r)])):Fe(e),Ye=e=>({dataPaths:[...e.dataPaths.keys()],dynamic:e.dynamic,operators:[...e.operators],fragments:[...e.fragments]});export{me as AxiosClient,E as ErrorCodes,n as EvaluationData,pe as FetchClient,T as FigTreeError,t as OPERATOR_CATEGORIES,y as OperatorFailure,Qe as PostgresConnection,Re as SQLiteConnection,ie as defineOperator,oe as httpFailure,Le as httpOperators,Me as inspect,h as isOperatorFailure,g as renderText,R as resolvePath,le as sqlFailure,Se as sqlOperators,A as version};
@@ -0,0 +1,55 @@
1
+ type BasicType = 'any' | 'string' | 'number' | 'boolean' | 'array' | 'object' | 'null' | 'integer';
2
+ type LiteralType = {
3
+ literal: readonly (string | number | boolean)[];
4
+ };
5
+ type ExpectedType = BasicType | LiteralType | readonly BasicType[];
6
+ interface Constraints {
7
+ length?: number;
8
+ homogeneous?: readonly BasicType[];
9
+ elementShape?: Record<string, TypeDeclaration>;
10
+ }
11
+ interface TypeDeclaration {
12
+ type?: ExpectedType;
13
+ required?: boolean;
14
+ constraints?: Constraints;
15
+ }
16
+
17
+ interface FragmentParameterDeclaration extends TypeDeclaration {
18
+ default?: unknown;
19
+ description?: string;
20
+ metadata?: Record<string, unknown>;
21
+ }
22
+ interface FragmentDefinition {
23
+ expression: unknown;
24
+ parameters?: Record<string, FragmentParameterDeclaration>;
25
+ description?: string;
26
+ metadata?: Record<string, unknown>;
27
+ }
28
+
29
+ interface MigrationIssue {
30
+ code: 'split-trailing-empty' | 'remainder-sign' | 'template-numbering' | 'named-token-source' | 'response-collapse' | 'computed-delimiter' | 'computed-branches' | 'graphql-relative-url' | 'output-type' | 'missing-data-fallback' | 'unprefixed-parameter' | 'cache-opt-in' | 'instance-case-insensitive' | 'values-cut' | 'fallback-converted' | 'malformed-entry' | 'unreachable-branches' | 'overridden-value' | 'discarded-expression' | 'fragment-shorthand-payload' | 'shadowed-argument' | 'unknown-argument' | 'name-renamed' | 'unknown-parameter-type' | 'default-outside-type' | 'unused-output-type' | 'deciding-value' | 'drilled-substitution-token' | 'number-mapping' | 'template-escape' | 'computed-dollar-template' | 'custom-function-call' | 'computed-function-name' | 'computed-arguments' | 'body-override' | 'computed-fragment-name' | 'replaced-output-type' | 'computed-children' | 'unknown-operator' | 'unconvertible-input';
31
+ tag: 'non-convertible' | 'intentional-semantic-change' | 'lossy-default';
32
+ path: (string | number)[];
33
+ message: string;
34
+ }
35
+ interface MigrationResult {
36
+ expression: unknown;
37
+ issues: MigrationIssue[];
38
+ }
39
+ interface FragmentMigrationResult {
40
+ fragments: Record<string, FragmentDefinition>;
41
+ issues: MigrationIssue[];
42
+ }
43
+ interface V2Options {
44
+ fragments?: Record<string, unknown>;
45
+ functions?: readonly string[] | Record<string, unknown>;
46
+ evaluateFullObject?: boolean;
47
+ noShorthand?: boolean;
48
+ caseInsensitive?: boolean;
49
+ useCache?: boolean;
50
+ }
51
+
52
+ declare const migrateV2Expression: (expression: unknown, options?: V2Options) => MigrationResult;
53
+ declare const migrateV2Fragments: (options: V2Options) => FragmentMigrationResult;
54
+
55
+ export { migrateV2Expression, migrateV2Fragments };
@@ -0,0 +1 @@
1
+ const e=(e,t)=>t.length<=e.length&&t.every((t,s)=>e[s]===t),t={"split-trailing-empty":{tag:"intentional-semantic-change",message:()=>"v2 dropped one trailing empty piece, so `'a,b,'` split to `['a', 'b']` and `''` to `[]`. v3 keeps it, giving `['a', 'b', '']` and `['']`. Where empty pieces must go, `filter` the result."},"computed-delimiter":{tag:"intentional-semantic-change",message:()=>"The delimiter is computed. v2 turned `\\n`, `\\t` and `\\r` typed as text in a delimiter into the characters they name, and v3 splits on the text as written. If the delimiter can hold such text, make it the real character."},"output-type":{tag:"intentional-semantic-change",message:({differences:e})=>`v3's \`convert\` is strict where v2 guessed: ${e}. Check that this node's result can never be one of them.`},"remainder-sign":{tag:"intentional-semantic-change",message:()=>"v2's remainder took the sign of the dividend (−7 remainder 3 was −1), and v3's `modulo` takes the sign of `mod` (2). They differ only when exactly one operand is negative. For v2's answer there, take the `modulo` of the `abs` values and give it the dividend's sign."},"template-numbering":{tag:"intentional-semantic-change",message:()=>"The template is computed, so its tokens cannot be renumbered. v2 matched tokens to substitutions by rank (`'%1 %3'` used the first two), and v3 matches by number. Check that the template's tokens have no gaps."},"named-token-source":{tag:"intentional-semantic-change",message:()=>"The template or `substitutions` is computed, so the converter cannot tell which `{{…}}` tokens read `data` in v2, which any name missing from `substitutions` did. In v3 such a token is written `{{$data.name}}`. Rewrite those tokens."},"response-collapse":{tag:"intentional-semantic-change",message:()=>"v2 reduced each single-key object in the response to its value, so a list of `{ name }` objects came back as a list of names. v3 returns the response as sent. To keep v2's result, project the field in `returnPath`, as in `'countries[*].name'`. The same `[*]` is needed wherever `returnPath` crosses an array, since v2 projected a key across one silently. Where the array holds the one element wanted, as a lookup by name often does, `[0]` reads that element instead: `'[0].flag'` rather than `'[*].flag'`, which gives a list of one."},"computed-branches":{tag:"intentional-semantic-change",message:()=>"`branches` is computed. v2 evaluated the branch it picked when that was an expression, and answered with a `fallback` key when nothing matched. v3 returns the branch as it is, and reads `fallback` as an ordinary key. Check that the object holds plain values, and give the no-match answer with `default`."},"graphql-relative-url":{tag:"intentional-semantic-change",message:()=>"v2 joined a relative `url` to its GraphQL endpoint option, and v3 joins it to `http.baseEndpoint`. Check the host's `http.baseEndpoint`, or write the full URL."},"missing-data-fallback":{tag:"intentional-semantic-change",message:()=>"In v2 a missing path failed, and this `fallback` answered. In v3 the read gives `null` and the node carries on. For data, set the host option `strictDataPaths: true` to fail as v2 did, or give the read its own default (`get`'s `default`, or `firstOf`). For a response's `returnPath`, which `strictDataPaths` does not reach, use `firstOf`, or read the path with a `get` and its `default`."},"cache-opt-in":{tag:"intentional-semantic-change",message:({operator:e,fragment:t})=>"v2 cached this. In v3 an expression can only turn caching off, and an operator caches only if its definition declares `cache: true`. "+(void 0!==t?`The body of \`${t}\` has \`noCache\` at its root, since v2 left it uncached by default; take that out of the definition if every call may cache.`:`Declare \`cache: true\` on ${void 0===e?"the call's operator":`\`${e}\``} if this call needs caching.`)},"unprefixed-parameter":{tag:"intentional-semantic-change",message:({name:e})=>`v2 read the declared name \`${e}\` as written, without a \`$\`, so the declaration never filled the body's \`$${e}\`: its default and type did nothing, and a call that left \`$${e}\` out got that text. v3 applies the declaration. Check the calls that leave it out.`},"instance-case-insensitive":{tag:"lossy-default",message:({operator:e})=>`v2's \`caseInsensitive\` option applied to this node. v3 compares case-sensitively until the host adds \`operatorDefaults: { ${e}: { caseInsensitive: true } }\`, or this node sets \`caseInsensitive: true\`.`},"values-cut":{tag:"lossy-default",message:({removed:e})=>`v2 used the first two values and ignored the rest. Removed: ${e}.`},"fallback-converted":{tag:"lossy-default",message:({type:e})=>`This \`fallback\` becomes \`default\`, which v3's \`convert\` then converts to ${e}, where v2 returned it as it was. Unless the default is already of that type, it fails or changes. Give a default of that type.`},"malformed-entry":{tag:"lossy-default",message:({odd:e})=>e?"An alternating list gives each key a value, and v2 failed on this key, which has none. v3 builds the object without it. Removed.":"v2 skipped an entry with no `key` or no `value`. Removed."},"overridden-value":{tag:"lossy-default",message:({key:e,winner:t})=>`v2 never read \`${e}\`: \`${t}\` gave the same parameter and won. Removed.`},"discarded-expression":{tag:"lossy-default",message:()=>"v2 evaluated this and then discarded it, so a failure in it failed the node, and any request, query or function call in it ran. v3 never evaluates it. Removed."},"unreachable-branches":{tag:"lossy-default",message:()=>"`branches` has a `fallback`, which v2 answered with before it read the node's own keys, so this branch was never reached. Removed."},"fragment-shorthand-payload":{tag:"lossy-default",message:()=>"A fragment shorthand takes an object of arguments. v2 spread this one into `parameters`, where it named nothing, so the call had no arguments. Removed."},"shadowed-argument":{tag:"lossy-default",message:({fragment:e,key:t})=>`The body of \`${e}\` sets its own \`${t}\`, which beat this argument in v2, so the argument never applied. Removed.`},"unknown-argument":{tag:"lossy-default",message:({fragment:e,name:t})=>`\`${e}\` has no parameter \`${t}\`. v2 ignored the argument, and v3 rejects it. Removed.`},"unused-output-type":{tag:"lossy-default",message:({key:e,reason:t})=>`v2 never applied this \`${e}\`: ${t}. Removed.`},"name-renamed":{tag:"lossy-default",message:({name:e,reason:t,renamed:s})=>`\`${e}\` cannot be registered in v3 (${t}), so it is renamed \`${s}\`, and calls follow. Update anything outside expressions that uses the old name.`},"unknown-parameter-type":{tag:"lossy-default",message:({type:e})=>`\`${e}\` is not a v3 type, so the parameter takes \`'any'\`.`},"default-outside-type":{tag:"lossy-default",message:({value:e,type:t})=>`The default \`${e}\` is not of the declared type \`${t}\`. v2 never checked it, and v3 would refuse to register the fragment, so the parameter takes \`'any'\`.`},"deciding-value":{tag:"non-convertible",message:({reason:e,wrote:t,key:s})=>`${e}, so the converter cannot tell what v2 did. It wrote ${t}, v2's default. Where \`${s}\` can be otherwise, rewrite the node by hand.`},"drilled-substitution-token":{tag:"non-convertible",message:({token:e,name:t})=>`\`${e}\` drills into the substitution \`${t}\`, and v3's substitution tokens do not drill. Pass the drilled value as a substitution of its own.`},"number-mapping":{tag:"non-convertible",message:({token:e})=>`v3 has no \`numberMapping\`, so ${e} renders the bare number. Choose the text in the substitution instead, with \`match\` or \`if\`.`},"template-escape":{tag:"non-convertible",message:()=>"v3 has no escapes, and reads `%N` and `{{…}}` in a template as tokens. To show such text literally, pass it in as a substitution."},"computed-dollar-template":{tag:"non-convertible",message:({what:e})=>`The template's \`$N\` tokens must become \`%N\` for v3, and a computed ${e} cannot be rewritten. Rewrite the template with v3's tokens.`},"custom-function-call":{tag:"non-convertible",message:({name:e,rename:t})=>`A call on the v2 custom function \`${e}\`. Register a v3 operator of that name, as "Custom functions" in the migration guide suggests, and check this call against its parameters.`+(void 0===t?"":` ${t}, so register it under another name and rename the call.`)+" Until then, v3 refuses the expression."},"computed-function-name":{tag:"non-convertible",message:()=>"The function name is computed, and v3 operator names are literal. The call is quoted unconverted. Rewrite it by hand, for example as a `match` over the functions it can name."},"computed-children":{tag:"non-convertible",message:({operator:e})=>`\`children\` is computed, and \`${e}\` sends its children to different parameters, which cannot be split before evaluation. The node is quoted unconverted. Rewrite it with named parameters.`},"computed-arguments":{tag:"non-convertible",message:()=>"The arguments are computed. v2's had `$` names and v3's do not, so as written they fill nothing. Make the computing expression produce names without the `$`."},"body-override":{tag:"non-convertible",message:({key:e})=>`In v2, \`${e}\` set the body's own \`${e}\`, through the call's spread over it. A v3 call passes only arguments. Removed. Make it a parameter of the fragment, or change the body.`},"replaced-output-type":{tag:"non-convertible",message:({fragment:e})=>`In v2 this \`outputType\` replaced the output type that the body of \`${e}\` sets with \`type\`. In v3 the body converts its result first, and this \`convert\` converts that, which gives v2's answer only where the first conversion loses nothing. Check the result, or take the output type off the body.`},"computed-fragment-name":{tag:"non-convertible",message:()=>"The fragment name is computed, and v3 fragment names are literal. The call is quoted unconverted. Rewrite it by hand, for example as a `match` over the fragments it can name."},"unknown-operator":{tag:"non-convertible",message:({name:e})=>`\`${e}\` is not a v2 operator. If it is one of your v2 custom functions, list it in the conversion's \`functions\` option and convert again, so the call converts to a call on a custom operator of that name. The node is quoted unconverted.`},"unconvertible-input":{tag:"non-convertible",message:()=>"The input nests too deeply to convert, or holds itself, which no JSON config does. It is quoted unconverted. Split it into fragments, or rewrite it by hand."}},s=(e,s,...[a])=>{const{tag:r,message:n}=t[e];return{code:e,tag:r,path:s,message:n(a)}},a={GET:{evaluatesContents:["parameters","headers"]},POST:{evaluatesContents:["parameters","headers"]},GRAPHQL:{evaluatesContents:["variables"]},BUILD_OBJECT:{evaluatesContents:["properties"]},MATCH:{evaluatesContents:["branches"]},STRING_SUBSTITUTION:{evaluatesContents:["substitutions"]},CUSTOM_FUNCTIONS:{evaluatesContents:["input"]}},r=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),n=/^\$(?:data|d|vars|v|params|p|element|e|index|i|error|err)(?:$|[.[])/,o=/^\$(?:data|d|vars|v|params|p|element|e)(?:$|[.[])/,i=/^\$(?:data|d)(?:$|[.[])/,u="v2 conversion: ",c=(e,t)=>({...void 0!==t&&{"//":t},operator:"literal",value:e}),l=e=>r(e)&&"literal"===e.operator,h=e=>l(e)?e.value:e,p=["//","fallback","noCache","vars"],d=e=>{if(!r(e))return!1;if(Object.hasOwn(e,"operator")||Object.hasOwn(e,"fragment"))return!0;const t=Object.keys(e).filter(e=>!p.includes(e));return 1===t.length&&t[0].startsWith("$")},m=(e,t=!1)=>{if(Array.isArray(e)){const s=e.map(e=>m(e,t));return s.some((t,s)=>t!==e[s])?s:e}if(!r(e)||l(e))return e;const s=Object.getPrototypeOf(e);if(s!==Object.prototype&&null!==s)return e;const a=d(e),n=t||a&&!0===e.noCache;let o=!1;const i={};for(const[s,r]of Object.entries(e)){if(a&&t&&"noCache"===s){o=!0;continue}const e="//"===s?r:m(r,n);o||=e!==r,i[s]=e}return o?i:e},f=e=>"string"==typeof e?n.test(e):d(e)&&(!l(e)||(e=>l(e)&&[e["//"]].flat().some(e=>"string"==typeof e&&e.startsWith(u)))(e)),v=e=>!!f(e)||(Array.isArray(e)?e.some(v):r(e)&&!l(e)&&Object.values(e).some(v)),y=e=>"string"==typeof e?n.test(e):Array.isArray(e)?e.some(y):!!r(e)&&Object.entries(e).some(([e,t])=>"operator"===e||"fragment"===e||e.startsWith("$")||"vars"===e||"//"===e||y(t)),g=e=>y(e)?c(e):e,b=e=>{const t=T(e),s="string"==typeof t?`'${t}'`:JSON.stringify(t)??String(t);return s.length>60?`${s.slice(0,57)}...`:s},O=e=>""===e?"$data":e.startsWith("[")?`$data${e}`:`$data.${e}`,T=e=>l(e)?e.value:Array.isArray(e)?e.map(T):r(e)?Object.fromEntries(Object.entries(e).map(([e,t])=>[e,T(t)])):e,w=/*#__PURE__*/new Set(["operator","fragment","parameters","fallback","noCache","vars","//"]),k=/*#__PURE__*/new Set([...w,"data","params","element","index","error","d","v","p","e","i","err","literal"]),j=/*#__PURE__*/new Set(["any","string","number","boolean","array","object","null","integer"]),S=(e,t)=>{switch(t){case"any":return!0;case"integer":return Number.isInteger(e);case"array":return Array.isArray(e);case"object":return r(e);case"null":return null===e;default:return typeof e===t}},A=/^\$(?:data|d)[.[]/,C=(e,t)=>{const s=e=>C(e,t);if("string"==typeof e)return A.test(e);if(Array.isArray(e))return e.some(s);if(!r(e)||l(e))return!1;if(Object.hasOwn(e,"fragment")){return(Object.hasOwn(e,"fallback")?s(e.fallback):t(String(e.fragment)))||s(e.parameters)||s(e.vars)}if(d(e)&&Object.hasOwn(e,"fallback"))return s(e.fallback)||s(e.vars);const{operator:a}=e;return"get"===a&&!Object.hasOwn(e,"default")||(!("http"!==a&&"graphQL"!==a||!Object.hasOwn(e,"returnPath"))||Object.entries(e).some(([e,t])=>"//"!==e&&s(t)))},E=(e,t,s)=>(a,r)=>{const n={};e.forEach((e,t)=>{n[e]=void 0===a[t]&&"url"===e?"":r(t)});const o=a[e.length],i=e.length+1,u=Array.isArray(o)?o:[o];return n[t]=Object.fromEntries(u.map((e,t)=>[e,r(i+t)])),a.length-i>u.length&&(n[s]=r(a.length-1)),n},$={AND:{into:"values"},OR:{into:"values"},EQUAL:{into:"values"},NOT_EQUAL:{into:"values"},PLUS:{into:"values"},SUBTRACT:{into:"values"},MULTIPLY:{into:"values"},DIVIDE:{into:"values"},GREATER_THAN:{into:"values"},LESS_THAN:{into:"values"},COUNT:{into:"values"},CONDITIONAL:{positions:["condition","valueIfTrue","valueIfFalse"]},REGEX:{positions:["testString","pattern"]},SPLIT:{positions:["value","delimiter"],defaults:{delimiter:" "}},OBJECT_PROPERTIES:{positions:["property"],ifGiven:"fallback"},STRING_SUBSTITUTION:{positions:["string"],rest:"substitutions"},SQL:{positions:["query"],rest:"values"},CUSTOM_FUNCTIONS:{positions:["functionName"],rest:"args"},MATCH:(e,t)=>{const s={};for(let a=1;a+1<e.length;a+=2){const r=e[a];"string"!=typeof r&&"number"!=typeof r&&"boolean"!=typeof r||(s[String(r)]=t(a+1))}return{matchExpression:t(0),branches:s}},BUILD_OBJECT:(e,t)=>{if(e.every(r))return{properties:e.map((e,s)=>t(s))};const s=[];for(let a=0;a<e.length;a+=2)s.push(a+1<e.length?{key:t(a),value:t(a+1)}:{key:t(a)});return{properties:s}},GET:E(["url"],"parameters","returnProperty"),POST:E(["url"],"parameters","returnProperty"),GRAPHQL:E(["query","url"],"variables","returnNode"),PASSTHRU:(e,t)=>({value:1===e.length?t(0):e.map((e,s)=>t(s))})},I={and:"AND","&":"AND","&&":"AND",or:"OR","|":"OR","||":"OR","=":"EQUAL",eq:"EQUAL",equal:"EQUAL",equals:"EQUAL","!=":"NOT_EQUAL",notEqual:"NOT_EQUAL","!":"NOT_EQUAL",ne:"NOT_EQUAL","+":"PLUS",plus:"PLUS",add:"PLUS",concat:"PLUS",join:"PLUS",merge:"PLUS","-":"SUBTRACT",subtract:"SUBTRACT",minus:"SUBTRACT",takeaway:"SUBTRACT","*":"MULTIPLY",x:"MULTIPLY",multiply:"MULTIPLY",times:"MULTIPLY","/":"DIVIDE",divide:"DIVIDE","÷":"DIVIDE",">":"GREATER_THAN",greaterThan:"GREATER_THAN",higher:"GREATER_THAN",larger:"GREATER_THAN","<":"LESS_THAN",lessThan:"LESS_THAN",lower:"LESS_THAN",smaller:"LESS_THAN","?":"CONDITIONAL",conditional:"CONDITIONAL",ifThen:"CONDITIONAL",regex:"REGEX",patternMatch:"REGEX",regexp:"REGEX",matchPattern:"REGEX",getData:"OBJECT_PROPERTIES",dataProperties:"OBJECT_PROPERTIES",data:"OBJECT_PROPERTIES",objectProperties:"OBJECT_PROPERTIES",objProps:"OBJECT_PROPERTIES",getProperty:"OBJECT_PROPERTIES",getObjProp:"OBJECT_PROPERTIES",stringSubstitution:"STRING_SUBSTITUTION",substitute:"STRING_SUBSTITUTION",stringSub:"STRING_SUBSTITUTION",replace:"STRING_SUBSTITUTION",split:"SPLIT",arraySplit:"SPLIT",count:"COUNT",length:"COUNT",GET:"GET",get:"GET",api:"GET",POST:"POST",post:"POST",sql:"SQL",pgSql:"SQL",postgres:"SQL",pg:"SQL",sqLite:"SQL",sqlite:"SQL",mySql:"SQL",graphQL:"GRAPHQL",graphQl:"GRAPHQL",graphql:"GRAPHQL",gql:"GRAPHQL",buildObject:"BUILD_OBJECT",build:"BUILD_OBJECT",object:"BUILD_OBJECT",match:"MATCH",switch:"MATCH",customFunctions:"CUSTOM_FUNCTIONS",customFunction:"CUSTOM_FUNCTIONS",objectFunctions:"CUSTOM_FUNCTIONS",function:"CUSTOM_FUNCTIONS",functions:"CUSTOM_FUNCTIONS",runFunction:"CUSTOM_FUNCTIONS",pass:"PASSTHRU",_:"PASSTHRU",passThru:"PASSTHRU",passthru:"PASSTHRU",ignore:"PASSTHRU",coerce:"PASSTHRU",convert:"PASSTHRU"},N={AND:[{name:"values",aliases:[]}],OR:[{name:"values",aliases:[]}],EQUAL:[{name:"values",aliases:[]},{name:"caseInsensitive",aliases:[]},{name:"nullEqualsUndefined",aliases:[]}],NOT_EQUAL:[{name:"values",aliases:[]},{name:"caseInsensitive",aliases:[]},{name:"nullEqualsUndefined",aliases:[]}],PLUS:[{name:"values",aliases:[]},{name:"type",aliases:[]}],SUBTRACT:[{name:"values",aliases:[]},{name:"from",aliases:["subtractFrom"]},{name:"subtract",aliases:[]}],MULTIPLY:[{name:"values",aliases:[]}],DIVIDE:[{name:"values",aliases:[]},{name:"dividend",aliases:["divide"]},{name:"divisor",aliases:["by","divideBy"]},{name:"output",aliases:[]}],GREATER_THAN:[{name:"values",aliases:[]},{name:"strict",aliases:[]}],LESS_THAN:[{name:"values",aliases:[]},{name:"strict",aliases:[]}],CONDITIONAL:[{name:"condition",aliases:[]},{name:"valueIfTrue",aliases:["ifTrue"]},{name:"valueIfFalse",aliases:["ifFalse","ifNot"]}],REGEX:[{name:"testString",aliases:["string","value"]},{name:"pattern",aliases:["regex","regexp","regExp","re"]}],OBJECT_PROPERTIES:[{name:"property",aliases:["path","propertyName"]},{name:"additionalData",aliases:["additional","objects","data","additionalObjects"]}],STRING_SUBSTITUTION:[{name:"string",aliases:[]},{name:"substitutions",aliases:["replacements","values"]},{name:"trimWhiteSpace",aliases:["trim","trimWhitespace"]},{name:"substitutionCharacter",aliases:["subCharacter","subChar"]},{name:"numberMapping",aliases:["numMap","numberMap","pluralisation","pluralization","plurals"]}],SPLIT:[{name:"value",aliases:["string"]},{name:"delimiter",aliases:["separator"]},{name:"trimWhiteSpace",aliases:["trim","trimWhitespace"]},{name:"excludeTrailing",aliases:["removeTrailing","excludeTrailingDelimiter"]}],COUNT:[{name:"values",aliases:[]}],GET:[{name:"url",aliases:["endpoint"]},{name:"returnProperty",aliases:["outputProperty"]},{name:"headers",aliases:[]},{name:"parameters",aliases:["queryParams","queryParameters","urlQueries"]},{name:"useCache",aliases:[]}],POST:[{name:"url",aliases:["endpoint"]},{name:"returnProperty",aliases:["outputProperty"]},{name:"headers",aliases:[]},{name:"parameters",aliases:["bodyJson","data"]},{name:"useCache",aliases:[]}],SQL:[{name:"query",aliases:["text"]},{name:"values",aliases:["replacements"]},{name:"single",aliases:["singleRecord"]},{name:"flatten",aliases:["flat","array"]},{name:"useCache",aliases:[]}],GRAPHQL:[{name:"query",aliases:[]},{name:"url",aliases:["endpoint"]},{name:"headers",aliases:[]},{name:"variables",aliases:[]},{name:"returnNode",aliases:["outputNode","returnProperty"]},{name:"useCache",aliases:[]}],BUILD_OBJECT:[{name:"properties",aliases:["values","keyValPairs","keyValuePairs"]}],MATCH:[{name:"matchExpression",aliases:["matchValue"]},{name:"branches",aliases:["arms","cases"]}],CUSTOM_FUNCTIONS:[{name:"functionName",aliases:["functionPath","funcName","function","path","name"]},{name:"args",aliases:["arguments","variables"]},{name:"input",aliases:["arg"]},{name:"useCache",aliases:[]}],PASSTHRU:[{name:"value",aliases:["_","data"]}]},U=e=>/^\$.+/.test(e),R=e=>Object.hasOwn(e,"operator")||Object.hasOwn(e,"fragment"),P=e=>{const t=(e=>(e=>e.replace(/[^A-Za-z\d _-]/g,"").split(/[-_ ]/).flatMap(e=>e.match(/[a-z]+|[A-Z]+[a-z]*/g)??e).filter(e=>""!==e).map((e,t)=>0===t?e.toLowerCase():e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(""))(e)||e)(e);return Object.hasOwn(I,t)?I[t]:void 0},L=["fallback","useCache","outputType"],x=["array","string","number"],_=["fallback","outputType","type","useCache","args","input"],M=Object.fromEntries(Object.entries(N).map(([e,t])=>[e,t.map(({name:e})=>e)])),q=Object.fromEntries(Object.entries(N).map(([e,t])=>[e,Object.fromEntries(t.flatMap(({name:e,aliases:t})=>t.map(t=>[t,e])))])),B=e=>"object"==typeof e?null!==e:"string"==typeof e&&U(e),G=(e,t)=>e.entries?.[t]??{path:[...e.path,t]},H=(t,s)=>(e(t,s)&&t.length>s.length?t.slice(s.length):t).map((e,t)=>"number"==typeof e?`[${e}]`:0===t?e:`.${e}`).join(""),Q=e=>{const t=e.get("operator"),s=t?.source.path.at(-1);if("string"==typeof s&&U(s))return s.slice(1);const a=t?.value;return"string"==typeof a?a:JSON.stringify(a)??String(a)};class D{index;constructor(e){this.index=e}}class F{source;issues;entries=new Map;constructor(e,t){this.source=e,this.issues=t}get(e){return this.entries.get(e)}has(e){return this.entries.has(e)}set(e,t,s=t.source.path){const a=this.entries.get(e);a&&this.overridden(a.source.path,s),this.entries.set(e,t)}drop(e,t){const s=this.entries.get(e);s&&this.overridden(s.source.path,t),this.entries.delete(e)}overridden(t,a){if(this.issues.some(({code:s,path:a})=>"overridden-value"===s&&e(t,a)))return;const r=this.source.path,n={key:H(t,r),winner:H(a,r)};this.issues.push(s("overridden-value",t,n))}}class W{sources=new Map;issues=[];fragments;functions;shorthand;fullObject;constructor(e){const{functions:t={}}=e;this.fragments=e.fragments??{},this.functions=new Set(Array.isArray(t)?t:Object.keys(t)),this.shorthand=!e.noShorthand,this.fullObject=!0===e.evaluateFullObject}value(e,t){if(Array.isArray(e)){const s=e.map((e,s)=>this.value(e,G(t,s)));return this.record(s,t)}if(!r(e))return e;const s=this.issues.length;if(Object.hasOwn(e,"fragment"))return this.fragmentCall(this.draft(e,t),e,s);if(Object.hasOwn(e,"operator"))return this.operatorNode(this.draft(e,t),e,s);const a=this.expandShorthand(e,t,this.issues);return void 0===a?this.plain(e,t):a.has("fragment")?this.fragmentCall(a,e,s):this.operatorNode(a,e,s)}draft(e,t){const s=new F(t,this.issues);for(const[a,r]of Object.entries(e))s.set(a,{value:r,source:G(t,a)});return s}plain(e,t){return this.fullObject?this.walk(e,t):t.entries?this.record(e,t):e}evaluates(e){if(Array.isArray(e))return e.some(e=>this.evaluates(e));if(!r(e))return!1;if(R(e))return!0;return!!Object.keys(e).some(e=>this.shorthand&&U(e)&&(void 0!==P(e.slice(1))||Object.hasOwn(this.fragments,e.slice(1))||this.functions.has(e.slice(1))))||this.fullObject&&Object.values(e).some(e=>this.evaluates(e))}walk(e,t,s=()=>!1){const a=Object.fromEntries(Object.entries(e).map(([e,a])=>[e,s(e)?a:this.value(a,G(t,e))]));return this.record(a,t)}record(e,t){const s=Object.fromEntries(Object.keys(e).map(s=>{const a=Array.isArray(e)?Number(s):s;return[s,G(t,a).path]}));return this.sources.set(e,{path:t.path,keys:s}),e}expandShorthand(e,t,s){if(!this.shorthand)return;const a=new F(t,s);let r=!1;for(const[s,n]of Object.entries(e))U(s)&&(r=this.expand(a,s,n,G(t,s))||r);for(const[s,r]of Object.entries(e))U(s)||a.set(s,{value:r,source:G(t,s)});return r?a:void 0}expand(e,t,a,n){const o=t.slice(1),i=e=>({value:[e],source:{path:n.path,entries:{0:n}}}),u=t=>{for(const[s,a]of Object.entries(t))e.set(s,{value:a,source:G(n,s)})},c=P(o);return void 0!==c?(Array.isArray(a)?(e.set("operator",{value:c,source:n}),e.set("children",{value:a,source:n})):r(a)&&!Object.keys(a).some(U)?(Object.hasOwn(a,"fragment")?e.overridden(n.path,[...n.path,"fragment"]):e.set("operator",{value:c,source:n}),u(a)):(e.set("operator",{value:c,source:n}),e.set("children",i(a))),!0):Object.hasOwn(this.fragments,o)?(e.set("fragment",{value:o,source:n}),r(a)||e.issues.push(s("fragment-shorthand-payload",n.path)),e.set("parameters",{value:r(a)?a:{},source:n}),!0):this.functions.has(o)?(e.set("operator",{value:o,source:n}),Array.isArray(a)?e.set("args",{value:a,source:n}):r(a)?Object.hasOwn(a,"input")||Object.hasOwn(a,"args")?u(a):e.set("input",{value:a,source:n}):e.set("args",i(a)),!0):(e.set(t,{value:a,source:n}),!1)}operatorNode(e,t,s){const{source:a}=e,r=e.get("operator")?.value;let n,o;if("string"==typeof r&&this.functions.has(r)?(({draft:e,ignored:n}=this.explicitCall(e)),o="CUSTOM_FUNCTIONS"):"string"==typeof r&&(o=P(r)),void 0===o)return this.asWritten(t,a,s,{code:"unknown-operator",at:e.get("operator")?.source.path??a.path,name:Q(e)});const i=this.parameterNames(e,o),u=i.get("children");if(void 0!==u){i.entries.delete("children");const r=$[o];if(Array.isArray(u.value))this.mapChildren(i,o,u);else{if("function"==typeof r||!("into"in r))return this.asWritten(t,a,s,{code:"computed-children",at:u.source.path,name:Q(e)});i.set(r.into,u)}}const c="CUSTOM_FUNCTIONS"===o?i.get("functionName"):void 0;return void 0!==c&&B(c.value)?this.asWritten(t,a,s,{code:"computed-function-name",at:c.source.path}):("MATCH"===o&&this.gatherBranches(i),this.writeNode(i,o,n))}asWritten(e,t,s,a){this.issues.length=s;const r=this.record({...e},t);return this.sources.get(r).quoted=a,r}explicitCall(e){const t=e.get("operator"),s=new F(e.source,e.issues);s.set("operator",{value:"CUSTOM_FUNCTIONS",source:t.source}),s.set("functionName",t);const a=[];for(const[t,r]of e.entries)"operator"!==t&&(_.includes(t)?s.set(t,r):a.push([t,r]));return 0===a.length?{draft:s}:s.has("input")?{draft:s,ignored:Object.fromEntries(a.map(([e,{value:t}])=>[e,t]))}:(s.set("input",{value:Object.fromEntries(a.map(([e,{value:t}])=>[e,t])),source:{path:e.source.path,entries:Object.fromEntries(a.map(([e,t])=>[e,t.source]))}}),{draft:s})}parameterNames(e,t){const s=q[t],a=new F(e.source,e.issues);for(const[t,r]of e.entries)a.set(Object.hasOwn(s,t)?s[t]:t,r);null==a.get("outputType")?.value&&a.entries.delete("outputType");const r=a.get("type"),n=a.get("outputType");return void 0===r||"PLUS"===t||"SQL"===t&&B(r.value)||(a.entries.delete("type"),"SQL"===t&&x.includes(r.value)?(a.set("flatten",{value:!0,source:r.source}),void 0===n&&a.set("outputType",r)):void 0!==n?a.overridden(r.source.path,n.source.path):a.set("outputType",r)),a}mapChildren(e,t,s){const a=s.value,n=t=>{if(t instanceof D)return t.index<a.length?{value:a[t.index],source:G(s.source,t.index)}:{value:void 0,source:s.source};if(Array.isArray(t)||r(t)){const e=Object.entries(t).map(([e,t])=>[e,n(t)]),a=e.map(([e,{value:t}])=>[e,t]);return{value:Array.isArray(t)?a.map(([,e])=>e):Object.fromEntries(a),source:{path:s.source.path,entries:Object.fromEntries(e.map(([e,{source:t}])=>[e,t]))}}}return{value:t,source:e.source}},o=((e,t,s=e=>t[e])=>{const a=$[e];if("function"==typeof a)return a(t,s);if("into"in a)return{[a.into]:t.map((e,t)=>s(t))};const{positions:r,rest:n,defaults:o={},ifGiven:i}=a,u={};return r.forEach((e,a)=>{u[e]=void 0===t[a]&&Object.hasOwn(o,e)?o[e]:s(a)}),void 0!==n&&(u[n]=t.slice(r.length).map((e,t)=>s(r.length+t))),void 0!==i&&void 0!==t[r.length]&&(u[i]=s(r.length)),u})(t,a,e=>new D(e));for(const[t,a]of Object.entries(o)){const r=n(a);void 0===r.value?e.drop(t,s.source.path):e.set(t,r,s.source.path)}}gatherBranches(e){const t=["operator",...M.MATCH,...L],a=[...e.entries].filter(([e])=>!t.includes(e)&&!U(e));if(0===a.length)return;const n=e.get("branches"),o=n?.value;if(Array.isArray(o)||r(o)&&!Object.hasOwn(o,"operator")){const t=n.source,r=Array.isArray(o)?o.filter((e,t)=>t%2==0).map(e=>String(e)):Object.keys(o),i=r.includes("fallback"),u=[];for(const[n,o]of a)e.entries.delete(n),i?e.issues.push(s("unreachable-branches",o.source.path)):r.includes(n)?e.overridden(o.source.path,[...t.path,n]):u.push([n,o]);if(0===u.length)return;if(Array.isArray(o)){const s={};o.forEach((e,a)=>s[a]=G(t,a)),u.forEach(([,e],t)=>{s[o.length+2*t]=e.source,s[o.length+2*t+1]=e.source});const a=u.flatMap(([e,{value:t}])=>[e,t]);e.entries.set("branches",{value:[...o,...a],source:{path:t.path,entries:s}})}else{const s=Object.fromEntries(Object.keys(o).map(e=>[e,G(t,e)]));for(const[e,t]of u)s[e]=t.source;e.entries.set("branches",{value:{...o,...Object.fromEntries(u.map(([e,t])=>[e,t.value]))},source:{path:t.path,entries:s}})}return}if(null==o){for(const[t]of a)e.entries.delete(t);e.entries.set("branches",{value:Object.fromEntries(a.map(([e,{value:t}])=>[e,t])),source:{path:e.source.path,entries:Object.fromEntries(a.map(([e,{source:t}])=>[e,t]))}})}}writeNode(e,t,s){const r=M[t],n=["operator",...r,...L],o=[...n.filter(t=>e.has(t)),...[...e.entries.keys()].filter(e=>!n.includes(e))],i=a[t]?.evaluatesContents??[],u={},c={};for(const s of o){const{value:a,source:n}=e.get(s);c[s]=n.path,"operator"===s?u[s]=t:"MATCH"===t&&"branches"===s?u[s]=this.matchBranches(a,n):r.includes(s)&&i.includes(s)?u[s]=this.contents(t,this.value(a,n),n):r.includes(s)||L.includes(s)||U(s)||"type"===s||"MATCH"===t?u[s]=this.value(a,n):u[s]=a}return this.sources.set(u,{path:e.source.path,keys:c,...s&&{ignored:s}}),u}contents(e,t,s){if(this.fullObject)return t;if("BUILD_OBJECT"===e){if(!Array.isArray(t)||!t.every(r))return t;const e=t.map((e,t)=>{if(R(e))return e;const a=G(s,t),r={...e};for(const t of["key","value"])Object.hasOwn(e,t)&&(r[t]=this.value(e[t],G(a,t)));return this.record(r,a)});return this.record(e,s)}return!r(t)||R(t)?t:"STRING_SUBSTITUTION"===e?this.walk(t,s,U):this.walk(t,s)}matchBranches(e,t){return Array.isArray(e)?this.value(e,t):r(e)?Object.hasOwn(e,"operator")?this.value(e,t):this.walk(e,t):e}fragmentCall(e,t,a){const{source:n}=e,o=e.get("fragment"),i="string"==typeof o.value&&Object.hasOwn(this.fragments,o.value);if(B(o.value)&&!i)return this.asWritten(t,n,a,{code:"computed-fragment-name",at:o.source.path});const u=e.get("parameters"),c=void 0===u||r(u.value)&&!R(u.value),l={fragment:o.value},h={fragment:o.source.path};if(c){const t=u?.source??n,a=new F(n,e.issues),r=this.bodyAliases(o.value),i=(t,a)=>e.issues.push(s("shadowed-argument",a,{fragment:String(o.value),key:t}));for(const[n,o]of Object.entries(u?.value??{})){const u={value:o,source:G(t,n)};this.fullObject&&r.has(n)?(i(n,u.source.path),this.evaluates(o)&&e.issues.push(s("discarded-expression",u.source.path))):a.set(n,u)}for(const[t,s]of e.entries){if(!U(t))continue;const e=a.get(t);void 0!==e?a.overridden(s.source.path,e.source.path):r.has(t)?i(t,s.source.path):a.set(t,s)}const c={},p={};for(const[e,{value:t,source:s}]of a.entries)c[e]=this.value(t,s),p[e]=s;l.parameters=this.record(c,{path:t.path,entries:p}),h.parameters=t.path}else l.parameters=this.value(u.value,u.source),h.parameters=u.source.path;for(const[t,{value:s,source:a}]of e.entries){if("fragment"===t||"parameters"===t||c&&U(t))continue;const e=L.includes(t)||U(t);l[t]=e?this.value(s,a):s,h[t]=a.path}return this.sources.set(l,{path:n.path,keys:h}),l}bodyAliases(e){if("string"!=typeof e||!Object.hasOwn(this.fragments,e))return new Set;const t=this.fragments[e];if(!r(t))return new Set;const s=R(t)?Object.keys(t):[...this.expandShorthand(t,{path:[]},[])?.entries.keys()??[]];return new Set(s.includes("operator")?s.filter(U):[])}}const J=(e,t={},s=[])=>{const a=new W(t);return{expression:a.value(e,{path:s}),sources:a.sources,issues:a.issues}},V={and:"and",or:"or",not:"not","!":"not",if:"if","?":"if",match:"match",firstOf:"firstOf",equal:"equal","=":"equal",notEqual:"notEqual","!=":"notEqual",greaterThan:"greaterThan",">":"greaterThan",greaterThanOrEqual:"greaterThanOrEqual",">=":"greaterThanOrEqual",lessThan:"lessThan","<":"lessThan",lessThanOrEqual:"lessThanOrEqual","<=":"lessThanOrEqual",plus:"plus","+":"plus",subtract:"subtract","-":"subtract",multiply:"multiply","*":"multiply",divide:"divide","/":"divide",modulo:"modulo",power:"power","^":"power",round:"round",floor:"floor",ceil:"ceil",abs:"abs",min:"min",max:"max",buildString:"buildString",split:"split",join:"join",lower:"lower",upper:"upper",trim:"trim",regex:"regex",length:"length",map:"map",filter:"filter",find:"find",some:"some",every:"every",get:"get",buildObject:"buildObject",convert:"convert",http:"http",graphQL:"graphQL",sql:"sql"},X=["name","type","required","default","description"],Y=(e,t)=>e.key<t.key?-1:e.key>t.key?1:0,z=e=>e.replace(/^\$+/,"").replace(/[.[\]]/g,"_")||"_",Z=(e,t)=>{let s=e;for(let a=2;t.has(s);a++)s=`${e}_${a}`;return t.add(s),s},K=e=>{if(""===e)return"a v3 name cannot be empty";if(e.startsWith("$"))return"a v3 name cannot start with `$`";const t=/[.[\]]/.exec(e)?.[0];return void 0===t?void 0:`a v3 name cannot hold a \`${t}\``},ee=e=>e.slice(1).map((e,t)=>"number"==typeof e?`[${e}]`:0===t?e:`.${e}`).join(""),te=(e,t,a,n)=>{if(!r(t)||"string"!=typeof t.name)return;const o=t.name.startsWith("$"),i=o?t.name:`$${t.name}`;if(!U(i)||e.parameters.has(i))return;const u=[e.key,"metadata","parameters",a],c=o?void 0:((e,t)=>{if(void 0===e.operator||void 0===e.body)return;const s=N[e.operator].find(e=>e.name===t||e.aliases.includes(t));return void 0!==s?s.name:["fallback","useCache","outputType"].includes(t)?t:"type"===t?"outputType":void 0})(e,t.name);o||void 0!==c||e.issues.push(s("unprefixed-parameter",[...u,"name"],{name:t.name}));const{type:l,required:h,default:p,description:d}=t,m=Object.fromEntries(Object.entries(t).filter(([e])=>!X.includes(e))),f={key:i,name:i.slice(1),at:u,declared:!0,required:!0===h,exact:!1};if(void 0!==l){const t=(e=>{if("string"==typeof e)return j.has(e)?{type:e}:{type:"any",unknown:e};if(Array.isArray(e)){const t=e.filter(e=>"undefined"!==e);if(0===t.length)return{type:"any",unknown:"undefined"};const s=t.find(e=>"string"!=typeof e||!j.has(e));return void 0!==s?{type:"any",unknown:s}:{type:1===t.length?t[0]:t}}if(r(e)&&Array.isArray(e.literal)&&e.literal.length>0){const t=e=>["string","number","boolean"].includes(typeof e);if(e.literal.every(t))return{type:{literal:e.literal}}}return{type:"any",unknown:e}})(l);if(f.type=t.type,Object.hasOwn(t,"unknown")){const a="string"==typeof t.unknown?t.unknown:b(t.unknown);e.issues.push(s("unknown-parameter-type",[...u,"type"],{type:a}))}}if(void 0!==d&&(f.description=d),Object.keys(m).length>0&&(f.metadata=m),void 0!==p){const t=[...u,"default"],s=J(p,n,t);s.sources.forEach((t,s)=>e.sources.set(s,t)),e.issues.push(...s.issues),f.default={value:s.expression,path:t}}void 0!==c&&se(e,f,c),e.parameters.set(i,f)},se=(t,s,a)=>{const r=t.body,n=t.sources.get(r),o=n?.keys[a]??[t.key,a];Object.hasOwn(r,a)&&(void 0===s.default?s.default={value:r[a],path:o}:t.issues=t.issues.filter(t=>!e(t.path,o))),r[a]=s.key,void 0!==n&&(n.keys[a]=o)},ae=(t,a,r,n)=>{for(const o of Object.keys(a).filter(U)){const i={value:a[o],path:r?.keys[o]??[t.key,o]},u=t.parameters.get(o);if(void 0===u)t.parameters.set(o,{key:o,name:o.slice(1),at:i.path,declared:!1,required:!1,type:"any",default:i,exact:!1});else if(void 0===u.default)u.default=i;else{const[a,r]=n.evaluateFullObject?[i,u.default]:[u.default,i],o={key:ee(r.path),winner:ee(a.path)};t.issues=t.issues.filter(({path:t})=>!e(t,r.path)),t.issues.push(s("overridden-value",r.path,o)),u.default=a}}},re=e=>{const t=e=>K(e)??(w.has(e)?"it is a reserved node key":void 0),a=[...e.parameters.values()],r=new Set(w);for(const e of a)void 0===t(e.name)&&r.add(e.name);for(const n of a.filter(({name:e})=>void 0!==t(e)).sort(Y)){const a=t(n.name),o={name:n.name,reason:a,renamed:Z(z(n.name),r)};n.name=o.renamed,e.issues.push(s("name-renamed",n.at,o))}},ne=([e,...t],s,a)=>e===s&&t.at(-1)===a&&(1===t.length||2===t.length&&"string"==typeof t[0]&&U(t[0])),oe=(e,t)=>{const a=r(e.fragments)?e.fragments:{},n=Object.entries(a).map(([t,s])=>((e,t,s)=>{const a={key:e,name:e,sources:new Map,convertsByType:!1,parameters:new Map,issues:[]};if(!r(t))return{...a,data:t};const{metadata:n,...o}=t,i=r(n)?n:void 0,u=J(i?o:t,s,[e]),c=u.expression;if(!r(c)||!Object.hasOwn(c,"operator")||Object.hasOwn(c,"fragment"))return{...a,data:t};a.body=c,u.sources.forEach((e,t)=>a.sources.set(t,e)),a.issues.push(...u.issues);const l=u.sources.get(c);if(void 0===l?.quoted&&(a.operator=c.operator),void 0!==i){const{description:e,parameters:t,...r}=i;"string"==typeof e?a.description=e:void 0!==e&&(r.description=e),Array.isArray(t)?t.forEach((e,t)=>te(a,e,t,s)):void 0!==t&&(r.parameters=t),Object.keys(r).length>0&&(a.metadata=r)}void 0===l?.quoted&&ae(a,c,l,s);const h=l?.keys.outputType?.at(-1);return Object.hasOwn(c,"outputType")?a.ownOutput="type"===h?"type":"outputType":Object.hasOwn(c,"type")&&(a.ownOutput="type"),a.convertsByType="type"===a.ownOutput&&("PLUS"===a.operator?["number","boolean","bool"].includes(c.type):Object.hasOwn(c,"outputType")),a})(t,s,e));((e,t)=>{const{functions:a={}}=t,r=new Set(Array.isArray(a)?a:Object.keys(a)),n=e=>K(e)??(k.has(e)?"it is a reserved name":Object.hasOwn(V,e)?"it is already a v3 operator's name":r.has(e)?"it is a custom function's name, which becomes a v3 operator":void 0),o=new Set([...k,...Object.keys(V),...r]);for(const t of e)void 0===n(t.key)&&o.add(t.key);for(const t of e.filter(({key:e})=>void 0!==n(e)).sort(Y)){t.name=Z(z(t.key),o);const e={name:t.key,reason:n(t.key),renamed:t.name};t.issues.unshift(s("name-renamed",[t.key],e))}})(n,e);const o={fragments:new Map(n.map(e=>[e.key,e])),bodyReads:()=>!1},i=new Map,u=new Map;for(let e=!0;e;){e=!1;for(const s of n){if(void 0===s.body)continue;const a=new Map,r=(e,t,s)=>a.set(e,[...a.get(e)??[],{path:t,throughCall:s}]);i.set(s.key,t(s,o,r)),u.set(s.key,a);for(const[t,[{path:r}]]of a)s.parameters.has(t)||(e=!0,s.parameters.set(t,{key:t,name:t.slice(1),at:r,declared:!1,required:!1,type:"any",exact:!1}))}}for(const e of n){for(const t of e.parameters.values()){const s=u.get(e.key)?.get(t.key)??[];t.exact=1===s.length&&!s[0].throughCall&&ne(s[0].path,e.key,t.key.slice(1))}re(e)}const c=new Map(n.map(e=>[e.name,e.key])),l=new Map;return o.bodyReads=e=>{const t=c.get(e);return!(void 0===t||!i.has(t))&&(l.has(t)||(l.set(t,!1),l.set(t,C(i.get(t),o.bodyReads))),l.get(t))},o},ie=(e,t,a)=>{const n=void 0!==t&&"computed"!==t?t:void 0;let{type:o}=e;if(void 0!==n&&void 0!==o&&!((e,t)=>Array.isArray(t)?t.some(t=>S(e,t)):r(t)&&Array.isArray(t.literal)?t.literal.includes(e):S(e,t))(n.constant,o)){const t={value:b(n.constant),type:b(o)};a.push(s("default-outside-type",e.default.path,t)),o="any"}const i=!e.declared&&void 0===t;return{...void 0!==o&&{type:o},...!(void 0!==n||i||e.required&&void 0===t)&&{required:!1},...void 0!==n&&{default:n.constant},...i&&{default:e.key},...void 0!==e.description&&{description:e.description},...void 0!==e.metadata&&{metadata:e.metadata}}},ue=(e,t,s,a)=>{const r=[...e.parameters.values()],n=[...r.filter(({declared:e})=>e),...r.filter(({declared:e})=>!e).sort((e,t)=>e.name<t.name?-1:1)],o=Object.fromEntries(n.map(e=>[e.name,ie(e,s.get(e.key),a)]));return{expression:t,...n.length>0&&{parameters:o},...void 0!==e.description&&{description:e.description},...void 0!==e.metadata&&{metadata:e.metadata}}},ce=e=>void 0!==e&&e>="0"&&e<="9",le={"%":/(?<!\\)%\d+/,$:/(?<!\\)\$\d+/},he=/(?<!\\)({{(?:[A-Za-z0-9_.]|\[[0-9]+\])+}})/,pe=/(?<!\\){{(.+)}}/,de=e=>n.test(e)?c(e):e,me=(e,t=e.to)=>({operator:t,...e.params}),fe=(e,t)=>f(t)?`\`${e}\` is computed`:`\`${b(t)}\` is not a value v2 accepted for \`${e}\``,ve=e=>Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e)),ye=(e,t)=>(!0!==t.options.caseInsensitive||Object.hasOwn(e.v2,"caseInsensitive")||t.issue("instance-case-insensitive",void 0,{operator:String(e.to)}),me(e)),ge=(e,t)=>(e.length>2&&(t.issue("values-cut","values",{removed:e.slice(2).map(b).join(", ")}),t.discard("values",2)),e.slice(0,2)),be=e=>(t,s)=>{const{strict:a}=t.v2,r=!1===a?e:t.to;void 0!==a&&"boolean"!=typeof a&&s.issue("deciding-value","strict",{reason:fe("strict",a),wrote:`\`${t.to}\``,key:"strict"}),s.discard("strict");const{values:n}=t.params;return Array.isArray(n)&&(t.params.values=ge(n,s)),me(t,r)},Oe=(e,t,s)=>(a,r)=>{const n=(e,t)=>ve({operator:a.to,value:e,[s]:t}),{values:i}=a.v2;if(void 0===i)return n(a.v2[e],a.v2[t]);const u=String(r.at("values").at(-1));for(const s of[e,t])Object.hasOwn(a.v2,s)&&(r.issue("overridden-value",s,{key:String(r.at(s).at(-1)),winner:u}),r.discard(s));if(Array.isArray(i)){const[e,t]=ge(i,r);return n(e,t)}if("string"==typeof i&&o.test(i))return n(`${i}[0]`,`${i}[1]`);const c=r.freshVar("values");return{...n(`$vars.${c}[0]`,`$vars.${c}[1]`),vars:{[c]:i}}},Te=Oe("from","subtract","minus"),we=Oe("dividend","divisor","by"),ke={number:e=>"number"==typeof e,string:e=>"string"==typeof e,boolean:e=>"boolean"==typeof e,array:Array.isArray},je=e=>{const t=h(e.url);if(f(e.url)||!r(t)||!l(e.url)&&v(e.url))return;const{url:s,headers:a}=t;if(e.url=g(s),void 0===a)return;const n=e.headers;e.headers=void 0===n?g(a):r(n)&&!d(n)&&r(a)&&!y(a)?{...a,...n}:{operator:"plus",values:[g(a),n]}},Se=(e,t)=>{je(e.params);const{url:s,method:a,query:r,body:n,headers:o,returnPath:i}=e.params;return t.issue("response-collapse",void 0),ve({operator:"http",url:s,method:a,query:r,body:"post"===a?n??{}:n,headers:o,returnPath:i})},Ae={"00":"rows",10:"firstRow","01":"column",11:"firstValue"},Ce=e=>{const t=e.startsWith("$")?"$":/[.[\]]/.exec(e)?.[0];return"$"===t?`\`${e}\` starts with \`$\`, which a v3 name cannot`:void 0!==t?`\`${e}\` holds a \`${t}\`, which a v3 name cannot`:Object.hasOwn(V,e)?`\`${e}\` is already a v3 operator's name`:void 0},Ee={AND:{to:"and",params:{values:"values"}},OR:{to:"or",params:{values:"values"}},MULTIPLY:{to:"multiply",params:{values:"values"}},EQUAL:{to:"equal",params:{values:"values",caseInsensitive:"caseInsensitive",nullEqualsUndefined:"omitted"},build:ye},NOT_EQUAL:{to:"notEqual",params:{values:"values",caseInsensitive:"caseInsensitive",nullEqualsUndefined:"omitted"},build:ye},GREATER_THAN:{to:"greaterThan",params:{values:"values",strict:"consumed"},build:be("greaterThanOrEqual")},LESS_THAN:{to:"lessThan",params:{values:"values",strict:"consumed"},build:be("lessThanOrEqual")},CONDITIONAL:{to:"if",params:{condition:"condition",valueIfTrue:"then",valueIfFalse:"else"}},REGEX:{to:"regex",params:{testString:"value",pattern:"pattern"}},COUNT:{to:"length",params:{values:"value"}},SPLIT:{to:"split",params:{value:"value",delimiter:{to:"delimiter",value:(e,t)=>{if(f(e))t.issue("computed-delimiter","delimiter");else if("string"==typeof e)return e.replace(/\\n/g,"\n").replace(/\\t/g,"\t").replace(/\\r/g,"\r");return e}},trimWhiteSpace:"trim",excludeTrailing:"consumed"},build:(e,t)=>(!1!==e.v2.excludeTrailing&&t.issue("split-trailing-empty",void 0),t.discard("excludeTrailing"),me(e))},PLUS:{to:"plus",params:{values:"values",type:"consumed"},build:(e,t)=>{if(!Object.hasOwn(e.v2,"type"))return me(e);t.discard("type");const{type:s}=e.v2,{values:a}=e.params;switch(s){case"string":return{operator:"join",...e.params,delimiter:""};case"array":return Array.isArray(a)&&(e.params.values=a.map(e=>Array.isArray(h(e))||f(e)?e:[e])),{...me(e),expect:"array"};case"number":case"boolean":case"bool":return Object.hasOwn(e.modifiers,"outputType")||Object.assign(e.modifiers,{outputType:"number"===s?"number":"boolean",outputTypeAt:"type"}),me(e)}return t.issue("deciding-value","type",{reason:fe("type",s),wrote:"`plus`",key:"type"}),me(e)}},SUBTRACT:{to:"subtract",params:{values:"consumed",from:"consumed",subtract:"consumed"},build:Te},DIVIDE:{to:"divide",params:{values:"consumed",dividend:"consumed",divisor:"consumed",output:"consumed"},build:(e,t)=>{t.discard("output");const{vars:s,...a}=we(e,t),{output:r}=e.v2,n=e=>({...e,...void 0!==s&&{vars:s}});switch(r){case void 0:case"decimal":return n(a);case"quotient":return n({operator:"floor",value:a});case"remainder":{t.issue("remainder-sign","output");const{value:e,by:s}=a;return n(ve({operator:"modulo",value:e,mod:s}))}}return t.issue("deciding-value","output",{reason:fe("output",r),wrote:"`divide`",key:"output"}),n(a)}},OBJECT_PROPERTIES:{to:"get",params:{property:"path",additionalData:{to:"from",value:e=>({operator:"plus",values:["$data",e]})}},build:(e,t)=>{const{modifiers:s}=e;if(Object.hasOwn(s,"fallback")){const{fallback:a}=s;return delete s.fallback,Object.hasOwn(s,"outputType")&&((e,t,s)=>{const a="bool"===t?"boolean":t;!f(e)&&"string"==typeof a&&Object.hasOwn(ke,a)&&ke[a](h(e))||s.issue("fallback-converted","fallback",{type:f(a)?"the type `outputType` computes":`\`${String(h(a))}\``})})(a,s.outputType,t),{...me(e),default:a}}const{path:a}=e.params;return Object.hasOwn(e.params,"from")||"string"!=typeof a||f(a)||!(e=>/^(?:[^[]|\[(?:\d+|\*|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')\])*$/.test(e))(a)?me(e):O(a)}},STRING_SUBSTITUTION:{to:"buildString",params:{string:"template",substitutions:"substitutions",trimWhiteSpace:"consumed",substitutionCharacter:"consumed",numberMapping:"consumed"},build:(e,t)=>{const{substitutions:s}=e.params,{trimWhiteSpace:a,substitutionCharacter:n}=e.v2,o=e.params.template,i=h(o),u=f(n)?void 0:"$"===n?"$":"%",c="string"==typeof i&&!f(o),l=Array.isArray(s),p=null==s||r(s)&&!d(s),m=l||!p&&c&&((e,t)=>le[t].test(e))(i,u??"%")&&!he.test(i)?"positional":"named";let v=o;"positional"===m?void 0===u?t.issue("computed-dollar-template","substitutionCharacter",{what:"`substitutionCharacter`"}):c?v=de(((e,t,s)=>{const a=e.match(new RegExp(le[t],"g"))??[],r=[...new Set([...a].sort((e,t)=>Number(e.slice(1))-Number(t.slice(1))))],n=new Map(r.map((e,t)=>[e,`%${t+1}`]));let o="",i=!1;for(let s=0;s<e.length;){const a=e[s];if("\\"!==a||e[s+1]!==t){if(a===t&&ce(e[s+1])){let t=s+1;for(;ce(e[t]);)t++;o+=n.get(e.slice(s,t)),s=t;continue}"%"===a&&ce(e[s+1])&&(i=!0),o+=a,s++}else ce(e[s+2])?(i=!0,o+=`\\${t}`):o+=t,s+=2}return i&&s.issue("template-escape","string"),o})(i,u,t)):"$"===u?t.issue("computed-dollar-template","string",{what:"template"}):t.issue("template-numbering","string"):c&&p?v=de(((e,t,s,a)=>{const{numberMapping:n}=s.v2,o=h(n);f(n)&&a.issue("number-mapping","numberMapping",{token:"each token it maps"});let i=!1;const u=e.split(he).map((e,s)=>{if(s%2==0)return pe.test(e)?e:e.replace(/\\{{/g,(t,s)=>{const a=e.indexOf("}}",s+3),r=-1!==a&&(n=e.slice(s+3,a),!/[{}]/.test(n)&&(n.startsWith("$")?n.length>1:""!==n&&!/[.[\]]/.test(n)));var n;return r&&(i=!0),r?t:"{{"});const n=e.slice(2,-2),u=`{{${n}}}`;r(o)&&Object.hasOwn(o,n)&&a.issue("number-mapping",["numberMapping",n],{token:`\`${u}\``});const[c]=n.split(/[.[]/);return void 0!==t&&Object.hasOwn(t,c)?(c!==n&&a.issue("drilled-substitution-token","string",{token:u,name:c}),e):`{{${O(n)}}}`});return i&&a.issue("template-escape","string"),u.join("")})(i,s??void 0,e,t)):t.issue("named-token-source","string");const y=void 0===a||(!1===a?void 0:a);return void 0===y&&t.discard("trimWhiteSpace"),t.discard("substitutionCharacter"),t.discard("numberMapping"),{operator:"buildString",...void 0!==o&&{template:v},...void 0!==s&&{substitutions:s},...void 0!==y&&{trim:y}}}},BUILD_OBJECT:{to:"buildObject",params:{properties:{to:"entries",value:(e,t)=>{if(!Array.isArray(e))return e;const s=[];if(!e.every(e=>f(e)||r(e)&&(!l(e)||r(e.value)))){for(let a=0;a<e.length;a+=2)a+1<e.length?s.push({key:e[a],value:e[a+1]}):(t.issue("malformed-entry",["properties",a],{odd:!0}),t.discard(["properties",a]));return s}return e.forEach((e,a)=>{f(e)||d(e)||Object.hasOwn(e,"key")&&Object.hasOwn(e,"value")?s.push(e):(t.issue("malformed-entry",["properties",a],{odd:!1}),t.discard(["properties",a]))}),s}}}},MATCH:{to:"match",params:{matchExpression:"value",branches:{to:"branches",value:e=>{if(!Array.isArray(e))return e;const t={};for(let s=0;s+1<e.length;s+=2){const a=e[s];"string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a||(t[String(a)]=e[s+1])}return t}}},build:(e,t)=>{const{value:s,branches:a={}}=e.params;if(r(a)&&!d(a)){if(!Object.hasOwn(a,"fallback"))return{...me(e),branches:a};const{fallback:t,...s}=a;return{...me(e),branches:s,default:t}}if(t.issue("computed-branches","branches"),0===Object.keys(e.extra).length)return me(e);let n,o=s;if("string"!=typeof s&&v(s)){const e=t.freshVar("value");o=`$vars.${e}`,n={[e]:s}}return{...me(e),value:o,default:{operator:"match",value:o,branches:e.extra},...void 0!==n&&{vars:n}}}},PASSTHRU:{params:{value:"consumed"},build:({v2:e})=>Object.hasOwn(e,"value")?e.value:null},GET:{to:"http",params:{url:"url",parameters:"query",headers:"headers",returnProperty:"returnPath"},build:Se},POST:{to:"http",add:{method:"post"},params:{url:"url",parameters:"body",headers:"headers",returnProperty:"returnPath"},build:Se},GRAPHQL:{to:"graphQL",params:{query:"query",url:"url",headers:"headers",variables:"variables",returnNode:"returnPath"},build:(e,t)=>{je(e.params);const{url:s}=e.params;return""===s||"string"==typeof s&&"graphqlendpoint"===s.toLowerCase()?delete e.params.url:"string"!=typeof s||f(s)||/^https?:\/\/.+/.test(s)||t.issue("graphql-relative-url","url"),t.issue("response-collapse",void 0),me(e)}},SQL:{to:"sql",params:{query:"query",values:"values",single:"consumed",flatten:"consumed"},build:(e,t)=>{const s=[],a=(e,t)=>void 0===t||"boolean"==typeof t?!0===t:(s.push([e,t]),!1),r=a("single",e.v2.single);let n=a("flatten",e.v2.flatten);!n&&Object.hasOwn(e.extra,"type")&&(n=a("type",e.extra.type));const o=Ae[`${Number(r)}${Number(n)}`];for(const[e,a]of s)t.issue("deciding-value",e,{reason:fe(e,a),wrote:`\`shape: '${o}'\``,key:e});for(const e of["single","flatten","type"])t.discard(e);return{...me(e),..."rows"!==o&&{shape:o}}}},CUSTOM_FUNCTIONS:{params:{functionName:"consumed",args:"consumed",input:"consumed"},build:(e,t)=>{const s=String(h(e.v2.functionName));t.issue("custom-function-call",void 0,{name:s,rename:Ce(s)});const{args:a,input:r}=e.v2;if(!Object.hasOwn(e.v2,"input"))return{[`$${s}`]:a??[]};const n=void 0===a||Array.isArray(a)||f(a)?a:[a];return ve({operator:s,input:r,args:n})}}},$e=["fallback","useCache","outputType"],Ie=["fragment","parameters","fallback","useCache","outputType","type","operator","//"],Ne=["array","string","number"],Ue={GET:!0,POST:!1,GRAPHQL:!0,SQL:!0,CUSTOM_FUNCTIONS:!1},Re=/*#__PURE__*/new Set(["GET","POST","GRAPHQL","SQL"]),Pe=e=>"string"==typeof e.functionName?{operator:e.functionName}:{},Le={number:"v2 took the first number in a text (`'abc4.5x'` was `4.5`), made a text with none `0`, and made `null` `0`, where v3 fails on a text that is not a number, and keeps `null`",string:"v2 wrote an array or object as text (`[1, 2]` was `'1,2'`) and `null` as `'null'`, where v3 fails on an array or object, which `join` or `buildString` render, and keeps `null`",boolean:"v2 made any text but `''` `true` (`'false'` was `true`), where v3 reads `'true'` and `'false'` as the booleans they name",array:"v2 wrapped `null` as `[null]`, where v3 keeps `null`"},xe=e=>{const t="bool"===e?"boolean":e;if("string"==typeof t&&Object.hasOwn(Le,t))return Le[t];return`the target type ${f(e)?"is computed":`\`${b(e)}\` is not one v2 had`}, and v2 guessed differently for each: ${Object.values(Le).join("; ")}`},_e=(e,{comment:t,fallback:s,noCache:a,vars:r})=>({...void 0!==t&&{"//":t},...e,...void 0!==s&&{fallback:s},...void 0!==a&&{noCache:a},...void 0!==r&&{vars:r}}),Me=e=>{const{"//":t,fallback:s,noCache:a,vars:r,...n}=e;return{body:n,carried:{comment:t,fallback:s,noCache:a,vars:r}}},qe=(e,t)=>void 0===e?t:void 0===t?e:[...Array.isArray(e)?e:[e],...Array.isArray(t)?t:[t]],Be=(e,t)=>void 0===e?t:void 0===t?e:{...e,...t},Ge=(e,t)=>{const s=`$vars.${t}`;return"string"==typeof e?e===s||e.startsWith(`${s}.`)||e.startsWith(`${s}[`):Array.isArray(e)?e.some(e=>Ge(e,t)):r(e)&&!l(e)&&Object.values(e).some(e=>Ge(e,t))},He=(e,t)=>{const s=new Set(t),a=new Map,r=e=>e.replace(/^\$+/,"").replace(/[.[\]]/g,"_")||"_";for(const t of e)r(t)!==t.slice(1)||s.has(t.slice(1))||a.set(t,t.slice(1));a.forEach(e=>s.add(e));for(const t of e.filter(e=>!a.has(e)).sort()){let e=r(t);for(let a=2;s.has(e);a++)e=`${r(t)}_${a}`;s.add(e),a.set(t,e)}return{names:a,taken:s}},Qe=(e,t)=>!0===e?.parameters.get(`$${t}`)?.exact,De=(e,t)=>{if(Array.isArray(e)&&e.forEach(e=>De(e,t)),!r(e)||l(e))return t;for(const[s,a]of Object.entries(e))"vars"===s&&r(a)&&Object.keys(a).forEach(e=>t.add(e)),De(a,t);return t};class Fe{sources;options;fragments;onRead;issues=[];dropped=new Set;droppedPaths=[];raised=new WeakMap;constructor(e,t,s,a){this.sources=e,this.options=t,this.fragments=s,this.onRead=a}pathOf(e,t,s){return this.sources.get(e)?.keys[String(t)]??[...s,t]}pathIn(e,[t,...s],a){let r=this.pathOf(e,t,a),n=e[t];for(const e of s)"object"==typeof n&&null!==n?(r=this.pathOf(n,e,r),n=n[e]):r=[...r,e];return r}value(e,t,s){const a=this.issues.length,n=r(e)&&this.sources.get(e)?.path||t,o=this.convert(e,n,s);return"object"==typeof e&&null!==e&&this.raised.set(e,{from:a,to:this.issues.length}),o}convert(e,t,s){if(Array.isArray(e))return e.map((a,r)=>this.value(a,this.pathOf(e,r,t),s));if("string"==typeof e)return this.string(e,t,s);if(!r(e))return e;const a=this.sources.get(e)?.quoted;if(void 0!==a){const{code:t,at:s,name:r=""}=a;return"unknown-operator"===t?this.placeholder(e,t,s,{name:r}):"computed-children"===t?this.placeholder(e,t,s,{operator:r}):this.placeholder(e,t,s)}return Object.hasOwn(e,"fragment")?this.call(e,t,s):Object.hasOwn(e,"operator")?this.node(e,t,s):this.plain(e,t,s)}kept(t){const s=({path:t})=>this.droppedPaths.some(s=>e(t,s));return[...t.filter(e=>!s(e)),...this.issues.filter(e=>!this.dropped.has(e))]}drop(e){if("object"!=typeof e||null===e)return;const t=this.raised.get(e);if(void 0===t)for(const t of Object.values(e))this.drop(t);else for(let e=t.from;e<t.to;e++)this.dropped.add(this.issues[e])}asWritten(e){return void 0!==this.sources.get(e)?.quoted}evaluates(e){return Array.isArray(e)?e.some(e=>this.evaluates(e)):!!r(e)&&(!(!R(e)&&!this.asWritten(e))||!0===this.options.evaluateFullObject&&Object.values(e).some(e=>this.evaluates(e)))}settle({leftOut:t,start:a},r){for(const{input:n,path:o,evaluated:i}of t){if(this.drop(n),this.droppedPaths.push(o),!i||!this.evaluates(n))continue;this.issues.slice(a).some(t=>"non-convertible"===t.tag&&!this.dropped.has(t)&&t.path.length>r.length&&e(o,t.path))||this.issues.push(s("discarded-expression",o))}}string(e,t,s){if(U(e)){const a=s.refs.get(e);if(void 0!==a)return a===s.params?.get(e)&&this.onRead?.(e,t,!1),a;if(void 0!==this.onRead)return this.onRead(e,t,!1),`$params.${z(e)}`}return n.test(e)?c(e):e}plain(e,t,s){return this.options.evaluateFullObject?this.walked(e,t,s):y(e)?c(e):e}walked(e,t,s){const{vars:a,inner:r}=this.declare(e,t,s,!1),n=Object.entries(e).filter(([e])=>!U(e)).map(([s,a])=>[s,this.value(a,this.pathOf(e,s,t),r)]);return n.some(([e])=>"vars"===e||"//"===e)?_e({operator:"buildObject",entries:n.map(([e,t])=>({key:e,value:t}))},{vars:a}):{...Object.fromEntries(n),...void 0!==a&&{vars:a}}}declare(e,t,s,a=!0){const r=Object.keys(e).filter(U);if(0===r.length)return{inner:s};const{names:n,taken:o}=He(r,s.names),i=Object.fromEntries(r.map(r=>{const o=e[r],i=a&&"string"==typeof o&&o!==r&&!s.refs.has(o)?n.get(o):void 0,u=void 0!==i?`$vars.${i}`:this.value(o,this.pathOf(e,r,t),s);return[n.get(r),u]})),u=new Map(s.refs);for(const[e,t]of n)u.set(e,`$vars.${t}`);return{vars:i,inner:{refs:u,names:o,params:s.params},sources:new Map(r.map(s=>[n.get(s),{input:e[s],path:this.pathOf(e,s,t)}]))}}node(e,t,s,a){const r=e.operator,n=N[r].map(({name:e})=>e).filter(e=>"useCache"!==e),{vars:o,inner:i,sources:u}=a??this.declare(e,t,s),c=[],l={};for(const s of n)Object.hasOwn(e,s)&&(l[s]=this.parameter(r,s,e,t,i));const h=s=>this.value(e[s],this.pathOf(e,s,t),i),p=Object.fromEntries(this.extraKeys(e,r,n).map(e=>[e,h(e)])),d={};Object.hasOwn(e,"fallback")&&(d.fallback=h("fallback")),Object.hasOwn(e,"outputType")&&Object.assign(d,{outputType:h("outputType"),outputTypeAt:"outputType"});const m=new Set([...i.names,...De([l,p,d],new Set)]),f=this.context(e,t,c,m,n,u),v=((e,t,s)=>{const a={};for(const[r,n]of Object.entries(e.params))if(Object.hasOwn(t.v2,r)&&"consumed"!==n)if("omitted"===n)s.discard(r);else if("string"==typeof n)a[n]=t.v2[r];else{const e=n.value(t.v2[r],s);void 0!==e?a[n.to]=e:s.discard(r)}Object.assign(a,e.add);const r={to:e.to,params:a,...t};return e.build?e.build(r,s):me(r)})(Ee[r],{v2:l,extra:p,modifiers:d},f),y=this.noCache(e,r,f),g=this.comment(e,[...n,...Object.keys(p)],c),b=this.attach(v,{comment:g,noCache:y,vars:o},d,f);return this.settle(f,t),b}parameter(e,t,s,n,o){const i=s[t],u=this.pathOf(s,t,n);if(!a[e]?.evaluatesContents?.includes(t))return this.value(i,u,o);if(Array.isArray(i)){if("MATCH"===e)return this.branchList(i,u,o);if("BUILD_OBJECT"===e)return this.entries(i,u,o)}if("BUILD_OBJECT"===e)return this.value(i,u,o);if(!r(i)||this.asWritten(i)||("MATCH"===e?Object.hasOwn(i,"operator"):R(i)))return this.value(i,u,o);const c=this.sources.get(i)?.path??u,l=(e=()=>!1)=>{const t={},s={};for(const[a,r]of Object.entries(i))e(a)?s[a]=r:t[a]=this.value(r,this.pathOf(i,a,c),o);return Object.keys(s).length>0?{"//":s,...t}:t};switch(e){case"MATCH":return l();case"STRING_SUBSTITUTION":return this.options.evaluateFullObject?this.walked(i,c,o):l(U);default:return this.walked(i,c,o)}}branchList(e,t,s){return e.map((a,r)=>r%2==0?a:this.value(a,this.pathOf(e,r,t),s))}entries(e,t,s){return this.options.evaluateFullObject||!e.every(r)?this.value(e,t,s):e.map((a,r)=>{const n=this.pathOf(e,r,t);if(R(a)||this.asWritten(a))return this.value(a,n,s);const o=this.sources.get(a)?.path??n,i={};for(const e of["key","value"])Object.hasOwn(a,e)&&(i[e]=this.value(a[e],this.pathOf(a,e,o),s));return i})}extraKeys(e,t,s){if("SQL"===t)return Object.hasOwn(e,"type")?["type"]:[];if("MATCH"!==t)return[];const a=["operator",...s,...$e,"//"];return Object.keys(e).filter(e=>!a.includes(e)&&!U(e))}context(e,t,a,r,n=[],o){const i=[];return{leftOut:i,start:this.issues.length,discard:(s,a)=>{const r="string"==typeof s?[s]:s;let o=e;for(const e of r){if("object"!=typeof o||null===o||!Object.hasOwn(o,e))return;o=o[e]}const u=this.pathIn(e,r,t),c=n.includes(String(r[0]));if(void 0===a)i.push({input:o,path:u,evaluated:c});else if(Array.isArray(o))for(let e=a;e<o.length;e++)i.push({input:o[e],path:this.pathOf(o,e,u),evaluated:c})},discardVars:e=>{for(const t of e){const e=o?.get(t);void 0!==e&&i.push({...e,evaluated:!0})}},options:this.options,path:t,at:s=>this.pathOf(e,s,t),issue:(r,n,...o)=>{const i=void 0===n?t:"string"==typeof n?this.pathOf(e,n,t):this.pathIn(e,n,t),c=s(r,i,...o);this.issues.push(c),"non-convertible"===c.tag&&a.push(`${u}${c.message}`)},freshVar:e=>{let t=e;for(let s=2;r.has(t);s++)t=`${e}_${s}`;return r.add(t),t}}}noCache(e,t,s){const a=Ue[t];if(void 0===a)return;const r=e.useCache,n="boolean"==typeof r?r:this.options.useCache??a,o=!n&&Re.has(t),i=Object.hasOwn(e,"useCache")?"useCache":void 0;return void 0!==i&&"boolean"!=typeof r&&s.issue("deciding-value","useCache",{reason:fe("useCache",r),wrote:o?"`noCache: true`":"no `noCache`",key:"useCache"}),n&&"CUSTOM_FUNCTIONS"===t&&s.issue("cache-opt-in",i,Pe(e)),!!o||void 0}callNoCache(e,t,s){if(!Object.hasOwn(e,"useCache"))return;s.discard("useCache");const a=t?.body;if(void 0!==t&&void 0!==a&&Object.hasOwn(a,"useCache"))return void s.issue("shadowed-argument","useCache",{fragment:t.key,key:"useCache"});const r=t?.operator,n=void 0===r?void 0:Ue[r];if(void 0!==t&&void 0===n)return;const o=this.options.useCache??n??!0,i=e.useCache,u="boolean"==typeof i?i:o,c="CUSTOM_FUNCTIONS"===r,l=!u&&!c&&(void 0===t||o);return"boolean"!=typeof i&&s.issue("deciding-value","useCache",{reason:fe("useCache",i),wrote:l?"`noCache: true`":"no `noCache`",key:"useCache"}),void 0===t||!u||!c&&o||s.issue("cache-opt-in","useCache",c?Pe(a):{fragment:t.key}),!!l||void 0}comment(e,t,s){const a=["operator",...t,...$e,"//"],r=Object.fromEntries(Object.entries(e).filter(([e])=>!a.includes(e)&&!U(e)));Object.assign(r,this.sources.get(e)?.ignored);const n=[...s,...Object.hasOwn(e,"//")?[e["//"]]:[],...Object.keys(r).length>0?[r]:[]];return 0===n.length?void 0:1===n.length?n[0]:n}attach(e,t,s,a){let{vars:r}=t;const{fallback:n}=s;if(({result:e,vars:r}=this.ownVar(e,r,n)),!Object.hasOwn(s,"outputType")||!s.outputType)return this.carry(e,{...t,fallback:n,vars:r},Object.hasOwn(s,"fallback"),a);const o=s.outputType;a.issue("output-type",s.outputTypeAt??"outputType",{differences:xe(o)});const i=d(e)&&!l(e),u=i?this.carry(e,{comment:t.comment,noCache:t.noCache},!1,a):e;return this.carry({operator:"convert",value:u,to:"bool"===o?"boolean":o},{comment:i?void 0:t.comment,fallback:n,vars:r},Object.hasOwn(s,"fallback"),a)}ownVar(e,t,s){const a={...t};let r="string"==typeof e?/^\$vars\.([^.[]+)$/.exec(e)?.[1]:void 0;for(;void 0!==r&&Object.hasOwn(a,r);){const{[r]:t,...n}=a;[e=t,s,...Object.values(n)].some(e=>Ge(e,r))||delete a[r],r="string"==typeof e?/^\$vars\.([^.[]+)$/.exec(e)?.[1]:void 0}return{result:e,vars:Object.keys(a).length>0?a:void 0}}carry(e,t,s,a){const{comment:n,fallback:o,noCache:u,vars:c}=t;if(d(e)&&!l(e)){const{body:t,carried:r}=Me(e);let i=r.fallback;return s&&(void 0!==r.fallback?i=this.chain(r.fallback,o,a):(this.beneath(t,r.vars)&&a.issue("missing-data-fallback","fallback"),i=o)),_e(t,{comment:qe(r.comment,n),fallback:i,noCache:r.noCache??u,vars:Be(c,r.vars)})}if("string"==typeof e&&i.test(e)){const t=e.replace(/^\$(?:data|d)\.?/,""),r=""!==t;if(s&&!r&&a.discard("fallback"),!(s&&r||void 0!==c))return e;const i={operator:"get",path:t,...s&&r&&{default:o}};return _e(i,{comment:n,vars:c})}if(r(e)&&!l(e)&&v(e)){const{vars:t,...r}=e,i=Be(c,t);if(!s)return _e(r,{comment:n,vars:i});const u={operator:"buildObject",entries:Object.entries(r).map(([e,t])=>({key:e,value:t}))};return this.uncaught(u)&&a.issue("missing-data-fallback","fallback"),_e(u,{comment:n,fallback:o,vars:i})}if(Array.isArray(e)&&v(e)&&(s||void 0!==c)){const t={operator:"convert",value:e,to:"array"};return s&&this.uncaught(t)&&a.issue("missing-data-fallback","fallback"),_e(t,{comment:n,fallback:s?o:void 0,vars:c})}if(s&&a.discard("fallback"),void 0!==c&&a.discardVars(Object.keys(c)),!l(e)||void 0===n)return e;const{body:h,carried:p}=Me(e);return _e(h,{comment:qe(p.comment,n)})}chain(e,t,s){if(!d(e)||l(e))return s.discard("fallback"),e;const{body:a,carried:r}=Me(e);return void 0!==r.fallback?_e(a,{...r,fallback:this.chain(r.fallback,t,s)}):(this.beneath(a)&&s.issue("missing-data-fallback","fallback"),_e(a,{...r,fallback:t}))}uncaught(e){return C(e,this.fragments.bodyReads)}beneath(e,t){return Object.hasOwn(e,"fragment")?this.fragments.bodyReads(String(e.fragment)):this.uncaught(e)||this.uncaught(t)}call(e,t,s){const a=this.fragments.fragments.get(String(e.fragment)),r=[],n=this.sharedArguments(e,s,a),o={...s,names:n.taken},i=this.context(e,t,r,new Set(o.names)),u={fragment:a?.name??e.fragment},{parameters:c,vars:l}=this.callArguments(e,t,o,a,i,n.names);void 0!==c&&(u.parameters=c);const h={};Object.hasOwn(e,"fallback")&&(h.fallback=this.value(e.fallback,this.pathOf(e,"fallback",t),o)),this.callOutput(e,t,o,a,h,i);const p=this.callNoCache(e,a,i);Object.hasOwn(e,"operator")&&(i.issue("overridden-value","operator",{key:"operator",winner:"fragment"}),i.discard("operator"));for(const t of Object.keys(e))Ie.includes(t)||U(t)||(i.issue("body-override",t,{key:t}),i.discard(t));const d=[...r,...Object.hasOwn(e,"//")?[e["//"]]:[]],m=0===d.length?void 0:1===d.length?d[0]:d,f=this.attach(u,{comment:m,noCache:p,vars:l},h,i);return this.settle(i,t),f}sharedArguments(e,t,s){const a=e.parameters;if(!r(a)||R(a))return He([],t.names);const n=Object.keys(a).filter(e=>U(e)&&!(Object.hasOwn(a,e.slice(1))&&Qe(s,e.slice(1)))),o=e=>{const s=a[e];return"string"==typeof s&&s!==e&&n.includes(s)&&!t.refs.has(s)?s:void 0},i=new Set,u=n.filter(e=>void 0===s||s.parameters.has(e));for(;u.length>0;){const e=o(u.pop());void 0===e||i.has(e)||(i.add(e),u.push(e))}return He(n.filter(e=>i.has(e)),t.names)}callArguments(e,t,s,a,n,o){const i=e.parameters,u=this.pathOf(e,"parameters",t);if(null!=i&&(!r(i)||R(i))){n.issue("computed-arguments","parameters");const e=this.value(i,u,s);return f(e)?{parameters:e}:(n.leftOut.push({input:i,path:u,evaluated:!1}),{})}const c={},l={},h=new Set,p=r(i)?Object.entries(i):[],d=r(i)&&this.sources.get(i)?.path||u,m=(e,t,a)=>{const r="string"!=typeof t||t===e||s.refs.has(t)?void 0:o.get(t);return void 0!==r?`$vars.${r}`:this.value(t,a,s)};for(const[e,t]of p){const s=["parameters",e],r=this.pathOf(i,e,d),u=o.get(e);if(void 0!==u&&(l[u]=m(e,t,r)),!U(e)&&!Qe(a,e)){n.issue("body-override",s,{key:e}),n.leftOut.push({input:t,path:r,evaluated:!1});continue}if(U(e)&&Object.hasOwn(i,e.slice(1))&&Qe(a,e.slice(1))){n.issue("overridden-value",s,{key:e,winner:e.slice(1)}),n.leftOut.push({input:t,path:r,evaluated:!0});continue}const p=U(e)?e:`$${e}`,f=a?.parameters.get(p);if(void 0!==a&&void 0===f){if(void 0!==u)continue;n.issue("unknown-argument",s,{fragment:a.key,name:e}),n.leftOut.push({input:t,path:r,evaluated:!0});continue}c[f?.name??z(p)]=void 0!==u?`$vars.${u}`:m(e,t,r),h.add(p)}return void 0!==a&&this.fill(a,h,c,t,s),{...Object.keys(c).length>0&&{parameters:c},...Object.keys(l).length>0&&{vars:l}}}fill(e,t,s,a,r){for(const n of e.parameters.values()){if(t.has(n.key)||void 0!==n.default)continue;let e=r.refs.get(n.key);if(void 0===e){if(void 0===this.onRead)continue;this.onRead(n.key,a,!0),e=`$params.${z(n.key)}`}else e===r.params?.get(n.key)&&this.onRead?.(n.key,a,!0);s[n.name]=e}}callOutput(e,t,s,a,r,n){const o=["outputType","type"].find(t=>Object.hasOwn(e,t)&&("type"===t||null!=e[t]));if(void 0===o)return;if("outputType"===o&&Object.hasOwn(e,"type")&&(n.issue("overridden-value","type",{key:"type",winner:"outputType"}),n.discard("type")),void 0!==a){const t=e=>{n.issue("unused-output-type",o,{key:o,reason:`the body of \`${a.key}\` ${e}`}),n.discard(o)};if(void 0===a.body)return t("is not an operator node, which v2 returned as it was");if("outputType"===a.ownOutput||"type"===a.ownOutput&&"type"===o)return t("sets its own output type");const s=e.type,r="SQL"===a.operator&&("object"==typeof s&&null!==s||"string"==typeof s&&(U(s)||Ne.includes(s)));if("type"===o&&("PLUS"===a.operator||r))return n.issue("body-override","type",{key:o}),n.discard("type");"outputType"===o&&a.convertsByType&&n.issue("replaced-output-type","outputType",{fragment:a.key})}const i=this.value(e[o],this.pathOf(e,o,t),s);Object.assign(r,{outputType:i,outputTypeAt:o})}body(e){const t=new Map([...e.parameters.values()].map(({key:e,name:t})=>[e,`$params.${t}`])),s={refs:t,names:new Set,params:t},a=new Map(t),r=new Map,n={},o=new Map;for(const{key:t,name:i,default:u}of e.parameters.values()){if(void 0===u)continue;const e=this.value(u.value,u.path,s);v(e)?(r.set(t,"computed"),n[i]={operator:"firstOf",values:[`$params.${i}`,e]},o.set(i,{input:u.value,path:u.path}),a.set(t,`$vars.${i}`)):r.set(t,{constant:T(e)})}const i={refs:a,names:new Set(Object.keys(n)),params:a},u=i.names.size>0?n:void 0,c=e.body,l=this.sources.get(c)?.path??[e.key];return void 0!==this.sources.get(c)?.quoted?{expression:this.value(c,l,i),defaults:r}:{expression:this.node(c,l,i,{vars:u,inner:i,sources:o}),defaults:r}}placeholder(e,t,a,...r){const n=s(t,a,...r);return this.issues.push(n),c(e,`${u}${n.message}`)}}const We=e=>(t,s,a)=>new Fe(t.sources,e,s,a).body(t).expression,Je=e=>{const t=r(e)?e:{},{fragments:s,functions:a,useCache:n}=t;return{fragments:r(s)?s:{},functions:Array.isArray(a)?a.filter(e=>"string"==typeof e):r(a)?Object.keys(a):[],evaluateFullObject:Boolean(t.evaluateFullObject),noShorthand:Boolean(t.noShorthand),caseInsensitive:Boolean(t.caseInsensitive),...null!=n&&{useCache:Boolean(n)}}},Ve=e=>{try{return JSON.stringify(e,function(e,t){const s=this[e],a=null===s||"string"==typeof s||"boolean"==typeof s||"number"==typeof s&&Number.isFinite(s)||"object"==typeof s&&(Array.isArray(s)||(e=>{const t=Object.getPrototypeOf(e);return"function"!=typeof e.toJSON&&(null===t||null===Object.getPrototypeOf(t))})(s));if(!a)throw new TypeError("not JSON");return t})}catch{return}};let Xe;const Ye=(e,t,a)=>{if(!(e instanceof RangeError))throw e;const r=s("unconvertible-input",a);return{expression:c(t,`${u}${r.message}`),issue:r}},ze=(e,t)=>{const s=Je(t),a=J(e,s),r=new Fe(a.sources,s,(e=>{const t=Ve(e);if(void 0!==t&&t===Xe?.key)return Xe.catalogue;const s=oe(e,We(e));return void 0!==t&&(Xe={key:t,catalogue:s}),s})(s)),n={refs:new Map,names:new Set};return{expression:m(r.value(a.expression,[],n)),issues:r.kept(a.issues)}},Ze=e=>{const t=Je(e),s=oe(t,We(t)),a={},r=[];for(const e of s.fragments.values()){if(void 0===e.body){r.push(...e.issues),a[e.name]=ue(e,g(e.data),new Map,r);continue}const n=new Fe(e.sources,t,s),{expression:o,defaults:i}=n.body(e);r.push(...n.kept(e.issues)),a[e.name]=ue(e,m(o),i,r)}return{fragments:a,issues:r}},Ke=(e,t)=>((e,t)=>{try{return ze(e,t)}catch(t){const s=Ye(t,e,[]);return{expression:s.expression,issues:[s.issue]}}})(e,t),et=e=>(e=>{try{return Ze(e)}catch(t){const s={},a=[],n=r(e?.fragments)?e.fragments:{};for(const[e,r]of Object.entries(n)){const n=Ye(t,r,[e]);s[e]={expression:n.expression},a.push(n.issue)}return{fragments:s,issues:a}}})(e);export{Ke as migrateV2Expression,et as migrateV2Fragments};
package/package.json CHANGED
@@ -1,72 +1,129 @@
1
1
  {
2
2
  "name": "fig-tree-evaluator",
3
- "version": "2.23.2",
3
+ "version": "3.0.0-preview.10",
4
4
  "description": "Module to evaluate JSON-structured expression trees",
5
- "main": "build/index.cjs.js",
6
- "module": "build/index.esm.js",
5
+ "type": "module",
6
+ "main": "./build/index.js",
7
+ "types": "./build/index.d.ts",
7
8
  "sideEffects": false,
8
- "types": "build/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./build/index.d.ts",
12
- "import": "./build/index.esm.js",
13
- "require": "./build/index.cjs.js",
14
- "default": "./build/index.esm.js"
12
+ "default": "./build/index.js"
13
+ },
14
+ "./migrate": {
15
+ "types": "./build/migrate/index.d.ts",
16
+ "default": "./build/migrate/index.js"
17
+ },
18
+ "./editor-hints": {
19
+ "types": "./build/editor-hints/index.d.ts",
20
+ "default": "./build/editor-hints/index.js"
21
+ },
22
+ "./format": {
23
+ "types": "./build/format/index.d.ts",
24
+ "default": "./build/format/index.js"
25
+ },
26
+ "./authoring": {
27
+ "types": "./build/authoring/index.d.ts",
28
+ "default": "./build/authoring/index.js"
29
+ }
30
+ },
31
+ "typesVersions": {
32
+ "*": {
33
+ "migrate": [
34
+ "./build/migrate/index.d.ts"
35
+ ],
36
+ "editor-hints": [
37
+ "./build/editor-hints/index.d.ts"
38
+ ],
39
+ "format": [
40
+ "./build/format/index.d.ts"
41
+ ],
42
+ "authoring": [
43
+ "./build/authoring/index.d.ts"
44
+ ]
15
45
  }
16
46
  },
17
47
  "files": [
18
48
  "build"
19
49
  ],
20
- "repository": "git+https://github.com/CarlosNZ/fig-tree-evaluator.git",
50
+ "engines": {
51
+ "node": ">=22.12"
52
+ },
53
+ "packageManager": "pnpm@10.8.1",
54
+ "pnpm": {
55
+ "onlyBuiltDependencies": [
56
+ "esbuild",
57
+ "sqlite3",
58
+ "unrs-resolver"
59
+ ]
60
+ },
61
+ "repository": {
62
+ "type": "git",
63
+ "url": "git+https://github.com/CarlosNZ/fig-tree-evaluator.git"
64
+ },
21
65
  "author": "Carl Smith <5456533+CarlosNZ@users.noreply.github.com>",
22
66
  "license": "MIT",
23
- "devDependencies": {
24
- "@rollup/plugin-typescript": "^11.1.5",
25
- "@testing-library/jest-dom": "^6.1.3",
26
- "@testing-library/react": "^14.0.0",
27
- "@types/jest": "^29.5.5",
28
- "@types/node": "^20.8.2",
29
- "@types/node-fetch": "^2.6.11",
30
- "@types/pg": "^8.10.3",
31
- "@typescript-eslint/eslint-plugin": "^6.11.0",
32
- "@typescript-eslint/parser": "^6.11.0",
33
- "axios": "^1.7.2",
34
- "dotenv": "^16.0.1",
35
- "eslint": "^8.53.0",
36
- "fig-tree-evaluator": "^2.23.1",
37
- "jest": "^29.7.0",
38
- "node-fetch": "2.7.0",
39
- "pg": "^8.11.3",
40
- "prettier": "^3.0.3",
41
- "rimraf": "^5.0.5",
42
- "rollup": "^4.53.3",
43
- "rollup-plugin-bundle-size": "^1.0.3",
44
- "rollup-plugin-dts": "^6.0.2",
45
- "rollup-plugin-sizes": "^1.0.5",
46
- "rollup-plugin-terser": "^7.0.2",
47
- "sqlite": "^5.1.1",
48
- "sqlite3": "^5.1.7",
49
- "ts-jest": "^29.1.1",
50
- "ts-node": "^10.8.0",
51
- "tslib": "^2.6.2",
52
- "typescript": "^5.2.0"
53
- },
54
67
  "scripts": {
55
- "setup": "yarn install && cd demo && yarn install",
56
68
  "test": "jest",
57
- "generate": "ts-node ./codegen/buildOperatorAliasReference.ts",
58
- "generateMassiveQuery": "ts-node ./codegen/generateMassiveQuery.ts",
59
- "getVersion": "ts-node ./codegen/getVersion.ts",
60
- "lint": "eslint . --ext .ts",
61
- "build": "rimraf ./build && rollup -c && rimraf ./build/dts",
69
+ "test:v2": "jest --config jest.v2.config.js",
70
+ "test:live": "jest --config jest.live.config.js",
71
+ "generate:operators": "tsx codegen/buildOperatorReference.ts",
72
+ "artifacts:fetch": "node codegen/fetchArtifacts.mjs",
73
+ "generateMassiveQuery": "tsx codegen/generateMassiveQuery.ts",
74
+ "getVersion": "tsx codegen/getVersion.ts",
75
+ "checkDefinitions": "tsx codegen/checkDefinitions.ts",
76
+ "extractV2Table": "tsx codegen/extractV2Table.ts",
77
+ "coverageCases": "tsx codegen/coverageCasesPage.ts",
78
+ "differential": "tsx differential/index.ts",
79
+ "lint": "eslint .",
80
+ "format": "prettier --write .",
81
+ "format:check": "prettier --check .",
82
+ "typecheck": "tsc --noEmit -p tsconfig.test.json && tsc -p tsconfig.globals.json",
83
+ "build": "pnpm getVersion && pnpm checkDefinitions && rimraf ./build && rollup -c && rimraf ./build/dts",
84
+ "size": "node codegen/bundleSize.mjs",
85
+ "size:imports": "node codegen/importTree.mjs",
86
+ "check:package": "node codegen/checkPackage.mjs",
62
87
  "compile": "rimraf ./build && tsc",
63
- "prebuild": "yarn generate && yarn getVersion",
64
- "dev": "cp -n src/dev/playground_example.ts src/dev/playground.ts || ts-node src/dev/playground.ts",
65
- "prepublishOnly": "yarn build"
88
+ "dev": "node codegen/dev.mjs",
89
+ "bench": "node codegen/bench.mjs",
90
+ "bench:browser": "node codegen/benchBrowser.mjs",
91
+ "bench:serve": "node codegen/benchServe.mjs",
92
+ "release": "node codegen/release.mjs",
93
+ "prepublishOnly": "pnpm build"
66
94
  },
67
- "dependencies": {
95
+ "devDependencies": {
96
+ "@eslint/js": "^9.0.0",
97
+ "@jridgewell/trace-mapping": "^0.3.31",
98
+ "@rollup/plugin-terser": "^0.4.4",
99
+ "@rollup/plugin-typescript": "^12.3.0",
100
+ "@types/jest": "^30.0.0",
101
+ "@types/node": "^22.0.0",
102
+ "@types/node-fetch": "^2.6.13",
103
+ "@types/pg": "^8.20.0",
104
+ "axios": "^1.18.1",
68
105
  "dequal": "^2.0.3",
69
- "object-property-extractor": "^1.0.14"
106
+ "dotenv": "^16.6.1",
107
+ "esbuild": "0.28.1",
108
+ "eslint": "^9.0.0",
109
+ "eslint-plugin-comment-length": "^2.3.1",
110
+ "fig-tree-evaluator-v2": "npm:fig-tree-evaluator@2.23.2",
111
+ "globals": "^17.12.0",
112
+ "jest": "^30.4.2",
113
+ "node-fetch": "2.7.0",
114
+ "object-property-extractor": "^1.0.14",
115
+ "pg": "^8.22.0",
116
+ "prettier": "^3.9.4",
117
+ "rimraf": "^6.1.3",
118
+ "rollup": "^4.62.2",
119
+ "rollup-plugin-dts": "^6.4.1",
120
+ "sqlite": "^5.1.1",
121
+ "sqlite3": "^5.1.7",
122
+ "ts-jest": "^29.4.11",
123
+ "tslib": "^2.8.1",
124
+ "tsx": "^4.19.0",
125
+ "typescript": "^5.9.3",
126
+ "typescript-eslint": "^8.63.0"
70
127
  },
71
128
  "bugs": {
72
129
  "url": "https://github.com/CarlosNZ/fig-tree-evaluator/issues"