diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..8bf4490796e8f3910bafa97c1b7e223712851f62 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,3 +33,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text *tfevents* filter=lfs diff=lfs merge=lfs -text + +# The browser demo's SQLite runtime is below 1 MiB. Keep it in ordinary Git so +# the static Space is self-contained and reproducible without Git LFS tooling. +assets/*.wasm -filter -diff -merge -text +dist/assets/*.wasm -filter -diff -merge -text diff --git a/README.md b/README.md index c1027bda56a5a5d6feb7684407ba8bc93454d7b0..ec10b55a6288abb78647bc0316b77379a58aaf3f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ sdk: static app_file: dist/index.html pinned: false license: apache-2.0 -short_description: Typed queries and real TraceChain, entirely in your browser. +short_description: Business UI to generated Q, TraceChain and real SQLite SQL. tags: - teaql - sqlite @@ -17,56 +17,46 @@ tags: # TeaQL Browser SQLite Playground -Edit a generated TypeScript Q query and inspect its data, facets and actual SQL -execution evidence. SQLite/WASM runs in a browser worker; there is no application -backend or server-side business database. Query data stays in your browser. +This Space demonstrates an auditable chain from a recognizable order-management +interface to generated TeaQL Q expressions, runtime TraceChain and the actual SQL +executed by SQLite/WASM in the browser. -The deterministic fixture contains four synthetic orders, twenty items and three -statuses. The default query demonstrates filtered pagination, named totals, -status COUNT/SUM facets, status details and three-item previews with full counts. -Switch the example, edit the query, or restore the preset. Peggy parses a controlled -query AST; it does not evaluate arbitrary JavaScript, imports or assignments. +The default page is the full order center. Its status cards, colors, order counts, +order totals, rows, item previews and pagination are produced by one generated Q +request whose search parameters change without changing the query shape. Results +can be inspected as a table or a tree. The evidence table shows execution time, +request identity, the runtime-provided TraceChain and executed SQL. -## Request TraceChain +Additional entry points are retained independently: -Each SQL record retains its root purpose, root comment, native Q-operation parents -and nested business comments. The browser only renders runtime `traceChain`; -physical `tracePath` remains separate. For example: +- [`/orders.html`](./orders.html): generated Order model and request-tree conformance view. +- [`/work-items.html`](./work-items.html): the earlier WorkItem browser SQLite example. -```text -render order list page: load order list → selectStatusWith(...) → load status -render order list page: load order list → facetByStatusAs('statusCounts') → load status facets -``` - -The table displays `Time | Identity | Trace chain | SQL`. Time is recorded execution -duration; Identity is the request entity, not an invented user or object ID. SQL is -the runtime's parameter-filled diagnostic text, with its masking policy intact. -An explicit execution observer retains evidence even when diagnostic logging is off. - -## Storage and reproducibility +All data is deterministic demo data and remains in the browser. Memory mode works +everywhere. OPFS is offered only when the hosting origin provides the required +cross-origin isolation. -Memory is the default and resets on refresh. Audited generated mutation APIs seed -the data; Reset recreates it. OPFS is enabled only when the hosting origin provides -cross-origin isolation. When unavailable on Hugging Face, the option is disabled -and memory mode remains fully usable. +## Reproduce the deployed build -This demo uses a tested **unreleased request-tree runtime snapshot**, based on -the [TeaQL TypeScript repository](https://github.com/teaql/teaql-ts). Its package -version remains 0.3.0; this is not a claim that published npm 0.3.0 contains the new -TraceChain design. Exact source, model, generated library, packaged runtime and -hashes are retained in [source](https://huggingface.co/spaces/teaql/browser-sqlite-playground/tree/main/source). +The exact runtime, tests, model, generated Order library and browser application +source are retained under [`source/teaql-ts`](./source/teaql-ts). They correspond to +TeaQL TypeScript commit `e87b5d843a1bc2ae5f677f402b6b3177a7d40b50` on `main`. ```bash -hf download teaql/browser-sqlite-playground --repo-type space --include 'source/**' --local-dir teaql-demo -cd teaql-demo/source/browser-sqlite +cd source/teaql-ts +npm ci +npm run build +npm test -- --runInBand --silent + +cd examples/browser-sqlite npm ci npm run build npm run smoke -npm run dev +npm run smoke:orders ``` -The included browser test checks memory/OPFS, refresh/reset, logging modes, exact -facets/counts/previews, real TraceChain rows, query presets and rejected constructor -access. This first profile does not implement multi-tab coordination or true streaming. +The validated runtime result was 56 passing suites and 604 passing tests, with six +tests skipped by the repository configuration. Both real-browser smoke suites pass. -Learn more at [teaql.io](https://teaql.io/). +Learn more at [teaql.io](https://teaql.io/) and inspect the upstream source at +[github.com/teaql/teaql-ts](https://github.com/teaql/teaql-ts). diff --git a/assets/dynamic-search-BBmdgl4H.js b/assets/dynamic-search-BBmdgl4H.js new file mode 100644 index 0000000000000000000000000000000000000000..08ffb8822e2d0b40448ab09bc0b30e38c4ce5d16 --- /dev/null +++ b/assets/dynamic-search-BBmdgl4H.js @@ -0,0 +1,8 @@ +(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))n(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const s of o.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&n(s)}).observe(document,{childList:!0,subtree:!0});function t(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(r){if(r.ep)return;r.ep=!0;const o=t(r);fetch(r.href,o)}})();const Ae=Object.freeze({success:()=>{},failure:()=>{}}),rt=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function st(i){const e={"teaql.operation.family":i.family,"teaql.operation.name":i.name};for(const[t,n]of Object.entries(i.attributes||{}))rt.has(t)||(e[t]=n);return Object.freeze({...i,attributes:Object.freeze(e)})}function N(i,e){if(!i)return Ae;try{const t=i.start(st(e));let n=!1;return{correlation:()=>{try{return t.correlation?.()}catch{return}},run:t.run?r=>t.run(r):r=>r(),success(r){if(!n){n=!0;try{t?.success(r)}catch{}}},failure(r){if(!n){n=!0;try{t?.failure(r)}catch{}}}}}catch{return Ae}}async function D(i,e,t,n){const r=N(i,e);try{const o=await(r.run?r.run(t):t());return r.success(n?.(o)),o}catch(o){throw r.failure(o),o}}class ot extends Error{constructor(e){super(`Check failed: ${e.map(t=>t.message??`${t.ruleId}:${t.location}`).join("; ")}`),this.violations=e,this.name="CheckException"}}const at="teaql.i18n/v1",ct="en",lt={en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}},ut={schema:at,defaultLocale:ct,locales:lt},ht=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"];class Oe extends Error{constructor(e){super(`Unsupported locale: ${e}`),this.localeCode=e}}const dt={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function Be(i){if(typeof i!="string"||!i.trim())throw new Oe(i);const e=i.trim().replace(/_/g,"-").toLowerCase(),t=ht.find(r=>r.toLowerCase()===e);if(t)return t;const n=dt[e];if(!n)throw new Oe(i);return n}const ce=class ce{constructor(e,t){if(this.data=e,this.fallback=t,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(Be)}message(e,t){return this.data.locales[e]?.messages[t]??this.fallback?.data.locales[e]?.messages[t]??this.data.locales.en?.messages[t]??this.fallback?.data.locales.en?.messages[t]??t}translate(e,t){const r={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,o=String(e.inputValue),s=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(t,r).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(o).split("{input_len}").join(String(s)),e}};ce.builtin=new ce(ut);let me=ce;const Qe=Symbol("teaql.context.schema-capability");function C(i){return Object.freeze(i.map(e=>Object.freeze({...e})))}class ft{#e;#t;constructor(e,t){this.#e=e,this.#t=Object.freeze({...t}),Object.freeze(this)}recover(){const e=[];let t=this;for(;t;)e.push(t.#t),t=t.#e;return C(e.reverse())}}function gt(i,e,t,n,r){const o=i?r:n;if(i&&(typeof o!="string"||new RegExp("^\\p{White_Space}*$","u").test(o)))return i;const s=String(t),a=/^(0|[1-9][0-9]*)$/.test(s)&&BigInt(s)<=18446744073709551615n?t:void 0;return new ft(i,{kind:"auditReason",name:e,entityId:a,detail:o})}const pt=new Set(["comment","purpose","auditReason"]),ue=i=>!new RegExp("^\\p{White_Space}*$","u").test(i);function ye(i,e,t){const n=s=>{for(let a=i.length-1;a>=0;a--)if(i[a].kind===s)return i[a].detail??""},r=["operation","provider","sql"].every(s=>i.some(a=>a.kind===s));let o;if(r)o=i.filter(s=>!pt.has(s.kind));else{const s=i.find(c=>ue(c.name))?.name??"unknown";let a=s;if(t!=="select")for(const c of i)c.kind==="entity"&&ue(c.name)&&(a=c.name);o=[{kind:"operation",name:s,detail:t==="select"?"query":"mutation"},{kind:t==="select"?"request":"entity",name:t==="select"?s:a,detail:""},...i.filter(c=>c.kind==="relation"),{kind:"provider",name:ue(e)?e:"unknown",detail:""},{kind:"sql",name:t,detail:""}]}return Object.freeze({tracePath:C(o),comment:n("comment"),purpose:n("purpose"),auditReason:n("auditReason")})}function ze(i,e,t){return C([{kind:"comment",name:i,detail:e},{kind:"purpose",name:i,detail:t}])}function mt(i,e,t,n){if(n&&!i.trim())throw new Error("Missing SQL template");let r=0;const o=new Set,s=u=>{if(u<0||u>=e.length)throw new Error("SQL bind count mismatch");return o.add(u),n?n(u):Ue(e[u],t)};let a="",c="sql";for(let u=0;u=0&&h=0&&ht.toString(16).padStart(2,"0")).join("")}'`:_(typeof i=="object"?JSON.stringify(i):String(i))}function _(i){return`'${i.replace(/'/g,"''")}'`}var yt={};const wt="TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS",bt="I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK",te="[REDACTED]",he="[REDACTED SQL; NOT REPLAYABLE]",St=`-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN +`;let Re=!1;function vt(i){const e=Array.from(i);return e.length<8||/^[0-9]+$/.test(i)?"*".repeat(e.length):e.slice(0,2).join("")+"*".repeat(e.length-4)+e.slice(-2).join("")}function Et(){const e=yt?.[wt]===bt;return e&&!Re&&(Re=!0,console.warn("TeaQL: sensitive plaintext logging enabled; application data may be written to disk. Authentication secrets remain redacted.")),e}function W(i){const e=i.toLowerCase().replace(/[^a-z0-9]/g,"");return["password","passwd","passphrase","privatekey","secret","accesstoken","refreshtoken","idtoken","apikey","authorization","credential","sessiontoken","magiclinktoken"].some(t=>e.includes(t))}function we(i){return Array.isArray(i)?i.some(we):i&&typeof i=="object"?Object.entries(i).some(([e,t])=>W(e)||we(t)):!1}function q(i){return i==null||i===""?[]:Array.isArray(i)?i.flatMap(q):i instanceof Date?[i.toISOString()]:typeof i=="object"?Object.values(i).flatMap(q):[String(i)]}function V(i,e){return[...new Set(e)].sort((t,n)=>n.length-t.length).reduce((t,n)=>t?.split(n).join(te),i)}const K=new WeakMap,be=new WeakMap,Ve=new WeakMap;function ke(i,e,t=[]){Ve.set(i,{bindings:e?R(e):void 0,intentValues:Object.freeze(t.map(G))})}function ie(i){const e=i.parameterLogPolicies,t=!!e&&e.length===i.parameters.length,n=W(i.parameterizedSQL)&&(i.sqlOrigin!=="generated"||!t);return i.parameters.map((r,o)=>{if(n||we(r))return"credential";const s=t?e[o]:void 0;return s==="plain"||s==="masked"||s==="credential"?s:"unknown"})}function Se(i,e){return i==="credential"||i==="unknown"||!e&&i!=="plain"}function Ce(i){if(!i)return[];const e=ie(i);return i.parameters.flatMap((t,n)=>Se(e[n],!1)?q(t):[])}function G(i){return i instanceof Date?new Date(i.getTime()):i instanceof Uint8Array?new Uint8Array(i):Array.isArray(i)?Object.freeze(i.map(G)):i&&typeof i=="object"?Object.freeze(Object.fromEntries(Object.entries(i).map(([e,t])=>[e,G(t)]))):i}function R(i,e){const t=e?[e,i]:[i];return Object.freeze({parameterizedSQL:"",sqlOrigin:"generated",parameters:Object.freeze(t.flatMap(n=>n.parameters.map(G))),parameterLogPolicies:Object.freeze(t.flatMap(ie))})}function ve(i){return i==null?null:Array.isArray(i)?i.map(ve):i&&typeof i=="object"&&"type"in i?ve(i.value):typeof i=="object"&&!(i instanceof Date)?te:vt(i instanceof Date?i.toISOString():String(i))}function Ke(i,e,t=[]){const n=Et()&&i.logMode!=="masked",r=K.get(i);if(r!==void 0&&(!r||n))return i;const o=be.get(i);if(!n&&o)return o;const s=ne(i,n,e,t);if(K.set(s,n),n){const a=ne(i,!1,e,t);K.set(a,!1),be.set(s,a)}return s}function It(i){const e=be.get(i);if(e)return e;if(K.get(i)===!1)return i;const t=ne(i,!1);return K.set(t,!1),t}function ne(i,e,t,n=[]){const r=Ve.get(i);r?.bindings&&(t=R(r.bindings,t)),r&&(n=[...n,...r.intentValues]);const o=i.parameterLogPolicies,s=!o||o.length===i.parameters.length,a=W(i.parameterizedSQL)&&(i.sqlOrigin!=="generated"||!o||!s),c=ie(i),u=c.map(w=>Se(w,e)),l=i.parameters.flatMap((w,v)=>u[v]?q(w):[]);if(t){const w=ie(t);l.push(...t.parameters.flatMap((v,I)=>Se(w[I],e)?q(v):[]))}const f=[...l,...n.flatMap(q)],g=!e&&i.logMode==="debug-plaintext"&&!t,h=w=>g&&w?te:V(w,f),p=i.parameters.map((w,v)=>u[v]?c[v]==="masked"?ve(w):te:G(w)),m=i.parameterizedSQL.replace(/\$[0-9]+|@p[0-9]+/gi,"?"),y=(!e||a)&&i.sqlOrigin!=="generated"&&/['"`$]|--|\/\*|\b\d+\b|:[A-Za-z_]/.test(m),d=i.databaseKind??"sqlite";let b=he,E=y?"untrusted-literal-sql":s?void 0:"policy-count-mismatch";if(!y&&s)try{b=mt(i.parameterizedSQL,p,d,w=>Ue(p[w],d)+(u[w]?" /* masked */":"")),b=(e?u.some(Boolean)?`-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN; PARTIALLY MASKED; NOT REPLAYABLE +`:St:`-- TeaQL MASKED; NOT REPLAYABLE +`)+b}catch{b=he,E="unsupported-or-mismatched-bindings"}return Object.freeze({...i,...i.statements?{statements:Object.freeze(i.statements.map(w=>ne(w,e,R(i,t),n)))}:{},parameterizedSQL:y?he:i.sqlOrigin==="generated"?i.parameterizedSQL:V(i.parameterizedSQL,l),parameters:Object.freeze(p),parameterLogPolicies:Object.freeze(c),maskedParameters:Object.freeze(u),logMode:e?"debug-plaintext":"masked",omissionReason:E,debugSQL:b,comment:h(i.comment),purpose:h(i.purpose),auditReason:h(i.auditReason),...i.traceChain?{traceChain:Object.freeze(i.traceChain.map(w=>Object.freeze(Object.fromEntries(Object.entries(w).map(([v,I])=>[v,v!=="entityId"&&typeof I=="string"?h(I):I])))))}:{},resultSummary:i.resultCount!==void 0?`${i.resultCount} rows returned`:i.affectedRows!==void 0?`${i.affectedRows} rows affected`:V(i.resultSummary,l),tracePath:Object.freeze(i.tracePath.map(w=>Object.freeze(Object.fromEntries(Object.entries(w).map(([v,I])=>[v,v!=="entityId"&&typeof I=="string"?h(I):I]))))),...i.traceChain?{traceChain:Object.freeze(i.traceChain.map(w=>Object.freeze(Object.fromEntries(Object.entries(w).map(([v,I])=>[v,v!=="entityId"&&typeof I=="string"?h(I):I])))))}:{},...i.mutationLineage?{mutationLineage:Object.freeze(i.mutationLineage.map(w=>Object.freeze(Object.fromEntries(Object.entries(w).map(([v,I])=>[v,v!=="entityId"&&typeof I=="string"?h(I):I])))))}:{}})}const H=new WeakMap,re=new WeakMap;function _e(i){return re.get(i)}function Lt(i,e){re.set(i,e)}function $t(i){return H.get(i)}function Q(i,e){H.set(e,H.get(i)??M(i))}function M(i,e=new Map){if(!i||typeof i!="object")return i;if(e.has(i))return e.get(i);if(i instanceof Date)return new Date(i.getTime());if(i instanceof Uint8Array)return new Uint8Array(i);const t=Array.isArray(i)?[]:Object.create(Object.getPrototypeOf(i));e.set(i,t);for(const o of Reflect.ownKeys(i)){const s=Object.getOwnPropertyDescriptor(i,o);"value"in s&&s.enumerable&&(s.value=M(s.value,e)),Object.defineProperty(t,o,s)}const n=H.get(i);n&&H.set(t,n);const r=re.get(i);return r&&re.set(t,r),t}const X=new WeakMap;class Le{#e;constructor(e={}){this.#e=M(e),Object.freeze(this)}values(){return M(this.#e)}static captureFor(e,t){const n=new Le(t);return X.set(e,n),n}static forEntity(e){return X.get(e)}static restoreFor(e,t){t?X.set(e,t):X.delete(e)}}const Pe=new WeakMap,de=new WeakMap,Ee=new WeakMap,We=new WeakMap;function Ge(i){if(!["named-count","facet","relation-count","relation-select","aggregate","pagination"].includes(i.kind)||i.method!==void 0&&!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i.method)||i.alias!==void 0&&typeof i.alias!="string"||i.relation!==void 0&&typeof i.relation!="string")throw new Error("QUERY_OPERATION_INVALID: invalid generated operation descriptor");return Object.freeze({kind:i.kind,method:i.method,alias:i.alias,relation:i.relation})}function Tt(i){const e=Ge(i),t=n=>"'"+n.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+"'";return e.method?e.method+"("+(e.alias!==void 0?t(e.alias):e.kind==="relation-select"?"...":"")+")":"framework: "+e.kind+(e.relation?" "+e.relation:"")+(e.alias!==void 0?" "+t(e.alias):"")}const F=Symbol("runtime request binding");class At extends Error{constructor(e,t,n){super(`${e}: ${n} request requires a non-blank ${t}; supply it at the request entry point`),this.code=e,this.field=t,this.requestKind=n,this.name="RequestIntentError"}}function B(i,e,t){if(typeof i!="string"||new RegExp("^\\p{White_Space}*$","u").test(i))throw new At(e==="comment"?"REQUEST_COMMENT_REQUIRED":"QUERY_PURPOSE_REQUIRED",e,t);return i}class se{#e;#t;constructor(e,t){this.#e=B(e,"comment","query"),this.#t=B(t,"purpose","query"),Object.freeze(this)}get comment(){return this.#e}get purpose(){return this.#t}}class z{#e;constructor(e){this.#e=B(e,"comment","mutation"),Object.freeze(this)}get comment(){return this.#e}get auditReason(){return this.#e}readbackIntent(){return new se(this.#e,"verify persisted mutation result")}}class L{#e;#t;#n;#r;#s;#o;#i;constructor(e,t,n){const r=e,o=_e(e),s=o instanceof L?o:void 0;if(this.#e=t===void 0?s?.intent??new se(r?._comment??r?.commentText,r?._purpose??r?.purposeText):new se(t?.comment,t?.purpose),n&&n[F]!==!0)throw new Error("QUERY_REQUEST_OWNERSHIP_INVALID: request binding is runtime-owned");const a=s&&s.intent.comment===this.#e.comment&&s.purpose===this.#e.purpose?s:void 0;this.#i=n?.invocation??(n?.parent?n.parent.#i:void 0)??(a?a.#i:void 0)??Object.freeze({}),this.#n=n?n.parent:a?.parentRequest,this.#r=B(n?.comment??a?.comment??this.#e.comment,"comment","query"),this.#s=n?.name??a?.requestName??String(r.entity??"query"),this.#o=n?.operation??a?.operation,this.#t=M(e);const c=this.#t;for(const[u,l]of[["commentText",this.comment],["purposeText",this.purpose],["_comment",this.comment],["_purpose",this.purpose]])Object.defineProperty(c,u,{value:l,enumerable:!u.startsWith("_"),configurable:!0,writable:!1});de.set(c,C(n?.source??a?.traceSource??de.get(e)??ze(String(r.entity),this.intent.comment,this.purpose))),Lt(c,this),Object.freeze(this)}get intent(){return this.#e}get query(){return this.#t}get comment(){return this.#r}get purpose(){return this.#e.purpose}get traceSource(){return de.get(this.#t)}get parentRequest(){return this.#n}get rootRequest(){let e=this;for(;e.parentRequest;)e=e.parentRequest;return e}get requestName(){return this.#s}get operation(){return this.#o}get traceChain(){const e=[];for(let t=this;t;t=t.parentRequest)e.push({kind:"comment",name:t.requestName,detail:t.comment});return C([{kind:"purpose",name:this.rootRequest.requestName,detail:this.purpose},...e.reverse()])}withQuery(e){const t=_e(e);if(t instanceof L&&t.#i!==this.#i)throw new Error("QUERY_SCOPE_OWNER_MISMATCH: replacement belongs to another query invocation");return new L(e,this.intent,{[F]:!0,parent:this.parentRequest,comment:this.comment,name:this.requestName,operation:this.operation,source:this.traceSource,invocation:this.#i})}deriveOperation(e,t){const n=Ge(t);return new L(e,this.intent,{[F]:!0,parent:this,comment:Tt(n),name:String(e.entity??this.requestName),operation:n,source:this.traceSource})}deriveHelper(e,t){return new L(e,this.intent,{[F]:!0,parent:this,comment:B(t,"comment","query"),name:String(e.entity??this.requestName),source:this.traceSource})}derive(e,t,n){if(n)return this.deriveOperation(this.query,n).deriveChild(e,t);const r=`${String(this.query.entity)}.${t}`;return this.deriveChild(e,t,void 0,r)}deriveAggregate(e,t,n){const r=this.parentRequest?.operation?.kind==="facet"?this.parentRequest:void 0,o=r?r.deriveHelper(e,"aggregate "+r.operation.relation):this.deriveOperation(e,n),s=[...this.traceSource,{kind:"relation",name:t,detail:`${String(this.query.entity)}.${t}`}],a=new L(e,this.intent,{[F]:!0,parent:o.parentRequest,comment:o.comment,name:o.requestName,operation:o.operation,source:s});return(e._comment??e.commentText)===void 0?a:a.deriveChild(e)}deriveChild(e,t,n,r){const o=e,s=o._comment??o.commentText;return new L(e,this.intent,{[F]:!0,parent:this,comment:s===void 0?n??`load ${String(o.entity)}`:B(s,"comment","query"),name:r??String(o.entity),source:t===void 0?this.traceSource:[...this.traceSource,{kind:"relation",name:t,detail:`${String(this.query.entity)}.${t}`}]})}}class x{#e;#t;constructor(e,t){this.#e=new z(t===void 0?e?.comment:t?.comment),this.#t={...e},Object.defineProperty(this.#t,"comment",{value:this.#e.comment,enumerable:!0,writable:!1,configurable:!1}),Object.freeze(this)}get intent(){return this.#e}get mutation(){return this.#t}get comment(){return this.#e.comment}withLoadedSnapshot(e){return Pe.set(this,new Le(e.values())),this}loadedValues(){return Pe.get(this)?.values()??{}}get graphSession(){return Ee.get(this)?.session}scopeFor(e){const t=Ee.get(this),n=gt(t?.parent,e.entity,e.id,this.comment,t?.localComment);return t&&We.set(n,t.session),n}traceFor(e){const t=this.#t,n=t.ledgerRoot?.traceChain(t.ledgerKey??e);return n?.length?C(n):this.scopeFor(e).recover()}auditProjection(e,t,n){const r=[...q(t),...q(this.#t.id),...n?Ce(n):q(this.loadedValues()),...Ce(this.graphSession?.logBindings)];return Object.freeze({reason:V(this.comment,r),mutationLineage:C(this.traceFor(e).map(o=>({...o,detail:V(o.detail,r)})))})}}class Ot{#e;#t;constructor(e){this.#e=new z(e?.comment),Object.freeze(this)}get intent(){return this.#e}request(e,t,n){if(t&&We.get(t)!==this)throw new Error("GRAPH_TRACE_SCOPE_MISMATCH: parent scope belongs to another graph invocation");const r=new x(e,this.#e);return Ee.set(r,{session:this,parent:t,localComment:n}),r}captureLogBindings(e){this.#t=R(e,this.#t)}get logBindings(){return this.#t}}class qe extends Error{constructor(e){super("GRAPH_ALREADY_COMMITTED: post-commit processing failed; do not retry as an uncommitted mutation"),this.cause=e,this.committed=!0,this.name="GraphCommittedError"}}const Rt="MUTATION-POLICY-001",kt="MUTATION-POLICY-002";class k extends Error{constructor(e){super(e),this.name="MutationPolicyError"}}class ci{constructor(e){this.resolver=e}resolve(e){return this.resolver(e)}}class li{constructor(e){this.finder=e}findApproval(e){return this.finder(e)}}class Ct{onWarning(e,t){!t.firstOccurrence||typeof console>"u"||console.warn(`TeaQL mutation policy warning code=${t.warningCode} requestKey=${t.snapshot.requestKey} source=${t.snapshot.source} approval=${t.snapshot.approvalStatus}`)}}let Ne=0;class _t{constructor(){this.profile={warningSink:new Ct},this.emittedWarnings=new Set,this.graphActive=!1,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.remaining=new Map}setRegistry(e){this.profile.registry=e}setApprovalProvider(e){this.profile.approvalProvider=e}setWarningSink(e){this.profile.warningSink=e}beginGraph(){if(this.graphActive)throw new k("mutation policy graph is already active");this.graphActive=!0,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.rootEntity=void 0,this.auditReason=void 0,this.remaining.clear(),this.graphSnapshot=void 0}endGraph(){this.graphActive=!1,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.rootEntity=void 0,this.auditReason=void 0,this.remaining.clear(),this.graphSnapshot=void 0}recordPreflight(e){if(!this.graphActive)return;if(this.graphReviewed)throw new k("mutation preflight cannot change after policy review");const t=xe(e);this.rootEntity??=t.entity,this.auditReason??=J(e),this.preflight.push(t),this.preflightKeys.push(Me(e,t))}enterMutation(e,t){const n=xe(t);if(!this.graphActive)return{snapshot:this.review(e,this.plan(n.entity,J(t),[n]))};if(!this.graphReviewed){if(this.profile.registry&&this.preflight.length===0)throw new k("customer mutation policy requires complete graph preflight before provider mutation");if(!this.profile.registry&&this.preflight.length===0)return{snapshot:this.review(e,this.plan(n.entity,J(t),[n]))};const r=this.preflight.length?this.preflight:[n];this.graphSnapshot=this.review(e,this.plan(this.rootEntity??r[0].entity,this.auditReason??J(t),r)),this.remaining.clear();const o=this.preflight.length?this.preflightKeys:r.map(Ye);for(const s of o)this.remaining.set(s,(this.remaining.get(s)??0)+1);this.graphReviewed=!0}return this.consume(Me(t,n)),{snapshot:this.graphSnapshot}}ensureGraphComplete(){if(this.graphReviewed&&this.remaining.size)throw new k("reviewed mutation plan contains operations that were not executed")}review(e,t){Pt(t);const n=je(t),r=this.profile.registry?.resolve(n.requestKey);let o,s,a,c;if(!r)o="generated_default",a="not_applicable",c=[Rt];else{s=qt(r.identity);const l=r.review(e,n);if(!l||l.verdict!=="allow"&&l.verdict!=="deny")throw new k("customer mutation policy returned an invalid decision");if(l.verdict==="deny")throw new k(`[MUTATION POLICY DENIED] ${l.code||"MUTATION-POLICY-DENIED"}: ${l.message||"mutation rejected"}`);o="customer";const f=this.profile.approvalProvider?.findApproval(s);a=Nt(f,s)?"approved":"missing",c=a==="approved"?[]:[kt]}const u=Object.freeze({executionId:n.executionId,requestKey:n.requestKey,source:o,policy:s,approvalStatus:a,warningCodes:Object.freeze([...c]),operations:Object.freeze(n.operations.map(l=>Object.freeze({kind:l.kind,entity:l.entity,entityId:j(l.entityId),changedFields:Object.freeze(Object.keys(l.changedValues).sort())})))});for(const l of c)this.emitWarning(e,u,l);return u}plan(e,t,n){return Ne+=1,je({executionId:`teaql-mutation-${Ne}`,requestKey:`${e}.saveGraph`,rootEntityType:e,auditReason:new z(t).comment,operations:n})}consume(e){const t=this.remaining.get(e)??0;if(t<1)throw new k("provider mutation is not present in the reviewed graph plan");t===1?this.remaining.delete(e):this.remaining.set(e,t-1)}emitWarning(e,t,n){const r=t.policy?`${t.policy.policyId}:${t.policy.version}:${t.policy.fingerprint}`:"none",o=`${t.requestKey}|${r}|${n}`,s=!this.emittedWarnings.has(o);this.emittedWarnings.add(o);try{this.profile.warningSink.onWarning(e,Object.freeze({snapshot:t,warningCode:n,firstOccurrence:s}))}catch{}}}function xe(i){const e=String(i?.entity??"").trim(),t=String(i?.action??"").toLowerCase(),n={create:"create",update:"update",delete:"delete",recover:"recover"};if(!e||!n[t])throw new k("mutation must contain a supported entity operation");const r=i?.payload&&typeof i.payload=="object"?i.payload:{};return Object.freeze({kind:n[t],entity:e,entityId:j(i?.id??r.id),originalVersion:i?.version??i?.expectedVersion,changedValues:He(r)})}function J(i){return new z(i?.comment).comment}function Pt(i){if(new z(i?.auditReason),!i.executionId?.trim())throw new k("execution id is required");if(!i.requestKey?.trim())throw new k("request key is required");if(!i.rootEntityType?.trim())throw new k("root entity type is required");if(!i.operations.length)throw new k("mutation plan is empty")}function qt(i){if(!i||!i.policyId?.trim()||!i.version?.trim()||!i.fingerprint?.trim())throw new k("customer mutation policy identity is invalid");return Object.freeze({policyId:i.policyId.trim(),version:i.version.trim(),fingerprint:i.fingerprint.trim()})}function Nt(i,e){return!!i&&xt(i.policy,e)&&!!i.approvedBy?.trim()&&i.approvedAt instanceof Date&&Number.isFinite(i.approvedAt.getTime())&&i.approvedAt.getTime()!==0}function xt(i,e){return i.policyId===e.policyId&&i.version===e.version&&i.fingerprint===e.fingerprint}function je(i){return Object.freeze({executionId:i.executionId,requestKey:i.requestKey,rootEntityType:i.rootEntityType,auditReason:i.auditReason,operations:Object.freeze(i.operations.map(e=>Object.freeze({kind:e.kind,entity:e.entity,entityId:j(e.entityId),originalVersion:e.originalVersion,changedValues:He(e.changedValues)})))})}function j(i,e=new WeakSet){if(i==null||typeof i=="string"||typeof i=="number"||typeof i=="boolean"||typeof i=="bigint")return i;if(i instanceof Date)return i.toISOString();if(typeof i=="object"){if(e.has(i))throw new k("mutation policy values must not contain cycles");e.add(i);try{if(Array.isArray(i))return Object.freeze(i.map(n=>j(n,e)));const t=i;return"id"in t&&Object.keys(t).some(n=>n!=="id")?j(t.id,e):Object.freeze(Object.fromEntries(Object.entries(t).map(([n,r])=>[n,j(r,e)])))}finally{e.delete(i)}}return String(i)}function He(i){return Object.freeze(Object.fromEntries(Object.entries(i).map(([e,t])=>[e,j(t)])))}function Ye(i){return oe({kind:i.kind,entity:i.entity,entityId:i.entityId,originalVersion:i.originalVersion,changedValues:i.changedValues})}function Me(i,e){const t=i?.ledgerKey;return t&&typeof t=="object"&&String(t.entity??"").trim()&&t.id!==void 0&&t.id!==null?`ledger:${String(t.entity).trim()}:${oe(t.id)}`:`operation:${Ye(e)}`}function oe(i){return typeof i=="bigint"?JSON.stringify(`${i.toString()}n`):i===void 0?'""':i===null||typeof i!="object"?JSON.stringify(i):Array.isArray(i)?`[${i.map(oe).join(",")}]`:`{${Object.entries(i).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${oe(t)}`).join(",")}}`}const De=new WeakMap;let jt=1;function Mt(i){if(!i||typeof i!="object"&&typeof i!="function")return String(i);const e=i;let t=De.get(e);return t||(t=jt++,De.set(e,t)),String(t)}class Fe extends Error{constructor(e,t,n){super(`context root ${e}: expected ${t}`),this.reason=e,this.expectedType=t,this.activeRoot=n,this.name="ContextRootError"}}class Dt{constructor(){this.mutationPolicy=new _t,this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(e,t)=>this.getContinuousPageCursor(e,t),put:(e,t,n)=>this.putContinuousPageCursor(e,t,n),observe:(e,t)=>{this.continuousPagePlan=e,this.continuousPageCursorId=t}},this.idSetPaginationRuntime={owner:"",scope:"",get:e=>this.idSetStore().get(e),put:(e,t)=>this.idSetStore().put(e,t),build:(e,t)=>this.singleFlightIdSetBuild(e,t),observe:(e,t)=>{this.idSetPaginationPlan=e,this.idSetPaginationCount=t,this.idSetPaginationCountAccuracy=e==="ID_SET_BUILD"||e==="ID_SET_HIT"?"EXACT":e==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=me.builtin}async withQueryRequest(e,t){const n=this.requireResource("dataService");return n.withQueryRequest?n.withQueryRequest(e,t):t()}setLocaleCode(e){const t=Be(e);return this.locale=t,this}setLanguageCode(e){return this.setLocaleCode(e)}installI18nCatalog(e){if(!e)throw new Error("catalog is required");return this.i18nCatalog=e,this}installIdSetPaginationStore(e){if(!e)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",e)}translateCheckResults(e){return e.map(t=>this.i18nCatalog.translate(t,this.locale))}withMutationPolicyRegistry(e){if(!e||typeof e.resolve!="function")throw new TypeError("mutation policy registry must expose resolve(requestKey)");return this.mutationPolicy.setRegistry(e),this}withMutationPolicyApprovalProvider(e){if(!e||typeof e.findApproval!="function")throw new TypeError("mutation policy approval provider must expose findApproval(identity)");return this.mutationPolicy.setApprovalProvider(e),this}withMutationGovernanceSink(e){if(!e||typeof e.onWarning!="function")throw new TypeError("mutation governance sink must expose onWarning(context, warning)");return this.mutationPolicy.setWarningSink(e),this}reviewMutationPlan(e){return this.mutationPolicy.review(this,e)}beginMutationPolicyGraph(){this.mutationPolicy.beginGraph()}recordMutationPolicyPreflight(e){this.mutationPolicy.recordPreflight(e)}enterMutationPolicy(e){return this.mutationPolicy.enterMutation(this,e).snapshot}ensureMutationPolicyGraphComplete(){this.mutationPolicy.ensureGraphComplete()}endMutationPolicyGraph(){this.mutationPolicy.endGraph()}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(e){const t=String(e.sourceLabel||""),n=t.toLowerCase();if(!e.entityType||!e.modelPath||!t||n.includes("authorization")||n.includes("cookie")||n.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const r=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",r),r.push(Object.freeze({...e})),this}finishFixEvidence(){const e=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...e])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(e,t){return this.resources.set(e,t),this}getResource(e){return this.resources.get(e)}removeResource(e){return this.resources.delete(e),this}requireResource(e){const t=this.getResource(e);if(t===void 0)throw new Error(`Required UserContext resource is missing: ${e}`);return t}ensureSchema(){const e=this.requireResource("dataService"),t=e[Qe];if(!t)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return t.call(e,this)}withActiveRoot(e){if(!e||!e.entity||e.id===void 0||e.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...e}))}requireActiveRoot(e){const t=this.getResource("activeRoot");if(!t)throw new Fe("missing",e);if(t.entity!==e)throw new Fe("type_mismatch",e,t);return t}prepareQuery(e){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const t=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,t?`${t.entity}:${String(t.id)}`:"-",Mt(this.getResource("dataService"))].join("|"),e.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(e,t){const n=`${e}:${t}`,r=this.continuousPageCursors.get(n);if(r&&r.expiresAt<=Date.now()){this.continuousPageCursors.delete(n);return}return r}putContinuousPageCursor(e,t,n){if(this.continuousPageCursors.size>=4096){const r=[...this.continuousPageCursors.entries()].sort((o,s)=>o[1].expiresAt-s[1].expiresAt)[0];r&&this.continuousPageCursors.delete(r[0])}this.continuousPageCursors.set(`${e}:${t}`,n)}getRetainedIdSet(e){const t=this.retainedIdSets.get(e);if(t&&t.expiresAt<=Date.now()){this.retainedIdSets.delete(e);return}return t}idSetStore(){return this.getResource("idSetPaginationStore")??{get:e=>this.getRetainedIdSet(e),put:(e,t)=>this.putRetainedIdSet(e,t),invalidate:e=>{this.retainedIdSets.delete(e)}}}putRetainedIdSet(e,t){if(t.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const r=()=>[...this.retainedIdSets.values()].reduce((o,s)=>o+s.ids.byteLength,0);for(;this.retainedIdSets.size>=64||r()+t.ids.byteLength>268435456;){const o=[...this.retainedIdSets.entries()].sort((s,a)=>s[1].expiresAt-a[1].expiresAt)[0];if(!o)break;this.retainedIdSets.delete(o[0])}this.retainedIdSets.set(e,t)}async singleFlightIdSetBuild(e,t){const n=this.idSetBuilds.get(e);if(n)return{value:await n,built:!1};const r=t();this.idSetBuilds.set(e,r);try{return{value:await r,built:!0}}finally{this.idSetBuilds.delete(e)}}}function Xe(i,e){const t=i.defaultDomainRoot,n=e.defaultDomainRoot;if(t&&n&&(t.entity!==n.entity||t.id!==n.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const r=new Map;for(const o of[...i.constants??[],...e.constants??[]])r.set(`${o.entity}:${o.id}`,o);return{defaultDomainRoot:n??t,constants:[...r.values()],ensure:i.ensure&&e.ensure?async o=>{await i.ensure(o),await e.ensure(o)}:e.ensure??i.ensure}}class Je{constructor(e={},t={},n={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...t}),this.bootstrap=Object.freeze({defaultDomainRoot:n.defaultDomainRoot,constants:Object.freeze([...n.constants??[]]),ensure:n.ensure})}and(e){return new Je({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},Xe(this.bootstrap,e.bootstrap))}}class P{constructor(e,t,n){this.field=e,this.expr=t,this.direction=n}static new(e,t){return new P(e,null,t)}static expr(e,t){return new P("",e,t)}static asc(e){return P.new(e,"Asc")}static desc(e){return P.new(e,"Desc")}}class ae{constructor(e,t,n,r){this.enabledValue=e,this.cacheExpiredMillis=t,this.propagateValue=n,this.propagateCacheExpiredMillis=r}static enabled(e){return new ae(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}}let Ft=class Ze{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,t,n,r=!0,o){return this.facets.push({facetName:e,relationName:t,query:n.toQuery(),includeAllFacets:r,operation:o}),this}clone(){const e=M(this);for(const t of["commentText","purposeText","_comment","_purpose"]){const n=Object.getOwnPropertyDescriptor(e,t);n&&"value"in n&&n.configurable&&Object.defineProperty(e,t,{...n,writable:!0})}return e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,t){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:t},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,t,n){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(n)||n<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:t,maxIds:n},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const t=new Ze(this.entity);return t.filterCondition=M(this.filterCondition),t.commentText=this.commentText,t.purposeText=this.purposeText,t.aggregate("Count","id",e),Q(this,t),t}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const t of this.relations)t.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,t,n="id",r="id",o=!0,s){return this.relations.push({name:e,query:t,localKey:n,foreignKey:r,many:o,operation:s}),this}relationAggregate(e,t,n,r=!0,o){return this.relationAggregates.push({relationName:e,alias:t,query:n,singleResult:r,operation:o}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=ae.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=ae.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,t,n){return this.aggregateItems.push({function:e,field:t,alias:n}),this}groupBy(e){return this.groupByItems.push(e),this}};function Bt(i,e){if(i.logMode!=="masked")throw new Error("Telemetry requires safe SQL projection");const t=(n=[])=>JSON.stringify(n.map(r=>({kind:r.kind,name:r.name,detail:r.detail??""})));return Object.freeze({body:"TeaQL SQL execution",correlation:e,attributes:Object.freeze({"teaql.trace_chain":t(i.traceChain),"teaql.trace_path":t(i.tracePath),"teaql.mutation_lineage":t(i.mutationLineage),"teaql.intent.comment":i.comment??i.auditReason??"","teaql.intent.purpose":i.purpose??"","teaql.sql.debug":i.debugSQL,"teaql.sql.log_mode":i.logMode,"teaql.sql.operation":i.operation,"teaql.sql.outcome":i.executionOutcome??"unknown","teaql.sql.elapsed_us":i.elapsedMicros,...i.resultCount===void 0?{}:{"teaql.sql.result_count":i.resultCount},...i.affectedRows===void 0?{}:{"teaql.sql.affected_rows":i.affectedRows}})})}function fe(i,e=!1){try{e?console.warn(i):console.info(i)}catch{}}class Y extends Array{static get[Symbol.species](){return Array}constructor(e=[],t={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,Y.prototype),this.totalCount=t.totalCount,this.aggregations=t.aggregations??{},this.summary=t.summary??{},this.facets=t.facets??{},this.isLoaded=t.isLoaded??!0}static empty(){return new Y([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,t){return this.facets[e]=t,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}}function Qt(i){return i.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function Ie(i){if(i&&typeof i=="object"){const e=i;return e.id??e.Id}return i}function zt(i,e){const t=Qt(e);for(const n of[e,`${e}Id`,t,`${t}_id`]){const r=Ie(i[n]);if(r!=null)return r}}function Ut(i){const e=i.function.toLowerCase();return e==="count"||e==="sum"?0:null}function Vt(i,e){return typeof i=="number"&&typeof e=="number"?i-e:i instanceof Date&&e instanceof Date?i.getTime()-e.getTime():String(i).localeCompare(String(e))}async function Kt(i,e,t,n,r,o){const s=n.clone();s.facets=[],s.relations=[],s.relationAggregates=[],s.orderItems=[],s.aggregateItems=[],s.groupByItems=[],s.offsetValue=0,s.limitValue=0,s.selectItems=[...new Set([r,...o.map(l=>l.field)])],s.comment(`aggregate ${r}`),Q(n,s);const a=await i.executeQuery(t.deriveHelper(e(s),`aggregate ${r}`).query),c=new Map,u=new Map;for(const l of a){const f=zt(l,r);if(f==null)continue;const g=String(f),h=c.get(g)??{},p=u.get(g)??{};for(const m of o){const y=m.function.toLowerCase(),d=l[m.field];if(y==="count")d!=null&&(h[m.alias]=Number(h[m.alias]??0)+1);else if(y==="sum"||y==="avg"){if(d!=null){const b=Number(d);if(!Number.isFinite(b))throw new Error(`Facet aggregate ${m.alias} requires numeric values`);h[m.alias]=Number(h[m.alias]??0)+b,y==="avg"&&(p[m.alias]=(p[m.alias]??0)+1)}}else if(y==="min"||y==="max"){if(d!=null){const b=h[m.alias],E=b==null?0:Vt(d,b);(b==null||y==="min"&&E<0||y==="max"&&E>0)&&(h[m.alias]=d)}}else throw new Error(`Unsupported facet aggregate: ${m.function}`)}c.set(g,h),u.set(g,p)}for(const[l,f]of c){const g=u.get(l)??{};for(const h of o){if(h.function.toLowerCase()!=="avg")continue;const p=g[h.alias]??0;f[h.alias]=p?Number(f[h.alias]??0)/p:null}}return c}async function et(i,e,t,n){const r=new L(t);t=r.query;const o={};for(const s of n){const a=r.deriveOperation(t,s.operation??{kind:"facet",relation:s.relationName,alias:s.facetName}),c=a.deriveChild(s.query.clone(),s.relationName),u=c.query,l=u.facets;u.facets=[];const f=u.aggregateItems.map(d=>({function:String(d.function),field:String(d.field),alias:String(d.alias)})),g=f.length?f:[{function:"Count",field:"id",alias:"__teaql_facet_membership_count"}];let h;if(i.executeFacetAggregates)h=await i.executeFacetAggregates(a.deriveHelper(e(t.clone()),`aggregate ${s.relationName}`).query,s.relationName,g);else if(i.executeFacetMembership&&g.every(d=>d.function.toLowerCase()==="count")){const d=await i.executeFacetMembership(a.deriveHelper(e(t.clone()),`aggregate ${s.relationName}`).query,s.relationName);h=new Map([...d].map(([b,E])=>[b,Object.fromEntries(g.map(S=>[S.alias,E]))]))}else h=await Kt(i,e,a,t,s.relationName,g);u.aggregateItems=[],u.groupByItems=[];for(const d of u.relationAggregates){if(d.query.entity!==t.entity)continue;const b=t.clone();b.selectItems=["id"],b.properties=[],b.relations=[],b.relationAggregates=[],b.facets=[],b.aggregateItems=[],b.groupByItems=[],b.orderItems=[],b.offsetValue=0,b.limitValue=0;const E={id:{$inSubquery:{query:b,field:"id"}}};d.query.filterCondition=d.query.filterCondition?{$and:[d.query.filterCondition,E]}:E,Q(t,d.query)}if(!s.includeAllFacets){const d={id:{$in:[...h.keys()]}};u.filterCondition=u.filterCondition?{$and:[u.filterCondition,d]}:d}Q(t,u);const m=(await i.executeQuery(c.withQuery(e(u)).query)).map(d=>{const b=String(Ie(d.id??d.Id)),E=h.get(b),S={...d};for(const w of f)S[w.alias]=E?.[w.alias]??Ut(w);return S}).filter(d=>s.includeAllFacets||h.has(String(Ie(d.id??d.Id)))),y=new Y(m);l.length&&(y.facets=await et(i,e,c.withQuery(u).query,l)),o[s.facetName]=y}return o}function Wt(i){const e=new Map;for(const t of Object.values(i))for(const n of Object.values(t.relations||{})){if(!n.many)continue;const r=i[n.targetEntity],o=r?.columns[n.foreignKey]?.columnName,s=r?.columns.id?.columnName;if(!r||!o||!s)continue;const a=`idx_${r.table}_${o}_${s}`;let c=2166136261;for(let f=0;f>>0).toString(36),l=a.length<=30?a:`${a.slice(0,Math.max(1,29-u.length))}_${u}`;e.set(l,{name:l,table:r.table,foreignColumn:o,idColumn:s})}return[...e.values()]}async function Gt(i,e,t,n){const r=Number(n);if(!Number.isSafeInteger(r)||r<0)throw new Error(`Invalid ID space floor ${n} for ${t}`);for(let o=1;o<=100;o+=1){const s=await i.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[t]);if(!s.rowCount){try{if((await i.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[t,r])).rowCount===1)return}catch(u){if(!(await i.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[t])).rowCount)throw u}continue}const a=Number(s.rows[0].id);if(a>=r)return;const c=await i.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[r,t,a]);if(c.rowCount===1)return;if(c.rowCount!==0)throw new Error(`ID space floor update for ${t} changed ${c.rowCount} rows on attempt ${o}`)}throw new Error(`Unable to synchronize ID space floor for ${t} after 100 optimistic-lock attempts`)}function Ht(i,e){return i===e?!0:(i instanceof Date&&(i=i.getTime()),e instanceof Date&&(e=e.getTime()),i!=null&&e!==null&&e!==void 0&&String(i)===String(e))}function ee(i){return Object.freeze(i.map((e,t)=>Object.freeze({...e,level:t})))}function ge(i,e,t,n,r,o){const s=i.traceFor({entity:String(e.entity),id:r}),a=ye([...s,{kind:"entity",name:String(e.entity),entityId:r,detail:""}],t,n);return{auditReason:i.comment,tracePath:ee(a.tracePath),mutationLineage:s,targetID:r,inheritedBindings:R(o,i.graphSession?.logBindings)}}class Yt{constructor(e=t=>console.debug(t)){this.writer=e}write(e){e=Ke(e),this.writer(`[TeaQL SQL][${e.operation}][${e.elapsedMicros}us] ${e.resultSummary}${e.executionOutcome?` outcome=${e.executionOutcome}`:""} +comment=${e.comment??""} purpose=${e.purpose??""} auditReason=${e.auditReason??""} tracePath=${pe(e.tracePath)} traceChain=${pe(e.traceChain??[])} mutationLineage=${pe(e.mutationLineage??[])} +`+(e.omissionReason?`SQL omitted: ${e.omissionReason} +`:"")+`Debug SQL: ${e.debugSQL}`)}}function pe(i){return JSON.stringify(i,(e,t)=>typeof t=="bigint"?t.toString():t)}class ui{constructor(){this.mode="all",this.entries=[]}record(e){const t=e.operation==="select";this.mode==="disabled"||this.mode==="select"&&!t||this.mode==="mutation"&&t||this.entries.push(Object.freeze({...e,...e.traceChain?{traceChain:C(e.traceChain)}:{},parameters:Object.freeze([...e.parameters])}))}setMode(e){return this.mode=e,this.entries=[],this}enableAll(){return this.setMode("all")}enableSelect(){return this.setMode("select")}enableMutation(){return this.setMode("mutation")}disable(){return this.setMode("disabled")}snapshot(){return[...this.entries]}}class Xt{constructor(e,t){this.driver=e,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.bindLogPolicies=new WeakMap,this.bindOperandSources=new WeakMap,this.derivedQueryBindings=new WeakMap,this.derivedRelationAssembly=new WeakMap,this.auditEvents=[],this.diagnosticSQLLogSink=new Yt,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.customTelemetry=!1,this.checkers={},this.userContext=new Dt,this.bootstrap={},this.graphAuditActions=[],this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve(),this.schemas={...t}}fieldLogPolicy(e,t){const n=e.columns[t],r=n?.modelName??n?.columnName??t;return W(r)||W(t)?"credential":e.auditMaskFields?e.auditMaskFields?.includes(r)||e.auditMaskFields?.includes(t)?"masked":n?.logPolicy??"unknown":"unknown"}bindValue(e,t,n,r){const o=this.bindLogPolicies.get(e)??e.map(()=>"unknown");e.push(t),o.push(n),this.bindLogPolicies.set(e,o),r!==void 0&&this.bindOperandSources.set(e,R({parameterizedSQL:"",parameters:[r],parameterLogPolicies:[n],sqlOrigin:"generated"},this.bindOperandSources.get(e)))}queryLogBindings(e,t){return R({parameterizedSQL:e,parameters:t,parameterLogPolicies:this.bindLogPolicies.get(t),sqlOrigin:"generated"},this.bindOperandSources.get(t))}install(e){return Object.assign(this.schemas,e.schemas),Object.assign(this.checkers,e.checkers),this.bootstrap=Xe(this.bootstrap,e.bootstrap),this}setUserContext(e){return this.userContext=e,this}schema(e){const t=this.schemas[e];if(!t)throw new Error(`Unknown TeaQL entity: ${e}`);return t}toRuntimeMutationRecord(e,t){const n={};for(const[r,o]of Object.entries(t)){const s=e.columns[r]?r:Object.keys(e.columns).find(a=>e.columns[a].modelName===r||e.columns[a].columnName===r);s&&(n[s]=o)}return n}encode(e,t){const n=e?.id??e;if(n!==void 0)return this.driver.encode(n,t)}decodeRow(e,t,n=[]){const r=this.schema(e),o={...t};for(const[s,a]of Object.entries(r.columns)){const c=o[s];c!=null&&(a.decode==="number"&&(o[s]=Number(c)),a.decode==="string"&&(o[s]=String(c)),a.decode==="date"&&c instanceof Date&&(o[s]=c.toISOString()),a.logicalType==="boolean"&&(o[s]=!!c))}for(const s of n)o[s]!==null&&o[s]!==void 0&&(o[s]=Number(o[s]));return o}get auditTrace(){return[...this.auditEvents]}setAuditSink(e){return this.auditSink=e,this}setRuntimeTelemetrySink(e){return this.telemetrySink=e,this}setDiagnosticSQLLogSink(e){return this.diagnosticSQLLogSink=e,this}setQueryLoggingEnabled(e){return this.queryLoggingEnabled=e,this}setMutationLoggingEnabled(e){return this.mutationLoggingEnabled=e,this}setRuntimeTelemetry(e){return this.customTelemetry=!0,this.runtimeTelemetry=e,this}attachStandardTelemetryStartup(e){this.telemetryStartup=e.then(async t=>{if(t){if(this.customTelemetry){await t.release();return}this.standardTelemetryHandle=t,this.runtimeTelemetry=t.telemetry}}).catch(()=>{fe("TeaQL telemetry: initialization failed; business continues without export.",!0)})}async flushTelemetry(){await this.telemetryStartup;try{await this.standardTelemetryHandle?.flush()}catch{fe("TeaQL telemetry: export flush failed; business outcome unchanged.",!0)}}async withQueryRequest(e,t){return new L(e),await this.telemetryStartup,D(this.runtimeTelemetry,{family:"query",name:`${String(e.entity)}.request`,attributes:{"teaql.entity.type":String(e.entity)}},t)}recordSQL(e,t,n,r,o,s,a={},c="success",u,l){const g=e==="select"?this.queryLoggingEnabled:this.mutationLoggingEnabled,{targetID:h,inheritedBindings:p,...m}=a,y=Object.freeze({operation:e,...m,executionOutcome:c,traceChain:C(a.traceChain??[]),tracePath:ee(a.tracePath??[]),...a.traceChain?{traceChain:C(a.traceChain)}:{},...a.mutationLineage?{mutationLineage:C(a.mutationLineage)}:{},parameterizedSQL:t,parameters:Object.freeze([...n]),debugSQL:"",databaseKind:this.driver.databaseKind,sqlOrigin:"generated",parameterLogPolicies:Object.freeze([...this.bindLogPolicies.get(n)??n.map(()=>"unknown")]),elapsedMicros:Math.max(0,(Date.now()-r)*1e3),resultCount:o,affectedRows:s,resultSummary:o!==void 0?`${o} rows returned`:s!==void 0?`${s} rows affected`:`statement ${c}; row count unknown`}),d=p&&u?R(u,p):p??u,b=this.bindOperandSources.get(n),E=b?R(b,d):d;if(ke(y,E,h===void 0?[]:[h]),this.runtimeTelemetry?.recordDiagnostic)try{this.runtimeTelemetry.recordsSQLDiagnostics?.()!==!1&&this.runtimeTelemetry.recordDiagnostic(Bt(It(y),l))}catch{fe("TeaQL telemetry: SQL diagnostic rejected; business outcome unchanged.",!0)}if(!this.telemetrySink&&!(g&&this.diagnosticSQLLogSink))return y;try{const S=Ke(y);try{this.telemetrySink?.record(S)}catch{}if(g)try{this.diagnosticSQLLogSink?.write(S)}catch{}}catch{}return y}queryLogIntent(e){const t=new L(e),n=ye(t.traceSource,this.driver.databaseKind,"select");return{comment:t.intent.comment,purpose:t.purpose,traceChain:t.traceChain,tracePath:ee(n.tracePath)}}async executeLoggedSQL(e,t,n,r,o,s,a){await this.telemetryStartup;const c=N(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.${e}`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":e==="select"?"query":e}}),u=c.correlation?.(),l=Date.now();let f;try{f=await(c.run?c.run(o):o())}catch(h){try{const p=this.recordSQL(e,t,n,l,void 0,void 0,r,"failure",s,u);a?.push(p)}finally{throw c.failure(h),h}}const g=this.recordSQL(e,t,n,l,e==="select"?f.rowCount:void 0,e==="select"?void 0:f.rowCount,r,"success",s,u);return a?.push(g),c.success({attributes:{"teaql.result.cardinality":f.rowCount}}),f}async[Qe](e){await this.telemetryStartup,this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const t=this.bootstrapTail;let n;this.bootstrapTail=new Promise(s=>{n=s}),await t,this.userContext=e;const r=e.getResource("bootstrapActor"),o=e.getResource("bootstrapCategory");e.insertResource("bootstrapActor","teaql-generated-bootstrap"),e.insertResource("bootstrapCategory","runtime-bootstrap");try{this.bootstrap.ensure?await this.bootstrap.ensure(e):await this.ensureBootstrapData()}finally{r===void 0?e.removeResource("bootstrapActor"):e.insertResource("bootstrapActor",r),o===void 0?e.removeResource("bootstrapCategory"):e.insertResource("bootstrapCategory",o),n()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const e=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];e.length&&await this.executeGraphSave(new z("reconcile model bootstrap data"),async t=>{const n=this.graphMutationSession,r=[];for(const o of e){const s=await this.planBootstrapMutation(n,o);s&&r.push({record:o,request:t.request(s)})}for(const{request:o}of r)this.preflightMutation(o);for(const{request:o}of r)await this.executeMutation(o);for(const o of e)await this.driver.ensureIdFloor(n,o.entity,o.id)})}async planBootstrapMutation(e,t){const n=this.schema(t.entity),r=Object.entries(t.values??{}).map(([g,h])=>{const p=n.columns[g];if(!p)throw new Error(`Unknown bootstrap field ${t.entity}.${g}`);return{column:p.columnName,value:this.driver.encode(h,p)}}),o=new Ft(t.entity).filter({id:{$eq:t.id}}).limit(1).comment("inspect model bootstrap record").purpose("ensure model-defined root and constants");o.prepareForList();const s=new L(o),a=`SELECT * FROM ${this.driver.identifier(n.table)} WHERE ${this.driver.identifier(n.columns.id?.columnName??"id")} = ${this.driver.placeholder(1)}`,c=[t.id];this.bindLogPolicies.set(c,[this.fieldLogPolicy(n,"id")]);const u=await this.executeLoggedSQL("select",a,c,this.queryLogIntent(s.query),()=>e.query(a,c));if(!u.rowCount)return{entity:t.entity,action:"Create",id:t.id,version:0,payload:{...t.values}};const l=u.rows[0];if(r.filter(g=>!Ht(l[g.column],g.value)).length)return{entity:t.entity,action:"Update",id:t.id,version:Number(l[n.columns.version?.columnName??"version"]),payload:{...this.decodeRowForSchema(n,l),...t.values}}}async executeGraphSave(e,t){const n=new Ot(e);await this.telemetryStartup;const r=async()=>{const o=this.graphSaveTail;let s;this.graphSaveTail=new Promise(l=>{s=l}),await o;let a=!1,c=!1,u=!1;try{this.graphCommitActions=[],this.graphRollbackActions=[],this.graphAuditActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence(),a=!0,this.userContext.beginMutationPolicyGraph(),c=!0;const l=await this.driver.transaction(async h=>{this.graphMutationSession=h,this.activeGraph=n;try{const p=await t(n);return this.userContext.ensureMutationPolicyGraphComplete(),p}finally{this.graphMutationSession=void 0,this.activeGraph=void 0}});u=!0;let f,g=!1;for(const h of[...this.graphCommitActions,...this.graphAuditActions])try{await h()}catch(p){g||(f=p),g=!0}if(g)throw new qe(f);return l}catch(l){if(!u)for(const f of[...this.graphRollbackActions].reverse())try{f()}catch{}throw l}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.graphAuditActions=[],c&&this.userContext.endMutationPolicyGraph(),this.userContext.removeResource("fixTime"),a&&this.userContext.finishFixEvidence(),s()}};return D(this.runtimeTelemetry,{family:"mutation",name:"graph.save",attributes:{"teaql.entity.type":"graph","teaql.mutation.kind":"graph"}},r)}afterGraphCommit(e){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(e)}afterGraphRollback(e){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(e)}requireGraphOwnership(e){if(e.graphSession!==this.activeGraph||this.graphMutationSession!==void 0&&e.graphSession===void 0)throw new Error("GRAPH_MUTATION_SESSION_REQUIRED: use the explicit active graph request capability")}async withMutationSession(e,t){return this.requireGraphOwnership(e),e.graphSession?t(this.graphMutationSession):this.driver.transaction(t)}preflightMutation(e){const t=e instanceof x?e:new x(e);if(this.requireGraphOwnership(t),e=this.checkAndFixMutation(t),t.graphSession){const n=this.schema(e.entity);t.graphSession.captureLogBindings(this.mutationLogBindings(t,e,n))}return this.userContext.recordMutationPolicyPreflight(e),e}mutationLogBindings(e,t,n){const r=o=>{const s=this.toRuntimeMutationRecord(n,o),a=Object.keys(s);return{parameterizedSQL:"",sqlOrigin:"generated",parameters:a.map(c=>s[c]),parameterLogPolicies:a.map(c=>this.fieldLogPolicy(n,c))}};return R(r(t.payload||{}),r(e.loadedValues()))}checkAndFixMutation(e){const t=e instanceof x?e:new x(e);this.requireGraphOwnership(t),e=t.mutation,e={...e,payload:{...e?.payload??{}}},Object.defineProperty(e,"comment",{value:t.comment,enumerable:!0});const n=this.checkers[String(e.entity)];if(!n)return e;const r=[],o=this.userContext.getResource("fixTime")===void 0;o&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(n.checkAndFix(this.userContext,e,r),e.ledgerKey&&e.ledgerRoot)for(const[s,a]of Object.entries(e.payload||{}))e.ledgerRoot.set(e.ledgerKey,s,a);if(this.userContext.translateCheckResults(r),r.length)throw new ot(r);return e}finally{o&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(e){await this.telemetryStartup;const t=e instanceof x?e:new x(e);this.requireGraphOwnership(t),e=t.mutation;const n=N(this.runtimeTelemetry,{family:"mutation",name:`${String(e?.entity||"unknown")}.${String(e?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(e?.entity||"unknown"),"teaql.mutation.kind":String(e?.action||"unknown").toLowerCase()}}),r=async()=>{try{e=this.checkAndFixMutation(t);const o=this.userContext.enterMutationPolicy(e),s=this.schema(e.entity),a=this.toRuntimeMutationRecord(s,e.payload||{}),c=this.mutationLogBindings(t,e,s),u=this.driver.identifier(s.table),l=[],f=await D(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(e.action).toLowerCase()}},()=>this.withMutationSession(t,async y=>{if(e.action==="Create"){const d=e.id?String(e.id):await this.driver.nextId(y,e.entity);e.id&&await this.driver.ensureIdFloor(y,e.entity,d);const b=Number(e.version||0)+1,E={...a,id:d,version:b},S=Object.keys(s.columns).filter($=>E[$]!==void 0),w=S.map($=>this.driver.identifier(s.columns[$].columnName)).join(", "),v=S.map(($,A)=>this.driver.placeholder(A+1)).join(", "),I=S.map($=>this.encode(E[$],s.columns[$]));this.bindLogPolicies.set(I,S.map($=>this.fieldLogPolicy(s,$)));const T=`INSERT INTO ${u} (${w}) VALUES (${v})`,O=ge(t,e,this.driver.databaseKind,"insert",d,c);return await this.executeLoggedSQL("insert",T,I,O,()=>y.query(T,I),void 0,l),{success:!0,id:d,version:b,persistedRecord:await this.readPersistedRecord(y,s,d,O,T,I,l)}}if(e.action==="Update"){const d=Object.keys(s.columns).filter($=>$!=="id"&&$!=="version"&&a[$]!==void 0),b=d.map($=>this.encode(a[$],s.columns[$]));this.bindLogPolicies.set(b,d.map($=>this.fieldLogPolicy(s,$)));const E=d.map(($,A)=>`${this.driver.identifier(s.columns[$].columnName)} = `+this.driver.placeholder(A+1)),S=this.driver.identifier("version");E.push(`${S} = ${S} + 1`),this.bindValue(b,String(e.id),this.fieldLogPolicy(s,"id"));const w=[`${this.driver.identifier("id")} = ${this.driver.placeholder(b.length)}`];e.version!==void 0&&e.version!==null&&(this.bindValue(b,Number(e.version),this.fieldLogPolicy(s,"version")),w.push(`${S} = ${this.driver.placeholder(b.length)}`));const v=`UPDATE ${u} SET ${E.join(", ")} WHERE ${w.join(" AND ")}`,I=ge(t,e,this.driver.databaseKind,"update",String(e.id),c);if((await this.executeLoggedSQL("update",v,b,I,()=>y.query(v,b),void 0,l)).rowCount!==1)throw new Error(`Optimistic lock failed or ${e.entity}(${e.id}) does not exist`);const O=await this.readPersistedRecord(y,s,String(e.id),I,v,b,l);return{success:!0,id:String(e.id),version:Number(O.version),persistedRecord:O}}if(e.action==="Delete"){const d=this.driver.identifier("version"),b=[String(e.id)];this.bindLogPolicies.set(b,[this.fieldLogPolicy(s,"id")]);const E=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];e.version!==void 0&&e.version!==null&&(this.bindValue(b,Number(e.version),this.fieldLogPolicy(s,"version")),E.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(b.length)));const S=`UPDATE ${u} SET ${d} = -(${d} + 1) WHERE ${E.join(" AND ")}`,w=ge(t,e,this.driver.databaseKind,"delete",String(e.id),c);if((await this.executeLoggedSQL("delete",S,b,w,()=>y.query(S,b),void 0,l)).rowCount!==1)throw new Error(`Optimistic lock failed or ${e.entity}(${e.id}) does not exist`);const I=await this.readPersistedRecord(y,s,String(e.id),w,S,b,l);return{success:!0,id:String(e.id),version:Number(I.version),deleted:!0,persistedRecord:I}}throw new Error(`Unsupported mutation action: ${e.action}`)})),g=t.auditProjection({entity:String(e.entity),id:f.id},e.payload,c),h=Object.freeze({entity:e.entity,action:e.action,id:String(f.id),...g,recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.freeze(Object.keys(e.payload||{}).sort()),version:f.version,mutationGovernance:o}),p=async()=>{this.auditEvents.push(h),this.auditSink&&await D(this.runtimeTelemetry,{family:"audit",name:`${e.entity}.audit`,attributes:{"teaql.entity.type":String(e.entity),"teaql.mutation.kind":String(e.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(e.payload||{}).length}},async()=>this.auditSink(h))};if(t.graphSession)this.graphAuditActions.push(p);else try{await p()}catch(y){throw new qe(y)}n.success();const m=Object.freeze({...l[0],statements:Object.freeze([...l])});return ke(m,R(c,t.graphSession?.logBindings),[f.id]),{...f,metadata:m}}catch(o){throw n.failure(o),o}};return n.run?n.run(r):r()}async readPersistedRecord(e,t,n,r,o,s,a){const u=`SELECT ${Object.entries(t.columns).map(([S,w])=>`${this.driver.identifier(w.columnName)} AS ${this.driver.identifier(S)}`).join(", ")} FROM ${this.driver.identifier(t.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,l=[n];this.bindLogPolicies.set(l,[this.fieldLogPolicy(t,"id")]);const f=N(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.readback`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}}),g=Date.now();let h;const p={parameterizedSQL:o,parameters:s,parameterLogPolicies:this.bindLogPolicies.get(s),sqlOrigin:"generated"},m=r.tracePath?.find(S=>S.kind==="operation")?.name??"unknown",y=ye([...ze(m,r.auditReason,"verify persisted mutation result"),...(r.tracePath??[]).filter(S=>S.kind==="relation")],this.driver.databaseKind,"select"),d={...r,tracePath:ee(y.tracePath),comment:r.auditReason,purpose:"verify persisted mutation result"},b=S=>a.push(this.recordSQL("select",u,l,g,h?.rowCount,void 0,d,S,p,f.correlation?.()));let E;try{if(h=await(f.run?f.run(()=>e.query(u,l)):e.query(u,l)),f.success({attributes:{"teaql.result.cardinality":h.rowCount}}),h.rowCount!==1)throw new Error(`Persisted ${t.table}(${n}) could not be read back`);E=this.decodeRowForSchema(t,h.rows[0])}catch(S){h||f.failure(S);const w=h?"success":S instanceof Error&&(S.name==="AbortError"||S.name==="TimeoutError")?"cancelled":"failure";try{b(w)}finally{throw S}}return b("success"),E}decodeRowForSchema(e,t){const n={...t};for(const[r,o]of Object.entries(e.columns)){const s=n[r];s!=null&&(o.decode==="number"&&(n[r]=Number(s)),o.decode==="string"&&(n[r]=String(s)),o.decode==="date"&&s instanceof Date&&(n[r]=s.toISOString()),o.logicalType==="boolean"&&(n[r]=!!s))}return n}compileExpression(e,t,n){if(Array.isArray(e?.$and))return`(${e.$and.map(s=>this.compileExpression(s,t,n)).join(" AND ")})`;const r=Object.entries(e||{}).map(([o,s])=>{const a=t.columns[o];if(!a)throw new Error(`Unknown field ${o} for SQL query`);const c=this.driver.identifier(a.columnName),u=this.fieldLogPolicy(t,o);if(s?.$eq!==void 0){const l=s.$eq?.id??s.$eq;return l===null?`${c} IS NULL`:(this.bindValue(n,this.encode(l,a),u),`${c} = ${this.driver.placeholder(n.length)}`)}if(s?.$ne!==void 0){const l=s.$ne?.id??s.$ne;return l===null?`${c} IS NOT NULL`:(this.bindValue(n,this.encode(l,a),u),`${c} <> ${this.driver.placeholder(n.length)}`)}if(s?.$soundLike!==void 0)return this.bindValue(n,String(s.$soundLike),u),`SOUNDEX(${c}) = SOUNDEX(${this.driver.placeholder(n.length)})`;if(s?.$contains!==void 0)return this.bindValue(n,String(s.$contains),u),this.driver.contains(c,this.driver.placeholder(n.length));if(s?.$notContains!==void 0)return this.bindValue(n,String(s.$notContains),u),`NOT (${this.driver.contains(c,this.driver.placeholder(n.length))})`;for(const[l,f,g,h]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(s?.[l]!==void 0){const p=String(s[l]);this.bindValue(n,`${f}${p}${g}`,u,p);const m=`${c} LIKE ${this.driver.placeholder(n.length)}`;return h?`NOT (${m})`:m}if(Array.isArray(s?.$in)){if(!s.$in.length)return"FALSE";const l=s.$in.map(f=>(this.bindValue(n,this.encode(f?.id??f,a),u),this.driver.placeholder(n.length)));return`${c} IN (${l.join(", ")})`}if(Array.isArray(s?.$notIn)){if(!s.$notIn.length)return"TRUE";const l=s.$notIn.map(f=>(this.bindValue(n,this.encode(f?.id??f,a),u),this.driver.placeholder(n.length)));return`${c} NOT IN (${l.join(", ")})`}for(const[l,f]of[["$inSubquery",!1],["$notInSubquery",!0]]){const g=s?.[l];if(g!==void 0){const h=g.query,p=this.schema(h?.entity),m=String(g.field),y=p.columns[m];if(!y)throw new Error(`Unknown subquery projection ${m} for ${h?.entity}`);const d=this.filters(h).map(S=>this.compileExpression(S,p,n));p.columns.version&&d.push(`${this.driver.identifier(p.columns.version.columnName)} > 0`),f&&d.push(`${this.driver.identifier(y.columnName)} IS NOT NULL`);const b=d.length?` WHERE ${d.join(" AND ")}`:"",E=`SELECT ${this.driver.identifier(y.columnName)} FROM ${this.driver.identifier(p.table)}${b}`;return`${c} ${f?"NOT IN":"IN"} (${E})`}}if(Array.isArray(s?.$between)&&s.$between.length===2){this.bindValue(n,this.encode(s.$between[0],a),u);const l=this.driver.placeholder(n.length);this.bindValue(n,this.encode(s.$between[1],a),u);const f=this.driver.placeholder(n.length);return`${c} BETWEEN ${l} AND ${f}`}if(s?.$isNull===!0)return`${c} IS NULL`;if(s?.$isNull===!1)return`${c} IS NOT NULL`;if(s?.$gte!==void 0)return this.bindValue(n,this.encode(s.$gte,a),u),`${c} >= ${this.driver.placeholder(n.length)}`;if(s?.$lte!==void 0)return this.bindValue(n,this.encode(s.$lte,a),u),`${c} <= ${this.driver.placeholder(n.length)}`;if(s?.$gt!==void 0)return this.bindValue(n,this.encode(s.$gt,a),u),`${c} > ${this.driver.placeholder(n.length)}`;if(s?.$lt!==void 0)return this.bindValue(n,this.encode(s.$lt,a),u),`${c} < ${this.driver.placeholder(n.length)}`;throw new Error(`Unsupported query predicate for ${o}: ${JSON.stringify(s)}`)});return r.length?`(${r.join(" AND ")})`:"TRUE"}filters(e){return Array.isArray(e._filters)&&e._filters.length?e._filters:e.filterCondition?[e.filterCondition]:[]}groupBy(e){return e._groupBy||e.groupByItems||[]}aggregates(e){return Array.isArray(e._aggregates)?e._aggregates:(e.aggregateItems||[]).map(t=>({func:t.function,field:t.field,retName:t.alias}))}orders(e){return Array.isArray(e._orderBy)?e._orderBy.map(t=>({field:t.f,direction:t.d})):(e.orderItems||[]).map(t=>({field:t.field,direction:t.direction}))}async compileQuery(e,t=!0,n=[]){new se(e?.commentText??e?._comment,e?.purposeText??e?._purpose);const r=this.schema(e.entity),o=[],s=this.groupBy(e),a=s.map(w=>{if(!r.columns[w])throw new Error(`Unknown group field: ${w}`);return this.driver.identifier(r.columns[w].columnName)}),c=s.map(w=>`${this.driver.identifier(r.columns[w].columnName)} AS `+this.driver.identifier(w)),u=[],l=Array.isArray(e.selectItems)&&e.selectItems.length?[...new Set(["id","version",...e.selectItems])]:Object.keys(r.columns);if(!s.length&&!this.aggregates(e).length){for(const v of n)l.includes(v)||l.push(v);const w=[...(e.relations??[]).map(v=>v.name),...(e.relationAggregates??[]).map(v=>v.relationName)];for(const v of w){const I=r.relations?.[v];if(!I)throw new Error(`Missing relation ${e.entity}.${v}`);l.includes(I.localKey)||l.push(I.localKey)}}for(const w of l)if(!r.columns[w])throw new Error(`Unknown selected field: ${w}`);let f=l.map(w=>{const v=r.columns[w];return`${this.driver.identifier(v.columnName)} AS ${this.driver.identifier(w)}`}).join(", ");const g=this.aggregates(e);if(g.length){const w=g.map(v=>{if(!r.columns[v.field])throw new Error(`Unknown aggregate field: ${v.field}`);return u.push(v.retName),`${this.driver.aggregateFunction(v.func)}(${this.driver.identifier(r.columns[v.field].columnName)}) AS `+this.driver.identifier(v.retName)});f=[...c,...w].join(", ")}const h=e.__teaqlPartitionBy,p=this.orders(e),m=p.map(w=>{if(!r.columns[w.field])throw new Error(`Unknown order field: ${w.field}`);const v=String(w.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(r.columns[w.field].columnName)} ${v}`});if(h){const w=r.columns[h];if(!w)throw new Error(`Unknown partition field: ${h}`);const v=m.length?` ORDER BY ${m.join(", ")}`:"";f+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier(w.columnName)}${v}) AS `+this.driver.identifier("__teaql_partition_rank")}let y=`SELECT ${f} FROM ${this.driver.identifier(r.table)}`;const b=this.filters(e).map(w=>this.compileExpression(w,r,o));r.columns.version&&b.push(`${this.driver.identifier(r.columns.version.columnName)} > 0`),b.length&&(y+=` WHERE ${b.join(" AND ")}`),a.length&&(y+=` GROUP BY ${a.join(", ")}`);const E=e._limit!==void 0?Number(e._limit):Number(e.limitValue||0),S=e._offset!==void 0?Number(e._offset):Number(e.offsetValue||0);if(h){const w=this.driver.identifier("__teaql_partition_rank"),v=[];this.bindValue(o,S,"plain"),v.push(`${w} > ${this.driver.placeholder(o.length)}`),E>0&&(this.bindValue(o,S+E,"plain"),v.push(`${w} <= ${this.driver.placeholder(o.length)}`)),y=`SELECT * FROM (${y}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${v.join(" AND ")} ORDER BY ${w}`}else p.length&&(y+=` ORDER BY ${m.join(", ")}`);return!h&&E>0&&(this.bindValue(o,E,"plain"),y+=` LIMIT ${this.driver.placeholder(o.length)}`),!h&&S>0&&(this.bindValue(o,S,"plain"),y+=` OFFSET ${this.driver.placeholder(o.length)}`),t&&this.sqlTrace.push(y),{sql:y,values:o,aggregateNames:u}}async executeQuery(e){const t=e instanceof L?e:new L(e);return!(e instanceof L)&&e?.[this.internalQueryToken]!==!0&&typeof e?.prepareForList=="function"&&e.prepareForList(),this.executeQueryWithIntent(t.query,this.derivedQueryBindings.get(e),this.derivedRelationAssembly.get(e))}async executeDerivedQuery(e,t,n,r){const o=new L(e,n).query;t&&this.derivedQueryBindings.set(o,t),r&&this.derivedRelationAssembly.set(o,r);try{return await this.executeQuery(o)}finally{this.derivedQueryBindings.delete(o),this.derivedRelationAssembly.delete(o)}}descendantBindings(e,t,n,r){if(!(!e.relations?.length&&!e.relationAggregates?.length))return R(this.queryLogBindings(t,n),r)}async queryTreeBindings(e,t,n,r){let o=R(this.queryLogBindings(t,n),r);const s=new L(e).intent,a=[e],c=new Set;for(;a.length;){const u=a.pop();if(!u||c.has(u))continue;if(c.add(u),u!==e){const f=await this.compileQuery(new L(u,s).query,!1);o=R(this.queryLogBindings(f.sql,f.values),o)}const l=$t(u);l&&a.push(l);for(const f of[...u.relations??[],...u.relationAggregates??[]])f.query&&a.push(f.query);for(const f of u.facets??[]){if(!f.query)continue;const g=f.query.clone();g.aggregateItems=[],g.groupByItems=[],a.push(g)}}return o}async executeQueryWithIntent(e,t,n){await this.telemetryStartup;const r=N(this.runtimeTelemetry,{family:"query",name:`${String(e?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(e?.entity||"unknown")}}),o=async()=>{try{const s=e?.[this.internalQueryToken]===!0;if(!s){if(typeof e?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");e.prepareForList()}const a=s?{query:e,execution:void 0}:await this.prepareIdSetPage(e,t),c=s?a:await this.prepareContinuousPage(a.query);e=new L(e).withQuery(c.query).query;const{sql:u,values:l,aggregateNames:f}=await this.compileQuery(e,!0,n?[n.field]:[]);t=await this.queryTreeBindings(e,u,l,t);const h=(await this.executeLoggedSQL("select",u,l,this.queryLogIntent(e),()=>this.driver.query(u,l),t)).rows.map(m=>this.decodeRow(e.entity,m,f));if(a.execution?.pageIds){const m=new Map(a.execution.pageIds.map((y,d)=>[String(y),d]));h.sort((y,d)=>(m.get(String(y.id))??Number.MAX_SAFE_INTEGER)-(m.get(String(d.id))??Number.MAX_SAFE_INTEGER))}const p=this.descendantBindings(e,u,l,t);if(n)for(const m of h)n.keys.set(m,m[n.field]);if(await this.enhanceQueryRows(h,e,p),n&&Array.isArray(e.selectItems)&&e.selectItems.length&&!["id","version",...e.selectItems,...this.groupBy(e)].includes(n.field)){const m=this.schema(e.entity);if(![...(e.relations??[]).map(d=>d.name),...(e.relationAggregates??[]).map(d=>d.relationName)].some(d=>m.relations?.[d]?.localKey===n.field))for(const d of h)delete d[n.field]}return s||await this.registerContinuousPage(e,c.execution,h),r.success({attributes:{"teaql.result.cardinality":h.length}}),h}catch(s){throw r.failure(s),s}};return r.run?r.run(o):o()}async prepareIdSetPage(e,t){const n=e.localIdSetPaginationOptions?.(),r=e.localIdSetPaginationRuntime?.();if(!n||!r)return r?.observe("ID_SET_DISABLED"),{query:e};const o=this.queryLimit(e);if(!o||e.localContinuousPageOptions?.()||this.aggregates(e).length||this.groupBy(e).length||e.__teaqlPartitionBy)return r.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:e};if((e.orderItems||[]).some(m=>m.expr!=null))return r.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:e};this.orders(e).some(m=>m.field==="id")||(e=e.clone().order(P.asc("id")));const s=e.clone();s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.relations=[],s.commentText=void 0,s.purposeText=void 0,s.clearIdSetPaginationRuntime(),s.clearContinuousPageRuntime();const a=`${n.namespace}|${r.scope}|${JSON.stringify(s)}`;let c=2166136261;for(let m=0;m>>0).toString(16)}`;let l,f=!1;try{l=r.get(u)}catch{return r.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:e}}if(l)f=!0,r.observe("ID_SET_HIT",l.ids.length);else{let m;try{m=await r.build(u,async()=>{const y=r.get(u);if(y)return y;const d=e.clone();d.selectItems=["id"],d.relations=[],d.relationAggregates=[],d.facets=[],d.offsetValue=0,d.limitValue=n.maxIds+1,d.clearIdSetPaginationRuntime(),d.clearContinuousPageRuntime(),d[this.internalQueryToken]=!0;const b=new L(e).deriveHelper(d,`collect ${e.entity} IDs for pagination`),E=await this.compileQuery(e,!1),S=await this.queryTreeBindings(e,E.sql,E.values,t),w=await this.executeDerivedQuery(b.query,S,b.intent);if(w.length>n.maxIds)return;let v;try{v=BigUint64Array.from(w.map(T=>BigInt(T.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const I={ids:v,expiresAt:Date.now()+n.ttlSeconds*1e3};return r.put(u,I),I})}catch(y){return r.observe(y instanceof Error&&y.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:e}}if(l=m.value,!l)return r.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",n.maxIds+1),{query:e};f=!m.built,r.observe(f?"ID_SET_HIT":"ID_SET_BUILD",l.ids.length)}const g=Number(e.offsetValue||e._offset||0),h=Array.from(l.ids.slice(g,g+o)),p=e.clone();return p.offsetValue=0,p.limitValue=Math.max(h.length,1),p.filterCondition=p.filterCondition?{$and:[p.filterCondition,{id:{$in:h}}]}:{id:{$in:h}},p.clearIdSetPaginationRuntime(),r.observe(f?"ID_SET_HIT":"ID_SET_BUILD",l.ids.length),{query:p,execution:{pageIds:h,totalCount:l.ids.length}}}async executeFacetMembership(e,t,n=[]){const r=await this.executeFacetAggregates(e,t,[{function:"Count",field:"id",alias:"__teaql_facet_count"}]);return new Map([...r].map(([o,s])=>[o,Number(s.__teaql_facet_count??0)]))}async executeFacetAggregates(e,t,n){const r=new L(e);e=r.query;const o=r.withQuery(e.clone()).query;Q(e,o),o.facets=[],o.relations=[],o.relationAggregates=[],o.orderItems=[],o.offsetValue=0,o.limitValue=0,o.selectItems=[],o.groupByItems=[t],o.aggregateItems=n.map(a=>({...a})),o[this.internalQueryToken]=!0;const s=await this.executeQuery(o);return new Map(s.flatMap(a=>{const c=a[t];if(c==null)return[];const u={};for(const l of n)u[l.alias]=a[l.alias];return[[String(c),u]]}))}async executeCount(e,t,n){const r=e instanceof L?e:new L(e);if(e=r.query,typeof e?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const o=t??"__teaql_total",s=r.deriveOperation(e.forExactCount(o),n??{kind:"named-count",...t!==void 0?{alias:t}:{}}),c=(await this.executeQuery(s.query))[0]?.[o];if(typeof c!="number"||!Number.isFinite(c))throw new Error(`TeaQL provider did not return exact count alias ${o}`);return c}async prepareContinuousPage(e){const t=e.localContinuousPageOptions?.(),n=e.localContinuousPageRuntime?.();if(!t||!n)return n?.observe("DISABLED"),{query:e};const r=this.orders(e),o=this.queryLimit(e);if(!o||r.length!==1||r[0].field!=="id"||this.aggregates(e).length||this.groupBy(e).length||e.__teaqlPartitionBy)return n.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:e};const s=Object.assign(Object.create(Object.getPrototypeOf(e)),e);s.orderItems=[...e.orderItems||[]],s.relations=[...e.relations||[]],Object.defineProperty(s,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:t}),Object.defineProperty(s,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:n});const a=Number(e.offsetValue||e._offset||0),c={...JSON.parse(JSON.stringify(s)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},u=`${t.namespace}|${n.owner}|${JSON.stringify(c)}`;let l=2166136261;for(let m=0;m>>0).toString(16)}`,g={queryKey:f,offset:a,limit:o,direction:String(r[0].direction).toLowerCase(),ttlSeconds:t.ttlSeconds,runtime:n,optimized:!1};if(a===0)return n.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:s,execution:g};let h;try{h=await D(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>n.get(f,a))}catch{return n.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:s,execution:g}}if(!h)return n.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:s,execution:g};const p={id:{[g.direction==="desc"?"$lt":"$gt"]:h.boundary}};return s.filterCondition=s.filterCondition?{$and:[s.filterCondition,p]}:p,s.offsetValue=0,s._offset!==void 0&&(s._offset=0),g.optimized=!0,g.cursorId=h.cursorId,n.observe("CURSOR_SEEK",h.cursorId),{query:s,execution:g}}async registerContinuousPage(e,t,n){if(!(!t||n.length!==t.limit||!n.length||n[n.length-1].id===void 0)){try{await D(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>t.runtime.put(t.queryKey,t.offset+n.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:n[n.length-1].id,expiresAt:Date.now()+t.ttlSeconds*1e3}))}catch{t.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}t.optimized&&t.runtime.observe("CURSOR_SEEK",t.cursorId)}}executeForStream(e,t=1e3){try{const n=e instanceof L?new L(e.query,e.intent):new L(e);return this.executeCapturedStream(n.query,t)}catch(n){return(async function*(){throw n})()}}async*executeCapturedStream(e,t){if(await this.telemetryStartup,!Number.isInteger(t)||t<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(e.facets)&&e.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:n,values:r,aggregateNames:o}=await this.compileQuery(e),s=await this.queryTreeBindings(e,n,r),a=N(this.runtimeTelemetry,{family:"query",name:`${String(e.entity)}.stream`,attributes:{"teaql.entity.type":String(e.entity)}});let c;const u=async()=>{c=N(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.stream`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}})};await(a.run?a.run(u):u());const l=c.correlation?.(),f=this.driver.stream(n,r)[Symbol.asyncIterator](),g=Date.now();let h="cancelled",p=0,m=[];const y=this.descendantBindings(e,n,r,s);try{for(;;){const d=await(c.run?c.run(()=>f.next()):f.next());if(d.done)break;m.push(this.decodeRow(e.entity,d.value,o)),m.length===t&&(await this.enhanceQueryRows(m,e,y),p+=m.length,yield m,m=[])}m.length&&(await this.enhanceQueryRows(m,e,y),p+=m.length,yield m),h="success"}catch(d){throw h="failure",c.failure(d),a.failure(d),d}finally{try{await f.return?.()}catch(d){if(h!=="failure")throw h="failure",c.failure(d),a.failure(d),d}finally{if(h==="failure")try{this.recordSQL("select",n,r,g,p,void 0,this.queryLogIntent(e),h,s,l)}catch{}else this.recordSQL("select",n,r,g,p,void 0,this.queryLogIntent(e),h,s,l),c.success({attributes:{"teaql.result.cardinality":p}}),a.success({attributes:{"teaql.result.cardinality":p}})}}}async enhanceQueryRows(e,t,n){if(!e.length)return;const r=[...(t.relations??[]).map(a=>a.name),...(t.relationAggregates??[]).map(a=>a.relationName)];if(!r.length)return;const o=this.schema(t.entity),s=new Map;for(const a of r){const c=o.relations?.[a];if(!c)throw new Error(`Missing relation ${t.entity}.${a}`);s.has(c.localKey)||s.set(c.localKey,e.map(u=>u[c.localKey]))}await this.enhanceRelationAggregates(e,t,s,n),await this.enhanceRelations(e,t,s,n)}async enhanceRelations(e,t,n,r){if(!e.length||!Array.isArray(t.relations)||!t.relations.length)return;const o=this.schema(t.entity),s=new L(t).intent;for(const a of t.relations){const c=o.relations?.[a.name];if(!c)throw new Error(`Missing relation ${t.entity}.${a.name}`);const u=n.get(c.localKey),l=u.filter(S=>S!=null),f=a.query?this.queryLimit(a.query):void 0,g=a.query?.localTopNProbeParentThreshold?.(),h=c.many&&f!==void 0,p=Array.isArray(a.query?.selectItems)?a.query.selectItems:[],m=p.length>0&&!p.includes(c.foreignKey),y=this.driver.topNRelationPlanPolicy==="alwaysProbe",d=h&&(g===void 0?y:g>0&&l.length<=g),b=d?"bounded_probes":"window",E=N(this.runtimeTelemetry,{family:"relation_load",name:`${t.entity}.${String(a.name)}`,attributes:{"teaql.entity.type":String(t.entity),"teaql.relation.name":String(a.name),"teaql.relation.parent_count":l.length,"teaql.relation.per_parent_limit":f??0,"teaql.relation.configured_probe_threshold":g??"provider-default","teaql.relation.selected_plan":b,"teaql.relation.probe_count":d?l.length:0}});try{if(!l.length&&!(c.many&&a.query?.facets?.length)){for(const T of e)T[a.name]=c.many?[]:null;E.success({attributes:{"teaql.result.cardinality":0}});continue}const S={...a.query||{},entity:c.targetEntity,selectItems:m?[...p,c.foreignKey]:p,_filters:[...this.filters(a.query||{})],relations:[...a.query?.relations||[]],orderItems:[...a.query?.orderItems||[]],__teaqlPartitionBy:h&&!d?c.foreignKey:void 0};if(h){const T=this.groupBy(S),O=T.length||this.aggregates(S).length?T:["id"];for(const $ of O)S.orderItems.some(A=>A.field===$)||S.orderItems.push(P.asc($))}typeof S.clearContinuousPageRuntime=="function"&&S.clearContinuousPageRuntime(),S[this.internalQueryToken]=!0;const w=[],v={field:c.foreignKey,keys:new WeakMap};if(d)for(const T of l){const O={...S,_filters:[...S._filters,{[c.foreignKey]:{$eq:T}}],__teaqlPartitionBy:void 0};w.push(...await this.executeDerivedQuery(new L(t).derive(O,a.name,a.operation).query,r,s,v))}else S._filters.push({[c.foreignKey]:{$in:l}}),w.push(...await this.executeDerivedQuery(new L(t).derive(S,a.name,a.operation).query,r,s,v));for(const T of w)delete T.__teaql_partition_rank;const I=new Map;for(const T of w){if(!v.keys.has(T))throw new Error("Relation assembly lost its captured row identity");const O=v.keys.get(T),$=I.get(O)||[];$.push(T),I.set(O,$)}if(m)for(const T of w)delete T[c.foreignKey];for(const[T,O]of e.entries()){const $=I.get(u[T])||[];if(c.many&&a.query?.facets?.length){const A=a.query.clone();A.entity=c.targetEntity;const le=u[T],Te={[c.foreignKey]:le==null?{$in:[]}:{$eq:le}};A.filterCondition=A.filterCondition?{$and:[A.filterCondition,Te]}:Te,Q(t,A);const it=new L(t).derive(A,a.name,a.operation).query;O[a.name]=new Y($,{facets:await et(this,nt=>nt,it,A.facets)})}else{const A=u[T];O[a.name]=c.many?$:$[0]??(A==null?null:{[c.foreignKey]:A})}}E.success({attributes:{"teaql.result.cardinality":w.length}})}catch(S){throw E.failure(S),S}}}async enhanceRelationAggregates(e,t,n,r){const o=t.relationAggregates;if(!e.length||!Array.isArray(o)||!o.length)return;const s=this.schema(t.entity),a=new L(t).intent;for(const c of o){const u=s.relations?.[c.relationName];if(!u)throw new Error(`Missing relation ${t.entity}.${c.relationName}`);const l=n.get(u.localKey),f=l.filter(y=>y!=null);if(!f.length){for(const y of e)y[c.alias]=c.singleResult?this.emptyAggregateValue(c.query):{};continue}const g=c.query.clone();g.entity=u.targetEntity,g.selectItems=[],g.properties=[],g.orderItems=[],g.limitValue=0,g.offsetValue=0,g.relations=[],g.relationAggregates=[],g.aggregateItems.length||g.aggregate("Count","id",c.alias),g.groupByItems.includes(u.foreignKey)||g.groupBy(u.foreignKey);const h={[u.foreignKey]:{$in:f}};g.filterCondition=g.filterCondition?{$and:[g.filterCondition,h]}:h,g[this.internalQueryToken]=!0;const p=await this.executeDerivedQuery(new L(t).deriveAggregate(g,c.relationName,c.operation??{kind:"relation-count",relation:c.relationName,alias:c.alias}).query,r,a),m=new Map;for(const y of p)m.set(y[u.foreignKey],y);for(const[y,d]of e.entries()){const b=m.get(l[y]);b?c.singleResult?d[c.alias]=b[g.aggregateItems[0].alias]??null:d[c.alias]=Object.fromEntries(Object.entries(b).filter(([E])=>E!==u.foreignKey)):d[c.alias]=c.singleResult?this.emptyAggregateValue(c.query):{}}}}emptyAggregateValue(e){const t=e.aggregateItems[0];return!t||String(t.function).toLowerCase()==="count"?0:null}queryLimit(e){if(e._limit!==void 0)return Number(e._limit);if(e.limitValue!==void 0&&Number(e.limitValue)>0)return Number(e.limitValue)}async close(){try{await this.driver.close()}finally{await this.telemetryStartup,await this.standardTelemetryHandle?.release(),this.standardTelemetryHandle=void 0}}}function Jt(i){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i))throw new Error(`Unsafe SQL identifier: ${i}`);return i}function Zt(i){const t={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(i).toLowerCase()];if(!t)throw new Error(`Unsupported aggregate: ${i}`);return t}class ei{constructor(e){this.worker=e,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=t=>{const n=t.data;if(!n||n.type!=="teaql-browser-sqlite-response")return;const r=this.pending.get(n.requestId);if(r)if(this.pending.delete(n.requestId),n.error){const o=new Error(n.error.message);o.name=n.error.name,n.error.code&&(o.code=n.error.code),r.reject(o)}else r.resolve(n.result)},this.onError=t=>{const n=new Error(t.message||"Browser SQLite worker failed");n.name="BrowserSQLiteWorkerError";for(const r of this.pending.values())r.reject(n);this.pending.clear()},e.addEventListener("message",this.onMessage),e.addEventListener("error",this.onError)}request(e,t){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const n=this.nextRequestId++;return new Promise((r,o)=>{this.pending.set(n,{resolve:s=>r(s),reject:o}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:n,operation:e,payload:t})})}async close(e){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),e&&this.worker.terminate?.();const t=new Error("Browser SQLite worker is closed");for(const n of this.pending.values())n.reject(t);this.pending.clear()}}}class ti{constructor(e){this.transport=e}query(e,t=[]){return this.transport.request("query",{sql:e,values:t})}}class $e{constructor(e,t){this.transport=e,this.options=t,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,t={}){const n={storage:t.storage??"memory",databaseName:ni(t.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:t.terminateWorkerOnClose??!0},r=new ei(e);return await r.request("open",n),new $e(r,n)}identifier(e){return`"${Jt(e)}"`}placeholder(e){return"?"}contains(e,t){return`CAST(${e} AS TEXT) LIKE '%' || ${t} || '%'`}aggregateFunction(e){return Zt(e)}encode(e,t){return e==null?e:t?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):t?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const t=this.accessTail;let n;this.accessTail=new Promise(r=>{n=r}),await t;try{return await e()}finally{n()}}query(e,t=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:t}))}async*stream(e,t=[]){const n=await this.query(e,t);for(const r of n.rows)yield r}transaction(e){return this.exclusive(async()=>{const t=new ti(this.transport);await t.query("BEGIN IMMEDIATE");try{const n=await e(t);return await t.query("COMMIT"),n}catch(n){try{await t.query("ROLLBACK")}catch{}throw n}})}async ensureSchema(e){for(const t of Object.values(e)){const n=this.identifier(t.table);await this.query(`CREATE TABLE IF NOT EXISTS ${n} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const r=await this.query(`PRAGMA table_info(${n})`),o=new Set(r.rows.map(s=>String(s.name)));for(const[s,a]of Object.entries(t.columns))s==="id"||s==="version"||o.has(a.columnName)||await this.query(`ALTER TABLE ${n} ADD COLUMN ${this.identifier(a.columnName)} ${ii(a.logicalType)}${a.nullable===!1?" NOT NULL":""}`)}for(const t of Wt(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(t.name)} ON ${this.identifier(t.table)} (${this.identifier(t.foreignColumn)}, ${this.identifier(t.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,t){for(let n=1;n<=100;n+=1){const r=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t]);if(!r.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[t])).rowCount===1)return"1"}catch(c){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t])).rowCount)throw c}continue}const o=Number(r.rows[0].id),s=o+1,a=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[s,t,o]);if(a.rowCount===1)return String(s);if(a.rowCount!==0)throw new Error(`ID space update for ${t} changed ${a.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${t} after 100 optimistic-lock attempts`)}ensureIdFloor(e,t,n){return Gt(e,r=>this.placeholder(r),t,n)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}}class tt extends Xt{constructor(e,t){super(e,t),this.browserDriver=e}static async open(e,t,n={}){return new tt(await $e.open(e,n),t)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}}function ii(i){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[i]}function ni(i){const e=i.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}function hi(i,e,t,n){const r=o=>{if(o.includes("."))throw new Error("Dynamic search requires a trusted relation binding");const s=t[i.entity]?.queryFields;if(!s||!Object.prototype.hasOwnProperty.call(s,o))throw new Error("Missing generated scalar search binding");return s[o]};return ri(i,e,t,{filter:(o,s)=>{const[a,c]=Object.entries(s)[0];if(c===null&&a!=="$eq"&&a!=="$ne")throw new Error("Null supports only equality predicates");return{[r(o)]:s}},order:(o,s)=>s==="asc"?P.asc(r(o)):P.desc(r(o))},n)}function ri(i,e,t,n,r=o=>console.warn({...o,fieldPath:""})){const o=ai(e,i.entity,t,()=>{}),s=Object.entries(o.search.filter??{}).map(([f,g])=>n.filter(f,g)),a=(o.search.orderBy??[]).map(f=>n.order(f.field,f.direction));if(s.some(f=>!U(f)))throw new Error("Invalid trusted search filter binding");if(a.some(f=>!(f instanceof P)))throw new Error("Invalid trusted search order binding");const c=i.clone(),u=i._filters??[],l=[...u,...i.filterCondition?[i.filterCondition]:[]];return(s.length||u.length)&&c.filter({$and:[...l,...s]}),c.orderItems.push(...a),o.warnings.forEach(f=>r({...f})),{query:c,warnings:o.warnings}}const Z=(i,e)=>Object.prototype.hasOwnProperty.call(i,e),U=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),si=new Set(["__proto__","prototype","constructor"]),oi=new Set(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$notIn","$contains"]);function ai(i,e,t,n=o=>console.warn({...o,fieldPath:""}),r=100){if(!Number.isSafeInteger(r)||r<1)throw new Error("Invalid search limit");if(!Z(t,e))throw new Error("Unknown search entity");let o;try{o=typeof i=="string"?JSON.parse(i):i}catch{throw new Error("Dynamic search requires valid JSON")}if(!U(o)||Object.keys(o).some(h=>!["filter","orderBy"].includes(h)))throw new Error("Unsupported dynamic search input or control");if(o.filter!==void 0&&!U(o.filter))throw new Error("Invalid search filter");if(o.orderBy!==void 0&&!Array.isArray(o.orderBy))throw new Error("Invalid search ordering");const s=Object.entries(o.filter??{}),a=o.orderBy??[];if(s.length+a.length>r)throw new Error("Dynamic search exceeds clause limit");const c=[],u={filter:Object.create(null),orderBy:[]};function l(h){const p=h.split(".");if(p.length>16||p.some(d=>!d||d.startsWith("$")||si.has(d)))throw new Error("Invalid dynamic search field path");let m=t[e];for(const d of p.slice(0,-1)){if(!Z(m.relations,d))return;const b=m.relations[d];if(!Z(t,b))throw new Error("Invalid trusted search relation metadata");m=t[b]}const y=p[p.length-1];return Z(m.fields,y)?m.fields[y]:void 0}function f(h,p){c.push({code:"DYNAMIC_SEARCH_UNKNOWN_FIELD",entity:e,clause:p,fieldPath:h})}function g(h,p){if(h===null)return;if(!(p==="date"?typeof h=="string"&&/^\d{4}-\d{2}-\d{2}$/.test(h)&&!h.startsWith("0000-")&&Number.isFinite(Date.parse(h+"T00:00:00Z"))&&new Date(h+"T00:00:00Z").toISOString().slice(0,10)===h:p==="decimal"?typeof h=="string"&&/^[+-]?\d+(?:\.\d+)?$/.test(h)||typeof h=="number"&&Number.isFinite(h):p==="integer"||p==="timestamp"?typeof h=="number"&&Number.isSafeInteger(h):p==="number"?typeof h=="number"&&Number.isFinite(h):typeof h===p))throw new Error("Invalid value for known search field")}for(const[h,p]of s){const m=U(p)?Object.entries(p):[["$eq",p]];if(m.length!==1||!oi.has(m[0][0]))throw new Error("Unsupported or malformed dynamic search operator");const[y,d]=m[0];if((y==="$in"||y==="$notIn")&&(!Array.isArray(d)||d.length>1e3))throw new Error("Invalid or oversized search value list");const b=l(h);if(b===void 0){f(h,"FILTER");continue}if(b==="unsupported")throw new Error("Known search field has no supported scalar binding");if(y==="$contains"&&b!=="string")throw new Error("String operator requires a string field");if(Array.isArray(d)){if(y!=="$in"&&y!=="$notIn")throw new Error("Unexpected search value list");d.forEach(E=>g(E,b))}else g(d,b);u.filter[h]={[y]:Array.isArray(d)?[...d]:d}}for(const h of a){if(!U(h)||Object.keys(h).some(m=>!["field","direction"].includes(m))||typeof h.field!="string"||!["asc","desc"].includes(h.direction))throw new Error("Invalid dynamic search ordering");const p=l(h.field);if(p===void 0){f(h.field,"ORDER_BY");continue}if(p==="unsupported")throw new Error("Known search field has no supported scalar binding");u.orderBy.push({field:h.field,direction:h.direction})}return c.forEach(h=>n({...h})),{search:u,warnings:c}}export{tt as B,ot as C,ci as D,Le as L,z as M,P as O,se as Q,Je as R,Ft as S,Dt as U,Y as a,ui as b,li as c,hi as d,et as e,C as f,ri as m}; diff --git a/assets/index-3Oa_Nwum.js b/assets/index-3Oa_Nwum.js deleted file mode 100644 index 97de65e23b83a85c8c57bca60d8f22f205d0a772..0000000000000000000000000000000000000000 --- a/assets/index-3Oa_Nwum.js +++ /dev/null @@ -1,5 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function i(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(s){if(s.ep)return;s.ep=!0;const n=i(s);fetch(s.href,n)}})();var we={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},Ce=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],G=class extends Error{constructor(e){super(`Unsupported locale: ${e}`),this.localeCode=e}},be={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function ne(t){if(typeof t!="string"||!t.trim())throw new G(t);const e=t.trim().replace(/_/g,"-").toLowerCase(),i=Ce.find(s=>s.toLowerCase()===e);if(i)return i;const r=be[e];if(!r)throw new G(t);return r}var j=class{constructor(e,i){if(this.data=e,this.fallback=i,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(ne)}message(e,i){return this.data.locales[e]?.messages[i]??this.fallback?.data.locales[e]?.messages[i]??this.data.locales.en?.messages[i]??this.fallback?.data.locales.en?.messages[i]??i}translate(e,i){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(i,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};j.builtin=new j(we);var ve=j,ue=Symbol("teaql.context.schema-capability"),H=new WeakMap,Ie=1;function Se(t){if(!t||typeof t!="object"&&typeof t!="function")return String(t);const e=t;let i=H.get(e);return i||(i=Ie++,H.set(e,i)),String(i)}var X=class extends Error{constructor(t,e,i){super(`context root ${t}: expected ${e}`),this.reason=t,this.expectedType=e,this.activeRoot=i,this.name="ContextRootError"}},oe=class{constructor(){this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(t,e)=>this.getContinuousPageCursor(t,e),put:(t,e,i)=>this.putContinuousPageCursor(t,e,i),observe:(t,e)=>{this.continuousPagePlan=t,this.continuousPageCursorId=e}},this.idSetPaginationRuntime={owner:"",scope:"",get:t=>this.idSetStore().get(t),put:(t,e)=>this.idSetStore().put(t,e),build:(t,e)=>this.singleFlightIdSetBuild(t,e),observe:(t,e)=>{this.idSetPaginationPlan=t,this.idSetPaginationCount=e,this.idSetPaginationCountAccuracy=t==="ID_SET_BUILD"||t==="ID_SET_HIT"?"EXACT":t==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=ve.builtin}setLocaleCode(t){const e=ne(t);return this.locale=e,this}setLanguageCode(t){return this.setLocaleCode(t)}installI18nCatalog(t){if(!t)throw new Error("catalog is required");return this.i18nCatalog=t,this}installIdSetPaginationStore(t){if(!t)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",t)}translateCheckResults(t){return t.map(e=>this.i18nCatalog.translate(e,this.locale))}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(t){const e=String(t.sourceLabel||""),i=e.toLowerCase();if(!t.entityType||!t.modelPath||!e||i.includes("authorization")||i.includes("cookie")||i.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const r=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",r),r.push(Object.freeze({...t})),this}finishFixEvidence(){const t=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...t])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(t,e){return this.resources.set(t,e),this}getResource(t){return this.resources.get(t)}removeResource(t){return this.resources.delete(t),this}requireResource(t){const e=this.getResource(t);if(e===void 0)throw new Error(`Required UserContext resource is missing: ${t}`);return e}ensureSchema(){const t=this.requireResource("dataService"),e=t[ue];if(!e)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return e.call(t,this)}withActiveRoot(t){if(!t||!t.entity||t.id===void 0||t.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...t}))}requireActiveRoot(t){const e=this.getResource("activeRoot");if(!e)throw new X("missing",t);if(e.entity!==t)throw new X("type_mismatch",t,e);return e}prepareQuery(t){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const e=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,e?`${e.entity}:${String(e.id)}`:"-",Se(this.getResource("dataService"))].join("|"),t.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(t,e){const i=`${t}:${e}`,r=this.continuousPageCursors.get(i);if(r&&r.expiresAt<=Date.now()){this.continuousPageCursors.delete(i);return}return r}putContinuousPageCursor(t,e,i){if(this.continuousPageCursors.size>=4096){const r=[...this.continuousPageCursors.entries()].sort((s,n)=>s[1].expiresAt-n[1].expiresAt)[0];r&&this.continuousPageCursors.delete(r[0])}this.continuousPageCursors.set(`${t}:${e}`,i)}getRetainedIdSet(t){const e=this.retainedIdSets.get(t);if(e&&e.expiresAt<=Date.now()){this.retainedIdSets.delete(t);return}return e}idSetStore(){return this.getResource("idSetPaginationStore")??{get:t=>this.getRetainedIdSet(t),put:(t,e)=>this.putRetainedIdSet(t,e),invalidate:t=>{this.retainedIdSets.delete(t)}}}putRetainedIdSet(t,e){if(e.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const r=()=>[...this.retainedIdSets.values()].reduce((s,n)=>s+n.ids.byteLength,0);for(;this.retainedIdSets.size>=64||r()+e.ids.byteLength>268435456;){const s=[...this.retainedIdSets.entries()].sort((n,o)=>n[1].expiresAt-o[1].expiresAt)[0];if(!s)break;this.retainedIdSets.delete(s[0])}this.retainedIdSets.set(t,e)}async singleFlightIdSetBuild(t,e){const i=this.idSetBuilds.get(t);if(i)return{value:await i,built:!1};const r=e();this.idSetBuilds.set(t,r);try{return{value:await r,built:!0}}finally{this.idSetBuilds.delete(t)}}},_e=class extends Error{constructor(e){super(`Check failed: ${e.map(i=>i.message??`${i.ruleId}:${i.location}`).join("; ")}`),this.violations=e,this.name="CheckException"}};function ke(t,e){const i=t.defaultDomainRoot,r=e.defaultDomainRoot;if(i&&r&&(i.entity!==r.entity||i.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...t.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??i,constants:[...s.values()],ensure:t.ensure&&e.ensure?async n=>{await t.ensure(n),await e.ensure(n)}:e.ensure??t.ensure}}var Y=class B{constructor(e,i,r){this.field=e,this.expr=i,this.direction=r}static new(e,i){return new B(e,null,i)}static expr(e,i){return new B("",e,i)}static asc(e){return B.new(e,"Asc")}static desc(e){return B.new(e,"Desc")}},J=Object.freeze({success:()=>{},failure:()=>{}}),$e=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function Ae(t){const e={"teaql.operation.family":t.family,"teaql.operation.name":t.name};for(const[i,r]of Object.entries(t.attributes||{}))$e.has(i)||(e[i]=r);return Object.freeze({...t,attributes:Object.freeze(e)})}function D(t,e){if(!t)return J;try{const i=t.start(Ae(e));let r=!1;return{run:i.run?s=>i.run(s):s=>s(),success(s){if(!r){r=!0;try{i?.success(s)}catch{}}},failure(s){if(!r){r=!0;try{i?.failure(s)}catch{}}}}}catch{return J}}async function T(t,e,i,r){const s=D(t,e);try{const n=await(s.run?s.run(i):i());return s.success(r?.(n)),n}catch(n){throw s.failure(n),n}}function qe(t){const e=new Map;for(const i of Object.values(t))for(const r of Object.values(i.relations||{})){if(!r.many)continue;const s=t[r.targetEntity],n=s?.columns[r.foreignKey]?.columnName,o=s?.columns.id?.columnName;if(!s||!n||!o)continue;const u=`idx_${s.table}_${n}_${o}`;let a=2166136261;for(let l=0;l>>0).toString(36),h=u.length<=30?u:`${u.slice(0,Math.max(1,29-c.length))}_${c}`;e.set(h,{name:h,table:s.table,foreignColumn:n,idColumn:o})}return[...e.values()]}async function xe(t,e,i,r){const s=Number(r);if(!Number.isSafeInteger(s)||s<0)throw new Error(`Invalid ID space floor ${r} for ${i}`);for(let n=1;n<=100;n+=1){const o=await t.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[i]);if(!o.rowCount){try{if((await t.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[i,s])).rowCount===1)return}catch(c){if(!(await t.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[i])).rowCount)throw c}continue}const u=Number(o.rows[0].id);if(u>=s)return;const a=await t.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[s,i,u]);if(a.rowCount===1)return;if(a.rowCount!==0)throw new Error(`ID space floor update for ${i} changed ${a.rowCount} rows on attempt ${n}`)}throw new Error(`Unable to synchronize ID space floor for ${i} after 100 optimistic-lock attempts`)}function Le(t){return t.startsWith('"')&&t.endsWith('"')||t.startsWith("`")&&t.endsWith("`")?t.slice(1,-1).replace(/""/g,'"').replace(/``/g,"`"):t}function Te(t,e){return t===e?!0:(t instanceof Date&&(t=t.getTime()),e instanceof Date&&(e=e.getTime()),t!=null&&e!==null&&e!==void 0&&String(t)===String(e))}function N(t,e,i){return[{level:0,kind:"operation",name:"mutation"},{level:1,kind:"entity",name:String(t.entity)},{level:2,kind:"provider",name:e},{level:3,kind:"sql",name:i}]}function Be(t,e,i="sqlite"){let r=0,s="",n="sql";for(let o=0;o=0&&h=0&&hi.toString(16).padStart(2,"0")).join("")}'`:_(typeof t=="object"?JSON.stringify(t):String(t))}function _(t){return`'${t.replace(/'/g,"''")}'`}var Re=class{constructor(t=e=>console.debug(e)){this.writer=t}write(t){this.writer(`[TeaQL SQL][${t.operation}][${t.elapsedMicros}us] ${t.resultSummary} -comment=${t.comment??""} purpose=${t.purpose??""} auditReason=${t.auditReason??""} tracePath=${Z(t.tracePath)} -Parameterized SQL: ${t.parameterizedSQL} params=${Z(t.parameters)} -Debug SQL: ${t.debugSQL}`)}};function Z(t){return JSON.stringify(t,(e,i)=>typeof i=="bigint"?i.toString():i)}var Fe=class{constructor(t,e){this.driver=t,this.schemas=e,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.auditEvents=[],this.diagnosticSQLLogSink=new Re,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.checkers={},this.userContext=new oe,this.bootstrap={},this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve()}install(t){return Object.assign(this.schemas,t.schemas),Object.assign(this.checkers,t.checkers),this.bootstrap=ke(this.bootstrap,t.bootstrap),this}setUserContext(t){return this.userContext=t,this}schema(t){const e=this.schemas[t];if(!e)throw new Error(`Unknown TeaQL entity: ${t}`);return e}toRuntimeMutationRecord(t,e){const i={};for(const[r,s]of Object.entries(e)){const n=t.columns[r]?r:Object.keys(t.columns).find(o=>t.columns[o].modelName===r||t.columns[o].columnName===r);n&&(i[n]=s)}return i}encode(t,e){const i=t?.id??t;if(i!==void 0)return this.driver.encode(i,e)}decodeRow(t,e,i=[]){const r=this.schema(t),s={...e};for(const[n,o]of Object.entries(r.columns)){const u=s[n];u!=null&&(o.decode==="number"&&(s[n]=Number(u)),o.decode==="string"&&(s[n]=String(u)),o.decode==="date"&&u instanceof Date&&(s[n]=u.toISOString()),o.logicalType==="boolean"&&(s[n]=!!u))}for(const n of i)s[n]!==null&&s[n]!==void 0&&(s[n]=Number(s[n]));return s}get auditTrace(){return[...this.auditEvents]}setAuditSink(t){return this.auditSink=t,this}setRuntimeTelemetrySink(t){return this.telemetrySink=t,this}setDiagnosticSQLLogSink(t){return this.diagnosticSQLLogSink=t,this}setQueryLoggingEnabled(t){return this.queryLoggingEnabled=t,this}setMutationLoggingEnabled(t){return this.mutationLoggingEnabled=t,this}setRuntimeTelemetry(t){return this.runtimeTelemetry=t,this}recordSQL(t,e,i,r,s,n,o={}){const u=t==="select";if(u&&!this.queryLoggingEnabled||!u&&!this.mutationLoggingEnabled||!this.telemetrySink&&!this.diagnosticSQLLogSink)return;const a=Object.freeze({operation:t,...o,tracePath:Object.freeze([...o.tracePath??[]]),parameterizedSQL:e,parameters:Object.freeze([...i]),debugSQL:Be(e,i,this.driver.databaseKind),elapsedMicros:Math.max(0,(Date.now()-r)*1e3),resultCount:s,affectedRows:n,resultSummary:s!==void 0?`${s} rows returned`:`${n??0} rows affected`});this.telemetrySink?.record(a),this.diagnosticSQLLogSink?.write(a)}async[ue](t){this.userContext=t,this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const e=this.bootstrapTail;let i;this.bootstrapTail=new Promise(r=>{i=r}),await e;try{if(this.bootstrap.ensure){t.insertResource("bootstrapActor","teaql-generated-bootstrap"),t.insertResource("bootstrapCategory","runtime-bootstrap");try{await this.bootstrap.ensure(t)}finally{t.removeResource("bootstrapActor"),t.removeResource("bootstrapCategory")}}else await this.ensureBootstrapData()}finally{i()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const t=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];t.length&&await this.driver.transaction(async e=>{for(const i of t)await this.reconcileBootstrapEntity(e,i)})}async reconcileBootstrapEntity(t,e){const i=this.schema(e.entity),r=this.driver.identifier(i.table),s=this.driver.identifier(i.columns.id?.columnName??"id"),n=this.driver.identifier(i.columns.version?.columnName??"version"),o=Object.entries(e.values??{}).map(([a,c])=>{const h=i.columns[a];if(!h)throw new Error(`Unknown bootstrap field ${e.entity}.${a}`);return{column:this.driver.identifier(h.columnName),value:this.driver.encode(c,h)}}),u=await t.query(`SELECT * FROM ${r} WHERE ${s} = ${this.driver.placeholder(1)}`,[e.id]);if(u.rowCount){const a=u.rows[0],c=o.filter(h=>!Te(a[Le(h.column)],h.value));if(c.length){const h=c.map((l,m)=>`${l.column} = ${this.driver.placeholder(m+1)}`);h.push(`${n} = ${n} + 1`),await t.query(`UPDATE ${r} SET ${h.join(", ")} WHERE ${s} = `+this.driver.placeholder(c.length+1),[...c.map(l=>l.value),e.id])}}else{const a=[s,n,...o.map(l=>l.column)],c=[e.id,1,...o.map(l=>l.value)],h=c.map((l,m)=>this.driver.placeholder(m+1));await t.query(`INSERT INTO ${r} (${a.join(", ")}) VALUES (${h.join(", ")})`,c)}await this.driver.ensureIdFloor(t,e.entity,e.id)}async executeGraphSave(t){const e=this.graphSaveTail;let i;this.graphSaveTail=new Promise(r=>{i=r}),await e,this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence();try{const r=await this.driver.transaction(async s=>{this.graphMutationSession=s;try{return await t()}finally{this.graphMutationSession=void 0}});for(const s of this.graphCommitActions)s();return r}catch(r){for(const s of[...this.graphRollbackActions].reverse())s();throw r}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.removeResource("fixTime").finishFixEvidence(),i()}}afterGraphCommit(t){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(t)}afterGraphRollback(t){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(t)}async withMutationSession(t){return this.graphMutationSession?t(this.graphMutationSession):this.driver.transaction(t)}preflightMutation(t){if(!String(t?.comment||"").trim())throw new Error("Security audit failure: audit reason is required before mutation");t={...t,payload:{...t?.payload??{}}};const e=this.checkers[String(t.entity)];if(!e)return t;const i=[],r=this.userContext.getResource("fixTime")===void 0;r&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(e.checkAndFix(this.userContext,t,i),t.ledgerKey&&t.ledgerRoot)for(const[s,n]of Object.entries(t.payload||{}))t.ledgerRoot.set(t.ledgerKey,s,n);if(this.userContext.translateCheckResults(i),i.length)throw new _e(i);return t}finally{r&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(t){const e=D(this.runtimeTelemetry,{family:"mutation",name:`${String(t?.entity||"unknown")}.${String(t?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(t?.entity||"unknown"),"teaql.mutation.kind":String(t?.action||"unknown").toLowerCase()}});try{t=this.preflightMutation(t);const i=this.schema(t.entity),r=this.toRuntimeMutationRecord(i,t.payload||{}),s=this.driver.identifier(i.table),n=await T(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(t.action).toLowerCase()}},()=>this.withMutationSession(async u=>{if(t.action==="Create"){const a=t.id?String(t.id):await this.driver.nextId(u,t.entity);t.id&&await this.driver.ensureIdFloor(u,t.entity,a);const c=Number(t.version||0)+1,h={...r,id:a,version:c},l=Object.keys(i.columns).filter(w=>h[w]!==void 0),m=l.map(w=>this.driver.identifier(i.columns[w].columnName)).join(", "),d=l.map((w,k)=>this.driver.placeholder(k+1)).join(", "),p=l.map(w=>this.encode(h[w],i.columns[w])),f=`INSERT INTO ${s} (${m}) VALUES (${d})`,g=Date.now(),E=await u.query(f,p);return this.recordSQL("insert",f,p,g,void 0,E.rowCount,{auditReason:String(t.comment),tracePath:N(t,this.driver.databaseKind,"insert")}),{success:!0,id:a,version:c,persistedRecord:await this.readPersistedRecord(u,i,a)}}if(t.action==="Update"){const a=Object.keys(i.columns).filter(E=>E!=="id"&&E!=="version"&&r[E]!==void 0),c=a.map(E=>this.encode(r[E],i.columns[E])),h=a.map((E,w)=>`${this.driver.identifier(i.columns[E].columnName)} = `+this.driver.placeholder(w+1)),l=this.driver.identifier("version");h.push(`${l} = ${l} + 1`),c.push(String(t.id));const m=[`${this.driver.identifier("id")} = ${this.driver.placeholder(c.length)}`];t.version!==void 0&&t.version!==null&&(c.push(Number(t.version)),m.push(`${l} = ${this.driver.placeholder(c.length)}`));const d=`UPDATE ${s} SET ${h.join(", ")} WHERE ${m.join(" AND ")}`,p=Date.now(),f=await u.query(d,c);if(this.recordSQL("update",d,c,p,void 0,f.rowCount,{auditReason:String(t.comment),tracePath:N(t,this.driver.databaseKind,"update")}),f.rowCount!==1)throw new Error(`Optimistic lock failed or ${t.entity}(${t.id}) does not exist`);const g=await this.readPersistedRecord(u,i,String(t.id));return{success:!0,id:String(t.id),version:Number(g.version),persistedRecord:g}}if(t.action==="Delete"){const a=this.driver.identifier("version"),c=[String(t.id)],h=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];t.version!==void 0&&t.version!==null&&(c.push(Number(t.version)),h.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(c.length)));const l=`UPDATE ${s} SET ${a} = -(${a} + 1) WHERE ${h.join(" AND ")}`,m=Date.now(),d=await u.query(l,c);if(this.recordSQL("delete",l,c,m,void 0,d.rowCount,{auditReason:String(t.comment),tracePath:N(t,this.driver.databaseKind,"delete")}),d.rowCount!==1)throw new Error(`Optimistic lock failed or ${t.entity}(${t.id}) does not exist`);const p=await this.readPersistedRecord(u,i,String(t.id));return{success:!0,id:String(t.id),version:Number(p.version),deleted:!0,persistedRecord:p}}throw new Error(`Unsupported mutation action: ${t.action}`)})),o=Object.freeze({entity:t.entity,action:t.action,id:String(n.id),reason:String(t.comment),recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.keys(t.payload||{}).sort(),version:n.version});return this.auditEvents.push(o),this.auditSink&&await T(this.runtimeTelemetry,{family:"audit",name:`${t.entity}.audit`,attributes:{"teaql.entity.type":String(t.entity),"teaql.mutation.kind":String(t.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(t.payload||{}).length}},async()=>this.auditSink(o)),e.success(),n}catch(i){throw e.failure(i),i}}async readPersistedRecord(t,e,i){const r=Object.entries(e.columns).map(([n,o])=>`${this.driver.identifier(o.columnName)} AS ${this.driver.identifier(n)}`).join(", "),s=await t.query(`SELECT ${r} FROM ${this.driver.identifier(e.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,[i]);if(s.rowCount!==1)throw new Error(`Persisted ${e.table}(${i}) could not be read back`);return this.decodeRowForSchema(e,s.rows[0])}decodeRowForSchema(t,e){const i={...e};for(const[r,s]of Object.entries(t.columns)){const n=i[r];n!=null&&(s.decode==="number"&&(i[r]=Number(n)),s.decode==="string"&&(i[r]=String(n)),s.decode==="date"&&n instanceof Date&&(i[r]=n.toISOString()),s.logicalType==="boolean"&&(i[r]=!!n))}return i}compileExpression(t,e,i){if(Array.isArray(t?.$and))return`(${t.$and.map(n=>this.compileExpression(n,e,i)).join(" AND ")})`;const r=Object.entries(t||{}).map(([s,n])=>{const o=e.columns[s];if(!o)throw new Error(`Unknown field ${s} for SQL query`);const u=this.driver.identifier(o.columnName);if(n?.$eq!==void 0){const a=n.$eq?.id??n.$eq;return a===null?`${u} IS NULL`:(i.push(this.encode(a,o)),`${u} = ${this.driver.placeholder(i.length)}`)}if(n?.$ne!==void 0){const a=n.$ne?.id??n.$ne;return a===null?`${u} IS NOT NULL`:(i.push(this.encode(a,o)),`${u} <> ${this.driver.placeholder(i.length)}`)}if(n?.$soundLike!==void 0)return i.push(String(n.$soundLike)),`SOUNDEX(${u}) = SOUNDEX(${this.driver.placeholder(i.length)})`;if(n?.$contains!==void 0)return i.push(String(n.$contains)),this.driver.contains(u,this.driver.placeholder(i.length));if(n?.$notContains!==void 0)return i.push(String(n.$notContains)),`NOT (${this.driver.contains(u,this.driver.placeholder(i.length))})`;for(const[a,c,h,l]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(n?.[a]!==void 0){i.push(`${c}${String(n[a])}${h}`);const m=`${u} LIKE ${this.driver.placeholder(i.length)}`;return l?`NOT (${m})`:m}if(Array.isArray(n?.$in)){if(!n.$in.length)return"FALSE";const a=n.$in.map(c=>(i.push(this.encode(c?.id??c,o)),this.driver.placeholder(i.length)));return`${u} IN (${a.join(", ")})`}if(Array.isArray(n?.$notIn)){if(!n.$notIn.length)return"TRUE";const a=n.$notIn.map(c=>(i.push(this.encode(c?.id??c,o)),this.driver.placeholder(i.length)));return`${u} NOT IN (${a.join(", ")})`}for(const[a,c]of[["$inSubquery",!1],["$notInSubquery",!0]]){const h=n?.[a];if(h!==void 0){const l=h.query,m=this.schema(l?.entity),d=String(h.field),p=m.columns[d];if(!p)throw new Error(`Unknown subquery projection ${d} for ${l?.entity}`);const f=this.filters(l).map(w=>this.compileExpression(w,m,i));m.columns.version&&f.push(`${this.driver.identifier(m.columns.version.columnName)} > 0`),c&&f.push(`${this.driver.identifier(p.columnName)} IS NOT NULL`);const g=f.length?` WHERE ${f.join(" AND ")}`:"",E=`SELECT ${this.driver.identifier(p.columnName)} FROM ${this.driver.identifier(m.table)}${g}`;return`${u} ${c?"NOT IN":"IN"} (${E})`}}if(Array.isArray(n?.$between)&&n.$between.length===2){i.push(this.encode(n.$between[0],o));const a=this.driver.placeholder(i.length);i.push(this.encode(n.$between[1],o));const c=this.driver.placeholder(i.length);return`${u} BETWEEN ${a} AND ${c}`}if(n?.$isNull===!0)return`${u} IS NULL`;if(n?.$isNull===!1)return`${u} IS NOT NULL`;if(n?.$gte!==void 0)return i.push(this.encode(n.$gte,o)),`${u} >= ${this.driver.placeholder(i.length)}`;if(n?.$lte!==void 0)return i.push(this.encode(n.$lte,o)),`${u} <= ${this.driver.placeholder(i.length)}`;if(n?.$gt!==void 0)return i.push(this.encode(n.$gt,o)),`${u} > ${this.driver.placeholder(i.length)}`;if(n?.$lt!==void 0)return i.push(this.encode(n.$lt,o)),`${u} < ${this.driver.placeholder(i.length)}`;throw new Error(`Unsupported query predicate for ${s}: ${JSON.stringify(n)}`)});return r.length?`(${r.join(" AND ")})`:"TRUE"}filters(t){return Array.isArray(t._filters)&&t._filters.length?t._filters:t.filterCondition?[t.filterCondition]:[]}groupBy(t){return t._groupBy||t.groupByItems||[]}aggregates(t){return Array.isArray(t._aggregates)?t._aggregates:(t.aggregateItems||[]).map(e=>({func:e.function,field:e.field,retName:e.alias}))}orders(t){return Array.isArray(t._orderBy)?t._orderBy.map(e=>({field:e.f,direction:e.d})):(t.orderItems||[]).map(e=>({field:e.field,direction:e.direction}))}async compileQuery(t){const e=t?.[this.internalQueryToken]===!0,i=t?._purpose??t?.purposeText,r=t?._comment??t?.commentText;if(!e&&(!String(i||"").trim()||!String(r||"").trim()))throw new Error("Security audit failure: purpose and comment are required before query execution");const s=this.schema(t.entity),n=[],o=this.groupBy(t),u=o.map(y=>{if(!s.columns[y])throw new Error(`Unknown group field: ${y}`);return this.driver.identifier(s.columns[y].columnName)}),a=o.map(y=>`${this.driver.identifier(s.columns[y].columnName)} AS `+this.driver.identifier(y)),c=[],h=Array.isArray(t.selectItems)&&t.selectItems.length?[...new Set(["id","version",...t.selectItems])]:Object.keys(s.columns);for(const y of h)if(!s.columns[y])throw new Error(`Unknown selected field: ${y}`);let l=h.map(y=>{const C=s.columns[y];return`${this.driver.identifier(C.columnName)} AS ${this.driver.identifier(y)}`}).join(", ");const m=this.aggregates(t);if(m.length){const y=m.map(C=>{if(!s.columns[C.field])throw new Error(`Unknown aggregate field: ${C.field}`);return c.push(C.retName),`${this.driver.aggregateFunction(C.func)}(${this.driver.identifier(s.columns[C.field].columnName)}) AS `+this.driver.identifier(C.retName)});l=[...a,...y].join(", ")}const d=t.__teaqlPartitionBy,p=this.orders(t),f=p.map(y=>{if(!s.columns[y.field])throw new Error(`Unknown order field: ${y.field}`);const C=String(y.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(s.columns[y.field].columnName)} ${C}`});if(d){const y=s.columns[d];if(!y)throw new Error(`Unknown partition field: ${d}`);const C=f.length?` ORDER BY ${f.join(", ")}`:"";l+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier(y.columnName)}${C}) AS `+this.driver.identifier("__teaql_partition_rank")}let g=`SELECT ${l} FROM ${this.driver.identifier(s.table)}`;const w=this.filters(t).map(y=>this.compileExpression(y,s,n));s.columns.version&&w.push(`${this.driver.identifier(s.columns.version.columnName)} > 0`),w.length&&(g+=` WHERE ${w.join(" AND ")}`),u.length&&(g+=` GROUP BY ${u.join(", ")}`);const k=t._limit!==void 0?Number(t._limit):Number(t.limitValue||0),F=t._offset!==void 0?Number(t._offset):Number(t.offsetValue||0);if(d){const y=this.driver.identifier("__teaql_partition_rank"),C=[];n.push(F),C.push(`${y} > ${this.driver.placeholder(n.length)}`),k>0&&(n.push(F+k),C.push(`${y} <= ${this.driver.placeholder(n.length)}`)),g=`SELECT * FROM (${g}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${C.join(" AND ")} ORDER BY ${y}`}else p.length&&(g+=` ORDER BY ${f.join(", ")}`);return!d&&k>0&&(n.push(k),g+=` LIMIT ${this.driver.placeholder(n.length)}`),!d&&F>0&&(n.push(F),g+=` OFFSET ${this.driver.placeholder(n.length)}`),this.sqlTrace.push(g),{sql:g,values:n,aggregateNames:c}}async executeQuery(t){const e=D(this.runtimeTelemetry,{family:"query",name:`${String(t?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(t?.entity||"unknown")}});try{const i=t?.[this.internalQueryToken]===!0;if(!i){if(typeof t?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");t.prepareForList()}const r=i?{query:t,execution:void 0}:await this.prepareIdSetPage(t),s=i?r:await this.prepareContinuousPage(r.query);t=s.query;const{sql:n,values:o,aggregateNames:u}=await this.compileQuery(t),a=Date.now(),c=await T(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.query`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}},()=>this.driver.query(n,o)),h=t?._comment??t?.commentText,l=t?._purpose??t?.purposeText,m=Array.isArray(t?.__teaqlTracePath)?t.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(t.entity)}],d=[...m,{level:m.length,kind:"provider",name:this.driver.databaseKind},{level:m.length+1,kind:"sql",name:"select"}];this.recordSQL("select",n,o,a,c.rowCount,void 0,{comment:h,purpose:l,tracePath:d});const p=c.rows.map(f=>this.decodeRow(t.entity,f,u));if(r.execution?.pageIds){const f=new Map(r.execution.pageIds.map((g,E)=>[String(g),E]));p.sort((g,E)=>(f.get(String(g.id))??Number.MAX_SAFE_INTEGER)-(f.get(String(E.id))??Number.MAX_SAFE_INTEGER))}return await this.enhanceRelations(p,t),await this.enhanceRelationAggregates(p,t),i||await this.registerContinuousPage(t,s.execution,p),e.success({attributes:{"teaql.result.cardinality":p.length}}),p}catch(i){throw e.failure(i),i}}async prepareIdSetPage(t){const e=t.localIdSetPaginationOptions?.(),i=t.localIdSetPaginationRuntime?.();if(!e||!i)return i?.observe("ID_SET_DISABLED"),{query:t};const r=this.queryLimit(t);if(!r||t.localContinuousPageOptions?.()||this.aggregates(t).length||this.groupBy(t).length||t.__teaqlPartitionBy)return i.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:t};if((t.orderItems||[]).some(d=>d.expr!=null))return i.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:t};this.orders(t).some(d=>d.field==="id")||(t=t.clone().order(Y.asc("id")));const s=t.clone();s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.relations=[],s.commentText=void 0,s.purposeText=void 0,s.clearIdSetPaginationRuntime(),s.clearContinuousPageRuntime();const n=`${e.namespace}|${i.scope}|${JSON.stringify(s)}`;let o=2166136261;for(let d=0;d>>0).toString(16)}`;let a,c=!1;try{a=i.get(u)}catch{return i.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:t}}if(a)c=!0,i.observe("ID_SET_HIT",a.ids.length);else{let d;try{d=await i.build(u,async()=>{const p=i.get(u);if(p)return p;const f=t.clone();f.selectItems=["id"],f.relations=[],f.relationAggregates=[],f.facets=[],f.offsetValue=0,f.limitValue=e.maxIds+1,f.clearIdSetPaginationRuntime(),f.clearContinuousPageRuntime(),f[this.internalQueryToken]=!0;const g=await this.executeQuery(f);if(g.length>e.maxIds)return;let E;try{E=BigUint64Array.from(g.map(k=>BigInt(k.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const w={ids:E,expiresAt:Date.now()+e.ttlSeconds*1e3};return i.put(u,w),w})}catch(p){return i.observe(p instanceof Error&&p.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:t}}if(a=d.value,!a)return i.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",e.maxIds+1),{query:t};c=!d.built,i.observe(c?"ID_SET_HIT":"ID_SET_BUILD",a.ids.length)}const h=Number(t.offsetValue||t._offset||0),l=Array.from(a.ids.slice(h,h+r)),m=t.clone();return m.offsetValue=0,m.limitValue=Math.max(l.length,1),m.filterCondition=m.filterCondition?{$and:[m.filterCondition,{id:{$in:l}}]}:{id:{$in:l}},m.clearIdSetPaginationRuntime(),i.observe(c?"ID_SET_HIT":"ID_SET_BUILD",a.ids.length),{query:m,execution:{pageIds:l,totalCount:a.ids.length}}}async executeFacetMembership(t,e){const i=t.clone();i.facets=[],i.relations=[],i.orderItems=[],i.offsetValue=0,i.limitValue=0,i.selectItems=[],i.groupByItems=[e],i.aggregateItems=[{function:"Count",field:"id",alias:"__teaql_facet_count"}],i[this.internalQueryToken]=!0;const r=await this.executeQuery(i);return new Map(r.flatMap(s=>{const n=s[e],o=Number(s.__teaql_facet_count??0);return n==null?[]:[[String(n),o]]}))}async executeCount(t){if(typeof t?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const e="__teaql_total",r=(await this.executeQuery(t.forExactCount(e)))[0]?.[e];if(typeof r!="number"||!Number.isFinite(r))throw new Error(`TeaQL provider did not return exact count alias ${e}`);return r}async prepareContinuousPage(t){const e=t.localContinuousPageOptions?.(),i=t.localContinuousPageRuntime?.();if(!e||!i)return i?.observe("DISABLED"),{query:t};const r=this.orders(t),s=this.queryLimit(t);if(!s||r.length!==1||r[0].field!=="id"||this.aggregates(t).length||this.groupBy(t).length||t.__teaqlPartitionBy)return i.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:t};const n=Object.assign(Object.create(Object.getPrototypeOf(t)),t);n.orderItems=[...t.orderItems||[]],n.relations=[...t.relations||[]],Object.defineProperty(n,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:e}),Object.defineProperty(n,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:i});const o=Number(t.offsetValue||t._offset||0),u={...JSON.parse(JSON.stringify(n)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},a=`${e.namespace}|${i.owner}|${JSON.stringify(u)}`;let c=2166136261;for(let p=0;p>>0).toString(16)}`,l={queryKey:h,offset:o,limit:s,direction:String(r[0].direction).toLowerCase(),ttlSeconds:e.ttlSeconds,runtime:i,optimized:!1};if(o===0)return i.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:n,execution:l};let m;try{m=await T(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>i.get(h,o))}catch{return i.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:n,execution:l}}if(!m)return i.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:n,execution:l};const d={id:{[l.direction==="desc"?"$lt":"$gt"]:m.boundary}};return n.filterCondition=n.filterCondition?{$and:[n.filterCondition,d]}:d,n.offsetValue=0,n._offset!==void 0&&(n._offset=0),l.optimized=!0,l.cursorId=m.cursorId,i.observe("CURSOR_SEEK",m.cursorId),{query:n,execution:l}}async registerContinuousPage(t,e,i){if(!(!e||i.length!==e.limit||!i.length||i[i.length-1].id===void 0)){try{await T(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>e.runtime.put(e.queryKey,e.offset+i.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:i[i.length-1].id,expiresAt:Date.now()+e.ttlSeconds*1e3}))}catch{e.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}e.optimized&&e.runtime.observe("CURSOR_SEEK",e.cursorId)}}async*executeForStream(t,e=1e3){if(!Number.isInteger(e)||e<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(t.facets)&&t.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:i,values:r,aggregateNames:s}=await this.compileQuery(t);let n=[];for await(const o of this.driver.stream(i,r))n.push(this.decodeRow(t.entity,o,s)),n.length===e&&(await this.enhanceRelations(n,t),yield n,n=[]);n.length&&(await this.enhanceRelations(n,t),yield n)}async enhanceRelations(t,e){if(!t.length||!Array.isArray(e.relations)||!e.relations.length)return;const i=this.schema(e.entity);for(const r of e.relations){const s=i.relations?.[r.name];if(!s)throw new Error(`Missing relation ${e.entity}.${r.name}`);const n=t.map(d=>d[s.localKey]).filter(d=>d!=null),o=r.query?this.queryLimit(r.query):void 0,u=r.query?.localTopNProbeParentThreshold?.(),a=s.many&&o!==void 0,c=this.driver.topNRelationPlanPolicy==="alwaysProbe",h=a&&(u===void 0?c:u>0&&n.length<=u),l=h?"bounded_probes":"window",m=D(this.runtimeTelemetry,{family:"relation_load",name:`${e.entity}.${String(r.name)}`,attributes:{"teaql.entity.type":String(e.entity),"teaql.relation.name":String(r.name),"teaql.relation.parent_count":n.length,"teaql.relation.per_parent_limit":o??0,"teaql.relation.configured_probe_threshold":u??"provider-default","teaql.relation.selected_plan":l,"teaql.relation.probe_count":h?n.length:0}});try{if(!n.length){for(const g of t)g[r.name]=s.many?[]:null;m.success({attributes:{"teaql.result.cardinality":0}});continue}const d={...r.query||{},entity:s.targetEntity,_filters:[...this.filters(r.query||{})],relations:[...r.query?.relations||[]],orderItems:[...r.query?.orderItems||[]],__teaqlPartitionBy:a&&!h?s.foreignKey:void 0,__teaqlTracePath:[...Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(e.entity)}],{level:Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath.length:2,kind:"relation",name:`${String(e.entity)}.${String(r.name)}`}],commentText:e?._comment??e?.commentText,purposeText:e?._purpose??e?.purposeText};a&&!d.orderItems.some(g=>g.field==="id")&&d.orderItems.push(Y.asc("id")),typeof d.clearContinuousPageRuntime=="function"&&d.clearContinuousPageRuntime(),d[this.internalQueryToken]=!0;const p=[];if(h)for(const g of n){const E={...d,_filters:[...d._filters,{[s.foreignKey]:{$eq:g}}],__teaqlPartitionBy:void 0};p.push(...await this.executeQuery(E))}else d._filters.push({[s.foreignKey]:{$in:n}}),p.push(...await this.executeQuery(d));for(const g of p)delete g.__teaql_partition_rank;const f=new Map;for(const g of p){const E=g[s.foreignKey],w=f.get(E)||[];w.push(g),f.set(E,w)}for(const g of t){const E=f.get(g[s.localKey])||[];g[r.name]=s.many?E:E[0]??null}m.success({attributes:{"teaql.result.cardinality":p.length}})}catch(d){throw m.failure(d),d}}}async enhanceRelationAggregates(t,e){const i=e.relationAggregates;if(!t.length||!Array.isArray(i)||!i.length)return;const r=this.schema(e.entity);for(const s of i){const n=r.relations?.[s.relationName];if(!n)throw new Error(`Missing relation ${e.entity}.${s.relationName}`);const o=t.map(h=>h[n.localKey]).filter(h=>h!=null);if(!o.length){for(const h of t)h[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{};continue}const u=s.query.clone();u.entity=n.targetEntity,u.selectItems=[],u.properties=[],u.orderItems=[],u.limitValue=0,u.offsetValue=0,u.relations=[],u.relationAggregates=[],u.aggregateItems.length||u.aggregate("Count","id",s.alias),u.groupByItems.includes(n.foreignKey)||u.groupBy(n.foreignKey),u.filterCondition={...u.filterCondition||{},[n.foreignKey]:{$in:o}},u[this.internalQueryToken]=!0;const a=await this.executeQuery(u),c=new Map;for(const h of a)c.set(h[n.foreignKey],h);for(const h of t){const l=c.get(h[n.localKey]);l?s.singleResult?h[s.alias]=l[u.aggregateItems[0].alias]??null:h[s.alias]=Object.fromEntries(Object.entries(l).filter(([m])=>m!==n.foreignKey)):h[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{}}}}emptyAggregateValue(t){const e=t.aggregateItems[0];return!e||String(e.function).toLowerCase()==="count"?0:null}queryLimit(t){if(t._limit!==void 0)return Number(t._limit);if(t.limitValue!==void 0&&Number(t.limitValue)>0)return Number(t.limitValue)}async close(){await this.driver.close()}};function De(t){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))throw new Error(`Unsafe SQL identifier: ${t}`);return t}function Ne(t){const i={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(t).toLowerCase()];if(!i)throw new Error(`Unsupported aggregate: ${t}`);return i}var Pe=class{constructor(t){this.worker=t,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=e=>{const i=e.data;if(!i||i.type!=="teaql-browser-sqlite-response")return;const r=this.pending.get(i.requestId);if(r)if(this.pending.delete(i.requestId),i.error){const s=new Error(i.error.message);s.name=i.error.name,i.error.code&&(s.code=i.error.code),r.reject(s)}else r.resolve(i.result)},this.onError=e=>{const i=new Error(e.message||"Browser SQLite worker failed");i.name="BrowserSQLiteWorkerError";for(const r of this.pending.values())r.reject(i);this.pending.clear()},t.addEventListener("message",this.onMessage),t.addEventListener("error",this.onError)}request(t,e){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const i=this.nextRequestId++;return new Promise((r,s)=>{this.pending.set(i,{resolve:n=>r(n),reject:s}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:i,operation:t,payload:e})})}async close(t){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),t&&this.worker.terminate?.();const e=new Error("Browser SQLite worker is closed");for(const i of this.pending.values())i.reject(e);this.pending.clear()}}},Oe=class{constructor(t){this.transport=t}query(t,e=[]){return this.transport.request("query",{sql:t,values:e})}},je=class ae{constructor(e,i){this.transport=e,this.options=i,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,i={}){const r={storage:i.storage??"memory",databaseName:We(i.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:i.terminateWorkerOnClose??!0},s=new Pe(e);return await s.request("open",r),new ae(s,r)}identifier(e){return`"${De(e)}"`}placeholder(e){return"?"}contains(e,i){return`CAST(${e} AS TEXT) LIKE '%' || ${i} || '%'`}aggregateFunction(e){return Ne(e)}encode(e,i){return e==null?e:i?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):i?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const i=this.accessTail;let r;this.accessTail=new Promise(s=>{r=s}),await i;try{return await e()}finally{r()}}query(e,i=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:i}))}async*stream(e,i=[]){const r=await this.query(e,i);for(const s of r.rows)yield s}transaction(e){return this.exclusive(async()=>{const i=new Oe(this.transport);await i.query("BEGIN IMMEDIATE");try{const r=await e(i);return await i.query("COMMIT"),r}catch(r){try{await i.query("ROLLBACK")}catch{}throw r}})}async ensureSchema(e){for(const i of Object.values(e)){const r=this.identifier(i.table);await this.query(`CREATE TABLE IF NOT EXISTS ${r} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const s=await this.query(`PRAGMA table_info(${r})`),n=new Set(s.rows.map(o=>String(o.name)));for(const[o,u]of Object.entries(i.columns))o==="id"||o==="version"||n.has(u.columnName)||await this.query(`ALTER TABLE ${r} ADD COLUMN ${this.identifier(u.columnName)} ${Me(u.logicalType)}${u.nullable===!1?" NOT NULL":""}`)}for(const i of qe(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(i.name)} ON ${this.identifier(i.table)} (${this.identifier(i.foreignColumn)}, ${this.identifier(i.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,i){for(let r=1;r<=100;r+=1){const s=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[i]);if(!s.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[i])).rowCount===1)return"1"}catch(a){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[i])).rowCount)throw a}continue}const n=Number(s.rows[0].id),o=n+1,u=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[o,i,n]);if(u.rowCount===1)return String(o);if(u.rowCount!==0)throw new Error(`ID space update for ${i} changed ${u.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${i} after 100 optimistic-lock attempts`)}ensureIdFloor(e,i,r){return xe(e,s=>this.placeholder(s),i,r)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}},Ve=class le extends Fe{constructor(e,i){super(e,i),this.browserDriver=e}static async open(e,i,r={}){return new le(await je.open(e,r),i)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}};function Me(t){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[t]}function We(t){const e=t.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}var Ue={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},Ke=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],ee=class extends Error{constructor(t){super(`Unsupported locale: ${t}`),this.localeCode=t}},Qe={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function ze(t){if(typeof t!="string"||!t.trim())throw new ee(t);const e=t.trim().replace(/_/g,"-").toLowerCase(),i=Ke.find(s=>s.toLowerCase()===e);if(i)return i;const r=Qe[e];if(!r)throw new ee(t);return r}var te=class{constructor(e,i){if(this.data=e,this.fallback=i,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(ze)}message(e,i){return this.data.locales[e]?.messages[i]??this.fallback?.data.locales[e]?.messages[i]??this.data.locales.en?.messages[i]??this.fallback?.data.locales.en?.messages[i]??i}translate(e,i){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(i,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};te.builtin=new te(Ue);var x=class extends Error{constructor(t){super(`Check failed: ${t.map(e=>e.message??`${e.ruleId}:${e.location}`).join("; ")}`),this.violations=t,this.name="CheckException"}};function Ge(t,e){const i=t.defaultDomainRoot,r=e.defaultDomainRoot;if(i&&r&&(i.entity!==r.entity||i.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...t.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??i,constants:[...s.values()],ensure:t.ensure&&e.ensure?async n=>{await t.ensure(n),await e.ensure(n)}:e.ensure??t.ensure}}var He=class ce{constructor(e={},i={},r={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...i}),this.bootstrap=Object.freeze({defaultDomainRoot:r.defaultDomainRoot,constants:Object.freeze([...r.constants??[]]),ensure:r.ensure})}and(e){return new ce({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},Ge(this.bootstrap,e.bootstrap))}},ie=class he{constructor(e,i,r,s){this.enabledValue=e,this.cacheExpiredMillis=i,this.propagateValue=r,this.propagateCacheExpiredMillis=s}static enabled(e){return new he(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}},Xe=class V{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,i,r,s=!0){return this.facets.push({facetName:e,relationName:i,query:r.toQuery(),includeAllFacets:s}),this}clone(){const e=new V(this.entity);return e.filterCondition=this.filterCondition,e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.orderItems=[...this.orderItems],e.selectItems=[...this.selectItems],e.properties=[...this.properties],e.joins=[...this.joins],e.groupByItems=[...this.groupByItems],e.aggregateItems=this.aggregateItems.map(i=>({...i})),e.aggregationCache=this.aggregationCache,e.facets=this.facets.map(i=>({...i,query:i.query.clone()})),e.relations=this.relations.map(i=>({...i,query:i.query?.clone()})),e.relationAggregates=this.relationAggregates.map(i=>({...i,query:i.query.clone()})),e.commentText=this.commentText,e.purposeText=this.purposeText,e.idSetPaginationOptions=this.idSetPaginationOptions,e.idSetPaginationRuntimeContext=this.idSetPaginationRuntimeContext,e.topNProbeThreshold=this.topNProbeThreshold,e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,i){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(i)||i<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:i},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,i,r){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(i)||i<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(r)||r<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:i,maxIds:r},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const i=new V(this.entity);return i.filterCondition=this.filterCondition,i.commentText=this.commentText,i.purposeText=this.purposeText,i.aggregate("Count","id",e),i}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const i of this.relations)i.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,i,r="id",s="id",n=!0){return this.relations.push({name:e,query:i,localKey:r,foreignKey:s,many:n}),this}relationAggregate(e,i,r,s=!0){return this.relationAggregates.push({relationName:e,alias:i,query:r,singleResult:s}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=ie.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=ie.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,i,r){return this.aggregateItems.push({function:e,field:i,alias:r}),this}groupBy(e){return this.groupByItems.push(e),this}},I=t=>`${t.entity}\0${typeof t.id}:${String(t.id)}`,A=class{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map}set(t,e,i){if(!e.trim())throw new TypeError("field is required");const r=I(t),s=this.changes.get(r)??{key:Object.freeze({...t}),values:{}};s.values[e]=i,this.changes.set(r,s)}snapshot(){return[...this.changes.values()].map(t=>({key:Object.freeze({...t.key}),values:Object.freeze({...t.values})}))}change(t){return Object.freeze({...this.changes.get(I(t))?.values??{}})}mergeFrom(t){if(t!==this){for(const e of t.snapshot())for(const[i,r]of Object.entries(e.values))this.set(e.key,i,r);for(const e of t.newKeys.values())this.markAsNew(e);for(const e of t.deletedKeys.values())this.markAsDeleted(e);for(const e of t.snapshotVersions())this.setOriginalVersion(e.key,e.version)}}snapshotVersions(){return[...this.originalVersions.values()]}rekey(t,e){const i=I(t),r=I(e);if(i===r)return;const s=this.changes.get(i);if(s){this.changes.delete(i);for(const[o,u]of Object.entries(s.values))this.set(e,o,u)}const n=this.originalVersions.get(i);n!==void 0&&(this.originalVersions.delete(i),this.originalVersions.set(r,{key:Object.freeze({...e}),version:n.version})),this.newKeys.delete(i)&&this.newKeys.set(r,Object.freeze({...e})),this.deletedKeys.delete(i)&&this.deletedKeys.set(r,Object.freeze({...e}))}clearEntity(t){const e=I(t);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e)}setOriginalVersion(t,e){this.originalVersions.set(I(t),{key:Object.freeze({...t}),version:e})}originalVersion(t){return this.originalVersions.get(I(t))?.version}markAsNew(t){this.newKeys.set(I(t),Object.freeze({...t}))}isNew(t){return this.newKeys.has(I(t))}markAsDeleted(t){const e=I(t);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...t}))}isDeleted(t){return this.deletedKeys.has(I(t))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear()}};function de(t){const e=t.split("_");return e[0]+e.slice(1).map(i=>i?i[0].toUpperCase()+i.slice(1):"").join("")}function Ye(t,e){if(e==="snake_case")return t;const i=de(t);return e==="camelCase"||!i?i:i[0].toUpperCase()+i.slice(1)}function Je(t){return t.replace(/~/g,"~0").replace(/\//g,"~1")}var S=class L{constructor(e){this.segments=e}static root(){return new L([])}static property(e){return L.root().property(e)}property(e){return new L([...this.segments,{kind:"property",name:e}])}index(e){return new L([...this.segments,{kind:"index",index:e}])}prefixedBy(e){return new L([...e.segments,...this.segments])}modelPath(){return this.render(e=>e)}nativePath(){return this.render(de)}instancePath(e="camelCase"){return this.segments.map(i=>i.kind==="index"?String(i.index):Je(Ye(i.name,e))).map(i=>`/${i}`).join("")}toString(){return this.nativePath()}render(e){let i="";for(const r of this.segments)r.kind==="index"?i+=`[${r.index}]`:i+=`${i?".":""}${e(r.name)}`;return i}},q=class M extends Array{static get[Symbol.species](){return Array}constructor(e=[],i={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,M.prototype),this.totalCount=i.totalCount,this.aggregations=i.aggregations??{},this.summary=i.summary??{},this.facets=i.facets??{},this.isLoaded=i.isLoaded??!0}static empty(){return new M([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,i){return this.facets[e]=i,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}};function Ze(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function W(t){if(t&&typeof t=="object"){const e=t;return e.id??e.Id}return t}function et(t,e){const i=Ze(e);for(const r of[e,`${e}Id`,i,`${i}_id`]){const s=W(t[r]);if(s!=null)return s}}async function me(t,e,i,r){const s={};for(const n of r){let o;if(t.executeFacetMembership)o=await t.executeFacetMembership(e(i.clone()),n.relationName);else{const l=i.clone();l.facets=[],l.relations=[],l.orderItems=[],l.aggregateItems=[],l.groupByItems=[],l.offsetValue=0,l.limitValue=0,l.selectItems=[n.relationName];const m=await t.executeQuery(e(l));o=new Map;for(const d of m){const p=et(d,n.relationName);if(p==null)continue;const f=String(p);o.set(f,(o.get(f)??0)+1)}}const u=n.query.clone();u.facets=[];const a=u.aggregateItems.filter(l=>String(l.function).toLowerCase()==="count").map(l=>String(l.alias));u.aggregateItems=[],u.groupByItems=[];const h=(await t.executeQuery(e(u))).map(l=>{const m=o.get(String(W(l.id??l.Id)))??0,d={...l};for(const p of a)d[p]=m;return d}).filter(l=>n.includeAllFacets||o.has(String(W(l.id??l.Id))));s[n.facetName]=new q(h)}return s}class R extends Xe{orderBy(e,i){return this.order({field:e,expr:null,direction:i==="desc"?"Desc":"Asc"})}relationQuery(e,i,r="id",s="id",n=!0){return this.relations.push({name:e,query:i,localKey:r,foreignKey:s,many:n}),this}}class b{static teaqlTemporaryId=0;id;title;description;platform;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--b.teaqlTemporaryId,writable:!0,enumerable:!1}),e){const r={...e};Object.assign(this,r),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof v?e.platform:v.fromRecord(e.platform),this.markLoaded("platform"))}const i=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(i):this.version!==void 0&&this._root.setOriginalVersion(i,Number(this.version))}teaqlEntityKey(){return{entity:"WorkItem",id:this._ledgerId}}teaqlAttachRoot(e){return this._root!==e&&(e.mergeFrom(this._root),this._root=e),this}static fromRecord(e,i){const r=new b(e);return i?r.teaqlAttachRoot(i):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const i of e)this._loadedFields.add(i);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new b({id:String(e)})}static teaqlBootstrapNew(e){return new b().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const i=e.requireResource("dataService");return i.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,i),this.teaqlSaveWithinGraph(e,i)))}teaqlPreflightGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"title",canonical:"title"},{member:"description",canonical:"description"},{member:"platform",canonical:"platform"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new x([{ruleId:"invalid_type",location:S.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}i.preflightMutation({entity:"WorkItem",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root})}async teaqlSaveWithinGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"WorkItem",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},o=await i.executeMutation(n);for(const[h,l]of Object.entries(n.payload))h!=="id"&&h!=="version"&&this._root.set(this.teaqlEntityKey(),h,l);if(!o.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},a=this.teaqlEntityKey();Object.assign(this,o.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();return this._root.rekey(a,c),i.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(c,a)}),this._loadedFields=new Set(Object.keys(o.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update"),i.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.setOriginalVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,title:this.title,description:this.description,platform:this.platform,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateTitle(e){return this.title=e,this.markLoaded("title"),this._root.set(this.teaqlEntityKey(),"title",e),this}updateDescription(e){return this.description=e,this.markLoaded("description"),this._root.set(this.teaqlEntityKey(),"description",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}}class v{static teaqlTemporaryId=0;id;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--v.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_workItemList",{value:[],writable:!0,enumerable:!1}),e){const r={...e};delete r.workItemList,Object.assign(this,r),Array.isArray(e.workItemList)&&(this._workItemList=e.workItemList.map(s=>s instanceof b?s:b.fromRecord(s)),this.markLoaded("workItemList"))}const i=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(i):this.version!==void 0&&this._root.setOriginalVersion(i,Number(this.version))}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const i of this._workItemList)i.teaqlAttachRoot(e);return this}static fromRecord(e,i){const r=new v(e);return i?r.teaqlAttachRoot(i):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const i of e)this._loadedFields.add(i);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new v({id:String(e)})}static teaqlBootstrapNew(e){return new v().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const i=e.requireResource("dataService");return i.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,i),this.teaqlSaveWithinGraph(e,i)))}teaqlPreflightGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new x([{ruleId:"invalid_type",location:S.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}i.preflightMutation({entity:"Platform",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root});for(const[s,n]of this._workItemList.entries()){n.teaqlAttachRoot(this._root),n.updatePlatform(this),n.auditAs(this._comment);try{n.teaqlPreflightGraph(e,i)}catch(o){if(!(o instanceof x))throw o;const u=S.property("work_item_list").index(s);throw new x(o.violations.map(a=>({...a,location:a.location.prefixedBy(u)})))}}}async teaqlSaveWithinGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"Platform",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},o=await i.executeMutation(n);for(const[h,l]of Object.entries(n.payload))h!=="id"&&h!=="version"&&this._root.set(this.teaqlEntityKey(),h,l);if(!o.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},a=this.teaqlEntityKey();Object.assign(this,o.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(a,c),i.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(c,a)}),this._loadedFields=new Set(Object.keys(o.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update");for(const[h,l]of this._workItemList.entries()){l.teaqlAttachRoot(this._root),l.updatePlatform(this),l.auditAs(this._comment);try{await l.teaqlSaveWithinGraph(e,e.requireResource("dataService"))}catch(m){if(!(m instanceof x))throw m;const d=S.property("work_item_list").index(h);throw new x(m.violations.map(p=>({...p,location:p.location.prefixedBy(d)})))}}return i.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.setOriginalVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}workItemList(){return this._workItemList}}class re{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new R("Platform"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new tt(i=>this.executeForListInternal(i),i=>this.executeForRowsInternal(i),(i,r,s)=>this.executeForPageInternal(i,r,s),(i,r)=>this.executeForStreamInternal(i,r),()=>this.limit(1),i=>this.comment(i),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,i){return this.query.optimizeForContinuousPageFetchWith(e,i),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,i,r){return this.query.optimizePaginationWithIdSetConfig(e,i,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectWorkItemListWith(e){return this.query.relationQuery("workItemList",e.toQuery(),"id","platform",!0),this}haveWorkItems(){return this.withWorkItemListMatching({toQuery:()=>new R("WorkItem")})}haveNoWorkItems(){return this.withoutWorkItemListMatching({toQuery:()=>new R("WorkItem")})}withWorkItemListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutWorkItemListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}countWorkItems(){return this.countWorkItemsAs("countWorkItems")}countWorkItemsAs(e){const i=new R("WorkItem").filter({version:{$gte:1}});return this.countWorkItemsWith(e,{toQuery:()=>i})}countWorkItemsWith(e,i){return i.toQuery().aggregate("Count","id",e),this.query.relationAggregate("workItemList",e,i.toQuery(),!0),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,i){return this.filters.push({id:{$between:[e,i]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,i){return this.filters.push({name:{$between:[e,i]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,i){return this.filters.push({version:{$between:[e,i]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),r=await i.executeQuery(e.prepareQuery(this.query)),s=new A,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:r.map(a=>a instanceof v?a:v.fromRecord(a,s)),u=new q(o);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await me(i,a=>e.prepareQuery(a),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService");return new q(await i.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,i,r){this.ensureIntent(),this.query.offset(i).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),a=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:o??await s.executeCount(this.query),c=new A,h=new q(u.map(l=>l instanceof v?l:v.fromRecord(l,c)));return h.totalCount=a,{data:h,totalCount:a,offset:i,limit:r}}async*executeForStreamInternal(e,i){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new A;for await(const n of r.executeForStream(this.query,i))for(const o of n)yield o instanceof v?o:v.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class tt{constructor(e,i,r,s,n,o,u){this.execute=e,this.executeRows=i,this.page=r,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new v}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,i,r){return this.ensureIntent(),this.page(e,i,r)}executeForStream(e,i=1e3){return this.ensureIntent(),this.stream(e,i)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class se{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new R("WorkItem"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new it(i=>this.executeForListInternal(i),i=>this.executeForRowsInternal(i),(i,r,s)=>this.executeForPageInternal(i,r,s),(i,r)=>this.executeForStreamInternal(i,r),()=>this.limit(1),i=>this.comment(i),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,i){return this.query.optimizeForContinuousPageFetchWith(e,i),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,i,r){return this.query.optimizePaginationWithIdSetConfig(e,i,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","title","description","platform","version"]),this}selectId(){return this.query.select(["id"]),this}selectTitle(){return this.query.select(["title"]),this}selectDescription(){return this.query.select(["description"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,i){return this.filters.push({id:{$between:[e,i]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withTitleContaining(e){return this.filters.push({title:{$contains:e}}),this}withTitleIs(e){return this.filters.push({title:{$eq:e}}),this}withTitleIsNot(e){return this.filters.push({title:{$ne:e}}),this}withTitleIn(...e){return this.filters.push({title:{$in:e}}),this}withTitleNotIn(...e){return this.filters.push({title:{$notIn:e}}),this}withTitleGreaterThan(e){return this.filters.push({title:{$gt:e}}),this}withTitleGreaterThanOrEqualTo(e){return this.filters.push({title:{$gte:e}}),this}withTitleLessThan(e){return this.filters.push({title:{$lt:e}}),this}withTitleLessThanOrEqualTo(e){return this.filters.push({title:{$lte:e}}),this}withTitleBetween(e,i){return this.filters.push({title:{$between:[e,i]}}),this}withTitleIsKnown(){return this.filters.push({title:{$isNull:!1}}),this}withTitleIsUnknown(){return this.filters.push({title:{$isNull:!0}}),this}withTitleNotContaining(e){return this.filters.push({title:{$notContains:e}}),this}withTitleStartingWith(e){return this.filters.push({title:{$startsWith:e}}),this}withTitleNotStartingWith(e){return this.filters.push({title:{$notStartsWith:e}}),this}withTitleEndingWith(e){return this.filters.push({title:{$endsWith:e}}),this}withTitleNotEndingWith(e){return this.filters.push({title:{$notEndsWith:e}}),this}withTitleSoundingLike(e){return this.filters.push({title:{$soundLike:e}}),this}withDescriptionContaining(e){return this.filters.push({description:{$contains:e}}),this}withDescriptionIs(e){return this.filters.push({description:{$eq:e}}),this}withDescriptionIsNot(e){return this.filters.push({description:{$ne:e}}),this}withDescriptionIn(...e){return this.filters.push({description:{$in:e}}),this}withDescriptionNotIn(...e){return this.filters.push({description:{$notIn:e}}),this}withDescriptionGreaterThan(e){return this.filters.push({description:{$gt:e}}),this}withDescriptionGreaterThanOrEqualTo(e){return this.filters.push({description:{$gte:e}}),this}withDescriptionLessThan(e){return this.filters.push({description:{$lt:e}}),this}withDescriptionLessThanOrEqualTo(e){return this.filters.push({description:{$lte:e}}),this}withDescriptionBetween(e,i){return this.filters.push({description:{$between:[e,i]}}),this}withDescriptionIsKnown(){return this.filters.push({description:{$isNull:!1}}),this}withDescriptionIsUnknown(){return this.filters.push({description:{$isNull:!0}}),this}withDescriptionNotContaining(e){return this.filters.push({description:{$notContains:e}}),this}withDescriptionStartingWith(e){return this.filters.push({description:{$startsWith:e}}),this}withDescriptionNotStartingWith(e){return this.filters.push({description:{$notStartsWith:e}}),this}withDescriptionEndingWith(e){return this.filters.push({description:{$endsWith:e}}),this}withDescriptionNotEndingWith(e){return this.filters.push({description:{$notEndsWith:e}}),this}withDescriptionSoundingLike(e){return this.filters.push({description:{$soundLike:e}}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,i){return this.filters.push({version:{$between:[e,i]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByTitleAscending(){return this.query.orderBy("title","asc"),this}orderByTitleDescending(){return this.query.orderBy("title","desc"),this}orderByDescriptionAscending(){return this.query.orderBy("description","asc"),this}orderByDescriptionDescending(){return this.query.orderBy("description","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByTitle(){return this.query.groupBy("title"),this}groupByTitleAs(e){return this.query.groupBy("title"),this}groupByDescription(){return this.query.groupBy("description"),this}groupByDescriptionAs(e){return this.query.groupBy("description"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,i,r=!0){return this.query.facetBy(e,"platform",i,r),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),r=await i.executeQuery(e.prepareQuery(this.query)),s=new A,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:r.map(a=>a instanceof b?a:b.fromRecord(a,s)),u=new q(o);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await me(i,a=>e.prepareQuery(a),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService");return new q(await i.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,i,r){this.ensureIntent(),this.query.offset(i).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),a=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:o??await s.executeCount(this.query),c=new A,h=new q(u.map(l=>l instanceof b?l:b.fromRecord(l,c)));return h.totalCount=a,{data:h,totalCount:a,offset:i,limit:r}}async*executeForStreamInternal(e,i){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new A;for await(const n of r.executeForStream(this.query,i))for(const o of n)yield o instanceof b?o:b.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class it{constructor(e,i,r,s,n,o,u){this.execute=e,this.executeRows=i,this.page=r,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new b}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,i,r){return this.ensureIntent(),this.page(e,i,r)}executeForStream(e,i=1e3){return this.ensureIntent(),this.stream(e,i)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class K{static platforms(){return new re(!1)}static platformsWithMinimalFields(){return new re(!0)}static workItems(){return new se(!1)}static workItemsWithMinimalFields(){return new se(!0)}}const pe={Platform:{table:"platform_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}};async function rt(t){let e=(await K.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(t))[0];e||(e=v.teaqlBootstrapNew("1"),e.updateName("Runtime Example"),await e.auditAs("create generated Domain Root Platform").save(t)),t.withActiveRoot({entity:"Platform",id:e.id})}const st=new He(pe,{Platform:{checkAndFix(t,e,i){t.getResource("fixTime"),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&i.push({ruleId:"required",location:S.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&i.push({ruleId:"max_length",location:S.property("name"),inputValue:e.payload.name,systemValue:100})}},WorkItem:{checkAndFix(t,e,i){t.getResource("fixTime"),(e.action==="Create"&&e.payload.title===void 0||e.payload.title===null)&&i.push({ruleId:"required",location:S.property("title")}),e.payload.title!=null&&!([...String(e.payload.title)].length>=1)&&i.push({ruleId:"min_length",location:S.property("title"),inputValue:e.payload.title,systemValue:1}),e.payload.title!=null&&[...String(e.payload.title)].length>80&&i.push({ruleId:"max_length",location:S.property("title"),inputValue:e.payload.title,systemValue:80}),e.payload.description!=null&&[...String(e.payload.description)].length>100&&i.push({ruleId:"max_length",location:S.property("description"),inputValue:e.payload.description,systemValue:100}),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&i.push({ruleId:"required",location:S.property("platform")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Runtime Example"}},constants:[],ensure:rt}),Q=document.querySelector("#status"),nt=document.querySelector("#result"),U=document.querySelector("#persist"),O=document.querySelector("#reset");let $;const fe=localStorage.getItem("teaql-browser-storage")==="opfs"?"opfs":"memory";U.checked=fe==="opfs";async function ut(t){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),i=await Ve.open(e,{...pe},{storage:t,databaseName:"teaql-browser-example.sqlite3"});i.install(st);const r=new oe().insertResource("dataService",i);return i.setUserContext(r),await r.ensureSchema(),{client:i,context:r}}async function ge({context:t}){if(!(await K.workItemsWithMinimalFields().comment("what: detect existing browser demo records").purpose("why: keep generated mutation bootstrap idempotent").executeForList(t)).length)for(const i of["Evaluate semantic model","Generate typed library","Verify browser runtime"])await new b().updateTitle(i).updatePlatform("1").auditAs("seed deterministic browser demo data").save(t)}async function Ee(t){const e=await K.workItems().selectTitle().orderByIdAscending().limit(20).comment("what: load browser-local work items").purpose("why: prove the generated Q API runs without a backend").executeForList(t.context);nt.textContent=JSON.stringify(e,null,2),Q.textContent=`${t.client.storage.toUpperCase()} · ${e.length} rows · ready`}async function ye(t){Q.textContent=`Opening ${t.toUpperCase()} SQLite/WASM…`;const e=$;$=void 0,await e?.client.close();const i=await ut(t);$=i,await ge(i),await Ee(i)}U.addEventListener("change",()=>{const t=U.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",t),ye(t).catch(z)});O.addEventListener("click",async()=>{if($){O.disabled=!0;try{await $.client.reset($.context),await ge($),await Ee($)}catch(t){z(t)}finally{O.disabled=!1}}});function z(t){const e=t instanceof Error?t:new Error(String(t));Q.textContent=`${e.name}: ${e.message}`}ye(fe).catch(z); diff --git a/assets/index-BMClFIER.css b/assets/index-BMClFIER.css deleted file mode 100644 index c4e7e4a90b396223654574378a4b8e189f0a7e23..0000000000000000000000000000000000000000 --- a/assets/index-BMClFIER.css +++ /dev/null @@ -1 +0,0 @@ -:root{font:16px/1.5 Inter,system-ui,sans-serif;color:#e8edf5;background:#090b10}body{margin:0}main{width:min(760px,calc(100% - 40px));margin:10vh auto}.eyebrow{color:#d9ff52;font-size:12px;font-weight:800;letter-spacing:.16em}h1{margin:8px 0;font-size:clamp(36px,7vw,68px);letter-spacing:-.05em}.controls{display:flex;gap:18px;align-items:center;margin:32px 0}button{border:0;border-radius:5px;padding:10px 14px;background:#d9ff52;font-weight:800}#status{color:#aab4c4}pre{min-height:260px;padding:22px;overflow:auto;border:1px solid #2b323e;border-radius:8px;background:#11151c;color:#c6d1df} diff --git a/assets/index-CSFBt0NB.js b/assets/index-CSFBt0NB.js deleted file mode 100644 index 73e07c14a5047bac0f9b3ddcf4ea310a8b984992..0000000000000000000000000000000000000000 --- a/assets/index-CSFBt0NB.js +++ /dev/null @@ -1,29 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))i(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function t(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function i(s){if(s.ep)return;s.ep=!0;const n=t(s);fetch(s.href,n)}})();var Fr=r=>{throw TypeError(r)},Mr=(r,e,t)=>e.has(r)||Fr("Cannot "+t),Q=(r,e,t)=>(Mr(r,e,"read from private field"),t?t.call(r):e.get(r)),Y=(r,e,t)=>e.has(r)?Fr("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),H=(r,e,t,i)=>(Mr(r,e,"write to private field"),e.set(r,t),t),Ki={},zi={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},Gi=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],fr=class extends Error{constructor(r){super(`Unsupported locale: ${r}`),this.localeCode=r}},Yi={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function jr(r){if(typeof r!="string"||!r.trim())throw new fr(r);const e=r.trim().replace(/_/g,"-").toLowerCase(),t=Gi.find(s=>s.toLowerCase()===e);if(t)return t;const i=Yi[e];if(!i)throw new fr(r);return i}var jt=class{constructor(e,t){if(this.data=e,this.fallback=t,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(jr)}message(e,t){return this.data.locales[e]?.messages[t]??this.fallback?.data.locales[e]?.messages[t]??this.data.locales.en?.messages[t]??this.fallback?.data.locales.en?.messages[t]??t}translate(e,t){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(t,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};jt.builtin=new jt(zi);var Hi=jt,Vr=Symbol("teaql.context.schema-capability");function me(r){return Object.freeze(r.map(e=>Object.freeze({...e})))}var mt,ft,Xi=class{constructor(r,e){Y(this,mt),Y(this,ft),H(this,mt,r),H(this,ft,Object.freeze({...e})),Object.freeze(this)}recover(){const r=[];let e=this;for(;e;)r.push(Q(e,ft)),e=Q(e,mt);return me(r.reverse())}};mt=new WeakMap;ft=new WeakMap;function Ji(r,e,t,i,s){const n=r?s:i;if(r&&(typeof n!="string"||new RegExp("^\\p{White_Space}*$","u").test(n)))return r;const o=String(t),a=/^(0|[1-9][0-9]*)$/.test(o)&&BigInt(o)<=18446744073709551615n?t:void 0;return new Xi(r,{kind:"auditReason",name:e,entityId:a,detail:n})}var Zi=new Set(["comment","purpose","auditReason"]),Rt=r=>!new RegExp("^\\p{White_Space}*$","u").test(r);function Vt(r,e,t){const i=o=>{for(let a=r.length-1;a>=0;a--)if(r[a].kind===o)return r[a].detail??""},s=["operation","provider","sql"].every(o=>r.some(a=>a.kind===o));let n;if(s)n=r.filter(o=>!Zi.has(o.kind));else{const o=r.find(u=>Rt(u.name))?.name??"unknown";let a=o;if(t!=="select")for(const u of r)u.kind==="entity"&&Rt(u.name)&&(a=u.name);n=[{kind:"operation",name:o,detail:t==="select"?"query":"mutation"},{kind:t==="select"?"request":"entity",name:t==="select"?o:a,detail:""},...r.filter(u=>u.kind==="relation"),{kind:"provider",name:Rt(e)?e:"unknown",detail:""},{kind:"sql",name:t,detail:""}]}return Object.freeze({tracePath:me(n),comment:i("comment"),purpose:i("purpose"),auditReason:i("auditReason")})}function Wr(r,e,t){return me([{kind:"comment",name:r,detail:e},{kind:"purpose",name:r,detail:t}])}function es(r,e,t,i){if(i&&!r.trim())throw new Error("Missing SQL template");let s=0;const n=new Set,o=h=>{if(h<0||h>=e.length)throw new Error("SQL bind count mismatch");return n.add(h),i?i(h):Ur(e[h],t)};let a="",u="sql";for(let h=0;h=0&&f=0&&ft.toString(16).padStart(2,"0")).join("")}'`:le(typeof r=="object"?JSON.stringify(r):String(r))}function le(r){return`'${r.replace(/'/g,"''")}'`}var ts="TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS",rs="I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK",bt="[REDACTED]",kt="[REDACTED SQL; NOT REPLAYABLE]",is=`-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN -`,pr=!1;function ss(r){const e=Array.from(r);return e.length<8||/^[0-9]+$/.test(r)?"*".repeat(e.length):e.slice(0,2).join("")+"*".repeat(e.length-4)+e.slice(-2).join("")}function ns(){const e=Ki?.[ts]===rs;return e&&!pr&&(pr=!0,console.warn("TeaQL: sensitive plaintext logging enabled; application data may be written to disk. Authentication secrets remain redacted.")),e}function Ze(r){const e=r.toLowerCase().replace(/[^a-z0-9]/g,"");return["password","passwd","passphrase","privatekey","secret","accesstoken","refreshtoken","idtoken","apikey","authorization","credential","sessiontoken","magiclinktoken"].some(t=>e.includes(t))}function Wt(r){return Array.isArray(r)?r.some(Wt):r&&typeof r=="object"?Object.entries(r).some(([e,t])=>Ze(e)||Wt(t)):!1}function ye(r){return r==null||r===""?[]:Array.isArray(r)?r.flatMap(ye):r instanceof Date?[r.toISOString()]:typeof r=="object"?Object.values(r).flatMap(ye):[String(r)]}function Je(r,e){return[...new Set(e)].sort((t,i)=>i.length-t.length).reduce((t,i)=>t?.split(i).join(bt),r)}var xt=new WeakMap,gr=new WeakMap,Kr=new WeakMap;function yr(r,e,t=[]){Kr.set(r,{bindings:e?re(e):void 0,intentValues:Object.freeze(t.map(et))})}function Lt(r){const e=r.parameterLogPolicies,t=!!e&&e.length===r.parameters.length,i=Ze(r.parameterizedSQL)&&(r.sqlOrigin!=="generated"||!t);return r.parameters.map((s,n)=>{if(i||Wt(s))return"credential";const o=t?e[n]:void 0;return o==="plain"||o==="masked"||o==="credential"?o:"unknown"})}function Ut(r,e){return r==="credential"||r==="unknown"||!e&&r!=="plain"}function wr(r){if(!r)return[];const e=Lt(r);return r.parameters.flatMap((t,i)=>Ut(e[i],!1)?ye(t):[])}function et(r){return r instanceof Date?new Date(r.getTime()):r instanceof Uint8Array?new Uint8Array(r):Array.isArray(r)?Object.freeze(r.map(et)):r&&typeof r=="object"?Object.freeze(Object.fromEntries(Object.entries(r).map(([e,t])=>[e,et(t)]))):r}function re(r,e){const t=e?[e,r]:[r];return Object.freeze({parameterizedSQL:"",sqlOrigin:"generated",parameters:Object.freeze(t.flatMap(i=>i.parameters.map(et))),parameterLogPolicies:Object.freeze(t.flatMap(Lt))})}function Kt(r){return r==null?null:Array.isArray(r)?r.map(Kt):r&&typeof r=="object"&&"type"in r?Kt(r.value):typeof r=="object"&&!(r instanceof Date)?bt:ss(r instanceof Date?r.toISOString():String(r))}function zr(r,e,t=[]){const i=ns()&&r.logMode!=="masked",s=xt.get(r);if(s!==void 0&&(!s||i))return r;const n=gr.get(r);if(!i&&n)return n;const o=zt(r,i,e,t);if(xt.set(o,i),i){const a=zt(r,!1,e,t);xt.set(a,!1),gr.set(o,a)}return o}function zt(r,e,t,i=[]){const s=Kr.get(r);s?.bindings&&(t=re(s.bindings,t)),s&&(i=[...i,...s.intentValues]);const n=r.parameterLogPolicies,o=!n||n.length===r.parameters.length,a=Ze(r.parameterizedSQL)&&(r.sqlOrigin!=="generated"||!n||!o),u=Lt(r),h=u.map(A=>Ut(A,e)),l=r.parameters.flatMap((A,k)=>h[k]?ye(A):[]);if(t){const A=Lt(t);l.push(...t.parameters.flatMap((k,M)=>Ut(A[M],e)?ye(k):[]))}const d=[...l,...i.flatMap(ye)],c=!e&&r.logMode==="debug-plaintext"&&!t,f=A=>c&&A?bt:Je(A,d),y=r.parameters.map((A,k)=>h[k]?u[k]==="masked"?Kt(A):bt:et(A)),O=r.parameterizedSQL.replace(/\$[0-9]+|@p[0-9]+/gi,"?"),w=(!e||a)&&r.sqlOrigin!=="generated"&&/['"`$]|--|\/\*|\b\d+\b|:[A-Za-z_]/.test(O),I=r.databaseKind??"sqlite";let S=kt,R=w?"untrusted-literal-sql":o?void 0:"policy-count-mismatch";if(!w&&o)try{S=es(r.parameterizedSQL,y,I,A=>Ur(y[A],I)+(h[A]?" /* masked */":"")),S=(e?h.some(Boolean)?`-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN; PARTIALLY MASKED; NOT REPLAYABLE -`:is:`-- TeaQL MASKED; NOT REPLAYABLE -`)+S}catch{S=kt,R="unsupported-or-mismatched-bindings"}return Object.freeze({...r,...r.statements?{statements:Object.freeze(r.statements.map(A=>zt(A,e,re(r,t),i)))}:{},parameterizedSQL:w?kt:r.sqlOrigin==="generated"?r.parameterizedSQL:Je(r.parameterizedSQL,l),parameters:Object.freeze(y),parameterLogPolicies:Object.freeze(u),maskedParameters:Object.freeze(h),logMode:e?"debug-plaintext":"masked",omissionReason:R,debugSQL:S,comment:f(r.comment),purpose:f(r.purpose),auditReason:f(r.auditReason),...r.traceChain?{traceChain:Object.freeze(r.traceChain.map(A=>Object.freeze(Object.fromEntries(Object.entries(A).map(([k,M])=>[k,k!=="entityId"&&typeof M=="string"?f(M):M])))))}:{},resultSummary:r.resultCount!==void 0?`${r.resultCount} rows returned`:r.affectedRows!==void 0?`${r.affectedRows} rows affected`:Je(r.resultSummary,l),tracePath:Object.freeze(r.tracePath.map(A=>Object.freeze(Object.fromEntries(Object.entries(A).map(([k,M])=>[k,k!=="entityId"&&typeof M=="string"?f(M):M]))))),...r.mutationLineage?{mutationLineage:Object.freeze(r.mutationLineage.map(A=>Object.freeze(Object.fromEntries(Object.entries(A).map(([k,M])=>[k,k!=="entityId"&&typeof M=="string"?f(M):M])))))}:{}})}var tt=new WeakMap,Ct=new WeakMap;function Or(r){return Ct.get(r)}function os(r,e){Ct.set(r,e)}function as(r){return tt.get(r)}function Fe(r,e){tt.set(e,tt.get(r)??Pe(r))}function Pe(r,e=new Map){if(!r||typeof r!="object")return r;if(e.has(r))return e.get(r);if(r instanceof Date)return new Date(r.getTime());if(r instanceof Uint8Array)return new Uint8Array(r);const t=Array.isArray(r)?[]:Object.create(Object.getPrototypeOf(r));e.set(r,t);for(const n of Reflect.ownKeys(r)){const o=Object.getOwnPropertyDescriptor(r,n);"value"in o&&o.enumerable&&(o.value=Pe(o.value,e)),Object.defineProperty(t,n,o)}const i=tt.get(r);i&&tt.set(t,i);const s=Ct.get(r);return s&&Ct.set(t,s),t}var pt,ue=class{constructor(r={}){Y(this,pt),H(this,pt,Pe(r)),Object.freeze(this)}values(){return Pe(Q(this,pt))}};pt=new WeakMap;var vr=new WeakMap,Dt=new WeakMap,Gt=new WeakMap,Gr=new WeakMap;function Yr(r){if(!["named-count","facet","relation-count","relation-select","aggregate","pagination"].includes(r.kind)||r.method!==void 0&&!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r.method)||r.alias!==void 0&&typeof r.alias!="string"||r.relation!==void 0&&typeof r.relation!="string")throw new Error("QUERY_OPERATION_INVALID: invalid generated operation descriptor");return Object.freeze({kind:r.kind,method:r.method,alias:r.alias,relation:r.relation})}function us(r){const e=Yr(r),t=i=>"'"+i.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+"'";return e.method?e.method+"("+(e.alias!==void 0?t(e.alias):e.kind==="relation-select"?"...":"")+")":"framework: "+e.kind+(e.relation?" "+e.relation:"")+(e.alias!==void 0?" "+t(e.alias):"")}var Ne=Symbol("runtime request binding"),hs=class extends Error{constructor(r,e,t){super(`${r}: ${t} request requires a non-blank ${e}; supply it at the request entry point`),this.code=r,this.field=e,this.requestKind=t,this.name="RequestIntentError"}};function Me(r,e,t){if(typeof r!="string"||new RegExp("^\\p{White_Space}*$","u").test(r))throw new hs(e==="comment"?"REQUEST_COMMENT_REQUIRED":"QUERY_PURPOSE_REQUIRED",e,t);return r}var gt,yt,_e=class{constructor(r,e){Y(this,gt),Y(this,yt),H(this,gt,Me(r,"comment","query")),H(this,yt,Me(e,"purpose","query")),Object.freeze(this)}get comment(){return Q(this,gt)}get purpose(){return Q(this,yt)}};gt=new WeakMap;yt=new WeakMap;var Te,he=class{constructor(r){Y(this,Te),H(this,Te,Me(r,"comment","mutation")),Object.freeze(this)}get comment(){return Q(this,Te)}get auditReason(){return Q(this,Te)}readbackIntent(){return new _e(Q(this,Te),"verify persisted mutation result")}};Te=new WeakMap;var ve,Re,wt,Ot,vt,qt,qe,ls=class Ie{constructor(e,t,i){Y(this,ve),Y(this,Re),Y(this,wt),Y(this,Ot),Y(this,vt),Y(this,qt),Y(this,qe);const s=e;if(H(this,ve,t===void 0?new _e(s?._comment??s?.commentText,s?._purpose??s?.purposeText):new _e(t?.comment,t?.purpose)),i&&i[Ne]!==!0)throw new Error("QUERY_REQUEST_OWNERSHIP_INVALID: request binding is runtime-owned");const n=Or(e),o=n instanceof Ie&&n.intent.comment===Q(this,ve).comment&&n.purpose===Q(this,ve).purpose?n:void 0;H(this,qe,i?.invocation??(i?.parent?Q(i.parent,qe):void 0)??(o?Q(o,qe):void 0)??Object.freeze({})),H(this,wt,i?i.parent:o?.parentRequest),H(this,Ot,Me(i?.comment??o?.comment??Q(this,ve).comment,"comment","query")),H(this,vt,i?.name??o?.requestName??String(s.entity??"query")),H(this,qt,i?.operation??o?.operation),H(this,Re,Pe(e));const a=Q(this,Re);for(const[u,h]of[["commentText",this.intent.comment],["purposeText",this.purpose],["_comment",this.intent.comment],["_purpose",this.purpose]])Object.defineProperty(a,u,{value:h,enumerable:!u.startsWith("_"),configurable:!0,writable:!1});Dt.set(a,me(i?.source??o?.traceSource??Dt.get(e)??Wr(String(s.entity),this.intent.comment,this.purpose))),os(a,this),Object.freeze(this)}get intent(){return Q(this,ve)}get query(){return Q(this,Re)}get comment(){return Q(this,Ot)}get purpose(){return Q(this,ve).purpose}get traceSource(){return Dt.get(Q(this,Re))}get parentRequest(){return Q(this,wt)}get rootRequest(){let e=this;for(;e.parentRequest;)e=e.parentRequest;return e}get requestName(){return Q(this,vt)}get operation(){return Q(this,qt)}get traceChain(){const e=[];for(let t=this;t;t=t.parentRequest)e.push({kind:"comment",name:t.requestName,detail:t.comment});return me([{kind:"purpose",name:this.rootRequest.requestName,detail:this.purpose},...e.reverse()])}withQuery(e){const t=Or(e);if(t instanceof Ie&&Q(t,qe)!==Q(this,qe))throw new Error("QUERY_SCOPE_OWNER_MISMATCH: replacement belongs to another query invocation");return new Ie(e,this.intent,{[Ne]:!0,parent:this.parentRequest,comment:this.comment,name:this.requestName,operation:this.operation,source:this.traceSource,invocation:Q(this,qe)})}deriveOperation(e,t){const i=Yr(t);return new Ie(e,this.intent,{[Ne]:!0,parent:this,comment:us(i),name:String(e.entity??this.requestName),operation:i,source:this.traceSource})}deriveHelper(e,t){return new Ie(e,this.intent,{[Ne]:!0,parent:this,comment:Me(t,"comment","query"),name:String(e.entity??this.requestName),source:this.traceSource})}derive(e,t,i){return this.deriveOperation(this.query,i??{kind:"relation-select",relation:t}).deriveChild(e,t)}deriveAggregate(e,t,i){const s=this.parentRequest?.operation?.kind==="facet"?this.parentRequest:void 0,n=s?s.deriveHelper(e,"aggregate "+s.operation.relation):this.deriveOperation(e,i),o=[...this.traceSource,{kind:"relation",name:t,detail:`${String(this.query.entity)}.${t}`}],a=new Ie(e,this.intent,{[Ne]:!0,parent:n.parentRequest,comment:n.comment,name:n.requestName,operation:n.operation,source:o});return(e._comment??e.commentText)===void 0?a:a.deriveChild(e)}deriveChild(e,t,i){const s=e,n=s._comment??s.commentText;return new Ie(e,this.intent,{[Ne]:!0,parent:this,comment:n===void 0?i??"load "+String(s.entity):Me(n,"comment","query"),name:String(s.entity),source:t===void 0?this.traceSource:[...this.traceSource,{kind:"relation",name:t,detail:`${String(this.query.entity)}.${t}`}]})}};ve=new WeakMap;Re=new WeakMap;wt=new WeakMap;Ot=new WeakMap;vt=new WeakMap;qt=new WeakMap;qe=new WeakMap;var U=ls,ke,Le,Ce=class{constructor(r,e){Y(this,ke),Y(this,Le),H(this,ke,new he(e===void 0?r?.comment:e?.comment)),H(this,Le,{...r}),Object.defineProperty(Q(this,Le),"comment",{value:Q(this,ke).comment,enumerable:!0,writable:!1,configurable:!1}),Object.freeze(this)}get intent(){return Q(this,ke)}get mutation(){return Q(this,Le)}get comment(){return Q(this,ke).comment}withLoadedSnapshot(r){return vr.set(this,new ue(r.values())),this}loadedValues(){return vr.get(this)?.values()??{}}get graphSession(){return Gt.get(this)?.session}scopeFor(r){const e=Gt.get(this),t=Ji(e?.parent,r.entity,r.id,this.comment,e?.localComment);return e&&Gr.set(t,e.session),t}traceFor(r){const e=Q(this,Le),t=e.ledgerRoot?.traceChain(e.ledgerKey??r);return t?.length?me(t):this.scopeFor(r).recover()}auditProjection(r,e,t){const i=[...ye(e),...ye(Q(this,Le).id),...t?wr(t):ye(this.loadedValues()),...wr(this.graphSession?.logBindings)];return Object.freeze({reason:Je(this.comment,i),mutationLineage:me(this.traceFor(r).map(s=>({...s,detail:Je(s.detail,i)})))})}};ke=new WeakMap;Le=new WeakMap;var Ge,Ye,ds=class{constructor(r){Y(this,Ge),Y(this,Ye),H(this,Ge,new he(r?.comment)),Object.freeze(this)}get intent(){return Q(this,Ge)}request(r,e,t){if(e&&Gr.get(e)!==this)throw new Error("GRAPH_TRACE_SCOPE_MISMATCH: parent scope belongs to another graph invocation");const i=new Ce(r,Q(this,Ge));return Gt.set(i,{session:this,parent:e,localComment:t}),i}captureLogBindings(r){H(this,Ye,re(r,Q(this,Ye)))}get logBindings(){return Q(this,Ye)}};Ge=new WeakMap;Ye=new WeakMap;var qr=class extends Error{constructor(r){super("GRAPH_ALREADY_COMMITTED: post-commit processing failed; do not retry as an uncommitted mutation"),this.cause=r,this.committed=!0,this.name="GraphCommittedError"}},cs="MUTATION-POLICY-001",ms="MUTATION-POLICY-002",ie=class extends Error{constructor(r){super(r),this.name="MutationPolicyError"}},fs=class{constructor(r){this.resolver=r}resolve(r){return this.resolver(r)}},ps=class{constructor(r){this.finder=r}findApproval(r){return this.finder(r)}},gs=class{onWarning(r,e){!e.firstOccurrence||typeof console>"u"||console.warn(`TeaQL mutation policy warning code=${e.warningCode} requestKey=${e.snapshot.requestKey} source=${e.snapshot.source} approval=${e.snapshot.approvalStatus}`)}},Ir=0,ys=class{constructor(){this.profile={warningSink:new gs},this.emittedWarnings=new Set,this.graphActive=!1,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.remaining=new Map}setRegistry(r){this.profile.registry=r}setApprovalProvider(r){this.profile.approvalProvider=r}setWarningSink(r){this.profile.warningSink=r}beginGraph(){if(this.graphActive)throw new ie("mutation policy graph is already active");this.graphActive=!0,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.rootEntity=void 0,this.auditReason=void 0,this.remaining.clear(),this.graphSnapshot=void 0}endGraph(){this.graphActive=!1,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.rootEntity=void 0,this.auditReason=void 0,this.remaining.clear(),this.graphSnapshot=void 0}recordPreflight(r){if(!this.graphActive)return;if(this.graphReviewed)throw new ie("mutation preflight cannot change after policy review");const e=Ar(r);this.rootEntity??(this.rootEntity=e.entity),this.auditReason??(this.auditReason=dt(r)),this.preflight.push(e),this.preflightKeys.push(br(r,e))}enterMutation(r,e){const t=Ar(e);if(!this.graphActive)return{snapshot:this.review(r,this.plan(t.entity,dt(e),[t]))};if(!this.graphReviewed){if(this.profile.registry&&this.preflight.length===0)throw new ie("customer mutation policy requires complete graph preflight before provider mutation");if(!this.profile.registry&&this.preflight.length===0)return{snapshot:this.review(r,this.plan(t.entity,dt(e),[t]))};const i=this.preflight.length?this.preflight:[t];this.graphSnapshot=this.review(r,this.plan(this.rootEntity??i[0].entity,this.auditReason??dt(e),i)),this.remaining.clear();const s=this.preflight.length?this.preflightKeys:i.map(Xr);for(const n of s)this.remaining.set(n,(this.remaining.get(n)??0)+1);this.graphReviewed=!0}return this.consume(br(e,t)),{snapshot:this.graphSnapshot}}ensureGraphComplete(){if(this.graphReviewed&&this.remaining.size)throw new ie("reviewed mutation plan contains operations that were not executed")}review(r,e){ws(e);const t=Sr(e),i=this.profile.registry?.resolve(t.requestKey);let s,n,o,a;if(!i)s="generated_default",o="not_applicable",a=[cs];else{n=Os(i.identity);const h=i.review(r,t);if(!h||h.verdict!=="allow"&&h.verdict!=="deny")throw new ie("customer mutation policy returned an invalid decision");if(h.verdict==="deny")throw new ie(`[MUTATION POLICY DENIED] ${h.code||"MUTATION-POLICY-DENIED"}: ${h.message||"mutation rejected"}`);s="customer";const l=this.profile.approvalProvider?.findApproval(n);o=vs(l,n)?"approved":"missing",a=o==="approved"?[]:[ms]}const u=Object.freeze({executionId:t.executionId,requestKey:t.requestKey,source:s,policy:n,approvalStatus:o,warningCodes:Object.freeze([...a]),operations:Object.freeze(t.operations.map(h=>Object.freeze({kind:h.kind,entity:h.entity,entityId:$e(h.entityId),changedFields:Object.freeze(Object.keys(h.changedValues).sort())})))});for(const h of a)this.emitWarning(r,u,h);return u}plan(r,e,t){return Ir+=1,Sr({executionId:`teaql-mutation-${Ir}`,requestKey:`${r}.saveGraph`,rootEntityType:r,auditReason:new he(e).comment,operations:t})}consume(r){const e=this.remaining.get(r)??0;if(e<1)throw new ie("provider mutation is not present in the reviewed graph plan");e===1?this.remaining.delete(r):this.remaining.set(r,e-1)}emitWarning(r,e,t){const i=e.policy?`${e.policy.policyId}:${e.policy.version}:${e.policy.fingerprint}`:"none",s=`${e.requestKey}|${i}|${t}`,n=!this.emittedWarnings.has(s);this.emittedWarnings.add(s);try{this.profile.warningSink.onWarning(r,Object.freeze({snapshot:e,warningCode:t,firstOccurrence:n}))}catch{}}};function Ar(r){const e=String(r?.entity??"").trim(),t=String(r?.action??"").toLowerCase(),i={create:"create",update:"update",delete:"delete",recover:"recover"};if(!e||!i[t])throw new ie("mutation must contain a supported entity operation");const s=r?.payload&&typeof r.payload=="object"?r.payload:{};return Object.freeze({kind:i[t],entity:e,entityId:$e(r?.id??s.id),originalVersion:r?.version??r?.expectedVersion,changedValues:Hr(s)})}function dt(r){return new he(r?.comment).comment}function ws(r){if(new he(r?.auditReason),!r.executionId?.trim())throw new ie("execution id is required");if(!r.requestKey?.trim())throw new ie("request key is required");if(!r.rootEntityType?.trim())throw new ie("root entity type is required");if(!r.operations.length)throw new ie("mutation plan is empty")}function Os(r){if(!r||!r.policyId?.trim()||!r.version?.trim()||!r.fingerprint?.trim())throw new ie("customer mutation policy identity is invalid");return Object.freeze({policyId:r.policyId.trim(),version:r.version.trim(),fingerprint:r.fingerprint.trim()})}function vs(r,e){return!!r&&qs(r.policy,e)&&!!r.approvedBy?.trim()&&r.approvedAt instanceof Date&&Number.isFinite(r.approvedAt.getTime())&&r.approvedAt.getTime()!==0}function qs(r,e){return r.policyId===e.policyId&&r.version===e.version&&r.fingerprint===e.fingerprint}function Sr(r){return Object.freeze({executionId:r.executionId,requestKey:r.requestKey,rootEntityType:r.rootEntityType,auditReason:r.auditReason,operations:Object.freeze(r.operations.map(e=>Object.freeze({kind:e.kind,entity:e.entity,entityId:$e(e.entityId),originalVersion:e.originalVersion,changedValues:Hr(e.changedValues)})))})}function $e(r,e=new WeakSet){if(r==null||typeof r=="string"||typeof r=="number"||typeof r=="boolean"||typeof r=="bigint")return r;if(r instanceof Date)return r.toISOString();if(typeof r=="object"){if(e.has(r))throw new ie("mutation policy values must not contain cycles");e.add(r);try{if(Array.isArray(r))return Object.freeze(r.map(i=>$e(i,e)));const t=r;return"id"in t&&Object.keys(t).some(i=>i!=="id")?$e(t.id,e):Object.freeze(Object.fromEntries(Object.entries(t).map(([i,s])=>[i,$e(s,e)])))}finally{e.delete(r)}}return String(r)}function Hr(r){return Object.freeze(Object.fromEntries(Object.entries(r).map(([e,t])=>[e,$e(t)])))}function Xr(r){return _t({kind:r.kind,entity:r.entity,entityId:r.entityId,originalVersion:r.originalVersion,changedValues:r.changedValues})}function br(r,e){const t=r?.ledgerKey;return t&&typeof t=="object"&&String(t.entity??"").trim()&&t.id!==void 0&&t.id!==null?`ledger:${String(t.entity).trim()}:${_t(t.id)}`:`operation:${Xr(e)}`}function _t(r){return typeof r=="bigint"?JSON.stringify(`${r.toString()}n`):r===void 0?'""':r===null||typeof r!="object"?JSON.stringify(r):Array.isArray(r)?`[${r.map(_t).join(",")}]`:`{${Object.entries(r).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${_t(t)}`).join(",")}}`}var Lr=new WeakMap,Is=1;function As(r){if(!r||typeof r!="object"&&typeof r!="function")return String(r);const e=r;let t=Lr.get(e);return t||(t=Is++,Lr.set(e,t)),String(t)}var Cr=class extends Error{constructor(r,e,t){super(`context root ${r}: expected ${e}`),this.reason=r,this.expectedType=e,this.activeRoot=t,this.name="ContextRootError"}},Jr=class{constructor(){this.mutationPolicy=new ys,this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(r,e)=>this.getContinuousPageCursor(r,e),put:(r,e,t)=>this.putContinuousPageCursor(r,e,t),observe:(r,e)=>{this.continuousPagePlan=r,this.continuousPageCursorId=e}},this.idSetPaginationRuntime={owner:"",scope:"",get:r=>this.idSetStore().get(r),put:(r,e)=>this.idSetStore().put(r,e),build:(r,e)=>this.singleFlightIdSetBuild(r,e),observe:(r,e)=>{this.idSetPaginationPlan=r,this.idSetPaginationCount=e,this.idSetPaginationCountAccuracy=r==="ID_SET_BUILD"||r==="ID_SET_HIT"?"EXACT":r==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=Hi.builtin}setLocaleCode(r){const e=jr(r);return this.locale=e,this}setLanguageCode(r){return this.setLocaleCode(r)}installI18nCatalog(r){if(!r)throw new Error("catalog is required");return this.i18nCatalog=r,this}installIdSetPaginationStore(r){if(!r)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",r)}translateCheckResults(r){return r.map(e=>this.i18nCatalog.translate(e,this.locale))}withMutationPolicyRegistry(r){if(!r||typeof r.resolve!="function")throw new TypeError("mutation policy registry must expose resolve(requestKey)");return this.mutationPolicy.setRegistry(r),this}withMutationPolicyApprovalProvider(r){if(!r||typeof r.findApproval!="function")throw new TypeError("mutation policy approval provider must expose findApproval(identity)");return this.mutationPolicy.setApprovalProvider(r),this}withMutationGovernanceSink(r){if(!r||typeof r.onWarning!="function")throw new TypeError("mutation governance sink must expose onWarning(context, warning)");return this.mutationPolicy.setWarningSink(r),this}reviewMutationPlan(r){return this.mutationPolicy.review(this,r)}beginMutationPolicyGraph(){this.mutationPolicy.beginGraph()}recordMutationPolicyPreflight(r){this.mutationPolicy.recordPreflight(r)}enterMutationPolicy(r){return this.mutationPolicy.enterMutation(this,r).snapshot}ensureMutationPolicyGraphComplete(){this.mutationPolicy.ensureGraphComplete()}endMutationPolicyGraph(){this.mutationPolicy.endGraph()}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(r){const e=String(r.sourceLabel||""),t=e.toLowerCase();if(!r.entityType||!r.modelPath||!e||t.includes("authorization")||t.includes("cookie")||t.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const i=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",i),i.push(Object.freeze({...r})),this}finishFixEvidence(){const r=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...r])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(r,e){return this.resources.set(r,e),this}getResource(r){return this.resources.get(r)}removeResource(r){return this.resources.delete(r),this}requireResource(r){const e=this.getResource(r);if(e===void 0)throw new Error(`Required UserContext resource is missing: ${r}`);return e}ensureSchema(){const r=this.requireResource("dataService"),e=r[Vr];if(!e)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return e.call(r,this)}withActiveRoot(r){if(!r||!r.entity||r.id===void 0||r.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...r}))}requireActiveRoot(r){const e=this.getResource("activeRoot");if(!e)throw new Cr("missing",r);if(e.entity!==r)throw new Cr("type_mismatch",r,e);return e}prepareQuery(r){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const e=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,e?`${e.entity}:${String(e.id)}`:"-",As(this.getResource("dataService"))].join("|"),r.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(r,e){const t=`${r}:${e}`,i=this.continuousPageCursors.get(t);if(i&&i.expiresAt<=Date.now()){this.continuousPageCursors.delete(t);return}return i}putContinuousPageCursor(r,e,t){if(this.continuousPageCursors.size>=4096){const i=[...this.continuousPageCursors.entries()].sort((s,n)=>s[1].expiresAt-n[1].expiresAt)[0];i&&this.continuousPageCursors.delete(i[0])}this.continuousPageCursors.set(`${r}:${e}`,t)}getRetainedIdSet(r){const e=this.retainedIdSets.get(r);if(e&&e.expiresAt<=Date.now()){this.retainedIdSets.delete(r);return}return e}idSetStore(){return this.getResource("idSetPaginationStore")??{get:r=>this.getRetainedIdSet(r),put:(r,e)=>this.putRetainedIdSet(r,e),invalidate:r=>{this.retainedIdSets.delete(r)}}}putRetainedIdSet(r,e){if(e.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const i=()=>[...this.retainedIdSets.values()].reduce((s,n)=>s+n.ids.byteLength,0);for(;this.retainedIdSets.size>=64||i()+e.ids.byteLength>268435456;){const s=[...this.retainedIdSets.entries()].sort((n,o)=>n[1].expiresAt-o[1].expiresAt)[0];if(!s)break;this.retainedIdSets.delete(s[0])}this.retainedIdSets.set(r,e)}async singleFlightIdSetBuild(r,e){const t=this.idSetBuilds.get(r);if(t)return{value:await t,built:!1};const i=e();this.idSetBuilds.set(r,i);try{return{value:await i,built:!0}}finally{this.idSetBuilds.delete(r)}}},j=class extends Error{constructor(r){super(`Check failed: ${r.map(e=>e.message??`${e.ruleId}:${e.location}`).join("; ")}`),this.violations=r,this.name="CheckException"}},rt=class He{constructor(e,t,i){this.field=e,this.expr=t,this.direction=i}static new(e,t){return new He(e,null,t)}static expr(e,t){return new He("",e,t)}static asc(e){return He.new(e,"Asc")}static desc(e){return He.new(e,"Desc")}},_r=class Zr{constructor(e,t,i,s){this.enabledValue=e,this.cacheExpiredMillis=t,this.propagateValue=i,this.propagateCacheExpiredMillis=s}static enabled(e){return new Zr(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}},ei=class ti{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,t,i,s=!0,n){return this.facets.push({facetName:e,relationName:t,query:i.toQuery(),includeAllFacets:s,operation:n}),this}clone(){const e=Pe(this);for(const t of["commentText","purposeText","_comment","_purpose"]){const i=Object.getOwnPropertyDescriptor(e,t);i&&"value"in i&&i.configurable&&Object.defineProperty(e,t,{...i,writable:!0})}return e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,t){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:t},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,t,i){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(i)||i<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:t,maxIds:i},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const t=new ti(this.entity);return t.filterCondition=Pe(this.filterCondition),t.commentText=this.commentText,t.purposeText=this.purposeText,t.aggregate("Count","id",e),Fe(this,t),t}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const t of this.relations)t.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,t,i="id",s="id",n=!0,o){return this.relations.push({name:e,query:t,localKey:i,foreignKey:s,many:n,operation:o}),this}relationAggregate(e,t,i,s=!0,n){return this.relationAggregates.push({relationName:e,alias:t,query:i,singleResult:s,operation:n}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=_r.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=_r.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,t,i){return this.aggregateItems.push({function:e,field:t,alias:i}),this}groupBy(e){return this.groupByItems.push(e),this}};function ri(r,e){const t=r.defaultDomainRoot,i=e.defaultDomainRoot;if(t&&i&&(t.entity!==i.entity||t.id!==i.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...r.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:i??t,constants:[...s.values()],ensure:r.ensure&&e.ensure?async n=>{await r.ensure(n),await e.ensure(n)}:e.ensure??r.ensure}}var Ss=class ii{constructor(e={},t={},i={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...t}),this.bootstrap=Object.freeze({defaultDomainRoot:i.defaultDomainRoot,constants:Object.freeze([...i.constants??[]]),ensure:i.ensure})}and(e){return new ii({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},ri(this.bootstrap,e.bootstrap))}},X=class Yt extends Array{static get[Symbol.species](){return Array}constructor(e=[],t={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,Yt.prototype),this.totalCount=t.totalCount,this.aggregations=t.aggregations??{},this.summary=t.summary??{},this.facets=t.facets??{},this.isLoaded=t.isLoaded??!0}static empty(){return new Yt([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,t){return this.facets[e]=t,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}};function bs(r){return r.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function Ht(r){if(r&&typeof r=="object"){const e=r;return e.id??e.Id}return r}function Ls(r,e){const t=bs(e);for(const i of[e,`${e}Id`,t,`${t}_id`]){const s=Ht(r[i]);if(s!=null)return s}}async function oe(r,e,t,i){const s=new U(t);t=s.query;const n={};for(const o of i){const a=s.deriveOperation(t,o.operation??{kind:"facet",relation:o.relationName,alias:o.facetName}),u=o.query.aggregateItems.filter(w=>String(w.function).toLowerCase()==="count").map(w=>String(w.alias));let h;if(r.executeFacetMembership)h=await r.executeFacetMembership(a.deriveHelper(e(t.clone()),"aggregate "+o.relationName).query,o.relationName,u);else{const w=t.clone();Fe(t,w),w.facets=[],w.relations=[],w.relationAggregates=[],w.orderItems=[],w.aggregateItems=[],w.groupByItems=[],w.offsetValue=0,w.limitValue=0,w.selectItems=[o.relationName];const I=await r.executeQuery(a.deriveHelper(e(w),"aggregate "+o.relationName).query);h=new Map;for(const S of I){const R=Ls(S,o.relationName);if(R==null)continue;const $=String(R);h.set($,(h.get($)??0)+1)}}const l=a.deriveChild(o.query.clone(),o.relationName),d=l.query,c=d.facets;d.facets=[],d.aggregateItems=[],d.groupByItems=[];for(const w of d.relationAggregates){if(w.query.entity!==t.entity)continue;const I=t.clone();I.selectItems=["id"],I.properties=[],I.relations=[],I.relationAggregates=[],I.facets=[],I.aggregateItems=[],I.groupByItems=[],I.orderItems=[],I.offsetValue=0,I.limitValue=0;const S={id:{$inSubquery:{query:I,field:"id"}}};w.query.filterCondition=w.query.filterCondition?{$and:[w.query.filterCondition,S]}:S,Fe(t,w.query)}if(!o.includeAllFacets){const w={id:{$in:[...h.keys()]}};d.filterCondition=d.filterCondition?{$and:[d.filterCondition,w]}:w}Fe(t,d);const y=(await r.executeQuery(l.withQuery(e(d)).query)).map(w=>{const I=h.get(String(Ht(w.id??w.Id)))??0,S={...w};for(const R of u)S[R]=I;return S}).filter(w=>o.includeAllFacets||h.has(String(Ht(w.id??w.Id)))),O=new X(y);c.length&&(O.facets=await oe(r,e,l.withQuery(d).query,c)),n[o.facetName]=O}return n}var $r=Object.freeze({success:()=>{},failure:()=>{}}),Cs=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function _s(r){const e={"teaql.operation.family":r.family,"teaql.operation.name":r.name};for(const[t,i]of Object.entries(r.attributes||{}))Cs.has(t)||(e[t]=i);return Object.freeze({...r,attributes:Object.freeze(e)})}function It(r,e){if(!r)return $r;try{const t=r.start(_s(e));let i=!1;return{run:t.run?s=>t.run(s):s=>s(),success(s){if(!i){i=!0;try{t?.success(s)}catch{}}},failure(s){if(!i){i=!0;try{t?.failure(s)}catch{}}}}}catch{return $r}}async function ze(r,e,t,i){const s=It(r,e);try{const n=await(s.run?s.run(t):t());return s.success(i?.(n)),n}catch(n){throw s.failure(n),n}}function $s(r){const e=new Map;for(const t of Object.values(r))for(const i of Object.values(t.relations||{})){if(!i.many)continue;const s=r[i.targetEntity],n=s?.columns[i.foreignKey]?.columnName,o=s?.columns.id?.columnName;if(!s||!n||!o)continue;const a=`idx_${s.table}_${n}_${o}`;let u=2166136261;for(let d=0;d>>0).toString(36),l=a.length<=30?a:`${a.slice(0,Math.max(1,29-h.length))}_${h}`;e.set(l,{name:l,table:s.table,foreignColumn:n,idColumn:o})}return[...e.values()]}async function Ps(r,e,t,i){const s=Number(i);if(!Number.isSafeInteger(s)||s<0)throw new Error(`Invalid ID space floor ${i} for ${t}`);for(let n=1;n<=100;n+=1){const o=await r.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[t]);if(!o.rowCount){try{if((await r.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[t,s])).rowCount===1)return}catch(h){if(!(await r.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[t])).rowCount)throw h}continue}const a=Number(o.rows[0].id);if(a>=s)return;const u=await r.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[s,t,a]);if(u.rowCount===1)return;if(u.rowCount!==0)throw new Error(`ID space floor update for ${t} changed ${u.rowCount} rows on attempt ${n}`)}throw new Error(`Unable to synchronize ID space floor for ${t} after 100 optimistic-lock attempts`)}function Es(r,e){return r===e?!0:(r instanceof Date&&(r=r.getTime()),e instanceof Date&&(e=e.getTime()),r!=null&&e!==null&&e!==void 0&&String(r)===String(e))}function At(r){return Object.freeze(r.map((e,t)=>Object.freeze({...e,level:t})))}function Bt(r,e,t,i,s,n){const o=r.traceFor({entity:String(e.entity),id:s}),a=Vt([...o,{kind:"entity",name:String(e.entity),entityId:s,detail:""}],t,i);return{auditReason:r.comment,tracePath:At(a.tracePath),mutationLineage:o,targetID:s,inheritedBindings:re(n,r.graphSession?.logBindings)}}var Ns=class{constructor(r=e=>console.debug(e)){this.writer=r}write(r){r=zr(r),this.writer(`[TeaQL SQL][${r.operation}][${r.elapsedMicros}us] ${r.resultSummary}${r.executionOutcome?` outcome=${r.executionOutcome}`:""} -comment=${r.comment??""} purpose=${r.purpose??""} auditReason=${r.auditReason??""} tracePath=${Qt(r.tracePath)} traceChain=${Qt(r.traceChain??[])} mutationLineage=${Qt(r.mutationLineage??[])} -`+(r.omissionReason?`SQL omitted: ${r.omissionReason} -`:"")+`Debug SQL: ${r.debugSQL}`)}};function Qt(r){return JSON.stringify(r,(e,t)=>typeof t=="bigint"?t.toString():t)}var Ts=class{constructor(){this.mode="all",this.entries=[]}record(r){const e=r.operation==="select";this.mode==="disabled"||this.mode==="select"&&!e||this.mode==="mutation"&&e||this.entries.push(Object.freeze({...r,parameters:Object.freeze([...r.parameters])}))}setMode(r){return this.mode=r,this.entries=[],this}enableAll(){return this.setMode("all")}enableSelect(){return this.setMode("select")}enableMutation(){return this.setMode("mutation")}disable(){return this.setMode("disabled")}snapshot(){return[...this.entries]}},Rs=class{constructor(r,e){this.driver=r,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.bindLogPolicies=new WeakMap,this.bindOperandSources=new WeakMap,this.derivedQueryBindings=new WeakMap,this.derivedRelationAssembly=new WeakMap,this.auditEvents=[],this.diagnosticSQLLogSink=new Ns,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.checkers={},this.userContext=new Jr,this.bootstrap={},this.graphAuditActions=[],this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve(),this.schemas={...e}}fieldLogPolicy(r,e){const t=r.columns[e],i=t?.modelName??t?.columnName??e;return Ze(i)||Ze(e)?"credential":r.auditMaskFields?r.auditMaskFields?.includes(i)||r.auditMaskFields?.includes(e)?"masked":t?.logPolicy??"unknown":"unknown"}bindValue(r,e,t,i){const s=this.bindLogPolicies.get(r)??r.map(()=>"unknown");r.push(e),s.push(t),this.bindLogPolicies.set(r,s),i!==void 0&&this.bindOperandSources.set(r,re({parameterizedSQL:"",parameters:[i],parameterLogPolicies:[t],sqlOrigin:"generated"},this.bindOperandSources.get(r)))}queryLogBindings(r,e){return re({parameterizedSQL:r,parameters:e,parameterLogPolicies:this.bindLogPolicies.get(e),sqlOrigin:"generated"},this.bindOperandSources.get(e))}install(r){return Object.assign(this.schemas,r.schemas),Object.assign(this.checkers,r.checkers),this.bootstrap=ri(this.bootstrap,r.bootstrap),this}setUserContext(r){return this.userContext=r,this}schema(r){const e=this.schemas[r];if(!e)throw new Error(`Unknown TeaQL entity: ${r}`);return e}toRuntimeMutationRecord(r,e){const t={};for(const[i,s]of Object.entries(e)){const n=r.columns[i]?i:Object.keys(r.columns).find(o=>r.columns[o].modelName===i||r.columns[o].columnName===i);n&&(t[n]=s)}return t}encode(r,e){const t=r?.id??r;if(t!==void 0)return this.driver.encode(t,e)}decodeRow(r,e,t=[]){const i=this.schema(r),s={...e};for(const[n,o]of Object.entries(i.columns)){const a=s[n];a!=null&&(o.decode==="number"&&(s[n]=Number(a)),o.decode==="string"&&(s[n]=String(a)),o.decode==="date"&&a instanceof Date&&(s[n]=a.toISOString()),o.logicalType==="boolean"&&(s[n]=!!a))}for(const n of t)s[n]!==null&&s[n]!==void 0&&(s[n]=Number(s[n]));return s}get auditTrace(){return[...this.auditEvents]}setAuditSink(r){return this.auditSink=r,this}setRuntimeTelemetrySink(r){return this.telemetrySink=r,this}setDiagnosticSQLLogSink(r){return this.diagnosticSQLLogSink=r,this}setQueryLoggingEnabled(r){return this.queryLoggingEnabled=r,this}setMutationLoggingEnabled(r){return this.mutationLoggingEnabled=r,this}setRuntimeTelemetry(r){return this.runtimeTelemetry=r,this}recordSQL(r,e,t,i,s,n,o={},a="success",u){const l=r==="select"?this.queryLoggingEnabled:this.mutationLoggingEnabled,{targetID:d,inheritedBindings:c,...f}=o,y=Object.freeze({operation:r,...f,executionOutcome:a,tracePath:At(o.tracePath??[]),...o.traceChain?{traceChain:me(o.traceChain)}:{},...o.mutationLineage?{mutationLineage:me(o.mutationLineage)}:{},parameterizedSQL:e,parameters:Object.freeze([...t]),debugSQL:"",databaseKind:this.driver.databaseKind,sqlOrigin:"generated",parameterLogPolicies:Object.freeze([...this.bindLogPolicies.get(t)??t.map(()=>"unknown")]),elapsedMicros:Math.max(0,(Date.now()-i)*1e3),resultCount:s,affectedRows:n,resultSummary:s!==void 0?`${s} rows returned`:n!==void 0?`${n} rows affected`:`statement ${a}; row count unknown`}),O=c&&u?re(u,c):c??u,w=this.bindOperandSources.get(t),I=w?re(w,O):O;if(yr(y,I,d===void 0?[]:[d]),!this.telemetrySink&&!(l&&this.diagnosticSQLLogSink))return y;try{const S=zr(y);try{this.telemetrySink?.record(S)}catch{}if(l)try{this.diagnosticSQLLogSink?.write(S)}catch{}}catch{}return y}queryLogIntent(r){const e=new U(r),t=Vt(e.traceSource,this.driver.databaseKind,"select");return{comment:e.intent.comment,purpose:e.purpose,traceChain:e.traceChain,tracePath:At(t.tracePath)}}async executeLoggedSQL(r,e,t,i,s,n,o){const a=Date.now();let u;try{u=await s()}catch(l){try{const d=this.recordSQL(r,e,t,a,void 0,void 0,i,"failure",n);o?.push(d)}finally{throw l}}const h=this.recordSQL(r,e,t,a,r==="select"?u.rowCount:void 0,r==="select"?void 0:u.rowCount,i,"success",n);return o?.push(h),u}async[Vr](r){this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const e=this.bootstrapTail;let t;this.bootstrapTail=new Promise(n=>{t=n}),await e,this.userContext=r;const i=r.getResource("bootstrapActor"),s=r.getResource("bootstrapCategory");r.insertResource("bootstrapActor","teaql-generated-bootstrap"),r.insertResource("bootstrapCategory","runtime-bootstrap");try{this.bootstrap.ensure?await this.bootstrap.ensure(r):await this.ensureBootstrapData()}finally{i===void 0?r.removeResource("bootstrapActor"):r.insertResource("bootstrapActor",i),s===void 0?r.removeResource("bootstrapCategory"):r.insertResource("bootstrapCategory",s),t()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const r=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];r.length&&await this.executeGraphSave(new he("reconcile model bootstrap data"),async e=>{for(const t of r)await this.reconcileBootstrapEntity(this.graphMutationSession,e,t)})}async reconcileBootstrapEntity(r,e,t){const i=this.schema(t.entity),s=Object.entries(t.values??{}).map(([l,d])=>{const c=i.columns[l];if(!c)throw new Error(`Unknown bootstrap field ${t.entity}.${l}`);return{column:c.columnName,value:this.driver.encode(d,c)}}),n=new ei(t.entity).filter({id:{$eq:t.id}}).limit(1).comment("inspect model bootstrap record").purpose("ensure model-defined root and constants");n.prepareForList();const o=new U(n),a=`SELECT * FROM ${this.driver.identifier(i.table)} WHERE ${this.driver.identifier(i.columns.id?.columnName??"id")} = ${this.driver.placeholder(1)}`,u=[t.id];this.bindLogPolicies.set(u,[this.fieldLogPolicy(i,"id")]);const h=await this.executeLoggedSQL("select",a,u,this.queryLogIntent(o.query),()=>r.query(a,u));if(!h.rowCount)await this.executeMutation(e.request({entity:t.entity,action:"Create",id:t.id,version:0,payload:{...t.values}}));else{const l=h.rows[0];s.filter(c=>!Es(l[c.column],c.value)).length&&await this.executeMutation(e.request({entity:t.entity,action:"Update",id:t.id,version:Number(l[i.columns.version?.columnName??"version"]),payload:{...this.decodeRowForSchema(i,l),...t.values}}))}await this.driver.ensureIdFloor(r,t.entity,t.id)}async executeGraphSave(r,e){const t=new ds(r),i=this.graphSaveTail;let s;this.graphSaveTail=new Promise(u=>{s=u}),await i;let n=!1,o=!1,a=!1;try{this.graphCommitActions=[],this.graphRollbackActions=[],this.graphAuditActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence(),n=!0,this.userContext.beginMutationPolicyGraph(),o=!0;const u=await this.driver.transaction(async d=>{this.graphMutationSession=d,this.activeGraph=t;try{const c=await e(t);return this.userContext.ensureMutationPolicyGraphComplete(),c}finally{this.graphMutationSession=void 0,this.activeGraph=void 0}});a=!0;let h,l=!1;for(const d of[...this.graphCommitActions,...this.graphAuditActions])try{await d()}catch(c){l||(h=c),l=!0}if(l)throw new qr(h);return u}catch(u){if(!a)for(const h of[...this.graphRollbackActions].reverse())try{h()}catch{}throw u}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.graphAuditActions=[],o&&this.userContext.endMutationPolicyGraph(),this.userContext.removeResource("fixTime"),n&&this.userContext.finishFixEvidence(),s()}}afterGraphCommit(r){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(r)}afterGraphRollback(r){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(r)}requireGraphOwnership(r){if(r.graphSession!==this.activeGraph||this.graphMutationSession!==void 0&&r.graphSession===void 0)throw new Error("GRAPH_MUTATION_SESSION_REQUIRED: use the explicit active graph request capability")}async withMutationSession(r,e){return this.requireGraphOwnership(r),r.graphSession?e(this.graphMutationSession):this.driver.transaction(e)}preflightMutation(r){const e=r instanceof Ce?r:new Ce(r);if(this.requireGraphOwnership(e),r=this.checkAndFixMutation(e),e.graphSession){const t=this.schema(r.entity);e.graphSession.captureLogBindings(this.mutationLogBindings(e,r,t))}return this.userContext.recordMutationPolicyPreflight(r),r}mutationLogBindings(r,e,t){const i=s=>{const n=this.toRuntimeMutationRecord(t,s),o=Object.keys(n);return{parameterizedSQL:"",sqlOrigin:"generated",parameters:o.map(a=>n[a]),parameterLogPolicies:o.map(a=>this.fieldLogPolicy(t,a))}};return re(i(e.payload||{}),i(r.loadedValues()))}checkAndFixMutation(r){const e=r instanceof Ce?r:new Ce(r);this.requireGraphOwnership(e),r=e.mutation,r={...r,payload:{...r?.payload??{}}},Object.defineProperty(r,"comment",{value:e.comment,enumerable:!0});const t=this.checkers[String(r.entity)];if(!t)return r;const i=[],s=this.userContext.getResource("fixTime")===void 0;s&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(t.checkAndFix(this.userContext,r,i),r.ledgerKey&&r.ledgerRoot)for(const[n,o]of Object.entries(r.payload||{}))r.ledgerRoot.set(r.ledgerKey,n,o);if(this.userContext.translateCheckResults(i),i.length)throw new j(i);return r}finally{s&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(r){const e=r instanceof Ce?r:new Ce(r);this.requireGraphOwnership(e),r=e.mutation;const t=It(this.runtimeTelemetry,{family:"mutation",name:`${String(r?.entity||"unknown")}.${String(r?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(r?.entity||"unknown"),"teaql.mutation.kind":String(r?.action||"unknown").toLowerCase()}});try{r=this.checkAndFixMutation(e);const i=this.userContext.enterMutationPolicy(r),s=this.schema(r.entity),n=this.toRuntimeMutationRecord(s,r.payload||{}),o=this.mutationLogBindings(e,r,s),a=this.driver.identifier(s.table),u=[],h=await ze(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(r.action).toLowerCase()}},()=>this.withMutationSession(e,async y=>{if(r.action==="Create"){const O=r.id?String(r.id):await this.driver.nextId(y,r.entity);r.id&&await this.driver.ensureIdFloor(y,r.entity,O);const w=Number(r.version||0)+1,I={...n,id:O,version:w},S=Object.keys(s.columns).filter(B=>I[B]!==void 0),R=S.map(B=>this.driver.identifier(s.columns[B].columnName)).join(", "),$=S.map((B,fe)=>this.driver.placeholder(fe+1)).join(", "),A=S.map(B=>this.encode(I[B],s.columns[B]));this.bindLogPolicies.set(A,S.map(B=>this.fieldLogPolicy(s,B)));const k=`INSERT INTO ${a} (${R}) VALUES (${$})`,M=Bt(e,r,this.driver.databaseKind,"insert",O,o);return await this.executeLoggedSQL("insert",k,A,M,()=>y.query(k,A),void 0,u),{success:!0,id:O,version:w,persistedRecord:await this.readPersistedRecord(y,s,O,M,k,A,u)}}if(r.action==="Update"){const O=Object.keys(s.columns).filter(B=>B!=="id"&&B!=="version"&&n[B]!==void 0),w=O.map(B=>this.encode(n[B],s.columns[B]));this.bindLogPolicies.set(w,O.map(B=>this.fieldLogPolicy(s,B)));const I=O.map((B,fe)=>`${this.driver.identifier(s.columns[B].columnName)} = `+this.driver.placeholder(fe+1)),S=this.driver.identifier("version");I.push(`${S} = ${S} + 1`),this.bindValue(w,String(r.id),this.fieldLogPolicy(s,"id"));const R=[`${this.driver.identifier("id")} = ${this.driver.placeholder(w.length)}`];r.version!==void 0&&r.version!==null&&(this.bindValue(w,Number(r.version),this.fieldLogPolicy(s,"version")),R.push(`${S} = ${this.driver.placeholder(w.length)}`));const $=`UPDATE ${a} SET ${I.join(", ")} WHERE ${R.join(" AND ")}`,A=Bt(e,r,this.driver.databaseKind,"update",String(r.id),o);if((await this.executeLoggedSQL("update",$,w,A,()=>y.query($,w),void 0,u)).rowCount!==1)throw new Error(`Optimistic lock failed or ${r.entity}(${r.id}) does not exist`);const M=await this.readPersistedRecord(y,s,String(r.id),A,$,w,u);return{success:!0,id:String(r.id),version:Number(M.version),persistedRecord:M}}if(r.action==="Delete"){const O=this.driver.identifier("version"),w=[String(r.id)];this.bindLogPolicies.set(w,[this.fieldLogPolicy(s,"id")]);const I=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];r.version!==void 0&&r.version!==null&&(this.bindValue(w,Number(r.version),this.fieldLogPolicy(s,"version")),I.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(w.length)));const S=`UPDATE ${a} SET ${O} = -(${O} + 1) WHERE ${I.join(" AND ")}`,R=Bt(e,r,this.driver.databaseKind,"delete",String(r.id),o);if((await this.executeLoggedSQL("delete",S,w,R,()=>y.query(S,w),void 0,u)).rowCount!==1)throw new Error(`Optimistic lock failed or ${r.entity}(${r.id}) does not exist`);const A=await this.readPersistedRecord(y,s,String(r.id),R,S,w,u);return{success:!0,id:String(r.id),version:Number(A.version),deleted:!0,persistedRecord:A}}throw new Error(`Unsupported mutation action: ${r.action}`)})),l=e.auditProjection({entity:String(r.entity),id:h.id},r.payload,o),d=Object.freeze({entity:r.entity,action:r.action,id:String(h.id),...l,recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.freeze(Object.keys(r.payload||{}).sort()),version:h.version,mutationGovernance:i}),c=async()=>{this.auditEvents.push(d),this.auditSink&&await ze(this.runtimeTelemetry,{family:"audit",name:`${r.entity}.audit`,attributes:{"teaql.entity.type":String(r.entity),"teaql.mutation.kind":String(r.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(r.payload||{}).length}},async()=>this.auditSink(d))};if(e.graphSession)this.graphAuditActions.push(c);else try{await c()}catch(y){throw new qr(y)}t.success();const f=Object.freeze({...u[0],statements:Object.freeze([...u])});return yr(f,re(o,e.graphSession?.logBindings),[h.id]),{...h,metadata:f}}catch(i){throw t.failure(i),i}}async readPersistedRecord(r,e,t,i,s,n,o){const u=`SELECT ${Object.entries(e.columns).map(([S,R])=>`${this.driver.identifier(R.columnName)} AS ${this.driver.identifier(S)}`).join(", ")} FROM ${this.driver.identifier(e.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,h=[t];this.bindLogPolicies.set(h,[this.fieldLogPolicy(e,"id")]);const l=Date.now();let d;const c={parameterizedSQL:s,parameters:n,parameterLogPolicies:this.bindLogPolicies.get(n),sqlOrigin:"generated"},f=i.tracePath?.find(S=>S.kind==="operation")?.name??"unknown",y=Vt([...Wr(f,i.auditReason,"verify persisted mutation result"),...(i.tracePath??[]).filter(S=>S.kind==="relation")],this.driver.databaseKind,"select"),O={...i,tracePath:At(y.tracePath),comment:i.auditReason,purpose:"verify persisted mutation result"},w=S=>o.push(this.recordSQL("select",u,h,l,d?.rowCount,void 0,O,S,c));let I;try{if(d=await r.query(u,h),d.rowCount!==1)throw new Error(`Persisted ${e.table}(${t}) could not be read back`);I=this.decodeRowForSchema(e,d.rows[0])}catch(S){const R=d?"success":S instanceof Error&&(S.name==="AbortError"||S.name==="TimeoutError")?"cancelled":"failure";try{w(R)}finally{throw S}}return w("success"),I}decodeRowForSchema(r,e){const t={...e};for(const[i,s]of Object.entries(r.columns)){const n=t[i];n!=null&&(s.decode==="number"&&(t[i]=Number(n)),s.decode==="string"&&(t[i]=String(n)),s.decode==="date"&&n instanceof Date&&(t[i]=n.toISOString()),s.logicalType==="boolean"&&(t[i]=!!n))}return t}compileExpression(r,e,t){if(Array.isArray(r?.$and))return`(${r.$and.map(n=>this.compileExpression(n,e,t)).join(" AND ")})`;const i=Object.entries(r||{}).map(([s,n])=>{const o=e.columns[s];if(!o)throw new Error(`Unknown field ${s} for SQL query`);const a=this.driver.identifier(o.columnName),u=this.fieldLogPolicy(e,s);if(n?.$eq!==void 0){const h=n.$eq?.id??n.$eq;return h===null?`${a} IS NULL`:(this.bindValue(t,this.encode(h,o),u),`${a} = ${this.driver.placeholder(t.length)}`)}if(n?.$ne!==void 0){const h=n.$ne?.id??n.$ne;return h===null?`${a} IS NOT NULL`:(this.bindValue(t,this.encode(h,o),u),`${a} <> ${this.driver.placeholder(t.length)}`)}if(n?.$soundLike!==void 0)return this.bindValue(t,String(n.$soundLike),u),`SOUNDEX(${a}) = SOUNDEX(${this.driver.placeholder(t.length)})`;if(n?.$contains!==void 0)return this.bindValue(t,String(n.$contains),u),this.driver.contains(a,this.driver.placeholder(t.length));if(n?.$notContains!==void 0)return this.bindValue(t,String(n.$notContains),u),`NOT (${this.driver.contains(a,this.driver.placeholder(t.length))})`;for(const[h,l,d,c]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(n?.[h]!==void 0){const f=String(n[h]);this.bindValue(t,`${l}${f}${d}`,u,f);const y=`${a} LIKE ${this.driver.placeholder(t.length)}`;return c?`NOT (${y})`:y}if(Array.isArray(n?.$in)){if(!n.$in.length)return"FALSE";const h=n.$in.map(l=>(this.bindValue(t,this.encode(l?.id??l,o),u),this.driver.placeholder(t.length)));return`${a} IN (${h.join(", ")})`}if(Array.isArray(n?.$notIn)){if(!n.$notIn.length)return"TRUE";const h=n.$notIn.map(l=>(this.bindValue(t,this.encode(l?.id??l,o),u),this.driver.placeholder(t.length)));return`${a} NOT IN (${h.join(", ")})`}for(const[h,l]of[["$inSubquery",!1],["$notInSubquery",!0]]){const d=n?.[h];if(d!==void 0){const c=d.query,f=this.schema(c?.entity),y=String(d.field),O=f.columns[y];if(!O)throw new Error(`Unknown subquery projection ${y} for ${c?.entity}`);const w=this.filters(c).map(R=>this.compileExpression(R,f,t));f.columns.version&&w.push(`${this.driver.identifier(f.columns.version.columnName)} > 0`),l&&w.push(`${this.driver.identifier(O.columnName)} IS NOT NULL`);const I=w.length?` WHERE ${w.join(" AND ")}`:"",S=`SELECT ${this.driver.identifier(O.columnName)} FROM ${this.driver.identifier(f.table)}${I}`;return`${a} ${l?"NOT IN":"IN"} (${S})`}}if(Array.isArray(n?.$between)&&n.$between.length===2){this.bindValue(t,this.encode(n.$between[0],o),u);const h=this.driver.placeholder(t.length);this.bindValue(t,this.encode(n.$between[1],o),u);const l=this.driver.placeholder(t.length);return`${a} BETWEEN ${h} AND ${l}`}if(n?.$isNull===!0)return`${a} IS NULL`;if(n?.$isNull===!1)return`${a} IS NOT NULL`;if(n?.$gte!==void 0)return this.bindValue(t,this.encode(n.$gte,o),u),`${a} >= ${this.driver.placeholder(t.length)}`;if(n?.$lte!==void 0)return this.bindValue(t,this.encode(n.$lte,o),u),`${a} <= ${this.driver.placeholder(t.length)}`;if(n?.$gt!==void 0)return this.bindValue(t,this.encode(n.$gt,o),u),`${a} > ${this.driver.placeholder(t.length)}`;if(n?.$lt!==void 0)return this.bindValue(t,this.encode(n.$lt,o),u),`${a} < ${this.driver.placeholder(t.length)}`;throw new Error(`Unsupported query predicate for ${s}: ${JSON.stringify(n)}`)});return i.length?`(${i.join(" AND ")})`:"TRUE"}filters(r){return Array.isArray(r._filters)&&r._filters.length?r._filters:r.filterCondition?[r.filterCondition]:[]}groupBy(r){return r._groupBy||r.groupByItems||[]}aggregates(r){return Array.isArray(r._aggregates)?r._aggregates:(r.aggregateItems||[]).map(e=>({func:e.function,field:e.field,retName:e.alias}))}orders(r){return Array.isArray(r._orderBy)?r._orderBy.map(e=>({field:e.f,direction:e.d})):(r.orderItems||[]).map(e=>({field:e.field,direction:e.direction}))}async compileQuery(r,e=!0,t=[]){new _e(r?._comment??r?.commentText,r?._purpose??r?.purposeText);const i=this.schema(r.entity),s=[],n=this.groupBy(r),o=n.map($=>{if(!i.columns[$])throw new Error(`Unknown group field: ${$}`);return this.driver.identifier(i.columns[$].columnName)}),a=n.map($=>`${this.driver.identifier(i.columns[$].columnName)} AS `+this.driver.identifier($)),u=[],h=Array.isArray(r.selectItems)&&r.selectItems.length?[...new Set(["id","version",...r.selectItems])]:Object.keys(i.columns);if(!n.length&&!this.aggregates(r).length){for(const A of t)h.includes(A)||h.push(A);const $=[...(r.relations??[]).map(A=>A.name),...(r.relationAggregates??[]).map(A=>A.relationName)];for(const A of $){const k=i.relations?.[A];if(!k)throw new Error(`Missing relation ${r.entity}.${A}`);h.includes(k.localKey)||h.push(k.localKey)}}for(const $ of h)if(!i.columns[$])throw new Error(`Unknown selected field: ${$}`);let l=h.map($=>{const A=i.columns[$];return`${this.driver.identifier(A.columnName)} AS ${this.driver.identifier($)}`}).join(", ");const d=this.aggregates(r);if(d.length){const $=d.map(A=>{if(!i.columns[A.field])throw new Error(`Unknown aggregate field: ${A.field}`);return u.push(A.retName),`${this.driver.aggregateFunction(A.func)}(${this.driver.identifier(i.columns[A.field].columnName)}) AS `+this.driver.identifier(A.retName)});l=[...a,...$].join(", ")}const c=r.__teaqlPartitionBy,f=this.orders(r),y=f.map($=>{if(!i.columns[$.field])throw new Error(`Unknown order field: ${$.field}`);const A=String($.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(i.columns[$.field].columnName)} ${A}`});if(c){const $=i.columns[c];if(!$)throw new Error(`Unknown partition field: ${c}`);const A=y.length?` ORDER BY ${y.join(", ")}`:"";l+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier($.columnName)}${A}) AS `+this.driver.identifier("__teaql_partition_rank")}let O=`SELECT ${l} FROM ${this.driver.identifier(i.table)}`;const I=this.filters(r).map($=>this.compileExpression($,i,s));i.columns.version&&I.push(`${this.driver.identifier(i.columns.version.columnName)} > 0`),I.length&&(O+=` WHERE ${I.join(" AND ")}`),o.length&&(O+=` GROUP BY ${o.join(", ")}`);const S=r._limit!==void 0?Number(r._limit):Number(r.limitValue||0),R=r._offset!==void 0?Number(r._offset):Number(r.offsetValue||0);if(c){const $=this.driver.identifier("__teaql_partition_rank"),A=[];this.bindValue(s,R,"plain"),A.push(`${$} > ${this.driver.placeholder(s.length)}`),S>0&&(this.bindValue(s,R+S,"plain"),A.push(`${$} <= ${this.driver.placeholder(s.length)}`)),O=`SELECT * FROM (${O}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${A.join(" AND ")} ORDER BY ${$}`}else f.length&&(O+=` ORDER BY ${y.join(", ")}`);return!c&&S>0&&(this.bindValue(s,S,"plain"),O+=` LIMIT ${this.driver.placeholder(s.length)}`),!c&&R>0&&(this.bindValue(s,R,"plain"),O+=` OFFSET ${this.driver.placeholder(s.length)}`),e&&this.sqlTrace.push(O),{sql:O,values:s,aggregateNames:u}}async executeQuery(r){const e=r instanceof U?r:new U(r);return!(r instanceof U)&&r?.[this.internalQueryToken]!==!0&&typeof r?.prepareForList=="function"&&r.prepareForList(),this.executeQueryWithIntent(e.query,this.derivedQueryBindings.get(r),this.derivedRelationAssembly.get(r))}async executeDerivedQuery(r,e,t,i){const s=new U(r,t).query;e&&this.derivedQueryBindings.set(s,e),i&&this.derivedRelationAssembly.set(s,i);try{return await this.executeQuery(s)}finally{this.derivedQueryBindings.delete(s),this.derivedRelationAssembly.delete(s)}}descendantBindings(r,e,t,i){if(!(!r.relations?.length&&!r.relationAggregates?.length))return re(this.queryLogBindings(e,t),i)}async queryTreeBindings(r,e,t,i){let s=re(this.queryLogBindings(e,t),i);const n=new _e(r._comment??r.commentText,r._purpose??r.purposeText),o=[r],a=new Set;for(;o.length;){const u=o.pop();if(!u||a.has(u))continue;if(a.add(u),u!==r){const l=await this.compileQuery(new U(u,n).query,!1);s=re(this.queryLogBindings(l.sql,l.values),s)}const h=as(u);h&&o.push(h);for(const l of[...u.relations??[],...u.relationAggregates??[],...u.facets??[]])l.query&&o.push(l.query)}return s}async executeQueryWithIntent(r,e,t){const i=It(this.runtimeTelemetry,{family:"query",name:`${String(r?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(r?.entity||"unknown")}});try{const s=r?.[this.internalQueryToken]===!0;if(!s){if(typeof r?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");r.prepareForList()}const n=s?{query:r,execution:void 0}:await this.prepareIdSetPage(r,e),o=s?n:await this.prepareContinuousPage(n.query);r=new U(r).withQuery(o.query).query;const{sql:a,values:u,aggregateNames:h}=await this.compileQuery(r,!0,t?[t.field]:[]);e=await this.queryTreeBindings(r,a,u,e);const d=(await this.executeLoggedSQL("select",a,u,this.queryLogIntent(r),()=>ze(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.query`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}},()=>this.driver.query(a,u)),e)).rows.map(f=>this.decodeRow(r.entity,f,h));if(n.execution?.pageIds){const f=new Map(n.execution.pageIds.map((y,O)=>[String(y),O]));d.sort((y,O)=>(f.get(String(y.id))??Number.MAX_SAFE_INTEGER)-(f.get(String(O.id))??Number.MAX_SAFE_INTEGER))}const c=this.descendantBindings(r,a,u,e);if(t)for(const f of d)t.keys.set(f,f[t.field]);if(await this.enhanceQueryRows(d,r,c),t&&Array.isArray(r.selectItems)&&r.selectItems.length&&!["id","version",...r.selectItems,...this.groupBy(r)].includes(t.field)){const f=this.schema(r.entity);if(![...(r.relations??[]).map(O=>O.name),...(r.relationAggregates??[]).map(O=>O.relationName)].some(O=>f.relations?.[O]?.localKey===t.field))for(const O of d)delete O[t.field]}return s||await this.registerContinuousPage(r,o.execution,d),i.success({attributes:{"teaql.result.cardinality":d.length}}),d}catch(s){throw i.failure(s),s}}async prepareIdSetPage(r,e){const t=r.localIdSetPaginationOptions?.(),i=r.localIdSetPaginationRuntime?.();if(!t||!i)return i?.observe("ID_SET_DISABLED"),{query:r};const s=this.queryLimit(r);if(!s||r.localContinuousPageOptions?.()||this.aggregates(r).length||this.groupBy(r).length||r.__teaqlPartitionBy)return i.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:r};if((r.orderItems||[]).some(y=>y.expr!=null))return i.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:r};this.orders(r).some(y=>y.field==="id")||(r=r.clone().order(rt.asc("id")));const n=r.clone();n.offsetValue=0,n.limitValue=0,n.selectItems=[],n.relations=[],n.commentText=void 0,n.purposeText=void 0,n.clearIdSetPaginationRuntime(),n.clearContinuousPageRuntime();const o=`${t.namespace}|${i.scope}|${JSON.stringify(n)}`;let a=2166136261;for(let y=0;y>>0).toString(16)}`;let h,l=!1;try{h=i.get(u)}catch{return i.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:r}}if(h)l=!0,i.observe("ID_SET_HIT",h.ids.length);else{let y;try{y=await i.build(u,async()=>{const O=i.get(u);if(O)return O;const w=r.clone();w.selectItems=["id"],w.relations=[],w.relationAggregates=[],w.facets=[],w.offsetValue=0,w.limitValue=t.maxIds+1,w.clearIdSetPaginationRuntime(),w.clearContinuousPageRuntime(),w[this.internalQueryToken]=!0;const I=new U(r).deriveHelper(w,`collect ${r.entity} IDs for pagination`),S=await this.compileQuery(r,!1),R=await this.queryTreeBindings(r,S.sql,S.values,e),$=await this.executeDerivedQuery(I.query,R,I.intent);if($.length>t.maxIds)return;let A;try{A=BigUint64Array.from($.map(M=>BigInt(M.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const k={ids:A,expiresAt:Date.now()+t.ttlSeconds*1e3};return i.put(u,k),k})}catch(O){return i.observe(O instanceof Error&&O.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:r}}if(h=y.value,!h)return i.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",t.maxIds+1),{query:r};l=!y.built,i.observe(l?"ID_SET_HIT":"ID_SET_BUILD",h.ids.length)}const d=Number(r.offsetValue||r._offset||0),c=Array.from(h.ids.slice(d,d+s)),f=r.clone();return f.offsetValue=0,f.limitValue=Math.max(c.length,1),f.filterCondition=f.filterCondition?{$and:[f.filterCondition,{id:{$in:c}}]}:{id:{$in:c}},f.clearIdSetPaginationRuntime(),i.observe(l?"ID_SET_HIT":"ID_SET_BUILD",h.ids.length),{query:f,execution:{pageIds:c,totalCount:h.ids.length}}}async executeFacetMembership(r,e,t=[]){const i=new U(r);r=i.query;const s=i.withQuery(r.clone()).query;Fe(r,s),s.facets=[],s.relations=[],s.relationAggregates=[],s.orderItems=[],s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.groupByItems=[e];const n=t.length?[...t]:["__teaql_facet_count"];s.aggregateItems=n.map(a=>({function:"Count",field:"id",alias:a})),s[this.internalQueryToken]=!0;const o=await this.executeQuery(s);return new Map(o.flatMap(a=>{const u=a[e],h=Number(a[n[0]]??0);return u==null?[]:[[String(u),h]]}))}async executeCount(r,e,t){const i=r instanceof U?r:new U(r);if(r=i.query,typeof r?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const s=e??"__teaql_total",n=i.deriveOperation(r.forExactCount(s),t??{kind:"named-count",...e!==void 0?{alias:e}:{}}),a=(await this.executeQuery(n.query))[0]?.[s];if(typeof a!="number"||!Number.isFinite(a))throw new Error(`TeaQL provider did not return exact count alias ${s}`);return a}async prepareContinuousPage(r){const e=r.localContinuousPageOptions?.(),t=r.localContinuousPageRuntime?.();if(!e||!t)return t?.observe("DISABLED"),{query:r};const i=this.orders(r),s=this.queryLimit(r);if(!s||i.length!==1||i[0].field!=="id"||this.aggregates(r).length||this.groupBy(r).length||r.__teaqlPartitionBy)return t.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:r};const n=Object.assign(Object.create(Object.getPrototypeOf(r)),r);n.orderItems=[...r.orderItems||[]],n.relations=[...r.relations||[]],Object.defineProperty(n,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:e}),Object.defineProperty(n,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:t});const o=Number(r.offsetValue||r._offset||0),a={...JSON.parse(JSON.stringify(n)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},u=`${e.namespace}|${t.owner}|${JSON.stringify(a)}`;let h=2166136261;for(let y=0;y>>0).toString(16)}`,d={queryKey:l,offset:o,limit:s,direction:String(i[0].direction).toLowerCase(),ttlSeconds:e.ttlSeconds,runtime:t,optimized:!1};if(o===0)return t.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:n,execution:d};let c;try{c=await ze(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>t.get(l,o))}catch{return t.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:n,execution:d}}if(!c)return t.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:n,execution:d};const f={id:{[d.direction==="desc"?"$lt":"$gt"]:c.boundary}};return n.filterCondition=n.filterCondition?{$and:[n.filterCondition,f]}:f,n.offsetValue=0,n._offset!==void 0&&(n._offset=0),d.optimized=!0,d.cursorId=c.cursorId,t.observe("CURSOR_SEEK",c.cursorId),{query:n,execution:d}}async registerContinuousPage(r,e,t){if(!(!e||t.length!==e.limit||!t.length||t[t.length-1].id===void 0)){try{await ze(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>e.runtime.put(e.queryKey,e.offset+t.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:t[t.length-1].id,expiresAt:Date.now()+e.ttlSeconds*1e3}))}catch{e.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}e.optimized&&e.runtime.observe("CURSOR_SEEK",e.cursorId)}}executeForStream(r,e=1e3){try{const t=r instanceof U?new U(r.query,r.intent):new U(r);return this.executeCapturedStream(t.query,e)}catch(t){return(async function*(){throw t})()}}async*executeCapturedStream(r,e){if(!Number.isInteger(e)||e<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(r.facets)&&r.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:t,values:i,aggregateNames:s}=await this.compileQuery(r),n=await this.queryTreeBindings(r,t,i),o=Date.now();let a="cancelled",u=0,h=[];const l=this.descendantBindings(r,t,i,n);try{for await(const d of this.driver.stream(t,i))h.push(this.decodeRow(r.entity,d,s)),h.length===e&&(await this.enhanceQueryRows(h,r,l),u+=h.length,yield h,h=[]);h.length&&(await this.enhanceQueryRows(h,r,l),u+=h.length,yield h),a="success"}catch(d){throw a="failure",d}finally{if(a==="failure")try{this.recordSQL("select",t,i,o,u,void 0,this.queryLogIntent(r),a,n)}catch{}else this.recordSQL("select",t,i,o,u,void 0,this.queryLogIntent(r),a,n)}}async enhanceQueryRows(r,e,t){if(!r.length)return;const i=[...(e.relations??[]).map(o=>o.name),...(e.relationAggregates??[]).map(o=>o.relationName)];if(!i.length)return;const s=this.schema(e.entity),n=new Map;for(const o of i){const a=s.relations?.[o];if(!a)throw new Error(`Missing relation ${e.entity}.${o}`);n.has(a.localKey)||n.set(a.localKey,r.map(u=>u[a.localKey]))}await this.enhanceRelationAggregates(r,e,n,t),await this.enhanceRelations(r,e,n,t)}async enhanceRelations(r,e,t,i){if(!r.length||!Array.isArray(e.relations)||!e.relations.length)return;const s=this.schema(e.entity),n=new _e(e._comment??e.commentText,e._purpose??e.purposeText);for(const o of e.relations){const a=s.relations?.[o.name];if(!a)throw new Error(`Missing relation ${e.entity}.${o.name}`);const u=t.get(a.localKey),h=u.filter(I=>I!=null),l=o.query?this.queryLimit(o.query):void 0,d=o.query?.localTopNProbeParentThreshold?.(),c=a.many&&l!==void 0,f=this.driver.topNRelationPlanPolicy==="alwaysProbe",y=c&&(d===void 0?f:d>0&&h.length<=d),O=y?"bounded_probes":"window",w=It(this.runtimeTelemetry,{family:"relation_load",name:`${e.entity}.${String(o.name)}`,attributes:{"teaql.entity.type":String(e.entity),"teaql.relation.name":String(o.name),"teaql.relation.parent_count":h.length,"teaql.relation.per_parent_limit":l??0,"teaql.relation.configured_probe_threshold":d??"provider-default","teaql.relation.selected_plan":O,"teaql.relation.probe_count":y?h.length:0}});try{if(!h.length&&!(a.many&&o.query?.facets?.length)){for(const A of r)A[o.name]=a.many?[]:null;w.success({attributes:{"teaql.result.cardinality":0}});continue}const I={...o.query||{},entity:a.targetEntity,_filters:[...this.filters(o.query||{})],relations:[...o.query?.relations||[]],orderItems:[...o.query?.orderItems||[]],__teaqlPartitionBy:c&&!y?a.foreignKey:void 0};if(c){const A=this.groupBy(I),k=A.length||this.aggregates(I).length?A:["id"];for(const M of k)I.orderItems.some(B=>B.field===M)||I.orderItems.push(rt.asc(M))}typeof I.clearContinuousPageRuntime=="function"&&I.clearContinuousPageRuntime(),I[this.internalQueryToken]=!0;const S=[],R={field:a.foreignKey,keys:new WeakMap};if(y)for(const A of h){const k={...I,_filters:[...I._filters,{[a.foreignKey]:{$eq:A}}],__teaqlPartitionBy:void 0};S.push(...await this.executeDerivedQuery(new U(e).derive(k,o.name,o.operation).query,i,n,R))}else I._filters.push({[a.foreignKey]:{$in:h}}),S.push(...await this.executeDerivedQuery(new U(e).derive(I,o.name,o.operation).query,i,n,R));for(const A of S)delete A.__teaql_partition_rank;const $=new Map;for(const A of S){if(!R.keys.has(A))throw new Error("Relation assembly lost its captured row identity");const k=R.keys.get(A),M=$.get(k)||[];M.push(A),$.set(k,M)}for(const[A,k]of r.entries()){const M=$.get(u[A])||[];if(a.many&&o.query?.facets?.length){const B=o.query.clone();B.entity=a.targetEntity;const fe=u[A],Ve={[a.foreignKey]:fe==null?{$in:[]}:{$eq:fe}};B.filterCondition=B.filterCondition?{$and:[B.filterCondition,Ve]}:Ve,Fe(e,B);const Et=new U(e).derive(B,o.name,o.operation).query;k[o.name]=new X(M,{facets:await oe(this,We=>We,Et,B.facets)})}else{const B=u[A];k[o.name]=a.many?M:M[0]??(B==null?null:{[a.foreignKey]:B})}}w.success({attributes:{"teaql.result.cardinality":S.length}})}catch(I){throw w.failure(I),I}}}async enhanceRelationAggregates(r,e,t,i){const s=e.relationAggregates;if(!r.length||!Array.isArray(s)||!s.length)return;const n=this.schema(e.entity),o=new _e(e._comment??e.commentText,e._purpose??e.purposeText);for(const a of s){const u=n.relations?.[a.relationName];if(!u)throw new Error(`Missing relation ${e.entity}.${a.relationName}`);const h=t.get(u.localKey),l=h.filter(O=>O!=null);if(!l.length){for(const O of r)O[a.alias]=a.singleResult?this.emptyAggregateValue(a.query):{};continue}const d=a.query.clone();d.entity=u.targetEntity,d.selectItems=[],d.properties=[],d.orderItems=[],d.limitValue=0,d.offsetValue=0,d.relations=[],d.relationAggregates=[],d.aggregateItems.length||d.aggregate("Count","id",a.alias),d.groupByItems.includes(u.foreignKey)||d.groupBy(u.foreignKey);const c={[u.foreignKey]:{$in:l}};d.filterCondition=d.filterCondition?{$and:[d.filterCondition,c]}:c,d[this.internalQueryToken]=!0;const f=await this.executeDerivedQuery(new U(e).deriveAggregate(d,a.relationName,a.operation??{kind:"relation-count",relation:a.relationName,alias:a.alias}).query,i,o),y=new Map;for(const O of f)y.set(O[u.foreignKey],O);for(const[O,w]of r.entries()){const I=y.get(h[O]);I?a.singleResult?w[a.alias]=I[d.aggregateItems[0].alias]??null:w[a.alias]=Object.fromEntries(Object.entries(I).filter(([S])=>S!==u.foreignKey)):w[a.alias]=a.singleResult?this.emptyAggregateValue(a.query):{}}}}emptyAggregateValue(r){const e=r.aggregateItems[0];return!e||String(e.function).toLowerCase()==="count"?0:null}queryLimit(r){if(r._limit!==void 0)return Number(r._limit);if(r.limitValue!==void 0&&Number(r.limitValue)>0)return Number(r.limitValue)}async close(){await this.driver.close()}};function ks(r){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r))throw new Error(`Unsafe SQL identifier: ${r}`);return r}function xs(r){const t={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(r).toLowerCase()];if(!t)throw new Error(`Unsupported aggregate: ${r}`);return t}var Ds=class{constructor(r){this.worker=r,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=e=>{const t=e.data;if(!t||t.type!=="teaql-browser-sqlite-response")return;const i=this.pending.get(t.requestId);if(i)if(this.pending.delete(t.requestId),t.error){const s=new Error(t.error.message);s.name=t.error.name,t.error.code&&(s.code=t.error.code),i.reject(s)}else i.resolve(t.result)},this.onError=e=>{const t=new Error(e.message||"Browser SQLite worker failed");t.name="BrowserSQLiteWorkerError";for(const i of this.pending.values())i.reject(t);this.pending.clear()},r.addEventListener("message",this.onMessage),r.addEventListener("error",this.onError)}request(r,e){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const t=this.nextRequestId++;return new Promise((i,s)=>{this.pending.set(t,{resolve:n=>i(n),reject:s}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:t,operation:r,payload:e})})}async close(r){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),r&&this.worker.terminate?.();const e=new Error("Browser SQLite worker is closed");for(const t of this.pending.values())t.reject(e);this.pending.clear()}}},Bs=class{constructor(r){this.transport=r}query(r,e=[]){return this.transport.request("query",{sql:r,values:e})}},Qs=class si{constructor(e,t){this.transport=e,this.options=t,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,t={}){const i={storage:t.storage??"memory",databaseName:js(t.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:t.terminateWorkerOnClose??!0},s=new Ds(e);return await s.request("open",i),new si(s,i)}identifier(e){return`"${ks(e)}"`}placeholder(e){return"?"}contains(e,t){return`CAST(${e} AS TEXT) LIKE '%' || ${t} || '%'`}aggregateFunction(e){return xs(e)}encode(e,t){return e==null?e:t?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):t?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const t=this.accessTail;let i;this.accessTail=new Promise(s=>{i=s}),await t;try{return await e()}finally{i()}}query(e,t=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:t}))}async*stream(e,t=[]){const i=await this.query(e,t);for(const s of i.rows)yield s}transaction(e){return this.exclusive(async()=>{const t=new Bs(this.transport);await t.query("BEGIN IMMEDIATE");try{const i=await e(t);return await t.query("COMMIT"),i}catch(i){try{await t.query("ROLLBACK")}catch{}throw i}})}async ensureSchema(e){for(const t of Object.values(e)){const i=this.identifier(t.table);await this.query(`CREATE TABLE IF NOT EXISTS ${i} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const s=await this.query(`PRAGMA table_info(${i})`),n=new Set(s.rows.map(o=>String(o.name)));for(const[o,a]of Object.entries(t.columns))o==="id"||o==="version"||n.has(a.columnName)||await this.query(`ALTER TABLE ${i} ADD COLUMN ${this.identifier(a.columnName)} ${Ms(a.logicalType)}${a.nullable===!1?" NOT NULL":""}`)}for(const t of $s(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(t.name)} ON ${this.identifier(t.table)} (${this.identifier(t.foreignColumn)}, ${this.identifier(t.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,t){for(let i=1;i<=100;i+=1){const s=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t]);if(!s.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[t])).rowCount===1)return"1"}catch(u){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t])).rowCount)throw u}continue}const n=Number(s.rows[0].id),o=n+1,a=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[o,t,n]);if(a.rowCount===1)return String(o);if(a.rowCount!==0)throw new Error(`ID space update for ${t} changed ${a.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${t} after 100 optimistic-lock attempts`)}ensureIdFloor(e,t,i){return Ps(e,s=>this.placeholder(s),t,i)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}},Fs=class ni extends Rs{constructor(e,t){super(e,t),this.browserDriver=e}static async open(e,t,i={}){return new ni(await Qs.open(e,i),t)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}};function Ms(r){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[r]}function js(r){const e=r.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}var Z=r=>`${r.entity}\0${typeof r.id}:${String(r.id)}`,z=class{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map,this.traces=new Map}setTraceChain(r,e){this.traces.set(Z(r),{key:Object.freeze({...r}),nodes:me(e)})}traceChain(r){return this.traces.get(Z(r))?.nodes}set(r,e,t){if(!e.trim())throw new TypeError("field is required");const i=Z(r),s=this.changes.get(i)??{key:Object.freeze({...r}),values:{}};s.values[e]=t,this.changes.set(i,s)}snapshot(){return[...this.changes.values()].map(r=>({key:Object.freeze({...r.key}),values:Object.freeze({...r.values})}))}change(r){return Object.freeze({...this.changes.get(Z(r))?.values??{}})}mergeFrom(r){if(r!==this){for(const e of r.snapshotVersions())this.requireMatchingVersion(e.key,e.version);for(const e of r.snapshot())for(const[t,i]of Object.entries(e.values))this.set(e.key,t,i);for(const e of r.newKeys.values())this.markAsNew(e);for(const e of r.deletedKeys.values())this.markAsDeleted(e);for(const e of r.snapshotVersions())this.setOriginalVersion(e.key,e.version);for(const e of r.traces.values())this.setTraceChain(e.key,e.nodes)}}mergeEntityFrom(r,e){if(r===this)return;const t=r.originalVersion(e);t!==void 0&&this.requireMatchingVersion(e,t);for(const[s,n]of Object.entries(r.change(e)))this.set(e,s,n);r.isNew(e)&&this.markAsNew(e),r.isDeleted(e)&&this.markAsDeleted(e),t!==void 0&&this.setOriginalVersion(e,t);const i=r.traceChain(e);i&&this.setTraceChain(e,i)}hasPending(r){const e=Z(r);return this.newKeys.has(e)||this.deletedKeys.has(e)||Object.keys(this.changes.get(e)?.values??{}).length>0}snapshotVersions(){return[...this.originalVersions.values()]}rekey(r,e){const t=Z(r),i=Z(e);if(t===i)return;const s=this.originalVersion(r);s!==void 0&&this.requireMatchingVersion(e,s);const n=this.changes.get(t);if(n){this.changes.delete(t);for(const[u,h]of Object.entries(n.values))this.set(e,u,h)}const o=this.originalVersions.get(t);o!==void 0&&(this.originalVersions.delete(t),this.originalVersions.set(i,{key:Object.freeze({...e}),version:o.version})),this.newKeys.delete(t)&&this.newKeys.set(i,Object.freeze({...e})),this.deletedKeys.delete(t)&&this.deletedKeys.set(i,Object.freeze({...e}));const a=this.traces.get(t);a&&(this.traces.delete(t),this.setTraceChain(e,a.nodes))}clearEntity(r){const e=Z(r);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e),this.traces.delete(e)}requireMatchingVersion(r,e){const t=this.originalVersion(r);if(t!==void 0&&t!==e)throw new Error("ENTITY_VERSION_CONFLICT: one graph cannot contain different loaded versions of the same typed entity")}setOriginalVersion(r,e){this.requireMatchingVersion(r,e),this.originalVersions.set(Z(r),{key:Object.freeze({...r}),version:e})}acceptCommittedVersion(r,e){if(this.hasPending(r))throw new Error("ENTITY_COMMIT_PENDING: clear committed changes before accepting the persisted version");this.originalVersions.set(Z(r),{key:Object.freeze({...r}),version:e})}originalVersion(r){return this.originalVersions.get(Z(r))?.version}markAsNew(r){this.newKeys.set(Z(r),Object.freeze({...r}))}isNew(r){return this.newKeys.has(Z(r))}markAsDeleted(r){const e=Z(r);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...r}))}isDeleted(r){return this.deletedKeys.has(Z(r))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear(),this.traces.clear()}};function oi(r){const e=r.split("_");return e[0]+e.slice(1).map(t=>t?t[0].toUpperCase()+t.slice(1):"").join("")}function Vs(r,e){if(e==="snake_case")return r;const t=oi(r);return e==="camelCase"||!t?t:t[0].toUpperCase()+t.slice(1)}function Ws(r){return r.replace(/~/g,"~0").replace(/\//g,"~1")}var x=class xe{constructor(e){this.segments=e}static root(){return new xe([])}static property(e){return xe.root().property(e)}property(e){return new xe([...this.segments,{kind:"property",name:e}])}index(e){return new xe([...this.segments,{kind:"index",index:e}])}prefixedBy(e){return new xe([...e.segments,...this.segments])}modelPath(){return this.render(e=>e)}nativePath(){return this.render(oi)}instancePath(e="camelCase"){return this.segments.map(t=>t.kind==="index"?String(t.index):Ws(Vs(t.name,e))).map(t=>`/${t}`).join("")}toString(){return this.nativePath()}render(e){let t="";for(const i of this.segments)i.kind==="index"?t+=`[${i.index}]`:t+=`${t?".":""}${e(i.name)}`;return t}};function st(r,e,t,i){const s=n=>{if(n.includes("."))throw new Error("Dynamic search requires a trusted relation binding");const o=t[r.entity]?.queryFields;if(!o||!Object.prototype.hasOwnProperty.call(o,n))throw new Error("Missing generated scalar search binding");return o[n]};return Us(r,e,t,{filter:(n,o)=>{const[a,u]=Object.entries(o)[0];if(u===null&&a!=="$eq"&&a!=="$ne")throw new Error("Null supports only equality predicates");return{[s(n)]:o}},order:(n,o)=>o==="asc"?rt.asc(s(n)):rt.desc(s(n))},i)}function Us(r,e,t,i,s=n=>console.warn({...n,fieldPath:""})){const n=Gs(e,r.entity,t,()=>{}),o=Object.entries(n.search.filter??{}).map(([d,c])=>i.filter(d,c)),a=(n.search.orderBy??[]).map(d=>i.order(d.field,d.direction));if(o.some(d=>!Xe(d)))throw new Error("Invalid trusted search filter binding");if(a.some(d=>!(d instanceof rt)))throw new Error("Invalid trusted search order binding");const u=r.clone(),h=r._filters??[],l=[...h,...r.filterCondition?[r.filterCondition]:[]];return(o.length||h.length)&&u.filter({$and:[...l,...o]}),u.orderItems.push(...a),n.warnings.forEach(d=>s({...d})),{query:u,warnings:n.warnings}}var ct=(r,e)=>Object.prototype.hasOwnProperty.call(r,e),Xe=r=>typeof r=="object"&&r!==null&&!Array.isArray(r),Ks=new Set(["__proto__","prototype","constructor"]),zs=new Set(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$notIn","$contains"]);function Gs(r,e,t,i=n=>console.warn({...n,fieldPath:""}),s=100){if(!Number.isSafeInteger(s)||s<1)throw new Error("Invalid search limit");if(!ct(t,e))throw new Error("Unknown search entity");let n;try{n=typeof r=="string"?JSON.parse(r):r}catch{throw new Error("Dynamic search requires valid JSON")}if(!Xe(n)||Object.keys(n).some(f=>!["filter","orderBy"].includes(f)))throw new Error("Unsupported dynamic search input or control");if(n.filter!==void 0&&!Xe(n.filter))throw new Error("Invalid search filter");if(n.orderBy!==void 0&&!Array.isArray(n.orderBy))throw new Error("Invalid search ordering");const o=Object.entries(n.filter??{}),a=n.orderBy??[];if(o.length+a.length>s)throw new Error("Dynamic search exceeds clause limit");const u=[],h={filter:Object.create(null),orderBy:[]};function l(f){const y=f.split(".");if(y.length>16||y.some(I=>!I||I.startsWith("$")||Ks.has(I)))throw new Error("Invalid dynamic search field path");let O=t[e];for(const I of y.slice(0,-1)){if(!ct(O.relations,I))return;const S=O.relations[I];if(!ct(t,S))throw new Error("Invalid trusted search relation metadata");O=t[S]}const w=y[y.length-1];return ct(O.fields,w)?O.fields[w]:void 0}function d(f,y){u.push({code:"DYNAMIC_SEARCH_UNKNOWN_FIELD",entity:e,clause:y,fieldPath:f})}function c(f,y){if(f===null)return;if(!(y==="date"?typeof f=="string"&&/^\d{4}-\d{2}-\d{2}$/.test(f)&&!f.startsWith("0000-")&&Number.isFinite(Date.parse(f+"T00:00:00Z"))&&new Date(f+"T00:00:00Z").toISOString().slice(0,10)===f:y==="decimal"?typeof f=="string"&&/^[+-]?\d+(?:\.\d+)?$/.test(f)||typeof f=="number"&&Number.isFinite(f):y==="integer"||y==="timestamp"?typeof f=="number"&&Number.isSafeInteger(f):y==="number"?typeof f=="number"&&Number.isFinite(f):typeof f===y))throw new Error("Invalid value for known search field")}for(const[f,y]of o){const O=Xe(y)?Object.entries(y):[["$eq",y]];if(O.length!==1||!zs.has(O[0][0]))throw new Error("Unsupported or malformed dynamic search operator");const[w,I]=O[0];if((w==="$in"||w==="$notIn")&&(!Array.isArray(I)||I.length>1e3))throw new Error("Invalid or oversized search value list");const S=l(f);if(S===void 0){d(f,"FILTER");continue}if(S==="unsupported")throw new Error("Known search field has no supported scalar binding");if(w==="$contains"&&S!=="string")throw new Error("String operator requires a string field");if(Array.isArray(I)){if(w!=="$in"&&w!=="$notIn")throw new Error("Unexpected search value list");I.forEach(R=>c(R,S))}else c(I,S);h.filter[f]={[w]:Array.isArray(I)?[...I]:I}}for(const f of a){if(!Xe(f)||Object.keys(f).some(O=>!["field","direction"].includes(O))||typeof f.field!="string"||!["asc","desc"].includes(f.direction))throw new Error("Invalid dynamic search ordering");const y=l(f.field);if(y===void 0){d(f.field,"ORDER_BY");continue}if(y==="unsupported")throw new Error("Known search field has no supported scalar binding");h.orderBy.push({field:f.field,direction:f.direction})}return u.forEach(f=>i({...f})),{search:h,warnings:u}}var Pr=class extends SyntaxError{constructor(r,e,t,i){super(r),this.expected=e,this.found=t,this.location=i,this.name="SyntaxError"}format(r){let e="Error: "+this.message;if(this.location){let t=null;const i=r.find(a=>a.source===this.location.source);i&&(t=i.text.split(/\r\n|\n|\r/g));const s=this.location.start,n=this.location.source&&typeof this.location.source.offset=="function"?this.location.source.offset(s):s,o=this.location.source+":"+n.line+":"+n.column;if(t){const a=this.location.end,u="".padEnd(n.line.toString().length," "),h=t[s.line-1],d=(s.line===a.line?a.column:h.length+1)-s.column||1;e+=` - --> `+o+` -`+u+` | -`+n.line+" | "+h+` -`+u+" | "+"".padEnd(s.column-1," ")+"".padEnd(d,"^")}else e+=` - at `+o}return e}static buildMessage(r,e){function t(d){return d.codePointAt(0).toString(16).toUpperCase()}const i=Object.prototype.hasOwnProperty.call(RegExp.prototype,"unicode")?new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]","gu"):null;function s(d){return i?d.replace(i,c=>"\\u{"+t(c)+"}"):d}function n(d){return s(d.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,c=>"\\x0"+t(c)).replace(/[\x10-\x1F\x7F-\x9F]/g,c=>"\\x"+t(c)))}function o(d){return s(d.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,c=>"\\x0"+t(c)).replace(/[\x10-\x1F\x7F-\x9F]/g,c=>"\\x"+t(c)))}const a={literal(d){return'"'+n(d.text)+'"'},class(d){const c=d.parts.map(f=>Array.isArray(f)?o(f[0])+"-"+o(f[1]):o(f));return"["+(d.inverted?"^":"")+c.join("")+"]"+(d.unicode?"u":"")},any(){return"any character"},end(){return"end of input"},other(d){return d.description}};function u(d){return a[d.type](d)}function h(d){const c=d.map(u);if(c.sort(),c.length>0){let f=1;for(let y=1;yL[3])]}function _i(p){return p||[]}function $i(p){return JSON.parse(p)}function hn(p){return p}function Pi(p){return p.join("")}function Ei(p){return Number(p)}function Ni(){return!0}function Ti(){return!1}function Ri(){return null}function ln(p){return p}let m=e.peg$currPos|0;const Ee=[{line:1,column:1}];let ae=m,lt=e.peg$maxFailExpected||[],P=e.peg$silentFails|0,Ue;if(e.startRule){if(!(e.startRule in s))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=s[e.startRule]}function ki(p=m){const v=r.codePointAt(p);return v===void 0?"":String.fromCodePoint(v)}function ee(p,v){return{type:"literal",text:p,ignoreCase:v}}function Oe(p,v,L,q){return{type:"class",parts:p,inverted:v,ignoreCase:L,unicode:q}}function xi(){return{type:"any"}}function Di(){return{type:"end"}}function or(p){let v=Ee[p],L;if(v)return v;if(p>=Ee.length)L=Ee.length-1;else for(L=p;!Ee[--L];);for(v=Ee[L],v={line:v.line,column:v.column};Lae&&(ae=m,lt=[]),lt.push(p))}function Bi(p,v,L){return new Pr(Pr.buildMessage(p,v),p,v,L)}function ur(){let p,v;return p=m,J(),v=hr(),v!==t?(J(),r.charCodeAt(m)===59?m++:P===0&&E(Et),J(),p=v):(m=p,p=t),p}function hr(){let p,v,L,q,_,b,N,F;if(p=m,v=cr(),v!==t){if(L=[],q=m,_=J(),r.charCodeAt(m)===46?(b=o,m++):(b=t,P===0&&E(We)),b!==t?(N=J(),F=lr(),F!==t?(_=[_,b,N,F],q=_):(m=q,q=t)):(m=q,q=t),q!==t)for(;q!==t;)L.push(q),q=m,_=J(),r.charCodeAt(m)===46?(b=o,m++):(b=t,P===0&&E(We)),b!==t?(N=J(),F=lr(),F!==t?(_=[_,b,N,F],q=_):(m=q,q=t)):(m=q,q=t);else L=t;L!==t?p=bi(v,L):(m=p,p=t)}else m=p,p=t;return p}function lr(){let p,v,L,q,_;return p=m,v=cr(),v!==t?(J(),r.charCodeAt(m)===40?(L=a,m++):(L=t,P===0&&E(mi)),L!==t?(J(),q=dr(),q===t&&(q=null),J(),r.charCodeAt(m)===41?(_=u,m++):(_=t,P===0&&E(fi)),_!==t?p=Li(v,q):(m=p,p=t)):(m=p,p=t)):(m=p,p=t),p}function dr(){let p,v,L,q,_,b,N,F;if(p=m,v=Nt(),v!==t){for(L=[],q=m,_=J(),r.charCodeAt(m)===44?(b=h,m++):(b=t,P===0&&E(er)),b!==t?(N=J(),F=Nt(),F!==t?(_=[_,b,N,F],q=_):(m=q,q=t)):(m=q,q=t);q!==t;)L.push(q),q=m,_=J(),r.charCodeAt(m)===44?(b=h,m++):(b=t,P===0&&E(er)),b!==t?(N=J(),F=Nt(),F!==t?(_=[_,b,N,F],q=_):(m=q,q=t)):(m=q,q=t);p=Ci(v,L)}else m=p,p=t;return p}function Nt(){let p;return p=hr(),p===t&&(p=Qi(),p===t&&(p=Fi(),p===t&&(p=Mi(),p===t&&(p=ji(),p===t&&(p=Vi(),p===t&&(p=Wi())))))),p}function Qi(){let p,v,L,q;return p=m,r.charCodeAt(m)===91?(v=l,m++):(v=t,P===0&&E(pi)),v!==t?(J(),L=dr(),L===t&&(L=null),J(),r.charCodeAt(m)===93?(q=d,m++):(q=t,P===0&&E(gi)),q!==t?p=_i(L):(m=p,p=t)):(m=p,p=t),p}function Fi(){let p,v,L,q,_,b,N,F;if(p=m,v=m,L=m,r.charCodeAt(m)===34?(q=c,m++):(q=t,P===0&&E(tr)),q!==t){for(_=[],b=m,r.charCodeAt(m)===92?(N=f,m++):(N=t,P===0&&E(ut)),N!==t?(r.length>m?(F=r.charAt(m),m++):(F=t,P===0&&E(ht)),F!==t?(N=[N,F],b=N):(m=b,b=t)):(m=b,b=t),b===t&&(b=r.charAt(m),R.test(b)?m++:(b=t,P===0&&E(rr)));b!==t;)_.push(b),b=m,r.charCodeAt(m)===92?(N=f,m++):(N=t,P===0&&E(ut)),N!==t?(r.length>m?(F=r.charAt(m),m++):(F=t,P===0&&E(ht)),F!==t?(N=[N,F],b=N):(m=b,b=t)):(m=b,b=t),b===t&&(b=r.charAt(m),R.test(b)?m++:(b=t,P===0&&E(rr)));r.charCodeAt(m)===34?(b=c,m++):(b=t,P===0&&E(tr)),b!==t?(q=[q,_,b],L=q):(m=L,L=t)}else m=L,L=t;return L!==t?v=r.substring(v,m):v=L,v!==t&&(v=$i(v)),p=v,p}function Mi(){let p,v,L,q,_,b;if(p=m,r.charCodeAt(m)===39?(v=y,m++):(v=t,P===0&&E(ir)),v!==t){for(L=[],q=m,r.charCodeAt(m)===92?(_=f,m++):(_=t,P===0&&E(ut)),_!==t?(r.length>m?(b=r.charAt(m),m++):(b=t,P===0&&E(ht)),b!==t?q=b:(m=q,q=t)):(m=q,q=t),q===t&&(q=r.charAt(m),$.test(q)?m++:(q=t,P===0&&E(sr)));q!==t;)L.push(q),q=m,r.charCodeAt(m)===92?(_=f,m++):(_=t,P===0&&E(ut)),_!==t?(r.length>m?(b=r.charAt(m),m++):(b=t,P===0&&E(ht)),b!==t?q=b:(m=q,q=t)):(m=q,q=t),q===t&&(q=r.charAt(m),$.test(q)?m++:(q=t,P===0&&E(sr)));r.charCodeAt(m)===39?(q=y,m++):(q=t,P===0&&E(ir)),q!==t?p=Pi(L):(m=p,p=t)}else m=p,p=t;return p}function ji(){let p,v,L,q,_,b,N,F,te,pe;if(p=m,v=m,L=m,r.charCodeAt(m)===45?(q=O,m++):(q=t,P===0&&E(yi)),q===t&&(q=null),_=m,b=[],N=r.charAt(m),A.test(N)?m++:(N=t,P===0&&E(we)),N!==t)for(;N!==t;)b.push(N),N=r.charAt(m),A.test(N)?m++:(N=t,P===0&&E(we));else b=t;if(b!==t)if(r.charCodeAt(m)===46?(N=o,m++):(N=t,P===0&&E(We)),N!==t){if(F=[],te=r.charAt(m),A.test(te)?m++:(te=t,P===0&&E(we)),te!==t)for(;te!==t;)F.push(te),te=r.charAt(m),A.test(te)?m++:(te=t,P===0&&E(we));else F=t;F!==t?(b=[b,N,F],_=b):(m=_,_=t)}else m=_,_=t;else m=_,_=t;if(_===t)if(_=[],b=r.charAt(m),A.test(b)?m++:(b=t,P===0&&E(we)),b!==t)for(;b!==t;)_.push(b),b=r.charAt(m),A.test(b)?m++:(b=t,P===0&&E(we));else _=t;if(_!==t){if(b=m,N=r.charAt(m),k.test(N)?m++:(N=t,P===0&&E(wi)),N!==t){if(F=r.charAt(m),M.test(F)?m++:(F=t,P===0&&E(Oi)),F===t&&(F=null),te=[],pe=r.charAt(m),A.test(pe)?m++:(pe=t,P===0&&E(we)),pe!==t)for(;pe!==t;)te.push(pe),pe=r.charAt(m),A.test(pe)?m++:(pe=t,P===0&&E(we));else te=t;te!==t?(N=[N,F,te],b=N):(m=b,b=t)}else m=b,b=t;b===t&&(b=null),q=[q,_,b],L=q}else m=L,L=t;return L!==t?v=r.substring(v,m):v=L,v!==t&&(v=Ei(v)),p=v,p}function Vi(){let p,v,L,q;return p=m,r.substr(m,4)===w?(v=w,m+=4):(v=t,P===0&&E(vi)),v!==t?(L=m,P++,q=Ke(),P--,q===t?L=void 0:(m=L,L=t),L!==t?p=Ni():(m=p,p=t)):(m=p,p=t),p===t&&(p=m,r.substr(m,5)===I?(v=I,m+=5):(v=t,P===0&&E(qi)),v!==t?(L=m,P++,q=Ke(),P--,q===t?L=void 0:(m=L,L=t),L!==t?p=Ti():(m=p,p=t)):(m=p,p=t)),p}function Wi(){let p,v,L,q;return p=m,r.substr(m,4)===S?(v=S,m+=4):(v=t,P===0&&E(Ii)),v!==t?(L=m,P++,q=Ke(),P--,q===t?L=void 0:(m=L,L=t),L!==t?p=Ri():(m=p,p=t)):(m=p,p=t),p}function cr(){let p,v,L,q,_,b;if(p=m,v=m,L=m,q=r.charAt(m),B.test(q)?m++:(q=t,P===0&&E(Ai)),q!==t){for(_=[],b=Ke();b!==t;)_.push(b),b=Ke();q=[q,_],L=q}else m=L,L=t;return L!==t?v=r.substring(v,m):v=L,v!==t&&(v=v),p=v,p}function Ke(){let p;return p=r.charAt(m),fe.test(p)?m++:(p=t,P===0&&E(Si)),p}function J(){let p,v;for(p=[],v=r.charAt(m),Ve.test(v)?m++:(v=t,P===0&&E(nr));v!==t;)p.push(v),v=r.charAt(m),Ve.test(v)?m++:(v=t,P===0&&E(nr));return p}function Ui(p,v){return{type:"CallChain",target:p,calls:v.map(L=>L[3])}}Ue=n();const Tt=Ue!==t&&m===r.length;function mr(){throw Ue!==t&&mtypeof o=="object"&&o!==null&&!Array.isArray(o)?ai(o,e):o);t=s.apply(t,n)}return t}var Xs=class{static parse(r,e){const t=Ys(r,void 0);return ai(t,e)}};class C extends ei{orderBy(e,t){return this.order({field:e,expr:null,direction:t==="desc"?"Desc":"Asc"})}relationQuery(e,t,i="id",s="id",n=!0,o){return super.relationQuery(e,t,i,s,n,o)}}class G{static teaqlTemporaryId=0;id;platform;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--G.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerOrderList",{value:[],writable:!0,enumerable:!1}),e){const i={...e};delete i.customerOrderList,Object.assign(this,i),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof W?e.platform:W.fromRecord(e.platform),this.markLoaded("platform")),Array.isArray(e.customerOrderList)&&(this._customerOrderList=e.customerOrderList.map(s=>s instanceof K?s:K.fromRecord(s)),this.markLoaded("customerOrderList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"Customer",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._customerOrderList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const i=new G(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new G({id:String(e)})}static teaqlBootstrapNew(e){return new G().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const u=[{member:"id",canonical:"id"},{member:"platform",canonical:"platform"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new j([{ruleId:"invalid_type",location:x.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"Customer",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o);const a=o.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._customerOrderList.entries()){h.teaqlAttachRoot(this._root),h.updateCustomer(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("customer_order_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"Customer",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[y,O]of Object.entries(a.payload))y!=="id"&&y!=="version"&&this._root.set(this.teaqlEntityKey(),y,O);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update");const f=u.scopeFor(c);for(const[y,O]of this._customerOrderList.entries()){O.teaqlAttachRoot(this._root),O.updateCustomer(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("customer_order_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,platform:this.platform,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}customerOrderList(){return this._customerOrderList}}class se{static teaqlTemporaryId=0;id;customerOrder;productName;quantity;unitPrice;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--se.teaqlTemporaryId,writable:!0,enumerable:!1}),e){const i={...e};Object.assign(this,i),e.customerOrder&&typeof e.customerOrder=="object"&&(this.customerOrder=e.customerOrder instanceof K?e.customerOrder:K.fromRecord(e.customerOrder),this.markLoaded("customerOrder"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"OrderItem",id:this._ledgerId}}teaqlAttachRoot(e){return this._root!==e&&(e.mergeFrom(this._root),this._root=e),this}static fromRecord(e,t){const i=new se(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new se({id:String(e)})}static teaqlBootstrapNew(e){return new se().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const a=[{member:"id",canonical:"id"},{member:"customerOrder",canonical:"customer_order"},{member:"productName",canonical:"product_name"},{member:"quantity",canonical:"quantity"},{member:"unitPrice",canonical:"unit_price"},{member:"version",canonical:"version"}].find(u=>!this.isLoaded(u.member));if(a)throw new j([{ruleId:"invalid_type",location:x.property(a.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"OrderItem",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o),o.scopeFor(this.teaqlEntityKey())}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"OrderItem",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[f,y]of Object.entries(a.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,y);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();return this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update"),u.scopeFor(c),t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,customer_order:this.customerOrder,product_name:this.productName,quantity:this.quantity,unit_price:this.unitPrice,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateProductName(e){return this.productName=e,this.markLoaded("productName"),this._root.set(this.teaqlEntityKey(),"product_name",e),this}updateQuantity(e){return this.quantity=e,this.markLoaded("quantity"),this._root.set(this.teaqlEntityKey(),"quantity",e),this}updateUnitPrice(e){return this.unitPrice=e,this.markLoaded("unitPrice"),this._root.set(this.teaqlEntityKey(),"unit_price",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updateCustomerOrder(e){return this.customerOrder=e?.id??e,this.markLoaded("customerOrder"),this._root.set(this.teaqlEntityKey(),"customer_order",this.customerOrder),this}}class K{static teaqlTemporaryId=0;id;customer;status;orderNumber;orderDate;totalAmount;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--K.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_orderItemList",{value:[],writable:!0,enumerable:!1}),e){const i={...e};delete i.orderItemList,Object.assign(this,i),e.customer&&typeof e.customer=="object"&&(this.customer=e.customer instanceof G?e.customer:G.fromRecord(e.customer),this.markLoaded("customer")),e.status&&typeof e.status=="object"&&(this.status=e.status instanceof V?e.status:V.fromRecord(e.status),this.markLoaded("status")),Array.isArray(e.orderItemList)&&(this._orderItemList=e.orderItemList.map(s=>s instanceof se?s:se.fromRecord(s)),this.markLoaded("orderItemList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"CustomerOrder",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._orderItemList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const i=new K(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new K({id:String(e)})}static teaqlBootstrapNew(e){return new K().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const u=[{member:"id",canonical:"id"},{member:"customer",canonical:"customer"},{member:"status",canonical:"status"},{member:"orderNumber",canonical:"order_number"},{member:"orderDate",canonical:"order_date"},{member:"totalAmount",canonical:"total_amount"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new j([{ruleId:"invalid_type",location:x.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"CustomerOrder",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o);const a=o.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._orderItemList.entries()){h.teaqlAttachRoot(this._root),h.updateCustomerOrder(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("order_item_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"CustomerOrder",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[y,O]of Object.entries(a.payload))y!=="id"&&y!=="version"&&this._root.set(this.teaqlEntityKey(),y,O);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update");const f=u.scopeFor(c);for(const[y,O]of this._orderItemList.entries()){O.teaqlAttachRoot(this._root),O.updateCustomerOrder(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("order_item_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,customer:this.customer,status:this.status,order_number:this.orderNumber,order_date:this.orderDate,total_amount:this.totalAmount,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateOrderNumber(e){return this.orderNumber=e,this.markLoaded("orderNumber"),this._root.set(this.teaqlEntityKey(),"order_number",e),this}updateOrderDate(e){return this.orderDate=e,this.markLoaded("orderDate"),this._root.set(this.teaqlEntityKey(),"order_date",e),this}updateTotalAmount(e){return this.totalAmount=e,this.markLoaded("totalAmount"),this._root.set(this.teaqlEntityKey(),"total_amount",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updateCustomer(e){return this.customer=e?.id??e,this.markLoaded("customer"),this._root.set(this.teaqlEntityKey(),"customer",this.customer),this}updateStatus(e){return this.status=e?.id??e,this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToNew(){return this.status="1001",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToPaid(){return this.status="1002",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToCancelled(){return this.status="1003",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}orderItemList(){return this._orderItemList}}class V{static teaqlTemporaryId=0;platform;id;name;code;color;displayOrder;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--V.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerOrderList",{value:[],writable:!0,enumerable:!1}),e){const i={...e};delete i.customerOrderList,Object.assign(this,i),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof W?e.platform:W.fromRecord(e.platform),this.markLoaded("platform")),Array.isArray(e.customerOrderList)&&(this._customerOrderList=e.customerOrderList.map(s=>s instanceof K?s:K.fromRecord(s)),this.markLoaded("customerOrderList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"OrderStatus",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._customerOrderList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const i=new V(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new V({id:String(e)})}static teaqlBootstrapNew(e){return new V().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const u=[{member:"platform",canonical:"platform"},{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"code",canonical:"code"},{member:"color",canonical:"color"},{member:"displayOrder",canonical:"display_order"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new j([{ruleId:"invalid_type",location:x.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"OrderStatus",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o);const a=o.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._customerOrderList.entries()){h.teaqlAttachRoot(this._root),h.updateStatus(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("customer_order_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"OrderStatus",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[y,O]of Object.entries(a.payload))y!=="id"&&y!=="version"&&this._root.set(this.teaqlEntityKey(),y,O);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update");const f=u.scopeFor(c);for(const[y,O]of this._customerOrderList.entries()){O.teaqlAttachRoot(this._root),O.updateStatus(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("customer_order_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{platform:this.platform,id:this.id,name:this.name,code:this.code,color:this.color,display_order:this.displayOrder,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateCode(e){return this.code=e,this.markLoaded("code"),this._root.set(this.teaqlEntityKey(),"code",e),this}updateColor(e){return this.color=e,this.markLoaded("color"),this._root.set(this.teaqlEntityKey(),"color",e),this}updateDisplayOrder(e){return this.displayOrder=e,this.markLoaded("displayOrder"),this._root.set(this.teaqlEntityKey(),"display_order",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}customerOrderList(){return this._customerOrderList}}class W{static teaqlTemporaryId=0;id;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--W.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_orderStatusList",{value:[],writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerList",{value:[],writable:!0,enumerable:!1}),e){const i={...e};delete i.orderStatusList,delete i.customerList,Object.assign(this,i),Array.isArray(e.orderStatusList)&&(this._orderStatusList=e.orderStatusList.map(s=>s instanceof V?s:V.fromRecord(s)),this.markLoaded("orderStatusList")),Array.isArray(e.customerList)&&(this._customerList=e.customerList.map(s=>s instanceof G?s:G.fromRecord(s)),this.markLoaded("customerList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._orderStatusList)t.teaqlAttachRoot(e);for(const t of this._customerList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const i=new W(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new W({id:String(e)})}static teaqlBootstrapNew(e){return new W().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const u=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new j([{ruleId:"invalid_type",location:x.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"Platform",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o);const a=o.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._orderStatusList.entries()){h.teaqlAttachRoot(this._root),h.updatePlatform(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("order_status_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}for(const[u,h]of this._customerList.entries()){h.teaqlAttachRoot(this._root),h.updatePlatform(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("customer_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"Platform",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[y,O]of Object.entries(a.payload))y!=="id"&&y!=="version"&&this._root.set(this.teaqlEntityKey(),y,O);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update");const f=u.scopeFor(c);for(const[y,O]of this._orderStatusList.entries()){O.teaqlAttachRoot(this._root),O.updatePlatform(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("order_status_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}for(const[y,O]of this._customerList.entries()){O.teaqlAttachRoot(this._root),O.updatePlatform(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("customer_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}orderStatusList(){return this._orderStatusList}customerList(){return this._customerList}}const nt=Object.freeze({Platform:Object.freeze({fields:Object.freeze({id:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",name:"name",version:"version"}),relations:Object.freeze({orderStatusList:"OrderStatus",customerList:"Customer"})}),OrderStatus:Object.freeze({fields:Object.freeze({platform:"integer",id:"integer",name:"string",code:"string",color:"string",display_order:"integer",displayOrder:"integer",version:"integer"}),queryFields:Object.freeze({platform:"platform",id:"id",name:"name",code:"code",color:"color",display_order:"displayOrder",displayOrder:"displayOrder",version:"version"}),relations:Object.freeze({platform:"Platform",customerOrderList:"CustomerOrder"})}),Customer:Object.freeze({fields:Object.freeze({id:"integer",platform:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",platform:"platform",name:"name",version:"version"}),relations:Object.freeze({platform:"Platform",customerOrderList:"CustomerOrder"})}),CustomerOrder:Object.freeze({fields:Object.freeze({id:"integer",customer:"integer",status:"integer",order_number:"string",orderNumber:"string",order_date:"date",orderDate:"date",total_amount:"decimal",totalAmount:"decimal",version:"integer"}),queryFields:Object.freeze({id:"id",customer:"customer",status:"status",order_number:"orderNumber",orderNumber:"orderNumber",order_date:"orderDate",orderDate:"orderDate",total_amount:"totalAmount",totalAmount:"totalAmount",version:"version"}),relations:Object.freeze({customer:"Customer",status:"OrderStatus",orderItemList:"OrderItem"})}),OrderItem:Object.freeze({fields:Object.freeze({id:"integer",customer_order:"integer",customerOrder:"integer",product_name:"string",productName:"string",quantity:"integer",unit_price:"decimal",unitPrice:"decimal",version:"integer"}),queryFields:Object.freeze({id:"id",customer_order:"customerOrder",customerOrder:"customerOrder",product_name:"productName",productName:"productName",quantity:"quantity",unit_price:"unitPrice",unitPrice:"unitPrice",version:"version"}),relations:Object.freeze({customer_order:"CustomerOrder",customerOrder:"CustomerOrder"})})});class Er{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("Platform"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new Js(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectOrderStatusListWith(e){return this.query.relationQuery("orderStatusList",e.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectOrderStatusListWith",relation:"orderStatusList"}),this}selectCustomerListWith(e){return this.query.relationQuery("customerList",e.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectCustomerListWith",relation:"customerList"}),this}haveOrderStatuses(){return this.withOrderStatusListMatching({toQuery:()=>new C("OrderStatus")})}haveNoOrderStatuses(){return this.withoutOrderStatusListMatching({toQuery:()=>new C("OrderStatus")})}withOrderStatusListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutOrderStatusListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}haveCustomers(){return this.withCustomerListMatching({toQuery:()=>new C("Customer")})}haveNoCustomers(){return this.withoutCustomerListMatching({toQuery:()=>new C("Customer")})}withCustomerListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutCustomerListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}countOrderStatuses(){return this.countOrderStatusesAs("countOrderStatuses")}countOrderStatusesAs(e){const t=new C("OrderStatus").filter({version:{$gte:1}});return this.countOrderStatusesWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countOrderStatusesAs",relation:"orderStatusList",alias:e},this}countOrderStatusesWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"relation-count",method:"countOrderStatusesWith",relation:"orderStatusList",alias:e}),this}minDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.minDisplayOrderOfOrderStatusesAs("minOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}minDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"minDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}maxDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.maxDisplayOrderOfOrderStatusesAs("maxOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}maxDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"maxDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}sumDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.sumDisplayOrderOfOrderStatusesAs("sumOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}sumDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"sumDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}avgDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.avgDisplayOrderOfOrderStatusesAs("avgOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}avgDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"avgDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}standardDeviationDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.standardDeviationDisplayOrderOfOrderStatusesAs("standardDeviationOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}standardDeviationDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"standardDeviationDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs("squareRootOfPopulationStandardDeviationOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}sampleVarianceDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.sampleVarianceDisplayOrderOfOrderStatusesAs("sampleVarianceOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}sampleVarianceDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"sampleVarianceDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}samplePopulationVarianceDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.samplePopulationVarianceDisplayOrderOfOrderStatusesAs("samplePopulationVarianceOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}samplePopulationVarianceDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}countCustomers(){return this.countCustomersAs("countCustomers")}countCustomersAs(e){const t=new C("Customer").filter({version:{$gte:1}});return this.countCustomersWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomersAs",relation:"customerList",alias:e},this}countCustomersWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("customerList",e,i,!0,{kind:"relation-count",method:"countCustomersWith",relation:"customerList",alias:e}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,t){return this.filters.push({name:{$between:[e,t]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof W?u:W.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof W?f:W.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof W?o:W.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class Js{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new W}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Nr{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("OrderStatus"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new Zs(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["platform","id","name","code","color","displayOrder","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectCode(){return this.query.select(["code"]),this}selectColor(){return this.query.select(["color"]),this}selectDisplayOrder(){return this.query.select(["displayOrder"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}selectCustomerOrderListWith(e){return this.query.relationQuery("customerOrderList",e.toQuery(),"id","status",!0,{kind:"relation-select",method:"selectCustomerOrderListWith",relation:"customerOrderList"}),this}haveCustomerOrders(){return this.withCustomerOrderListMatching({toQuery:()=>new C("CustomerOrder")})}haveNoCustomerOrders(){return this.withoutCustomerOrderListMatching({toQuery:()=>new C("CustomerOrder")})}withCustomerOrderListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"status"}}}),this}withoutCustomerOrderListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"status"}}}),this}countCustomerOrders(){return this.countCustomerOrdersAs("countCustomerOrders")}countCustomerOrdersAs(e){const t=new C("CustomerOrder").filter({version:{$gte:1}});return this.countCustomerOrdersWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomerOrdersAs",relation:"customerOrderList",alias:e},this}countCustomerOrdersWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"relation-count",method:"countCustomerOrdersWith",relation:"customerOrderList",alias:e}),this}minTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.minTotalAmountOfCustomerOrdersAs("minOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}minTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"minTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}maxTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.maxTotalAmountOfCustomerOrdersAs("maxOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}maxTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"maxTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}sumTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.sumTotalAmountOfCustomerOrdersAs("sumOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}sumTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"sumTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}avgTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.avgTotalAmountOfCustomerOrdersAs("avgOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}avgTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"avgTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}standardDeviationTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.standardDeviationTotalAmountOfCustomerOrdersAs("standardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}standardDeviationTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"standardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs("squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}sampleVarianceTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.sampleVarianceTotalAmountOfCustomerOrdersAs("sampleVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}sampleVarianceTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"sampleVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}samplePopulationVarianceTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs("samplePopulationVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}samplePopulationVarianceTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,t){return this.filters.push({name:{$between:[e,t]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withCodeContaining(e){return this.filters.push({code:{$contains:e}}),this}withCodeIs(e){return this.filters.push({code:{$eq:e}}),this}withCodeIsNot(e){return this.filters.push({code:{$ne:e}}),this}withCodeIn(...e){return this.filters.push({code:{$in:e}}),this}withCodeNotIn(...e){return this.filters.push({code:{$notIn:e}}),this}withCodeGreaterThan(e){return this.filters.push({code:{$gt:e}}),this}withCodeGreaterThanOrEqualTo(e){return this.filters.push({code:{$gte:e}}),this}withCodeLessThan(e){return this.filters.push({code:{$lt:e}}),this}withCodeLessThanOrEqualTo(e){return this.filters.push({code:{$lte:e}}),this}withCodeBetween(e,t){return this.filters.push({code:{$between:[e,t]}}),this}withCodeIsKnown(){return this.filters.push({code:{$isNull:!1}}),this}withCodeIsUnknown(){return this.filters.push({code:{$isNull:!0}}),this}withCodeNotContaining(e){return this.filters.push({code:{$notContains:e}}),this}withCodeStartingWith(e){return this.filters.push({code:{$startsWith:e}}),this}withCodeNotStartingWith(e){return this.filters.push({code:{$notStartsWith:e}}),this}withCodeEndingWith(e){return this.filters.push({code:{$endsWith:e}}),this}withCodeNotEndingWith(e){return this.filters.push({code:{$notEndsWith:e}}),this}withCodeSoundingLike(e){return this.filters.push({code:{$soundLike:e}}),this}withColorContaining(e){return this.filters.push({color:{$contains:e}}),this}withColorIs(e){return this.filters.push({color:{$eq:e}}),this}withColorIsNot(e){return this.filters.push({color:{$ne:e}}),this}withColorIn(...e){return this.filters.push({color:{$in:e}}),this}withColorNotIn(...e){return this.filters.push({color:{$notIn:e}}),this}withColorGreaterThan(e){return this.filters.push({color:{$gt:e}}),this}withColorGreaterThanOrEqualTo(e){return this.filters.push({color:{$gte:e}}),this}withColorLessThan(e){return this.filters.push({color:{$lt:e}}),this}withColorLessThanOrEqualTo(e){return this.filters.push({color:{$lte:e}}),this}withColorBetween(e,t){return this.filters.push({color:{$between:[e,t]}}),this}withColorIsKnown(){return this.filters.push({color:{$isNull:!1}}),this}withColorIsUnknown(){return this.filters.push({color:{$isNull:!0}}),this}withColorNotContaining(e){return this.filters.push({color:{$notContains:e}}),this}withColorStartingWith(e){return this.filters.push({color:{$startsWith:e}}),this}withColorNotStartingWith(e){return this.filters.push({color:{$notStartsWith:e}}),this}withColorEndingWith(e){return this.filters.push({color:{$endsWith:e}}),this}withColorNotEndingWith(e){return this.filters.push({color:{$notEndsWith:e}}),this}withColorSoundingLike(e){return this.filters.push({color:{$soundLike:e}}),this}withDisplayOrderIs(e){return this.filters.push({displayOrder:{$eq:e}}),this}withDisplayOrderIsNot(e){return this.filters.push({displayOrder:{$ne:e}}),this}withDisplayOrderIn(...e){return this.filters.push({displayOrder:{$in:e}}),this}withDisplayOrderNotIn(...e){return this.filters.push({displayOrder:{$notIn:e}}),this}withDisplayOrderGreaterThan(e){return this.filters.push({displayOrder:{$gt:e}}),this}withDisplayOrderGreaterThanOrEqualTo(e){return this.filters.push({displayOrder:{$gte:e}}),this}withDisplayOrderLessThan(e){return this.filters.push({displayOrder:{$lt:e}}),this}withDisplayOrderLessThanOrEqualTo(e){return this.filters.push({displayOrder:{$lte:e}}),this}withDisplayOrderBetween(e,t){return this.filters.push({displayOrder:{$between:[e,t]}}),this}withDisplayOrderIsKnown(){return this.filters.push({displayOrder:{$isNull:!1}}),this}withDisplayOrderIsUnknown(){return this.filters.push({displayOrder:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByCodeAscending(){return this.query.orderBy("code","asc"),this}orderByCodeDescending(){return this.query.orderBy("code","desc"),this}orderByColorAscending(){return this.query.orderBy("color","asc"),this}orderByColorDescending(){return this.query.orderBy("color","desc"),this}orderByDisplayOrderAscending(){return this.query.orderBy("displayOrder","asc"),this}orderByDisplayOrderDescending(){return this.query.orderBy("displayOrder","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}minDisplayOrder(){return this.minDisplayOrderAs("minOfDisplayOrder")}minDisplayOrderAs(e){return this.query.aggregate("min","displayOrder",e),this}maxDisplayOrder(){return this.maxDisplayOrderAs("maxOfDisplayOrder")}maxDisplayOrderAs(e){return this.query.aggregate("max","displayOrder",e),this}sumDisplayOrder(){return this.sumDisplayOrderAs("sumOfDisplayOrder")}sumDisplayOrderAs(e){return this.query.aggregate("sum","displayOrder",e),this}avgDisplayOrder(){return this.avgDisplayOrderAs("avgOfDisplayOrder")}avgDisplayOrderAs(e){return this.query.aggregate("avg","displayOrder",e),this}standardDeviationDisplayOrder(){return this.standardDeviationDisplayOrderAs("standardDeviationOfDisplayOrder")}standardDeviationDisplayOrderAs(e){return this.query.aggregate("stddev","displayOrder",e),this}squareRootOfPopulationStandardDeviationDisplayOrder(){return this.squareRootOfPopulationStandardDeviationDisplayOrderAs("squareRootOfPopulationStandardDeviationOfDisplayOrder")}squareRootOfPopulationStandardDeviationDisplayOrderAs(e){return this.query.aggregate("stddev_pop","displayOrder",e),this}sampleVarianceDisplayOrder(){return this.sampleVarianceDisplayOrderAs("sampleVarianceOfDisplayOrder")}sampleVarianceDisplayOrderAs(e){return this.query.aggregate("var_samp","displayOrder",e),this}samplePopulationVarianceDisplayOrder(){return this.samplePopulationVarianceDisplayOrderAs("samplePopulationVarianceOfDisplayOrder")}samplePopulationVarianceDisplayOrderAs(e){return this.query.aggregate("var_pop","displayOrder",e),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByCode(){return this.query.groupBy("code"),this}groupByCodeAs(e){return this.query.groupBy("code"),this}groupByColor(){return this.query.groupBy("color"),this}groupByColorAs(e){return this.query.groupBy("color"),this}groupByDisplayOrder(){return this.query.groupBy("displayOrder"),this}groupByDisplayOrderAs(e){return this.query.groupBy("displayOrder"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,t,i=!0){return this.query.facetBy(e,"platform",t,i,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:e}),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof V?u:V.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof V?f:V.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof V?o:V.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class Zs{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new V}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Tr{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("Customer"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new en(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","platform","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}selectCustomerOrderListWith(e){return this.query.relationQuery("customerOrderList",e.toQuery(),"id","customer",!0,{kind:"relation-select",method:"selectCustomerOrderListWith",relation:"customerOrderList"}),this}haveCustomerOrders(){return this.withCustomerOrderListMatching({toQuery:()=>new C("CustomerOrder")})}haveNoCustomerOrders(){return this.withoutCustomerOrderListMatching({toQuery:()=>new C("CustomerOrder")})}withCustomerOrderListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"customer"}}}),this}withoutCustomerOrderListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"customer"}}}),this}countCustomerOrders(){return this.countCustomerOrdersAs("countCustomerOrders")}countCustomerOrdersAs(e){const t=new C("CustomerOrder").filter({version:{$gte:1}});return this.countCustomerOrdersWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomerOrdersAs",relation:"customerOrderList",alias:e},this}countCustomerOrdersWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"relation-count",method:"countCustomerOrdersWith",relation:"customerOrderList",alias:e}),this}minTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.minTotalAmountOfCustomerOrdersAs("minOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}minTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"minTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}maxTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.maxTotalAmountOfCustomerOrdersAs("maxOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}maxTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"maxTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}sumTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.sumTotalAmountOfCustomerOrdersAs("sumOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}sumTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"sumTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}avgTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.avgTotalAmountOfCustomerOrdersAs("avgOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}avgTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"avgTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}standardDeviationTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.standardDeviationTotalAmountOfCustomerOrdersAs("standardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}standardDeviationTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"standardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs("squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}sampleVarianceTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.sampleVarianceTotalAmountOfCustomerOrdersAs("sampleVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}sampleVarianceTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"sampleVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}samplePopulationVarianceTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs("samplePopulationVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}samplePopulationVarianceTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,t){return this.filters.push({name:{$between:[e,t]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,t,i=!0){return this.query.facetBy(e,"platform",t,i,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:e}),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof G?u:G.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof G?f:G.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof G?o:G.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class en{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new G}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Rr{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("CustomerOrder"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new tn(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","customer","status","orderNumber","orderDate","totalAmount","version"]),this}selectId(){return this.query.select(["id"]),this}selectOrderNumber(){return this.query.select(["orderNumber"]),this}selectOrderDate(){return this.query.select(["orderDate"]),this}selectTotalAmount(){return this.query.select(["totalAmount"]),this}selectVersion(){return this.query.select(["version"]),this}selectCustomerWith(e){return this.query.select(["customer"]),this.query.relationQuery("customer",e.toQuery(),"customer","id",!1,{kind:"relation-select",method:"selectCustomerWith",relation:"customer"}),this}selectStatusWith(e){return this.query.select(["status"]),this.query.relationQuery("status",e.toQuery(),"status","id",!1,{kind:"relation-select",method:"selectStatusWith",relation:"status"}),this}withCustomerMatching(e){return this.filters.push({customer:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutCustomerMatching(e){return this.filters.push({customer:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withStatusMatching(e){return this.filters.push({status:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutStatusMatching(e){return this.filters.push({status:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}selectOrderItemListWith(e){return this.query.relationQuery("orderItemList",e.toQuery(),"id","customerOrder",!0,{kind:"relation-select",method:"selectOrderItemListWith",relation:"orderItemList"}),this}haveOrderItems(){return this.withOrderItemListMatching({toQuery:()=>new C("OrderItem")})}haveNoOrderItems(){return this.withoutOrderItemListMatching({toQuery:()=>new C("OrderItem")})}withOrderItemListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"customerOrder"}}}),this}withoutOrderItemListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"customerOrder"}}}),this}countOrderItems(){return this.countOrderItemsAs("countOrderItems")}countOrderItemsAs(e){const t=new C("OrderItem").filter({version:{$gte:1}});return this.countOrderItemsWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countOrderItemsAs",relation:"orderItemList",alias:e},this}countOrderItemsWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"relation-count",method:"countOrderItemsWith",relation:"orderItemList",alias:e}),this}minQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.minQuantityOfOrderItemsAs("minOfQuantityOfOrderItems",{toQuery:()=>e})}minQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"minQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}maxQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.maxQuantityOfOrderItemsAs("maxOfQuantityOfOrderItems",{toQuery:()=>e})}maxQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"maxQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}sumQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.sumQuantityOfOrderItemsAs("sumOfQuantityOfOrderItems",{toQuery:()=>e})}sumQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"sumQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}avgQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.avgQuantityOfOrderItemsAs("avgOfQuantityOfOrderItems",{toQuery:()=>e})}avgQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"avgQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}standardDeviationQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.standardDeviationQuantityOfOrderItemsAs("standardDeviationOfQuantityOfOrderItems",{toQuery:()=>e})}standardDeviationQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"standardDeviationQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}squareRootOfPopulationStandardDeviationQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs("squareRootOfPopulationStandardDeviationOfQuantityOfOrderItems",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}sampleVarianceQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.sampleVarianceQuantityOfOrderItemsAs("sampleVarianceOfQuantityOfOrderItems",{toQuery:()=>e})}sampleVarianceQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"sampleVarianceQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}samplePopulationVarianceQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.samplePopulationVarianceQuantityOfOrderItemsAs("samplePopulationVarianceOfQuantityOfOrderItems",{toQuery:()=>e})}samplePopulationVarianceQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}minUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.minUnitPriceOfOrderItemsAs("minOfUnitPriceOfOrderItems",{toQuery:()=>e})}minUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"minUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}maxUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.maxUnitPriceOfOrderItemsAs("maxOfUnitPriceOfOrderItems",{toQuery:()=>e})}maxUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"maxUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}sumUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.sumUnitPriceOfOrderItemsAs("sumOfUnitPriceOfOrderItems",{toQuery:()=>e})}sumUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"sumUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}avgUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.avgUnitPriceOfOrderItemsAs("avgOfUnitPriceOfOrderItems",{toQuery:()=>e})}avgUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"avgUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}standardDeviationUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.standardDeviationUnitPriceOfOrderItemsAs("standardDeviationOfUnitPriceOfOrderItems",{toQuery:()=>e})}standardDeviationUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"standardDeviationUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}squareRootOfPopulationStandardDeviationUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs("squareRootOfPopulationStandardDeviationOfUnitPriceOfOrderItems",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}sampleVarianceUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.sampleVarianceUnitPriceOfOrderItemsAs("sampleVarianceOfUnitPriceOfOrderItems",{toQuery:()=>e})}sampleVarianceUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"sampleVarianceUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}samplePopulationVarianceUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.samplePopulationVarianceUnitPriceOfOrderItemsAs("samplePopulationVarianceOfUnitPriceOfOrderItems",{toQuery:()=>e})}samplePopulationVarianceUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByCustomer(e){return this.filters.push({customer:{$eq:e}}),this}filterByCustomerIn(...e){return this.filters.push({customer:{$in:e}}),this}withCustomerIsKnown(){return this.filters.push({customer:{$isNull:!1}}),this}withCustomerIsUnknown(){return this.filters.push({customer:{$isNull:!0}}),this}filterByStatus(e){return this.filters.push({status:{$eq:e}}),this}filterByStatusIn(...e){return this.filters.push({status:{$in:e}}),this}withStatusIsKnown(){return this.filters.push({status:{$isNull:!1}}),this}withStatusIsUnknown(){return this.filters.push({status:{$isNull:!0}}),this}withStatusIsNew(){return this.filters.push({status:{$eq:"1001"}}),this}withStatusIsPaid(){return this.filters.push({status:{$eq:"1002"}}),this}withStatusIsCancelled(){return this.filters.push({status:{$eq:"1003"}}),this}withOrderNumberContaining(e){return this.filters.push({orderNumber:{$contains:e}}),this}withOrderNumberIs(e){return this.filters.push({orderNumber:{$eq:e}}),this}withOrderNumberIsNot(e){return this.filters.push({orderNumber:{$ne:e}}),this}withOrderNumberIn(...e){return this.filters.push({orderNumber:{$in:e}}),this}withOrderNumberNotIn(...e){return this.filters.push({orderNumber:{$notIn:e}}),this}withOrderNumberGreaterThan(e){return this.filters.push({orderNumber:{$gt:e}}),this}withOrderNumberGreaterThanOrEqualTo(e){return this.filters.push({orderNumber:{$gte:e}}),this}withOrderNumberLessThan(e){return this.filters.push({orderNumber:{$lt:e}}),this}withOrderNumberLessThanOrEqualTo(e){return this.filters.push({orderNumber:{$lte:e}}),this}withOrderNumberBetween(e,t){return this.filters.push({orderNumber:{$between:[e,t]}}),this}withOrderNumberIsKnown(){return this.filters.push({orderNumber:{$isNull:!1}}),this}withOrderNumberIsUnknown(){return this.filters.push({orderNumber:{$isNull:!0}}),this}withOrderNumberNotContaining(e){return this.filters.push({orderNumber:{$notContains:e}}),this}withOrderNumberStartingWith(e){return this.filters.push({orderNumber:{$startsWith:e}}),this}withOrderNumberNotStartingWith(e){return this.filters.push({orderNumber:{$notStartsWith:e}}),this}withOrderNumberEndingWith(e){return this.filters.push({orderNumber:{$endsWith:e}}),this}withOrderNumberNotEndingWith(e){return this.filters.push({orderNumber:{$notEndsWith:e}}),this}withOrderNumberSoundingLike(e){return this.filters.push({orderNumber:{$soundLike:e}}),this}withOrderDateIs(e){return this.filters.push({orderDate:{$eq:e}}),this}withOrderDateIsNot(e){return this.filters.push({orderDate:{$ne:e}}),this}withOrderDateIn(...e){return this.filters.push({orderDate:{$in:e}}),this}withOrderDateNotIn(...e){return this.filters.push({orderDate:{$notIn:e}}),this}withOrderDateGreaterThan(e){return this.filters.push({orderDate:{$gt:e}}),this}withOrderDateGreaterThanOrEqualTo(e){return this.filters.push({orderDate:{$gte:e}}),this}withOrderDateLessThan(e){return this.filters.push({orderDate:{$lt:e}}),this}withOrderDateLessThanOrEqualTo(e){return this.filters.push({orderDate:{$lte:e}}),this}withOrderDateBetween(e,t){return this.filters.push({orderDate:{$between:[e,t]}}),this}withOrderDateIsKnown(){return this.filters.push({orderDate:{$isNull:!1}}),this}withOrderDateIsUnknown(){return this.filters.push({orderDate:{$isNull:!0}}),this}withTotalAmountIs(e){return this.filters.push({totalAmount:{$eq:e}}),this}withTotalAmountIsNot(e){return this.filters.push({totalAmount:{$ne:e}}),this}withTotalAmountIn(...e){return this.filters.push({totalAmount:{$in:e}}),this}withTotalAmountNotIn(...e){return this.filters.push({totalAmount:{$notIn:e}}),this}withTotalAmountGreaterThan(e){return this.filters.push({totalAmount:{$gt:e}}),this}withTotalAmountGreaterThanOrEqualTo(e){return this.filters.push({totalAmount:{$gte:e}}),this}withTotalAmountLessThan(e){return this.filters.push({totalAmount:{$lt:e}}),this}withTotalAmountLessThanOrEqualTo(e){return this.filters.push({totalAmount:{$lte:e}}),this}withTotalAmountBetween(e,t){return this.filters.push({totalAmount:{$between:[e,t]}}),this}withTotalAmountIsKnown(){return this.filters.push({totalAmount:{$isNull:!1}}),this}withTotalAmountIsUnknown(){return this.filters.push({totalAmount:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByOrderNumberAscending(){return this.query.orderBy("orderNumber","asc"),this}orderByOrderNumberDescending(){return this.query.orderBy("orderNumber","desc"),this}orderByOrderDateAscending(){return this.query.orderBy("orderDate","asc"),this}orderByOrderDateDescending(){return this.query.orderBy("orderDate","desc"),this}orderByTotalAmountAscending(){return this.query.orderBy("totalAmount","asc"),this}orderByTotalAmountDescending(){return this.query.orderBy("totalAmount","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}minTotalAmount(){return this.minTotalAmountAs("minOfTotalAmount")}minTotalAmountAs(e){return this.query.aggregate("min","totalAmount",e),this}maxTotalAmount(){return this.maxTotalAmountAs("maxOfTotalAmount")}maxTotalAmountAs(e){return this.query.aggregate("max","totalAmount",e),this}sumTotalAmount(){return this.sumTotalAmountAs("sumOfTotalAmount")}sumTotalAmountAs(e){return this.query.aggregate("sum","totalAmount",e),this}avgTotalAmount(){return this.avgTotalAmountAs("avgOfTotalAmount")}avgTotalAmountAs(e){return this.query.aggregate("avg","totalAmount",e),this}standardDeviationTotalAmount(){return this.standardDeviationTotalAmountAs("standardDeviationOfTotalAmount")}standardDeviationTotalAmountAs(e){return this.query.aggregate("stddev","totalAmount",e),this}squareRootOfPopulationStandardDeviationTotalAmount(){return this.squareRootOfPopulationStandardDeviationTotalAmountAs("squareRootOfPopulationStandardDeviationOfTotalAmount")}squareRootOfPopulationStandardDeviationTotalAmountAs(e){return this.query.aggregate("stddev_pop","totalAmount",e),this}sampleVarianceTotalAmount(){return this.sampleVarianceTotalAmountAs("sampleVarianceOfTotalAmount")}sampleVarianceTotalAmountAs(e){return this.query.aggregate("var_samp","totalAmount",e),this}samplePopulationVarianceTotalAmount(){return this.samplePopulationVarianceTotalAmountAs("samplePopulationVarianceOfTotalAmount")}samplePopulationVarianceTotalAmountAs(e){return this.query.aggregate("var_pop","totalAmount",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByCustomer(){return this.query.groupBy("customer"),this}groupByCustomerAs(e){return this.query.groupBy("customer"),this}groupByStatus(){return this.query.groupBy("status"),this}groupByStatusAs(e){return this.query.groupBy("status"),this}groupByOrderNumber(){return this.query.groupBy("orderNumber"),this}groupByOrderNumberAs(e){return this.query.groupBy("orderNumber"),this}groupByOrderDate(){return this.query.groupBy("orderDate"),this}groupByOrderDateAs(e){return this.query.groupBy("orderDate"),this}groupByTotalAmount(){return this.query.groupBy("totalAmount"),this}groupByTotalAmountAs(e){return this.query.groupBy("totalAmount"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByCustomerAs(e,t,i=!0){return this.query.facetBy(e,"customer",t,i,{kind:"facet",method:"facetByCustomerAs",relation:"customer",alias:e}),this}facetByStatusAs(e,t,i=!0){return this.query.facetBy(e,"status",t,i,{kind:"facet",method:"facetByStatusAs",relation:"status",alias:e}),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof K?u:K.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof K?f:K.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof K?o:K.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class tn{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new K}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class kr{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("OrderItem"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new rn(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","customerOrder","productName","quantity","unitPrice","version"]),this}selectId(){return this.query.select(["id"]),this}selectProductName(){return this.query.select(["productName"]),this}selectQuantity(){return this.query.select(["quantity"]),this}selectUnitPrice(){return this.query.select(["unitPrice"]),this}selectVersion(){return this.query.select(["version"]),this}selectCustomerOrderWith(e){return this.query.select(["customerOrder"]),this.query.relationQuery("customerOrder",e.toQuery(),"customerOrder","id",!1,{kind:"relation-select",method:"selectCustomerOrderWith",relation:"customerOrder"}),this}withCustomerOrderMatching(e){return this.filters.push({customerOrder:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutCustomerOrderMatching(e){return this.filters.push({customerOrder:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByCustomerOrder(e){return this.filters.push({customerOrder:{$eq:e}}),this}filterByCustomerOrderIn(...e){return this.filters.push({customerOrder:{$in:e}}),this}withCustomerOrderIsKnown(){return this.filters.push({customerOrder:{$isNull:!1}}),this}withCustomerOrderIsUnknown(){return this.filters.push({customerOrder:{$isNull:!0}}),this}withProductNameContaining(e){return this.filters.push({productName:{$contains:e}}),this}withProductNameIs(e){return this.filters.push({productName:{$eq:e}}),this}withProductNameIsNot(e){return this.filters.push({productName:{$ne:e}}),this}withProductNameIn(...e){return this.filters.push({productName:{$in:e}}),this}withProductNameNotIn(...e){return this.filters.push({productName:{$notIn:e}}),this}withProductNameGreaterThan(e){return this.filters.push({productName:{$gt:e}}),this}withProductNameGreaterThanOrEqualTo(e){return this.filters.push({productName:{$gte:e}}),this}withProductNameLessThan(e){return this.filters.push({productName:{$lt:e}}),this}withProductNameLessThanOrEqualTo(e){return this.filters.push({productName:{$lte:e}}),this}withProductNameBetween(e,t){return this.filters.push({productName:{$between:[e,t]}}),this}withProductNameIsKnown(){return this.filters.push({productName:{$isNull:!1}}),this}withProductNameIsUnknown(){return this.filters.push({productName:{$isNull:!0}}),this}withProductNameNotContaining(e){return this.filters.push({productName:{$notContains:e}}),this}withProductNameStartingWith(e){return this.filters.push({productName:{$startsWith:e}}),this}withProductNameNotStartingWith(e){return this.filters.push({productName:{$notStartsWith:e}}),this}withProductNameEndingWith(e){return this.filters.push({productName:{$endsWith:e}}),this}withProductNameNotEndingWith(e){return this.filters.push({productName:{$notEndsWith:e}}),this}withProductNameSoundingLike(e){return this.filters.push({productName:{$soundLike:e}}),this}withQuantityIs(e){return this.filters.push({quantity:{$eq:e}}),this}withQuantityIsNot(e){return this.filters.push({quantity:{$ne:e}}),this}withQuantityIn(...e){return this.filters.push({quantity:{$in:e}}),this}withQuantityNotIn(...e){return this.filters.push({quantity:{$notIn:e}}),this}withQuantityGreaterThan(e){return this.filters.push({quantity:{$gt:e}}),this}withQuantityGreaterThanOrEqualTo(e){return this.filters.push({quantity:{$gte:e}}),this}withQuantityLessThan(e){return this.filters.push({quantity:{$lt:e}}),this}withQuantityLessThanOrEqualTo(e){return this.filters.push({quantity:{$lte:e}}),this}withQuantityBetween(e,t){return this.filters.push({quantity:{$between:[e,t]}}),this}withQuantityIsKnown(){return this.filters.push({quantity:{$isNull:!1}}),this}withQuantityIsUnknown(){return this.filters.push({quantity:{$isNull:!0}}),this}withUnitPriceIs(e){return this.filters.push({unitPrice:{$eq:e}}),this}withUnitPriceIsNot(e){return this.filters.push({unitPrice:{$ne:e}}),this}withUnitPriceIn(...e){return this.filters.push({unitPrice:{$in:e}}),this}withUnitPriceNotIn(...e){return this.filters.push({unitPrice:{$notIn:e}}),this}withUnitPriceGreaterThan(e){return this.filters.push({unitPrice:{$gt:e}}),this}withUnitPriceGreaterThanOrEqualTo(e){return this.filters.push({unitPrice:{$gte:e}}),this}withUnitPriceLessThan(e){return this.filters.push({unitPrice:{$lt:e}}),this}withUnitPriceLessThanOrEqualTo(e){return this.filters.push({unitPrice:{$lte:e}}),this}withUnitPriceBetween(e,t){return this.filters.push({unitPrice:{$between:[e,t]}}),this}withUnitPriceIsKnown(){return this.filters.push({unitPrice:{$isNull:!1}}),this}withUnitPriceIsUnknown(){return this.filters.push({unitPrice:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByProductNameAscending(){return this.query.orderBy("productName","asc"),this}orderByProductNameDescending(){return this.query.orderBy("productName","desc"),this}orderByQuantityAscending(){return this.query.orderBy("quantity","asc"),this}orderByQuantityDescending(){return this.query.orderBy("quantity","desc"),this}orderByUnitPriceAscending(){return this.query.orderBy("unitPrice","asc"),this}orderByUnitPriceDescending(){return this.query.orderBy("unitPrice","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}minQuantity(){return this.minQuantityAs("minOfQuantity")}minQuantityAs(e){return this.query.aggregate("min","quantity",e),this}maxQuantity(){return this.maxQuantityAs("maxOfQuantity")}maxQuantityAs(e){return this.query.aggregate("max","quantity",e),this}sumQuantity(){return this.sumQuantityAs("sumOfQuantity")}sumQuantityAs(e){return this.query.aggregate("sum","quantity",e),this}avgQuantity(){return this.avgQuantityAs("avgOfQuantity")}avgQuantityAs(e){return this.query.aggregate("avg","quantity",e),this}standardDeviationQuantity(){return this.standardDeviationQuantityAs("standardDeviationOfQuantity")}standardDeviationQuantityAs(e){return this.query.aggregate("stddev","quantity",e),this}squareRootOfPopulationStandardDeviationQuantity(){return this.squareRootOfPopulationStandardDeviationQuantityAs("squareRootOfPopulationStandardDeviationOfQuantity")}squareRootOfPopulationStandardDeviationQuantityAs(e){return this.query.aggregate("stddev_pop","quantity",e),this}sampleVarianceQuantity(){return this.sampleVarianceQuantityAs("sampleVarianceOfQuantity")}sampleVarianceQuantityAs(e){return this.query.aggregate("var_samp","quantity",e),this}samplePopulationVarianceQuantity(){return this.samplePopulationVarianceQuantityAs("samplePopulationVarianceOfQuantity")}samplePopulationVarianceQuantityAs(e){return this.query.aggregate("var_pop","quantity",e),this}minUnitPrice(){return this.minUnitPriceAs("minOfUnitPrice")}minUnitPriceAs(e){return this.query.aggregate("min","unitPrice",e),this}maxUnitPrice(){return this.maxUnitPriceAs("maxOfUnitPrice")}maxUnitPriceAs(e){return this.query.aggregate("max","unitPrice",e),this}sumUnitPrice(){return this.sumUnitPriceAs("sumOfUnitPrice")}sumUnitPriceAs(e){return this.query.aggregate("sum","unitPrice",e),this}avgUnitPrice(){return this.avgUnitPriceAs("avgOfUnitPrice")}avgUnitPriceAs(e){return this.query.aggregate("avg","unitPrice",e),this}standardDeviationUnitPrice(){return this.standardDeviationUnitPriceAs("standardDeviationOfUnitPrice")}standardDeviationUnitPriceAs(e){return this.query.aggregate("stddev","unitPrice",e),this}squareRootOfPopulationStandardDeviationUnitPrice(){return this.squareRootOfPopulationStandardDeviationUnitPriceAs("squareRootOfPopulationStandardDeviationOfUnitPrice")}squareRootOfPopulationStandardDeviationUnitPriceAs(e){return this.query.aggregate("stddev_pop","unitPrice",e),this}sampleVarianceUnitPrice(){return this.sampleVarianceUnitPriceAs("sampleVarianceOfUnitPrice")}sampleVarianceUnitPriceAs(e){return this.query.aggregate("var_samp","unitPrice",e),this}samplePopulationVarianceUnitPrice(){return this.samplePopulationVarianceUnitPriceAs("samplePopulationVarianceOfUnitPrice")}samplePopulationVarianceUnitPriceAs(e){return this.query.aggregate("var_pop","unitPrice",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByCustomerOrder(){return this.query.groupBy("customerOrder"),this}groupByCustomerOrderAs(e){return this.query.groupBy("customerOrder"),this}groupByProductName(){return this.query.groupBy("productName"),this}groupByProductNameAs(e){return this.query.groupBy("productName"),this}groupByQuantity(){return this.query.groupBy("quantity"),this}groupByQuantityAs(e){return this.query.groupBy("quantity"),this}groupByUnitPrice(){return this.query.groupBy("unitPrice"),this}groupByUnitPriceAs(e){return this.query.groupBy("unitPrice"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByCustomerOrderAs(e,t,i=!0){return this.query.facetBy(e,"customerOrder",t,i,{kind:"facet",method:"facetByCustomerOrderAs",relation:"customerOrder",alias:e}),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof se?u:se.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof se?f:se.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof se?o:se.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class rn{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new se}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class de{static platforms(){return new Er(!1)}static platformsWithMinimalFields(){return new Er(!0)}static orderStatuses(){return new Nr(!1)}static orderStatusesWithMinimalFields(){return new Nr(!0)}static customers(){return new Tr(!1)}static customersWithMinimalFields(){return new Tr(!0)}static customerOrders(){return new Rr(!1)}static customerOrdersWithMinimalFields(){return new Rr(!0)}static orderItems(){return new kr(!1)}static orderItemsWithMinimalFields(){return new kr(!0)}}class D extends Error{constructor(e,t,i){const s=`select${i.charAt(0).toUpperCase()}${i.slice(1)}(...)`,n={error:"TeaQLNotLoadedError",root:e,accessPath:t.split("."),breakPoint:i,missingPreload:[i],suggestedFix:s,severity:"error",humanMessage:`访问 ${e}.${t} 时缺少预加载。请在查询中加入 ${s}`};super(JSON.stringify(n)),this.root=e,this.accessPath=t,this.breakPoint=i,this.name="TeaQLNotLoadedError",this.details=n}root;accessPath;breakPoint;details}function T(r,e){return r?`${r}.${e}`:e}class g{constructor(e,t=!0,i){this.value=e,this.present=t,this.notLoaded=i}value;present;notLoaded;static missing(){return new g(void 0,!1)}static notLoaded(e){return new g(void 0,!1,e)}eval(){if(this.notLoaded)throw this.notLoaded;return this.present?this.value:void 0}isPresent(){if(this.notLoaded)throw this.notLoaded;return this.present}orElse(e){const t=this.eval();return this.present&&t!=null?t:e}}class ge{constructor(e,t="Platform(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}name(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"name");return this.value.isLoaded("name")?new g(this.value.name):g.notLoaded(new D(this.root,e,"name"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}orderStatusList(){const e=T(this.path,"orderStatusList");return this.notLoaded?new De([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("orderStatusList")?new De(this.value.orderStatusList(),this.root,e):new De([],this.root,e,!1,new D(this.root,e,"orderStatusList")):De.missing(this.root,e)}customerList(){const e=T(this.path,"customerList");return this.notLoaded?new Be([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("customerList")?new Be(this.value.customerList(),this.root,e):new Be([],this.root,e,!1,new D(this.root,e,"customerList")):Be.missing(this.root,e)}}class Ae{constructor(e,t="OrderStatus(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}name(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"name");return this.value.isLoaded("name")?new g(this.value.name):g.notLoaded(new D(this.root,e,"name"))}code(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"code");return this.value.isLoaded("code")?new g(this.value.code):g.notLoaded(new D(this.root,e,"code"))}color(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"color");return this.value.isLoaded("color")?new g(this.value.color):g.notLoaded(new D(this.root,e,"color"))}displayOrder(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"displayOrder");return this.value.isLoaded("displayOrder")?new g(this.value.displayOrder):g.notLoaded(new D(this.root,e,"displayOrder"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}platformId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"platform");return this.value.isLoaded("platform")?new g(this.value.platform):g.notLoaded(new D(this.root,e,"platform"))}platform(){const e=T(this.path,"platform");if(this.notLoaded)return new ge(void 0,this.root,e,this.notLoaded);if(!this.value)return new ge(void 0,this.root,e);if(!this.value.isLoaded("platform"))return new ge(void 0,this.root,e,new D(this.root,e,"platform"));const t=this.value.platform,i=t==null?void 0:t instanceof W?t:W.fromRecord({id:t});return new ge(i,this.root,e)}customerOrderList(){const e=T(this.path,"customerOrderList");return this.notLoaded?new ce([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("customerOrderList")?new ce(this.value.customerOrderList(),this.root,e):new ce([],this.root,e,!1,new D(this.root,e,"customerOrderList")):ce.missing(this.root,e)}}class Se{constructor(e,t="Customer(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}name(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"name");return this.value.isLoaded("name")?new g(this.value.name):g.notLoaded(new D(this.root,e,"name"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}platformId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"platform");return this.value.isLoaded("platform")?new g(this.value.platform):g.notLoaded(new D(this.root,e,"platform"))}platform(){const e=T(this.path,"platform");if(this.notLoaded)return new ge(void 0,this.root,e,this.notLoaded);if(!this.value)return new ge(void 0,this.root,e);if(!this.value.isLoaded("platform"))return new ge(void 0,this.root,e,new D(this.root,e,"platform"));const t=this.value.platform,i=t==null?void 0:t instanceof W?t:W.fromRecord({id:t});return new ge(i,this.root,e)}customerOrderList(){const e=T(this.path,"customerOrderList");return this.notLoaded?new ce([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("customerOrderList")?new ce(this.value.customerOrderList(),this.root,e):new ce([],this.root,e,!1,new D(this.root,e,"customerOrderList")):ce.missing(this.root,e)}}class be{constructor(e,t="CustomerOrder(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}orderNumber(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"orderNumber");return this.value.isLoaded("orderNumber")?new g(this.value.orderNumber):g.notLoaded(new D(this.root,e,"orderNumber"))}orderDate(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"orderDate");return this.value.isLoaded("orderDate")?new g(this.value.orderDate):g.notLoaded(new D(this.root,e,"orderDate"))}totalAmount(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"totalAmount");return this.value.isLoaded("totalAmount")?new g(this.value.totalAmount):g.notLoaded(new D(this.root,e,"totalAmount"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}customerId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"customer");return this.value.isLoaded("customer")?new g(this.value.customer):g.notLoaded(new D(this.root,e,"customer"))}statusId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"status");return this.value.isLoaded("status")?new g(this.value.status):g.notLoaded(new D(this.root,e,"status"))}customer(){const e=T(this.path,"customer");if(this.notLoaded)return new Se(void 0,this.root,e,this.notLoaded);if(!this.value)return new Se(void 0,this.root,e);if(!this.value.isLoaded("customer"))return new Se(void 0,this.root,e,new D(this.root,e,"customer"));const t=this.value.customer,i=t==null?void 0:t instanceof G?t:G.fromRecord({id:t});return new Se(i,this.root,e)}status(){const e=T(this.path,"status");if(this.notLoaded)return new Ae(void 0,this.root,e,this.notLoaded);if(!this.value)return new Ae(void 0,this.root,e);if(!this.value.isLoaded("status"))return new Ae(void 0,this.root,e,new D(this.root,e,"status"));const t=this.value.status,i=t==null?void 0:t instanceof V?t:V.fromRecord({id:t});return new Ae(i,this.root,e)}orderItemList(){const e=T(this.path,"orderItemList");return this.notLoaded?new Qe([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("orderItemList")?new Qe(this.value.orderItemList(),this.root,e):new Qe([],this.root,e,!1,new D(this.root,e,"orderItemList")):Qe.missing(this.root,e)}}class St{constructor(e,t="OrderItem(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}productName(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"productName");return this.value.isLoaded("productName")?new g(this.value.productName):g.notLoaded(new D(this.root,e,"productName"))}quantity(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"quantity");return this.value.isLoaded("quantity")?new g(this.value.quantity):g.notLoaded(new D(this.root,e,"quantity"))}unitPrice(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"unitPrice");return this.value.isLoaded("unitPrice")?new g(this.value.unitPrice):g.notLoaded(new D(this.root,e,"unitPrice"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}customerOrderId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"customerOrder");return this.value.isLoaded("customerOrder")?new g(this.value.customerOrder):g.notLoaded(new D(this.root,e,"customerOrder"))}customerOrder(){const e=T(this.path,"customerOrder");if(this.notLoaded)return new be(void 0,this.root,e,this.notLoaded);if(!this.value)return new be(void 0,this.root,e);if(!this.value.isLoaded("customerOrder"))return new be(void 0,this.root,e,new D(this.root,e,"customerOrder"));const t=this.value.customerOrder,i=t==null?void 0:t instanceof K?t:K.fromRecord({id:t});return new be(i,this.root,e)}}class De{constructor(e,t="OrderStatus(null)",i="",s=!0,n){this.items=e,this.root=t,this.path=i,this.present=s,this.notLoaded=n}items;root;path;present;notLoaded;static missing(e,t=""){return new De([],e,t,!1)}size(){return this.notLoaded?g.notLoaded(this.notLoaded):this.present?new g(this.items.length):g.missing()}first(){return this.get(0)}get(e){const t=T(this.path,`get(${e})`);return this.notLoaded?new Ae(void 0,this.root,t,this.notLoaded):!this.present||e<0||e>=this.items.length?new Ae(void 0,this.root,t):new Ae(this.items[e],this.root,t)}}class Be{constructor(e,t="Customer(null)",i="",s=!0,n){this.items=e,this.root=t,this.path=i,this.present=s,this.notLoaded=n}items;root;path;present;notLoaded;static missing(e,t=""){return new Be([],e,t,!1)}size(){return this.notLoaded?g.notLoaded(this.notLoaded):this.present?new g(this.items.length):g.missing()}first(){return this.get(0)}get(e){const t=T(this.path,`get(${e})`);return this.notLoaded?new Se(void 0,this.root,t,this.notLoaded):!this.present||e<0||e>=this.items.length?new Se(void 0,this.root,t):new Se(this.items[e],this.root,t)}}class ce{constructor(e,t="CustomerOrder(null)",i="",s=!0,n){this.items=e,this.root=t,this.path=i,this.present=s,this.notLoaded=n}items;root;path;present;notLoaded;static missing(e,t=""){return new ce([],e,t,!1)}size(){return this.notLoaded?g.notLoaded(this.notLoaded):this.present?new g(this.items.length):g.missing()}first(){return this.get(0)}get(e){const t=T(this.path,`get(${e})`);return this.notLoaded?new be(void 0,this.root,t,this.notLoaded):!this.present||e<0||e>=this.items.length?new be(void 0,this.root,t):new be(this.items[e],this.root,t)}}class Qe{constructor(e,t="OrderItem(null)",i="",s=!0,n){this.items=e,this.root=t,this.path=i,this.present=s,this.notLoaded=n}items;root;path;present;notLoaded;static missing(e,t=""){return new Qe([],e,t,!1)}size(){return this.notLoaded?g.notLoaded(this.notLoaded):this.present?new g(this.items.length):g.missing()}first(){return this.get(0)}get(e){const t=T(this.path,`get(${e})`);return this.notLoaded?new St(void 0,this.root,t,this.notLoaded):!this.present||e<0||e>=this.items.length?new St(void 0,this.root,t):new St(this.items[e],this.root,t)}}class Ft{static platform(e){return new ge(e,`Platform(id=${e?.id??"null"})`)}static orderStatus(e){return new Ae(e,`OrderStatus(id=${e?.id??"null"})`)}static customer(e){return new Se(e,`Customer(id=${e?.id??"null"})`)}static customerOrder(e){return new be(e,`CustomerOrder(id=${e?.id??"null"})`)}static orderItem(e){return new St(e,`OrderItem(id=${e?.id??"null"})`)}}const ui={Platform:{table:"platform_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{orderStatusList:{targetEntity:"OrderStatus",localKey:"id",foreignKey:"platform",many:!0},customerList:{targetEntity:"Customer",localKey:"id",foreignKey:"platform",many:!0}}},OrderStatus:{table:"order_status_data",auditMaskFields:[],columns:{platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},code:{columnName:"code",modelName:"code",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},color:{columnName:"color",modelName:"color",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},displayOrder:{columnName:"display_order",modelName:"display_order",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1},customerOrderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"status",many:!0}}},Customer:{table:"customer_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1},customerOrderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"customer",many:!0}}},CustomerOrder:{table:"customer_order_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},customer:{columnName:"customer",modelName:"customer",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},status:{columnName:"status",modelName:"status",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},orderNumber:{columnName:"order_number",modelName:"order_number",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},orderDate:{columnName:"order_date",modelName:"order_date",logPolicy:"plain",logicalType:"date",decode:"date",nullable:!1},totalAmount:{columnName:"total_amount",modelName:"total_amount",logPolicy:"plain",logicalType:"decimal",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{customer:{targetEntity:"Customer",localKey:"customer",foreignKey:"id",many:!1},status:{targetEntity:"OrderStatus",localKey:"status",foreignKey:"id",many:!1},orderItemList:{targetEntity:"OrderItem",localKey:"id",foreignKey:"customerOrder",many:!0}}},OrderItem:{table:"order_item_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},customerOrder:{columnName:"customer_order",modelName:"customer_order",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},productName:{columnName:"product_name",modelName:"product_name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},quantity:{columnName:"quantity",modelName:"quantity",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1},unitPrice:{columnName:"unit_price",modelName:"unit_price",logPolicy:"plain",logicalType:"decimal",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{customerOrder:{targetEntity:"CustomerOrder",localKey:"customerOrder",foreignKey:"id",many:!1}}}};async function sn(r){let e=(await de.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(r))[0];e||(e=W.teaqlBootstrapNew("1"),e.updateName("Commerce Test Platform"),await e.auditAs("create generated Domain Root Platform").save(r)),r.withActiveRoot({entity:"Platform",id:e.id});let t=(await de.orderStatuses().withIdIs("1001").comment("what: locate generated constant OrderStatus(1001)").purpose("why: idempotent runtime bootstrap").executeForList(r))[0];if(!t)t=V.teaqlBootstrapNew("1001"),t.updatePlatform(e),t.updateName("New"),t.updateCode("NEW"),t.updateColor("#94A3B8"),t.updateDisplayOrder(1),await t.auditAs("create model constant OrderStatus(1001)").save(r);else{let n=!1;String(t.platform?.id??t.platform)!==String(e.id)&&(t.updatePlatform(e),n=!0),t.name!=="New"&&(t.updateName("New"),n=!0),t.code!=="NEW"&&(t.updateCode("NEW"),n=!0),t.color!=="#94A3B8"&&(t.updateColor("#94A3B8"),n=!0),t.displayOrder!==1&&(t.updateDisplayOrder(1),n=!0),n&&await t.auditAs("reconcile model constant OrderStatus(1001)").save(r)}let i=(await de.orderStatuses().withIdIs("1002").comment("what: locate generated constant OrderStatus(1002)").purpose("why: idempotent runtime bootstrap").executeForList(r))[0];if(!i)i=V.teaqlBootstrapNew("1002"),i.updatePlatform(e),i.updateName("Paid"),i.updateCode("PAID"),i.updateColor("#22C55E"),i.updateDisplayOrder(2),await i.auditAs("create model constant OrderStatus(1002)").save(r);else{let n=!1;String(i.platform?.id??i.platform)!==String(e.id)&&(i.updatePlatform(e),n=!0),i.name!=="Paid"&&(i.updateName("Paid"),n=!0),i.code!=="PAID"&&(i.updateCode("PAID"),n=!0),i.color!=="#22C55E"&&(i.updateColor("#22C55E"),n=!0),i.displayOrder!==2&&(i.updateDisplayOrder(2),n=!0),n&&await i.auditAs("reconcile model constant OrderStatus(1002)").save(r)}let s=(await de.orderStatuses().withIdIs("1003").comment("what: locate generated constant OrderStatus(1003)").purpose("why: idempotent runtime bootstrap").executeForList(r))[0];if(!s)s=V.teaqlBootstrapNew("1003"),s.updatePlatform(e),s.updateName("Cancelled"),s.updateCode("CANCELLED"),s.updateColor("#EF4444"),s.updateDisplayOrder(3),await s.auditAs("create model constant OrderStatus(1003)").save(r);else{let n=!1;String(s.platform?.id??s.platform)!==String(e.id)&&(s.updatePlatform(e),n=!0),s.name!=="Cancelled"&&(s.updateName("Cancelled"),n=!0),s.code!=="CANCELLED"&&(s.updateCode("CANCELLED"),n=!0),s.color!=="#EF4444"&&(s.updateColor("#EF4444"),n=!0),s.displayOrder!==3&&(s.updateDisplayOrder(3),n=!0),n&&await s.auditAs("reconcile model constant OrderStatus(1003)").save(r)}}const nn=new Ss(ui,{Platform:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&t.push({ruleId:"required",location:x.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&t.push({ruleId:"max_length",location:x.property("name"),inputValue:e.payload.name,systemValue:100})}},OrderStatus:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&t.push({ruleId:"required",location:x.property("platform")}),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&t.push({ruleId:"required",location:x.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&t.push({ruleId:"max_length",location:x.property("name"),inputValue:e.payload.name,systemValue:100}),(e.action==="Create"&&e.payload.code===void 0||e.payload.code===null)&&t.push({ruleId:"required",location:x.property("code")}),e.payload.code!=null&&[...String(e.payload.code)].length>100&&t.push({ruleId:"max_length",location:x.property("code"),inputValue:e.payload.code,systemValue:100}),(e.action==="Create"&&e.payload.color===void 0||e.payload.color===null)&&t.push({ruleId:"required",location:x.property("color")}),e.payload.color!=null&&[...String(e.payload.color)].length>100&&t.push({ruleId:"max_length",location:x.property("color"),inputValue:e.payload.color,systemValue:100}),(e.action==="Create"&&e.payload.display_order===void 0||e.payload.display_order===null)&&t.push({ruleId:"required",location:x.property("display_order")})}},Customer:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&t.push({ruleId:"required",location:x.property("platform")}),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&t.push({ruleId:"required",location:x.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&t.push({ruleId:"max_length",location:x.property("name"),inputValue:e.payload.name,systemValue:100})}},CustomerOrder:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.customer===void 0||e.payload.customer===null)&&t.push({ruleId:"required",location:x.property("customer")}),(e.action==="Create"&&e.payload.status===void 0||e.payload.status===null)&&t.push({ruleId:"required",location:x.property("status")}),(e.action==="Create"&&e.payload.order_number===void 0||e.payload.order_number===null)&&t.push({ruleId:"required",location:x.property("order_number")}),e.payload.order_number!=null&&[...String(e.payload.order_number)].length>100&&t.push({ruleId:"max_length",location:x.property("order_number"),inputValue:e.payload.order_number,systemValue:100}),(e.action==="Create"&&e.payload.order_date===void 0||e.payload.order_date===null)&&t.push({ruleId:"required",location:x.property("order_date")}),(e.action==="Create"&&e.payload.total_amount===void 0||e.payload.total_amount===null)&&t.push({ruleId:"required",location:x.property("total_amount")})}},OrderItem:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.customer_order===void 0||e.payload.customer_order===null)&&t.push({ruleId:"required",location:x.property("customer_order")}),(e.action==="Create"&&e.payload.product_name===void 0||e.payload.product_name===null)&&t.push({ruleId:"required",location:x.property("product_name")}),e.payload.product_name!=null&&[...String(e.payload.product_name)].length>100&&t.push({ruleId:"max_length",location:x.property("product_name"),inputValue:e.payload.product_name,systemValue:100}),(e.action==="Create"&&e.payload.quantity===void 0||e.payload.quantity===null)&&t.push({ruleId:"required",location:x.property("quantity")}),(e.action==="Create"&&e.payload.unit_price===void 0||e.payload.unit_price===null)&&t.push({ruleId:"required",location:x.property("unit_price")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Commerce Test Platform"}},constants:[{entity:"OrderStatus",id:"1001",values:{platform:"1",name:"New",code:"NEW",color:"#94A3B8",displayOrder:1}},{entity:"OrderStatus",id:"1002",values:{platform:"1",name:"Paid",code:"PAID",color:"#22C55E",displayOrder:2}},{entity:"OrderStatus",id:"1003",values:{platform:"1",name:"Cancelled",code:"CANCELLED",color:"#EF4444",displayOrder:3}}],ensure:sn});function on(r){const e=Object.fromEntries(Object.entries(r.facets).map(([t,i])=>[t,Array.from(i)]));return{data:Array.from(r),resultCode:0,status:"YES",recordCount:r.totalCountOrLength(),version:"1.001",...Object.keys(e).length?{facets:e}:{},...Object.keys(r.aggregations).length?{aggregations:r.aggregations}:{}}}const Jt=document.querySelector("#status"),xr=document.querySelector("#result"),Dr=document.querySelector("#trace"),Br=document.querySelector("#sql"),Qr=document.querySelector("#evidence-rows"),it=document.querySelector("#persist"),hi=document.querySelector("#logging"),Mt=document.querySelector("#reset"),je=document.querySelector("#query"),ot=document.querySelector("#search"),Xt=document.querySelector("#example"),li=JSON.stringify(JSON.stringify({filter:{orderNumber:{$contains:"KEEP"}}})),$t=`Q.customerOrdersWithMinimalFields() - .filterByJson(${li}) - .countAs("totalOrders") - .facetByStatusAs("statusCounts", Q.orderStatusesWithMinimalFields() - .selectName().selectColor().countAs("orderCount") - .sumTotalAmountOfCustomerOrdersAs("orderTotalAmount", Q.customerOrdersWithMinimalFields()) - .orderByDisplayOrderAscending().comment("load status facets")) - .selectOrderNumber().selectOrderDate() - .selectStatusWith(Q.orderStatusesWithMinimalFields() - .selectName().selectColor().comment("load status")) - .selectOrderItemListWith(Q.orderItemsWithMinimalFields() - .selectProductName().selectQuantity().orderByIdAscending().limit(3).comment("load item previews")) - .countOrderItemsAs("itemCount") - .orderByOrderDateDescending().orderByIdDescending() - .comment("load order list").purpose("render order list page")`;ot.value=$t;let ne;const Zt=globalThis.crossOriginIsolated&&typeof navigator.storage?.getDirectory=="function";it.checked=Zt&&localStorage.getItem("teaql-browser-order-storage")==="opfs";it.disabled=!Zt;Zt||(document.querySelector("#opfs-note").textContent="(not available on this host; memory remains fully browser-local)");async function an(r){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),t=await Fs.open(e,{...ui},{storage:r,databaseName:"teaql-browser-orders.sqlite3"});t.install(nn),t.setDiagnosticSQLLogSink(void 0).setMutationLoggingEnabled(!1);const i=Object.freeze({policyId:"browser-order-seed",version:"1",fingerprint:"sha256:browser-order-seed-v1"}),s=new Jr().insertResource("dataService",t).withMutationPolicyRegistry(new fs(()=>({identity:i,review:(n,o)=>o.operations.length>0?{verdict:"allow"}:{verdict:"deny",code:"EMPTY_GRAPH",message:"empty mutation graph"}}))).withMutationPolicyApprovalProvider(new ps(n=>({policy:n,approvedBy:"browser-demo-owner",approvedAt:new Date})));return t.setUserContext(s),await s.ensureSchema(),await s.ensureSchema(),{client:t,context:s,evidence:new Ts,diagnostics:[]}}async function di({context:r}){if((await de.customerOrdersWithMinimalFields().limit(1).comment("detect existing order demo").purpose("keep mutation seeding idempotent").executeForList(r)).length)return;const t=(await de.platforms().limit(2).comment("load bootstrap platform").purpose("prepare order demo").executeForList(r))[0],i=de.customers().comment("initialize demo customer").purpose("prepare order demo").newEntity(r);i.updateName("North Star Retail").updatePlatform(t.id),await i.auditAs("seed browser order customer").save(r);for(let s=1;s<=4;s++){const n=de.customerOrders().comment("initialize demo order").purpose("prepare order demo").newEntity(r);n.updateCustomer(i.id).updateOrderNumber(s<4?`KEEP-00${s}`:"DROP-004").updateOrderDate(`2026-10-0${s}`).updateTotalAmount(s<4?s*100:900),s===1?n.updateStatusToNew():n.updateStatusToPaid(),await n.auditAs("seed browser order").save(r);for(let o=1;o<=5;o++){const a=de.orderItems().comment("initialize demo item").purpose("prepare item previews").newEntity(r);a.updateCustomerOrder(n.id).updateProductName(`Box ${o}`).updateQuantity(o).updateUnitPrice(20),await a.auditAs("seed browser order item").save(r)}}}async function Pt(r){xr.textContent="",Dr.textContent="",Br.textContent="[]",Qr.replaceChildren(),r.evidence.enableAll(),r.diagnostics.length=0;const e=Xs.parse(ot.value,de);if(typeof e?.executeForPage!="function")throw new Error("The query must contain a generated executable Q request");r.client.setRuntimeTelemetrySink(r.evidence).setQueryLoggingEnabled(hi.checked).setDiagnosticSQLLogSink({write:a=>r.diagnostics.push(a)});const t=await e.executeForPage(r.context,1,1),i=on(t.data),s={resultCode:i.resultCode,status:i.status,version:i.version,recordCount:t.totalCount,data:t.data.map(a=>{const u=Ft.customerOrder(a),h=u.orderItemList().size().eval();if(h==null)throw new Error("Selected item list unexpectedly has a null size");return{id:a.id,version:a.version,orderNumber:u.orderNumber().eval(),orderDate:u.orderDate().eval(),status:{name:u.status().name().eval(),color:u.status().color().eval()},items:Array.from({length:h},(l,d)=>({productName:u.orderItemList().get(d).productName().eval(),quantity:u.orderItemList().get(d).quantity().eval()})),itemCount:a.itemCount}}),metadata:{totalCount:t.totalCount,pageOffset:1,pageSize:1,aggregations:t.data.aggregations,searchWarnings:e.dynamicSearchWarnings??[]},facets:{statusCounts:t.data.facets.statusCounts.map(a=>({id:a.id,name:Ft.orderStatus(V.fromRecord(a)).name().eval(),color:Ft.orderStatus(V.fromRecord(a)).color().eval(),orderCount:a.orderCount,orderTotalAmount:a.orderTotalAmount}))}};xr.textContent=JSON.stringify(s,null,2);const n=r.evidence.snapshot(),o=n.map(a=>{const u=a.traceChain??[],h=u.filter(c=>c.kind==="purpose"),l=h.length===1?`${h[0].detail}: ${u.filter(c=>c.kind==="comment").map(c=>c.detail).join(" → ")}`:"TraceChain unavailable",d=document.createElement("tr");for(const c of[`${a.elapsedMicros} µs`,a.tracePath.find(f=>f.kind==="request")?.name??"—",l,a.debugSQL]){const f=document.createElement("td");f.textContent=c,d.append(f)}return{row:d,businessTrace:l}});Qr.replaceChildren(...o.map(a=>a.row)),Dr.textContent=o.map(a=>a.businessTrace).join(` -`),Br.textContent=JSON.stringify(n,null,2),Jt.textContent=`${r.client.storage.toUpperCase()} · ${t.totalCount} matches · ${n.length} SQL statements · ${r.diagnostics.length} diagnostics · policy installed · ready`}async function ci(r){Jt.textContent=`Opening ${r.toUpperCase()} SQLite/WASM…`;const e=ne;ne=void 0,await e?.client.close();const t=await an(r);ne=t,await di(t),await Pt(t)}function at(r){Jt.textContent=r instanceof Error?`${r.name}: ${r.message}`:String(r)}je.addEventListener("click",async()=>{if(ne){je.disabled=!0;try{await Pt(ne)}catch(r){at(r)}finally{je.disabled=!1}}});document.querySelector("#preset").addEventListener("click",()=>{ot.value=$t,Xt.value="filtered",je.click()});Xt.addEventListener("change",()=>{ot.value=Xt.value==="all"?$t.replace(li,JSON.stringify("{}")):$t,je.click()});ot.addEventListener("keydown",r=>{(r.ctrlKey||r.metaKey)&&r.key==="Enter"&&je.click()});hi.addEventListener("change",()=>{ne&&Pt(ne).catch(at)});it.addEventListener("change",()=>{const r=it.checked?"opfs":"memory";localStorage.setItem("teaql-browser-order-storage",r),ci(r).catch(at)});Mt.addEventListener("click",async()=>{if(ne){Mt.disabled=!0;try{await ne.client.reset(ne.context),await di(ne),await Pt(ne)}catch(r){at(r)}finally{Mt.disabled=!1}}});ci(it.checked?"opfs":"memory").catch(at); diff --git a/assets/index-DTZ5iA72.js b/assets/index-DTZ5iA72.js deleted file mode 100644 index 0f52273536cb7098b6ffb379e828748cfe919c81..0000000000000000000000000000000000000000 --- a/assets/index-DTZ5iA72.js +++ /dev/null @@ -1,31 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const a of n.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&r(a)}).observe(document,{childList:!0,subtree:!0});function t(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(s){if(s.ep)return;s.ep=!0;const n=t(s);fetch(s.href,n)}})();var Zt={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},ei=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],Me=class extends Error{constructor(e){super(`Unsupported locale: ${e}`),this.localeCode=e}},ti={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function et(i){if(typeof i!="string"||!i.trim())throw new Me(i);const e=i.trim().replace(/_/g,"-").toLowerCase(),t=ei.find(s=>s.toLowerCase()===e);if(t)return t;const r=ti[e];if(!r)throw new Me(i);return r}var Ce=class{constructor(e,t){if(this.data=e,this.fallback=t,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(et)}message(e,t){return this.data.locales[e]?.messages[t]??this.fallback?.data.locales[e]?.messages[t]??this.data.locales.en?.messages[t]??this.fallback?.data.locales.en?.messages[t]??t}translate(e,t){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),a=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(t,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(a)),e}};Ce.builtin=new Ce(Zt);var ii=Ce,tt=Symbol("teaql.context.schema-capability"),Ve=new WeakMap,ri=1;function si(i){if(!i||typeof i!="object"&&typeof i!="function")return String(i);const e=i;let t=Ve.get(e);return t||(t=ri++,Ve.set(e,t)),String(t)}var We=class extends Error{constructor(i,e,t){super(`context root ${i}: expected ${e}`),this.reason=i,this.expectedType=e,this.activeRoot=t,this.name="ContextRootError"}},it=class{constructor(){this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(i,e)=>this.getContinuousPageCursor(i,e),put:(i,e,t)=>this.putContinuousPageCursor(i,e,t),observe:(i,e)=>{this.continuousPagePlan=i,this.continuousPageCursorId=e}},this.idSetPaginationRuntime={owner:"",scope:"",get:i=>this.idSetStore().get(i),put:(i,e)=>this.idSetStore().put(i,e),build:(i,e)=>this.singleFlightIdSetBuild(i,e),observe:(i,e)=>{this.idSetPaginationPlan=i,this.idSetPaginationCount=e,this.idSetPaginationCountAccuracy=i==="ID_SET_BUILD"||i==="ID_SET_HIT"?"EXACT":i==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=ii.builtin}setLocaleCode(i){const e=et(i);return this.locale=e,this}setLanguageCode(i){return this.setLocaleCode(i)}installI18nCatalog(i){if(!i)throw new Error("catalog is required");return this.i18nCatalog=i,this}installIdSetPaginationStore(i){if(!i)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",i)}translateCheckResults(i){return i.map(e=>this.i18nCatalog.translate(e,this.locale))}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(i){const e=String(i.sourceLabel||""),t=e.toLowerCase();if(!i.entityType||!i.modelPath||!e||t.includes("authorization")||t.includes("cookie")||t.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const r=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",r),r.push(Object.freeze({...i})),this}finishFixEvidence(){const i=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...i])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(i,e){return this.resources.set(i,e),this}getResource(i){return this.resources.get(i)}removeResource(i){return this.resources.delete(i),this}requireResource(i){const e=this.getResource(i);if(e===void 0)throw new Error(`Required UserContext resource is missing: ${i}`);return e}ensureSchema(){const i=this.requireResource("dataService"),e=i[tt];if(!e)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return e.call(i,this)}withActiveRoot(i){if(!i||!i.entity||i.id===void 0||i.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...i}))}requireActiveRoot(i){const e=this.getResource("activeRoot");if(!e)throw new We("missing",i);if(e.entity!==i)throw new We("type_mismatch",i,e);return e}prepareQuery(i){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const e=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,e?`${e.entity}:${String(e.id)}`:"-",si(this.getResource("dataService"))].join("|"),i.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(i,e){const t=`${i}:${e}`,r=this.continuousPageCursors.get(t);if(r&&r.expiresAt<=Date.now()){this.continuousPageCursors.delete(t);return}return r}putContinuousPageCursor(i,e,t){if(this.continuousPageCursors.size>=4096){const r=[...this.continuousPageCursors.entries()].sort((s,n)=>s[1].expiresAt-n[1].expiresAt)[0];r&&this.continuousPageCursors.delete(r[0])}this.continuousPageCursors.set(`${i}:${e}`,t)}getRetainedIdSet(i){const e=this.retainedIdSets.get(i);if(e&&e.expiresAt<=Date.now()){this.retainedIdSets.delete(i);return}return e}idSetStore(){return this.getResource("idSetPaginationStore")??{get:i=>this.getRetainedIdSet(i),put:(i,e)=>this.putRetainedIdSet(i,e),invalidate:i=>{this.retainedIdSets.delete(i)}}}putRetainedIdSet(i,e){if(e.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const r=()=>[...this.retainedIdSets.values()].reduce((s,n)=>s+n.ids.byteLength,0);for(;this.retainedIdSets.size>=64||r()+e.ids.byteLength>268435456;){const s=[...this.retainedIdSets.entries()].sort((n,a)=>n[1].expiresAt-a[1].expiresAt)[0];if(!s)break;this.retainedIdSets.delete(s[0])}this.retainedIdSets.set(i,e)}async singleFlightIdSetBuild(i,e){const t=this.idSetBuilds.get(i);if(t)return{value:await t,built:!1};const r=e();this.idSetBuilds.set(i,r);try{return{value:await r,built:!0}}finally{this.idSetBuilds.delete(i)}}},ni=class extends Error{constructor(e){super(`Check failed: ${e.map(t=>t.message??`${t.ruleId}:${t.location}`).join("; ")}`),this.violations=e,this.name="CheckException"}};function oi(i,e){const t=i.defaultDomainRoot,r=e.defaultDomainRoot;if(t&&r&&(t.entity!==r.entity||t.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...i.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??t,constants:[...s.values()],ensure:i.ensure&&e.ensure?async n=>{await i.ensure(n),await e.ensure(n)}:e.ensure??i.ensure}}var Ue=class re{constructor(e,t,r){this.field=e,this.expr=t,this.direction=r}static new(e,t){return new re(e,null,t)}static expr(e,t){return new re("",e,t)}static asc(e){return re.new(e,"Asc")}static desc(e){return re.new(e,"Desc")}},Qe=Object.freeze({success:()=>{},failure:()=>{}}),ui=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function ai(i){const e={"teaql.operation.family":i.family,"teaql.operation.name":i.name};for(const[t,r]of Object.entries(i.attributes||{}))ui.has(t)||(e[t]=r);return Object.freeze({...i,attributes:Object.freeze(e)})}function le(i,e){if(!i)return Qe;try{const t=i.start(ai(e));let r=!1;return{run:t.run?s=>t.run(s):s=>s(),success(s){if(!r){r=!0;try{t?.success(s)}catch{}}},failure(s){if(!r){r=!0;try{t?.failure(s)}catch{}}}}}catch{return Qe}}async function ie(i,e,t,r){const s=le(i,e);try{const n=await(s.run?s.run(t):t());return s.success(r?.(n)),n}catch(n){throw s.failure(n),n}}function li(i){const e=new Map;for(const t of Object.values(i))for(const r of Object.values(t.relations||{})){if(!r.many)continue;const s=i[r.targetEntity],n=s?.columns[r.foreignKey]?.columnName,a=s?.columns.id?.columnName;if(!s||!n||!a)continue;const u=`idx_${s.table}_${n}_${a}`;let h=2166136261;for(let c=0;c>>0).toString(36),p=u.length<=30?u:`${u.slice(0,Math.max(1,29-m.length))}_${m}`;e.set(p,{name:p,table:s.table,foreignColumn:n,idColumn:a})}return[...e.values()]}async function ci(i,e,t,r){const s=Number(r);if(!Number.isSafeInteger(s)||s<0)throw new Error(`Invalid ID space floor ${r} for ${t}`);for(let n=1;n<=100;n+=1){const a=await i.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[t]);if(!a.rowCount){try{if((await i.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[t,s])).rowCount===1)return}catch(m){if(!(await i.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[t])).rowCount)throw m}continue}const u=Number(a.rows[0].id);if(u>=s)return;const h=await i.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[s,t,u]);if(h.rowCount===1)return;if(h.rowCount!==0)throw new Error(`ID space floor update for ${t} changed ${h.rowCount} rows on attempt ${n}`)}throw new Error(`Unable to synchronize ID space floor for ${t} after 100 optimistic-lock attempts`)}function hi(i){return i.startsWith('"')&&i.endsWith('"')||i.startsWith("`")&&i.endsWith("`")?i.slice(1,-1).replace(/""/g,'"').replace(/``/g,"`"):i}function di(i,e){return i===e?!0:(i instanceof Date&&(i=i.getTime()),e instanceof Date&&(e=e.getTime()),i!=null&&e!==null&&e!==void 0&&String(i)===String(e))}function Ee(i,e,t){return[{level:0,kind:"operation",name:"mutation"},{level:1,kind:"entity",name:String(i.entity)},{level:2,kind:"provider",name:e},{level:3,kind:"sql",name:t}]}function fi(i,e,t="sqlite"){let r=0,s="",n="sql";for(let a=0;a=0&&p=0&&pt.toString(16).padStart(2,"0")).join("")}'`:V(typeof i=="object"?JSON.stringify(i):String(i))}function V(i){return`'${i.replace(/'/g,"''")}'`}var mi=class{constructor(i=e=>console.debug(e)){this.writer=i}write(i){this.writer(`[TeaQL SQL][${i.operation}][${i.elapsedMicros}us] ${i.resultSummary} -comment=${i.comment??""} purpose=${i.purpose??""} auditReason=${i.auditReason??""} tracePath=${Ke(i.tracePath)} -Parameterized SQL: ${i.parameterizedSQL} params=${Ke(i.parameters)} -Debug SQL: ${i.debugSQL}`)}};function Ke(i){return JSON.stringify(i,(e,t)=>typeof t=="bigint"?t.toString():t)}var pi=class{constructor(i,e){this.driver=i,this.schemas=e,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.auditEvents=[],this.diagnosticSQLLogSink=new mi,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.checkers={},this.userContext=new it,this.bootstrap={},this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve()}install(i){return Object.assign(this.schemas,i.schemas),Object.assign(this.checkers,i.checkers),this.bootstrap=oi(this.bootstrap,i.bootstrap),this}setUserContext(i){return this.userContext=i,this}schema(i){const e=this.schemas[i];if(!e)throw new Error(`Unknown TeaQL entity: ${i}`);return e}toRuntimeMutationRecord(i,e){const t={};for(const[r,s]of Object.entries(e)){const n=i.columns[r]?r:Object.keys(i.columns).find(a=>i.columns[a].modelName===r||i.columns[a].columnName===r);n&&(t[n]=s)}return t}encode(i,e){const t=i?.id??i;if(t!==void 0)return this.driver.encode(t,e)}decodeRow(i,e,t=[]){const r=this.schema(i),s={...e};for(const[n,a]of Object.entries(r.columns)){const u=s[n];u!=null&&(a.decode==="number"&&(s[n]=Number(u)),a.decode==="string"&&(s[n]=String(u)),a.decode==="date"&&u instanceof Date&&(s[n]=u.toISOString()),a.logicalType==="boolean"&&(s[n]=!!u))}for(const n of t)s[n]!==null&&s[n]!==void 0&&(s[n]=Number(s[n]));return s}get auditTrace(){return[...this.auditEvents]}setAuditSink(i){return this.auditSink=i,this}setRuntimeTelemetrySink(i){return this.telemetrySink=i,this}setDiagnosticSQLLogSink(i){return this.diagnosticSQLLogSink=i,this}setQueryLoggingEnabled(i){return this.queryLoggingEnabled=i,this}setMutationLoggingEnabled(i){return this.mutationLoggingEnabled=i,this}setRuntimeTelemetry(i){return this.runtimeTelemetry=i,this}recordSQL(i,e,t,r,s,n,a={}){const u=i==="select";if(u&&!this.queryLoggingEnabled||!u&&!this.mutationLoggingEnabled||!this.telemetrySink&&!this.diagnosticSQLLogSink)return;const h=Object.freeze({operation:i,...a,tracePath:Object.freeze([...a.tracePath??[]]),parameterizedSQL:e,parameters:Object.freeze([...t]),debugSQL:fi(e,t,this.driver.databaseKind),elapsedMicros:Math.max(0,(Date.now()-r)*1e3),resultCount:s,affectedRows:n,resultSummary:s!==void 0?`${s} rows returned`:`${n??0} rows affected`});this.telemetrySink?.record(h),this.diagnosticSQLLogSink?.write(h)}async[tt](i){this.userContext=i,this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const e=this.bootstrapTail;let t;this.bootstrapTail=new Promise(r=>{t=r}),await e;try{if(this.bootstrap.ensure){i.insertResource("bootstrapActor","teaql-generated-bootstrap"),i.insertResource("bootstrapCategory","runtime-bootstrap");try{await this.bootstrap.ensure(i)}finally{i.removeResource("bootstrapActor"),i.removeResource("bootstrapCategory")}}else await this.ensureBootstrapData()}finally{t()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const i=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];i.length&&await this.driver.transaction(async e=>{for(const t of i)await this.reconcileBootstrapEntity(e,t)})}async reconcileBootstrapEntity(i,e){const t=this.schema(e.entity),r=this.driver.identifier(t.table),s=this.driver.identifier(t.columns.id?.columnName??"id"),n=this.driver.identifier(t.columns.version?.columnName??"version"),a=Object.entries(e.values??{}).map(([h,m])=>{const p=t.columns[h];if(!p)throw new Error(`Unknown bootstrap field ${e.entity}.${h}`);return{column:this.driver.identifier(p.columnName),value:this.driver.encode(m,p)}}),u=await i.query(`SELECT * FROM ${r} WHERE ${s} = ${this.driver.placeholder(1)}`,[e.id]);if(u.rowCount){const h=u.rows[0],m=a.filter(p=>!di(h[hi(p.column)],p.value));if(m.length){const p=m.map((c,g)=>`${c.column} = ${this.driver.placeholder(g+1)}`);p.push(`${n} = ${n} + 1`),await i.query(`UPDATE ${r} SET ${p.join(", ")} WHERE ${s} = `+this.driver.placeholder(m.length+1),[...m.map(c=>c.value),e.id])}}else{const h=[s,n,...a.map(c=>c.column)],m=[e.id,1,...a.map(c=>c.value)],p=m.map((c,g)=>this.driver.placeholder(g+1));await i.query(`INSERT INTO ${r} (${h.join(", ")}) VALUES (${p.join(", ")})`,m)}await this.driver.ensureIdFloor(i,e.entity,e.id)}async executeGraphSave(i){const e=this.graphSaveTail;let t;this.graphSaveTail=new Promise(r=>{t=r}),await e,this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence();try{const r=await this.driver.transaction(async s=>{this.graphMutationSession=s;try{return await i()}finally{this.graphMutationSession=void 0}});for(const s of this.graphCommitActions)s();return r}catch(r){for(const s of[...this.graphRollbackActions].reverse())s();throw r}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.removeResource("fixTime").finishFixEvidence(),t()}}afterGraphCommit(i){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(i)}afterGraphRollback(i){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(i)}async withMutationSession(i){return this.graphMutationSession?i(this.graphMutationSession):this.driver.transaction(i)}preflightMutation(i){if(!String(i?.comment||"").trim())throw new Error("Security audit failure: audit reason is required before mutation");i={...i,payload:{...i?.payload??{}}};const e=this.checkers[String(i.entity)];if(!e)return i;const t=[],r=this.userContext.getResource("fixTime")===void 0;r&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(e.checkAndFix(this.userContext,i,t),i.ledgerKey&&i.ledgerRoot)for(const[s,n]of Object.entries(i.payload||{}))i.ledgerRoot.set(i.ledgerKey,s,n);if(this.userContext.translateCheckResults(t),t.length)throw new ni(t);return i}finally{r&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(i){const e=le(this.runtimeTelemetry,{family:"mutation",name:`${String(i?.entity||"unknown")}.${String(i?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(i?.entity||"unknown"),"teaql.mutation.kind":String(i?.action||"unknown").toLowerCase()}});try{i=this.preflightMutation(i);const t=this.schema(i.entity),r=this.toRuntimeMutationRecord(t,i.payload||{}),s=this.driver.identifier(t.table),n=await ie(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(i.action).toLowerCase()}},()=>this.withMutationSession(async u=>{if(i.action==="Create"){const h=i.id?String(i.id):await this.driver.nextId(u,i.entity);i.id&&await this.driver.ensureIdFloor(u,i.entity,h);const m=Number(i.version||0)+1,p={...r,id:h,version:m},c=Object.keys(t.columns).filter(q=>p[q]!==void 0),g=c.map(q=>this.driver.identifier(t.columns[q].columnName)).join(", "),w=c.map((q,P)=>this.driver.placeholder(P+1)).join(", "),C=c.map(q=>this.encode(p[q],t.columns[q])),A=`INSERT INTO ${s} (${g}) VALUES (${w})`,I=Date.now(),x=await u.query(A,C);return this.recordSQL("insert",A,C,I,void 0,x.rowCount,{auditReason:String(i.comment),tracePath:Ee(i,this.driver.databaseKind,"insert")}),{success:!0,id:h,version:m,persistedRecord:await this.readPersistedRecord(u,t,h)}}if(i.action==="Update"){const h=Object.keys(t.columns).filter(x=>x!=="id"&&x!=="version"&&r[x]!==void 0),m=h.map(x=>this.encode(r[x],t.columns[x])),p=h.map((x,q)=>`${this.driver.identifier(t.columns[x].columnName)} = `+this.driver.placeholder(q+1)),c=this.driver.identifier("version");p.push(`${c} = ${c} + 1`),m.push(String(i.id));const g=[`${this.driver.identifier("id")} = ${this.driver.placeholder(m.length)}`];i.version!==void 0&&i.version!==null&&(m.push(Number(i.version)),g.push(`${c} = ${this.driver.placeholder(m.length)}`));const w=`UPDATE ${s} SET ${p.join(", ")} WHERE ${g.join(" AND ")}`,C=Date.now(),A=await u.query(w,m);if(this.recordSQL("update",w,m,C,void 0,A.rowCount,{auditReason:String(i.comment),tracePath:Ee(i,this.driver.databaseKind,"update")}),A.rowCount!==1)throw new Error(`Optimistic lock failed or ${i.entity}(${i.id}) does not exist`);const I=await this.readPersistedRecord(u,t,String(i.id));return{success:!0,id:String(i.id),version:Number(I.version),persistedRecord:I}}if(i.action==="Delete"){const h=this.driver.identifier("version"),m=[String(i.id)],p=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];i.version!==void 0&&i.version!==null&&(m.push(Number(i.version)),p.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(m.length)));const c=`UPDATE ${s} SET ${h} = -(${h} + 1) WHERE ${p.join(" AND ")}`,g=Date.now(),w=await u.query(c,m);if(this.recordSQL("delete",c,m,g,void 0,w.rowCount,{auditReason:String(i.comment),tracePath:Ee(i,this.driver.databaseKind,"delete")}),w.rowCount!==1)throw new Error(`Optimistic lock failed or ${i.entity}(${i.id}) does not exist`);const C=await this.readPersistedRecord(u,t,String(i.id));return{success:!0,id:String(i.id),version:Number(C.version),deleted:!0,persistedRecord:C}}throw new Error(`Unsupported mutation action: ${i.action}`)})),a=Object.freeze({entity:i.entity,action:i.action,id:String(n.id),reason:String(i.comment),recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.keys(i.payload||{}).sort(),version:n.version});return this.auditEvents.push(a),this.auditSink&&await ie(this.runtimeTelemetry,{family:"audit",name:`${i.entity}.audit`,attributes:{"teaql.entity.type":String(i.entity),"teaql.mutation.kind":String(i.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(i.payload||{}).length}},async()=>this.auditSink(a)),e.success(),n}catch(t){throw e.failure(t),t}}async readPersistedRecord(i,e,t){const r=Object.entries(e.columns).map(([n,a])=>`${this.driver.identifier(a.columnName)} AS ${this.driver.identifier(n)}`).join(", "),s=await i.query(`SELECT ${r} FROM ${this.driver.identifier(e.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,[t]);if(s.rowCount!==1)throw new Error(`Persisted ${e.table}(${t}) could not be read back`);return this.decodeRowForSchema(e,s.rows[0])}decodeRowForSchema(i,e){const t={...e};for(const[r,s]of Object.entries(i.columns)){const n=t[r];n!=null&&(s.decode==="number"&&(t[r]=Number(n)),s.decode==="string"&&(t[r]=String(n)),s.decode==="date"&&n instanceof Date&&(t[r]=n.toISOString()),s.logicalType==="boolean"&&(t[r]=!!n))}return t}compileExpression(i,e,t){if(Array.isArray(i?.$and))return`(${i.$and.map(n=>this.compileExpression(n,e,t)).join(" AND ")})`;const r=Object.entries(i||{}).map(([s,n])=>{const a=e.columns[s];if(!a)throw new Error(`Unknown field ${s} for SQL query`);const u=this.driver.identifier(a.columnName);if(n?.$eq!==void 0){const h=n.$eq?.id??n.$eq;return h===null?`${u} IS NULL`:(t.push(this.encode(h,a)),`${u} = ${this.driver.placeholder(t.length)}`)}if(n?.$ne!==void 0){const h=n.$ne?.id??n.$ne;return h===null?`${u} IS NOT NULL`:(t.push(this.encode(h,a)),`${u} <> ${this.driver.placeholder(t.length)}`)}if(n?.$soundLike!==void 0)return t.push(String(n.$soundLike)),`SOUNDEX(${u}) = SOUNDEX(${this.driver.placeholder(t.length)})`;if(n?.$contains!==void 0)return t.push(String(n.$contains)),this.driver.contains(u,this.driver.placeholder(t.length));if(n?.$notContains!==void 0)return t.push(String(n.$notContains)),`NOT (${this.driver.contains(u,this.driver.placeholder(t.length))})`;for(const[h,m,p,c]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(n?.[h]!==void 0){t.push(`${m}${String(n[h])}${p}`);const g=`${u} LIKE ${this.driver.placeholder(t.length)}`;return c?`NOT (${g})`:g}if(Array.isArray(n?.$in)){if(!n.$in.length)return"FALSE";const h=n.$in.map(m=>(t.push(this.encode(m?.id??m,a)),this.driver.placeholder(t.length)));return`${u} IN (${h.join(", ")})`}if(Array.isArray(n?.$notIn)){if(!n.$notIn.length)return"TRUE";const h=n.$notIn.map(m=>(t.push(this.encode(m?.id??m,a)),this.driver.placeholder(t.length)));return`${u} NOT IN (${h.join(", ")})`}for(const[h,m]of[["$inSubquery",!1],["$notInSubquery",!0]]){const p=n?.[h];if(p!==void 0){const c=p.query,g=this.schema(c?.entity),w=String(p.field),C=g.columns[w];if(!C)throw new Error(`Unknown subquery projection ${w} for ${c?.entity}`);const A=this.filters(c).map(q=>this.compileExpression(q,g,t));g.columns.version&&A.push(`${this.driver.identifier(g.columns.version.columnName)} > 0`),m&&A.push(`${this.driver.identifier(C.columnName)} IS NOT NULL`);const I=A.length?` WHERE ${A.join(" AND ")}`:"",x=`SELECT ${this.driver.identifier(C.columnName)} FROM ${this.driver.identifier(g.table)}${I}`;return`${u} ${m?"NOT IN":"IN"} (${x})`}}if(Array.isArray(n?.$between)&&n.$between.length===2){t.push(this.encode(n.$between[0],a));const h=this.driver.placeholder(t.length);t.push(this.encode(n.$between[1],a));const m=this.driver.placeholder(t.length);return`${u} BETWEEN ${h} AND ${m}`}if(n?.$isNull===!0)return`${u} IS NULL`;if(n?.$isNull===!1)return`${u} IS NOT NULL`;if(n?.$gte!==void 0)return t.push(this.encode(n.$gte,a)),`${u} >= ${this.driver.placeholder(t.length)}`;if(n?.$lte!==void 0)return t.push(this.encode(n.$lte,a)),`${u} <= ${this.driver.placeholder(t.length)}`;if(n?.$gt!==void 0)return t.push(this.encode(n.$gt,a)),`${u} > ${this.driver.placeholder(t.length)}`;if(n?.$lt!==void 0)return t.push(this.encode(n.$lt,a)),`${u} < ${this.driver.placeholder(t.length)}`;throw new Error(`Unsupported query predicate for ${s}: ${JSON.stringify(n)}`)});return r.length?`(${r.join(" AND ")})`:"TRUE"}filters(i){return Array.isArray(i._filters)&&i._filters.length?i._filters:i.filterCondition?[i.filterCondition]:[]}groupBy(i){return i._groupBy||i.groupByItems||[]}aggregates(i){return Array.isArray(i._aggregates)?i._aggregates:(i.aggregateItems||[]).map(e=>({func:e.function,field:e.field,retName:e.alias}))}orders(i){return Array.isArray(i._orderBy)?i._orderBy.map(e=>({field:e.f,direction:e.d})):(i.orderItems||[]).map(e=>({field:e.field,direction:e.direction}))}async compileQuery(i){const e=i?.[this.internalQueryToken]===!0,t=i?._purpose??i?.purposeText,r=i?._comment??i?.commentText;if(!e&&(!String(t||"").trim()||!String(r||"").trim()))throw new Error("Security audit failure: purpose and comment are required before query execution");const s=this.schema(i.entity),n=[],a=this.groupBy(i),u=a.map(_=>{if(!s.columns[_])throw new Error(`Unknown group field: ${_}`);return this.driver.identifier(s.columns[_].columnName)}),h=a.map(_=>`${this.driver.identifier(s.columns[_].columnName)} AS `+this.driver.identifier(_)),m=[],p=Array.isArray(i.selectItems)&&i.selectItems.length?[...new Set(["id","version",...i.selectItems])]:Object.keys(s.columns);for(const _ of p)if(!s.columns[_])throw new Error(`Unknown selected field: ${_}`);let c=p.map(_=>{const L=s.columns[_];return`${this.driver.identifier(L.columnName)} AS ${this.driver.identifier(_)}`}).join(", ");const g=this.aggregates(i);if(g.length){const _=g.map(L=>{if(!s.columns[L.field])throw new Error(`Unknown aggregate field: ${L.field}`);return m.push(L.retName),`${this.driver.aggregateFunction(L.func)}(${this.driver.identifier(s.columns[L.field].columnName)}) AS `+this.driver.identifier(L.retName)});c=[...h,..._].join(", ")}const w=i.__teaqlPartitionBy,C=this.orders(i),A=C.map(_=>{if(!s.columns[_.field])throw new Error(`Unknown order field: ${_.field}`);const L=String(_.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(s.columns[_.field].columnName)} ${L}`});if(w){const _=s.columns[w];if(!_)throw new Error(`Unknown partition field: ${w}`);const L=A.length?` ORDER BY ${A.join(", ")}`:"";c+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier(_.columnName)}${L}) AS `+this.driver.identifier("__teaql_partition_rank")}let I=`SELECT ${c} FROM ${this.driver.identifier(s.table)}`;const q=this.filters(i).map(_=>this.compileExpression(_,s,n));s.columns.version&&q.push(`${this.driver.identifier(s.columns.version.columnName)} > 0`),q.length&&(I+=` WHERE ${q.join(" AND ")}`),u.length&&(I+=` GROUP BY ${u.join(", ")}`);const P=i._limit!==void 0?Number(i._limit):Number(i.limitValue||0),z=i._offset!==void 0?Number(i._offset):Number(i.offsetValue||0);if(w){const _=this.driver.identifier("__teaql_partition_rank"),L=[];n.push(z),L.push(`${_} > ${this.driver.placeholder(n.length)}`),P>0&&(n.push(z+P),L.push(`${_} <= ${this.driver.placeholder(n.length)}`)),I=`SELECT * FROM (${I}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${L.join(" AND ")} ORDER BY ${_}`}else C.length&&(I+=` ORDER BY ${A.join(", ")}`);return!w&&P>0&&(n.push(P),I+=` LIMIT ${this.driver.placeholder(n.length)}`),!w&&z>0&&(n.push(z),I+=` OFFSET ${this.driver.placeholder(n.length)}`),this.sqlTrace.push(I),{sql:I,values:n,aggregateNames:m}}async executeQuery(i){const e=le(this.runtimeTelemetry,{family:"query",name:`${String(i?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(i?.entity||"unknown")}});try{const t=i?.[this.internalQueryToken]===!0;if(!t){if(typeof i?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");i.prepareForList()}const r=t?{query:i,execution:void 0}:await this.prepareIdSetPage(i),s=t?r:await this.prepareContinuousPage(r.query);i=s.query;const{sql:n,values:a,aggregateNames:u}=await this.compileQuery(i),h=Date.now(),m=await ie(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.query`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}},()=>this.driver.query(n,a)),p=i?._comment??i?.commentText,c=i?._purpose??i?.purposeText,g=Array.isArray(i?.__teaqlTracePath)?i.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(i.entity)}],w=[...g,{level:g.length,kind:"provider",name:this.driver.databaseKind},{level:g.length+1,kind:"sql",name:"select"}];this.recordSQL("select",n,a,h,m.rowCount,void 0,{comment:p,purpose:c,tracePath:w});const C=m.rows.map(A=>this.decodeRow(i.entity,A,u));if(r.execution?.pageIds){const A=new Map(r.execution.pageIds.map((I,x)=>[String(I),x]));C.sort((I,x)=>(A.get(String(I.id))??Number.MAX_SAFE_INTEGER)-(A.get(String(x.id))??Number.MAX_SAFE_INTEGER))}return await this.enhanceRelations(C,i),await this.enhanceRelationAggregates(C,i),t||await this.registerContinuousPage(i,s.execution,C),e.success({attributes:{"teaql.result.cardinality":C.length}}),C}catch(t){throw e.failure(t),t}}async prepareIdSetPage(i){const e=i.localIdSetPaginationOptions?.(),t=i.localIdSetPaginationRuntime?.();if(!e||!t)return t?.observe("ID_SET_DISABLED"),{query:i};const r=this.queryLimit(i);if(!r||i.localContinuousPageOptions?.()||this.aggregates(i).length||this.groupBy(i).length||i.__teaqlPartitionBy)return t.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:i};if((i.orderItems||[]).some(w=>w.expr!=null))return t.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:i};this.orders(i).some(w=>w.field==="id")||(i=i.clone().order(Ue.asc("id")));const s=i.clone();s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.relations=[],s.commentText=void 0,s.purposeText=void 0,s.clearIdSetPaginationRuntime(),s.clearContinuousPageRuntime();const n=`${e.namespace}|${t.scope}|${JSON.stringify(s)}`;let a=2166136261;for(let w=0;w>>0).toString(16)}`;let h,m=!1;try{h=t.get(u)}catch{return t.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:i}}if(h)m=!0,t.observe("ID_SET_HIT",h.ids.length);else{let w;try{w=await t.build(u,async()=>{const C=t.get(u);if(C)return C;const A=i.clone();A.selectItems=["id"],A.relations=[],A.relationAggregates=[],A.facets=[],A.offsetValue=0,A.limitValue=e.maxIds+1,A.clearIdSetPaginationRuntime(),A.clearContinuousPageRuntime(),A[this.internalQueryToken]=!0;const I=await this.executeQuery(A);if(I.length>e.maxIds)return;let x;try{x=BigUint64Array.from(I.map(P=>BigInt(P.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const q={ids:x,expiresAt:Date.now()+e.ttlSeconds*1e3};return t.put(u,q),q})}catch(C){return t.observe(C instanceof Error&&C.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:i}}if(h=w.value,!h)return t.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",e.maxIds+1),{query:i};m=!w.built,t.observe(m?"ID_SET_HIT":"ID_SET_BUILD",h.ids.length)}const p=Number(i.offsetValue||i._offset||0),c=Array.from(h.ids.slice(p,p+r)),g=i.clone();return g.offsetValue=0,g.limitValue=Math.max(c.length,1),g.filterCondition=g.filterCondition?{$and:[g.filterCondition,{id:{$in:c}}]}:{id:{$in:c}},g.clearIdSetPaginationRuntime(),t.observe(m?"ID_SET_HIT":"ID_SET_BUILD",h.ids.length),{query:g,execution:{pageIds:c,totalCount:h.ids.length}}}async executeFacetMembership(i,e){const t=i.clone();t.facets=[],t.relations=[],t.orderItems=[],t.offsetValue=0,t.limitValue=0,t.selectItems=[],t.groupByItems=[e],t.aggregateItems=[{function:"Count",field:"id",alias:"__teaql_facet_count"}],t[this.internalQueryToken]=!0;const r=await this.executeQuery(t);return new Map(r.flatMap(s=>{const n=s[e],a=Number(s.__teaql_facet_count??0);return n==null?[]:[[String(n),a]]}))}async executeCount(i){if(typeof i?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const e="__teaql_total",r=(await this.executeQuery(i.forExactCount(e)))[0]?.[e];if(typeof r!="number"||!Number.isFinite(r))throw new Error(`TeaQL provider did not return exact count alias ${e}`);return r}async prepareContinuousPage(i){const e=i.localContinuousPageOptions?.(),t=i.localContinuousPageRuntime?.();if(!e||!t)return t?.observe("DISABLED"),{query:i};const r=this.orders(i),s=this.queryLimit(i);if(!s||r.length!==1||r[0].field!=="id"||this.aggregates(i).length||this.groupBy(i).length||i.__teaqlPartitionBy)return t.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:i};const n=Object.assign(Object.create(Object.getPrototypeOf(i)),i);n.orderItems=[...i.orderItems||[]],n.relations=[...i.relations||[]],Object.defineProperty(n,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:e}),Object.defineProperty(n,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:t});const a=Number(i.offsetValue||i._offset||0),u={...JSON.parse(JSON.stringify(n)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},h=`${e.namespace}|${t.owner}|${JSON.stringify(u)}`;let m=2166136261;for(let C=0;C>>0).toString(16)}`,c={queryKey:p,offset:a,limit:s,direction:String(r[0].direction).toLowerCase(),ttlSeconds:e.ttlSeconds,runtime:t,optimized:!1};if(a===0)return t.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:n,execution:c};let g;try{g=await ie(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>t.get(p,a))}catch{return t.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:n,execution:c}}if(!g)return t.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:n,execution:c};const w={id:{[c.direction==="desc"?"$lt":"$gt"]:g.boundary}};return n.filterCondition=n.filterCondition?{$and:[n.filterCondition,w]}:w,n.offsetValue=0,n._offset!==void 0&&(n._offset=0),c.optimized=!0,c.cursorId=g.cursorId,t.observe("CURSOR_SEEK",g.cursorId),{query:n,execution:c}}async registerContinuousPage(i,e,t){if(!(!e||t.length!==e.limit||!t.length||t[t.length-1].id===void 0)){try{await ie(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>e.runtime.put(e.queryKey,e.offset+t.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:t[t.length-1].id,expiresAt:Date.now()+e.ttlSeconds*1e3}))}catch{e.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}e.optimized&&e.runtime.observe("CURSOR_SEEK",e.cursorId)}}async*executeForStream(i,e=1e3){if(!Number.isInteger(e)||e<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(i.facets)&&i.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:t,values:r,aggregateNames:s}=await this.compileQuery(i);let n=[];for await(const a of this.driver.stream(t,r))n.push(this.decodeRow(i.entity,a,s)),n.length===e&&(await this.enhanceRelations(n,i),yield n,n=[]);n.length&&(await this.enhanceRelations(n,i),yield n)}async enhanceRelations(i,e){if(!i.length||!Array.isArray(e.relations)||!e.relations.length)return;const t=this.schema(e.entity);for(const r of e.relations){const s=t.relations?.[r.name];if(!s)throw new Error(`Missing relation ${e.entity}.${r.name}`);const n=i.map(w=>w[s.localKey]).filter(w=>w!=null),a=r.query?this.queryLimit(r.query):void 0,u=r.query?.localTopNProbeParentThreshold?.(),h=s.many&&a!==void 0,m=this.driver.topNRelationPlanPolicy==="alwaysProbe",p=h&&(u===void 0?m:u>0&&n.length<=u),c=p?"bounded_probes":"window",g=le(this.runtimeTelemetry,{family:"relation_load",name:`${e.entity}.${String(r.name)}`,attributes:{"teaql.entity.type":String(e.entity),"teaql.relation.name":String(r.name),"teaql.relation.parent_count":n.length,"teaql.relation.per_parent_limit":a??0,"teaql.relation.configured_probe_threshold":u??"provider-default","teaql.relation.selected_plan":c,"teaql.relation.probe_count":p?n.length:0}});try{if(!n.length){for(const I of i)I[r.name]=s.many?[]:null;g.success({attributes:{"teaql.result.cardinality":0}});continue}const w={...r.query||{},entity:s.targetEntity,_filters:[...this.filters(r.query||{})],relations:[...r.query?.relations||[]],orderItems:[...r.query?.orderItems||[]],__teaqlPartitionBy:h&&!p?s.foreignKey:void 0,__teaqlTracePath:[...Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(e.entity)}],{level:Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath.length:2,kind:"relation",name:`${String(e.entity)}.${String(r.name)}`}],commentText:e?._comment??e?.commentText,purposeText:e?._purpose??e?.purposeText};h&&!w.orderItems.some(I=>I.field==="id")&&w.orderItems.push(Ue.asc("id")),typeof w.clearContinuousPageRuntime=="function"&&w.clearContinuousPageRuntime(),w[this.internalQueryToken]=!0;const C=[];if(p)for(const I of n){const x={...w,_filters:[...w._filters,{[s.foreignKey]:{$eq:I}}],__teaqlPartitionBy:void 0};C.push(...await this.executeQuery(x))}else w._filters.push({[s.foreignKey]:{$in:n}}),C.push(...await this.executeQuery(w));for(const I of C)delete I.__teaql_partition_rank;const A=new Map;for(const I of C){const x=I[s.foreignKey],q=A.get(x)||[];q.push(I),A.set(x,q)}for(const I of i){const x=A.get(I[s.localKey])||[];I[r.name]=s.many?x:x[0]??null}g.success({attributes:{"teaql.result.cardinality":C.length}})}catch(w){throw g.failure(w),w}}}async enhanceRelationAggregates(i,e){const t=e.relationAggregates;if(!i.length||!Array.isArray(t)||!t.length)return;const r=this.schema(e.entity);for(const s of t){const n=r.relations?.[s.relationName];if(!n)throw new Error(`Missing relation ${e.entity}.${s.relationName}`);const a=i.map(p=>p[n.localKey]).filter(p=>p!=null);if(!a.length){for(const p of i)p[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{};continue}const u=s.query.clone();u.entity=n.targetEntity,u.selectItems=[],u.properties=[],u.orderItems=[],u.limitValue=0,u.offsetValue=0,u.relations=[],u.relationAggregates=[],u.aggregateItems.length||u.aggregate("Count","id",s.alias),u.groupByItems.includes(n.foreignKey)||u.groupBy(n.foreignKey),u.filterCondition={...u.filterCondition||{},[n.foreignKey]:{$in:a}},u[this.internalQueryToken]=!0;const h=await this.executeQuery(u),m=new Map;for(const p of h)m.set(p[n.foreignKey],p);for(const p of i){const c=m.get(p[n.localKey]);c?s.singleResult?p[s.alias]=c[u.aggregateItems[0].alias]??null:p[s.alias]=Object.fromEntries(Object.entries(c).filter(([g])=>g!==n.foreignKey)):p[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{}}}}emptyAggregateValue(i){const e=i.aggregateItems[0];return!e||String(e.function).toLowerCase()==="count"?0:null}queryLimit(i){if(i._limit!==void 0)return Number(i._limit);if(i.limitValue!==void 0&&Number(i.limitValue)>0)return Number(i.limitValue)}async close(){await this.driver.close()}};function gi(i){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i))throw new Error(`Unsafe SQL identifier: ${i}`);return i}function Ei(i){const t={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(i).toLowerCase()];if(!t)throw new Error(`Unsupported aggregate: ${i}`);return t}var yi=class{constructor(i){this.worker=i,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=e=>{const t=e.data;if(!t||t.type!=="teaql-browser-sqlite-response")return;const r=this.pending.get(t.requestId);if(r)if(this.pending.delete(t.requestId),t.error){const s=new Error(t.error.message);s.name=t.error.name,t.error.code&&(s.code=t.error.code),r.reject(s)}else r.resolve(t.result)},this.onError=e=>{const t=new Error(e.message||"Browser SQLite worker failed");t.name="BrowserSQLiteWorkerError";for(const r of this.pending.values())r.reject(t);this.pending.clear()},i.addEventListener("message",this.onMessage),i.addEventListener("error",this.onError)}request(i,e){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const t=this.nextRequestId++;return new Promise((r,s)=>{this.pending.set(t,{resolve:n=>r(n),reject:s}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:t,operation:i,payload:e})})}async close(i){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),i&&this.worker.terminate?.();const e=new Error("Browser SQLite worker is closed");for(const t of this.pending.values())t.reject(e);this.pending.clear()}}},wi=class{constructor(i){this.transport=i}query(i,e=[]){return this.transport.request("query",{sql:i,values:e})}},Ci=class rt{constructor(e,t){this.transport=e,this.options=t,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,t={}){const r={storage:t.storage??"memory",databaseName:$i(t.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:t.terminateWorkerOnClose??!0},s=new yi(e);return await s.request("open",r),new rt(s,r)}identifier(e){return`"${gi(e)}"`}placeholder(e){return"?"}contains(e,t){return`CAST(${e} AS TEXT) LIKE '%' || ${t} || '%'`}aggregateFunction(e){return Ei(e)}encode(e,t){return e==null?e:t?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):t?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const t=this.accessTail;let r;this.accessTail=new Promise(s=>{r=s}),await t;try{return await e()}finally{r()}}query(e,t=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:t}))}async*stream(e,t=[]){const r=await this.query(e,t);for(const s of r.rows)yield s}transaction(e){return this.exclusive(async()=>{const t=new wi(this.transport);await t.query("BEGIN IMMEDIATE");try{const r=await e(t);return await t.query("COMMIT"),r}catch(r){try{await t.query("ROLLBACK")}catch{}throw r}})}async ensureSchema(e){for(const t of Object.values(e)){const r=this.identifier(t.table);await this.query(`CREATE TABLE IF NOT EXISTS ${r} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const s=await this.query(`PRAGMA table_info(${r})`),n=new Set(s.rows.map(a=>String(a.name)));for(const[a,u]of Object.entries(t.columns))a==="id"||a==="version"||n.has(u.columnName)||await this.query(`ALTER TABLE ${r} ADD COLUMN ${this.identifier(u.columnName)} ${vi(u.logicalType)}${u.nullable===!1?" NOT NULL":""}`)}for(const t of li(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(t.name)} ON ${this.identifier(t.table)} (${this.identifier(t.foreignColumn)}, ${this.identifier(t.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,t){for(let r=1;r<=100;r+=1){const s=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t]);if(!s.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[t])).rowCount===1)return"1"}catch(h){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t])).rowCount)throw h}continue}const n=Number(s.rows[0].id),a=n+1,u=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[a,t,n]);if(u.rowCount===1)return String(a);if(u.rowCount!==0)throw new Error(`ID space update for ${t} changed ${u.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${t} after 100 optimistic-lock attempts`)}ensureIdFloor(e,t,r){return ci(e,s=>this.placeholder(s),t,r)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}},bi=class st extends pi{constructor(e,t){super(e,t),this.browserDriver=e}static async open(e,t,r={}){return new st(await Ci.open(e,r),t)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}};function vi(i){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[i]}function $i(i){const e=i.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}var Si="1.001",Ii=class X{constructor(e={}){this.data=Array.from(e.data??[]),this.resultCode=e.resultCode??0,this.status=e.status??"YES",this.message=e.message,this.recordCount=e.recordCount??this.data.length,this.facets=e.facets,this.version=e.version??Si,this.traceId=e.traceId}static success(){return new X}static fail(e){return new X({resultCode:1,status:"NO",message:e})}static ofSingle(e){return new X({data:[e]})}static ofList(e){return new X({data:e})}static fromSmartList(e){const t=Object.fromEntries(Object.entries(e.facets).map(([r,s])=>[r,Array.from(s)]));return new X({data:e,recordCount:e.totalCountOrLength(),facets:Object.keys(t).length?t:void 0})}withTraceId(e){return this.traceId=e,this}},ze=class extends SyntaxError{constructor(i,e,t,r){super(i),this.expected=e,this.found=t,this.location=r,this.name="SyntaxError"}format(i){let e="Error: "+this.message;if(this.location){let t=null;const r=i.find(u=>u.source===this.location.source);r&&(t=r.text.split(/\r\n|\n|\r/g));const s=this.location.start,n=this.location.source&&typeof this.location.source.offset=="function"?this.location.source.offset(s):s,a=this.location.source+":"+n.line+":"+n.column;if(t){const u=this.location.end,h="".padEnd(n.line.toString().length," "),m=t[s.line-1],c=(s.line===u.line?u.column:m.length+1)-s.column||1;e+=` - --> `+a+` -`+h+` | -`+n.line+" | "+m+` -`+h+" | "+"".padEnd(s.column-1," ")+"".padEnd(c,"^")}else e+=` - at `+a}return e}static buildMessage(i,e){function t(c){return c.codePointAt(0).toString(16).toUpperCase()}const r=Object.prototype.hasOwnProperty.call(RegExp.prototype,"unicode")?new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]","gu"):null;function s(c){return r?c.replace(r,g=>"\\u{"+t(g)+"}"):c}function n(c){return s(c.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,g=>"\\x0"+t(g)).replace(/[\x10-\x1F\x7F-\x9F]/g,g=>"\\x"+t(g)))}function a(c){return s(c.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,g=>"\\x0"+t(g)).replace(/[\x10-\x1F\x7F-\x9F]/g,g=>"\\x"+t(g)))}const u={literal(c){return'"'+n(c.text)+'"'},class(c){const g=c.parts.map(w=>Array.isArray(w)?a(w[0])+"-"+a(w[1]):a(w));return"["+(c.inverted?"^":"")+g.join("")+"]"+(c.unicode?"u":"")},any(){return"any character"},end(){return"end of input"},other(c){return c.description}};function h(c){return u[c.type](c)}function m(c){const g=c.map(h);if(g.sort(),g.length>0){let w=1;for(let C=1;Cy[3])]}function Rt(l){return l||[]}function Dt(l){return JSON.parse(l)}function Gi(l){return l}function Nt(l){return l.join("")}function Pt(l){return Number(l)}function Ot(){return!0}function jt(){return!1}function Mt(){return null}function Hi(l){return l}let o=e.peg$currPos|0;const H=[{line:1,column:1}];let O=o,ae=e.peg$maxFailExpected||[],v=e.peg$silentFails|0,ee;if(e.startRule){if(!(e.startRule in s))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=s[e.startRule]}function Vt(l=o){const d=i.codePointAt(l);return d===void 0?"":String.fromCodePoint(d)}function R(l,d){return{type:"literal",text:l,ignoreCase:d}}function Q(l,d,y,f){return{type:"class",parts:l,inverted:d,ignoreCase:y,unicode:f}}function Wt(){return{type:"any"}}function Ut(){return{type:"end"}}function Be(l){let d=H[l],y;if(d)return d;if(l>=H.length)y=H.length-1;else for(y=l;!H[--y];);for(d=H[y],d={line:d.line,column:d.column};yO&&(O=o,ae=[]),ae.push(l))}function Qt(l,d,y){return new ze(ze.buildMessage(l,d),l,d,y)}function Re(){let l,d;return l=o,T(),d=De(),d!==t?(T(),i.charCodeAt(o)===59?o++:v===0&&$(wt),T(),l=d):(o=l,l=t),l}function De(){let l,d,y,f,b,E,S,k;if(l=o,d=Oe(),d!==t){if(y=[],f=o,b=T(),i.charCodeAt(o)===46?(E=a,o++):(E=t,v===0&&$(me)),E!==t?(S=T(),k=Ne(),k!==t?(b=[b,E,S,k],f=b):(o=f,f=t)):(o=f,f=t),f!==t)for(;f!==t;)y.push(f),f=o,b=T(),i.charCodeAt(o)===46?(E=a,o++):(E=t,v===0&&$(me)),E!==t?(S=T(),k=Ne(),k!==t?(b=[b,E,S,k],f=b):(o=f,f=t)):(o=f,f=t);else y=t;y!==t?l=Tt(d,y):(o=l,l=t)}else o=l,l=t;return l}function Ne(){let l,d,y,f,b;return l=o,d=Oe(),d!==t?(T(),i.charCodeAt(o)===40?(y=u,o++):(y=t,v===0&&$(Ct)),y!==t?(T(),f=Pe(),f===t&&(f=null),T(),i.charCodeAt(o)===41?(b=h,o++):(b=t,v===0&&$(bt)),b!==t?l=Bt(d,f):(o=l,l=t)):(o=l,l=t)):(o=l,l=t),l}function Pe(){let l,d,y,f,b,E,S,k;if(l=o,d=pe(),d!==t){for(y=[],f=o,b=T(),i.charCodeAt(o)===44?(E=m,o++):(E=t,v===0&&$(_e)),E!==t?(S=T(),k=pe(),k!==t?(b=[b,E,S,k],f=b):(o=f,f=t)):(o=f,f=t);f!==t;)y.push(f),f=o,b=T(),i.charCodeAt(o)===44?(E=m,o++):(E=t,v===0&&$(_e)),E!==t?(S=T(),k=pe(),k!==t?(b=[b,E,S,k],f=b):(o=f,f=t)):(o=f,f=t);l=Ft(d,y)}else o=l,l=t;return l}function pe(){let l;return l=De(),l===t&&(l=Kt(),l===t&&(l=zt(),l===t&&(l=Gt(),l===t&&(l=Ht(),l===t&&(l=Xt(),l===t&&(l=Yt())))))),l}function Kt(){let l,d,y,f;return l=o,i.charCodeAt(o)===91?(d=p,o++):(d=t,v===0&&$(vt)),d!==t?(T(),y=Pe(),y===t&&(y=null),T(),i.charCodeAt(o)===93?(f=c,o++):(f=t,v===0&&$($t)),f!==t?l=Rt(y):(o=l,l=t)):(o=l,l=t),l}function zt(){let l,d,y,f,b,E,S,k;if(l=o,d=o,y=o,i.charCodeAt(o)===34?(f=g,o++):(f=t,v===0&&$(ke)),f!==t){for(b=[],E=o,i.charCodeAt(o)===92?(S=w,o++):(S=t,v===0&&$(oe)),S!==t?(i.length>o?(k=i.charAt(o),o++):(k=t,v===0&&$(ue)),k!==t?(S=[S,k],E=S):(o=E,E=t)):(o=E,E=t),E===t&&(E=i.charAt(o),P.test(E)?o++:(E=t,v===0&&$(xe)));E!==t;)b.push(E),E=o,i.charCodeAt(o)===92?(S=w,o++):(S=t,v===0&&$(oe)),S!==t?(i.length>o?(k=i.charAt(o),o++):(k=t,v===0&&$(ue)),k!==t?(S=[S,k],E=S):(o=E,E=t)):(o=E,E=t),E===t&&(E=i.charAt(o),P.test(E)?o++:(E=t,v===0&&$(xe)));i.charCodeAt(o)===34?(E=g,o++):(E=t,v===0&&$(ke)),E!==t?(f=[f,b,E],y=f):(o=y,y=t)}else o=y,y=t;return y!==t?d=i.substring(d,o):d=y,d!==t&&(d=Dt(d)),l=d,l}function Gt(){let l,d,y,f,b,E;if(l=o,i.charCodeAt(o)===39?(d=C,o++):(d=t,v===0&&$(qe)),d!==t){for(y=[],f=o,i.charCodeAt(o)===92?(b=w,o++):(b=t,v===0&&$(oe)),b!==t?(i.length>o?(E=i.charAt(o),o++):(E=t,v===0&&$(ue)),E!==t?f=E:(o=f,f=t)):(o=f,f=t),f===t&&(f=i.charAt(o),z.test(f)?o++:(f=t,v===0&&$(Le)));f!==t;)y.push(f),f=o,i.charCodeAt(o)===92?(b=w,o++):(b=t,v===0&&$(oe)),b!==t?(i.length>o?(E=i.charAt(o),o++):(E=t,v===0&&$(ue)),E!==t?f=E:(o=f,f=t)):(o=f,f=t),f===t&&(f=i.charAt(o),z.test(f)?o++:(f=t,v===0&&$(Le)));i.charCodeAt(o)===39?(f=C,o++):(f=t,v===0&&$(qe)),f!==t?l=Nt(y):(o=l,l=t)}else o=l,l=t;return l}function Ht(){let l,d,y,f,b,E,S,k,D,W;if(l=o,d=o,y=o,i.charCodeAt(o)===45?(f=A,o++):(f=t,v===0&&$(St)),f===t&&(f=null),b=o,E=[],S=i.charAt(o),_.test(S)?o++:(S=t,v===0&&$(U)),S!==t)for(;S!==t;)E.push(S),S=i.charAt(o),_.test(S)?o++:(S=t,v===0&&$(U));else E=t;if(E!==t)if(i.charCodeAt(o)===46?(S=a,o++):(S=t,v===0&&$(me)),S!==t){if(k=[],D=i.charAt(o),_.test(D)?o++:(D=t,v===0&&$(U)),D!==t)for(;D!==t;)k.push(D),D=i.charAt(o),_.test(D)?o++:(D=t,v===0&&$(U));else k=t;k!==t?(E=[E,S,k],b=E):(o=b,b=t)}else o=b,b=t;else o=b,b=t;if(b===t)if(b=[],E=i.charAt(o),_.test(E)?o++:(E=t,v===0&&$(U)),E!==t)for(;E!==t;)b.push(E),E=i.charAt(o),_.test(E)?o++:(E=t,v===0&&$(U));else b=t;if(b!==t){if(E=o,S=i.charAt(o),L.test(S)?o++:(S=t,v===0&&$(It)),S!==t){if(k=i.charAt(o),gt.test(k)?o++:(k=t,v===0&&$(At)),k===t&&(k=null),D=[],W=i.charAt(o),_.test(W)?o++:(W=t,v===0&&$(U)),W!==t)for(;W!==t;)D.push(W),W=i.charAt(o),_.test(W)?o++:(W=t,v===0&&$(U));else D=t;D!==t?(S=[S,k,D],E=S):(o=E,E=t)}else o=E,E=t;E===t&&(E=null),f=[f,b,E],y=f}else o=y,y=t;return y!==t?d=i.substring(d,o):d=y,d!==t&&(d=Pt(d)),l=d,l}function Xt(){let l,d,y,f;return l=o,i.substr(o,4)===I?(d=I,o+=4):(d=t,v===0&&$(_t)),d!==t?(y=o,v++,f=te(),v--,f===t?y=void 0:(o=y,y=t),y!==t?l=Ot():(o=l,l=t)):(o=l,l=t),l===t&&(l=o,i.substr(o,5)===x?(d=x,o+=5):(d=t,v===0&&$(kt)),d!==t?(y=o,v++,f=te(),v--,f===t?y=void 0:(o=y,y=t),y!==t?l=jt():(o=l,l=t)):(o=l,l=t)),l}function Yt(){let l,d,y,f;return l=o,i.substr(o,4)===q?(d=q,o+=4):(d=t,v===0&&$(xt)),d!==t?(y=o,v++,f=te(),v--,f===t?y=void 0:(o=y,y=t),y!==t?l=Mt():(o=l,l=t)):(o=l,l=t),l}function Oe(){let l,d,y,f,b,E;if(l=o,d=o,y=o,f=i.charAt(o),Et.test(f)?o++:(f=t,v===0&&$(qt)),f!==t){for(b=[],E=te();E!==t;)b.push(E),E=te();f=[f,b],y=f}else o=y,y=t;return y!==t?d=i.substring(d,o):d=y,d!==t&&(d=d),l=d,l}function te(){let l;return l=i.charAt(o),yt.test(l)?o++:(l=t,v===0&&$(Lt)),l}function T(){let l,d;for(l=[],d=i.charAt(o),Ae.test(d)?o++:(d=t,v===0&&$(Te));d!==t;)l.push(d),d=i.charAt(o),Ae.test(d)?o++:(d=t,v===0&&$(Te));return l}function Jt(l,d){return{type:"CallChain",target:l,calls:d.map(y=>y[3])}}ee=n();const ge=ee!==t&&o===i.length;function je(){throw ee!==t&&otypeof a=="object"&&a!==null&&!Array.isArray(a)?nt(a,e):a);t=s.apply(t,n)}return t}var ki=class{static parse(i,e){const t=Ai(i,void 0);return nt(t,e)}},xi={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},qi=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],Ge=class extends Error{constructor(i){super(`Unsupported locale: ${i}`),this.localeCode=i}},Li={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function Ti(i){if(typeof i!="string"||!i.trim())throw new Ge(i);const e=i.trim().replace(/_/g,"-").toLowerCase(),t=qi.find(s=>s.toLowerCase()===e);if(t)return t;const r=Li[e];if(!r)throw new Ge(i);return r}var He=class{constructor(e,t){if(this.data=e,this.fallback=t,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(Ti)}message(e,t){return this.data.locales[e]?.messages[t]??this.fallback?.data.locales[e]?.messages[t]??this.data.locales.en?.messages[t]??this.fallback?.data.locales.en?.messages[t]??t}translate(e,t){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),a=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(t,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(a)),e}};He.builtin=new He(xi);var Y=class extends Error{constructor(i){super(`Check failed: ${i.map(e=>e.message??`${e.ruleId}:${e.location}`).join("; ")}`),this.violations=i,this.name="CheckException"}};function Bi(i,e){const t=i.defaultDomainRoot,r=e.defaultDomainRoot;if(t&&r&&(t.entity!==r.entity||t.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...i.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??t,constants:[...s.values()],ensure:i.ensure&&e.ensure?async n=>{await i.ensure(n),await e.ensure(n)}:e.ensure??i.ensure}}var Fi=class ot{constructor(e={},t={},r={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...t}),this.bootstrap=Object.freeze({defaultDomainRoot:r.defaultDomainRoot,constants:Object.freeze([...r.constants??[]]),ensure:r.ensure})}and(e){return new ot({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},Bi(this.bootstrap,e.bootstrap))}},Xe=class ut{constructor(e,t,r,s){this.enabledValue=e,this.cacheExpiredMillis=t,this.propagateValue=r,this.propagateCacheExpiredMillis=s}static enabled(e){return new ut(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}},Ri=class be{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,t,r,s=!0){return this.facets.push({facetName:e,relationName:t,query:r.toQuery(),includeAllFacets:s}),this}clone(){const e=new be(this.entity);return e.filterCondition=this.filterCondition,e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.orderItems=[...this.orderItems],e.selectItems=[...this.selectItems],e.properties=[...this.properties],e.joins=[...this.joins],e.groupByItems=[...this.groupByItems],e.aggregateItems=this.aggregateItems.map(t=>({...t})),e.aggregationCache=this.aggregationCache,e.facets=this.facets.map(t=>({...t,query:t.query.clone()})),e.relations=this.relations.map(t=>({...t,query:t.query?.clone()})),e.relationAggregates=this.relationAggregates.map(t=>({...t,query:t.query.clone()})),e.commentText=this.commentText,e.purposeText=this.purposeText,e.idSetPaginationOptions=this.idSetPaginationOptions,e.idSetPaginationRuntimeContext=this.idSetPaginationRuntimeContext,e.topNProbeThreshold=this.topNProbeThreshold,e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,t){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:t},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,t,r){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(r)||r<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:t,maxIds:r},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const t=new be(this.entity);return t.filterCondition=this.filterCondition,t.commentText=this.commentText,t.purposeText=this.purposeText,t.aggregate("Count","id",e),t}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const t of this.relations)t.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,t,r="id",s="id",n=!0){return this.relations.push({name:e,query:t,localKey:r,foreignKey:s,many:n}),this}relationAggregate(e,t,r,s=!0){return this.relationAggregates.push({relationName:e,alias:t,query:r,singleResult:s}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=Xe.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=Xe.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,t,r){return this.aggregateItems.push({function:e,field:t,alias:r}),this}groupBy(e){return this.groupByItems.push(e),this}},j=i=>`${i.entity}\0${typeof i.id}:${String(i.id)}`,K=class{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map}set(i,e,t){if(!e.trim())throw new TypeError("field is required");const r=j(i),s=this.changes.get(r)??{key:Object.freeze({...i}),values:{}};s.values[e]=t,this.changes.set(r,s)}snapshot(){return[...this.changes.values()].map(i=>({key:Object.freeze({...i.key}),values:Object.freeze({...i.values})}))}change(i){return Object.freeze({...this.changes.get(j(i))?.values??{}})}mergeFrom(i){if(i!==this){for(const e of i.snapshot())for(const[t,r]of Object.entries(e.values))this.set(e.key,t,r);for(const e of i.newKeys.values())this.markAsNew(e);for(const e of i.deletedKeys.values())this.markAsDeleted(e);for(const e of i.snapshotVersions())this.setOriginalVersion(e.key,e.version)}}snapshotVersions(){return[...this.originalVersions.values()]}rekey(i,e){const t=j(i),r=j(e);if(t===r)return;const s=this.changes.get(t);if(s){this.changes.delete(t);for(const[a,u]of Object.entries(s.values))this.set(e,a,u)}const n=this.originalVersions.get(t);n!==void 0&&(this.originalVersions.delete(t),this.originalVersions.set(r,{key:Object.freeze({...e}),version:n.version})),this.newKeys.delete(t)&&this.newKeys.set(r,Object.freeze({...e})),this.deletedKeys.delete(t)&&this.deletedKeys.set(r,Object.freeze({...e}))}clearEntity(i){const e=j(i);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e)}setOriginalVersion(i,e){this.originalVersions.set(j(i),{key:Object.freeze({...i}),version:e})}originalVersion(i){return this.originalVersions.get(j(i))?.version}markAsNew(i){this.newKeys.set(j(i),Object.freeze({...i}))}isNew(i){return this.newKeys.has(j(i))}markAsDeleted(i){const e=j(i);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...i}))}isDeleted(i){return this.deletedKeys.has(j(i))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear()}};function at(i){const e=i.split("_");return e[0]+e.slice(1).map(t=>t?t[0].toUpperCase()+t.slice(1):"").join("")}function Di(i,e){if(e==="snake_case")return i;const t=at(i);return e==="camelCase"||!t?t:t[0].toUpperCase()+t.slice(1)}function Ni(i){return i.replace(/~/g,"~0").replace(/\//g,"~1")}var M=class J{constructor(e){this.segments=e}static root(){return new J([])}static property(e){return J.root().property(e)}property(e){return new J([...this.segments,{kind:"property",name:e}])}index(e){return new J([...this.segments,{kind:"index",index:e}])}prefixedBy(e){return new J([...e.segments,...this.segments])}modelPath(){return this.render(e=>e)}nativePath(){return this.render(at)}instancePath(e="camelCase"){return this.segments.map(t=>t.kind==="index"?String(t.index):Ni(Di(t.name,e))).map(t=>`/${t}`).join("")}toString(){return this.nativePath()}render(e){let t="";for(const r of this.segments)r.kind==="index"?t+=`[${r.index}]`:t+=`${t?".":""}${e(r.name)}`;return t}},G=class ve extends Array{static get[Symbol.species](){return Array}constructor(e=[],t={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,ve.prototype),this.totalCount=t.totalCount,this.aggregations=t.aggregations??{},this.summary=t.summary??{},this.facets=t.facets??{},this.isLoaded=t.isLoaded??!0}static empty(){return new ve([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,t){return this.facets[e]=t,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}};function Pi(i){return i.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function $e(i){if(i&&typeof i=="object"){const e=i;return e.id??e.Id}return i}function Oi(i,e){const t=Pi(e);for(const r of[e,`${e}Id`,t,`${t}_id`]){const s=$e(i[r]);if(s!=null)return s}}async function lt(i,e,t,r){const s={};for(const n of r){let a;if(i.executeFacetMembership)a=await i.executeFacetMembership(e(t.clone()),n.relationName);else{const c=t.clone();c.facets=[],c.relations=[],c.orderItems=[],c.aggregateItems=[],c.groupByItems=[],c.offsetValue=0,c.limitValue=0,c.selectItems=[n.relationName];const g=await i.executeQuery(e(c));a=new Map;for(const w of g){const C=Oi(w,n.relationName);if(C==null)continue;const A=String(C);a.set(A,(a.get(A)??0)+1)}}const u=n.query.clone();u.facets=[],u.commentText??(u.commentText=t.commentText),u.purposeText??(u.purposeText=t.purposeText);const h=u.aggregateItems.filter(c=>String(c.function).toLowerCase()==="count").map(c=>String(c.alias));u.aggregateItems=[],u.groupByItems=[];const p=(await i.executeQuery(e(u))).map(c=>{const g=a.get(String($e(c.id??c.Id)))??0,w={...c};for(const C of h)w[C]=g;return w}).filter(c=>n.includeAllFacets||a.has(String($e(c.id??c.Id))));s[n.facetName]=new G(p)}return s}class se extends Ri{orderBy(e,t){return this.order({field:e,expr:null,direction:t==="desc"?"Desc":"Asc"})}relationQuery(e,t,r="id",s="id",n=!0){return this.relations.push({name:e,query:t,localKey:r,foreignKey:s,many:n}),this}}class B{static teaqlTemporaryId=0;id;title;description;platform;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new K,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--B.teaqlTemporaryId,writable:!0,enumerable:!1}),e){const r={...e};Object.assign(this,r),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof F?e.platform:F.fromRecord(e.platform),this.markLoaded("platform"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"WorkItem",id:this._ledgerId}}teaqlAttachRoot(e){return this._root!==e&&(e.mergeFrom(this._root),this._root=e),this}static fromRecord(e,t){const r=new B(e);return t?r.teaqlAttachRoot(t):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new B({id:String(e)})}static teaqlBootstrapNew(e){return new B().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,t),this.teaqlSaveWithinGraph(e,t)))}teaqlPreflightGraph(e,t){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"title",canonical:"title"},{member:"description",canonical:"description"},{member:"platform",canonical:"platform"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new Y([{ruleId:"invalid_type",location:M.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}t.preflightMutation({entity:"WorkItem",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root})}async teaqlSaveWithinGraph(e,t){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"WorkItem",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},a=await t.executeMutation(n);for(const[p,c]of Object.entries(n.payload))p!=="id"&&p!=="version"&&this._root.set(this.teaqlEntityKey(),p,c);if(!a.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},h=this.teaqlEntityKey();Object.assign(this,a.persistedRecord),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();return this._root.rekey(h,m),t.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(m,h)}),this._loadedFields=new Set(Object.keys(a.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update"),t.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.setOriginalVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,title:this.title,description:this.description,platform:this.platform,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateTitle(e){return this.title=e,this.markLoaded("title"),this._root.set(this.teaqlEntityKey(),"title",e),this}updateDescription(e){return this.description=e,this.markLoaded("description"),this._root.set(this.teaqlEntityKey(),"description",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}}class F{static teaqlTemporaryId=0;id;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new K,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--F.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_workItemList",{value:[],writable:!0,enumerable:!1}),e){const r={...e};delete r.workItemList,Object.assign(this,r),Array.isArray(e.workItemList)&&(this._workItemList=e.workItemList.map(s=>s instanceof B?s:B.fromRecord(s)),this.markLoaded("workItemList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._workItemList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const r=new F(e);return t?r.teaqlAttachRoot(t):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new F({id:String(e)})}static teaqlBootstrapNew(e){return new F().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,t),this.teaqlSaveWithinGraph(e,t)))}teaqlPreflightGraph(e,t){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new Y([{ruleId:"invalid_type",location:M.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}t.preflightMutation({entity:"Platform",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root});for(const[s,n]of this._workItemList.entries()){n.teaqlAttachRoot(this._root),n.updatePlatform(this),n.auditAs(this._comment);try{n.teaqlPreflightGraph(e,t)}catch(a){if(!(a instanceof Y))throw a;const u=M.property("work_item_list").index(s);throw new Y(a.violations.map(h=>({...h,location:h.location.prefixedBy(u)})))}}}async teaqlSaveWithinGraph(e,t){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"Platform",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},a=await t.executeMutation(n);for(const[p,c]of Object.entries(n.payload))p!=="id"&&p!=="version"&&this._root.set(this.teaqlEntityKey(),p,c);if(!a.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},h=this.teaqlEntityKey();Object.assign(this,a.persistedRecord),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(h,m),t.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(m,h)}),this._loadedFields=new Set(Object.keys(a.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update");for(const[p,c]of this._workItemList.entries()){c.teaqlAttachRoot(this._root),c.updatePlatform(this),c.auditAs(this._comment);try{await c.teaqlSaveWithinGraph(e,e.requireResource("dataService"))}catch(g){if(!(g instanceof Y))throw g;const w=M.property("work_item_list").index(p);throw new Y(g.violations.map(C=>({...C,location:C.location.prefixedBy(w)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.setOriginalVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}workItemList(){return this._workItemList}}class Ye{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new se("Platform"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new ji(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,r,s)=>this.executeForPageInternal(t,r,s),(t,r)=>this.executeForStreamInternal(t,r),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,r){return this.query.optimizePaginationWithIdSetConfig(e,t,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectWorkItemListWith(e){return this.query.relationQuery("workItemList",e.toQuery(),"id","platform",!0),this}haveWorkItems(){return this.withWorkItemListMatching({toQuery:()=>new se("WorkItem")})}haveNoWorkItems(){return this.withoutWorkItemListMatching({toQuery:()=>new se("WorkItem")})}withWorkItemListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutWorkItemListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}countWorkItems(){return this.countWorkItemsAs("countWorkItems")}countWorkItemsAs(e){const t=new se("WorkItem").filter({version:{$gte:1}});return this.countWorkItemsWith(e,{toQuery:()=>t})}countWorkItemsWith(e,t){return t.toQuery().aggregate("Count","id",e),this.query.relationAggregate("workItemList",e,t.toQuery(),!0),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,t){return this.filters.push({name:{$between:[e,t]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),r=await t.executeQuery(e.prepareQuery(this.query)),s=new K,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,a=n?[]:r.map(h=>h instanceof F?h:F.fromRecord(h,s)),u=new G(a);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await lt(t,h=>e.prepareQuery(h),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new G(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,r){this.ensureIntent(),this.query.offset(t).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,a=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),h=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query),m=new K,p=new G(u.map(c=>c instanceof F?c:F.fromRecord(c,m)));return p.totalCount=h,{data:p,totalCount:h,offset:t,limit:r}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new K;for await(const n of r.executeForStream(this.query,t))for(const a of n)yield a instanceof F?a:F.fromRecord(a,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class ji{constructor(e,t,r,s,n,a,u){this.execute=e,this.executeRows=t,this.page=r,this.stream=s,this.limitOne=n,this.addComment=a,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new F}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,r){return this.ensureIntent(),this.page(e,t,r)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Je{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new se("WorkItem"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new Mi(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,r,s)=>this.executeForPageInternal(t,r,s),(t,r)=>this.executeForStreamInternal(t,r),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,r){return this.query.optimizePaginationWithIdSetConfig(e,t,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","title","description","platform","version"]),this}selectId(){return this.query.select(["id"]),this}selectTitle(){return this.query.select(["title"]),this}selectDescription(){return this.query.select(["description"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withTitleContaining(e){return this.filters.push({title:{$contains:e}}),this}withTitleIs(e){return this.filters.push({title:{$eq:e}}),this}withTitleIsNot(e){return this.filters.push({title:{$ne:e}}),this}withTitleIn(...e){return this.filters.push({title:{$in:e}}),this}withTitleNotIn(...e){return this.filters.push({title:{$notIn:e}}),this}withTitleGreaterThan(e){return this.filters.push({title:{$gt:e}}),this}withTitleGreaterThanOrEqualTo(e){return this.filters.push({title:{$gte:e}}),this}withTitleLessThan(e){return this.filters.push({title:{$lt:e}}),this}withTitleLessThanOrEqualTo(e){return this.filters.push({title:{$lte:e}}),this}withTitleBetween(e,t){return this.filters.push({title:{$between:[e,t]}}),this}withTitleIsKnown(){return this.filters.push({title:{$isNull:!1}}),this}withTitleIsUnknown(){return this.filters.push({title:{$isNull:!0}}),this}withTitleNotContaining(e){return this.filters.push({title:{$notContains:e}}),this}withTitleStartingWith(e){return this.filters.push({title:{$startsWith:e}}),this}withTitleNotStartingWith(e){return this.filters.push({title:{$notStartsWith:e}}),this}withTitleEndingWith(e){return this.filters.push({title:{$endsWith:e}}),this}withTitleNotEndingWith(e){return this.filters.push({title:{$notEndsWith:e}}),this}withTitleSoundingLike(e){return this.filters.push({title:{$soundLike:e}}),this}withDescriptionContaining(e){return this.filters.push({description:{$contains:e}}),this}withDescriptionIs(e){return this.filters.push({description:{$eq:e}}),this}withDescriptionIsNot(e){return this.filters.push({description:{$ne:e}}),this}withDescriptionIn(...e){return this.filters.push({description:{$in:e}}),this}withDescriptionNotIn(...e){return this.filters.push({description:{$notIn:e}}),this}withDescriptionGreaterThan(e){return this.filters.push({description:{$gt:e}}),this}withDescriptionGreaterThanOrEqualTo(e){return this.filters.push({description:{$gte:e}}),this}withDescriptionLessThan(e){return this.filters.push({description:{$lt:e}}),this}withDescriptionLessThanOrEqualTo(e){return this.filters.push({description:{$lte:e}}),this}withDescriptionBetween(e,t){return this.filters.push({description:{$between:[e,t]}}),this}withDescriptionIsKnown(){return this.filters.push({description:{$isNull:!1}}),this}withDescriptionIsUnknown(){return this.filters.push({description:{$isNull:!0}}),this}withDescriptionNotContaining(e){return this.filters.push({description:{$notContains:e}}),this}withDescriptionStartingWith(e){return this.filters.push({description:{$startsWith:e}}),this}withDescriptionNotStartingWith(e){return this.filters.push({description:{$notStartsWith:e}}),this}withDescriptionEndingWith(e){return this.filters.push({description:{$endsWith:e}}),this}withDescriptionNotEndingWith(e){return this.filters.push({description:{$notEndsWith:e}}),this}withDescriptionSoundingLike(e){return this.filters.push({description:{$soundLike:e}}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByTitleAscending(){return this.query.orderBy("title","asc"),this}orderByTitleDescending(){return this.query.orderBy("title","desc"),this}orderByDescriptionAscending(){return this.query.orderBy("description","asc"),this}orderByDescriptionDescending(){return this.query.orderBy("description","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByTitle(){return this.query.groupBy("title"),this}groupByTitleAs(e){return this.query.groupBy("title"),this}groupByDescription(){return this.query.groupBy("description"),this}groupByDescriptionAs(e){return this.query.groupBy("description"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,t,r=!0){return this.query.facetBy(e,"platform",t,r),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),r=await t.executeQuery(e.prepareQuery(this.query)),s=new K,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,a=n?[]:r.map(h=>h instanceof B?h:B.fromRecord(h,s)),u=new G(a);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await lt(t,h=>e.prepareQuery(h),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new G(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,r){this.ensureIntent(),this.query.offset(t).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,a=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),h=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query),m=new K,p=new G(u.map(c=>c instanceof B?c:B.fromRecord(c,m)));return p.totalCount=h,{data:p,totalCount:h,offset:t,limit:r}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new K;for await(const n of r.executeForStream(this.query,t))for(const a of n)yield a instanceof B?a:B.fromRecord(a,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class Mi{constructor(e,t,r,s,n,a,u){this.execute=e,this.executeRows=t,this.page=r,this.stream=s,this.limitOne=n,this.addComment=a,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new B}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,r){return this.ensureIntent(),this.page(e,t,r)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Ie{static platforms(){return new Ye(!1)}static platformsWithMinimalFields(){return new Ye(!0)}static workItems(){return new Je(!1)}static workItemsWithMinimalFields(){return new Je(!0)}}const ct={Platform:{table:"platform_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}};async function Vi(i){let e=(await Ie.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(i))[0];e||(e=F.teaqlBootstrapNew("1"),e.updateName("Runtime Example"),await e.auditAs("create generated Domain Root Platform").save(i)),i.withActiveRoot({entity:"Platform",id:e.id})}const Wi=new Fi(ct,{Platform:{checkAndFix(i,e,t){i.getResource("fixTime"),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&t.push({ruleId:"required",location:M.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&t.push({ruleId:"max_length",location:M.property("name"),inputValue:e.payload.name,systemValue:100})}},WorkItem:{checkAndFix(i,e,t){i.getResource("fixTime"),(e.action==="Create"&&e.payload.title===void 0||e.payload.title===null)&&t.push({ruleId:"required",location:M.property("title")}),e.payload.title!=null&&!([...String(e.payload.title)].length>=1)&&t.push({ruleId:"min_length",location:M.property("title"),inputValue:e.payload.title,systemValue:1}),e.payload.title!=null&&[...String(e.payload.title)].length>80&&t.push({ruleId:"max_length",location:M.property("title"),inputValue:e.payload.title,systemValue:80}),e.payload.description!=null&&[...String(e.payload.description)].length>100&&t.push({ruleId:"max_length",location:M.property("description"),inputValue:e.payload.description,systemValue:100}),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&t.push({ruleId:"required",location:M.property("platform")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Runtime Example"}},constants:[],ensure:Vi}),ce=document.querySelector("#status"),Ui=document.querySelector("#result"),he=document.querySelector("#persist"),Qi=document.querySelector("#opfs-note"),we=document.querySelector("#reset"),Ze=document.querySelector("#preset"),de=document.querySelector("#query"),Se=document.querySelector("#run"),ht={facet:`Q.workItems() - .selectTitle() - .facetByPlatformAs( - "platforms", - Q.platforms().selectName().countAs("workItemCount") - ) - .orderByIdAscending() - .limit(20) - .comment("what: load browser-local work items with a platform facet") - .purpose("why: demonstrate the complete TeaQL web response")`,filter:`Q.workItems() - .selectTitle() - .withTitleContaining("model") - .orderByIdAscending() - .limit(20) - .comment("what: find work items whose title contains model") - .purpose("why: demonstrate a generated string predicate")`,all:`Q.workItems() - .selectTitle() - .orderByIdAscending() - .limit(20) - .comment("what: load browser-local work items") - .purpose("why: demonstrate a bounded generated query")`};de.value=ht.facet;let N;const fe=globalThis.crossOriginIsolated&&typeof navigator.storage?.getDirectory=="function",dt=localStorage.getItem("teaql-browser-storage")==="opfs",ft=dt&&fe?"opfs":"memory";dt&&!fe&&localStorage.removeItem("teaql-browser-storage");he.checked=ft==="opfs";he.disabled=!fe;fe||(Qi.textContent="(unavailable on this static host; memory mode remains fully browser-local)");async function Ki(i){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),t=await bi.open(e,{...ct},{storage:i,databaseName:"teaql-browser-example.sqlite3"});t.install(Wi);const r=new it().insertResource("dataService",t);return t.setUserContext(r),await r.ensureSchema(),{client:t,context:r}}async function mt({context:i}){if(!(await Ie.workItemsWithMinimalFields().comment("what: detect existing browser demo records").purpose("why: keep generated mutation bootstrap idempotent").executeForList(i)).length)for(const t of["Evaluate semantic model","Generate typed library","Verify browser runtime"])await new B().updateTitle(t).updatePlatform("1").auditAs("seed deterministic browser demo data").save(i)}async function ne(i){Se.disabled=!0,ce.textContent=`${i.client.storage.toUpperCase()} · running controlled query…`;try{const e=ki.parse(de.value,Ie);if(typeof e?.executeForList!="function")throw new Error("The query must end with a generated executable request");const t=await e.executeForList(i.context),r=Ii.fromSmartList(t);Ui.textContent=JSON.stringify(r,null,2),ce.textContent=`${i.client.storage.toUpperCase()} · ${r.recordCount} records · ready`}finally{Se.disabled=!1}}async function pt(i){ce.textContent=`Opening ${i.toUpperCase()} SQLite/WASM…`;const e=N;N=void 0,await e?.client.close();const t=await Ki(i);N=t,await mt(t),await ne(t)}Ze.addEventListener("change",()=>{de.value=ht[Ze.value],N&&ne(N).catch(Z)});Se.addEventListener("click",()=>{N&&ne(N).catch(Z)});de.addEventListener("keydown",i=>{(i.ctrlKey||i.metaKey)&&i.key==="Enter"&&N&&ne(N).catch(Z)});he.addEventListener("change",()=>{const i=he.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",i),pt(i).catch(Z)});we.addEventListener("click",async()=>{if(N){we.disabled=!0;try{await N.client.reset(N.context),await mt(N),await ne(N)}catch(i){Z(i)}finally{we.disabled=!1}}});function Z(i){const e=i instanceof Error?i:new Error(String(i));ce.textContent=`${e.name}: ${e.message}`}pt(ft).catch(Z); diff --git a/assets/index-DmPc8xp3.css b/assets/index-DmPc8xp3.css deleted file mode 100644 index 0c0b5de1295b8c7c6e54d45257452c38878ba434..0000000000000000000000000000000000000000 --- a/assets/index-DmPc8xp3.css +++ /dev/null @@ -1 +0,0 @@ -:root{font:16px/1.5 Inter,system-ui,sans-serif;color:#e8edf5;background:#090b10}body{margin:0}main{width:min(760px,calc(100% - 40px));margin:10vh auto}.eyebrow{color:#d9ff52;font-size:12px;font-weight:800;letter-spacing:.16em}h1{margin:8px 0;font-size:clamp(36px,7vw,68px);letter-spacing:-.05em}.controls{display:flex;gap:18px;align-items:center;margin:32px 0}button{border:0;border-radius:5px;padding:10px 14px;background:#d9ff52;font-weight:800}#status{color:#aab4c4}pre{min-height:260px;padding:22px;overflow:auto;border:1px solid #2b323e;border-radius:8px;background:#11151c;color:#c6d1df}.evidence-scroll{overflow-x:auto;margin:24px 0}.evidence-table{border-collapse:collapse;width:100%;text-align:left}.evidence-table th,.evidence-table td{padding:12px;border:1px solid #2b323e;vertical-align:top}.evidence-table td{white-space:pre-wrap;overflow-wrap:anywhere;min-width:110px}.evidence-table td:last-child{min-width:320px;font-family:monospace} diff --git a/assets/index-LiMSU-HT.js b/assets/index-LiMSU-HT.js deleted file mode 100644 index 341eb4c3a2b81d44239b3491458f1acc130d017b..0000000000000000000000000000000000000000 --- a/assets/index-LiMSU-HT.js +++ /dev/null @@ -1,5 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function i(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(s){if(s.ep)return;s.ep=!0;const n=i(s);fetch(s.href,n)}})();var be={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},ve=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],H=class extends Error{constructor(e){super(`Unsupported locale: ${e}`),this.localeCode=e}},Ie={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function ue(t){if(typeof t!="string"||!t.trim())throw new H(t);const e=t.trim().replace(/_/g,"-").toLowerCase(),i=ve.find(s=>s.toLowerCase()===e);if(i)return i;const r=Ie[e];if(!r)throw new H(t);return r}var M=class{constructor(e,i){if(this.data=e,this.fallback=i,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(ue)}message(e,i){return this.data.locales[e]?.messages[i]??this.fallback?.data.locales[e]?.messages[i]??this.data.locales.en?.messages[i]??this.fallback?.data.locales.en?.messages[i]??i}translate(e,i){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(i,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};M.builtin=new M(be);var Se=M,oe=Symbol("teaql.context.schema-capability"),X=new WeakMap,_e=1;function ke(t){if(!t||typeof t!="object"&&typeof t!="function")return String(t);const e=t;let i=X.get(e);return i||(i=_e++,X.set(e,i)),String(i)}var Y=class extends Error{constructor(t,e,i){super(`context root ${t}: expected ${e}`),this.reason=t,this.expectedType=e,this.activeRoot=i,this.name="ContextRootError"}},ae=class{constructor(){this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(t,e)=>this.getContinuousPageCursor(t,e),put:(t,e,i)=>this.putContinuousPageCursor(t,e,i),observe:(t,e)=>{this.continuousPagePlan=t,this.continuousPageCursorId=e}},this.idSetPaginationRuntime={owner:"",scope:"",get:t=>this.idSetStore().get(t),put:(t,e)=>this.idSetStore().put(t,e),build:(t,e)=>this.singleFlightIdSetBuild(t,e),observe:(t,e)=>{this.idSetPaginationPlan=t,this.idSetPaginationCount=e,this.idSetPaginationCountAccuracy=t==="ID_SET_BUILD"||t==="ID_SET_HIT"?"EXACT":t==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=Se.builtin}setLocaleCode(t){const e=ue(t);return this.locale=e,this}setLanguageCode(t){return this.setLocaleCode(t)}installI18nCatalog(t){if(!t)throw new Error("catalog is required");return this.i18nCatalog=t,this}installIdSetPaginationStore(t){if(!t)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",t)}translateCheckResults(t){return t.map(e=>this.i18nCatalog.translate(e,this.locale))}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(t){const e=String(t.sourceLabel||""),i=e.toLowerCase();if(!t.entityType||!t.modelPath||!e||i.includes("authorization")||i.includes("cookie")||i.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const r=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",r),r.push(Object.freeze({...t})),this}finishFixEvidence(){const t=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...t])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(t,e){return this.resources.set(t,e),this}getResource(t){return this.resources.get(t)}removeResource(t){return this.resources.delete(t),this}requireResource(t){const e=this.getResource(t);if(e===void 0)throw new Error(`Required UserContext resource is missing: ${t}`);return e}ensureSchema(){const t=this.requireResource("dataService"),e=t[oe];if(!e)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return e.call(t,this)}withActiveRoot(t){if(!t||!t.entity||t.id===void 0||t.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...t}))}requireActiveRoot(t){const e=this.getResource("activeRoot");if(!e)throw new Y("missing",t);if(e.entity!==t)throw new Y("type_mismatch",t,e);return e}prepareQuery(t){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const e=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,e?`${e.entity}:${String(e.id)}`:"-",ke(this.getResource("dataService"))].join("|"),t.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(t,e){const i=`${t}:${e}`,r=this.continuousPageCursors.get(i);if(r&&r.expiresAt<=Date.now()){this.continuousPageCursors.delete(i);return}return r}putContinuousPageCursor(t,e,i){if(this.continuousPageCursors.size>=4096){const r=[...this.continuousPageCursors.entries()].sort((s,n)=>s[1].expiresAt-n[1].expiresAt)[0];r&&this.continuousPageCursors.delete(r[0])}this.continuousPageCursors.set(`${t}:${e}`,i)}getRetainedIdSet(t){const e=this.retainedIdSets.get(t);if(e&&e.expiresAt<=Date.now()){this.retainedIdSets.delete(t);return}return e}idSetStore(){return this.getResource("idSetPaginationStore")??{get:t=>this.getRetainedIdSet(t),put:(t,e)=>this.putRetainedIdSet(t,e),invalidate:t=>{this.retainedIdSets.delete(t)}}}putRetainedIdSet(t,e){if(e.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const r=()=>[...this.retainedIdSets.values()].reduce((s,n)=>s+n.ids.byteLength,0);for(;this.retainedIdSets.size>=64||r()+e.ids.byteLength>268435456;){const s=[...this.retainedIdSets.entries()].sort((n,o)=>n[1].expiresAt-o[1].expiresAt)[0];if(!s)break;this.retainedIdSets.delete(s[0])}this.retainedIdSets.set(t,e)}async singleFlightIdSetBuild(t,e){const i=this.idSetBuilds.get(t);if(i)return{value:await i,built:!1};const r=e();this.idSetBuilds.set(t,r);try{return{value:await r,built:!0}}finally{this.idSetBuilds.delete(t)}}},$e=class extends Error{constructor(e){super(`Check failed: ${e.map(i=>i.message??`${i.ruleId}:${i.location}`).join("; ")}`),this.violations=e,this.name="CheckException"}};function Ae(t,e){const i=t.defaultDomainRoot,r=e.defaultDomainRoot;if(i&&r&&(i.entity!==r.entity||i.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...t.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??i,constants:[...s.values()],ensure:t.ensure&&e.ensure?async n=>{await t.ensure(n),await e.ensure(n)}:e.ensure??t.ensure}}var J=class B{constructor(e,i,r){this.field=e,this.expr=i,this.direction=r}static new(e,i){return new B(e,null,i)}static expr(e,i){return new B("",e,i)}static asc(e){return B.new(e,"Asc")}static desc(e){return B.new(e,"Desc")}},Z=Object.freeze({success:()=>{},failure:()=>{}}),qe=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function xe(t){const e={"teaql.operation.family":t.family,"teaql.operation.name":t.name};for(const[i,r]of Object.entries(t.attributes||{}))qe.has(i)||(e[i]=r);return Object.freeze({...t,attributes:Object.freeze(e)})}function D(t,e){if(!t)return Z;try{const i=t.start(xe(e));let r=!1;return{run:i.run?s=>i.run(s):s=>s(),success(s){if(!r){r=!0;try{i?.success(s)}catch{}}},failure(s){if(!r){r=!0;try{i?.failure(s)}catch{}}}}}catch{return Z}}async function T(t,e,i,r){const s=D(t,e);try{const n=await(s.run?s.run(i):i());return s.success(r?.(n)),n}catch(n){throw s.failure(n),n}}function Le(t){const e=new Map;for(const i of Object.values(t))for(const r of Object.values(i.relations||{})){if(!r.many)continue;const s=t[r.targetEntity],n=s?.columns[r.foreignKey]?.columnName,o=s?.columns.id?.columnName;if(!s||!n||!o)continue;const u=`idx_${s.table}_${n}_${o}`;let a=2166136261;for(let l=0;l>>0).toString(36),h=u.length<=30?u:`${u.slice(0,Math.max(1,29-c.length))}_${c}`;e.set(h,{name:h,table:s.table,foreignColumn:n,idColumn:o})}return[...e.values()]}async function Te(t,e,i,r){const s=Number(r);if(!Number.isSafeInteger(s)||s<0)throw new Error(`Invalid ID space floor ${r} for ${i}`);for(let n=1;n<=100;n+=1){const o=await t.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[i]);if(!o.rowCount){try{if((await t.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[i,s])).rowCount===1)return}catch(c){if(!(await t.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[i])).rowCount)throw c}continue}const u=Number(o.rows[0].id);if(u>=s)return;const a=await t.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[s,i,u]);if(a.rowCount===1)return;if(a.rowCount!==0)throw new Error(`ID space floor update for ${i} changed ${a.rowCount} rows on attempt ${n}`)}throw new Error(`Unable to synchronize ID space floor for ${i} after 100 optimistic-lock attempts`)}function Be(t){return t.startsWith('"')&&t.endsWith('"')||t.startsWith("`")&&t.endsWith("`")?t.slice(1,-1).replace(/""/g,'"').replace(/``/g,"`"):t}function Re(t,e){return t===e?!0:(t instanceof Date&&(t=t.getTime()),e instanceof Date&&(e=e.getTime()),t!=null&&e!==null&&e!==void 0&&String(t)===String(e))}function O(t,e,i){return[{level:0,kind:"operation",name:"mutation"},{level:1,kind:"entity",name:String(t.entity)},{level:2,kind:"provider",name:e},{level:3,kind:"sql",name:i}]}function Fe(t,e,i="sqlite"){let r=0,s="",n="sql";for(let o=0;o=0&&h=0&&hi.toString(16).padStart(2,"0")).join("")}'`:_(typeof t=="object"?JSON.stringify(t):String(t))}function _(t){return`'${t.replace(/'/g,"''")}'`}var De=class{constructor(t=e=>console.debug(e)){this.writer=t}write(t){this.writer(`[TeaQL SQL][${t.operation}][${t.elapsedMicros}us] ${t.resultSummary} -comment=${t.comment??""} purpose=${t.purpose??""} auditReason=${t.auditReason??""} tracePath=${ee(t.tracePath)} -Parameterized SQL: ${t.parameterizedSQL} params=${ee(t.parameters)} -Debug SQL: ${t.debugSQL}`)}};function ee(t){return JSON.stringify(t,(e,i)=>typeof i=="bigint"?i.toString():i)}var Ne=class{constructor(t,e){this.driver=t,this.schemas=e,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.auditEvents=[],this.diagnosticSQLLogSink=new De,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.checkers={},this.userContext=new ae,this.bootstrap={},this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve()}install(t){return Object.assign(this.schemas,t.schemas),Object.assign(this.checkers,t.checkers),this.bootstrap=Ae(this.bootstrap,t.bootstrap),this}setUserContext(t){return this.userContext=t,this}schema(t){const e=this.schemas[t];if(!e)throw new Error(`Unknown TeaQL entity: ${t}`);return e}toRuntimeMutationRecord(t,e){const i={};for(const[r,s]of Object.entries(e)){const n=t.columns[r]?r:Object.keys(t.columns).find(o=>t.columns[o].modelName===r||t.columns[o].columnName===r);n&&(i[n]=s)}return i}encode(t,e){const i=t?.id??t;if(i!==void 0)return this.driver.encode(i,e)}decodeRow(t,e,i=[]){const r=this.schema(t),s={...e};for(const[n,o]of Object.entries(r.columns)){const u=s[n];u!=null&&(o.decode==="number"&&(s[n]=Number(u)),o.decode==="string"&&(s[n]=String(u)),o.decode==="date"&&u instanceof Date&&(s[n]=u.toISOString()),o.logicalType==="boolean"&&(s[n]=!!u))}for(const n of i)s[n]!==null&&s[n]!==void 0&&(s[n]=Number(s[n]));return s}get auditTrace(){return[...this.auditEvents]}setAuditSink(t){return this.auditSink=t,this}setRuntimeTelemetrySink(t){return this.telemetrySink=t,this}setDiagnosticSQLLogSink(t){return this.diagnosticSQLLogSink=t,this}setQueryLoggingEnabled(t){return this.queryLoggingEnabled=t,this}setMutationLoggingEnabled(t){return this.mutationLoggingEnabled=t,this}setRuntimeTelemetry(t){return this.runtimeTelemetry=t,this}recordSQL(t,e,i,r,s,n,o={}){const u=t==="select";if(u&&!this.queryLoggingEnabled||!u&&!this.mutationLoggingEnabled||!this.telemetrySink&&!this.diagnosticSQLLogSink)return;const a=Object.freeze({operation:t,...o,tracePath:Object.freeze([...o.tracePath??[]]),parameterizedSQL:e,parameters:Object.freeze([...i]),debugSQL:Fe(e,i,this.driver.databaseKind),elapsedMicros:Math.max(0,(Date.now()-r)*1e3),resultCount:s,affectedRows:n,resultSummary:s!==void 0?`${s} rows returned`:`${n??0} rows affected`});this.telemetrySink?.record(a),this.diagnosticSQLLogSink?.write(a)}async[oe](t){this.userContext=t,this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const e=this.bootstrapTail;let i;this.bootstrapTail=new Promise(r=>{i=r}),await e;try{if(this.bootstrap.ensure){t.insertResource("bootstrapActor","teaql-generated-bootstrap"),t.insertResource("bootstrapCategory","runtime-bootstrap");try{await this.bootstrap.ensure(t)}finally{t.removeResource("bootstrapActor"),t.removeResource("bootstrapCategory")}}else await this.ensureBootstrapData()}finally{i()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const t=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];t.length&&await this.driver.transaction(async e=>{for(const i of t)await this.reconcileBootstrapEntity(e,i)})}async reconcileBootstrapEntity(t,e){const i=this.schema(e.entity),r=this.driver.identifier(i.table),s=this.driver.identifier(i.columns.id?.columnName??"id"),n=this.driver.identifier(i.columns.version?.columnName??"version"),o=Object.entries(e.values??{}).map(([a,c])=>{const h=i.columns[a];if(!h)throw new Error(`Unknown bootstrap field ${e.entity}.${a}`);return{column:this.driver.identifier(h.columnName),value:this.driver.encode(c,h)}}),u=await t.query(`SELECT * FROM ${r} WHERE ${s} = ${this.driver.placeholder(1)}`,[e.id]);if(u.rowCount){const a=u.rows[0],c=o.filter(h=>!Re(a[Be(h.column)],h.value));if(c.length){const h=c.map((l,m)=>`${l.column} = ${this.driver.placeholder(m+1)}`);h.push(`${n} = ${n} + 1`),await t.query(`UPDATE ${r} SET ${h.join(", ")} WHERE ${s} = `+this.driver.placeholder(c.length+1),[...c.map(l=>l.value),e.id])}}else{const a=[s,n,...o.map(l=>l.column)],c=[e.id,1,...o.map(l=>l.value)],h=c.map((l,m)=>this.driver.placeholder(m+1));await t.query(`INSERT INTO ${r} (${a.join(", ")}) VALUES (${h.join(", ")})`,c)}await this.driver.ensureIdFloor(t,e.entity,e.id)}async executeGraphSave(t){const e=this.graphSaveTail;let i;this.graphSaveTail=new Promise(r=>{i=r}),await e,this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence();try{const r=await this.driver.transaction(async s=>{this.graphMutationSession=s;try{return await t()}finally{this.graphMutationSession=void 0}});for(const s of this.graphCommitActions)s();return r}catch(r){for(const s of[...this.graphRollbackActions].reverse())s();throw r}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.removeResource("fixTime").finishFixEvidence(),i()}}afterGraphCommit(t){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(t)}afterGraphRollback(t){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(t)}async withMutationSession(t){return this.graphMutationSession?t(this.graphMutationSession):this.driver.transaction(t)}preflightMutation(t){if(!String(t?.comment||"").trim())throw new Error("Security audit failure: audit reason is required before mutation");t={...t,payload:{...t?.payload??{}}};const e=this.checkers[String(t.entity)];if(!e)return t;const i=[],r=this.userContext.getResource("fixTime")===void 0;r&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(e.checkAndFix(this.userContext,t,i),t.ledgerKey&&t.ledgerRoot)for(const[s,n]of Object.entries(t.payload||{}))t.ledgerRoot.set(t.ledgerKey,s,n);if(this.userContext.translateCheckResults(i),i.length)throw new $e(i);return t}finally{r&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(t){const e=D(this.runtimeTelemetry,{family:"mutation",name:`${String(t?.entity||"unknown")}.${String(t?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(t?.entity||"unknown"),"teaql.mutation.kind":String(t?.action||"unknown").toLowerCase()}});try{t=this.preflightMutation(t);const i=this.schema(t.entity),r=this.toRuntimeMutationRecord(i,t.payload||{}),s=this.driver.identifier(i.table),n=await T(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(t.action).toLowerCase()}},()=>this.withMutationSession(async u=>{if(t.action==="Create"){const a=t.id?String(t.id):await this.driver.nextId(u,t.entity);t.id&&await this.driver.ensureIdFloor(u,t.entity,a);const c=Number(t.version||0)+1,h={...r,id:a,version:c},l=Object.keys(i.columns).filter(w=>h[w]!==void 0),m=l.map(w=>this.driver.identifier(i.columns[w].columnName)).join(", "),d=l.map((w,k)=>this.driver.placeholder(k+1)).join(", "),p=l.map(w=>this.encode(h[w],i.columns[w])),f=`INSERT INTO ${s} (${m}) VALUES (${d})`,g=Date.now(),E=await u.query(f,p);return this.recordSQL("insert",f,p,g,void 0,E.rowCount,{auditReason:String(t.comment),tracePath:O(t,this.driver.databaseKind,"insert")}),{success:!0,id:a,version:c,persistedRecord:await this.readPersistedRecord(u,i,a)}}if(t.action==="Update"){const a=Object.keys(i.columns).filter(E=>E!=="id"&&E!=="version"&&r[E]!==void 0),c=a.map(E=>this.encode(r[E],i.columns[E])),h=a.map((E,w)=>`${this.driver.identifier(i.columns[E].columnName)} = `+this.driver.placeholder(w+1)),l=this.driver.identifier("version");h.push(`${l} = ${l} + 1`),c.push(String(t.id));const m=[`${this.driver.identifier("id")} = ${this.driver.placeholder(c.length)}`];t.version!==void 0&&t.version!==null&&(c.push(Number(t.version)),m.push(`${l} = ${this.driver.placeholder(c.length)}`));const d=`UPDATE ${s} SET ${h.join(", ")} WHERE ${m.join(" AND ")}`,p=Date.now(),f=await u.query(d,c);if(this.recordSQL("update",d,c,p,void 0,f.rowCount,{auditReason:String(t.comment),tracePath:O(t,this.driver.databaseKind,"update")}),f.rowCount!==1)throw new Error(`Optimistic lock failed or ${t.entity}(${t.id}) does not exist`);const g=await this.readPersistedRecord(u,i,String(t.id));return{success:!0,id:String(t.id),version:Number(g.version),persistedRecord:g}}if(t.action==="Delete"){const a=this.driver.identifier("version"),c=[String(t.id)],h=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];t.version!==void 0&&t.version!==null&&(c.push(Number(t.version)),h.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(c.length)));const l=`UPDATE ${s} SET ${a} = -(${a} + 1) WHERE ${h.join(" AND ")}`,m=Date.now(),d=await u.query(l,c);if(this.recordSQL("delete",l,c,m,void 0,d.rowCount,{auditReason:String(t.comment),tracePath:O(t,this.driver.databaseKind,"delete")}),d.rowCount!==1)throw new Error(`Optimistic lock failed or ${t.entity}(${t.id}) does not exist`);const p=await this.readPersistedRecord(u,i,String(t.id));return{success:!0,id:String(t.id),version:Number(p.version),deleted:!0,persistedRecord:p}}throw new Error(`Unsupported mutation action: ${t.action}`)})),o=Object.freeze({entity:t.entity,action:t.action,id:String(n.id),reason:String(t.comment),recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.keys(t.payload||{}).sort(),version:n.version});return this.auditEvents.push(o),this.auditSink&&await T(this.runtimeTelemetry,{family:"audit",name:`${t.entity}.audit`,attributes:{"teaql.entity.type":String(t.entity),"teaql.mutation.kind":String(t.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(t.payload||{}).length}},async()=>this.auditSink(o)),e.success(),n}catch(i){throw e.failure(i),i}}async readPersistedRecord(t,e,i){const r=Object.entries(e.columns).map(([n,o])=>`${this.driver.identifier(o.columnName)} AS ${this.driver.identifier(n)}`).join(", "),s=await t.query(`SELECT ${r} FROM ${this.driver.identifier(e.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,[i]);if(s.rowCount!==1)throw new Error(`Persisted ${e.table}(${i}) could not be read back`);return this.decodeRowForSchema(e,s.rows[0])}decodeRowForSchema(t,e){const i={...e};for(const[r,s]of Object.entries(t.columns)){const n=i[r];n!=null&&(s.decode==="number"&&(i[r]=Number(n)),s.decode==="string"&&(i[r]=String(n)),s.decode==="date"&&n instanceof Date&&(i[r]=n.toISOString()),s.logicalType==="boolean"&&(i[r]=!!n))}return i}compileExpression(t,e,i){if(Array.isArray(t?.$and))return`(${t.$and.map(n=>this.compileExpression(n,e,i)).join(" AND ")})`;const r=Object.entries(t||{}).map(([s,n])=>{const o=e.columns[s];if(!o)throw new Error(`Unknown field ${s} for SQL query`);const u=this.driver.identifier(o.columnName);if(n?.$eq!==void 0){const a=n.$eq?.id??n.$eq;return a===null?`${u} IS NULL`:(i.push(this.encode(a,o)),`${u} = ${this.driver.placeholder(i.length)}`)}if(n?.$ne!==void 0){const a=n.$ne?.id??n.$ne;return a===null?`${u} IS NOT NULL`:(i.push(this.encode(a,o)),`${u} <> ${this.driver.placeholder(i.length)}`)}if(n?.$soundLike!==void 0)return i.push(String(n.$soundLike)),`SOUNDEX(${u}) = SOUNDEX(${this.driver.placeholder(i.length)})`;if(n?.$contains!==void 0)return i.push(String(n.$contains)),this.driver.contains(u,this.driver.placeholder(i.length));if(n?.$notContains!==void 0)return i.push(String(n.$notContains)),`NOT (${this.driver.contains(u,this.driver.placeholder(i.length))})`;for(const[a,c,h,l]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(n?.[a]!==void 0){i.push(`${c}${String(n[a])}${h}`);const m=`${u} LIKE ${this.driver.placeholder(i.length)}`;return l?`NOT (${m})`:m}if(Array.isArray(n?.$in)){if(!n.$in.length)return"FALSE";const a=n.$in.map(c=>(i.push(this.encode(c?.id??c,o)),this.driver.placeholder(i.length)));return`${u} IN (${a.join(", ")})`}if(Array.isArray(n?.$notIn)){if(!n.$notIn.length)return"TRUE";const a=n.$notIn.map(c=>(i.push(this.encode(c?.id??c,o)),this.driver.placeholder(i.length)));return`${u} NOT IN (${a.join(", ")})`}for(const[a,c]of[["$inSubquery",!1],["$notInSubquery",!0]]){const h=n?.[a];if(h!==void 0){const l=h.query,m=this.schema(l?.entity),d=String(h.field),p=m.columns[d];if(!p)throw new Error(`Unknown subquery projection ${d} for ${l?.entity}`);const f=this.filters(l).map(w=>this.compileExpression(w,m,i));m.columns.version&&f.push(`${this.driver.identifier(m.columns.version.columnName)} > 0`),c&&f.push(`${this.driver.identifier(p.columnName)} IS NOT NULL`);const g=f.length?` WHERE ${f.join(" AND ")}`:"",E=`SELECT ${this.driver.identifier(p.columnName)} FROM ${this.driver.identifier(m.table)}${g}`;return`${u} ${c?"NOT IN":"IN"} (${E})`}}if(Array.isArray(n?.$between)&&n.$between.length===2){i.push(this.encode(n.$between[0],o));const a=this.driver.placeholder(i.length);i.push(this.encode(n.$between[1],o));const c=this.driver.placeholder(i.length);return`${u} BETWEEN ${a} AND ${c}`}if(n?.$isNull===!0)return`${u} IS NULL`;if(n?.$isNull===!1)return`${u} IS NOT NULL`;if(n?.$gte!==void 0)return i.push(this.encode(n.$gte,o)),`${u} >= ${this.driver.placeholder(i.length)}`;if(n?.$lte!==void 0)return i.push(this.encode(n.$lte,o)),`${u} <= ${this.driver.placeholder(i.length)}`;if(n?.$gt!==void 0)return i.push(this.encode(n.$gt,o)),`${u} > ${this.driver.placeholder(i.length)}`;if(n?.$lt!==void 0)return i.push(this.encode(n.$lt,o)),`${u} < ${this.driver.placeholder(i.length)}`;throw new Error(`Unsupported query predicate for ${s}: ${JSON.stringify(n)}`)});return r.length?`(${r.join(" AND ")})`:"TRUE"}filters(t){return Array.isArray(t._filters)&&t._filters.length?t._filters:t.filterCondition?[t.filterCondition]:[]}groupBy(t){return t._groupBy||t.groupByItems||[]}aggregates(t){return Array.isArray(t._aggregates)?t._aggregates:(t.aggregateItems||[]).map(e=>({func:e.function,field:e.field,retName:e.alias}))}orders(t){return Array.isArray(t._orderBy)?t._orderBy.map(e=>({field:e.f,direction:e.d})):(t.orderItems||[]).map(e=>({field:e.field,direction:e.direction}))}async compileQuery(t){const e=t?.[this.internalQueryToken]===!0,i=t?._purpose??t?.purposeText,r=t?._comment??t?.commentText;if(!e&&(!String(i||"").trim()||!String(r||"").trim()))throw new Error("Security audit failure: purpose and comment are required before query execution");const s=this.schema(t.entity),n=[],o=this.groupBy(t),u=o.map(y=>{if(!s.columns[y])throw new Error(`Unknown group field: ${y}`);return this.driver.identifier(s.columns[y].columnName)}),a=o.map(y=>`${this.driver.identifier(s.columns[y].columnName)} AS `+this.driver.identifier(y)),c=[],h=Array.isArray(t.selectItems)&&t.selectItems.length?[...new Set(["id","version",...t.selectItems])]:Object.keys(s.columns);for(const y of h)if(!s.columns[y])throw new Error(`Unknown selected field: ${y}`);let l=h.map(y=>{const C=s.columns[y];return`${this.driver.identifier(C.columnName)} AS ${this.driver.identifier(y)}`}).join(", ");const m=this.aggregates(t);if(m.length){const y=m.map(C=>{if(!s.columns[C.field])throw new Error(`Unknown aggregate field: ${C.field}`);return c.push(C.retName),`${this.driver.aggregateFunction(C.func)}(${this.driver.identifier(s.columns[C.field].columnName)}) AS `+this.driver.identifier(C.retName)});l=[...a,...y].join(", ")}const d=t.__teaqlPartitionBy,p=this.orders(t),f=p.map(y=>{if(!s.columns[y.field])throw new Error(`Unknown order field: ${y.field}`);const C=String(y.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(s.columns[y.field].columnName)} ${C}`});if(d){const y=s.columns[d];if(!y)throw new Error(`Unknown partition field: ${d}`);const C=f.length?` ORDER BY ${f.join(", ")}`:"";l+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier(y.columnName)}${C}) AS `+this.driver.identifier("__teaql_partition_rank")}let g=`SELECT ${l} FROM ${this.driver.identifier(s.table)}`;const w=this.filters(t).map(y=>this.compileExpression(y,s,n));s.columns.version&&w.push(`${this.driver.identifier(s.columns.version.columnName)} > 0`),w.length&&(g+=` WHERE ${w.join(" AND ")}`),u.length&&(g+=` GROUP BY ${u.join(", ")}`);const k=t._limit!==void 0?Number(t._limit):Number(t.limitValue||0),F=t._offset!==void 0?Number(t._offset):Number(t.offsetValue||0);if(d){const y=this.driver.identifier("__teaql_partition_rank"),C=[];n.push(F),C.push(`${y} > ${this.driver.placeholder(n.length)}`),k>0&&(n.push(F+k),C.push(`${y} <= ${this.driver.placeholder(n.length)}`)),g=`SELECT * FROM (${g}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${C.join(" AND ")} ORDER BY ${y}`}else p.length&&(g+=` ORDER BY ${f.join(", ")}`);return!d&&k>0&&(n.push(k),g+=` LIMIT ${this.driver.placeholder(n.length)}`),!d&&F>0&&(n.push(F),g+=` OFFSET ${this.driver.placeholder(n.length)}`),this.sqlTrace.push(g),{sql:g,values:n,aggregateNames:c}}async executeQuery(t){const e=D(this.runtimeTelemetry,{family:"query",name:`${String(t?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(t?.entity||"unknown")}});try{const i=t?.[this.internalQueryToken]===!0;if(!i){if(typeof t?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");t.prepareForList()}const r=i?{query:t,execution:void 0}:await this.prepareIdSetPage(t),s=i?r:await this.prepareContinuousPage(r.query);t=s.query;const{sql:n,values:o,aggregateNames:u}=await this.compileQuery(t),a=Date.now(),c=await T(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.query`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}},()=>this.driver.query(n,o)),h=t?._comment??t?.commentText,l=t?._purpose??t?.purposeText,m=Array.isArray(t?.__teaqlTracePath)?t.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(t.entity)}],d=[...m,{level:m.length,kind:"provider",name:this.driver.databaseKind},{level:m.length+1,kind:"sql",name:"select"}];this.recordSQL("select",n,o,a,c.rowCount,void 0,{comment:h,purpose:l,tracePath:d});const p=c.rows.map(f=>this.decodeRow(t.entity,f,u));if(r.execution?.pageIds){const f=new Map(r.execution.pageIds.map((g,E)=>[String(g),E]));p.sort((g,E)=>(f.get(String(g.id))??Number.MAX_SAFE_INTEGER)-(f.get(String(E.id))??Number.MAX_SAFE_INTEGER))}return await this.enhanceRelations(p,t),await this.enhanceRelationAggregates(p,t),i||await this.registerContinuousPage(t,s.execution,p),e.success({attributes:{"teaql.result.cardinality":p.length}}),p}catch(i){throw e.failure(i),i}}async prepareIdSetPage(t){const e=t.localIdSetPaginationOptions?.(),i=t.localIdSetPaginationRuntime?.();if(!e||!i)return i?.observe("ID_SET_DISABLED"),{query:t};const r=this.queryLimit(t);if(!r||t.localContinuousPageOptions?.()||this.aggregates(t).length||this.groupBy(t).length||t.__teaqlPartitionBy)return i.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:t};if((t.orderItems||[]).some(d=>d.expr!=null))return i.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:t};this.orders(t).some(d=>d.field==="id")||(t=t.clone().order(J.asc("id")));const s=t.clone();s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.relations=[],s.commentText=void 0,s.purposeText=void 0,s.clearIdSetPaginationRuntime(),s.clearContinuousPageRuntime();const n=`${e.namespace}|${i.scope}|${JSON.stringify(s)}`;let o=2166136261;for(let d=0;d>>0).toString(16)}`;let a,c=!1;try{a=i.get(u)}catch{return i.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:t}}if(a)c=!0,i.observe("ID_SET_HIT",a.ids.length);else{let d;try{d=await i.build(u,async()=>{const p=i.get(u);if(p)return p;const f=t.clone();f.selectItems=["id"],f.relations=[],f.relationAggregates=[],f.facets=[],f.offsetValue=0,f.limitValue=e.maxIds+1,f.clearIdSetPaginationRuntime(),f.clearContinuousPageRuntime(),f[this.internalQueryToken]=!0;const g=await this.executeQuery(f);if(g.length>e.maxIds)return;let E;try{E=BigUint64Array.from(g.map(k=>BigInt(k.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const w={ids:E,expiresAt:Date.now()+e.ttlSeconds*1e3};return i.put(u,w),w})}catch(p){return i.observe(p instanceof Error&&p.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:t}}if(a=d.value,!a)return i.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",e.maxIds+1),{query:t};c=!d.built,i.observe(c?"ID_SET_HIT":"ID_SET_BUILD",a.ids.length)}const h=Number(t.offsetValue||t._offset||0),l=Array.from(a.ids.slice(h,h+r)),m=t.clone();return m.offsetValue=0,m.limitValue=Math.max(l.length,1),m.filterCondition=m.filterCondition?{$and:[m.filterCondition,{id:{$in:l}}]}:{id:{$in:l}},m.clearIdSetPaginationRuntime(),i.observe(c?"ID_SET_HIT":"ID_SET_BUILD",a.ids.length),{query:m,execution:{pageIds:l,totalCount:a.ids.length}}}async executeFacetMembership(t,e){const i=t.clone();i.facets=[],i.relations=[],i.orderItems=[],i.offsetValue=0,i.limitValue=0,i.selectItems=[],i.groupByItems=[e],i.aggregateItems=[{function:"Count",field:"id",alias:"__teaql_facet_count"}],i[this.internalQueryToken]=!0;const r=await this.executeQuery(i);return new Map(r.flatMap(s=>{const n=s[e],o=Number(s.__teaql_facet_count??0);return n==null?[]:[[String(n),o]]}))}async executeCount(t){if(typeof t?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const e="__teaql_total",r=(await this.executeQuery(t.forExactCount(e)))[0]?.[e];if(typeof r!="number"||!Number.isFinite(r))throw new Error(`TeaQL provider did not return exact count alias ${e}`);return r}async prepareContinuousPage(t){const e=t.localContinuousPageOptions?.(),i=t.localContinuousPageRuntime?.();if(!e||!i)return i?.observe("DISABLED"),{query:t};const r=this.orders(t),s=this.queryLimit(t);if(!s||r.length!==1||r[0].field!=="id"||this.aggregates(t).length||this.groupBy(t).length||t.__teaqlPartitionBy)return i.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:t};const n=Object.assign(Object.create(Object.getPrototypeOf(t)),t);n.orderItems=[...t.orderItems||[]],n.relations=[...t.relations||[]],Object.defineProperty(n,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:e}),Object.defineProperty(n,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:i});const o=Number(t.offsetValue||t._offset||0),u={...JSON.parse(JSON.stringify(n)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},a=`${e.namespace}|${i.owner}|${JSON.stringify(u)}`;let c=2166136261;for(let p=0;p>>0).toString(16)}`,l={queryKey:h,offset:o,limit:s,direction:String(r[0].direction).toLowerCase(),ttlSeconds:e.ttlSeconds,runtime:i,optimized:!1};if(o===0)return i.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:n,execution:l};let m;try{m=await T(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>i.get(h,o))}catch{return i.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:n,execution:l}}if(!m)return i.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:n,execution:l};const d={id:{[l.direction==="desc"?"$lt":"$gt"]:m.boundary}};return n.filterCondition=n.filterCondition?{$and:[n.filterCondition,d]}:d,n.offsetValue=0,n._offset!==void 0&&(n._offset=0),l.optimized=!0,l.cursorId=m.cursorId,i.observe("CURSOR_SEEK",m.cursorId),{query:n,execution:l}}async registerContinuousPage(t,e,i){if(!(!e||i.length!==e.limit||!i.length||i[i.length-1].id===void 0)){try{await T(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>e.runtime.put(e.queryKey,e.offset+i.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:i[i.length-1].id,expiresAt:Date.now()+e.ttlSeconds*1e3}))}catch{e.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}e.optimized&&e.runtime.observe("CURSOR_SEEK",e.cursorId)}}async*executeForStream(t,e=1e3){if(!Number.isInteger(e)||e<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(t.facets)&&t.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:i,values:r,aggregateNames:s}=await this.compileQuery(t);let n=[];for await(const o of this.driver.stream(i,r))n.push(this.decodeRow(t.entity,o,s)),n.length===e&&(await this.enhanceRelations(n,t),yield n,n=[]);n.length&&(await this.enhanceRelations(n,t),yield n)}async enhanceRelations(t,e){if(!t.length||!Array.isArray(e.relations)||!e.relations.length)return;const i=this.schema(e.entity);for(const r of e.relations){const s=i.relations?.[r.name];if(!s)throw new Error(`Missing relation ${e.entity}.${r.name}`);const n=t.map(d=>d[s.localKey]).filter(d=>d!=null),o=r.query?this.queryLimit(r.query):void 0,u=r.query?.localTopNProbeParentThreshold?.(),a=s.many&&o!==void 0,c=this.driver.topNRelationPlanPolicy==="alwaysProbe",h=a&&(u===void 0?c:u>0&&n.length<=u),l=h?"bounded_probes":"window",m=D(this.runtimeTelemetry,{family:"relation_load",name:`${e.entity}.${String(r.name)}`,attributes:{"teaql.entity.type":String(e.entity),"teaql.relation.name":String(r.name),"teaql.relation.parent_count":n.length,"teaql.relation.per_parent_limit":o??0,"teaql.relation.configured_probe_threshold":u??"provider-default","teaql.relation.selected_plan":l,"teaql.relation.probe_count":h?n.length:0}});try{if(!n.length){for(const g of t)g[r.name]=s.many?[]:null;m.success({attributes:{"teaql.result.cardinality":0}});continue}const d={...r.query||{},entity:s.targetEntity,_filters:[...this.filters(r.query||{})],relations:[...r.query?.relations||[]],orderItems:[...r.query?.orderItems||[]],__teaqlPartitionBy:a&&!h?s.foreignKey:void 0,__teaqlTracePath:[...Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(e.entity)}],{level:Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath.length:2,kind:"relation",name:`${String(e.entity)}.${String(r.name)}`}],commentText:e?._comment??e?.commentText,purposeText:e?._purpose??e?.purposeText};a&&!d.orderItems.some(g=>g.field==="id")&&d.orderItems.push(J.asc("id")),typeof d.clearContinuousPageRuntime=="function"&&d.clearContinuousPageRuntime(),d[this.internalQueryToken]=!0;const p=[];if(h)for(const g of n){const E={...d,_filters:[...d._filters,{[s.foreignKey]:{$eq:g}}],__teaqlPartitionBy:void 0};p.push(...await this.executeQuery(E))}else d._filters.push({[s.foreignKey]:{$in:n}}),p.push(...await this.executeQuery(d));for(const g of p)delete g.__teaql_partition_rank;const f=new Map;for(const g of p){const E=g[s.foreignKey],w=f.get(E)||[];w.push(g),f.set(E,w)}for(const g of t){const E=f.get(g[s.localKey])||[];g[r.name]=s.many?E:E[0]??null}m.success({attributes:{"teaql.result.cardinality":p.length}})}catch(d){throw m.failure(d),d}}}async enhanceRelationAggregates(t,e){const i=e.relationAggregates;if(!t.length||!Array.isArray(i)||!i.length)return;const r=this.schema(e.entity);for(const s of i){const n=r.relations?.[s.relationName];if(!n)throw new Error(`Missing relation ${e.entity}.${s.relationName}`);const o=t.map(h=>h[n.localKey]).filter(h=>h!=null);if(!o.length){for(const h of t)h[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{};continue}const u=s.query.clone();u.entity=n.targetEntity,u.selectItems=[],u.properties=[],u.orderItems=[],u.limitValue=0,u.offsetValue=0,u.relations=[],u.relationAggregates=[],u.aggregateItems.length||u.aggregate("Count","id",s.alias),u.groupByItems.includes(n.foreignKey)||u.groupBy(n.foreignKey),u.filterCondition={...u.filterCondition||{},[n.foreignKey]:{$in:o}},u[this.internalQueryToken]=!0;const a=await this.executeQuery(u),c=new Map;for(const h of a)c.set(h[n.foreignKey],h);for(const h of t){const l=c.get(h[n.localKey]);l?s.singleResult?h[s.alias]=l[u.aggregateItems[0].alias]??null:h[s.alias]=Object.fromEntries(Object.entries(l).filter(([m])=>m!==n.foreignKey)):h[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{}}}}emptyAggregateValue(t){const e=t.aggregateItems[0];return!e||String(e.function).toLowerCase()==="count"?0:null}queryLimit(t){if(t._limit!==void 0)return Number(t._limit);if(t.limitValue!==void 0&&Number(t.limitValue)>0)return Number(t.limitValue)}async close(){await this.driver.close()}};function Pe(t){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))throw new Error(`Unsafe SQL identifier: ${t}`);return t}function Oe(t){const i={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(t).toLowerCase()];if(!i)throw new Error(`Unsupported aggregate: ${t}`);return i}var je=class{constructor(t){this.worker=t,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=e=>{const i=e.data;if(!i||i.type!=="teaql-browser-sqlite-response")return;const r=this.pending.get(i.requestId);if(r)if(this.pending.delete(i.requestId),i.error){const s=new Error(i.error.message);s.name=i.error.name,i.error.code&&(s.code=i.error.code),r.reject(s)}else r.resolve(i.result)},this.onError=e=>{const i=new Error(e.message||"Browser SQLite worker failed");i.name="BrowserSQLiteWorkerError";for(const r of this.pending.values())r.reject(i);this.pending.clear()},t.addEventListener("message",this.onMessage),t.addEventListener("error",this.onError)}request(t,e){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const i=this.nextRequestId++;return new Promise((r,s)=>{this.pending.set(i,{resolve:n=>r(n),reject:s}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:i,operation:t,payload:e})})}async close(t){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),t&&this.worker.terminate?.();const e=new Error("Browser SQLite worker is closed");for(const i of this.pending.values())i.reject(e);this.pending.clear()}}},Ve=class{constructor(t){this.transport=t}query(t,e=[]){return this.transport.request("query",{sql:t,values:e})}},Me=class le{constructor(e,i){this.transport=e,this.options=i,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,i={}){const r={storage:i.storage??"memory",databaseName:Ke(i.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:i.terminateWorkerOnClose??!0},s=new je(e);return await s.request("open",r),new le(s,r)}identifier(e){return`"${Pe(e)}"`}placeholder(e){return"?"}contains(e,i){return`CAST(${e} AS TEXT) LIKE '%' || ${i} || '%'`}aggregateFunction(e){return Oe(e)}encode(e,i){return e==null?e:i?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):i?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const i=this.accessTail;let r;this.accessTail=new Promise(s=>{r=s}),await i;try{return await e()}finally{r()}}query(e,i=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:i}))}async*stream(e,i=[]){const r=await this.query(e,i);for(const s of r.rows)yield s}transaction(e){return this.exclusive(async()=>{const i=new Ve(this.transport);await i.query("BEGIN IMMEDIATE");try{const r=await e(i);return await i.query("COMMIT"),r}catch(r){try{await i.query("ROLLBACK")}catch{}throw r}})}async ensureSchema(e){for(const i of Object.values(e)){const r=this.identifier(i.table);await this.query(`CREATE TABLE IF NOT EXISTS ${r} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const s=await this.query(`PRAGMA table_info(${r})`),n=new Set(s.rows.map(o=>String(o.name)));for(const[o,u]of Object.entries(i.columns))o==="id"||o==="version"||n.has(u.columnName)||await this.query(`ALTER TABLE ${r} ADD COLUMN ${this.identifier(u.columnName)} ${Ue(u.logicalType)}${u.nullable===!1?" NOT NULL":""}`)}for(const i of Le(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(i.name)} ON ${this.identifier(i.table)} (${this.identifier(i.foreignColumn)}, ${this.identifier(i.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,i){for(let r=1;r<=100;r+=1){const s=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[i]);if(!s.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[i])).rowCount===1)return"1"}catch(a){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[i])).rowCount)throw a}continue}const n=Number(s.rows[0].id),o=n+1,u=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[o,i,n]);if(u.rowCount===1)return String(o);if(u.rowCount!==0)throw new Error(`ID space update for ${i} changed ${u.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${i} after 100 optimistic-lock attempts`)}ensureIdFloor(e,i,r){return Te(e,s=>this.placeholder(s),i,r)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}},We=class ce extends Ne{constructor(e,i){super(e,i),this.browserDriver=e}static async open(e,i,r={}){return new ce(await Me.open(e,r),i)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}};function Ue(t){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[t]}function Ke(t){const e=t.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}var Qe={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},ze=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],te=class extends Error{constructor(t){super(`Unsupported locale: ${t}`),this.localeCode=t}},Ge={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function He(t){if(typeof t!="string"||!t.trim())throw new te(t);const e=t.trim().replace(/_/g,"-").toLowerCase(),i=ze.find(s=>s.toLowerCase()===e);if(i)return i;const r=Ge[e];if(!r)throw new te(t);return r}var ie=class{constructor(e,i){if(this.data=e,this.fallback=i,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(He)}message(e,i){return this.data.locales[e]?.messages[i]??this.fallback?.data.locales[e]?.messages[i]??this.data.locales.en?.messages[i]??this.fallback?.data.locales.en?.messages[i]??i}translate(e,i){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(i,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};ie.builtin=new ie(Qe);var x=class extends Error{constructor(t){super(`Check failed: ${t.map(e=>e.message??`${e.ruleId}:${e.location}`).join("; ")}`),this.violations=t,this.name="CheckException"}};function Xe(t,e){const i=t.defaultDomainRoot,r=e.defaultDomainRoot;if(i&&r&&(i.entity!==r.entity||i.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...t.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??i,constants:[...s.values()],ensure:t.ensure&&e.ensure?async n=>{await t.ensure(n),await e.ensure(n)}:e.ensure??t.ensure}}var Ye=class he{constructor(e={},i={},r={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...i}),this.bootstrap=Object.freeze({defaultDomainRoot:r.defaultDomainRoot,constants:Object.freeze([...r.constants??[]]),ensure:r.ensure})}and(e){return new he({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},Xe(this.bootstrap,e.bootstrap))}},re=class de{constructor(e,i,r,s){this.enabledValue=e,this.cacheExpiredMillis=i,this.propagateValue=r,this.propagateCacheExpiredMillis=s}static enabled(e){return new de(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}},Je=class W{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,i,r,s=!0){return this.facets.push({facetName:e,relationName:i,query:r.toQuery(),includeAllFacets:s}),this}clone(){const e=new W(this.entity);return e.filterCondition=this.filterCondition,e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.orderItems=[...this.orderItems],e.selectItems=[...this.selectItems],e.properties=[...this.properties],e.joins=[...this.joins],e.groupByItems=[...this.groupByItems],e.aggregateItems=this.aggregateItems.map(i=>({...i})),e.aggregationCache=this.aggregationCache,e.facets=this.facets.map(i=>({...i,query:i.query.clone()})),e.relations=this.relations.map(i=>({...i,query:i.query?.clone()})),e.relationAggregates=this.relationAggregates.map(i=>({...i,query:i.query.clone()})),e.commentText=this.commentText,e.purposeText=this.purposeText,e.idSetPaginationOptions=this.idSetPaginationOptions,e.idSetPaginationRuntimeContext=this.idSetPaginationRuntimeContext,e.topNProbeThreshold=this.topNProbeThreshold,e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,i){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(i)||i<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:i},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,i,r){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(i)||i<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(r)||r<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:i,maxIds:r},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const i=new W(this.entity);return i.filterCondition=this.filterCondition,i.commentText=this.commentText,i.purposeText=this.purposeText,i.aggregate("Count","id",e),i}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const i of this.relations)i.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,i,r="id",s="id",n=!0){return this.relations.push({name:e,query:i,localKey:r,foreignKey:s,many:n}),this}relationAggregate(e,i,r,s=!0){return this.relationAggregates.push({relationName:e,alias:i,query:r,singleResult:s}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=re.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=re.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,i,r){return this.aggregateItems.push({function:e,field:i,alias:r}),this}groupBy(e){return this.groupByItems.push(e),this}},I=t=>`${t.entity}\0${typeof t.id}:${String(t.id)}`,A=class{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map}set(t,e,i){if(!e.trim())throw new TypeError("field is required");const r=I(t),s=this.changes.get(r)??{key:Object.freeze({...t}),values:{}};s.values[e]=i,this.changes.set(r,s)}snapshot(){return[...this.changes.values()].map(t=>({key:Object.freeze({...t.key}),values:Object.freeze({...t.values})}))}change(t){return Object.freeze({...this.changes.get(I(t))?.values??{}})}mergeFrom(t){if(t!==this){for(const e of t.snapshot())for(const[i,r]of Object.entries(e.values))this.set(e.key,i,r);for(const e of t.newKeys.values())this.markAsNew(e);for(const e of t.deletedKeys.values())this.markAsDeleted(e);for(const e of t.snapshotVersions())this.setOriginalVersion(e.key,e.version)}}snapshotVersions(){return[...this.originalVersions.values()]}rekey(t,e){const i=I(t),r=I(e);if(i===r)return;const s=this.changes.get(i);if(s){this.changes.delete(i);for(const[o,u]of Object.entries(s.values))this.set(e,o,u)}const n=this.originalVersions.get(i);n!==void 0&&(this.originalVersions.delete(i),this.originalVersions.set(r,{key:Object.freeze({...e}),version:n.version})),this.newKeys.delete(i)&&this.newKeys.set(r,Object.freeze({...e})),this.deletedKeys.delete(i)&&this.deletedKeys.set(r,Object.freeze({...e}))}clearEntity(t){const e=I(t);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e)}setOriginalVersion(t,e){this.originalVersions.set(I(t),{key:Object.freeze({...t}),version:e})}originalVersion(t){return this.originalVersions.get(I(t))?.version}markAsNew(t){this.newKeys.set(I(t),Object.freeze({...t}))}isNew(t){return this.newKeys.has(I(t))}markAsDeleted(t){const e=I(t);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...t}))}isDeleted(t){return this.deletedKeys.has(I(t))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear()}};function me(t){const e=t.split("_");return e[0]+e.slice(1).map(i=>i?i[0].toUpperCase()+i.slice(1):"").join("")}function Ze(t,e){if(e==="snake_case")return t;const i=me(t);return e==="camelCase"||!i?i:i[0].toUpperCase()+i.slice(1)}function et(t){return t.replace(/~/g,"~0").replace(/\//g,"~1")}var S=class L{constructor(e){this.segments=e}static root(){return new L([])}static property(e){return L.root().property(e)}property(e){return new L([...this.segments,{kind:"property",name:e}])}index(e){return new L([...this.segments,{kind:"index",index:e}])}prefixedBy(e){return new L([...e.segments,...this.segments])}modelPath(){return this.render(e=>e)}nativePath(){return this.render(me)}instancePath(e="camelCase"){return this.segments.map(i=>i.kind==="index"?String(i.index):et(Ze(i.name,e))).map(i=>`/${i}`).join("")}toString(){return this.nativePath()}render(e){let i="";for(const r of this.segments)r.kind==="index"?i+=`[${r.index}]`:i+=`${i?".":""}${e(r.name)}`;return i}},q=class U extends Array{static get[Symbol.species](){return Array}constructor(e=[],i={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,U.prototype),this.totalCount=i.totalCount,this.aggregations=i.aggregations??{},this.summary=i.summary??{},this.facets=i.facets??{},this.isLoaded=i.isLoaded??!0}static empty(){return new U([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,i){return this.facets[e]=i,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}};function tt(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function K(t){if(t&&typeof t=="object"){const e=t;return e.id??e.Id}return t}function it(t,e){const i=tt(e);for(const r of[e,`${e}Id`,i,`${i}_id`]){const s=K(t[r]);if(s!=null)return s}}async function pe(t,e,i,r){const s={};for(const n of r){let o;if(t.executeFacetMembership)o=await t.executeFacetMembership(e(i.clone()),n.relationName);else{const l=i.clone();l.facets=[],l.relations=[],l.orderItems=[],l.aggregateItems=[],l.groupByItems=[],l.offsetValue=0,l.limitValue=0,l.selectItems=[n.relationName];const m=await t.executeQuery(e(l));o=new Map;for(const d of m){const p=it(d,n.relationName);if(p==null)continue;const f=String(p);o.set(f,(o.get(f)??0)+1)}}const u=n.query.clone();u.facets=[];const a=u.aggregateItems.filter(l=>String(l.function).toLowerCase()==="count").map(l=>String(l.alias));u.aggregateItems=[],u.groupByItems=[];const h=(await t.executeQuery(e(u))).map(l=>{const m=o.get(String(K(l.id??l.Id)))??0,d={...l};for(const p of a)d[p]=m;return d}).filter(l=>n.includeAllFacets||o.has(String(K(l.id??l.Id))));s[n.facetName]=new q(h)}return s}class R extends Je{orderBy(e,i){return this.order({field:e,expr:null,direction:i==="desc"?"Desc":"Asc"})}relationQuery(e,i,r="id",s="id",n=!0){return this.relations.push({name:e,query:i,localKey:r,foreignKey:s,many:n}),this}}class b{static teaqlTemporaryId=0;id;title;description;platform;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--b.teaqlTemporaryId,writable:!0,enumerable:!1}),e){const r={...e};Object.assign(this,r),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof v?e.platform:v.fromRecord(e.platform),this.markLoaded("platform"))}const i=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(i):this.version!==void 0&&this._root.setOriginalVersion(i,Number(this.version))}teaqlEntityKey(){return{entity:"WorkItem",id:this._ledgerId}}teaqlAttachRoot(e){return this._root!==e&&(e.mergeFrom(this._root),this._root=e),this}static fromRecord(e,i){const r=new b(e);return i?r.teaqlAttachRoot(i):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const i of e)this._loadedFields.add(i);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new b({id:String(e)})}static teaqlBootstrapNew(e){return new b().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const i=e.requireResource("dataService");return i.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,i),this.teaqlSaveWithinGraph(e,i)))}teaqlPreflightGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"title",canonical:"title"},{member:"description",canonical:"description"},{member:"platform",canonical:"platform"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new x([{ruleId:"invalid_type",location:S.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}i.preflightMutation({entity:"WorkItem",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root})}async teaqlSaveWithinGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"WorkItem",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},o=await i.executeMutation(n);for(const[h,l]of Object.entries(n.payload))h!=="id"&&h!=="version"&&this._root.set(this.teaqlEntityKey(),h,l);if(!o.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},a=this.teaqlEntityKey();Object.assign(this,o.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();return this._root.rekey(a,c),i.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(c,a)}),this._loadedFields=new Set(Object.keys(o.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update"),i.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.setOriginalVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,title:this.title,description:this.description,platform:this.platform,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateTitle(e){return this.title=e,this.markLoaded("title"),this._root.set(this.teaqlEntityKey(),"title",e),this}updateDescription(e){return this.description=e,this.markLoaded("description"),this._root.set(this.teaqlEntityKey(),"description",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}}class v{static teaqlTemporaryId=0;id;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--v.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_workItemList",{value:[],writable:!0,enumerable:!1}),e){const r={...e};delete r.workItemList,Object.assign(this,r),Array.isArray(e.workItemList)&&(this._workItemList=e.workItemList.map(s=>s instanceof b?s:b.fromRecord(s)),this.markLoaded("workItemList"))}const i=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(i):this.version!==void 0&&this._root.setOriginalVersion(i,Number(this.version))}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const i of this._workItemList)i.teaqlAttachRoot(e);return this}static fromRecord(e,i){const r=new v(e);return i?r.teaqlAttachRoot(i):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const i of e)this._loadedFields.add(i);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new v({id:String(e)})}static teaqlBootstrapNew(e){return new v().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const i=e.requireResource("dataService");return i.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,i),this.teaqlSaveWithinGraph(e,i)))}teaqlPreflightGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new x([{ruleId:"invalid_type",location:S.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}i.preflightMutation({entity:"Platform",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root});for(const[s,n]of this._workItemList.entries()){n.teaqlAttachRoot(this._root),n.updatePlatform(this),n.auditAs(this._comment);try{n.teaqlPreflightGraph(e,i)}catch(o){if(!(o instanceof x))throw o;const u=S.property("work_item_list").index(s);throw new x(o.violations.map(a=>({...a,location:a.location.prefixedBy(u)})))}}}async teaqlSaveWithinGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"Platform",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},o=await i.executeMutation(n);for(const[h,l]of Object.entries(n.payload))h!=="id"&&h!=="version"&&this._root.set(this.teaqlEntityKey(),h,l);if(!o.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},a=this.teaqlEntityKey();Object.assign(this,o.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(a,c),i.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(c,a)}),this._loadedFields=new Set(Object.keys(o.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update");for(const[h,l]of this._workItemList.entries()){l.teaqlAttachRoot(this._root),l.updatePlatform(this),l.auditAs(this._comment);try{await l.teaqlSaveWithinGraph(e,e.requireResource("dataService"))}catch(m){if(!(m instanceof x))throw m;const d=S.property("work_item_list").index(h);throw new x(m.violations.map(p=>({...p,location:p.location.prefixedBy(d)})))}}return i.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.setOriginalVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}workItemList(){return this._workItemList}}class se{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new R("Platform"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new rt(i=>this.executeForListInternal(i),i=>this.executeForRowsInternal(i),(i,r,s)=>this.executeForPageInternal(i,r,s),(i,r)=>this.executeForStreamInternal(i,r),()=>this.limit(1),i=>this.comment(i),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,i){return this.query.optimizeForContinuousPageFetchWith(e,i),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,i,r){return this.query.optimizePaginationWithIdSetConfig(e,i,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectWorkItemListWith(e){return this.query.relationQuery("workItemList",e.toQuery(),"id","platform",!0),this}haveWorkItems(){return this.withWorkItemListMatching({toQuery:()=>new R("WorkItem")})}haveNoWorkItems(){return this.withoutWorkItemListMatching({toQuery:()=>new R("WorkItem")})}withWorkItemListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutWorkItemListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}countWorkItems(){return this.countWorkItemsAs("countWorkItems")}countWorkItemsAs(e){const i=new R("WorkItem").filter({version:{$gte:1}});return this.countWorkItemsWith(e,{toQuery:()=>i})}countWorkItemsWith(e,i){return i.toQuery().aggregate("Count","id",e),this.query.relationAggregate("workItemList",e,i.toQuery(),!0),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,i){return this.filters.push({id:{$between:[e,i]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,i){return this.filters.push({name:{$between:[e,i]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,i){return this.filters.push({version:{$between:[e,i]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),r=await i.executeQuery(e.prepareQuery(this.query)),s=new A,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:r.map(a=>a instanceof v?a:v.fromRecord(a,s)),u=new q(o);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await pe(i,a=>e.prepareQuery(a),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService");return new q(await i.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,i,r){this.ensureIntent(),this.query.offset(i).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),a=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:o??await s.executeCount(this.query),c=new A,h=new q(u.map(l=>l instanceof v?l:v.fromRecord(l,c)));return h.totalCount=a,{data:h,totalCount:a,offset:i,limit:r}}async*executeForStreamInternal(e,i){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new A;for await(const n of r.executeForStream(this.query,i))for(const o of n)yield o instanceof v?o:v.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class rt{constructor(e,i,r,s,n,o,u){this.execute=e,this.executeRows=i,this.page=r,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new v}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,i,r){return this.ensureIntent(),this.page(e,i,r)}executeForStream(e,i=1e3){return this.ensureIntent(),this.stream(e,i)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class ne{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new R("WorkItem"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new st(i=>this.executeForListInternal(i),i=>this.executeForRowsInternal(i),(i,r,s)=>this.executeForPageInternal(i,r,s),(i,r)=>this.executeForStreamInternal(i,r),()=>this.limit(1),i=>this.comment(i),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,i){return this.query.optimizeForContinuousPageFetchWith(e,i),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,i,r){return this.query.optimizePaginationWithIdSetConfig(e,i,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","title","description","platform","version"]),this}selectId(){return this.query.select(["id"]),this}selectTitle(){return this.query.select(["title"]),this}selectDescription(){return this.query.select(["description"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,i){return this.filters.push({id:{$between:[e,i]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withTitleContaining(e){return this.filters.push({title:{$contains:e}}),this}withTitleIs(e){return this.filters.push({title:{$eq:e}}),this}withTitleIsNot(e){return this.filters.push({title:{$ne:e}}),this}withTitleIn(...e){return this.filters.push({title:{$in:e}}),this}withTitleNotIn(...e){return this.filters.push({title:{$notIn:e}}),this}withTitleGreaterThan(e){return this.filters.push({title:{$gt:e}}),this}withTitleGreaterThanOrEqualTo(e){return this.filters.push({title:{$gte:e}}),this}withTitleLessThan(e){return this.filters.push({title:{$lt:e}}),this}withTitleLessThanOrEqualTo(e){return this.filters.push({title:{$lte:e}}),this}withTitleBetween(e,i){return this.filters.push({title:{$between:[e,i]}}),this}withTitleIsKnown(){return this.filters.push({title:{$isNull:!1}}),this}withTitleIsUnknown(){return this.filters.push({title:{$isNull:!0}}),this}withTitleNotContaining(e){return this.filters.push({title:{$notContains:e}}),this}withTitleStartingWith(e){return this.filters.push({title:{$startsWith:e}}),this}withTitleNotStartingWith(e){return this.filters.push({title:{$notStartsWith:e}}),this}withTitleEndingWith(e){return this.filters.push({title:{$endsWith:e}}),this}withTitleNotEndingWith(e){return this.filters.push({title:{$notEndsWith:e}}),this}withTitleSoundingLike(e){return this.filters.push({title:{$soundLike:e}}),this}withDescriptionContaining(e){return this.filters.push({description:{$contains:e}}),this}withDescriptionIs(e){return this.filters.push({description:{$eq:e}}),this}withDescriptionIsNot(e){return this.filters.push({description:{$ne:e}}),this}withDescriptionIn(...e){return this.filters.push({description:{$in:e}}),this}withDescriptionNotIn(...e){return this.filters.push({description:{$notIn:e}}),this}withDescriptionGreaterThan(e){return this.filters.push({description:{$gt:e}}),this}withDescriptionGreaterThanOrEqualTo(e){return this.filters.push({description:{$gte:e}}),this}withDescriptionLessThan(e){return this.filters.push({description:{$lt:e}}),this}withDescriptionLessThanOrEqualTo(e){return this.filters.push({description:{$lte:e}}),this}withDescriptionBetween(e,i){return this.filters.push({description:{$between:[e,i]}}),this}withDescriptionIsKnown(){return this.filters.push({description:{$isNull:!1}}),this}withDescriptionIsUnknown(){return this.filters.push({description:{$isNull:!0}}),this}withDescriptionNotContaining(e){return this.filters.push({description:{$notContains:e}}),this}withDescriptionStartingWith(e){return this.filters.push({description:{$startsWith:e}}),this}withDescriptionNotStartingWith(e){return this.filters.push({description:{$notStartsWith:e}}),this}withDescriptionEndingWith(e){return this.filters.push({description:{$endsWith:e}}),this}withDescriptionNotEndingWith(e){return this.filters.push({description:{$notEndsWith:e}}),this}withDescriptionSoundingLike(e){return this.filters.push({description:{$soundLike:e}}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,i){return this.filters.push({version:{$between:[e,i]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByTitleAscending(){return this.query.orderBy("title","asc"),this}orderByTitleDescending(){return this.query.orderBy("title","desc"),this}orderByDescriptionAscending(){return this.query.orderBy("description","asc"),this}orderByDescriptionDescending(){return this.query.orderBy("description","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByTitle(){return this.query.groupBy("title"),this}groupByTitleAs(e){return this.query.groupBy("title"),this}groupByDescription(){return this.query.groupBy("description"),this}groupByDescriptionAs(e){return this.query.groupBy("description"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,i,r=!0){return this.query.facetBy(e,"platform",i,r),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),r=await i.executeQuery(e.prepareQuery(this.query)),s=new A,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:r.map(a=>a instanceof b?a:b.fromRecord(a,s)),u=new q(o);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await pe(i,a=>e.prepareQuery(a),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService");return new q(await i.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,i,r){this.ensureIntent(),this.query.offset(i).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),a=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:o??await s.executeCount(this.query),c=new A,h=new q(u.map(l=>l instanceof b?l:b.fromRecord(l,c)));return h.totalCount=a,{data:h,totalCount:a,offset:i,limit:r}}async*executeForStreamInternal(e,i){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new A;for await(const n of r.executeForStream(this.query,i))for(const o of n)yield o instanceof b?o:b.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class st{constructor(e,i,r,s,n,o,u){this.execute=e,this.executeRows=i,this.page=r,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new b}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,i,r){return this.ensureIntent(),this.page(e,i,r)}executeForStream(e,i=1e3){return this.ensureIntent(),this.stream(e,i)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Q{static platforms(){return new se(!1)}static platformsWithMinimalFields(){return new se(!0)}static workItems(){return new ne(!1)}static workItemsWithMinimalFields(){return new ne(!0)}}const fe={Platform:{table:"platform_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}};async function nt(t){let e=(await Q.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(t))[0];e||(e=v.teaqlBootstrapNew("1"),e.updateName("Runtime Example"),await e.auditAs("create generated Domain Root Platform").save(t)),t.withActiveRoot({entity:"Platform",id:e.id})}const ut=new Ye(fe,{Platform:{checkAndFix(t,e,i){t.getResource("fixTime"),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&i.push({ruleId:"required",location:S.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&i.push({ruleId:"max_length",location:S.property("name"),inputValue:e.payload.name,systemValue:100})}},WorkItem:{checkAndFix(t,e,i){t.getResource("fixTime"),(e.action==="Create"&&e.payload.title===void 0||e.payload.title===null)&&i.push({ruleId:"required",location:S.property("title")}),e.payload.title!=null&&!([...String(e.payload.title)].length>=1)&&i.push({ruleId:"min_length",location:S.property("title"),inputValue:e.payload.title,systemValue:1}),e.payload.title!=null&&[...String(e.payload.title)].length>80&&i.push({ruleId:"max_length",location:S.property("title"),inputValue:e.payload.title,systemValue:80}),e.payload.description!=null&&[...String(e.payload.description)].length>100&&i.push({ruleId:"max_length",location:S.property("description"),inputValue:e.payload.description,systemValue:100}),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&i.push({ruleId:"required",location:S.property("platform")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Runtime Example"}},constants:[],ensure:nt}),z=document.querySelector("#status"),ot=document.querySelector("#result"),N=document.querySelector("#persist"),at=document.querySelector("#opfs-note"),V=document.querySelector("#reset");let $;const P=globalThis.crossOriginIsolated&&typeof navigator.storage?.getDirectory=="function",ge=localStorage.getItem("teaql-browser-storage")==="opfs",Ee=ge&&P?"opfs":"memory";ge&&!P&&localStorage.removeItem("teaql-browser-storage");N.checked=Ee==="opfs";N.disabled=!P;P||(at.textContent="(unavailable on this static host; memory mode remains fully browser-local)");async function lt(t){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),i=await We.open(e,{...fe},{storage:t,databaseName:"teaql-browser-example.sqlite3"});i.install(ut);const r=new ae().insertResource("dataService",i);return i.setUserContext(r),await r.ensureSchema(),{client:i,context:r}}async function ye({context:t}){if(!(await Q.workItemsWithMinimalFields().comment("what: detect existing browser demo records").purpose("why: keep generated mutation bootstrap idempotent").executeForList(t)).length)for(const i of["Evaluate semantic model","Generate typed library","Verify browser runtime"])await new b().updateTitle(i).updatePlatform("1").auditAs("seed deterministic browser demo data").save(t)}async function we(t){const e=await Q.workItems().selectTitle().orderByIdAscending().limit(20).comment("what: load browser-local work items").purpose("why: prove the generated Q API runs without a backend").executeForList(t.context);ot.textContent=JSON.stringify(e,null,2),z.textContent=`${t.client.storage.toUpperCase()} · ${e.length} rows · ready`}async function Ce(t){z.textContent=`Opening ${t.toUpperCase()} SQLite/WASM…`;const e=$;$=void 0,await e?.client.close();const i=await lt(t);$=i,await ye(i),await we(i)}N.addEventListener("change",()=>{const t=N.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",t),Ce(t).catch(G)});V.addEventListener("click",async()=>{if($){V.disabled=!0;try{await $.client.reset($.context),await ye($),await we($)}catch(t){G(t)}finally{V.disabled=!1}}});function G(t){const e=t instanceof Error?t:new Error(String(t));z.textContent=`${e.name}: ${e.message}`}Ce(Ee).catch(G); diff --git a/assets/index-inj2slTy.css b/assets/index-inj2slTy.css deleted file mode 100644 index 8a15c8cb5bb0fef5d11ec596f176f905a1a9aced..0000000000000000000000000000000000000000 --- a/assets/index-inj2slTy.css +++ /dev/null @@ -1 +0,0 @@ -:root{font:16px/1.5 Inter,system-ui,sans-serif;color:#e8edf5;background:#090b10;color-scheme:dark}body{margin:0}main{width:min(1120px,calc(100% - 40px));margin:6vh auto}.eyebrow{color:#d9ff52;font-size:12px;font-weight:800;letter-spacing:.16em}h1{margin:8px 0;font-size:clamp(36px,7vw,68px);letter-spacing:-.05em}.controls{display:flex;gap:18px;align-items:center;margin:32px 0}button,select{border:0;border-radius:5px;padding:10px 14px;font:inherit;font-weight:700}button{background:#d9ff52;color:#111;cursor:pointer}button:disabled{cursor:wait;opacity:.55}select{background:#202630;color:#e8edf5}#status{color:#aab4c4}.query-panel,.response-panel{margin-top:22px;border:1px solid #2b323e;border-radius:10px;background:#11151c;overflow:hidden}.query-toolbar,.response-heading{display:flex;gap:12px;align-items:center;padding:14px 16px;border-bottom:1px solid #2b323e}.query-toolbar label{color:#aab4c4;font-size:13px;font-weight:800;text-transform:uppercase;letter-spacing:.08em}.query-toolbar .run{margin-left:auto;min-width:120px}textarea{box-sizing:border-box;width:100%;min-height:330px;resize:vertical;border:0;outline:0;padding:22px;background:#0c1016;color:#d9ff52;font:15px/1.65 ui-monospace,SFMono-Regular,Menlo,monospace;tab-size:2}.hint{margin:0;padding:10px 16px;border-top:1px solid #2b323e;color:#7f8a9a;font-size:13px}.response-heading{justify-content:space-between}.response-heading h2{margin:0;font-size:18px}.response-heading span{color:#8c98a8;font:12px ui-monospace,monospace}pre{box-sizing:border-box;min-height:360px;margin:0;padding:22px;overflow:auto;background:#11151c;color:#c6d1df;font-size:14px}@media(max-width:640px){main{width:min(100% - 24px,1120px);margin:24px auto}.controls,.query-toolbar{align-items:stretch;flex-direction:column}.query-toolbar .run{margin-left:0}} diff --git a/assets/main-gHLGx1pH.js b/assets/main-gHLGx1pH.js new file mode 100644 index 0000000000000000000000000000000000000000..5de35f55d321681eb889d38d979c8068d7a7b040 --- /dev/null +++ b/assets/main-gHLGx1pH.js @@ -0,0 +1,102 @@ +import{S as T,m as Te,a as ie,e as de,O as R,B as Qe,b as $e,R as Re,U as Be,D as Fe,c as ke,M as We}from"./dynamic-search-BBmdgl4H.js";/* empty css */const C=t=>({columnName:t,modelName:t,logicalType:"integer",decode:"string"}),y=t=>({columnName:t,modelName:t,logicalType:"text",decode:"native"}),ze=t=>({columnName:t,modelName:t,logicalType:"date",decode:"date"}),K=t=>({columnName:t,modelName:t,logicalType:"datetime",decode:"date"}),I=(t,e="decimal")=>({columnName:t,modelName:t,logicalType:e,decode:"number"}),f=Object.freeze({PENDING_PAYMENT:"1001",PAID:"1002",SHIPPED:"1003",DELIVERED:"1004",CANCELLED:"1005"}),_e=[{entity:"OrderStatus",id:f.PENDING_PAYMENT,values:{name:"Pending payment",code:"PENDING_PAYMENT",color:"#D97706",displayOrder:10}},{entity:"OrderStatus",id:f.PAID,values:{name:"Paid",code:"PAID",color:"#2563EB",displayOrder:20}},{entity:"OrderStatus",id:f.SHIPPED,values:{name:"Shipped",code:"SHIPPED",color:"#16A34A",displayOrder:30}},{entity:"OrderStatus",id:f.DELIVERED,values:{name:"Delivered",code:"DELIVERED",color:"#047857",displayOrder:40}},{entity:"OrderStatus",id:f.CANCELLED,values:{name:"Cancelled",code:"CANCELLED",color:"#9F1239",displayOrder:50}}],ce={Platform:{table:"platform_data",columns:{id:C("id"),name:y("name"),code:y("code"),region:y("region"),currency:y("currency"),version:I("version","integer")},relations:{customerList:{targetEntity:"Customer",localKey:"id",foreignKey:"platformId",many:!0},orderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"platformId",many:!0}}},Customer:{table:"customer_data",columns:{id:C("id"),name:y("name"),email:y("email"),city:y("city"),tier:y("tier"),platformId:C("platform_id"),version:I("version","integer")},relations:{platform:{targetEntity:"Platform",localKey:"platformId",foreignKey:"id",many:!1},orderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"customerId",many:!0}}},CustomerOrder:{table:"customer_order_data",columns:{id:C("id"),orderNumber:y("order_number"),orderDate:ze("order_date"),status:C("status_id"),totalAmount:I("total_amount"),currency:y("currency"),customerId:C("customer_id"),platformId:C("platform_id"),version:I("version","integer")},relations:{platform:{targetEntity:"Platform",localKey:"platformId",foreignKey:"id",many:!1},customer:{targetEntity:"Customer",localKey:"customerId",foreignKey:"id",many:!1},status:{targetEntity:"OrderStatus",localKey:"status",foreignKey:"id",many:!1},itemList:{targetEntity:"OrderItem",localKey:"id",foreignKey:"orderId",many:!0},paymentList:{targetEntity:"Payment",localKey:"id",foreignKey:"orderId",many:!0},shipmentList:{targetEntity:"Shipment",localKey:"id",foreignKey:"orderId",many:!0}}},OrderStatus:{table:"order_status_data",columns:{id:C("id"),name:y("name"),code:y("code"),color:y("color"),displayOrder:I("display_order","integer"),version:I("version","integer")},relations:{orderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"status",many:!0}}},OrderItem:{table:"order_item_data",columns:{id:C("id"),orderId:C("order_id"),productName:y("product_name"),sku:y("sku"),quantity:I("quantity","integer"),unitPrice:I("unit_price"),lineAmount:I("line_amount"),version:I("version","integer")},relations:{order:{targetEntity:"CustomerOrder",localKey:"orderId",foreignKey:"id",many:!1}}},Payment:{table:"payment_data",columns:{id:C("id"),orderId:C("order_id"),provider:y("provider"),status:y("status"),amount:I("amount"),currency:y("currency"),transactionId:y("transaction_id"),paidAt:K("paid_at"),version:I("version","integer")},relations:{order:{targetEntity:"CustomerOrder",localKey:"orderId",foreignKey:"id",many:!1}}},Shipment:{table:"shipment_data",columns:{id:C("id"),orderId:C("order_id"),carrier:y("carrier"),status:y("status"),trackingNumber:y("tracking_number"),shipToCity:y("ship_to_city"),shippedAt:K("shipped_at"),deliveredAt:K("delivered_at"),version:I("version","integer")},relations:{order:{targetEntity:"CustomerOrder",localKey:"orderId",foreignKey:"id",many:!1}}}},he=[{entity:"Platform",id:"1",payload:{name:"TeaQL Store",code:"TEAQL-CN",region:"China",currency:"CNY"}},{entity:"Platform",id:"2",payload:{name:"TeaQL Global",code:"TEAQL-GLOBAL",region:"Global",currency:"USD"}},{entity:"Customer",id:"101",payload:{name:"Lin Xiao",email:"lin.xiao@example.com",city:"Shanghai",tier:"GOLD",platformId:"1"}},{entity:"Customer",id:"102",payload:{name:"Zhou Ran",email:"zhou.ran@example.com",city:"Hangzhou",tier:"SILVER",platformId:"1"}},{entity:"Customer",id:"103",payload:{name:"Maya Patel",email:"maya.patel@example.com",city:"Singapore",tier:"GOLD",platformId:"2"}},{entity:"Customer",id:"104",payload:{name:"Lucas Martin",email:"lucas.martin@example.com",city:"Paris",tier:"SILVER",platformId:"2"}},{entity:"Customer",id:"105",payload:{name:"Wang Ning",email:"wang.ning@example.com",city:"Chengdu",tier:"BRONZE",platformId:"1"}},{entity:"CustomerOrder",id:"1001",payload:{orderNumber:"TQL-2026-1001",orderDate:"2026-08-28",status:f.DELIVERED,totalAmount:499,currency:"CNY",customerId:"101",platformId:"1"}},{entity:"CustomerOrder",id:"1002",payload:{orderNumber:"TQL-2026-1002",orderDate:"2026-09-02",status:f.SHIPPED,totalAmount:1299,currency:"CNY",customerId:"102",platformId:"1"}},{entity:"CustomerOrder",id:"1003",payload:{orderNumber:"TQL-2026-1003",orderDate:"2026-09-06",status:f.PAID,totalAmount:328.8,currency:"CNY",customerId:"101",platformId:"1"}},{entity:"CustomerOrder",id:"1004",payload:{orderNumber:"TQL-2026-1004",orderDate:"2026-09-11",status:f.PENDING_PAYMENT,totalAmount:79.9,currency:"CNY",customerId:"105",platformId:"1"}},{entity:"CustomerOrder",id:"1005",payload:{orderNumber:"TQL-2026-1005",orderDate:"2026-09-14",status:f.DELIVERED,totalAmount:219,currency:"USD",customerId:"103",platformId:"2"}},{entity:"CustomerOrder",id:"1006",payload:{orderNumber:"TQL-2026-1006",orderDate:"2026-09-18",status:f.PAID,totalAmount:640,currency:"USD",customerId:"104",platformId:"2"}},{entity:"CustomerOrder",id:"1007",payload:{orderNumber:"TQL-2026-1007",orderDate:"2026-09-21",status:f.CANCELLED,totalAmount:159,currency:"CNY",customerId:"102",platformId:"1"}},{entity:"CustomerOrder",id:"1008",payload:{orderNumber:"TQL-2026-1008",orderDate:"2026-09-25",status:f.SHIPPED,totalAmount:268,currency:"CNY",customerId:"105",platformId:"1"}},{entity:"OrderItem",id:"2001",payload:{orderId:"1001",productName:"TeaQL Mechanical Keyboard",sku:"KB-TQL-87",quantity:1,unitPrice:299,lineAmount:299}},{entity:"OrderItem",id:"2002",payload:{orderId:"1001",productName:"Silent Wireless Mouse",sku:"MS-SILENT",quantity:2,unitPrice:100,lineAmount:200}},{entity:"OrderItem",id:"2003",payload:{orderId:"1002",productName:"27-inch Developer Monitor",sku:"MON-27-4K",quantity:1,unitPrice:1299,lineAmount:1299}},{entity:"OrderItem",id:"2004",payload:{orderId:"1003",productName:"White Porcelain Travel Tea Set",sku:"TEA-TRAVEL",quantity:1,unitPrice:168.8,lineAmount:168.8}},{entity:"OrderItem",id:"2005",payload:{orderId:"1003",productName:"Pre-Qingming Longjing Tea",sku:"TEA-LJ-100",quantity:2,unitPrice:80,lineAmount:160}},{entity:"OrderItem",id:"2006",payload:{orderId:"1004",productName:"Double-wall Glass Tumbler",sku:"CUP-GLASS",quantity:1,unitPrice:79.9,lineAmount:79.9}},{entity:"OrderItem",id:"2007",payload:{orderId:"1005",productName:"Travel Brew Kit",sku:"BREW-KIT",quantity:1,unitPrice:219,lineAmount:219}},{entity:"OrderItem",id:"2008",payload:{orderId:"1006",productName:"Desktop Studio Speaker",sku:"SPK-STUDIO",quantity:2,unitPrice:260,lineAmount:520}},{entity:"OrderItem",id:"2009",payload:{orderId:"1006",productName:"Speaker Stand",sku:"SPK-STAND",quantity:1,unitPrice:120,lineAmount:120}},{entity:"OrderItem",id:"2010",payload:{orderId:"1007",productName:"Desktop Reading Lamp",sku:"LAMP-DESK",quantity:1,unitPrice:159,lineAmount:159}},{entity:"OrderItem",id:"2011",payload:{orderId:"1008",productName:"TeaQL Portable Keyboard",sku:"KB-TQL-68",quantity:1,unitPrice:268,lineAmount:268}},{entity:"Payment",id:"3001",payload:{orderId:"1001",provider:"Alipay",status:"CAPTURED",amount:499,currency:"CNY",transactionId:"ALI-260828-01",paidAt:"2026-08-28T10:14:00Z"}},{entity:"Payment",id:"3002",payload:{orderId:"1002",provider:"WeChat Pay",status:"CAPTURED",amount:1299,currency:"CNY",transactionId:"WX-260902-08",paidAt:"2026-09-02T03:20:00Z"}},{entity:"Payment",id:"3003",payload:{orderId:"1003",provider:"Alipay",status:"CAPTURED",amount:328.8,currency:"CNY",transactionId:"ALI-260906-11",paidAt:"2026-09-06T11:42:00Z"}},{entity:"Payment",id:"3004",payload:{orderId:"1004",provider:"WeChat Pay",status:"PENDING",amount:79.9,currency:"CNY",transactionId:"WX-260911-02",paidAt:null}},{entity:"Payment",id:"3005",payload:{orderId:"1005",provider:"Stripe",status:"CAPTURED",amount:219,currency:"USD",transactionId:"PI-260914-05",paidAt:"2026-09-14T06:10:00Z"}},{entity:"Payment",id:"3006",payload:{orderId:"1006",provider:"Stripe",status:"CAPTURED",amount:640,currency:"USD",transactionId:"PI-260918-03",paidAt:"2026-09-18T15:08:00Z"}},{entity:"Payment",id:"3007",payload:{orderId:"1007",provider:"Alipay",status:"REFUNDED",amount:159,currency:"CNY",transactionId:"ALI-260921-07",paidAt:"2026-09-21T02:55:00Z"}},{entity:"Payment",id:"3008",payload:{orderId:"1008",provider:"WeChat Pay",status:"CAPTURED",amount:268,currency:"CNY",transactionId:"WX-260925-06",paidAt:"2026-09-25T08:31:00Z"}},{entity:"Shipment",id:"4001",payload:{orderId:"1001",carrier:"SF Express",status:"DELIVERED",trackingNumber:"SF2608281001",shipToCity:"Shanghai",shippedAt:"2026-08-29T02:00:00Z",deliveredAt:"2026-08-30T07:26:00Z"}},{entity:"Shipment",id:"4002",payload:{orderId:"1002",carrier:"JD Logistics",status:"IN_TRANSIT",trackingNumber:"JD2609021002",shipToCity:"Hangzhou",shippedAt:"2026-09-03T04:12:00Z",deliveredAt:null}},{entity:"Shipment",id:"4003",payload:{orderId:"1003",carrier:"SF Express",status:"READY",trackingNumber:"SF2609061003",shipToCity:"Shanghai",shippedAt:null,deliveredAt:null}},{entity:"Shipment",id:"4004",payload:{orderId:"1005",carrier:"DHL",status:"DELIVERED",trackingNumber:"DHL2609141005",shipToCity:"Singapore",shippedAt:"2026-09-15T01:10:00Z",deliveredAt:"2026-09-17T09:22:00Z"}},{entity:"Shipment",id:"4005",payload:{orderId:"1006",carrier:"DHL",status:"READY",trackingNumber:"DHL2609181006",shipToCity:"Paris",shippedAt:null,deliveredAt:null}},{entity:"Shipment",id:"4006",payload:{orderId:"1008",carrier:"SF Express",status:"IN_TRANSIT",trackingNumber:"SF2609251008",shipToCity:"Chengdu",shippedAt:"2026-09-26T03:18:00Z",deliveredAt:null}}],L=t=>`'${t.replaceAll("\\","\\\\").replaceAll("'","\\'").replaceAll(` +`,"\\n")}'`,U=t=>t.toQExpression().replace(/\s*\n\s*/g,""),Me={CustomerOrder:{fields:{id:"integer",orderNumber:"string",orderDate:"date",status:"integer",totalAmount:"decimal",currency:"string",customerId:"integer",platformId:"integer"},relations:{status:"OrderStatus",itemList:"OrderItem"}},OrderStatus:{fields:{id:"integer",name:"string",code:"string",color:"string",displayOrder:"integer"},relations:{}},OrderItem:{fields:{id:"integer",orderId:"integer",productName:"string",sku:"string"},relations:{}}};function Ke(t){if(!t||typeof t!="object"||Array.isArray(t))return t;const e=structuredClone(t),r=e.filter;if(!r||typeof r!="object"||Array.isArray(r)||!("status"in r))return e;const n=r,o=n.status,s=d=>{const a=f[String(d)];return a===void 0?d:Number(a)};return o&&typeof o=="object"&&!Array.isArray(o)&&"$in"in o?n.status={$in:Array.isArray(o.$in)?o.$in.map(s):o.$in}:n.status=s(o),e}class D{query;filters=[];qRoot;qSteps=[];auditComment="";queryPurpose="";pageTotalAlias;constructor(e,r){this.query=new T(e),this.qRoot=r}comment(e){return this.auditComment=e,this.query.comment(e),this.record(`comment(${L(e)})`),this}purpose(e){return this.queryPurpose=e,this.query.purpose(e),this.record(`purpose(${L(e)})`),this}limit(e){return this.query.limit(e),this.record(`limit(${e})`),this}offset(e){return this.query.offset(e),this.record(`offset(${e})`),this}toQExpression(e){const r=e?[...this.qSteps,e]:this.qSteps;return[this.qRoot,...r.map(n=>` .${n}`)].join(` +`)}toQuery(){const e=this.query.clone();return this.filters.length&&e.filter({$and:[...this.filters]}),e}async executeForList(e){this.ensureIntent();const r=this.service(e),n=this.toQuery(),o=await r.executeQuery(e.prepareQuery(n)),s=new ie(o);return n.facets.length&&(s.facets=await de(r,d=>e.prepareQuery(d),n,n.facets)),s}async executeForRows(e){return this.executeForList(e)}async executeForPage(e,r,n){this.ensureIntent();const o=this.service(e),s=this.toQuery(),d=await o.executeCount(s,this.pageTotalAlias,this.pageTotalAlias?{kind:"named-count",method:"countAs",alias:this.pageTotalAlias}:void 0),a=this.toQuery().offset(r).limit(n),c=new ie(await o.executeQuery(e.prepareQuery(a)),{totalCount:d});return this.pageTotalAlias&&(c.aggregations[this.pageTotalAlias]=d),s.facets.length&&(c.facets=await de(o,m=>e.prepareQuery(m),s,s.facets)),{data:c,totalCount:d,offset:r,limit:n}}addFilter(e){return this.filters.push(e),this}select(...e){return this.query.select(e),this}order(e,r){return this.query.order(r==="asc"?R.asc(e):R.desc(e)),this}group(e){return this.query.groupBy(e),this}aggregate(e,r,n){return this.query.aggregate(e,r,n),this}record(e){return this.qSteps.push(e),this}includePageTotalAs(e){return this.pageTotalAlias=e,this}service(e){return e.requireResource("dataService")}ensureIntent(){if(!this.auditComment.trim()||!this.queryPurpose.trim())throw new Error("Generated Q requests require comment() and purpose() before execution")}}class Ue extends D{constructor(){super("Platform","Q.platforms()")}selectId(){return this.select("id")}selectName(){return this.select("name")}selectCode(){return this.select("code")}withIdIs(e){return this.addFilter({id:{$eq:e}})}}class Ye extends D{constructor(){super("Customer","Q.customers()")}selectId(){return this.select("id")}selectName(){return this.select("name")}selectCity(){return this.select("city")}selectTier(){return this.select("tier")}selectPlatformWith(e){return this.query.relationQuery("platform",e.toQuery(),"platformId","id",!1),this}countOrderListAs(e){return this.query.relationAggregate("orderList",e,new T("CustomerOrder").aggregate("Count","id",e)),this}orderByNameAscending(){return this.order("name","asc")}}class Ge extends D{constructor(){super("OrderItem","Q.orderItems()")}selectId(){return this.select("id"),this.record("selectId()")}selectOrderId(){return this.select("orderId"),this.record("selectOrderId()")}selectProductName(){return this.select("productName"),this.record("selectProductName()")}selectSku(){return this.select("sku"),this.record("selectSku()")}selectQuantity(){return this.select("quantity"),this.record("selectQuantity()")}withProductNameContaining(e){return this.addFilter({productName:{$contains:e}})}orderByIdAscending(){return this.order("id","asc"),this.record("orderByIdAscending()")}groupByProductName(){return this.group("productName")}sumQuantityAs(e){return this.aggregate("Sum","quantity",e)}sumLineAmountAs(e){return this.aggregate("Sum","lineAmount",e)}countAs(e){return this.aggregate("Count","id",e)}}class je extends D{constructor(){super("OrderStatus","Q.orderStatuses()")}selectId(){return this.select("id"),this.record("selectId()")}selectName(){return this.select("name"),this.record("selectName()")}selectCode(){return this.select("code"),this.record("selectCode()")}selectColor(){return this.select("color"),this.record("selectColor()")}selectDisplayOrder(){return this.select("displayOrder"),this.record("selectDisplayOrder()")}withCodeIs(e){return this.addFilter({code:{$eq:e}})}countAs(e){return this.aggregate("Count","id",e),this.record(`countAs(${L(e)})`)}sumOrderTotalAmountAs(e){return this.aggregate("Sum","totalAmount",e),this.record(`sumOrderTotalAmountAs(${L(e)})`)}orderByDisplayOrderAscending(){return this.order("displayOrder","asc"),this.record("orderByDisplayOrderAscending()")}}class He extends D{constructor(){super("Payment","Q.payments()")}groupByCurrency(){return this.group("currency")}groupByProvider(){return this.group("provider")}groupByStatus(){return this.group("status")}countAs(e){return this.aggregate("Count","id",e)}sumAmountAs(e){return this.aggregate("Sum","amount",e)}orderByCurrencyAscending(){return this.order("currency","asc")}orderByProviderAscending(){return this.order("provider","asc")}orderByIdAscending(){return this.order("id","asc")}}class Ve extends D{constructor(){super("Shipment","Q.shipments()")}withStatusIn(...e){return this.addFilter({status:{$in:e}})}selectOrderWith(e){return this.query.relationQuery("order",e.toQuery(),"orderId","id",!1),this}orderByStatusAscending(){return this.order("status","asc")}orderByIdAscending(){return this.order("id","asc")}}class ue extends D{dynamicWarnings=[];countAlias;rowCountApplied=!1;constructor(e=!1){super("CustomerOrder",e?"Q.customerOrdersWithMinimalFields()":"Q.customerOrders()"),e?this.query.select(["id","version"]):this.query.select(["id","orderNumber","orderDate","status","totalAmount","currency","customerId","platformId","version"])}selectId(){return this.select("id")}selectOrderNumber(){return this.select("orderNumber"),this.record("selectOrderNumber()")}selectOrderDate(){return this.select("orderDate"),this.record("selectOrderDate()")}selectStatus(){return this.select("status")}selectTotalAmount(){return this.select("totalAmount")}selectCurrency(){return this.select("currency")}withOrderNumberIs(e){return this.addFilter({orderNumber:{$eq:e}})}withOrderNumberContaining(e){return this.addFilter({orderNumber:{$contains:e}})}withStatusMatching(e){return this.addFilter({status:{$inSubquery:{query:e.toQuery(),field:"id"}}})}withStatusIsPendingPayment(){return this.addFilter({status:{$eq:f.PENDING_PAYMENT}})}withStatusIsPaid(){return this.addFilter({status:{$eq:f.PAID}})}withStatusIsShipped(){return this.addFilter({status:{$eq:f.SHIPPED}})}withStatusIsDelivered(){return this.addFilter({status:{$eq:f.DELIVERED}})}withStatusIsCancelled(){return this.addFilter({status:{$eq:f.CANCELLED}})}withCurrencyIs(e){return this.addFilter({currency:{$eq:e}})}withTotalAmountGreaterThanOrEqualTo(e){return this.addFilter({totalAmount:{$gte:e}})}withOrderDateGreaterThanOrEqualTo(e){return this.addFilter({orderDate:{$gte:e}})}withPlatformIdIs(e){return this.addFilter({platformId:{$eq:e}})}withItemListMatching(e){return this.addFilter({id:{$inSubquery:{query:e.toQuery(),field:"orderId"}}})}filterByJson(e){const{query:r,warnings:n}=Te(this.toQuery(),Ke(e),Me,{filter:(o,s)=>o==="status.code"?{status:{$inSubquery:{query:new T("OrderStatus").filter({code:s}),field:"id"}}}:o==="itemList.productName"?{id:{$inSubquery:{query:new T("OrderItem").filter({productName:s}),field:"orderId"}}}:{[o]:s},order:(o,s)=>s==="asc"?R.asc(o):R.desc(o)});return this.dynamicWarnings=n,this.query.filterCondition=r.filterCondition,this.query.orderItems=[...r.orderItems],this.record("filterByJson(searchParams)"),this}warnings(){return this.dynamicWarnings}selectPlatformWith(e){return this.query.relationQuery("platform",e.toQuery(),"platformId","id",!1),this}selectCustomerWith(e){return this.query.relationQuery("customer",e.toQuery(),"customerId","id",!1),this}selectStatusWith(e){return this.query.select(["status"]),this.query.relationQuery("status",e.toQuery(),"status","id",!1,{kind:"relation-select",method:"selectStatusWith",relation:"status"}),this.record(`selectStatusWith(${U(e)})`)}selectItemListWith(e){return this.query.relationQuery("itemList",e.toQuery(),"id","orderId",!0,{kind:"relation-select",method:"selectItemListWith",relation:"itemList"}),this.record(`selectItemListWith(${U(e)})`)}selectPaymentListWith(e){return this.query.relationQuery("paymentList",e.toQuery(),"id","orderId",!0),this}selectShipmentListWith(e){return this.query.relationQuery("shipmentList",e.toQuery(),"id","orderId",!0),this}countItemListAs(e){return this.query.relationAggregate("itemList",e,new T("OrderItem").aggregate("Count","id",e).comment("count items"),!0,{kind:"relation-count",method:"countItemListAs",relation:"itemList",alias:e}),this.record(`countItemListAs(${L(e)})`)}facetByStatusAs(e,r,n=!0){const o=r.toQuery();return o.commentText||o.comment("load status facets"),this.query.facetBy(e,"status",{toQuery:()=>o},n,{kind:"facet",method:"facetByStatusAs",relation:"status",alias:e}),this.record(`facetByStatusAs(${L(e)}, ${U(r)})`)}orderByOrderDateDescending(){return this.order("orderDate","desc"),this.record("orderByOrderDateDescending()")}orderByOrderDateAscending(){return this.order("orderDate","asc")}orderByIdDescending(){return this.order("id","desc"),this.record("orderByIdDescending()")}orderByTotalAmountDescending(){return this.order("totalAmount","desc")}groupByCurrency(){return this.group("currency")}groupByStatus(){return this.group("status")}countAs(e){return this.countAlias=e,this.record(`countAs(${L(e)})`)}sumTotalAmountAs(e){return this.aggregate("Sum","totalAmount",e)}averageTotalAmountAs(e){return this.aggregate("Avg","totalAmount",e)}executeForList(e){return this.applyRowCount(),super.executeForList(e)}executeForRows(e){return this.applyRowCount(),super.executeForList(e)}executeForPage(e,r,n){return this.countAlias&&this.includePageTotalAs(this.countAlias),super.executeForPage(e,r,n)}applyRowCount(){!this.countAlias||this.rowCountApplied||(this.query.aggregate("Count","id",this.countAlias),this.rowCountApplied=!0)}}class u{static platforms(){return new Ue}static customers(){return new Ye}static customerOrders(){return new ue}static customerOrdersWithMinimalFields(){return new ue(!0)}static orderItems(){return new Ge}static orderStatuses(){return new je}static payments(){return new He}static shipments(){return new Ve}}const k=document.querySelector("#status"),B=document.querySelector("#persist"),Y=document.querySelector("#reset"),F=document.querySelector("#query-catalog"),b=document.querySelector("#result"),ge=document.querySelector("#result-title"),fe=document.querySelector("#result-description"),J=document.querySelector("#result-meta"),le=document.querySelector("#query-code"),Ze=document.querySelector("#query-params-block"),Je=document.querySelector("#query-params-code"),Xe=document.querySelector("#result-grid"),$=document.querySelector("#result-view-label"),et=document.querySelector("#sql-count"),me=document.querySelector("#sql-output"),X=document.querySelector("#expand-all"),tt=document.querySelector("#collapse-all"),Q=document.querySelector("#view-table"),H=document.querySelector("#view-tree"),Ae=Array.from(document.querySelectorAll("[data-locale]")),rt={heroTitle:{en:"Understand TeaQL queries through a familiar order model.",zh:"用一个熟悉的订单模型,看懂 TeaQL 查询。"},heroIntro:{en:"Platform, customer, order, item, payment, and shipment data all run in the browser. Order status is backed by a constant model. Choose a query below to inspect real SQLite/WASM results.",zh:"平台、用户、订单、明细、支付和物流数据都在浏览器中运行;订单状态由常数模型提供。选择下面的查询,查看真实的 SQLite/WASM 结果。"},platform:{en:"Platform",zh:"平台"},customer:{en:"Customer",zh:"用户"},order:{en:"Order",zh:"订单"},item:{en:"Item",zh:"明细"},payment:{en:"Payment",zh:"支付"},shipment:{en:"Shipment",zh:"物流"},constantModel:{en:"Constant model",zh:"常数模型"},persist:{en:"Persist locally with OPFS",zh:"使用 OPFS 保存在本地"},reset:{en:"Reset demo data",zh:"重置演示数据"},chooseQuery:{en:"Choose a query",zh:"选择一个查询"},queryIntro:{en:"Queries are grouped by purpose and share the same order dataset.",zh:"查询按用途分组,并共用同一份订单数据。"},table:{en:"Table",zh:"表格"},resultTree:{en:"Result Tree",zh:"结果树"},expandAll:{en:"Expand all",zh:"全部展开"},collapseAll:{en:"Collapse all",zh:"全部折叠"},waiting:{en:"Waiting for query…",zh:"等待查询…"},queryNote:{en:"The Q expression stays fixed; search, status cards, and pagination only update dynamic parameters. The underlying SelectQuery remains inside the generated request implementation.",zh:"Q 表达式保持不变;搜索、状态卡片和分页只更新动态参数。底层 SelectQuery 仍封装在生成的请求实现中。"},executionEvidence:{en:"EXECUTION EVIDENCE",zh:"执行证据"},evidenceTime:{en:"Time",zh:"时间"},identity:{en:"Identity",zh:"身份"},traceChain:{en:"Trace chain",zh:"追踪链"},sqlNote:{en:"One plain-text line per statement: time, identity, trace chain, and the SQL SQLite executed.",zh:"每条语句使用一行纯文本:时间、身份、追踪链,以及 SQLite 实际执行的 SQL。"},localData:{en:"Data stays in this browser",zh:"数据只保留在当前浏览器中"}},nt={基本查询:"Basic queries","从订单、用户和关联对象开始":"Start with orders, customers, and related objects",汇总查询:"Aggregations","分组、计数、求和与平均值":"Grouping, counts, sums, and averages",过滤查询:"Filtered queries","精确、范围与组合条件":"Exact, range, and combined predicates",动态查询:"Dynamic queries","由页面条件安全生成,不使用 eval":"Safely generated from page criteria without eval","综合:订单管理中心":"Comprehensive: Order management center","一个真实的综合查询页面:状态指标、搜索、商品预览和分页都由 TeaQL 查询驱动。":"A real composite query page: status metrics, search, product previews, and pagination are all driven by TeaQL.",最近订单:"Recent orders","按下单日期倒序浏览全部订单,并带出所属平台与用户。":"Browse all orders by date descending, including their platform and customer.",完整订单详情:"Complete order details","查看一个订单及其用户、商品明细、支付和物流,体现完整对象图。":"Inspect one order with its customer, items, payments, and shipments as a complete object graph.",用户与订单数:"Customers with order counts","列出用户,并通过关联汇总显示每位用户的订单数量。":"List customers and show each customer’s order count through a relation aggregate.",订单状态汇总:"Orders by status","按币种与订单状态统计订单数、总额和平均客单价。":"Aggregate order count, gross amount, and average order value by currency and status.",商品销售汇总:"Product sales summary","按商品汇总销量与销售额,找出最受欢迎的订单明细。":"Aggregate units and revenue by product to identify the most popular order items.",支付渠道对账:"Payment reconciliation","按币种、支付渠道和状态汇总笔数与金额。":"Aggregate transaction count and amount by currency, payment provider, and status.",待支付订单:"Orders awaiting payment","筛选尚未完成付款的订单,并带出对应支付记录。":"Find orders that have not completed payment and include their payment records.",国内大额订单:"High-value domestic orders","组合平台与金额条件,找出 TeaQL 商城中金额不低于 500 元的订单。":"Combine platform and amount filters to find TeaQL Store orders worth at least CNY 500.",运输中的包裹:"Active shipments","筛选待揽收和运输中的物流单,并关联订单信息。":"Find shipments that are ready or in transit and include their order information.","动态:已付款国内订单":"Dynamic: paid domestic orders","从动态条件对象生成查询:人民币、金额至少 250,且状态为已付款或已发货。":"Build a query from dynamic criteria: CNY, at least 250, and status PAID or SHIPPED.","动态:九月新订单":"Dynamic: new September orders","运行时传入日期范围与排序方式,查询 9 月 15 日之后的订单。":"Pass a date range and sort order at runtime to find orders after September 15.","动态:字段白名单":"Dynamic: field allowlist","未知字段会被报告并忽略;合法条件仍可安全执行。":"Unknown fields are reported and ignored while valid predicates still execute safely."};let i=localStorage.getItem("teaql-browser-locale")==="zh"?"zh":"en";function st(t){return rt[t]?.[i]??t}function O(t){return i==="en"?nt[t]??t:t}let E,W=window.location.hash.slice(1)||"order-center";window.location.hash||history.replaceState(null,"","#order-center");let w="tree",v,Se=0,ee;const A={search:"",page:0,pageSize:4},Ce=localStorage.getItem("teaql-browser-storage")==="opfs"?"opfs":"memory";B.checked=Ce==="opfs";async function G(t,e){const r=u.customerOrders().filterByJson(e).limit(20).comment("what: execute a validated browser search").purpose("why: demonstrate safe dynamic order discovery"),n=await r.executeForList(t.context);return{request:e,warnings:r.warnings(),data:n}}const ot=Object.fromEntries(Object.entries(f).map(([t,e])=>[e,t]));function te(t){const e=String(t.code??"");return e&&e in f?e:"color"in t?ot[String(t.id??"")]??"":""}function Ie(t){const e=t.trim();if(!e)return{filter:{}};const r=e.toUpperCase(),n=["PENDING_PAYMENT","PAID","SHIPPED","DELIVERED","CANCELLED"].find(o=>o.includes(r));return n?{filter:{"status.code":n}}:/^(TQL-|\d)/i.test(e)?{filter:{orderNumber:{$contains:r}}}:{filter:{"itemList.productName":{$contains:e}}}}async function at(t){const e=Ie(A.search),r=u.customerOrdersWithMinimalFields().filterByJson(e).countAs("totalOrders").facetByStatusAs("statusCounts",u.orderStatuses().selectName().selectColor().countAs("orderCount").sumOrderTotalAmountAs("orderTotalAmount").orderByDisplayOrderAscending().comment("load status facets")).selectOrderNumber().selectOrderDate().selectStatusWith(u.orderStatuses().selectName().selectColor().comment("load status")).selectItemListWith(u.orderItems().selectProductName().selectQuantity().orderByIdAscending().limit(3).comment("load item previews")).countItemListAs("itemCount").orderByOrderDateDescending().orderByIdDescending().comment("load order list").purpose("render order list page"),n=await r.executeForPage(t.context,A.page*A.pageSize,A.pageSize),o=n.data.facet("statusCounts")??[];return{orders:n.data,totalOrders:Number(n.data.aggregations.totalOrders??n.totalCount),filteredOrders:n.totalCount,statusFacets:o.map(s=>({code:te(s),name:String(s.name??""),color:String(s.color??""),orderCount:Number(s.orderCount??0),orderTotalAmount:Number(s.orderTotalAmount??0)})).filter(s=>s.code&&s.name),search:A.search,page:A.page,pageSize:A.pageSize,queryExpression:r.toQExpression("executeForPage(ctx, pageOffset, pageSize);")}}const we=[{label:"基本查询",description:"从订单、用户和关联对象开始",queries:[{id:"order-center",title:"综合:订单管理中心",description:"一个真实的综合查询页面:状态指标、搜索、商品预览和分页都由 TeaQL 查询驱动。",code:"",view:"dashboard",run:at},{id:"recent-orders",title:"最近订单",description:"按下单日期倒序浏览全部订单,并带出所属平台与用户。",code:`await Q.customerOrders() + .selectPlatformWith(Q.platforms().selectName()) + .selectCustomerWith(Q.customers().selectName().selectCity().selectTier()) + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .orderByOrderDateDescending() + .orderByIdDescending() + .limit(8) + .comment('what: list recent commerce orders') + .purpose('why: provide the default order overview') + .executeForList(ctx)`,run:t=>u.customerOrders().selectPlatformWith(u.platforms().selectName()).selectCustomerWith(u.customers().selectName().selectCity().selectTier()).selectStatusWith(u.orderStatuses().selectName().selectColor()).orderByOrderDateDescending().orderByIdDescending().limit(8).comment("what: list recent commerce orders").purpose("why: provide the default order overview").executeForList(t.context)},{id:"order-detail",title:"完整订单详情",description:"查看一个订单及其用户、商品明细、支付和物流,体现完整对象图。",code:`await Q.customerOrders() + .withOrderNumberIs('TQL-2026-1003') + .selectPlatformWith(Q.platforms()) + .selectCustomerWith(Q.customers()) + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectItemListWith(Q.orderItems().orderByIdAscending()) + .selectPaymentListWith(Q.payments().orderByIdAscending()) + .selectShipmentListWith(Q.shipments().orderByIdAscending()) + .limit(1) + .comment('what: load one complete order graph') + .purpose('why: inspect items, payment and fulfillment together') + .executeForList(ctx)`,run:t=>u.customerOrders().withOrderNumberIs("TQL-2026-1003").selectPlatformWith(u.platforms()).selectCustomerWith(u.customers()).selectStatusWith(u.orderStatuses().selectName().selectColor()).selectItemListWith(u.orderItems().orderByIdAscending()).selectPaymentListWith(u.payments().orderByIdAscending()).selectShipmentListWith(u.shipments().orderByIdAscending()).limit(1).comment("what: load one complete order graph").purpose("why: inspect items, payment and fulfillment together").executeForList(t.context)},{id:"customers-with-order-count",title:"用户与订单数",description:"列出用户,并通过关联汇总显示每位用户的订单数量。",code:`await Q.customers() + .selectPlatformWith(Q.platforms().selectName()) + .countOrderListAs('orderCount') + .orderByNameAscending() + .comment('what: list customers with related order counts') + .purpose('why: compare customer activity at a glance') + .executeForList(ctx)`,run:t=>u.customers().selectPlatformWith(u.platforms().selectName()).countOrderListAs("orderCount").orderByNameAscending().comment("what: list customers with related order counts").purpose("why: compare customer activity at a glance").executeForList(t.context)}]},{label:"汇总查询",description:"分组、计数、求和与平均值",queries:[{id:"orders-by-status",title:"订单状态汇总",description:"按币种与订单状态统计订单数、总额和平均客单价。",code:`await Q.customerOrders() + .groupByCurrency().groupByStatus() + .countAs('orderCount') + .sumTotalAmountAs('grossAmount') + .averageTotalAmountAs('averageOrderValue') + .comment('what: aggregate orders by currency and status') + .purpose('why: show the current order funnel') + .executeForRows(ctx)`,run:t=>u.customerOrders().groupByCurrency().groupByStatus().countAs("orderCount").sumTotalAmountAs("grossAmount").averageTotalAmountAs("averageOrderValue").comment("what: aggregate orders by currency and status").purpose("why: show the current order funnel").executeForRows(t.context)},{id:"product-sales",title:"商品销售汇总",description:"按商品汇总销量与销售额,找出最受欢迎的订单明细。",code:`await Q.orderItems() + .groupByProductName() + .sumQuantityAs('units') + .sumLineAmountAs('revenue') + .comment('what: aggregate sold units and line revenue') + .purpose('why: identify the strongest products in the demo data') + .executeForRows(ctx)`,run:t=>u.orderItems().groupByProductName().sumQuantityAs("units").sumLineAmountAs("revenue").comment("what: aggregate sold units and line revenue").purpose("why: identify the strongest products in the demo data").executeForRows(t.context)},{id:"payment-reconciliation",title:"支付渠道对账",description:"按币种、支付渠道和状态汇总笔数与金额。",code:`await Q.payments() + .groupByCurrency().groupByProvider().groupByStatus() + .countAs('paymentCount').sumAmountAs('paymentAmount') + .orderByCurrencyAscending().orderByProviderAscending() + .comment('what: reconcile payment totals by provider') + .purpose('why: compare captured, pending and refunded money') + .executeForRows(ctx)`,run:t=>u.payments().groupByCurrency().groupByProvider().groupByStatus().countAs("paymentCount").sumAmountAs("paymentAmount").orderByCurrencyAscending().orderByProviderAscending().comment("what: reconcile payment totals by provider").purpose("why: compare captured, pending and refunded money").executeForRows(t.context)}]},{label:"过滤查询",description:"精确、范围与组合条件",queries:[{id:"pending-payment",title:"待支付订单",description:"筛选尚未完成付款的订单,并带出对应支付记录。",code:`await Q.customerOrders() + .withStatusIsPendingPayment() + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectCustomerWith(Q.customers().selectName()) + .selectPaymentListWith(Q.payments()) + .comment('what: find orders awaiting payment') + .purpose('why: support payment follow-up') + .executeForList(ctx)`,run:t=>u.customerOrders().withStatusIsPendingPayment().selectStatusWith(u.orderStatuses().selectName().selectColor()).selectCustomerWith(u.customers().selectName()).selectPaymentListWith(u.payments()).comment("what: find orders awaiting payment").purpose("why: support payment follow-up").executeForList(t.context)},{id:"large-cn-orders",title:"国内大额订单",description:"组合平台与金额条件,找出 TeaQL 商城中金额不低于 500 元的订单。",code:`await Q.customerOrders() + .withPlatformIdIs('1') + .withTotalAmountGreaterThanOrEqualTo(500) + .selectCustomerWith(Q.customers().selectName().selectCity()) + .orderByTotalAmountDescending() + .comment('what: find high-value domestic orders') + .purpose('why: prioritize valuable fulfillment work') + .executeForList(ctx)`,run:t=>u.customerOrders().withPlatformIdIs("1").withTotalAmountGreaterThanOrEqualTo(500).selectCustomerWith(u.customers().selectName().selectCity()).orderByTotalAmountDescending().comment("what: find high-value domestic orders").purpose("why: prioritize valuable fulfillment work").executeForList(t.context)},{id:"open-shipments",title:"运输中的包裹",description:"筛选待揽收和运输中的物流单,并关联订单信息。",code:`await Q.shipments() + .withStatusIn('READY', 'IN_TRANSIT') + .selectOrderWith(Q.customerOrders().selectOrderNumber().selectOrderDate().selectStatusWith(Q.orderStatuses().selectName().selectColor()).selectTotalAmount().selectCurrency()) + .orderByStatusAscending().orderByIdAscending() + .comment('what: find shipments that are not delivered') + .purpose('why: monitor active fulfillment') + .executeForList(ctx)`,run:t=>u.shipments().withStatusIn("READY","IN_TRANSIT").selectOrderWith(u.customerOrders().selectOrderNumber().selectOrderDate().selectStatusWith(u.orderStatuses().selectName().selectColor()).selectTotalAmount().selectCurrency()).orderByStatusAscending().orderByIdAscending().comment("what: find shipments that are not delivered").purpose("why: monitor active fulfillment").executeForList(t.context)}]},{label:"动态查询",description:"由页面条件安全生成,不使用 eval",queries:[{id:"dynamic-paid-cn",title:"动态:已付款国内订单",description:"从动态条件对象生成查询:人民币、金额至少 250,且状态为已付款或已发货。",code:`const input = { + "filter": { + "currency": "CNY", + "totalAmount": { "$gte": 250 }, + "status": { "$in": ["PAID", "SHIPPED"] } + }, + "orderBy": [{ "field": "totalAmount", "direction": "desc" }] +}; +const data = await Q.customerOrders() + .filterByJson(input) + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx);`,run:t=>G(t,{filter:{currency:"CNY",totalAmount:{$gte:250},status:{$in:["PAID","SHIPPED"]}},orderBy:[{field:"totalAmount",direction:"desc"}]})},{id:"dynamic-date-range",title:"动态:九月新订单",description:"运行时传入日期范围与排序方式,查询 9 月 15 日之后的订单。",code:`const input = { + "filter": { "orderDate": { "$gte": "2026-09-15" } }, + "orderBy": [{ "field": "orderDate", "direction": "asc" }] +}; +const data = await Q.customerOrders() + .filterByJson(input) + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx);`,run:t=>G(t,{filter:{orderDate:{$gte:"2026-09-15"}},orderBy:[{field:"orderDate",direction:"asc"}]})},{id:"dynamic-safe-fields",title:"动态:字段白名单",description:"未知字段会被报告并忽略;合法条件仍可安全执行。",code:`const input = { + "filter": { + "status": "DELIVERED", + "internalNote": { "$contains": "not queryable" } + } +}; +const request = Q.customerOrders().filterByJson(input); +const data = await request + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx); +const warnings = request.warnings();`,run:t=>G(t,{filter:{status:"DELIVERED",internalNote:{$contains:"not queryable"}}})}]}],pe=we.flatMap(t=>t.queries);async function it(t){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),r=await Qe.open(e,{...ce},{storage:t,databaseName:"teaql-order-playground-v3.sqlite3"}),n=new $e().enableSelect();r.install(new Re(ce,{},{constants:_e})),r.setRuntimeTelemetrySink(n).setDiagnosticSQLLogSink(void 0);const o=Object.freeze({policyId:"browser-order-demo-seed",version:"1",fingerprint:"sha256:browser-order-demo-seed-v1"}),s=new Be().insertResource("dataService",r).withMutationPolicyRegistry(new Fe(()=>({identity:o,review:(d,a)=>a.operations.length>0?{verdict:"allow"}:{verdict:"deny",code:"EMPTY_GRAPH",message:"empty mutation graph"}}))).withMutationPolicyApprovalProvider(new ke(d=>({policy:d,approvedBy:"browser-demo-owner",approvedAt:new Date})));return r.setUserContext(s),await s.ensureSchema(),{client:r,context:s,evidence:n}}async function be(t){if((await u.customerOrders().selectId().limit(1).comment("what: detect existing order playground data").purpose("why: keep deterministic browser bootstrap idempotent").executeForList(t.context)).length)return;const r=new We("Seed deterministic order playground data");await t.client.executeGraphSave(r,async n=>{const o=he.map(s=>n.request({entity:s.entity,action:"Create",id:s.id,payload:s.payload}));for(const s of o)t.client.preflightMutation(s);for(const s of o)await t.client.executeMutation(s)})}function dt(){F.replaceChildren();for(const t of we){const e=document.createElement("section");e.className="query-group";const r=document.createElement("div");r.className="query-group-heading";const n=document.createElement("h2");n.textContent=O(t.label);const o=document.createElement("p");o.textContent=O(t.description),r.append(n,o);const s=document.createElement("div");s.className="query-links";for(const d of t.queries){const a=document.createElement("a");a.href=`#${d.id}`,a.dataset.queryId=d.id,a.textContent=O(d.title),a.addEventListener("click",c=>{c.preventDefault(),W=d.id,history.replaceState(null,"",`#${d.id}`),V(),E&&P(d,E).catch(N)}),s.append(a)}e.append(r,s),F.append(e)}V()}function V(){F.querySelectorAll("a[data-query-id]").forEach(t=>{const e=t.dataset.queryId===W;t.classList.toggle("active",e),e?t.setAttribute("aria-current","page"):t.removeAttribute("aria-current")})}async function P(t,e){const r=performance.now(),n=new Date;e.evidence.enableSelect(),b.classList.add("loading"),b.setAttribute("aria-busy","true"),ge.textContent=O(t.title),fe.textContent=O(t.description),le.textContent=t.code,Ze.classList.toggle("hidden",t.view!=="dashboard"),Je.textContent=t.view==="dashboard"?JSON.stringify({searchParams:Ie(A.search),pageOffset:A.page*A.pageSize,pageSize:A.pageSize},null,2):"",Xe.classList.toggle("dashboard-mode",t.view==="dashboard"),b.classList.toggle("dashboard-result",t.view==="dashboard"),X.closest(".tree-actions")?.classList.toggle("hidden",t.view==="dashboard"),$.textContent=t.view==="dashboard"?i==="en"?"Order management center":"订单管理中心":i==="en"?"Result tree":"结果树",J.textContent=i==="en"?"Running query…":"查询中…";try{const o=await t.run(e);t.view==="dashboard"&&(le.textContent=o.queryExpression),v={data:o,query:t,active:e},w=t.view==="dashboard"||Z(o)?"table":"tree",z();const s=Math.max(1,Math.round(performance.now()-r));Se=s,ee=n;const d=e.evidence.snapshot();Ee(d,n),Pe(o,t,s)}finally{b.classList.remove("loading"),b.removeAttribute("aria-busy")}}function Ee(t,e=ee){me.replaceChildren(),et.textContent=i==="en"?`${t.length} statement${t.length===1?"":"s"}`:`${t.length} 条语句`,t.forEach((r,n)=>{const o=document.createElement("tr");o.className="evidence-row";const s=[...r.tracePath].reverse().find(l=>l.kind==="relation"||l.kind==="request"||l.kind==="entity"),d=document.createElement("td");d.className="evidence-time",d.dataset.executedAt=e?.toISOString()??"",d.textContent=`${e?.toISOString()??"—"} · ${Math.max(.01,r.elapsedMicros/1e3).toFixed(2)} ms`;const a=document.createElement("td");a.textContent=`${v?.query.id??"query"} · #${n+1} · ${s?.name??"query"}`;const c=document.createElement("td");if(c.className="evidence-trace",r.traceChain?.length){const l=r.traceChain.find(g=>g.kind==="purpose"),S=r.traceChain.filter(g=>g.kind==="comment").map(g=>g.detail||g.name);c.textContent=`${l?.detail||l?.name||""}: ${S.join(" → ")}`}else c.textContent=r.tracePath.map(l=>l.detail||l.name).join(" → ");const m=document.createElement("td");m.className="evidence-sql";const h=r.parameters.length?r.parameters.map(l=>String(l)).join(", "):"none";m.textContent=`${r.parameterizedSQL} · bindings: ${h}`,o.append(d,a,c,m),me.append(o)})}function Z(t){return Array.isArray(t)&&t.every(e=>e!==null&&typeof e=="object"&&!Array.isArray(e))}function z(){if(!v)return;const{data:t,query:e,active:r}=v,n=e.view==="dashboard"||Z(t);if(n||(w="tree"),Q.disabled=!n,Q.classList.toggle("active",w==="table"),H.classList.toggle("active",w==="tree"),Q.setAttribute("aria-pressed",String(w==="table")),H.setAttribute("aria-pressed",String(w==="tree")),X.closest(".tree-actions")?.classList.toggle("hidden",w!=="tree"),w==="table"&&e.view==="dashboard"){$.textContent=i==="en"?"Result table":"结果表格",mt(t,r,e);return}if(w==="table"&&Z(t)){$.textContent=i==="en"?"Result table":"结果表格",ut(t);return}$.textContent=i==="en"?"Result tree":"结果树",Le(e.view==="dashboard"?ct(t):t)}function ct(t){return{orders:t.orders,totalOrders:t.totalOrders,filteredOrders:t.filteredOrders,statusFacets:t.statusFacets,search:t.search,page:t.page,pageSize:t.pageSize}}function ut(t){const e=document.createElement("div");if(e.className="result-table-shell",!t.length){const a=document.createElement("p");a.className="result-table-empty",a.textContent=i==="en"?"The query returned no records.":"查询没有返回记录。",e.append(a),b.replaceChildren(e);return}const r=[...new Set(t.flatMap(a=>Object.keys(a)))],n=document.createElement("table");n.className="result-table";const o=document.createElement("thead"),s=document.createElement("tr");for(const a of r){const c=document.createElement("th");c.scope="col",c.textContent=a,s.append(c)}o.append(s);const d=document.createElement("tbody");for(const a of t){const c=document.createElement("tr");for(const m of r){const h=document.createElement("td");h.textContent=lt(a[m]),c.append(h)}d.append(c)}n.append(o,d),e.append(n),b.replaceChildren(e)}function lt(t){if(t==null)return"—";if(Array.isArray(t))return i==="en"?`${t.length} items`:`${t.length} 项`;if(t instanceof Date)return t.toISOString();if(typeof t=="object"){const e=t,r=te(e);if(r)return Ne(r);const n=e.name??e.orderNumber??e.code??e.id;return n===void 0?i==="en"?`${Object.keys(e).length} fields`:`${Object.keys(e).length} 个字段`:String(n)}return String(t)}function mt(t,e,r){const n=document.createElement("div");n.className="order-center";const o=document.createElement("div");o.className="order-center-toolbar";const s=document.createElement("div"),d=document.createElement("h3");d.textContent=i==="en"?"Order Management Center":"订单管理中心";const a=document.createElement("p");a.textContent=i==="en"?"One generated Q expression describes the entire page":"一个生成式 Q 表达式描述整个页面",s.append(d,a);const c=document.createElement("form");c.className="order-search";const m=document.createElement("input");m.type="search",m.placeholder=i==="en"?"Order number, status, or product…":"订单号、状态或商品名称…",m.value=t.search,m.setAttribute("aria-label",i==="en"?"Search orders":"搜索订单");const h=document.createElement("button");h.type="submit",h.className="order-search-submit",h.setAttribute("aria-label",i==="en"?"Run order query":"执行订单查询"),h.title=i==="en"?"Search":"查询";const l=document.createElement("span");l.className="search-icon",l.setAttribute("aria-hidden","true"),h.append(l),c.append(m,h),c.addEventListener("submit",p=>{p.preventDefault(),A.search=m.value.trim(),A.page=0,P(r,e).catch(N)}),o.append(s,c);const S=document.createElement("div");S.className="order-metrics",S.append(ye(i==="en"?"All orders":"全部订单",t.totalOrders,"total","#2B66D9",!t.search,()=>{A.search="",A.page=0,P(r,e).catch(N)}));for(const p of t.statusFacets)S.append(ye(p.name,p.orderCount,p.code.toLowerCase(),p.color,t.search.toUpperCase()===p.code,()=>{A.search=p.code,A.page=0,P(r,e).catch(N)},`${i==="en"?"Total":"总额"} ${pt(p.orderTotalAmount)}`));const g=document.createElement("div");g.className="order-table";const _=document.createElement("div");_.className="order-row order-row-head";const xe=i==="en"?["Order number","Order date","Status","Product details"]:["订单号","订单日期","状态","商品明细"];for(const p of xe){const x=document.createElement("span");x.textContent=p,_.append(x)}if(g.append(_),!t.orders.length){const p=document.createElement("div");p.className="order-empty",p.textContent=i==="en"?"No matching orders. Try an order number, status code, or product name.":"没有匹配的订单,请尝试订单号、状态英文或商品名称。",g.append(p)}for(const p of t.orders)g.append(yt(p));const M=document.createElement("div");M.className="order-center-footer";const ne=document.createElement("p"),se=t.filteredOrders?t.page*t.pageSize+1:0,oe=Math.min(t.filteredOrders,(t.page+1)*t.pageSize);ne.textContent=i==="en"?`Showing ${se}–${oe} of ${t.filteredOrders} orders`:`显示 ${se}–${oe},共 ${t.filteredOrders} 条订单`;const q=document.createElement("div");q.className="pagination";const ae=Math.max(1,Math.ceil(t.filteredOrders/t.pageSize));q.append(j("‹",t.page-1,t.page===0,e,r));for(let p=0;p=ae-1,e,r)),M.append(ne,q),n.append(o,S,g,M),b.replaceChildren(n)}function ye(t,e,r,n,o,s,d){const a=document.createElement("button");a.type="button",a.className=`metric-card metric-${r}`,n&&a.style.setProperty("--metric-color",n),a.classList.toggle("active",o);const c=document.createElement("span");c.textContent=t;const m=document.createElement("strong");if(m.textContent=String(e),a.append(c,m),d){const h=document.createElement("small");h.textContent=d,a.append(h)}return a.addEventListener("click",s),a}function pt(t){return new Intl.NumberFormat(i==="en"?"en-US":"zh-CN",{minimumFractionDigits:2,maximumFractionDigits:2}).format(t)}function yt(t){const e=document.createElement("div");e.className="order-row";const r=t.status??{},n=Array.isArray(t.itemList)?t.itemList:[];[String(t.orderNumber??""),String(t.orderDate??"")].forEach(l=>{const S=document.createElement("span");S.className="order-primary",S.textContent=l,e.append(S)});const s=document.createElement("span"),d=document.createElement("span"),a=te(r);d.className=`status-badge status-${a.toLowerCase()}`,d.textContent=Ne(a)||String(r.name??a);const c=String(r.color??"");c&&(d.style.color=c,d.style.backgroundColor=`${c}18`),s.append(d),e.append(s);const m=document.createElement("span");m.className="product-preview",n.forEach((l,S)=>{const g=document.createElement("span");g.className=`product-thumb product-tone-${S%3}`,g.textContent=String(l.productName??"?").slice(0,1),g.title=`${String(l.productName??"")} × ${String(l.quantity??1)}`,m.append(g)});const h=Number(t.itemCount??n.length)-n.length;if(h>0){const l=document.createElement("small");l.textContent=`+${h}`,m.append(l)}return e.append(m),e}function j(t,e,r,n,o){const s=document.createElement("button");return s.type="button",s.textContent=t,s.disabled=r,s.addEventListener("click",()=>{A.page=e,P(o,n).catch(N)}),s}function Ne(t){return(i==="en"?{PENDING_PAYMENT:"Pending payment",PAID:"Paid",SHIPPED:"Shipped",DELIVERED:"Delivered",CANCELLED:"Cancelled"}:{PENDING_PAYMENT:"待支付",PAID:"已支付",SHIPPED:"运输中",DELIVERED:"已完成",CANCELLED:"已取消"})[t]??t}function Le(t){b.replaceChildren(Oe(t,"result",0))}function Oe(t,e,r){if(t!==null&&typeof t=="object"){const d=Array.isArray(t)?t.map((S,g)=>[String(g),S]):Object.entries(t),a=document.createElement("details");a.className="tree-branch",a.open=r===0;const c=document.createElement("summary"),m=document.createElement("span");m.className="tree-key",m.textContent=e;const h=document.createElement("span");h.className="tree-preview",h.textContent=ht(t,d.length),c.append(m,h),a.append(c);const l=document.createElement("div");l.className="tree-children";for(const[S,g]of d)l.append(Oe(g,Array.isArray(t)?`#${Number(S)+1}`:S,r+1));return a.append(l),a}const n=document.createElement("div");n.className="tree-leaf";const o=document.createElement("span");o.className="tree-key",o.textContent=e;const s=document.createElement("span");return s.className=`tree-value tree-${t===null?"null":typeof t}`,s.textContent=t===null?"null":typeof t=="string"?`“${t}”`:String(t),n.append(o,s),n}function ht(t,e){if(Array.isArray(t))return i==="en"?`${e} items`:`${e} 项`;const r=t,n=r.orderNumber??r.name??r.productName??r.transactionId??r.trackingNumber;return n?String(n):i==="en"?`${e} fields`:`${e} 个字段`}function gt(t){return Array.isArray(t)?t.length:Array.isArray(t?.data)?t.data.length:1}function Pe(t,e,r){const n=e.view==="dashboard"?t.filteredOrders:gt(t),o=i==="en"?`${n} ${e.view==="dashboard"?`matching order${n===1?"":"s"}`:`result${n===1?"":"s"}`}`:`${n} 条${e.view==="dashboard"?"匹配订单":"结果"}`;J.textContent=`${o} · ${r} ms · ${i==="en"?"in-browser SQLite":"浏览器内 SQLite"}`}function De(t){const e=he.filter(r=>r.entity==="CustomerOrder").length;k.textContent=i==="en"?`${t.toUpperCase()} · ${e} orders · 7 entities · policy installed · ready`:`${t.toUpperCase()} · ${e} 个订单 · 7 个实体 · 已安装策略 · 就绪`}function ve(){document.documentElement.lang=i==="en"?"en":"zh-CN",document.title=i==="en"?"TeaQL Order Query Playground":"TeaQL 订单查询演练场";const t=document.querySelector('meta[name="description"]');if(t&&(t.content=i==="en"?"A TeaQL order-query playground running entirely in the browser":"完全运行在浏览器中的 TeaQL 订单查询演练场"),document.querySelectorAll("[data-i18n]").forEach(e=>{const r=e.dataset.i18n;r&&(e.textContent=st(r))}),Ae.forEach(e=>{const r=e.dataset.locale===i;e.classList.toggle("active",r),e.setAttribute("aria-pressed",String(r))}),document.querySelector(".language-switch")?.setAttribute("aria-label",i==="en"?"Language":"语言"),document.querySelector(".brand")?.setAttribute("aria-label",i==="en"?"TeaQL Playground home":"TeaQL 演练场首页"),document.querySelector(".model-map")?.setAttribute("aria-label",i==="en"?"Order domain model":"订单领域模型"),document.querySelector(".runtime-bar")?.setAttribute("aria-label",i==="en"?"Runtime settings":"运行时设置"),F.setAttribute("aria-label",i==="en"?"Example queries":"示例查询"),document.querySelector(".result-view-switch")?.setAttribute("aria-label",i==="en"?"Result views":"结果视图"),document.querySelector(".tree-actions")?.setAttribute("aria-label",i==="en"?"Result tree actions":"结果树操作"),dt(),v){const{data:e,query:r,active:n}=v;ge.textContent=O(r.title),fe.textContent=O(r.description),z(),Ee(n.evidence.snapshot(),ee),Pe(e,r,Se),De(B.checked?"opfs":"memory")}else k.textContent=i==="en"?"Starting SQLite/WASM…":"正在启动 SQLite/WASM…"}function re(){return pe.find(t=>t.id===W)??pe[0]}async function qe(t){k.textContent=i==="en"?`Opening ${t.toUpperCase()} SQLite/WASM…`:`正在打开 ${t.toUpperCase()} SQLite/WASM…`;const e=E;E=void 0,await e?.client.close();const r=await it(t);E=r,await be(r),await P(re(),r),De(t)}B.addEventListener("change",()=>{const t=B.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",t),qe(t).catch(N)});Y.addEventListener("click",async()=>{if(E){Y.disabled=!0;try{await E.client.reset(E.context),await be(E),await P(re(),E)}catch(t){N(t)}finally{Y.disabled=!1}}});X.addEventListener("click",()=>{b.querySelectorAll("details").forEach(t=>{t.open=!0})});Q.addEventListener("click",()=>{Q.disabled||(w="table",z())});H.addEventListener("click",()=>{w="tree",z()});tt.addEventListener("click",()=>{b.querySelectorAll("details").forEach((t,e)=>{t.open=e===0})});Ae.forEach(t=>{t.addEventListener("click",()=>{i=t.dataset.locale==="zh"?"zh":"en",localStorage.setItem("teaql-browser-locale",i),ve()})});function N(t){const e=t instanceof Error?t:new Error(String(t));k.textContent=`${e.name}: ${e.message}`,J.textContent=i==="en"?"Query failed":"查询失败",Le({error:e.name,message:e.message})}ve();W=re().id;V();qe(Ce).catch(N); diff --git a/assets/object-location-xgYMemK6.js b/assets/object-location-xgYMemK6.js new file mode 100644 index 0000000000000000000000000000000000000000..8c8bc4aa545522c7f661771b17aa4cfc4635714b --- /dev/null +++ b/assets/object-location-xgYMemK6.js @@ -0,0 +1 @@ +import{f as u}from"./dynamic-search-BBmdgl4H.js";const i=n=>`${n.entity}\0${typeof n.id}:${String(n.id)}`;class V{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map,this.traces=new Map}setTraceChain(s,e){this.traces.set(i(s),{key:Object.freeze({...s}),nodes:u(e)})}traceChain(s){return this.traces.get(i(s))?.nodes}set(s,e,t){if(!e.trim())throw new TypeError("field is required");const r=i(s),a=this.changes.get(r)??{key:Object.freeze({...s}),values:{}};a.values[e]=t,this.changes.set(r,a)}snapshot(){return[...this.changes.values()].map(s=>({key:Object.freeze({...s.key}),values:Object.freeze({...s.values})}))}change(s){return Object.freeze({...this.changes.get(i(s))?.values??{}})}mergeFrom(s){if(s!==this){for(const e of s.snapshotVersions())this.requireMatchingVersion(e.key,e.version);for(const e of s.snapshot())for(const[t,r]of Object.entries(e.values))this.set(e.key,t,r);for(const e of s.newKeys.values())this.markAsNew(e);for(const e of s.deletedKeys.values())this.markAsDeleted(e);for(const e of s.snapshotVersions())this.setOriginalVersion(e.key,e.version);for(const e of s.traces.values())this.setTraceChain(e.key,e.nodes)}}mergeEntityFrom(s,e){if(s===this)return;const t=s.originalVersion(e);t!==void 0&&this.requireMatchingVersion(e,t);for(const[a,c]of Object.entries(s.change(e)))this.set(e,a,c);s.isNew(e)&&this.markAsNew(e),s.isDeleted(e)&&this.markAsDeleted(e),t!==void 0&&this.setOriginalVersion(e,t);const r=s.traceChain(e);r&&this.setTraceChain(e,r)}hasPending(s){const e=i(s);return this.newKeys.has(e)||this.deletedKeys.has(e)||Object.keys(this.changes.get(e)?.values??{}).length>0}snapshotVersions(){return[...this.originalVersions.values()]}rekey(s,e){const t=i(s),r=i(e);if(t===r)return;const a=this.originalVersion(s);a!==void 0&&this.requireMatchingVersion(e,a);const c=this.changes.get(t);if(c){this.changes.delete(t);for(const[f,g]of Object.entries(c.values))this.set(e,f,g)}const h=this.originalVersions.get(t);h!==void 0&&(this.originalVersions.delete(t),this.originalVersions.set(r,{key:Object.freeze({...e}),version:h.version})),this.newKeys.delete(t)&&this.newKeys.set(r,Object.freeze({...e})),this.deletedKeys.delete(t)&&this.deletedKeys.set(r,Object.freeze({...e}));const l=this.traces.get(t);l&&(this.traces.delete(t),this.setTraceChain(e,l.nodes))}clearEntity(s){const e=i(s);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e),this.traces.delete(e)}requireMatchingVersion(s,e){const t=this.originalVersion(s);if(t!==void 0&&t!==e)throw new Error("ENTITY_VERSION_CONFLICT: one graph cannot contain different loaded versions of the same typed entity")}setOriginalVersion(s,e){this.requireMatchingVersion(s,e),this.originalVersions.set(i(s),{key:Object.freeze({...s}),version:e})}acceptCommittedVersion(s,e){if(this.hasPending(s))throw new Error("ENTITY_COMMIT_PENDING: clear committed changes before accepting the persisted version");this.originalVersions.set(i(s),{key:Object.freeze({...s}),version:e})}originalVersion(s){return this.originalVersions.get(i(s))?.version}markAsNew(s){this.newKeys.set(i(s),Object.freeze({...s}))}isNew(s){return this.newKeys.has(i(s))}markAsDeleted(s){const e=i(s);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...s}))}isDeleted(s){return this.deletedKeys.has(i(s))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear(),this.traces.clear()}}function d(n){const s=n.split("_");return s[0]+s.slice(1).map(e=>e?e[0].toUpperCase()+e.slice(1):"").join("")}function p(n,s){if(s==="snake_case")return n;const e=d(n);return s==="camelCase"||!e?e:e[0].toUpperCase()+e.slice(1)}function m(n){return n.replace(/~/g,"~0").replace(/\//g,"~1")}class o{constructor(s){this.segments=s}static root(){return new o([])}static property(s){return o.root().property(s)}property(s){return new o([...this.segments,{kind:"property",name:s}])}index(s){return new o([...this.segments,{kind:"index",index:s}])}prefixedBy(s){return new o([...s.segments,...this.segments])}modelPath(){return this.render(s=>s)}nativePath(){return this.render(d)}instancePath(s="camelCase"){return this.segments.map(e=>e.kind==="index"?String(e.index):m(p(e.name,s))).map(e=>`/${e}`).join("")}toString(){return this.nativePath()}render(s){let e="";for(const t of this.segments)t.kind==="index"?e+=`[${t.index}]`:e+=`${e?".":""}${s(t.name)}`;return e}}export{V as E,o as O}; diff --git a/assets/orders-CQOGX0kN.js b/assets/orders-CQOGX0kN.js new file mode 100644 index 0000000000000000000000000000000000000000..7d712fbdeea59f2a682869956b591f9018f3c8d5 --- /dev/null +++ b/assets/orders-CQOGX0kN.js @@ -0,0 +1,2 @@ +import{S as yt,a as A,L as v,M as b,C as L,d as G,e as F,Q as z,R as pt,B as ft,U as gt,D as Ot,c as wt,b as qt}from"./dynamic-search-BBmdgl4H.js";import{E as T,O as w}from"./object-location-xgYMemK6.js";/* empty css */class c extends yt{orderBy(t,e){return this.order({field:t,expr:null,direction:e==="desc"?"Desc":"Asc"})}relationQuery(t,e,r="id",i="id",s=!0,h){return super.relationQuery(t,e,r,i,s,h)}}class Q{static teaqlTemporaryId=0;id;platform;name;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--Q.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerOrderList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),t){const r={...t};if(delete r.customerOrderList,Object.assign(this,r),t.platform&&typeof t.platform=="object"&&(this.platform=t.platform instanceof N?t.platform:N.fromRecord(t.platform),this.markLoaded("platform")),Array.isArray(t.customerOrderList)){const i=t.customerOrderList;this._customerOrderList=new A(i.map(s=>s instanceof $?s:$.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("customerOrderList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"Customer",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._customerOrderList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const r=new Q(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new Q({id:String(t)})}static teaqlBootstrapNew(t){return new Q().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const l=[{member:"id",canonical:"id"},{member:"platform",canonical:"platform"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(a=>!this.isLoaded(a.member));if(l)throw new L([{ruleId:"invalid_type",location:w.property(l.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"Customer",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o);const p=o.scopeFor(this.teaqlEntityKey());for(const[l,a]of this._customerOrderList.entries()){a.teaqlAttachRoot(this._root);const u=a.customer;(this.id===void 0||!a.isLoaded("customer")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updateCustomer(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("customer_order_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"Customer",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=p.scopeFor(this.teaqlEntityKey());for(const[g,y]of this._customerOrderList.entries()){y.teaqlAttachRoot(this._root);const O=y.customer;(this.id===void 0||!y.isLoaded("customer")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updateCustomer(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("customer_order_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}return this}const l=await e.executeMutation(p);for(const[f,g]of Object.entries(o.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,g);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update");const C=p.scopeFor(m);for(const[f,g]of this._customerOrderList.entries()){g.teaqlAttachRoot(this._root);const y=g.customer;(this.id===void 0||!g.isLoaded("customer")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updateCustomer(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("customer_order_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,platform:this.platform,name:this.name,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateName(t){return this.name=t,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updatePlatform(t){return this.platform=t?.id??t,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}customerOrderList(){return this._customerOrderList}}class B{static teaqlTemporaryId=0;id;customerOrder;productName;quantity;unitPrice;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--B.teaqlTemporaryId,writable:!0,enumerable:!1}),t){const r={...t};Object.assign(this,r),t.customerOrder&&typeof t.customerOrder=="object"&&(this.customerOrder=t.customerOrder instanceof $?t.customerOrder:$.fromRecord(t.customerOrder),this.markLoaded("customerOrder"))}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"OrderItem",id:this._ledgerId}}teaqlAttachRoot(t){return this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t),this}static fromRecord(t,e){const r=new B(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new B({id:String(t)})}static teaqlBootstrapNew(t){return new B().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const p=[{member:"id",canonical:"id"},{member:"customerOrder",canonical:"customer_order"},{member:"productName",canonical:"product_name"},{member:"quantity",canonical:"quantity"},{member:"unitPrice",canonical:"unit_price"},{member:"version",canonical:"version"}].find(l=>!this.isLoaded(l.member));if(p)throw new L([{ruleId:"invalid_type",location:w.property(p.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"OrderItem",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o),o.scopeFor(this.teaqlEntityKey())}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"OrderItem",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey()))return p.scopeFor(this.teaqlEntityKey()),this;const l=await e.executeMutation(p);for(const[C,f]of Object.entries(o.payload))C!=="id"&&C!=="version"&&this._root.set(this.teaqlEntityKey(),C,f);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();return this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update"),p.scopeFor(m),e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,customer_order:this.customerOrder,product_name:this.productName,quantity:this.quantity,unit_price:this.unitPrice,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateProductName(t){return this.productName=t,this.markLoaded("productName"),this._root.set(this.teaqlEntityKey(),"product_name",t),this}updateQuantity(t){return this.quantity=t,this.markLoaded("quantity"),this._root.set(this.teaqlEntityKey(),"quantity",t),this}updateUnitPrice(t){return this.unitPrice=t,this.markLoaded("unitPrice"),this._root.set(this.teaqlEntityKey(),"unit_price",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updateCustomerOrder(t){return this.customerOrder=t?.id??t,this.markLoaded("customerOrder"),this._root.set(this.teaqlEntityKey(),"customer_order",this.customerOrder),this}}class ${static teaqlTemporaryId=0;id;customer;status;orderNumber;orderDate;totalAmount;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--$.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_orderItemList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),t){const r={...t};if(delete r.orderItemList,Object.assign(this,r),t.customer&&typeof t.customer=="object"&&(this.customer=t.customer instanceof Q?t.customer:Q.fromRecord(t.customer),this.markLoaded("customer")),t.status&&typeof t.status=="object"&&(this.status=t.status instanceof S?t.status:S.fromRecord(t.status),this.markLoaded("status")),Array.isArray(t.orderItemList)){const i=t.orderItemList;this._orderItemList=new A(i.map(s=>s instanceof B?s:B.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("orderItemList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"CustomerOrder",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._orderItemList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const r=new $(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new $({id:String(t)})}static teaqlBootstrapNew(t){return new $().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const l=[{member:"id",canonical:"id"},{member:"customer",canonical:"customer"},{member:"status",canonical:"status"},{member:"orderNumber",canonical:"order_number"},{member:"orderDate",canonical:"order_date"},{member:"totalAmount",canonical:"total_amount"},{member:"version",canonical:"version"}].find(a=>!this.isLoaded(a.member));if(l)throw new L([{ruleId:"invalid_type",location:w.property(l.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"CustomerOrder",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o);const p=o.scopeFor(this.teaqlEntityKey());for(const[l,a]of this._orderItemList.entries()){a.teaqlAttachRoot(this._root);const u=a.customerOrder;(this.id===void 0||!a.isLoaded("customerOrder")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updateCustomerOrder(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("order_item_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"CustomerOrder",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=p.scopeFor(this.teaqlEntityKey());for(const[g,y]of this._orderItemList.entries()){y.teaqlAttachRoot(this._root);const O=y.customerOrder;(this.id===void 0||!y.isLoaded("customerOrder")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updateCustomerOrder(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("order_item_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}return this}const l=await e.executeMutation(p);for(const[f,g]of Object.entries(o.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,g);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update");const C=p.scopeFor(m);for(const[f,g]of this._orderItemList.entries()){g.teaqlAttachRoot(this._root);const y=g.customerOrder;(this.id===void 0||!g.isLoaded("customerOrder")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updateCustomerOrder(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("order_item_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,customer:this.customer,status:this.status,order_number:this.orderNumber,order_date:this.orderDate,total_amount:this.totalAmount,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateOrderNumber(t){return this.orderNumber=t,this.markLoaded("orderNumber"),this._root.set(this.teaqlEntityKey(),"order_number",t),this}updateOrderDate(t){return this.orderDate=t,this.markLoaded("orderDate"),this._root.set(this.teaqlEntityKey(),"order_date",t),this}updateTotalAmount(t){return this.totalAmount=t,this.markLoaded("totalAmount"),this._root.set(this.teaqlEntityKey(),"total_amount",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updateCustomer(t){return this.customer=t?.id??t,this.markLoaded("customer"),this._root.set(this.teaqlEntityKey(),"customer",this.customer),this}updateStatus(t){return this.status=t?.id??t,this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToNew(){return this.status="1001",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToPaid(){return this.status="1002",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToCancelled(){return this.status="1003",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}orderItemList(){return this._orderItemList}}class S{static teaqlTemporaryId=0;platform;id;name;code;color;displayOrder;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--S.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerOrderList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),t){const r={...t};if(delete r.customerOrderList,Object.assign(this,r),t.platform&&typeof t.platform=="object"&&(this.platform=t.platform instanceof N?t.platform:N.fromRecord(t.platform),this.markLoaded("platform")),Array.isArray(t.customerOrderList)){const i=t.customerOrderList;this._customerOrderList=new A(i.map(s=>s instanceof $?s:$.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("customerOrderList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"OrderStatus",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._customerOrderList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const r=new S(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new S({id:String(t)})}static teaqlBootstrapNew(t){return new S().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const l=[{member:"platform",canonical:"platform"},{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"code",canonical:"code"},{member:"color",canonical:"color"},{member:"displayOrder",canonical:"display_order"},{member:"version",canonical:"version"}].find(a=>!this.isLoaded(a.member));if(l)throw new L([{ruleId:"invalid_type",location:w.property(l.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"OrderStatus",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o);const p=o.scopeFor(this.teaqlEntityKey());for(const[l,a]of this._customerOrderList.entries()){a.teaqlAttachRoot(this._root);const u=a.status;(this.id===void 0||!a.isLoaded("status")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updateStatus(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("customer_order_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"OrderStatus",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=p.scopeFor(this.teaqlEntityKey());for(const[g,y]of this._customerOrderList.entries()){y.teaqlAttachRoot(this._root);const O=y.status;(this.id===void 0||!y.isLoaded("status")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updateStatus(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("customer_order_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}return this}const l=await e.executeMutation(p);for(const[f,g]of Object.entries(o.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,g);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update");const C=p.scopeFor(m);for(const[f,g]of this._customerOrderList.entries()){g.teaqlAttachRoot(this._root);const y=g.status;(this.id===void 0||!g.isLoaded("status")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updateStatus(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("customer_order_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{platform:this.platform,id:this.id,name:this.name,code:this.code,color:this.color,display_order:this.displayOrder,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateName(t){return this.name=t,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",t),this}updateCode(t){return this.code=t,this.markLoaded("code"),this._root.set(this.teaqlEntityKey(),"code",t),this}updateColor(t){return this.color=t,this.markLoaded("color"),this._root.set(this.teaqlEntityKey(),"color",t),this}updateDisplayOrder(t){return this.displayOrder=t,this.markLoaded("displayOrder"),this._root.set(this.teaqlEntityKey(),"display_order",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updatePlatform(t){return this.platform=t?.id??t,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}customerOrderList(){return this._customerOrderList}}class N{static teaqlTemporaryId=0;id;name;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--N.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_orderStatusList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),t){const r={...t};if(delete r.orderStatusList,delete r.customerList,Object.assign(this,r),Array.isArray(t.orderStatusList)){const i=t.orderStatusList;this._orderStatusList=new A(i.map(s=>s instanceof S?s:S.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("orderStatusList")}if(Array.isArray(t.customerList)){const i=t.customerList;this._customerList=new A(i.map(s=>s instanceof Q?s:Q.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("customerList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._orderStatusList)e.teaqlAttachRoot(t);for(const e of this._customerList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const r=new N(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new N({id:String(t)})}static teaqlBootstrapNew(t){return new N().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const l=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(a=>!this.isLoaded(a.member));if(l)throw new L([{ruleId:"invalid_type",location:w.property(l.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"Platform",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o);const p=o.scopeFor(this.teaqlEntityKey());for(const[l,a]of this._orderStatusList.entries()){a.teaqlAttachRoot(this._root);const u=a.platform;(this.id===void 0||!a.isLoaded("platform")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updatePlatform(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("order_status_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}for(const[l,a]of this._customerList.entries()){a.teaqlAttachRoot(this._root);const u=a.platform;(this.id===void 0||!a.isLoaded("platform")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updatePlatform(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("customer_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"Platform",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=p.scopeFor(this.teaqlEntityKey());for(const[g,y]of this._orderStatusList.entries()){y.teaqlAttachRoot(this._root);const O=y.platform;(this.id===void 0||!y.isLoaded("platform")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updatePlatform(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("order_status_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}for(const[g,y]of this._customerList.entries()){y.teaqlAttachRoot(this._root);const O=y.platform;(this.id===void 0||!y.isLoaded("platform")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updatePlatform(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("customer_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}return this}const l=await e.executeMutation(p);for(const[f,g]of Object.entries(o.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,g);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update");const C=p.scopeFor(m);for(const[f,g]of this._orderStatusList.entries()){g.teaqlAttachRoot(this._root);const y=g.platform;(this.id===void 0||!g.isLoaded("platform")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updatePlatform(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("order_status_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}for(const[f,g]of this._customerList.entries()){g.teaqlAttachRoot(this._root);const y=g.platform;(this.id===void 0||!g.isLoaded("platform")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updatePlatform(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("customer_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateName(t){return this.name=t,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}orderStatusList(){return this._orderStatusList}customerList(){return this._customerList}}const J=Object.freeze({Platform:Object.freeze({fields:Object.freeze({id:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",name:"name",version:"version"}),relations:Object.freeze({orderStatusList:"OrderStatus",customerList:"Customer"})}),OrderStatus:Object.freeze({fields:Object.freeze({platform:"integer",id:"integer",name:"string",code:"string",color:"string",display_order:"integer",displayOrder:"integer",version:"integer"}),queryFields:Object.freeze({platform:"platform",id:"id",name:"name",code:"code",color:"color",display_order:"displayOrder",displayOrder:"displayOrder",version:"version"}),relations:Object.freeze({platform:"Platform",customerOrderList:"CustomerOrder"})}),Customer:Object.freeze({fields:Object.freeze({id:"integer",platform:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",platform:"platform",name:"name",version:"version"}),relations:Object.freeze({platform:"Platform",customerOrderList:"CustomerOrder"})}),CustomerOrder:Object.freeze({fields:Object.freeze({id:"integer",customer:"integer",status:"integer",order_number:"string",orderNumber:"string",order_date:"date",orderDate:"date",total_amount:"decimal",totalAmount:"decimal",version:"integer"}),queryFields:Object.freeze({id:"id",customer:"customer",status:"status",order_number:"orderNumber",orderNumber:"orderNumber",order_date:"orderDate",orderDate:"orderDate",total_amount:"totalAmount",totalAmount:"totalAmount",version:"version"}),relations:Object.freeze({customer:"Customer",status:"OrderStatus",orderItemList:"OrderItem"})}),OrderItem:Object.freeze({fields:Object.freeze({id:"integer",customer_order:"integer",customerOrder:"integer",product_name:"string",productName:"string",quantity:"integer",unit_price:"decimal",unitPrice:"decimal",version:"integer"}),queryFields:Object.freeze({id:"id",customer_order:"customerOrder",customerOrder:"customerOrder",product_name:"productName",productName:"productName",quantity:"quantity",unit_price:"unitPrice",unitPrice:"unitPrice",version:"version"}),relations:Object.freeze({customer_order:"CustomerOrder",customerOrder:"CustomerOrder"})})});class st{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("Platform"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new vt(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectOrderStatusListWith(t){return this.query.relationQuery("orderStatusList",t.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectOrderStatusListWith",relation:"orderStatusList"}),this}selectCustomerListWith(t){return this.query.relationQuery("customerList",t.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectCustomerListWith",relation:"customerList"}),this}haveOrderStatuses(){return this.withOrderStatusListMatching({toQuery:()=>new c("OrderStatus")})}haveNoOrderStatuses(){return this.withoutOrderStatusListMatching({toQuery:()=>new c("OrderStatus")})}withOrderStatusListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"platform"}}}),this}withoutOrderStatusListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"platform"}}}),this}haveCustomers(){return this.withCustomerListMatching({toQuery:()=>new c("Customer")})}haveNoCustomers(){return this.withoutCustomerListMatching({toQuery:()=>new c("Customer")})}withCustomerListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"platform"}}}),this}withoutCustomerListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"platform"}}}),this}countOrderStatuses(){return this.countOrderStatusesAs("countOrderStatuses")}countOrderStatusesAs(t){const e=new c("OrderStatus").filter({version:{$gte:1}});return this.countOrderStatusesWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countOrderStatusesAs",relation:"orderStatusList",alias:t},this}countOrderStatusesWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"relation-count",method:"countOrderStatusesWith",relation:"orderStatusList",alias:t}),this}minDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.minDisplayOrderOfOrderStatusesAs("minOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}minDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"minDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}maxDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.maxDisplayOrderOfOrderStatusesAs("maxOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}maxDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"maxDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}sumDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.sumDisplayOrderOfOrderStatusesAs("sumOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}sumDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"sumDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}avgDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.avgDisplayOrderOfOrderStatusesAs("avgOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}avgDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"avgDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}standardDeviationDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.standardDeviationDisplayOrderOfOrderStatusesAs("standardDeviationOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}standardDeviationDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"standardDeviationDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs("squareRootOfPopulationStandardDeviationOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}sampleVarianceDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.sampleVarianceDisplayOrderOfOrderStatusesAs("sampleVarianceOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}sampleVarianceDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"sampleVarianceDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}samplePopulationVarianceDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.samplePopulationVarianceDisplayOrderOfOrderStatusesAs("samplePopulationVarianceOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}samplePopulationVarianceDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}countCustomers(){return this.countCustomersAs("countCustomers")}countCustomersAs(t){const e=new c("Customer").filter({version:{$gte:1}});return this.countCustomersWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomersAs",relation:"customerList",alias:t},this}countCustomersWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("customerList",t,r,!0,{kind:"relation-count",method:"countCustomersWith",relation:"customerList",alias:t}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(t){return this.filters.push({name:{$contains:t}}),this}withNameIs(t){return this.filters.push({name:{$eq:t}}),this}withNameIsNot(t){return this.filters.push({name:{$ne:t}}),this}withNameIn(...t){return this.filters.push({name:{$in:t}}),this}withNameNotIn(...t){return this.filters.push({name:{$notIn:t}}),this}withNameGreaterThan(t){return this.filters.push({name:{$gt:t}}),this}withNameGreaterThanOrEqualTo(t){return this.filters.push({name:{$gte:t}}),this}withNameLessThan(t){return this.filters.push({name:{$lt:t}}),this}withNameLessThanOrEqualTo(t){return this.filters.push({name:{$lte:t}}),this}withNameBetween(t,e){return this.filters.push({name:{$between:[t,e]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(t){return this.filters.push({name:{$notContains:t}}),this}withNameStartingWith(t){return this.filters.push({name:{$startsWith:t}}),this}withNameNotStartingWith(t){return this.filters.push({name:{$notStartsWith:t}}),this}withNameEndingWith(t){return this.filters.push({name:{$endsWith:t}}),this}withNameNotEndingWith(t){return this.filters.push({name:{$notEndsWith:t}}),this}withNameSoundingLike(t){return this.filters.push({name:{$soundLike:t}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(t){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof N?o:N.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof N?u:N.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof N?o:N.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class vt{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new N}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class ot{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("OrderStatus"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new It(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["platform","id","name","code","color","displayOrder","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectCode(){return this.query.select(["code"]),this}selectColor(){return this.query.select(["color"]),this}selectDisplayOrder(){return this.query.select(["displayOrder"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(t){return this.query.select(["platform"]),this.query.relationQuery("platform",t.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(t){return this.filters.push({platform:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutPlatformMatching(t){return this.filters.push({platform:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}selectCustomerOrderListWith(t){return this.query.relationQuery("customerOrderList",t.toQuery(),"id","status",!0,{kind:"relation-select",method:"selectCustomerOrderListWith",relation:"customerOrderList"}),this}haveCustomerOrders(){return this.withCustomerOrderListMatching({toQuery:()=>new c("CustomerOrder")})}haveNoCustomerOrders(){return this.withoutCustomerOrderListMatching({toQuery:()=>new c("CustomerOrder")})}withCustomerOrderListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"status"}}}),this}withoutCustomerOrderListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"status"}}}),this}countCustomerOrders(){return this.countCustomerOrdersAs("countCustomerOrders")}countCustomerOrdersAs(t){const e=new c("CustomerOrder").filter({version:{$gte:1}});return this.countCustomerOrdersWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomerOrdersAs",relation:"customerOrderList",alias:t},this}countCustomerOrdersWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"relation-count",method:"countCustomerOrdersWith",relation:"customerOrderList",alias:t}),this}minTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.minTotalAmountOfCustomerOrdersAs("minOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}minTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"minTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}maxTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.maxTotalAmountOfCustomerOrdersAs("maxOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}maxTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"maxTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}sumTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.sumTotalAmountOfCustomerOrdersAs("sumOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}sumTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"sumTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}avgTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.avgTotalAmountOfCustomerOrdersAs("avgOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}avgTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"avgTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}standardDeviationTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.standardDeviationTotalAmountOfCustomerOrdersAs("standardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}standardDeviationTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"standardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs("squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}sampleVarianceTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.sampleVarianceTotalAmountOfCustomerOrdersAs("sampleVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}sampleVarianceTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"sampleVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}samplePopulationVarianceTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs("samplePopulationVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}samplePopulationVarianceTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}filterByPlatform(t){return this.filters.push({platform:{$eq:t}}),this}filterByPlatformIn(...t){return this.filters.push({platform:{$in:t}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(t){return this.filters.push({name:{$contains:t}}),this}withNameIs(t){return this.filters.push({name:{$eq:t}}),this}withNameIsNot(t){return this.filters.push({name:{$ne:t}}),this}withNameIn(...t){return this.filters.push({name:{$in:t}}),this}withNameNotIn(...t){return this.filters.push({name:{$notIn:t}}),this}withNameGreaterThan(t){return this.filters.push({name:{$gt:t}}),this}withNameGreaterThanOrEqualTo(t){return this.filters.push({name:{$gte:t}}),this}withNameLessThan(t){return this.filters.push({name:{$lt:t}}),this}withNameLessThanOrEqualTo(t){return this.filters.push({name:{$lte:t}}),this}withNameBetween(t,e){return this.filters.push({name:{$between:[t,e]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(t){return this.filters.push({name:{$notContains:t}}),this}withNameStartingWith(t){return this.filters.push({name:{$startsWith:t}}),this}withNameNotStartingWith(t){return this.filters.push({name:{$notStartsWith:t}}),this}withNameEndingWith(t){return this.filters.push({name:{$endsWith:t}}),this}withNameNotEndingWith(t){return this.filters.push({name:{$notEndsWith:t}}),this}withNameSoundingLike(t){return this.filters.push({name:{$soundLike:t}}),this}withCodeContaining(t){return this.filters.push({code:{$contains:t}}),this}withCodeIs(t){return this.filters.push({code:{$eq:t}}),this}withCodeIsNot(t){return this.filters.push({code:{$ne:t}}),this}withCodeIn(...t){return this.filters.push({code:{$in:t}}),this}withCodeNotIn(...t){return this.filters.push({code:{$notIn:t}}),this}withCodeGreaterThan(t){return this.filters.push({code:{$gt:t}}),this}withCodeGreaterThanOrEqualTo(t){return this.filters.push({code:{$gte:t}}),this}withCodeLessThan(t){return this.filters.push({code:{$lt:t}}),this}withCodeLessThanOrEqualTo(t){return this.filters.push({code:{$lte:t}}),this}withCodeBetween(t,e){return this.filters.push({code:{$between:[t,e]}}),this}withCodeIsKnown(){return this.filters.push({code:{$isNull:!1}}),this}withCodeIsUnknown(){return this.filters.push({code:{$isNull:!0}}),this}withCodeNotContaining(t){return this.filters.push({code:{$notContains:t}}),this}withCodeStartingWith(t){return this.filters.push({code:{$startsWith:t}}),this}withCodeNotStartingWith(t){return this.filters.push({code:{$notStartsWith:t}}),this}withCodeEndingWith(t){return this.filters.push({code:{$endsWith:t}}),this}withCodeNotEndingWith(t){return this.filters.push({code:{$notEndsWith:t}}),this}withCodeSoundingLike(t){return this.filters.push({code:{$soundLike:t}}),this}withColorContaining(t){return this.filters.push({color:{$contains:t}}),this}withColorIs(t){return this.filters.push({color:{$eq:t}}),this}withColorIsNot(t){return this.filters.push({color:{$ne:t}}),this}withColorIn(...t){return this.filters.push({color:{$in:t}}),this}withColorNotIn(...t){return this.filters.push({color:{$notIn:t}}),this}withColorGreaterThan(t){return this.filters.push({color:{$gt:t}}),this}withColorGreaterThanOrEqualTo(t){return this.filters.push({color:{$gte:t}}),this}withColorLessThan(t){return this.filters.push({color:{$lt:t}}),this}withColorLessThanOrEqualTo(t){return this.filters.push({color:{$lte:t}}),this}withColorBetween(t,e){return this.filters.push({color:{$between:[t,e]}}),this}withColorIsKnown(){return this.filters.push({color:{$isNull:!1}}),this}withColorIsUnknown(){return this.filters.push({color:{$isNull:!0}}),this}withColorNotContaining(t){return this.filters.push({color:{$notContains:t}}),this}withColorStartingWith(t){return this.filters.push({color:{$startsWith:t}}),this}withColorNotStartingWith(t){return this.filters.push({color:{$notStartsWith:t}}),this}withColorEndingWith(t){return this.filters.push({color:{$endsWith:t}}),this}withColorNotEndingWith(t){return this.filters.push({color:{$notEndsWith:t}}),this}withColorSoundingLike(t){return this.filters.push({color:{$soundLike:t}}),this}withDisplayOrderIs(t){return this.filters.push({displayOrder:{$eq:t}}),this}withDisplayOrderIsNot(t){return this.filters.push({displayOrder:{$ne:t}}),this}withDisplayOrderIn(...t){return this.filters.push({displayOrder:{$in:t}}),this}withDisplayOrderNotIn(...t){return this.filters.push({displayOrder:{$notIn:t}}),this}withDisplayOrderGreaterThan(t){return this.filters.push({displayOrder:{$gt:t}}),this}withDisplayOrderGreaterThanOrEqualTo(t){return this.filters.push({displayOrder:{$gte:t}}),this}withDisplayOrderLessThan(t){return this.filters.push({displayOrder:{$lt:t}}),this}withDisplayOrderLessThanOrEqualTo(t){return this.filters.push({displayOrder:{$lte:t}}),this}withDisplayOrderBetween(t,e){return this.filters.push({displayOrder:{$between:[t,e]}}),this}withDisplayOrderIsKnown(){return this.filters.push({displayOrder:{$isNull:!1}}),this}withDisplayOrderIsUnknown(){return this.filters.push({displayOrder:{$isNull:!0}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByCodeAscending(){return this.query.orderBy("code","asc"),this}orderByCodeDescending(){return this.query.orderBy("code","desc"),this}orderByColorAscending(){return this.query.orderBy("color","asc"),this}orderByColorDescending(){return this.query.orderBy("color","desc"),this}orderByDisplayOrderAscending(){return this.query.orderBy("displayOrder","asc"),this}orderByDisplayOrderDescending(){return this.query.orderBy("displayOrder","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}minDisplayOrder(){return this.minDisplayOrderAs("minOfDisplayOrder")}minDisplayOrderAs(t){return this.query.aggregate("min","displayOrder",t),this}maxDisplayOrder(){return this.maxDisplayOrderAs("maxOfDisplayOrder")}maxDisplayOrderAs(t){return this.query.aggregate("max","displayOrder",t),this}sumDisplayOrder(){return this.sumDisplayOrderAs("sumOfDisplayOrder")}sumDisplayOrderAs(t){return this.query.aggregate("sum","displayOrder",t),this}avgDisplayOrder(){return this.avgDisplayOrderAs("avgOfDisplayOrder")}avgDisplayOrderAs(t){return this.query.aggregate("avg","displayOrder",t),this}standardDeviationDisplayOrder(){return this.standardDeviationDisplayOrderAs("standardDeviationOfDisplayOrder")}standardDeviationDisplayOrderAs(t){return this.query.aggregate("stddev","displayOrder",t),this}squareRootOfPopulationStandardDeviationDisplayOrder(){return this.squareRootOfPopulationStandardDeviationDisplayOrderAs("squareRootOfPopulationStandardDeviationOfDisplayOrder")}squareRootOfPopulationStandardDeviationDisplayOrderAs(t){return this.query.aggregate("stddev_pop","displayOrder",t),this}sampleVarianceDisplayOrder(){return this.sampleVarianceDisplayOrderAs("sampleVarianceOfDisplayOrder")}sampleVarianceDisplayOrderAs(t){return this.query.aggregate("var_samp","displayOrder",t),this}samplePopulationVarianceDisplayOrder(){return this.samplePopulationVarianceDisplayOrderAs("samplePopulationVarianceOfDisplayOrder")}samplePopulationVarianceDisplayOrderAs(t){return this.query.aggregate("var_pop","displayOrder",t),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(t){return this.query.groupBy("platform"),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(t){return this.query.groupBy("name"),this}groupByCode(){return this.query.groupBy("code"),this}groupByCodeAs(t){return this.query.groupBy("code"),this}groupByColor(){return this.query.groupBy("color"),this}groupByColorAs(t){return this.query.groupBy("color"),this}groupByDisplayOrder(){return this.query.groupBy("displayOrder"),this}groupByDisplayOrderAs(t){return this.query.groupBy("displayOrder"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByPlatformAs(t,e,r=!0){return this.query.facetBy(t,"platform",e,r,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof S?o:S.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof S?u:S.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof S?o:S.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class It{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new S}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class nt{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("Customer"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new Lt(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","platform","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(t){return this.query.select(["platform"]),this.query.relationQuery("platform",t.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(t){return this.filters.push({platform:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutPlatformMatching(t){return this.filters.push({platform:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}selectCustomerOrderListWith(t){return this.query.relationQuery("customerOrderList",t.toQuery(),"id","customer",!0,{kind:"relation-select",method:"selectCustomerOrderListWith",relation:"customerOrderList"}),this}haveCustomerOrders(){return this.withCustomerOrderListMatching({toQuery:()=>new c("CustomerOrder")})}haveNoCustomerOrders(){return this.withoutCustomerOrderListMatching({toQuery:()=>new c("CustomerOrder")})}withCustomerOrderListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"customer"}}}),this}withoutCustomerOrderListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"customer"}}}),this}countCustomerOrders(){return this.countCustomerOrdersAs("countCustomerOrders")}countCustomerOrdersAs(t){const e=new c("CustomerOrder").filter({version:{$gte:1}});return this.countCustomerOrdersWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomerOrdersAs",relation:"customerOrderList",alias:t},this}countCustomerOrdersWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"relation-count",method:"countCustomerOrdersWith",relation:"customerOrderList",alias:t}),this}minTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.minTotalAmountOfCustomerOrdersAs("minOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}minTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"minTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}maxTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.maxTotalAmountOfCustomerOrdersAs("maxOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}maxTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"maxTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}sumTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.sumTotalAmountOfCustomerOrdersAs("sumOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}sumTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"sumTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}avgTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.avgTotalAmountOfCustomerOrdersAs("avgOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}avgTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"avgTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}standardDeviationTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.standardDeviationTotalAmountOfCustomerOrdersAs("standardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}standardDeviationTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"standardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs("squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}sampleVarianceTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.sampleVarianceTotalAmountOfCustomerOrdersAs("sampleVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}sampleVarianceTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"sampleVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}samplePopulationVarianceTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs("samplePopulationVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}samplePopulationVarianceTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByPlatform(t){return this.filters.push({platform:{$eq:t}}),this}filterByPlatformIn(...t){return this.filters.push({platform:{$in:t}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withNameContaining(t){return this.filters.push({name:{$contains:t}}),this}withNameIs(t){return this.filters.push({name:{$eq:t}}),this}withNameIsNot(t){return this.filters.push({name:{$ne:t}}),this}withNameIn(...t){return this.filters.push({name:{$in:t}}),this}withNameNotIn(...t){return this.filters.push({name:{$notIn:t}}),this}withNameGreaterThan(t){return this.filters.push({name:{$gt:t}}),this}withNameGreaterThanOrEqualTo(t){return this.filters.push({name:{$gte:t}}),this}withNameLessThan(t){return this.filters.push({name:{$lt:t}}),this}withNameLessThanOrEqualTo(t){return this.filters.push({name:{$lte:t}}),this}withNameBetween(t,e){return this.filters.push({name:{$between:[t,e]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(t){return this.filters.push({name:{$notContains:t}}),this}withNameStartingWith(t){return this.filters.push({name:{$startsWith:t}}),this}withNameNotStartingWith(t){return this.filters.push({name:{$notStartsWith:t}}),this}withNameEndingWith(t){return this.filters.push({name:{$endsWith:t}}),this}withNameNotEndingWith(t){return this.filters.push({name:{$notEndsWith:t}}),this}withNameSoundingLike(t){return this.filters.push({name:{$soundLike:t}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(t){return this.query.groupBy("platform"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(t){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByPlatformAs(t,e,r=!0){return this.query.facetBy(t,"platform",e,r,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof Q?o:Q.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof Q?u:Q.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof Q?o:Q.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class Lt{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new Q}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class at{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("CustomerOrder"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new At(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","customer","status","orderNumber","orderDate","totalAmount","version"]),this}selectId(){return this.query.select(["id"]),this}selectOrderNumber(){return this.query.select(["orderNumber"]),this}selectOrderDate(){return this.query.select(["orderDate"]),this}selectTotalAmount(){return this.query.select(["totalAmount"]),this}selectVersion(){return this.query.select(["version"]),this}selectCustomerWith(t){return this.query.select(["customer"]),this.query.relationQuery("customer",t.toQuery(),"customer","id",!1,{kind:"relation-select",method:"selectCustomerWith",relation:"customer"}),this}selectStatusWith(t){return this.query.select(["status"]),this.query.relationQuery("status",t.toQuery(),"status","id",!1,{kind:"relation-select",method:"selectStatusWith",relation:"status"}),this}withCustomerMatching(t){return this.filters.push({customer:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutCustomerMatching(t){return this.filters.push({customer:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}withStatusMatching(t){return this.filters.push({status:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutStatusMatching(t){return this.filters.push({status:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}selectOrderItemListWith(t){return this.query.relationQuery("orderItemList",t.toQuery(),"id","customerOrder",!0,{kind:"relation-select",method:"selectOrderItemListWith",relation:"orderItemList"}),this}haveOrderItems(){return this.withOrderItemListMatching({toQuery:()=>new c("OrderItem")})}haveNoOrderItems(){return this.withoutOrderItemListMatching({toQuery:()=>new c("OrderItem")})}withOrderItemListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"customerOrder"}}}),this}withoutOrderItemListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"customerOrder"}}}),this}countOrderItems(){return this.countOrderItemsAs("countOrderItems")}countOrderItemsAs(t){const e=new c("OrderItem").filter({version:{$gte:1}});return this.countOrderItemsWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countOrderItemsAs",relation:"orderItemList",alias:t},this}countOrderItemsWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"relation-count",method:"countOrderItemsWith",relation:"orderItemList",alias:t}),this}minQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.minQuantityOfOrderItemsAs("minOfQuantityOfOrderItems",{toQuery:()=>t})}minQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"minQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}maxQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.maxQuantityOfOrderItemsAs("maxOfQuantityOfOrderItems",{toQuery:()=>t})}maxQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"maxQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}sumQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.sumQuantityOfOrderItemsAs("sumOfQuantityOfOrderItems",{toQuery:()=>t})}sumQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"sumQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}avgQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.avgQuantityOfOrderItemsAs("avgOfQuantityOfOrderItems",{toQuery:()=>t})}avgQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"avgQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}standardDeviationQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.standardDeviationQuantityOfOrderItemsAs("standardDeviationOfQuantityOfOrderItems",{toQuery:()=>t})}standardDeviationQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"standardDeviationQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}squareRootOfPopulationStandardDeviationQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs("squareRootOfPopulationStandardDeviationOfQuantityOfOrderItems",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}sampleVarianceQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.sampleVarianceQuantityOfOrderItemsAs("sampleVarianceOfQuantityOfOrderItems",{toQuery:()=>t})}sampleVarianceQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"sampleVarianceQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}samplePopulationVarianceQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.samplePopulationVarianceQuantityOfOrderItemsAs("samplePopulationVarianceOfQuantityOfOrderItems",{toQuery:()=>t})}samplePopulationVarianceQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}minUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.minUnitPriceOfOrderItemsAs("minOfUnitPriceOfOrderItems",{toQuery:()=>t})}minUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"minUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}maxUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.maxUnitPriceOfOrderItemsAs("maxOfUnitPriceOfOrderItems",{toQuery:()=>t})}maxUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"maxUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}sumUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.sumUnitPriceOfOrderItemsAs("sumOfUnitPriceOfOrderItems",{toQuery:()=>t})}sumUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"sumUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}avgUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.avgUnitPriceOfOrderItemsAs("avgOfUnitPriceOfOrderItems",{toQuery:()=>t})}avgUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"avgUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}standardDeviationUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.standardDeviationUnitPriceOfOrderItemsAs("standardDeviationOfUnitPriceOfOrderItems",{toQuery:()=>t})}standardDeviationUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"standardDeviationUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}squareRootOfPopulationStandardDeviationUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs("squareRootOfPopulationStandardDeviationOfUnitPriceOfOrderItems",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}sampleVarianceUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.sampleVarianceUnitPriceOfOrderItemsAs("sampleVarianceOfUnitPriceOfOrderItems",{toQuery:()=>t})}sampleVarianceUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"sampleVarianceUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}samplePopulationVarianceUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.samplePopulationVarianceUnitPriceOfOrderItemsAs("samplePopulationVarianceOfUnitPriceOfOrderItems",{toQuery:()=>t})}samplePopulationVarianceUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByCustomer(t){return this.filters.push({customer:{$eq:t}}),this}filterByCustomerIn(...t){return this.filters.push({customer:{$in:t}}),this}withCustomerIsKnown(){return this.filters.push({customer:{$isNull:!1}}),this}withCustomerIsUnknown(){return this.filters.push({customer:{$isNull:!0}}),this}filterByStatus(t){return this.filters.push({status:{$eq:t}}),this}filterByStatusIn(...t){return this.filters.push({status:{$in:t}}),this}withStatusIsKnown(){return this.filters.push({status:{$isNull:!1}}),this}withStatusIsUnknown(){return this.filters.push({status:{$isNull:!0}}),this}withStatusIsNew(){return this.filters.push({status:{$eq:"1001"}}),this}withStatusIsPaid(){return this.filters.push({status:{$eq:"1002"}}),this}withStatusIsCancelled(){return this.filters.push({status:{$eq:"1003"}}),this}withOrderNumberContaining(t){return this.filters.push({orderNumber:{$contains:t}}),this}withOrderNumberIs(t){return this.filters.push({orderNumber:{$eq:t}}),this}withOrderNumberIsNot(t){return this.filters.push({orderNumber:{$ne:t}}),this}withOrderNumberIn(...t){return this.filters.push({orderNumber:{$in:t}}),this}withOrderNumberNotIn(...t){return this.filters.push({orderNumber:{$notIn:t}}),this}withOrderNumberGreaterThan(t){return this.filters.push({orderNumber:{$gt:t}}),this}withOrderNumberGreaterThanOrEqualTo(t){return this.filters.push({orderNumber:{$gte:t}}),this}withOrderNumberLessThan(t){return this.filters.push({orderNumber:{$lt:t}}),this}withOrderNumberLessThanOrEqualTo(t){return this.filters.push({orderNumber:{$lte:t}}),this}withOrderNumberBetween(t,e){return this.filters.push({orderNumber:{$between:[t,e]}}),this}withOrderNumberIsKnown(){return this.filters.push({orderNumber:{$isNull:!1}}),this}withOrderNumberIsUnknown(){return this.filters.push({orderNumber:{$isNull:!0}}),this}withOrderNumberNotContaining(t){return this.filters.push({orderNumber:{$notContains:t}}),this}withOrderNumberStartingWith(t){return this.filters.push({orderNumber:{$startsWith:t}}),this}withOrderNumberNotStartingWith(t){return this.filters.push({orderNumber:{$notStartsWith:t}}),this}withOrderNumberEndingWith(t){return this.filters.push({orderNumber:{$endsWith:t}}),this}withOrderNumberNotEndingWith(t){return this.filters.push({orderNumber:{$notEndsWith:t}}),this}withOrderNumberSoundingLike(t){return this.filters.push({orderNumber:{$soundLike:t}}),this}withOrderDateIs(t){return this.filters.push({orderDate:{$eq:t}}),this}withOrderDateIsNot(t){return this.filters.push({orderDate:{$ne:t}}),this}withOrderDateIn(...t){return this.filters.push({orderDate:{$in:t}}),this}withOrderDateNotIn(...t){return this.filters.push({orderDate:{$notIn:t}}),this}withOrderDateGreaterThan(t){return this.filters.push({orderDate:{$gt:t}}),this}withOrderDateGreaterThanOrEqualTo(t){return this.filters.push({orderDate:{$gte:t}}),this}withOrderDateLessThan(t){return this.filters.push({orderDate:{$lt:t}}),this}withOrderDateLessThanOrEqualTo(t){return this.filters.push({orderDate:{$lte:t}}),this}withOrderDateBetween(t,e){return this.filters.push({orderDate:{$between:[t,e]}}),this}withOrderDateIsKnown(){return this.filters.push({orderDate:{$isNull:!1}}),this}withOrderDateIsUnknown(){return this.filters.push({orderDate:{$isNull:!0}}),this}withTotalAmountIs(t){return this.filters.push({totalAmount:{$eq:t}}),this}withTotalAmountIsNot(t){return this.filters.push({totalAmount:{$ne:t}}),this}withTotalAmountIn(...t){return this.filters.push({totalAmount:{$in:t}}),this}withTotalAmountNotIn(...t){return this.filters.push({totalAmount:{$notIn:t}}),this}withTotalAmountGreaterThan(t){return this.filters.push({totalAmount:{$gt:t}}),this}withTotalAmountGreaterThanOrEqualTo(t){return this.filters.push({totalAmount:{$gte:t}}),this}withTotalAmountLessThan(t){return this.filters.push({totalAmount:{$lt:t}}),this}withTotalAmountLessThanOrEqualTo(t){return this.filters.push({totalAmount:{$lte:t}}),this}withTotalAmountBetween(t,e){return this.filters.push({totalAmount:{$between:[t,e]}}),this}withTotalAmountIsKnown(){return this.filters.push({totalAmount:{$isNull:!1}}),this}withTotalAmountIsUnknown(){return this.filters.push({totalAmount:{$isNull:!0}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByOrderNumberAscending(){return this.query.orderBy("orderNumber","asc"),this}orderByOrderNumberDescending(){return this.query.orderBy("orderNumber","desc"),this}orderByOrderDateAscending(){return this.query.orderBy("orderDate","asc"),this}orderByOrderDateDescending(){return this.query.orderBy("orderDate","desc"),this}orderByTotalAmountAscending(){return this.query.orderBy("totalAmount","asc"),this}orderByTotalAmountDescending(){return this.query.orderBy("totalAmount","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}minTotalAmount(){return this.minTotalAmountAs("minOfTotalAmount")}minTotalAmountAs(t){return this.query.aggregate("min","totalAmount",t),this}maxTotalAmount(){return this.maxTotalAmountAs("maxOfTotalAmount")}maxTotalAmountAs(t){return this.query.aggregate("max","totalAmount",t),this}sumTotalAmount(){return this.sumTotalAmountAs("sumOfTotalAmount")}sumTotalAmountAs(t){return this.query.aggregate("sum","totalAmount",t),this}avgTotalAmount(){return this.avgTotalAmountAs("avgOfTotalAmount")}avgTotalAmountAs(t){return this.query.aggregate("avg","totalAmount",t),this}standardDeviationTotalAmount(){return this.standardDeviationTotalAmountAs("standardDeviationOfTotalAmount")}standardDeviationTotalAmountAs(t){return this.query.aggregate("stddev","totalAmount",t),this}squareRootOfPopulationStandardDeviationTotalAmount(){return this.squareRootOfPopulationStandardDeviationTotalAmountAs("squareRootOfPopulationStandardDeviationOfTotalAmount")}squareRootOfPopulationStandardDeviationTotalAmountAs(t){return this.query.aggregate("stddev_pop","totalAmount",t),this}sampleVarianceTotalAmount(){return this.sampleVarianceTotalAmountAs("sampleVarianceOfTotalAmount")}sampleVarianceTotalAmountAs(t){return this.query.aggregate("var_samp","totalAmount",t),this}samplePopulationVarianceTotalAmount(){return this.samplePopulationVarianceTotalAmountAs("samplePopulationVarianceOfTotalAmount")}samplePopulationVarianceTotalAmountAs(t){return this.query.aggregate("var_pop","totalAmount",t),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByCustomer(){return this.query.groupBy("customer"),this}groupByCustomerAs(t){return this.query.groupBy("customer"),this}groupByStatus(){return this.query.groupBy("status"),this}groupByStatusAs(t){return this.query.groupBy("status"),this}groupByOrderNumber(){return this.query.groupBy("orderNumber"),this}groupByOrderNumberAs(t){return this.query.groupBy("orderNumber"),this}groupByOrderDate(){return this.query.groupBy("orderDate"),this}groupByOrderDateAs(t){return this.query.groupBy("orderDate"),this}groupByTotalAmount(){return this.query.groupBy("totalAmount"),this}groupByTotalAmountAs(t){return this.query.groupBy("totalAmount"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByCustomerAs(t,e,r=!0){return this.query.facetBy(t,"customer",e,r,{kind:"facet",method:"facetByCustomerAs",relation:"customer",alias:t}),this}facetByStatusAs(t,e,r=!0){return this.query.facetBy(t,"status",e,r,{kind:"facet",method:"facetByStatusAs",relation:"status",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof $?o:$.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof $?u:$.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof $?o:$.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class At{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new $}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class ut{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("OrderItem"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new _t(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","customerOrder","productName","quantity","unitPrice","version"]),this}selectId(){return this.query.select(["id"]),this}selectProductName(){return this.query.select(["productName"]),this}selectQuantity(){return this.query.select(["quantity"]),this}selectUnitPrice(){return this.query.select(["unitPrice"]),this}selectVersion(){return this.query.select(["version"]),this}selectCustomerOrderWith(t){return this.query.select(["customerOrder"]),this.query.relationQuery("customerOrder",t.toQuery(),"customerOrder","id",!1,{kind:"relation-select",method:"selectCustomerOrderWith",relation:"customerOrder"}),this}withCustomerOrderMatching(t){return this.filters.push({customerOrder:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutCustomerOrderMatching(t){return this.filters.push({customerOrder:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByCustomerOrder(t){return this.filters.push({customerOrder:{$eq:t}}),this}filterByCustomerOrderIn(...t){return this.filters.push({customerOrder:{$in:t}}),this}withCustomerOrderIsKnown(){return this.filters.push({customerOrder:{$isNull:!1}}),this}withCustomerOrderIsUnknown(){return this.filters.push({customerOrder:{$isNull:!0}}),this}withProductNameContaining(t){return this.filters.push({productName:{$contains:t}}),this}withProductNameIs(t){return this.filters.push({productName:{$eq:t}}),this}withProductNameIsNot(t){return this.filters.push({productName:{$ne:t}}),this}withProductNameIn(...t){return this.filters.push({productName:{$in:t}}),this}withProductNameNotIn(...t){return this.filters.push({productName:{$notIn:t}}),this}withProductNameGreaterThan(t){return this.filters.push({productName:{$gt:t}}),this}withProductNameGreaterThanOrEqualTo(t){return this.filters.push({productName:{$gte:t}}),this}withProductNameLessThan(t){return this.filters.push({productName:{$lt:t}}),this}withProductNameLessThanOrEqualTo(t){return this.filters.push({productName:{$lte:t}}),this}withProductNameBetween(t,e){return this.filters.push({productName:{$between:[t,e]}}),this}withProductNameIsKnown(){return this.filters.push({productName:{$isNull:!1}}),this}withProductNameIsUnknown(){return this.filters.push({productName:{$isNull:!0}}),this}withProductNameNotContaining(t){return this.filters.push({productName:{$notContains:t}}),this}withProductNameStartingWith(t){return this.filters.push({productName:{$startsWith:t}}),this}withProductNameNotStartingWith(t){return this.filters.push({productName:{$notStartsWith:t}}),this}withProductNameEndingWith(t){return this.filters.push({productName:{$endsWith:t}}),this}withProductNameNotEndingWith(t){return this.filters.push({productName:{$notEndsWith:t}}),this}withProductNameSoundingLike(t){return this.filters.push({productName:{$soundLike:t}}),this}withQuantityIs(t){return this.filters.push({quantity:{$eq:t}}),this}withQuantityIsNot(t){return this.filters.push({quantity:{$ne:t}}),this}withQuantityIn(...t){return this.filters.push({quantity:{$in:t}}),this}withQuantityNotIn(...t){return this.filters.push({quantity:{$notIn:t}}),this}withQuantityGreaterThan(t){return this.filters.push({quantity:{$gt:t}}),this}withQuantityGreaterThanOrEqualTo(t){return this.filters.push({quantity:{$gte:t}}),this}withQuantityLessThan(t){return this.filters.push({quantity:{$lt:t}}),this}withQuantityLessThanOrEqualTo(t){return this.filters.push({quantity:{$lte:t}}),this}withQuantityBetween(t,e){return this.filters.push({quantity:{$between:[t,e]}}),this}withQuantityIsKnown(){return this.filters.push({quantity:{$isNull:!1}}),this}withQuantityIsUnknown(){return this.filters.push({quantity:{$isNull:!0}}),this}withUnitPriceIs(t){return this.filters.push({unitPrice:{$eq:t}}),this}withUnitPriceIsNot(t){return this.filters.push({unitPrice:{$ne:t}}),this}withUnitPriceIn(...t){return this.filters.push({unitPrice:{$in:t}}),this}withUnitPriceNotIn(...t){return this.filters.push({unitPrice:{$notIn:t}}),this}withUnitPriceGreaterThan(t){return this.filters.push({unitPrice:{$gt:t}}),this}withUnitPriceGreaterThanOrEqualTo(t){return this.filters.push({unitPrice:{$gte:t}}),this}withUnitPriceLessThan(t){return this.filters.push({unitPrice:{$lt:t}}),this}withUnitPriceLessThanOrEqualTo(t){return this.filters.push({unitPrice:{$lte:t}}),this}withUnitPriceBetween(t,e){return this.filters.push({unitPrice:{$between:[t,e]}}),this}withUnitPriceIsKnown(){return this.filters.push({unitPrice:{$isNull:!1}}),this}withUnitPriceIsUnknown(){return this.filters.push({unitPrice:{$isNull:!0}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByProductNameAscending(){return this.query.orderBy("productName","asc"),this}orderByProductNameDescending(){return this.query.orderBy("productName","desc"),this}orderByQuantityAscending(){return this.query.orderBy("quantity","asc"),this}orderByQuantityDescending(){return this.query.orderBy("quantity","desc"),this}orderByUnitPriceAscending(){return this.query.orderBy("unitPrice","asc"),this}orderByUnitPriceDescending(){return this.query.orderBy("unitPrice","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}minQuantity(){return this.minQuantityAs("minOfQuantity")}minQuantityAs(t){return this.query.aggregate("min","quantity",t),this}maxQuantity(){return this.maxQuantityAs("maxOfQuantity")}maxQuantityAs(t){return this.query.aggregate("max","quantity",t),this}sumQuantity(){return this.sumQuantityAs("sumOfQuantity")}sumQuantityAs(t){return this.query.aggregate("sum","quantity",t),this}avgQuantity(){return this.avgQuantityAs("avgOfQuantity")}avgQuantityAs(t){return this.query.aggregate("avg","quantity",t),this}standardDeviationQuantity(){return this.standardDeviationQuantityAs("standardDeviationOfQuantity")}standardDeviationQuantityAs(t){return this.query.aggregate("stddev","quantity",t),this}squareRootOfPopulationStandardDeviationQuantity(){return this.squareRootOfPopulationStandardDeviationQuantityAs("squareRootOfPopulationStandardDeviationOfQuantity")}squareRootOfPopulationStandardDeviationQuantityAs(t){return this.query.aggregate("stddev_pop","quantity",t),this}sampleVarianceQuantity(){return this.sampleVarianceQuantityAs("sampleVarianceOfQuantity")}sampleVarianceQuantityAs(t){return this.query.aggregate("var_samp","quantity",t),this}samplePopulationVarianceQuantity(){return this.samplePopulationVarianceQuantityAs("samplePopulationVarianceOfQuantity")}samplePopulationVarianceQuantityAs(t){return this.query.aggregate("var_pop","quantity",t),this}minUnitPrice(){return this.minUnitPriceAs("minOfUnitPrice")}minUnitPriceAs(t){return this.query.aggregate("min","unitPrice",t),this}maxUnitPrice(){return this.maxUnitPriceAs("maxOfUnitPrice")}maxUnitPriceAs(t){return this.query.aggregate("max","unitPrice",t),this}sumUnitPrice(){return this.sumUnitPriceAs("sumOfUnitPrice")}sumUnitPriceAs(t){return this.query.aggregate("sum","unitPrice",t),this}avgUnitPrice(){return this.avgUnitPriceAs("avgOfUnitPrice")}avgUnitPriceAs(t){return this.query.aggregate("avg","unitPrice",t),this}standardDeviationUnitPrice(){return this.standardDeviationUnitPriceAs("standardDeviationOfUnitPrice")}standardDeviationUnitPriceAs(t){return this.query.aggregate("stddev","unitPrice",t),this}squareRootOfPopulationStandardDeviationUnitPrice(){return this.squareRootOfPopulationStandardDeviationUnitPriceAs("squareRootOfPopulationStandardDeviationOfUnitPrice")}squareRootOfPopulationStandardDeviationUnitPriceAs(t){return this.query.aggregate("stddev_pop","unitPrice",t),this}sampleVarianceUnitPrice(){return this.sampleVarianceUnitPriceAs("sampleVarianceOfUnitPrice")}sampleVarianceUnitPriceAs(t){return this.query.aggregate("var_samp","unitPrice",t),this}samplePopulationVarianceUnitPrice(){return this.samplePopulationVarianceUnitPriceAs("samplePopulationVarianceOfUnitPrice")}samplePopulationVarianceUnitPriceAs(t){return this.query.aggregate("var_pop","unitPrice",t),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByCustomerOrder(){return this.query.groupBy("customerOrder"),this}groupByCustomerOrderAs(t){return this.query.groupBy("customerOrder"),this}groupByProductName(){return this.query.groupBy("productName"),this}groupByProductNameAs(t){return this.query.groupBy("productName"),this}groupByQuantity(){return this.query.groupBy("quantity"),this}groupByQuantityAs(t){return this.query.groupBy("quantity"),this}groupByUnitPrice(){return this.query.groupBy("unitPrice"),this}groupByUnitPriceAs(t){return this.query.groupBy("unitPrice"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByCustomerOrderAs(t,e,r=!0){return this.query.facetBy(t,"customerOrder",e,r,{kind:"facet",method:"facetByCustomerOrderAs",relation:"customerOrder",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof B?o:B.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof B?u:B.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof B?o:B.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class _t{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new B}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class E{static platforms(){return new st(!1)}static platformsWithMinimalFields(){return new st(!0)}static orderStatuses(){return new ot(!1)}static orderStatusesWithMinimalFields(){return new ot(!0)}static customers(){return new nt(!1)}static customersWithMinimalFields(){return new nt(!0)}static customerOrders(){return new at(!1)}static customerOrdersWithMinimalFields(){return new at(!0)}static orderItems(){return new ut(!1)}static orderItemsWithMinimalFields(){return new ut(!0)}}class I extends Error{constructor(t,e,r){const i=`select${r.charAt(0).toUpperCase()}${r.slice(1)}(...)`,s={error:"TeaQLNotLoadedError",root:t,accessPath:e.split("."),breakPoint:r,missingPreload:[r],suggestedFix:i,severity:"error",humanMessage:`访问 ${t}.${e} 时缺少预加载。请在查询中加入 ${i}`};super(JSON.stringify(s)),this.root=t,this.accessPath=e,this.breakPoint=r,this.name="TeaQLNotLoadedError",this.details=s}root;accessPath;breakPoint;details}function q(d,t){return d?`${d}.${t}`:t}class n{constructor(t,e=!0,r){this.value=t,this.present=e,this.notLoaded=r}value;present;notLoaded;static missing(){return new n(void 0,!1)}static notLoaded(t){return new n(void 0,!1,t)}eval(){if(this.notLoaded)throw this.notLoaded;return this.present?this.value:void 0}isPresent(){if(this.notLoaded)throw this.notLoaded;return this.present}orElse(t){const e=this.eval();return this.present&&e!=null?e:t}}class x{constructor(t,e="Platform(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}name(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"name");return this.value.isLoaded("name")?new n(this.value.name):n.notLoaded(new I(this.root,t,"name"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}orderStatusList(){const t=q(this.path,"orderStatusList");return this.notLoaded?new U([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("orderStatusList")?new U(this.value.orderStatusList(),this.root,t):new U([],this.root,t,!1,new I(this.root,t,"orderStatusList")):U.missing(this.root,t)}customerList(){const t=q(this.path,"customerList");return this.notLoaded?new M([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("customerList")?new M(this.value.customerList(),this.root,t):new M([],this.root,t,!1,new I(this.root,t,"customerList")):M.missing(this.root,t)}}class V{constructor(t,e="OrderStatus(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}name(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"name");return this.value.isLoaded("name")?new n(this.value.name):n.notLoaded(new I(this.root,t,"name"))}code(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"code");return this.value.isLoaded("code")?new n(this.value.code):n.notLoaded(new I(this.root,t,"code"))}color(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"color");return this.value.isLoaded("color")?new n(this.value.color):n.notLoaded(new I(this.root,t,"color"))}displayOrder(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"displayOrder");return this.value.isLoaded("displayOrder")?new n(this.value.displayOrder):n.notLoaded(new I(this.root,t,"displayOrder"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}platformId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"platform");if(!this.value.isLoaded("platform"))return n.notLoaded(new I(this.root,t,"platform"));const e=this.value.platform;return new n(e instanceof N?e.id:e)}platform(){const t=q(this.path,"platform");if(this.notLoaded)return new x(void 0,this.root,t,this.notLoaded);if(!this.value)return new x(void 0,this.root,t);if(!this.value.isLoaded("platform"))return new x(void 0,this.root,t,new I(this.root,t,"platform"));const e=this.value.platform,r=e==null?void 0:e instanceof N?e:N.fromRecord({id:e});return new x(r,this.root,t)}customerOrderList(){const t=q(this.path,"customerOrderList");return this.notLoaded?new k([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("customerOrderList")?new k(this.value.customerOrderList(),this.root,t):new k([],this.root,t,!1,new I(this.root,t,"customerOrderList")):k.missing(this.root,t)}}class W{constructor(t,e="Customer(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}name(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"name");return this.value.isLoaded("name")?new n(this.value.name):n.notLoaded(new I(this.root,t,"name"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}platformId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"platform");if(!this.value.isLoaded("platform"))return n.notLoaded(new I(this.root,t,"platform"));const e=this.value.platform;return new n(e instanceof N?e.id:e)}platform(){const t=q(this.path,"platform");if(this.notLoaded)return new x(void 0,this.root,t,this.notLoaded);if(!this.value)return new x(void 0,this.root,t);if(!this.value.isLoaded("platform"))return new x(void 0,this.root,t,new I(this.root,t,"platform"));const e=this.value.platform,r=e==null?void 0:e instanceof N?e:N.fromRecord({id:e});return new x(r,this.root,t)}customerOrderList(){const t=q(this.path,"customerOrderList");return this.notLoaded?new k([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("customerOrderList")?new k(this.value.customerOrderList(),this.root,t):new k([],this.root,t,!1,new I(this.root,t,"customerOrderList")):k.missing(this.root,t)}}class K{constructor(t,e="CustomerOrder(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}orderNumber(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"orderNumber");return this.value.isLoaded("orderNumber")?new n(this.value.orderNumber):n.notLoaded(new I(this.root,t,"orderNumber"))}orderDate(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"orderDate");return this.value.isLoaded("orderDate")?new n(this.value.orderDate):n.notLoaded(new I(this.root,t,"orderDate"))}totalAmount(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"totalAmount");return this.value.isLoaded("totalAmount")?new n(this.value.totalAmount):n.notLoaded(new I(this.root,t,"totalAmount"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}customerId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"customer");if(!this.value.isLoaded("customer"))return n.notLoaded(new I(this.root,t,"customer"));const e=this.value.customer;return new n(e instanceof Q?e.id:e)}statusId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"status");if(!this.value.isLoaded("status"))return n.notLoaded(new I(this.root,t,"status"));const e=this.value.status;return new n(e instanceof S?e.id:e)}customer(){const t=q(this.path,"customer");if(this.notLoaded)return new W(void 0,this.root,t,this.notLoaded);if(!this.value)return new W(void 0,this.root,t);if(!this.value.isLoaded("customer"))return new W(void 0,this.root,t,new I(this.root,t,"customer"));const e=this.value.customer,r=e==null?void 0:e instanceof Q?e:Q.fromRecord({id:e});return new W(r,this.root,t)}status(){const t=q(this.path,"status");if(this.notLoaded)return new V(void 0,this.root,t,this.notLoaded);if(!this.value)return new V(void 0,this.root,t);if(!this.value.isLoaded("status"))return new V(void 0,this.root,t,new I(this.root,t,"status"));const e=this.value.status,r=e==null?void 0:e instanceof S?e:S.fromRecord({id:e});return new V(r,this.root,t)}orderItemList(){const t=q(this.path,"orderItemList");return this.notLoaded?new j([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("orderItemList")?new j(this.value.orderItemList(),this.root,t):new j([],this.root,t,!1,new I(this.root,t,"orderItemList")):j.missing(this.root,t)}}class H{constructor(t,e="OrderItem(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}productName(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"productName");return this.value.isLoaded("productName")?new n(this.value.productName):n.notLoaded(new I(this.root,t,"productName"))}quantity(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"quantity");return this.value.isLoaded("quantity")?new n(this.value.quantity):n.notLoaded(new I(this.root,t,"quantity"))}unitPrice(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"unitPrice");return this.value.isLoaded("unitPrice")?new n(this.value.unitPrice):n.notLoaded(new I(this.root,t,"unitPrice"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}customerOrderId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"customerOrder");if(!this.value.isLoaded("customerOrder"))return n.notLoaded(new I(this.root,t,"customerOrder"));const e=this.value.customerOrder;return new n(e instanceof $?e.id:e)}customerOrder(){const t=q(this.path,"customerOrder");if(this.notLoaded)return new K(void 0,this.root,t,this.notLoaded);if(!this.value)return new K(void 0,this.root,t);if(!this.value.isLoaded("customerOrder"))return new K(void 0,this.root,t,new I(this.root,t,"customerOrder"));const e=this.value.customerOrder,r=e==null?void 0:e instanceof $?e:$.fromRecord({id:e});return new K(r,this.root,t)}}class U{constructor(t,e="OrderStatus(null)",r="",i=!0,s){this.items=t,this.root=e,this.path=r,this.present=i,this.notLoaded=s}items;root;path;present;notLoaded;static missing(t,e=""){return new U([],t,e,!1)}size(){return this.notLoaded?n.notLoaded(this.notLoaded):this.present?new n(this.items.length):n.missing()}first(){return this.get(0)}get(t){const e=q(this.path,`get(${t})`);return this.notLoaded?new V(void 0,this.root,e,this.notLoaded):!this.present||t<0||t>=this.items.length?new V(void 0,this.root,e):new V(this.items[t],this.root,e)}}class M{constructor(t,e="Customer(null)",r="",i=!0,s){this.items=t,this.root=e,this.path=r,this.present=i,this.notLoaded=s}items;root;path;present;notLoaded;static missing(t,e=""){return new M([],t,e,!1)}size(){return this.notLoaded?n.notLoaded(this.notLoaded):this.present?new n(this.items.length):n.missing()}first(){return this.get(0)}get(t){const e=q(this.path,`get(${t})`);return this.notLoaded?new W(void 0,this.root,e,this.notLoaded):!this.present||t<0||t>=this.items.length?new W(void 0,this.root,e):new W(this.items[t],this.root,e)}}class k{constructor(t,e="CustomerOrder(null)",r="",i=!0,s){this.items=t,this.root=e,this.path=r,this.present=i,this.notLoaded=s}items;root;path;present;notLoaded;static missing(t,e=""){return new k([],t,e,!1)}size(){return this.notLoaded?n.notLoaded(this.notLoaded):this.present?new n(this.items.length):n.missing()}first(){return this.get(0)}get(t){const e=q(this.path,`get(${t})`);return this.notLoaded?new K(void 0,this.root,e,this.notLoaded):!this.present||t<0||t>=this.items.length?new K(void 0,this.root,e):new K(this.items[t],this.root,e)}}class j{constructor(t,e="OrderItem(null)",r="",i=!0,s){this.items=t,this.root=e,this.path=r,this.present=i,this.notLoaded=s}items;root;path;present;notLoaded;static missing(t,e=""){return new j([],t,e,!1)}size(){return this.notLoaded?n.notLoaded(this.notLoaded):this.present?new n(this.items.length):n.missing()}first(){return this.get(0)}get(t){const e=q(this.path,`get(${t})`);return this.notLoaded?new H(void 0,this.root,e,this.notLoaded):!this.present||t<0||t>=this.items.length?new H(void 0,this.root,e):new H(this.items[t],this.root,e)}}class et{static platform(t){return new x(t,`Platform(id=${t?.id??"null"})`)}static orderStatus(t){return new V(t,`OrderStatus(id=${t?.id??"null"})`)}static customer(t){return new W(t,`Customer(id=${t?.id??"null"})`)}static customerOrder(t){return new K(t,`CustomerOrder(id=${t?.id??"null"})`)}static orderItem(t){return new H(t,`OrderItem(id=${t?.id??"null"})`)}}const ht={Platform:{table:"platform_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{orderStatusList:{targetEntity:"OrderStatus",localKey:"id",foreignKey:"platform",many:!0},customerList:{targetEntity:"Customer",localKey:"id",foreignKey:"platform",many:!0}}},OrderStatus:{table:"order_status_data",auditMaskFields:[],columns:{platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},code:{columnName:"code",modelName:"code",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},color:{columnName:"color",modelName:"color",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},displayOrder:{columnName:"display_order",modelName:"display_order",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1},customerOrderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"status",many:!0}}},Customer:{table:"customer_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1},customerOrderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"customer",many:!0}}},CustomerOrder:{table:"customer_order_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},customer:{columnName:"customer",modelName:"customer",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},status:{columnName:"status",modelName:"status",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},orderNumber:{columnName:"order_number",modelName:"order_number",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},orderDate:{columnName:"order_date",modelName:"order_date",logPolicy:"plain",logicalType:"date",decode:"date",nullable:!1},totalAmount:{columnName:"total_amount",modelName:"total_amount",logPolicy:"plain",logicalType:"decimal",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{customer:{targetEntity:"Customer",localKey:"customer",foreignKey:"id",many:!1},status:{targetEntity:"OrderStatus",localKey:"status",foreignKey:"id",many:!1},orderItemList:{targetEntity:"OrderItem",localKey:"id",foreignKey:"customerOrder",many:!0}}},OrderItem:{table:"order_item_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},customerOrder:{columnName:"customer_order",modelName:"customer_order",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},productName:{columnName:"product_name",modelName:"product_name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},quantity:{columnName:"quantity",modelName:"quantity",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1},unitPrice:{columnName:"unit_price",modelName:"unit_price",logPolicy:"plain",logicalType:"decimal",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{customerOrder:{targetEntity:"CustomerOrder",localKey:"customerOrder",foreignKey:"id",many:!1}}}};async function Ct(d){let t=(await E.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(d))[0];t||(t=N.teaqlBootstrapNew("1"),t.updateName("Commerce Test Platform"),await t.auditAs("create generated Domain Root Platform").save(d)),d.withActiveRoot({entity:"Platform",id:t.id});let e=(await E.orderStatuses().withIdIs("1001").comment("what: locate generated constant OrderStatus(1001)").purpose("why: idempotent runtime bootstrap").executeForList(d))[0];if(!e)e=S.teaqlBootstrapNew("1001"),e.updatePlatform(t),e.updateName("New"),e.updateCode("NEW"),e.updateColor("#94A3B8"),e.updateDisplayOrder(1),await e.auditAs("create model constant OrderStatus(1001)").save(d);else{let s=!1;String(e.platform?.id??e.platform)!==String(t.id)&&(e.updatePlatform(t),s=!0),e.name!=="New"&&(e.updateName("New"),s=!0),e.code!=="NEW"&&(e.updateCode("NEW"),s=!0),e.color!=="#94A3B8"&&(e.updateColor("#94A3B8"),s=!0),e.displayOrder!==1&&(e.updateDisplayOrder(1),s=!0),s&&await e.auditAs("reconcile model constant OrderStatus(1001)").save(d)}let r=(await E.orderStatuses().withIdIs("1002").comment("what: locate generated constant OrderStatus(1002)").purpose("why: idempotent runtime bootstrap").executeForList(d))[0];if(!r)r=S.teaqlBootstrapNew("1002"),r.updatePlatform(t),r.updateName("Paid"),r.updateCode("PAID"),r.updateColor("#22C55E"),r.updateDisplayOrder(2),await r.auditAs("create model constant OrderStatus(1002)").save(d);else{let s=!1;String(r.platform?.id??r.platform)!==String(t.id)&&(r.updatePlatform(t),s=!0),r.name!=="Paid"&&(r.updateName("Paid"),s=!0),r.code!=="PAID"&&(r.updateCode("PAID"),s=!0),r.color!=="#22C55E"&&(r.updateColor("#22C55E"),s=!0),r.displayOrder!==2&&(r.updateDisplayOrder(2),s=!0),s&&await r.auditAs("reconcile model constant OrderStatus(1002)").save(d)}let i=(await E.orderStatuses().withIdIs("1003").comment("what: locate generated constant OrderStatus(1003)").purpose("why: idempotent runtime bootstrap").executeForList(d))[0];if(!i)i=S.teaqlBootstrapNew("1003"),i.updatePlatform(t),i.updateName("Cancelled"),i.updateCode("CANCELLED"),i.updateColor("#EF4444"),i.updateDisplayOrder(3),await i.auditAs("create model constant OrderStatus(1003)").save(d);else{let s=!1;String(i.platform?.id??i.platform)!==String(t.id)&&(i.updatePlatform(t),s=!0),i.name!=="Cancelled"&&(i.updateName("Cancelled"),s=!0),i.code!=="CANCELLED"&&(i.updateCode("CANCELLED"),s=!0),i.color!=="#EF4444"&&(i.updateColor("#EF4444"),s=!0),i.displayOrder!==3&&(i.updateDisplayOrder(3),s=!0),s&&await i.auditAs("reconcile model constant OrderStatus(1003)").save(d)}}const Pt=new pt(ht,{Platform:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.name===void 0||t.payload.name===null)&&e.push({ruleId:"required",location:w.property("name")}),t.payload.name!=null&&[...String(t.payload.name)].length>100&&e.push({ruleId:"max_length",location:w.property("name"),inputValue:t.payload.name,systemValue:100})}},OrderStatus:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.platform===void 0||t.payload.platform===null)&&e.push({ruleId:"required",location:w.property("platform")}),(t.action==="Create"&&t.payload.name===void 0||t.payload.name===null)&&e.push({ruleId:"required",location:w.property("name")}),t.payload.name!=null&&[...String(t.payload.name)].length>100&&e.push({ruleId:"max_length",location:w.property("name"),inputValue:t.payload.name,systemValue:100}),(t.action==="Create"&&t.payload.code===void 0||t.payload.code===null)&&e.push({ruleId:"required",location:w.property("code")}),t.payload.code!=null&&[...String(t.payload.code)].length>100&&e.push({ruleId:"max_length",location:w.property("code"),inputValue:t.payload.code,systemValue:100}),(t.action==="Create"&&t.payload.color===void 0||t.payload.color===null)&&e.push({ruleId:"required",location:w.property("color")}),t.payload.color!=null&&[...String(t.payload.color)].length>100&&e.push({ruleId:"max_length",location:w.property("color"),inputValue:t.payload.color,systemValue:100}),(t.action==="Create"&&t.payload.display_order===void 0||t.payload.display_order===null)&&e.push({ruleId:"required",location:w.property("display_order")})}},Customer:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.platform===void 0||t.payload.platform===null)&&e.push({ruleId:"required",location:w.property("platform")}),(t.action==="Create"&&t.payload.name===void 0||t.payload.name===null)&&e.push({ruleId:"required",location:w.property("name")}),t.payload.name!=null&&[...String(t.payload.name)].length>100&&e.push({ruleId:"max_length",location:w.property("name"),inputValue:t.payload.name,systemValue:100})}},CustomerOrder:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.customer===void 0||t.payload.customer===null)&&e.push({ruleId:"required",location:w.property("customer")}),(t.action==="Create"&&t.payload.status===void 0||t.payload.status===null)&&e.push({ruleId:"required",location:w.property("status")}),(t.action==="Create"&&t.payload.order_number===void 0||t.payload.order_number===null)&&e.push({ruleId:"required",location:w.property("order_number")}),t.payload.order_number!=null&&[...String(t.payload.order_number)].length>100&&e.push({ruleId:"max_length",location:w.property("order_number"),inputValue:t.payload.order_number,systemValue:100}),(t.action==="Create"&&t.payload.order_date===void 0||t.payload.order_date===null)&&e.push({ruleId:"required",location:w.property("order_date")}),(t.action==="Create"&&t.payload.total_amount===void 0||t.payload.total_amount===null)&&e.push({ruleId:"required",location:w.property("total_amount")})}},OrderItem:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.customer_order===void 0||t.payload.customer_order===null)&&e.push({ruleId:"required",location:w.property("customer_order")}),(t.action==="Create"&&t.payload.product_name===void 0||t.payload.product_name===null)&&e.push({ruleId:"required",location:w.property("product_name")}),t.payload.product_name!=null&&[...String(t.payload.product_name)].length>100&&e.push({ruleId:"max_length",location:w.property("product_name"),inputValue:t.payload.product_name,systemValue:100}),(t.action==="Create"&&t.payload.quantity===void 0||t.payload.quantity===null)&&e.push({ruleId:"required",location:w.property("quantity")}),(t.action==="Create"&&t.payload.unit_price===void 0||t.payload.unit_price===null)&&e.push({ruleId:"required",location:w.property("unit_price")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Commerce Test Platform"}},constants:[{entity:"OrderStatus",id:"1001",values:{platform:"1",name:"New",code:"NEW",color:"#94A3B8",displayOrder:1}},{entity:"OrderStatus",id:"1002",values:{platform:"1",name:"Paid",code:"PAID",color:"#22C55E",displayOrder:2}},{entity:"OrderStatus",id:"1003",values:{platform:"1",name:"Cancelled",code:"CANCELLED",color:"#EF4444",displayOrder:3}}],ensure:Ct}),it=document.querySelector("#status"),St=document.querySelector("#result"),Nt=document.querySelector("#trace"),$t=document.querySelector("#sql"),bt=document.querySelector("#evidence-rows"),Z=document.querySelector("#persist"),dt=document.querySelector("#logging"),rt=document.querySelector("#reset"),Y=document.querySelector("#query"),lt=document.querySelector("#search"),Tt={filter:{orderNumber:{$contains:"KEEP"}}};let R;Z.checked=localStorage.getItem("teaql-browser-order-storage")==="opfs";async function Qt(d){const t=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),e=await ft.open(t,{...ht},{storage:d,databaseName:"teaql-browser-orders.sqlite3"});e.install(Pt),e.setDiagnosticSQLLogSink(void 0).setMutationLoggingEnabled(!1);const r=Object.freeze({policyId:"browser-order-seed",version:"1",fingerprint:"sha256:browser-order-seed-v1"}),i=new gt().insertResource("dataService",e).withMutationPolicyRegistry(new Ot(()=>({identity:r,review:(s,h)=>h.operations.length>0?{verdict:"allow"}:{verdict:"deny",code:"EMPTY_GRAPH",message:"empty mutation graph"}}))).withMutationPolicyApprovalProvider(new wt(s=>({policy:s,approvedBy:"browser-demo-owner",approvedAt:new Date})));return e.setUserContext(i),await i.ensureSchema(),await i.ensureSchema(),{client:e,context:i,evidence:new qt,diagnostics:[]}}async function ct({context:d}){if((await E.customerOrdersWithMinimalFields().limit(1).comment("detect existing order demo").purpose("keep mutation seeding idempotent").executeForList(d)).length)return;const e=(await E.platforms().limit(2).comment("load bootstrap platform").purpose("prepare order demo").executeForList(d))[0],r=E.customers().comment("initialize demo customer").purpose("prepare order demo").newEntity(d);r.updateName("North Star Retail").updatePlatform(e.id),await r.auditAs("seed browser order customer").save(d);for(let i=1;i<=4;i++){const s=E.customerOrders().comment("initialize demo order").purpose("prepare order demo").newEntity(d);s.updateCustomer(r.id).updateOrderNumber(i<4?`KEEP-00${i}`:"DROP-004").updateOrderDate(`2026-10-0${i}`).updateTotalAmount(i<4?i*100:900),i===1?s.updateStatusToNew():s.updateStatusToPaid(),await s.auditAs("seed browser order").save(d);for(let h=1;h<=5;h++){const o=E.orderItems().comment("initialize demo item").purpose("prepare item previews").newEntity(d);o.updateCustomerOrder(s.id).updateProductName(`Box ${h}`).updateQuantity(h).updateUnitPrice(20),await o.auditAs("seed browser order item").save(d)}}}async function tt(d){const t=JSON.parse(lt.value),e=E.customerOrdersWithMinimalFields().filterByJson(t);d.evidence.enableAll(),d.diagnostics.length=0,d.client.setRuntimeTelemetrySink(d.evidence).setQueryLoggingEnabled(dt.checked).setDiagnosticSQLLogSink({write:o=>d.diagnostics.push(o)});const r=await e.countAs("totalOrders").facetByStatusAs("statusCounts",E.orderStatusesWithMinimalFields().selectName().selectColor().countAs("orderCount").sumTotalAmountOfCustomerOrdersAs("orderTotalAmount",E.customerOrdersWithMinimalFields()).orderByDisplayOrderAscending().comment("load status facets")).selectOrderNumber().selectOrderDate().selectStatusWith(E.orderStatusesWithMinimalFields().selectName().selectColor().comment("load status")).selectOrderItemListWith(E.orderItemsWithMinimalFields().selectProductName().selectQuantity().orderByIdAscending().limit(3).comment("load item previews")).countOrderItemsAs("itemCount").orderByOrderDateDescending().orderByIdDescending().offset(1).limit(1).comment("load order list").purpose("render order list page").executeForList(d.context),i={data:r.data.map(o=>{const p=et.customerOrder(o),l=p.orderItemList().size().eval();if(l==null)throw new Error("Selected item list unexpectedly has a null size");return{id:o.id,version:o.version,orderNumber:p.orderNumber().eval(),orderDate:p.orderDate().eval(),status:{name:p.status().name().eval(),color:p.status().color().eval()},items:Array.from({length:l},(a,u)=>({productName:p.orderItemList().get(u).productName().eval(),quantity:p.orderItemList().get(u).quantity().eval()})),itemCount:o.itemCount}}),metadata:{totalCount:r.totalCount,pageOffset:1,pageSize:1,aggregations:r.data.aggregations,searchWarnings:e.dynamicSearchWarnings},facets:{statusCounts:r.data.facets.statusCounts.map(o=>({id:o.id,name:et.orderStatus(S.fromRecord(o)).name().eval(),color:et.orderStatus(S.fromRecord(o)).color().eval(),orderCount:o.orderCount,orderTotalAmount:o.orderTotalAmount}))}};St.textContent=JSON.stringify(i,null,2);const s=d.evidence.snapshot(),h=s.map(o=>{const p=o.traceChain??[],l=p.filter(m=>m.kind==="purpose"),a=l.length===1?`${l[0].detail}: ${p.filter(m=>m.kind==="comment").map(m=>m.detail).join(" → ")}`:"TraceChain unavailable",u=document.createElement("tr");for(const m of[`${o.elapsedMicros} µs`,o.tracePath.find(C=>C.kind==="request")?.name??"—",a,o.debugSQL]){const C=document.createElement("td");C.textContent=m,u.append(C)}return{row:u,businessTrace:a}});bt.replaceChildren(...h.map(o=>o.row)),Nt.textContent=h.map(o=>o.businessTrace).join(` +`),$t.textContent=JSON.stringify(s,null,2),it.textContent=`${d.client.storage.toUpperCase()} · ${r.totalCount} matches · ${s.length} SQL statements · ${d.diagnostics.length} diagnostics · policy installed · ready`}async function mt(d){it.textContent=`Opening ${d.toUpperCase()} SQLite/WASM…`;const t=R;R=void 0,await t?.client.close();const e=await Qt(d);R=e,await ct(e),await tt(e)}function X(d){it.textContent=d instanceof Error?`${d.name}: ${d.message}`:String(d)}Y.addEventListener("click",async()=>{if(R){Y.disabled=!0;try{await tt(R)}catch(d){X(d)}finally{Y.disabled=!1}}});document.querySelector("#preset").addEventListener("click",()=>{lt.value=JSON.stringify(Tt,null,2),Y.click()});dt.addEventListener("change",()=>{R&&tt(R).catch(X)});Z.addEventListener("change",()=>{const d=Z.checked?"opfs":"memory";localStorage.setItem("teaql-browser-order-storage",d),mt(d).catch(X)});rt.addEventListener("click",async()=>{if(R){rt.disabled=!0;try{await R.client.reset(R.context),await ct(R),await tt(R)}catch(d){X(d)}finally{rt.disabled=!1}}});mt(Z.checked?"opfs":"memory").catch(X); diff --git a/assets/style-SCdXWqgK.css b/assets/style-SCdXWqgK.css new file mode 100644 index 0000000000000000000000000000000000000000..8274d2f8ef8b83862a47b0c69f23f755fda89d67 --- /dev/null +++ b/assets/style-SCdXWqgK.css @@ -0,0 +1 @@ +:root{font:16px/1.5 Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;color:#17231b;background:#f5f4ed;font-synthesis:none;--ink: #17231b;--muted: #677067;--paper: #fffef8;--line: #d8ddd3;--green: #145b37;--green-deep: #0e4329;--lime: #dff45c;--orange: #ef8354;--blue: #2b66d9}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;min-width:320px;background:#f5f4ed}button,input{font:inherit}button,a{-webkit-tap-highlight-color:transparent}.page-shell{width:min(1440px,100%);margin:0 auto;padding:0 42px}.site-header{height:76px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--line)}.brand,.docs-link{color:var(--ink);text-decoration:none;font-weight:750}.brand{display:inline-flex;align-items:center;gap:11px;letter-spacing:-.02em}.brand-mark{width:30px;height:30px;display:grid;place-items:center;border-radius:50%;color:var(--lime);background:var(--green-deep);font-family:Georgia,serif;font-style:italic}.docs-link{color:var(--green);font-size:14px}.header-actions{display:flex;align-items:center;gap:18px}.language-switch{display:flex;gap:3px;padding:3px;border:1px solid var(--line);border-radius:8px}.language-switch button{padding:3px 7px;border:0;border-radius:5px;color:var(--muted);background:transparent;font-size:11px;cursor:pointer}.language-switch button.active{color:#fff;background:var(--green)}.hero{min-height:460px;display:grid;grid-template-columns:minmax(0,1.1fr) minmax(440px,.9fr);align-items:center;gap:72px;padding:76px 0 66px}.eyebrow,.section-index,.query-card-label{margin:0 0 14px;color:var(--green);font-size:11px;font-weight:850;letter-spacing:.18em}h1{margin:0;max-width:820px;font-family:Georgia,"Noto Serif SC",serif;font-size:clamp(42px,5.6vw,78px);font-weight:500;line-height:1.08;letter-spacing:-.055em}.hero-intro{max-width:680px;margin:26px 0 0;color:var(--muted);font-size:18px}.model-map{position:relative;min-height:310px;padding:38px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:12px;border:1px solid #bfc8bb;border-radius:28px;background:linear-gradient(145deg,#fdfdf8,#e9eee5);box-shadow:0 18px 48px #213c280f;overflow:hidden}.model-map:before{content:"DOMAIN MODEL";position:absolute;top:18px;left:22px;color:#708073;font-size:10px;font-weight:800;letter-spacing:.16em}.model-flow{width:100%;display:grid;grid-template-columns:1fr auto 1fr auto 1fr;align-items:center;gap:10px}.model-flow>span:not(.model-arrow),.model-leaves span{min-width:0;padding:15px 17px;border:1px solid #b8c2b7;border-radius:12px;background:#fffffadb;font:750 14px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;box-shadow:0 8px 22px #1e3a260d}.model-map small{display:block;margin-top:7px;color:var(--muted);font:12px/1.2 Inter,sans-serif}.model-flow>span.model-root{color:#fff;border-color:var(--green);background:var(--green)}.model-map .model-root small{color:#cce4d4}.model-arrow{color:#809087;font-size:22px;text-align:center}.model-arrow-split{height:22px;line-height:18px}.model-leaves{width:100%;display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.runtime-bar{min-height:72px;padding:14px 18px 14px 22px;display:flex;align-items:center;justify-content:space-between;gap:24px;border-radius:14px;color:#e7f1e9;background:var(--green-deep)}#status{margin:0;color:#c8d9ce;font:12px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.controls{display:flex;align-items:center;gap:18px}.toggle{display:inline-flex;align-items:center;gap:9px;font-size:13px;cursor:pointer}.toggle input{position:absolute;opacity:0;pointer-events:none}.toggle span{position:relative;width:38px;height:22px;border-radius:999px;background:#55705f;transition:background .2s ease}.toggle span:after{content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;background:#fff;transition:transform .2s ease}.toggle input:checked+span{background:var(--lime)}.toggle input:checked+span:after{transform:translate(16px);background:var(--green-deep)}.secondary-button,.tree-actions button{border:1px solid currentColor;border-radius:8px;background:transparent;cursor:pointer}.secondary-button{padding:8px 12px;color:#fff;font-size:12px}.secondary-button:disabled{opacity:.45;cursor:wait}.query-browser{padding:96px 0 82px}.section-heading,.result-heading{display:flex;align-items:end;justify-content:space-between;gap:36px;margin-bottom:40px}.section-heading h2,.result-heading h2{margin:0;font-family:Georgia,"Noto Serif SC",serif;font-size:clamp(34px,4vw,52px);font-weight:500;letter-spacing:-.045em}.section-heading>p{max-width:420px;margin:0;color:var(--muted)}.query-group{display:grid;grid-template-columns:230px 1fr;gap:36px;padding:24px 0;border-top:1px solid var(--line)}.query-group:last-child{border-bottom:1px solid var(--line)}.query-group-heading h2{margin:0 0 4px;font-size:16px}.query-group-heading p{margin:0;color:var(--muted);font-size:12px}.query-links{display:flex;flex-wrap:wrap;align-items:center;gap:10px 24px}.query-links a{position:relative;padding:5px 0;color:#34443a;text-decoration-color:#a6b1a8;text-underline-offset:5px;font-weight:650;transition:color .16s ease}.query-links a:after{content:" ↗";color:#9aa49b;font-weight:400}.query-links a:hover{color:var(--green)}.query-links a.active{color:var(--green);text-decoration-color:var(--orange);text-decoration-thickness:2px}.result-panel{margin:0 -42px;padding:82px 42px 92px;color:#eef5f0;background:#111a15}.result-heading{align-items:center}.result-heading .section-index{color:var(--lime)}.result-heading h2{color:#fff}#result-description{max-width:620px;margin:10px 0 0;color:#9fb0a4}.result-actions{display:flex;align-items:center;gap:10px}.result-view-switch,.tree-actions{display:flex;gap:6px}.result-view-switch button,.tree-actions button{padding:8px 11px;border:1px solid #536159;border-radius:8px;color:#aebdb3;background:transparent;font-size:12px;cursor:pointer}.result-view-switch button.active{color:#17231b;border-color:var(--lime);background:var(--lime)}.result-view-switch button:disabled{opacity:.35;cursor:default}.tree-actions button:hover{color:var(--lime)}.result-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:18px;align-items:start}.tree-card,.query-card,.sql-card{border:1px solid #2f3d34;border-radius:14px;background:#17231b}.tree-card{min-height:520px;overflow:hidden}.tree-card-bar{min-height:48px;padding:0 18px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #2f3d34;color:#b8c9bd;font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase;letter-spacing:.08em}#result-meta{margin:0;color:#829188;text-transform:none;letter-spacing:0}.json-tree{min-height:470px;max-height:680px;padding:18px 20px 28px;overflow:auto;font:13px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.json-tree.loading{opacity:.55}.tree-actions.hidden{display:none}.result-table-shell{width:100%;min-height:470px;overflow:auto}.result-table{width:100%;border-collapse:collapse;white-space:nowrap}.result-table th,.result-table td{padding:11px 14px;border-bottom:1px solid #2f3d34;text-align:left;vertical-align:top}.result-table th{position:sticky;top:0;z-index:1;color:#8ea095;background:#131d17;font:700 10px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.result-table td{color:#d9e5dc;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}.result-table tbody tr:hover{background:#ffffff06}.result-table-empty{margin:0;padding:48px 20px;color:#7f9185;text-align:center}.tree-branch{margin:2px 0}.tree-branch>summary{min-height:29px;display:flex;align-items:center;gap:9px;list-style:none;cursor:pointer;border-radius:5px}.tree-branch>summary::-webkit-details-marker{display:none}.tree-branch>summary:before{content:"›";width:15px;color:#73887a;font-size:18px;line-height:1;transform-origin:center;transition:transform .12s ease}.tree-branch[open]>summary:before{transform:rotate(90deg)}.tree-branch>summary:hover{background:#ffffff09}.tree-children{margin-left:8px;padding-left:20px;border-left:1px solid #314238}.tree-leaf{min-height:28px;display:grid;grid-template-columns:minmax(110px,180px) 1fr;align-items:baseline;gap:12px;padding-left:23px}.tree-key{color:#bdd0c2;font-weight:700}.tree-preview{overflow:hidden;color:#718079;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.tree-value{overflow-wrap:anywhere}.tree-string{color:#dff45c}.tree-number{color:#82b4ff}.tree-boolean{color:#f2a27f}.tree-null{color:#78847c;font-style:italic}.query-card,.sql-card{min-width:0;padding:22px}.query-card-label{color:var(--lime)}.query-card pre{max-height:430px;margin:0;padding:0;overflow:auto;color:#d5e2d8;background:transparent;font:12px/1.72 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap}.query-params{margin-top:24px;padding-top:18px;border-top:1px solid #2f3d34}.query-params.hidden{display:none}.query-params .query-card-label{margin-bottom:10px;color:#82b4ff}.query-params pre{max-height:220px;color:#b9caee}.query-note{margin:28px 0 0;padding-top:18px;border-top:1px solid #2f3d34;color:#829188;font-size:12px}.sql-card-heading{display:flex;align-items:center;justify-content:space-between;gap:16px}.sql-card-heading .query-card-label{margin-bottom:0}#sql-count{color:#7f9185;font:10px/1.3 ui-monospace,SFMono-Regular,Menlo,monospace}.execution-evidence-wrap{margin-top:18px;overflow-x:auto;border:1px solid #34433a;border-radius:8px}.execution-evidence{min-width:1500px;width:100%;border-collapse:collapse;color:#c7d5cb}.execution-evidence th,.execution-evidence td{padding:10px 12px;border-right:1px solid #34433a;border-bottom:1px solid #34433a;text-align:left;vertical-align:top;white-space:nowrap}.execution-evidence th:last-child,.execution-evidence td:last-child{border-right:0}.execution-evidence tbody tr:last-child td{border-bottom:0}.execution-evidence th{color:#7f9185;background:#131d17;font:700 10px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.execution-evidence td{color:#cbd8ce;background:#101813;font:10px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}.execution-evidence tbody tr:hover td{background:#141f18}.execution-evidence .evidence-trace{color:#b9caee}.execution-evidence .evidence-sql{color:#dff45c}.dashboard-result{max-height:none;padding:0;color:var(--ink);background:#f7f8f5;font:14px/1.45 Inter,system-ui,sans-serif}.order-center{min-width:880px;padding:24px}.order-center-toolbar{display:flex;align-items:end;justify-content:space-between;gap:24px;margin-bottom:20px}.order-center-toolbar h3{margin:0;color:#111d16;font:750 22px/1.2 Inter,system-ui,sans-serif;letter-spacing:-.025em}.order-center-toolbar p{margin:5px 0 0;color:#778078;font-size:12px}.order-search{width:min(390px,45%);display:flex;align-items:center;gap:6px}.order-search input{min-width:0;height:32px;flex:1;padding:6px 10px;border:1px solid #cfd5ce;border-radius:7px;outline:0;background:#fff;font-size:12px}.order-search input:focus{border-color:#8e9990}.order-search-submit{width:30px;height:30px;flex:0 0 30px;display:grid;place-items:center;padding:0;border:1px solid #cfd5ce;border-radius:7px;color:#536057;background:#fff;cursor:pointer}.order-search-submit:hover,.order-search-submit:focus-visible{color:var(--green);border-color:#93a097;outline:none}.search-icon{position:relative;width:13px;height:13px;display:block;border:1.5px solid currentColor;border-radius:50%}.search-icon:after{content:"";position:absolute;right:-3px;bottom:-2px;width:5px;height:1.5px;border-radius:1px;background:currentColor;transform:rotate(45deg);transform-origin:left center}.order-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-bottom:18px}.metric-card{padding:14px;display:grid;gap:8px;text-align:left;border:1px solid #dbe0da;border-radius:9px;color:#58625b;background:#fff;cursor:pointer}.metric-card strong{color:#16231a;font-size:23px;line-height:1}.metric-card small{color:#727b74;font-size:10px;font-variant-numeric:tabular-nums}.metric-card.active{border-color:var(--metric-color, var(--blue));box-shadow:inset 3px 0 0 var(--metric-color, var(--blue))}.order-table{overflow:hidden;border:1px solid #e0e4df;border-radius:10px;background:#fff}.order-row{min-width:720px;display:grid;grid-template-columns:1.05fr .85fr .75fr 2fr;align-items:center;gap:14px;min-height:68px;padding:10px 14px;border-top:1px solid #edf0ec}.order-row:first-child{border-top:0}.order-row-head{min-height:40px;color:#69736b;background:#f2f4f1;font-size:11px;font-weight:750}.order-primary{color:#26322a;font:650 12px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.status-badge{display:inline-block;padding:4px 8px;border-radius:999px;color:#2b5e39;background:#e3f4e8;font-size:10px;white-space:nowrap}.status-pending_payment{color:#92580a;background:#fff0d8}.status-paid{color:#215b9d;background:#e2efff}.status-shipped{color:#1d6e38;background:#ddf5e4}.status-cancelled{color:#7b4650;background:#f6e6e9}.product-preview{display:flex;align-items:center;gap:5px}.product-thumb{width:32px;height:28px;display:grid;place-items:center;border:1px solid #cad4ca;border-radius:6px;color:#315139;background:linear-gradient(135deg,#e5eddf,#bdceb8);font:800 11px/1 Inter,sans-serif}.product-tone-1{color:#725333;background:linear-gradient(135deg,#f1e5d4,#d3b58d)}.product-tone-2{color:#3d526b;background:linear-gradient(135deg,#e1e9ef,#adbecd)}.product-preview small{color:#68736a;font-size:10px}.order-empty{padding:48px 20px;color:#7a847c;text-align:center}.order-center-footer{display:flex;align-items:center;justify-content:space-between;gap:20px;padding-top:16px}.order-center-footer p{margin:0;color:#7a847c;font-size:11px}.pagination{display:flex;gap:5px}.pagination button{min-width:31px;height:31px;border:1px solid #d8ddd7;border-radius:6px;color:#465149;background:#fff;cursor:pointer}.pagination button.active{color:#fff;border-color:var(--blue);background:var(--blue)}.pagination button:disabled{opacity:.4;cursor:default}footer{min-height:86px;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:12px}@media(max-width:980px){.page-shell{padding:0 24px}.hero{grid-template-columns:1fr;gap:46px;padding-top:58px}.model-map{min-height:260px}.result-panel{margin:0 -24px;padding-left:24px;padding-right:24px}.result-grid{grid-template-columns:1fr}}@media(max-width:680px){.page-shell{padding:0 16px}.site-header{height:64px}.header-actions{gap:9px}.docs-link{display:none}h1{font-size:43px}.hero{min-height:auto;padding:48px 0}.hero-intro{font-size:16px}.model-map{gap:9px;padding:52px 22px 22px}.model-flow{grid-template-columns:1fr}.model-flow>span:not(.model-arrow),.model-leaves span{width:100%}.model-flow .model-arrow{transform:rotate(90deg)}.model-leaves{grid-template-columns:1fr}.runtime-bar,.section-heading,.result-heading{align-items:flex-start;flex-direction:column}.runtime-bar{padding:18px}.controls{width:100%;justify-content:space-between}.query-browser{padding:70px 0 64px}.query-group{grid-template-columns:1fr;gap:14px}.query-links{gap:8px 18px}.result-panel{margin:0 -16px;padding:64px 16px}.result-actions{width:100%;align-items:stretch;flex-direction:column}.result-view-switch,.tree-actions{width:100%}.result-view-switch button,.tree-actions button{flex:1}.tree-leaf{grid-template-columns:minmax(90px,120px) 1fr;padding-left:15px}.json-tree{padding-left:12px;padding-right:12px}} diff --git a/assets/workItems-5mJKEgxC.css b/assets/workItems-5mJKEgxC.css new file mode 100644 index 0000000000000000000000000000000000000000..7185e90c42246c0339bd4f8538ffbea3f177851f --- /dev/null +++ b/assets/workItems-5mJKEgxC.css @@ -0,0 +1 @@ +:root{font:16px/1.5 Inter,system-ui,sans-serif;color:#e8edf5;background:#090b10}body{margin:0}main{width:min(760px,calc(100% - 40px));margin:10vh auto}.eyebrow{color:#d9ff52;font-size:12px;font-weight:800;letter-spacing:.16em}h1{margin:8px 0;font-size:clamp(36px,7vw,68px);letter-spacing:-.05em}a{color:#d9ff52}.controls{display:flex;gap:18px;align-items:center;margin:32px 0}button{border:0;border-radius:5px;padding:10px 14px;background:#d9ff52;font-weight:800}#status{color:#aab4c4}pre{min-height:260px;padding:22px;overflow:auto;border:1px solid #2b323e;border-radius:8px;background:#11151c;color:#c6d1df} diff --git a/assets/workItems-DraVJWt7.js b/assets/workItems-DraVJWt7.js new file mode 100644 index 0000000000000000000000000000000000000000..b0ae6062d03594b1ac8317d6b745a9cb72d5e143 --- /dev/null +++ b/assets/workItems-DraVJWt7.js @@ -0,0 +1 @@ +import{S as G,L as c,M as k,C as v,a as I,d as O,e as C,Q as K,R as U,B as z,U as H,D as J,c as Y}from"./dynamic-search-BBmdgl4H.js";import{E as $,O as g}from"./object-location-xgYMemK6.js";class L extends G{orderBy(t,e){return this.order({field:t,expr:null,direction:e==="desc"?"Desc":"Asc"})}relationQuery(t,e,i="id",r="id",s=!0,a){return super.relationQuery(t,e,i,r,s,a)}}class m{static teaqlTemporaryId=0;id;title;description;platform;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new $,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--m.teaqlTemporaryId,writable:!0,enumerable:!1}),t){const i={...t};Object.assign(this,i),t.platform&&typeof t.platform=="object"&&(this.platform=t.platform instanceof y?t.platform:y.fromRecord(t.platform),this.markLoaded("platform"))}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),c.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"WorkItem",id:this._ledgerId}}teaqlAttachRoot(t){return this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t),this}static fromRecord(t,e){const i=new m(t);return e?i.teaqlAttachRoot(e):i}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new m({id:String(t)})}static teaqlBootstrapNew(t){return new m().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new k(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new k(this._comment),async i=>(this.teaqlPreflightGraph(t,e,i),this.teaqlSaveWithinGraph(t,e,i)))}teaqlPreflightGraph(t,e,i,r){r||new k(this._comment);const s=this._action,a=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&a){const d=[{member:"id",canonical:"id"},{member:"title",canonical:"title"},{member:"description",canonical:"description"},{member:"platform",canonical:"platform"},{member:"version",canonical:"version"}].find(u=>!this.isLoaded(u.member));if(d)throw new v([{ruleId:"invalid_type",location:g.property(d.canonical),message:"Mutation requires a fully loaded entity"}])}const n=i.request({entity:"WorkItem",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},r,this._comment).withLoadedSnapshot(c.forEntity(this)??new c);a&&e.preflightMutation(n),n.scopeFor(this.teaqlEntityKey())}async teaqlSaveWithinGraph(t,e,i,r){r||new k(this._comment);const s=this._action,a=this._root.change(this.teaqlEntityKey()),n={entity:"WorkItem",action:this._action,payload:s==="Update"?a:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},d=i.request(n,r,this._comment).withLoadedSnapshot(c.forEntity(this)??new c);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey()))return d.scopeFor(this.teaqlEntityKey()),this;const u=await e.executeMutation(d);for(const[S,f]of Object.entries(n.payload))S!=="id"&&S!=="version"&&this._root.set(this.teaqlEntityKey(),S,f);if(!u.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const h={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:c.forEntity(this)},l=this.teaqlEntityKey();Object.assign(this,u.persistedRecord),c.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const p=this.teaqlEntityKey();return this._root.rekey(l,p),e.afterGraphRollback(()=>{Object.assign(this,h.payload),this._ledgerId=h.ledgerId,this._action=h.action,this._loadedFields=h.loadedFields,this._fullyLoaded=h.fullyLoaded,c.restoreFor(this,h.loadedSnapshot),this._root.rekey(p,l)}),this._loadedFields=new Set(Object.keys(u.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update"),d.scopeFor(p),e.afterGraphCommit(()=>{this._root.clearEntity(p),this.version!==void 0&&this._root.acceptCommittedVersion(p,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,title:this.title,description:this.description,platform:this.platform,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateTitle(t){return this.title=t,this.markLoaded("title"),this._root.set(this.teaqlEntityKey(),"title",t),this}updateDescription(t){return this.description=t,this.markLoaded("description"),this._root.set(this.teaqlEntityKey(),"description",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updatePlatform(t){return this.platform=t?.id??t,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}}class y{static teaqlTemporaryId=0;id;name;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new $,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--y.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_workItemList",{value:t?.id?I.empty():new I,writable:!0,enumerable:!1}),t){const i={...t};if(delete i.workItemList,Object.assign(this,i),Array.isArray(t.workItemList)){const r=t.workItemList;this._workItemList=new I(r.map(s=>s instanceof m?s:m.fromRecord(s)),{totalCount:r.totalCount,aggregations:r.aggregations,summary:r.summary,facets:r.facets,isLoaded:r.isLoaded??!0}),this.markLoaded("workItemList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),c.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._workItemList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const i=new y(t);return e?i.teaqlAttachRoot(e):i}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new y({id:String(t)})}static teaqlBootstrapNew(t){return new y().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new k(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new k(this._comment),async i=>(this.teaqlPreflightGraph(t,e,i),this.teaqlSaveWithinGraph(t,e,i)))}teaqlPreflightGraph(t,e,i,r){r||new k(this._comment);const s=this._action,a=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&a){const u=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new v([{ruleId:"invalid_type",location:g.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const n=i.request({entity:"Platform",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},r,this._comment).withLoadedSnapshot(c.forEntity(this)??new c);a&&e.preflightMutation(n);const d=n.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._workItemList.entries()){h.teaqlAttachRoot(this._root);const l=h.platform;(this.id===void 0||!h.isLoaded("platform")||(typeof l=="object"&&l!==null?l.id:l)!==this.id)&&h.updatePlatform(this);try{h.teaqlPreflightGraph(t,e,i,d)}catch(p){if(!(p instanceof v))throw p;const S=g.property("work_item_list").index(u);throw new v(p.violations.map(f=>({...f,location:f.location.prefixedBy(S)})))}}}async teaqlSaveWithinGraph(t,e,i,r){r||new k(this._comment);const s=this._action,a=this._root.change(this.teaqlEntityKey()),n={entity:"Platform",action:this._action,payload:s==="Update"?a:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},d=i.request(n,r,this._comment).withLoadedSnapshot(c.forEntity(this)??new c);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=d.scopeFor(this.teaqlEntityKey());for(const[q,w]of this._workItemList.entries()){w.teaqlAttachRoot(this._root);const _=w.platform;(this.id===void 0||!w.isLoaded("platform")||(typeof _=="object"&&_!==null?_.id:_)!==this.id)&&w.updatePlatform(this);try{await w.teaqlSaveWithinGraph(t,e,i,f)}catch(N){if(!(N instanceof v))throw N;const P=g.property("work_item_list").index(q);throw new v(N.violations.map(B=>({...B,location:B.location.prefixedBy(P)})))}}return this}const u=await e.executeMutation(d);for(const[f,q]of Object.entries(n.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,q);if(!u.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const h={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:c.forEntity(this)},l=this.teaqlEntityKey();Object.assign(this,u.persistedRecord),c.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const p=this.teaqlEntityKey();this._root.rekey(l,p),e.afterGraphRollback(()=>{Object.assign(this,h.payload),this._ledgerId=h.ledgerId,this._action=h.action,this._loadedFields=h.loadedFields,this._fullyLoaded=h.fullyLoaded,c.restoreFor(this,h.loadedSnapshot),this._root.rekey(p,l)}),this._loadedFields=new Set(Object.keys(u.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update");const S=d.scopeFor(p);for(const[f,q]of this._workItemList.entries()){q.teaqlAttachRoot(this._root);const w=q.platform;(this.id===void 0||!q.isLoaded("platform")||(typeof w=="object"&&w!==null?w.id:w)!==this.id)&&q.updatePlatform(this);try{await q.teaqlSaveWithinGraph(t,e,i,S)}catch(_){if(!(_ instanceof v))throw _;const N=g.property("work_item_list").index(f);throw new v(_.violations.map(P=>({...P,location:P.location.prefixedBy(N)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(p),this.version!==void 0&&this._root.acceptCommittedVersion(p,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateName(t){return this.name=t,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}workItemList(){return this._workItemList}}const D=Object.freeze({Platform:Object.freeze({fields:Object.freeze({id:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",name:"name",version:"version"}),relations:Object.freeze({workItemList:"WorkItem"})}),WorkItem:Object.freeze({fields:Object.freeze({id:"integer",title:"string",description:"string",platform:"integer",version:"integer"}),queryFields:Object.freeze({id:"id",title:"title",description:"description",platform:"platform",version:"version"}),relations:Object.freeze({platform:"Platform"})})});class A{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new L("Platform"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const r=O(i,t,D,e);return this.query=r.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...r.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new X(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,i)=>this.executeForStreamInternal(e,i),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,i){return this.query.optimizePaginationWithIdSetConfig(t,e,i),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectWorkItemListWith(t){return this.query.relationQuery("workItemList",t.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectWorkItemListWith",relation:"workItemList"}),this}haveWorkItems(){return this.withWorkItemListMatching({toQuery:()=>new L("WorkItem")})}haveNoWorkItems(){return this.withoutWorkItemListMatching({toQuery:()=>new L("WorkItem")})}withWorkItemListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"platform"}}}),this}withoutWorkItemListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"platform"}}}),this}countWorkItems(){return this.countWorkItemsAs("countWorkItems")}countWorkItemsAs(t){const e=new L("WorkItem").filter({version:{$gte:1}});return this.countWorkItemsWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countWorkItemsAs",relation:"workItemList",alias:t},this}countWorkItemsWith(t,e){const i=e.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",t),this.query.relationAggregate("workItemList",t,i,!0,{kind:"relation-count",method:"countWorkItemsWith",relation:"workItemList",alias:t}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(t){return this.filters.push({name:{$contains:t}}),this}withNameIs(t){return this.filters.push({name:{$eq:t}}),this}withNameIsNot(t){return this.filters.push({name:{$ne:t}}),this}withNameIn(...t){return this.filters.push({name:{$in:t}}),this}withNameNotIn(...t){return this.filters.push({name:{$notIn:t}}),this}withNameGreaterThan(t){return this.filters.push({name:{$gt:t}}),this}withNameGreaterThanOrEqualTo(t){return this.filters.push({name:{$gte:t}}),this}withNameLessThan(t){return this.filters.push({name:{$lt:t}}),this}withNameLessThanOrEqualTo(t){return this.filters.push({name:{$lte:t}}),this}withNameBetween(t,e){return this.filters.push({name:{$between:[t,e]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(t){return this.filters.push({name:{$notContains:t}}),this}withNameStartingWith(t){return this.filters.push({name:{$startsWith:t}}),this}withNameNotStartingWith(t){return this.filters.push({name:{$notStartsWith:t}}),this}withNameEndingWith(t){return this.filters.push({name:{$endsWith:t}}),this}withNameNotEndingWith(t){return this.filters.push({name:{$notEndsWith:t}}),this}withNameSoundingLike(t){return this.filters.push({name:{$soundLike:t}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(t){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),i=await e.executeQuery(t.prepareQuery(this.query)),r=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=r?[]:i.map(n=>n instanceof y?n:y.fromRecord(n,new $)),a=new I(s);return r&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await C(e,n=>t.prepareQuery(n),this.query,this.query.facets)),a}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new I(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),i=t.prepareQuery(this.query),r=i.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=r?void 0:await e.executeCount(i,this._pageCountAlias,s),n=i.clone();n.aggregateItems=n.aggregateItems.filter(l=>!(String(l.function).toLowerCase()==="count"&&l.alias===this._pageCountAlias));const d=await e.executeQuery(n),u=r&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:a??await e.executeCount(i,this._pageCountAlias,s),h=new I(d.map(l=>l instanceof y?l:y.fromRecord(l,new $)));return h.totalCount=u,this._pageCountAlias!==void 0&&(h.aggregations[this._pageCountAlias]=u),this.query.facets.length>0&&(h.facets=await C(e,l=>t.prepareQuery(l),i,i.facets)),h}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=t.requireResource("dataService"),r=t.prepareQuery(this.query),s=i.executeForStream(r,e);return(async function*(){for await(const a of s)for(const n of a)yield n instanceof y?n:y.fromRecord(n,new $)})()}ensureIntent(){new K(this._comment,this._purpose)}}class X{constructor(t,e,i,r,s,a){this.execute=t,this.executeRows=e,this.stream=i,this.limitOne=r,this.addComment=s,this.ensureIntent=a}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new y}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class x{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new L("WorkItem"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const r=O(i,t,D,e);return this.query=r.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...r.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new Z(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,i)=>this.executeForStreamInternal(e,i),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,i){return this.query.optimizePaginationWithIdSetConfig(t,e,i),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","title","description","platform","version"]),this}selectId(){return this.query.select(["id"]),this}selectTitle(){return this.query.select(["title"]),this}selectDescription(){return this.query.select(["description"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(t){return this.query.select(["platform"]),this.query.relationQuery("platform",t.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(t){return this.filters.push({platform:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutPlatformMatching(t){return this.filters.push({platform:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withTitleContaining(t){return this.filters.push({title:{$contains:t}}),this}withTitleIs(t){return this.filters.push({title:{$eq:t}}),this}withTitleIsNot(t){return this.filters.push({title:{$ne:t}}),this}withTitleIn(...t){return this.filters.push({title:{$in:t}}),this}withTitleNotIn(...t){return this.filters.push({title:{$notIn:t}}),this}withTitleGreaterThan(t){return this.filters.push({title:{$gt:t}}),this}withTitleGreaterThanOrEqualTo(t){return this.filters.push({title:{$gte:t}}),this}withTitleLessThan(t){return this.filters.push({title:{$lt:t}}),this}withTitleLessThanOrEqualTo(t){return this.filters.push({title:{$lte:t}}),this}withTitleBetween(t,e){return this.filters.push({title:{$between:[t,e]}}),this}withTitleIsKnown(){return this.filters.push({title:{$isNull:!1}}),this}withTitleIsUnknown(){return this.filters.push({title:{$isNull:!0}}),this}withTitleNotContaining(t){return this.filters.push({title:{$notContains:t}}),this}withTitleStartingWith(t){return this.filters.push({title:{$startsWith:t}}),this}withTitleNotStartingWith(t){return this.filters.push({title:{$notStartsWith:t}}),this}withTitleEndingWith(t){return this.filters.push({title:{$endsWith:t}}),this}withTitleNotEndingWith(t){return this.filters.push({title:{$notEndsWith:t}}),this}withTitleSoundingLike(t){return this.filters.push({title:{$soundLike:t}}),this}withDescriptionContaining(t){return this.filters.push({description:{$contains:t}}),this}withDescriptionIs(t){return this.filters.push({description:{$eq:t}}),this}withDescriptionIsNot(t){return this.filters.push({description:{$ne:t}}),this}withDescriptionIn(...t){return this.filters.push({description:{$in:t}}),this}withDescriptionNotIn(...t){return this.filters.push({description:{$notIn:t}}),this}withDescriptionGreaterThan(t){return this.filters.push({description:{$gt:t}}),this}withDescriptionGreaterThanOrEqualTo(t){return this.filters.push({description:{$gte:t}}),this}withDescriptionLessThan(t){return this.filters.push({description:{$lt:t}}),this}withDescriptionLessThanOrEqualTo(t){return this.filters.push({description:{$lte:t}}),this}withDescriptionBetween(t,e){return this.filters.push({description:{$between:[t,e]}}),this}withDescriptionIsKnown(){return this.filters.push({description:{$isNull:!1}}),this}withDescriptionIsUnknown(){return this.filters.push({description:{$isNull:!0}}),this}withDescriptionNotContaining(t){return this.filters.push({description:{$notContains:t}}),this}withDescriptionStartingWith(t){return this.filters.push({description:{$startsWith:t}}),this}withDescriptionNotStartingWith(t){return this.filters.push({description:{$notStartsWith:t}}),this}withDescriptionEndingWith(t){return this.filters.push({description:{$endsWith:t}}),this}withDescriptionNotEndingWith(t){return this.filters.push({description:{$notEndsWith:t}}),this}withDescriptionSoundingLike(t){return this.filters.push({description:{$soundLike:t}}),this}filterByPlatform(t){return this.filters.push({platform:{$eq:t}}),this}filterByPlatformIn(...t){return this.filters.push({platform:{$in:t}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByTitleAscending(){return this.query.orderBy("title","asc"),this}orderByTitleDescending(){return this.query.orderBy("title","desc"),this}orderByDescriptionAscending(){return this.query.orderBy("description","asc"),this}orderByDescriptionDescending(){return this.query.orderBy("description","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByTitle(){return this.query.groupBy("title"),this}groupByTitleAs(t){return this.query.groupBy("title"),this}groupByDescription(){return this.query.groupBy("description"),this}groupByDescriptionAs(t){return this.query.groupBy("description"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(t){return this.query.groupBy("platform"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByPlatformAs(t,e,i=!0){return this.query.facetBy(t,"platform",e,i,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),i=await e.executeQuery(t.prepareQuery(this.query)),r=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=r?[]:i.map(n=>n instanceof m?n:m.fromRecord(n,new $)),a=new I(s);return r&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await C(e,n=>t.prepareQuery(n),this.query,this.query.facets)),a}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new I(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),i=t.prepareQuery(this.query),r=i.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=r?void 0:await e.executeCount(i,this._pageCountAlias,s),n=i.clone();n.aggregateItems=n.aggregateItems.filter(l=>!(String(l.function).toLowerCase()==="count"&&l.alias===this._pageCountAlias));const d=await e.executeQuery(n),u=r&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:a??await e.executeCount(i,this._pageCountAlias,s),h=new I(d.map(l=>l instanceof m?l:m.fromRecord(l,new $)));return h.totalCount=u,this._pageCountAlias!==void 0&&(h.aggregations[this._pageCountAlias]=u),this.query.facets.length>0&&(h.facets=await C(e,l=>t.prepareQuery(l),i,i.facets)),h}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=t.requireResource("dataService"),r=t.prepareQuery(this.query),s=i.executeForStream(r,e);return(async function*(){for await(const a of s)for(const n of a)yield n instanceof m?n:m.fromRecord(n,new $)})()}ensureIntent(){new K(this._comment,this._purpose)}}class Z{constructor(t,e,i,r,s,a){this.execute=t,this.executeRows=e,this.stream=i,this.limitOne=r,this.addComment=s,this.ensureIntent=a}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new m}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class R{static platforms(){return new A(!1)}static platformsWithMinimalFields(){return new A(!0)}static workItems(){return new x(!1)}static workItemsWithMinimalFields(){return new x(!0)}}const tt={Platform:{table:"platform_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}};async function et(o){let t=(await R.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(o))[0];t||(t=y.teaqlBootstrapNew("1"),t.updateName("Runtime Example"),await t.auditAs("create generated Domain Root Platform").save(o)),o.withActiveRoot({entity:"Platform",id:t.id})}const it=new U(tt,{Platform:{checkAndFix(o,t,e){o.getResource("fixTime"),(t.action==="Create"&&t.payload.name===void 0||t.payload.name===null)&&e.push({ruleId:"required",location:g.property("name")}),t.payload.name!=null&&[...String(t.payload.name)].length>100&&e.push({ruleId:"max_length",location:g.property("name"),inputValue:t.payload.name,systemValue:100})}},WorkItem:{checkAndFix(o,t,e){o.getResource("fixTime"),(t.action==="Create"&&t.payload.title===void 0||t.payload.title===null)&&e.push({ruleId:"required",location:g.property("title")}),t.payload.title!=null&&!([...String(t.payload.title)].length>=1)&&e.push({ruleId:"min_length",location:g.property("title"),inputValue:t.payload.title,systemValue:1}),t.payload.title!=null&&[...String(t.payload.title)].length>80&&e.push({ruleId:"max_length",location:g.property("title"),inputValue:t.payload.title,systemValue:80}),t.payload.description!=null&&[...String(t.payload.description)].length>100&&e.push({ruleId:"max_length",location:g.property("description"),inputValue:t.payload.description,systemValue:100}),(t.action==="Create"&&t.payload.platform===void 0||t.payload.platform===null)&&e.push({ruleId:"required",location:g.property("platform")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Runtime Example"}},constants:[],ensure:et}),rt={Platform:{table:"platform_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}},F=document.querySelector("#status"),st=document.querySelector("#result"),T=document.querySelector("#persist"),E=document.querySelector("#reset");let b;const M=localStorage.getItem("teaql-browser-storage")==="opfs"?"opfs":"memory";T.checked=M==="opfs";async function nt(o){const t=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),e=await z.open(t,{...rt},{storage:o,databaseName:"teaql-browser-example.sqlite3"});e.install(it);const i=Object.freeze({policyId:"browser-demo-seed",version:"1",fingerprint:"sha256:browser-demo-seed-v1"}),r=new H().insertResource("dataService",e).withMutationPolicyRegistry(new J(()=>({identity:i,review:(s,a)=>a.operations.length>0?{verdict:"allow"}:{verdict:"deny",code:"EMPTY_GRAPH",message:"empty mutation graph"}}))).withMutationPolicyApprovalProvider(new Y(s=>({policy:s,approvedBy:"browser-demo-owner",approvedAt:new Date})));return e.setUserContext(r),await r.ensureSchema(),{client:e,context:r}}async function Q({context:o}){if(!(await R.workItemsWithMinimalFields().comment("what: detect existing browser demo records").purpose("why: keep generated mutation bootstrap idempotent").executeForList(o)).length)for(const e of["Evaluate semantic model","Generate typed library","Verify browser runtime"])await new m().updateTitle(e).updatePlatform("1").auditAs("seed deterministic browser demo data").save(o)}async function V(o){const t=await R.workItems().selectTitle().orderByIdAscending().limit(20).comment("what: load browser-local work items").purpose("why: prove the generated Q API runs without a backend").executeForList(o.context);st.textContent=JSON.stringify(t,null,2),F.textContent=`${o.client.storage.toUpperCase()} · ${t.length} rows · policy installed · ready`}async function j(o){F.textContent=`Opening ${o.toUpperCase()} SQLite/WASM…`;const t=b;b=void 0,await t?.client.close();const e=await nt(o);b=e,await Q(e),await V(e)}T.addEventListener("change",()=>{const o=T.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",o),j(o).catch(W)});E.addEventListener("click",async()=>{if(b){E.disabled=!0;try{await b.client.reset(b.context),await Q(b),await V(b)}catch(o){W(o)}finally{E.disabled=!1}}});function W(o){const t=o instanceof Error?o:new Error(String(o));F.textContent=`${t.name}: ${t.message}`}j(M).catch(W); diff --git a/dist/assets/dynamic-search-BBmdgl4H.js b/dist/assets/dynamic-search-BBmdgl4H.js new file mode 100644 index 0000000000000000000000000000000000000000..08ffb8822e2d0b40448ab09bc0b30e38c4ce5d16 --- /dev/null +++ b/dist/assets/dynamic-search-BBmdgl4H.js @@ -0,0 +1,8 @@ +(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))n(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const s of o.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&n(s)}).observe(document,{childList:!0,subtree:!0});function t(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(r){if(r.ep)return;r.ep=!0;const o=t(r);fetch(r.href,o)}})();const Ae=Object.freeze({success:()=>{},failure:()=>{}}),rt=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function st(i){const e={"teaql.operation.family":i.family,"teaql.operation.name":i.name};for(const[t,n]of Object.entries(i.attributes||{}))rt.has(t)||(e[t]=n);return Object.freeze({...i,attributes:Object.freeze(e)})}function N(i,e){if(!i)return Ae;try{const t=i.start(st(e));let n=!1;return{correlation:()=>{try{return t.correlation?.()}catch{return}},run:t.run?r=>t.run(r):r=>r(),success(r){if(!n){n=!0;try{t?.success(r)}catch{}}},failure(r){if(!n){n=!0;try{t?.failure(r)}catch{}}}}}catch{return Ae}}async function D(i,e,t,n){const r=N(i,e);try{const o=await(r.run?r.run(t):t());return r.success(n?.(o)),o}catch(o){throw r.failure(o),o}}class ot extends Error{constructor(e){super(`Check failed: ${e.map(t=>t.message??`${t.ruleId}:${t.location}`).join("; ")}`),this.violations=e,this.name="CheckException"}}const at="teaql.i18n/v1",ct="en",lt={en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}},ut={schema:at,defaultLocale:ct,locales:lt},ht=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"];class Oe extends Error{constructor(e){super(`Unsupported locale: ${e}`),this.localeCode=e}}const dt={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function Be(i){if(typeof i!="string"||!i.trim())throw new Oe(i);const e=i.trim().replace(/_/g,"-").toLowerCase(),t=ht.find(r=>r.toLowerCase()===e);if(t)return t;const n=dt[e];if(!n)throw new Oe(i);return n}const ce=class ce{constructor(e,t){if(this.data=e,this.fallback=t,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(Be)}message(e,t){return this.data.locales[e]?.messages[t]??this.fallback?.data.locales[e]?.messages[t]??this.data.locales.en?.messages[t]??this.fallback?.data.locales.en?.messages[t]??t}translate(e,t){const r={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,o=String(e.inputValue),s=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(t,r).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(o).split("{input_len}").join(String(s)),e}};ce.builtin=new ce(ut);let me=ce;const Qe=Symbol("teaql.context.schema-capability");function C(i){return Object.freeze(i.map(e=>Object.freeze({...e})))}class ft{#e;#t;constructor(e,t){this.#e=e,this.#t=Object.freeze({...t}),Object.freeze(this)}recover(){const e=[];let t=this;for(;t;)e.push(t.#t),t=t.#e;return C(e.reverse())}}function gt(i,e,t,n,r){const o=i?r:n;if(i&&(typeof o!="string"||new RegExp("^\\p{White_Space}*$","u").test(o)))return i;const s=String(t),a=/^(0|[1-9][0-9]*)$/.test(s)&&BigInt(s)<=18446744073709551615n?t:void 0;return new ft(i,{kind:"auditReason",name:e,entityId:a,detail:o})}const pt=new Set(["comment","purpose","auditReason"]),ue=i=>!new RegExp("^\\p{White_Space}*$","u").test(i);function ye(i,e,t){const n=s=>{for(let a=i.length-1;a>=0;a--)if(i[a].kind===s)return i[a].detail??""},r=["operation","provider","sql"].every(s=>i.some(a=>a.kind===s));let o;if(r)o=i.filter(s=>!pt.has(s.kind));else{const s=i.find(c=>ue(c.name))?.name??"unknown";let a=s;if(t!=="select")for(const c of i)c.kind==="entity"&&ue(c.name)&&(a=c.name);o=[{kind:"operation",name:s,detail:t==="select"?"query":"mutation"},{kind:t==="select"?"request":"entity",name:t==="select"?s:a,detail:""},...i.filter(c=>c.kind==="relation"),{kind:"provider",name:ue(e)?e:"unknown",detail:""},{kind:"sql",name:t,detail:""}]}return Object.freeze({tracePath:C(o),comment:n("comment"),purpose:n("purpose"),auditReason:n("auditReason")})}function ze(i,e,t){return C([{kind:"comment",name:i,detail:e},{kind:"purpose",name:i,detail:t}])}function mt(i,e,t,n){if(n&&!i.trim())throw new Error("Missing SQL template");let r=0;const o=new Set,s=u=>{if(u<0||u>=e.length)throw new Error("SQL bind count mismatch");return o.add(u),n?n(u):Ue(e[u],t)};let a="",c="sql";for(let u=0;u=0&&h=0&&ht.toString(16).padStart(2,"0")).join("")}'`:_(typeof i=="object"?JSON.stringify(i):String(i))}function _(i){return`'${i.replace(/'/g,"''")}'`}var yt={};const wt="TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS",bt="I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK",te="[REDACTED]",he="[REDACTED SQL; NOT REPLAYABLE]",St=`-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN +`;let Re=!1;function vt(i){const e=Array.from(i);return e.length<8||/^[0-9]+$/.test(i)?"*".repeat(e.length):e.slice(0,2).join("")+"*".repeat(e.length-4)+e.slice(-2).join("")}function Et(){const e=yt?.[wt]===bt;return e&&!Re&&(Re=!0,console.warn("TeaQL: sensitive plaintext logging enabled; application data may be written to disk. Authentication secrets remain redacted.")),e}function W(i){const e=i.toLowerCase().replace(/[^a-z0-9]/g,"");return["password","passwd","passphrase","privatekey","secret","accesstoken","refreshtoken","idtoken","apikey","authorization","credential","sessiontoken","magiclinktoken"].some(t=>e.includes(t))}function we(i){return Array.isArray(i)?i.some(we):i&&typeof i=="object"?Object.entries(i).some(([e,t])=>W(e)||we(t)):!1}function q(i){return i==null||i===""?[]:Array.isArray(i)?i.flatMap(q):i instanceof Date?[i.toISOString()]:typeof i=="object"?Object.values(i).flatMap(q):[String(i)]}function V(i,e){return[...new Set(e)].sort((t,n)=>n.length-t.length).reduce((t,n)=>t?.split(n).join(te),i)}const K=new WeakMap,be=new WeakMap,Ve=new WeakMap;function ke(i,e,t=[]){Ve.set(i,{bindings:e?R(e):void 0,intentValues:Object.freeze(t.map(G))})}function ie(i){const e=i.parameterLogPolicies,t=!!e&&e.length===i.parameters.length,n=W(i.parameterizedSQL)&&(i.sqlOrigin!=="generated"||!t);return i.parameters.map((r,o)=>{if(n||we(r))return"credential";const s=t?e[o]:void 0;return s==="plain"||s==="masked"||s==="credential"?s:"unknown"})}function Se(i,e){return i==="credential"||i==="unknown"||!e&&i!=="plain"}function Ce(i){if(!i)return[];const e=ie(i);return i.parameters.flatMap((t,n)=>Se(e[n],!1)?q(t):[])}function G(i){return i instanceof Date?new Date(i.getTime()):i instanceof Uint8Array?new Uint8Array(i):Array.isArray(i)?Object.freeze(i.map(G)):i&&typeof i=="object"?Object.freeze(Object.fromEntries(Object.entries(i).map(([e,t])=>[e,G(t)]))):i}function R(i,e){const t=e?[e,i]:[i];return Object.freeze({parameterizedSQL:"",sqlOrigin:"generated",parameters:Object.freeze(t.flatMap(n=>n.parameters.map(G))),parameterLogPolicies:Object.freeze(t.flatMap(ie))})}function ve(i){return i==null?null:Array.isArray(i)?i.map(ve):i&&typeof i=="object"&&"type"in i?ve(i.value):typeof i=="object"&&!(i instanceof Date)?te:vt(i instanceof Date?i.toISOString():String(i))}function Ke(i,e,t=[]){const n=Et()&&i.logMode!=="masked",r=K.get(i);if(r!==void 0&&(!r||n))return i;const o=be.get(i);if(!n&&o)return o;const s=ne(i,n,e,t);if(K.set(s,n),n){const a=ne(i,!1,e,t);K.set(a,!1),be.set(s,a)}return s}function It(i){const e=be.get(i);if(e)return e;if(K.get(i)===!1)return i;const t=ne(i,!1);return K.set(t,!1),t}function ne(i,e,t,n=[]){const r=Ve.get(i);r?.bindings&&(t=R(r.bindings,t)),r&&(n=[...n,...r.intentValues]);const o=i.parameterLogPolicies,s=!o||o.length===i.parameters.length,a=W(i.parameterizedSQL)&&(i.sqlOrigin!=="generated"||!o||!s),c=ie(i),u=c.map(w=>Se(w,e)),l=i.parameters.flatMap((w,v)=>u[v]?q(w):[]);if(t){const w=ie(t);l.push(...t.parameters.flatMap((v,I)=>Se(w[I],e)?q(v):[]))}const f=[...l,...n.flatMap(q)],g=!e&&i.logMode==="debug-plaintext"&&!t,h=w=>g&&w?te:V(w,f),p=i.parameters.map((w,v)=>u[v]?c[v]==="masked"?ve(w):te:G(w)),m=i.parameterizedSQL.replace(/\$[0-9]+|@p[0-9]+/gi,"?"),y=(!e||a)&&i.sqlOrigin!=="generated"&&/['"`$]|--|\/\*|\b\d+\b|:[A-Za-z_]/.test(m),d=i.databaseKind??"sqlite";let b=he,E=y?"untrusted-literal-sql":s?void 0:"policy-count-mismatch";if(!y&&s)try{b=mt(i.parameterizedSQL,p,d,w=>Ue(p[w],d)+(u[w]?" /* masked */":"")),b=(e?u.some(Boolean)?`-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN; PARTIALLY MASKED; NOT REPLAYABLE +`:St:`-- TeaQL MASKED; NOT REPLAYABLE +`)+b}catch{b=he,E="unsupported-or-mismatched-bindings"}return Object.freeze({...i,...i.statements?{statements:Object.freeze(i.statements.map(w=>ne(w,e,R(i,t),n)))}:{},parameterizedSQL:y?he:i.sqlOrigin==="generated"?i.parameterizedSQL:V(i.parameterizedSQL,l),parameters:Object.freeze(p),parameterLogPolicies:Object.freeze(c),maskedParameters:Object.freeze(u),logMode:e?"debug-plaintext":"masked",omissionReason:E,debugSQL:b,comment:h(i.comment),purpose:h(i.purpose),auditReason:h(i.auditReason),...i.traceChain?{traceChain:Object.freeze(i.traceChain.map(w=>Object.freeze(Object.fromEntries(Object.entries(w).map(([v,I])=>[v,v!=="entityId"&&typeof I=="string"?h(I):I])))))}:{},resultSummary:i.resultCount!==void 0?`${i.resultCount} rows returned`:i.affectedRows!==void 0?`${i.affectedRows} rows affected`:V(i.resultSummary,l),tracePath:Object.freeze(i.tracePath.map(w=>Object.freeze(Object.fromEntries(Object.entries(w).map(([v,I])=>[v,v!=="entityId"&&typeof I=="string"?h(I):I]))))),...i.traceChain?{traceChain:Object.freeze(i.traceChain.map(w=>Object.freeze(Object.fromEntries(Object.entries(w).map(([v,I])=>[v,v!=="entityId"&&typeof I=="string"?h(I):I])))))}:{},...i.mutationLineage?{mutationLineage:Object.freeze(i.mutationLineage.map(w=>Object.freeze(Object.fromEntries(Object.entries(w).map(([v,I])=>[v,v!=="entityId"&&typeof I=="string"?h(I):I])))))}:{}})}const H=new WeakMap,re=new WeakMap;function _e(i){return re.get(i)}function Lt(i,e){re.set(i,e)}function $t(i){return H.get(i)}function Q(i,e){H.set(e,H.get(i)??M(i))}function M(i,e=new Map){if(!i||typeof i!="object")return i;if(e.has(i))return e.get(i);if(i instanceof Date)return new Date(i.getTime());if(i instanceof Uint8Array)return new Uint8Array(i);const t=Array.isArray(i)?[]:Object.create(Object.getPrototypeOf(i));e.set(i,t);for(const o of Reflect.ownKeys(i)){const s=Object.getOwnPropertyDescriptor(i,o);"value"in s&&s.enumerable&&(s.value=M(s.value,e)),Object.defineProperty(t,o,s)}const n=H.get(i);n&&H.set(t,n);const r=re.get(i);return r&&re.set(t,r),t}const X=new WeakMap;class Le{#e;constructor(e={}){this.#e=M(e),Object.freeze(this)}values(){return M(this.#e)}static captureFor(e,t){const n=new Le(t);return X.set(e,n),n}static forEntity(e){return X.get(e)}static restoreFor(e,t){t?X.set(e,t):X.delete(e)}}const Pe=new WeakMap,de=new WeakMap,Ee=new WeakMap,We=new WeakMap;function Ge(i){if(!["named-count","facet","relation-count","relation-select","aggregate","pagination"].includes(i.kind)||i.method!==void 0&&!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i.method)||i.alias!==void 0&&typeof i.alias!="string"||i.relation!==void 0&&typeof i.relation!="string")throw new Error("QUERY_OPERATION_INVALID: invalid generated operation descriptor");return Object.freeze({kind:i.kind,method:i.method,alias:i.alias,relation:i.relation})}function Tt(i){const e=Ge(i),t=n=>"'"+n.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+"'";return e.method?e.method+"("+(e.alias!==void 0?t(e.alias):e.kind==="relation-select"?"...":"")+")":"framework: "+e.kind+(e.relation?" "+e.relation:"")+(e.alias!==void 0?" "+t(e.alias):"")}const F=Symbol("runtime request binding");class At extends Error{constructor(e,t,n){super(`${e}: ${n} request requires a non-blank ${t}; supply it at the request entry point`),this.code=e,this.field=t,this.requestKind=n,this.name="RequestIntentError"}}function B(i,e,t){if(typeof i!="string"||new RegExp("^\\p{White_Space}*$","u").test(i))throw new At(e==="comment"?"REQUEST_COMMENT_REQUIRED":"QUERY_PURPOSE_REQUIRED",e,t);return i}class se{#e;#t;constructor(e,t){this.#e=B(e,"comment","query"),this.#t=B(t,"purpose","query"),Object.freeze(this)}get comment(){return this.#e}get purpose(){return this.#t}}class z{#e;constructor(e){this.#e=B(e,"comment","mutation"),Object.freeze(this)}get comment(){return this.#e}get auditReason(){return this.#e}readbackIntent(){return new se(this.#e,"verify persisted mutation result")}}class L{#e;#t;#n;#r;#s;#o;#i;constructor(e,t,n){const r=e,o=_e(e),s=o instanceof L?o:void 0;if(this.#e=t===void 0?s?.intent??new se(r?._comment??r?.commentText,r?._purpose??r?.purposeText):new se(t?.comment,t?.purpose),n&&n[F]!==!0)throw new Error("QUERY_REQUEST_OWNERSHIP_INVALID: request binding is runtime-owned");const a=s&&s.intent.comment===this.#e.comment&&s.purpose===this.#e.purpose?s:void 0;this.#i=n?.invocation??(n?.parent?n.parent.#i:void 0)??(a?a.#i:void 0)??Object.freeze({}),this.#n=n?n.parent:a?.parentRequest,this.#r=B(n?.comment??a?.comment??this.#e.comment,"comment","query"),this.#s=n?.name??a?.requestName??String(r.entity??"query"),this.#o=n?.operation??a?.operation,this.#t=M(e);const c=this.#t;for(const[u,l]of[["commentText",this.comment],["purposeText",this.purpose],["_comment",this.comment],["_purpose",this.purpose]])Object.defineProperty(c,u,{value:l,enumerable:!u.startsWith("_"),configurable:!0,writable:!1});de.set(c,C(n?.source??a?.traceSource??de.get(e)??ze(String(r.entity),this.intent.comment,this.purpose))),Lt(c,this),Object.freeze(this)}get intent(){return this.#e}get query(){return this.#t}get comment(){return this.#r}get purpose(){return this.#e.purpose}get traceSource(){return de.get(this.#t)}get parentRequest(){return this.#n}get rootRequest(){let e=this;for(;e.parentRequest;)e=e.parentRequest;return e}get requestName(){return this.#s}get operation(){return this.#o}get traceChain(){const e=[];for(let t=this;t;t=t.parentRequest)e.push({kind:"comment",name:t.requestName,detail:t.comment});return C([{kind:"purpose",name:this.rootRequest.requestName,detail:this.purpose},...e.reverse()])}withQuery(e){const t=_e(e);if(t instanceof L&&t.#i!==this.#i)throw new Error("QUERY_SCOPE_OWNER_MISMATCH: replacement belongs to another query invocation");return new L(e,this.intent,{[F]:!0,parent:this.parentRequest,comment:this.comment,name:this.requestName,operation:this.operation,source:this.traceSource,invocation:this.#i})}deriveOperation(e,t){const n=Ge(t);return new L(e,this.intent,{[F]:!0,parent:this,comment:Tt(n),name:String(e.entity??this.requestName),operation:n,source:this.traceSource})}deriveHelper(e,t){return new L(e,this.intent,{[F]:!0,parent:this,comment:B(t,"comment","query"),name:String(e.entity??this.requestName),source:this.traceSource})}derive(e,t,n){if(n)return this.deriveOperation(this.query,n).deriveChild(e,t);const r=`${String(this.query.entity)}.${t}`;return this.deriveChild(e,t,void 0,r)}deriveAggregate(e,t,n){const r=this.parentRequest?.operation?.kind==="facet"?this.parentRequest:void 0,o=r?r.deriveHelper(e,"aggregate "+r.operation.relation):this.deriveOperation(e,n),s=[...this.traceSource,{kind:"relation",name:t,detail:`${String(this.query.entity)}.${t}`}],a=new L(e,this.intent,{[F]:!0,parent:o.parentRequest,comment:o.comment,name:o.requestName,operation:o.operation,source:s});return(e._comment??e.commentText)===void 0?a:a.deriveChild(e)}deriveChild(e,t,n,r){const o=e,s=o._comment??o.commentText;return new L(e,this.intent,{[F]:!0,parent:this,comment:s===void 0?n??`load ${String(o.entity)}`:B(s,"comment","query"),name:r??String(o.entity),source:t===void 0?this.traceSource:[...this.traceSource,{kind:"relation",name:t,detail:`${String(this.query.entity)}.${t}`}]})}}class x{#e;#t;constructor(e,t){this.#e=new z(t===void 0?e?.comment:t?.comment),this.#t={...e},Object.defineProperty(this.#t,"comment",{value:this.#e.comment,enumerable:!0,writable:!1,configurable:!1}),Object.freeze(this)}get intent(){return this.#e}get mutation(){return this.#t}get comment(){return this.#e.comment}withLoadedSnapshot(e){return Pe.set(this,new Le(e.values())),this}loadedValues(){return Pe.get(this)?.values()??{}}get graphSession(){return Ee.get(this)?.session}scopeFor(e){const t=Ee.get(this),n=gt(t?.parent,e.entity,e.id,this.comment,t?.localComment);return t&&We.set(n,t.session),n}traceFor(e){const t=this.#t,n=t.ledgerRoot?.traceChain(t.ledgerKey??e);return n?.length?C(n):this.scopeFor(e).recover()}auditProjection(e,t,n){const r=[...q(t),...q(this.#t.id),...n?Ce(n):q(this.loadedValues()),...Ce(this.graphSession?.logBindings)];return Object.freeze({reason:V(this.comment,r),mutationLineage:C(this.traceFor(e).map(o=>({...o,detail:V(o.detail,r)})))})}}class Ot{#e;#t;constructor(e){this.#e=new z(e?.comment),Object.freeze(this)}get intent(){return this.#e}request(e,t,n){if(t&&We.get(t)!==this)throw new Error("GRAPH_TRACE_SCOPE_MISMATCH: parent scope belongs to another graph invocation");const r=new x(e,this.#e);return Ee.set(r,{session:this,parent:t,localComment:n}),r}captureLogBindings(e){this.#t=R(e,this.#t)}get logBindings(){return this.#t}}class qe extends Error{constructor(e){super("GRAPH_ALREADY_COMMITTED: post-commit processing failed; do not retry as an uncommitted mutation"),this.cause=e,this.committed=!0,this.name="GraphCommittedError"}}const Rt="MUTATION-POLICY-001",kt="MUTATION-POLICY-002";class k extends Error{constructor(e){super(e),this.name="MutationPolicyError"}}class ci{constructor(e){this.resolver=e}resolve(e){return this.resolver(e)}}class li{constructor(e){this.finder=e}findApproval(e){return this.finder(e)}}class Ct{onWarning(e,t){!t.firstOccurrence||typeof console>"u"||console.warn(`TeaQL mutation policy warning code=${t.warningCode} requestKey=${t.snapshot.requestKey} source=${t.snapshot.source} approval=${t.snapshot.approvalStatus}`)}}let Ne=0;class _t{constructor(){this.profile={warningSink:new Ct},this.emittedWarnings=new Set,this.graphActive=!1,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.remaining=new Map}setRegistry(e){this.profile.registry=e}setApprovalProvider(e){this.profile.approvalProvider=e}setWarningSink(e){this.profile.warningSink=e}beginGraph(){if(this.graphActive)throw new k("mutation policy graph is already active");this.graphActive=!0,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.rootEntity=void 0,this.auditReason=void 0,this.remaining.clear(),this.graphSnapshot=void 0}endGraph(){this.graphActive=!1,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.rootEntity=void 0,this.auditReason=void 0,this.remaining.clear(),this.graphSnapshot=void 0}recordPreflight(e){if(!this.graphActive)return;if(this.graphReviewed)throw new k("mutation preflight cannot change after policy review");const t=xe(e);this.rootEntity??=t.entity,this.auditReason??=J(e),this.preflight.push(t),this.preflightKeys.push(Me(e,t))}enterMutation(e,t){const n=xe(t);if(!this.graphActive)return{snapshot:this.review(e,this.plan(n.entity,J(t),[n]))};if(!this.graphReviewed){if(this.profile.registry&&this.preflight.length===0)throw new k("customer mutation policy requires complete graph preflight before provider mutation");if(!this.profile.registry&&this.preflight.length===0)return{snapshot:this.review(e,this.plan(n.entity,J(t),[n]))};const r=this.preflight.length?this.preflight:[n];this.graphSnapshot=this.review(e,this.plan(this.rootEntity??r[0].entity,this.auditReason??J(t),r)),this.remaining.clear();const o=this.preflight.length?this.preflightKeys:r.map(Ye);for(const s of o)this.remaining.set(s,(this.remaining.get(s)??0)+1);this.graphReviewed=!0}return this.consume(Me(t,n)),{snapshot:this.graphSnapshot}}ensureGraphComplete(){if(this.graphReviewed&&this.remaining.size)throw new k("reviewed mutation plan contains operations that were not executed")}review(e,t){Pt(t);const n=je(t),r=this.profile.registry?.resolve(n.requestKey);let o,s,a,c;if(!r)o="generated_default",a="not_applicable",c=[Rt];else{s=qt(r.identity);const l=r.review(e,n);if(!l||l.verdict!=="allow"&&l.verdict!=="deny")throw new k("customer mutation policy returned an invalid decision");if(l.verdict==="deny")throw new k(`[MUTATION POLICY DENIED] ${l.code||"MUTATION-POLICY-DENIED"}: ${l.message||"mutation rejected"}`);o="customer";const f=this.profile.approvalProvider?.findApproval(s);a=Nt(f,s)?"approved":"missing",c=a==="approved"?[]:[kt]}const u=Object.freeze({executionId:n.executionId,requestKey:n.requestKey,source:o,policy:s,approvalStatus:a,warningCodes:Object.freeze([...c]),operations:Object.freeze(n.operations.map(l=>Object.freeze({kind:l.kind,entity:l.entity,entityId:j(l.entityId),changedFields:Object.freeze(Object.keys(l.changedValues).sort())})))});for(const l of c)this.emitWarning(e,u,l);return u}plan(e,t,n){return Ne+=1,je({executionId:`teaql-mutation-${Ne}`,requestKey:`${e}.saveGraph`,rootEntityType:e,auditReason:new z(t).comment,operations:n})}consume(e){const t=this.remaining.get(e)??0;if(t<1)throw new k("provider mutation is not present in the reviewed graph plan");t===1?this.remaining.delete(e):this.remaining.set(e,t-1)}emitWarning(e,t,n){const r=t.policy?`${t.policy.policyId}:${t.policy.version}:${t.policy.fingerprint}`:"none",o=`${t.requestKey}|${r}|${n}`,s=!this.emittedWarnings.has(o);this.emittedWarnings.add(o);try{this.profile.warningSink.onWarning(e,Object.freeze({snapshot:t,warningCode:n,firstOccurrence:s}))}catch{}}}function xe(i){const e=String(i?.entity??"").trim(),t=String(i?.action??"").toLowerCase(),n={create:"create",update:"update",delete:"delete",recover:"recover"};if(!e||!n[t])throw new k("mutation must contain a supported entity operation");const r=i?.payload&&typeof i.payload=="object"?i.payload:{};return Object.freeze({kind:n[t],entity:e,entityId:j(i?.id??r.id),originalVersion:i?.version??i?.expectedVersion,changedValues:He(r)})}function J(i){return new z(i?.comment).comment}function Pt(i){if(new z(i?.auditReason),!i.executionId?.trim())throw new k("execution id is required");if(!i.requestKey?.trim())throw new k("request key is required");if(!i.rootEntityType?.trim())throw new k("root entity type is required");if(!i.operations.length)throw new k("mutation plan is empty")}function qt(i){if(!i||!i.policyId?.trim()||!i.version?.trim()||!i.fingerprint?.trim())throw new k("customer mutation policy identity is invalid");return Object.freeze({policyId:i.policyId.trim(),version:i.version.trim(),fingerprint:i.fingerprint.trim()})}function Nt(i,e){return!!i&&xt(i.policy,e)&&!!i.approvedBy?.trim()&&i.approvedAt instanceof Date&&Number.isFinite(i.approvedAt.getTime())&&i.approvedAt.getTime()!==0}function xt(i,e){return i.policyId===e.policyId&&i.version===e.version&&i.fingerprint===e.fingerprint}function je(i){return Object.freeze({executionId:i.executionId,requestKey:i.requestKey,rootEntityType:i.rootEntityType,auditReason:i.auditReason,operations:Object.freeze(i.operations.map(e=>Object.freeze({kind:e.kind,entity:e.entity,entityId:j(e.entityId),originalVersion:e.originalVersion,changedValues:He(e.changedValues)})))})}function j(i,e=new WeakSet){if(i==null||typeof i=="string"||typeof i=="number"||typeof i=="boolean"||typeof i=="bigint")return i;if(i instanceof Date)return i.toISOString();if(typeof i=="object"){if(e.has(i))throw new k("mutation policy values must not contain cycles");e.add(i);try{if(Array.isArray(i))return Object.freeze(i.map(n=>j(n,e)));const t=i;return"id"in t&&Object.keys(t).some(n=>n!=="id")?j(t.id,e):Object.freeze(Object.fromEntries(Object.entries(t).map(([n,r])=>[n,j(r,e)])))}finally{e.delete(i)}}return String(i)}function He(i){return Object.freeze(Object.fromEntries(Object.entries(i).map(([e,t])=>[e,j(t)])))}function Ye(i){return oe({kind:i.kind,entity:i.entity,entityId:i.entityId,originalVersion:i.originalVersion,changedValues:i.changedValues})}function Me(i,e){const t=i?.ledgerKey;return t&&typeof t=="object"&&String(t.entity??"").trim()&&t.id!==void 0&&t.id!==null?`ledger:${String(t.entity).trim()}:${oe(t.id)}`:`operation:${Ye(e)}`}function oe(i){return typeof i=="bigint"?JSON.stringify(`${i.toString()}n`):i===void 0?'""':i===null||typeof i!="object"?JSON.stringify(i):Array.isArray(i)?`[${i.map(oe).join(",")}]`:`{${Object.entries(i).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${oe(t)}`).join(",")}}`}const De=new WeakMap;let jt=1;function Mt(i){if(!i||typeof i!="object"&&typeof i!="function")return String(i);const e=i;let t=De.get(e);return t||(t=jt++,De.set(e,t)),String(t)}class Fe extends Error{constructor(e,t,n){super(`context root ${e}: expected ${t}`),this.reason=e,this.expectedType=t,this.activeRoot=n,this.name="ContextRootError"}}class Dt{constructor(){this.mutationPolicy=new _t,this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(e,t)=>this.getContinuousPageCursor(e,t),put:(e,t,n)=>this.putContinuousPageCursor(e,t,n),observe:(e,t)=>{this.continuousPagePlan=e,this.continuousPageCursorId=t}},this.idSetPaginationRuntime={owner:"",scope:"",get:e=>this.idSetStore().get(e),put:(e,t)=>this.idSetStore().put(e,t),build:(e,t)=>this.singleFlightIdSetBuild(e,t),observe:(e,t)=>{this.idSetPaginationPlan=e,this.idSetPaginationCount=t,this.idSetPaginationCountAccuracy=e==="ID_SET_BUILD"||e==="ID_SET_HIT"?"EXACT":e==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=me.builtin}async withQueryRequest(e,t){const n=this.requireResource("dataService");return n.withQueryRequest?n.withQueryRequest(e,t):t()}setLocaleCode(e){const t=Be(e);return this.locale=t,this}setLanguageCode(e){return this.setLocaleCode(e)}installI18nCatalog(e){if(!e)throw new Error("catalog is required");return this.i18nCatalog=e,this}installIdSetPaginationStore(e){if(!e)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",e)}translateCheckResults(e){return e.map(t=>this.i18nCatalog.translate(t,this.locale))}withMutationPolicyRegistry(e){if(!e||typeof e.resolve!="function")throw new TypeError("mutation policy registry must expose resolve(requestKey)");return this.mutationPolicy.setRegistry(e),this}withMutationPolicyApprovalProvider(e){if(!e||typeof e.findApproval!="function")throw new TypeError("mutation policy approval provider must expose findApproval(identity)");return this.mutationPolicy.setApprovalProvider(e),this}withMutationGovernanceSink(e){if(!e||typeof e.onWarning!="function")throw new TypeError("mutation governance sink must expose onWarning(context, warning)");return this.mutationPolicy.setWarningSink(e),this}reviewMutationPlan(e){return this.mutationPolicy.review(this,e)}beginMutationPolicyGraph(){this.mutationPolicy.beginGraph()}recordMutationPolicyPreflight(e){this.mutationPolicy.recordPreflight(e)}enterMutationPolicy(e){return this.mutationPolicy.enterMutation(this,e).snapshot}ensureMutationPolicyGraphComplete(){this.mutationPolicy.ensureGraphComplete()}endMutationPolicyGraph(){this.mutationPolicy.endGraph()}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(e){const t=String(e.sourceLabel||""),n=t.toLowerCase();if(!e.entityType||!e.modelPath||!t||n.includes("authorization")||n.includes("cookie")||n.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const r=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",r),r.push(Object.freeze({...e})),this}finishFixEvidence(){const e=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...e])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(e,t){return this.resources.set(e,t),this}getResource(e){return this.resources.get(e)}removeResource(e){return this.resources.delete(e),this}requireResource(e){const t=this.getResource(e);if(t===void 0)throw new Error(`Required UserContext resource is missing: ${e}`);return t}ensureSchema(){const e=this.requireResource("dataService"),t=e[Qe];if(!t)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return t.call(e,this)}withActiveRoot(e){if(!e||!e.entity||e.id===void 0||e.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...e}))}requireActiveRoot(e){const t=this.getResource("activeRoot");if(!t)throw new Fe("missing",e);if(t.entity!==e)throw new Fe("type_mismatch",e,t);return t}prepareQuery(e){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const t=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,t?`${t.entity}:${String(t.id)}`:"-",Mt(this.getResource("dataService"))].join("|"),e.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(e,t){const n=`${e}:${t}`,r=this.continuousPageCursors.get(n);if(r&&r.expiresAt<=Date.now()){this.continuousPageCursors.delete(n);return}return r}putContinuousPageCursor(e,t,n){if(this.continuousPageCursors.size>=4096){const r=[...this.continuousPageCursors.entries()].sort((o,s)=>o[1].expiresAt-s[1].expiresAt)[0];r&&this.continuousPageCursors.delete(r[0])}this.continuousPageCursors.set(`${e}:${t}`,n)}getRetainedIdSet(e){const t=this.retainedIdSets.get(e);if(t&&t.expiresAt<=Date.now()){this.retainedIdSets.delete(e);return}return t}idSetStore(){return this.getResource("idSetPaginationStore")??{get:e=>this.getRetainedIdSet(e),put:(e,t)=>this.putRetainedIdSet(e,t),invalidate:e=>{this.retainedIdSets.delete(e)}}}putRetainedIdSet(e,t){if(t.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const r=()=>[...this.retainedIdSets.values()].reduce((o,s)=>o+s.ids.byteLength,0);for(;this.retainedIdSets.size>=64||r()+t.ids.byteLength>268435456;){const o=[...this.retainedIdSets.entries()].sort((s,a)=>s[1].expiresAt-a[1].expiresAt)[0];if(!o)break;this.retainedIdSets.delete(o[0])}this.retainedIdSets.set(e,t)}async singleFlightIdSetBuild(e,t){const n=this.idSetBuilds.get(e);if(n)return{value:await n,built:!1};const r=t();this.idSetBuilds.set(e,r);try{return{value:await r,built:!0}}finally{this.idSetBuilds.delete(e)}}}function Xe(i,e){const t=i.defaultDomainRoot,n=e.defaultDomainRoot;if(t&&n&&(t.entity!==n.entity||t.id!==n.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const r=new Map;for(const o of[...i.constants??[],...e.constants??[]])r.set(`${o.entity}:${o.id}`,o);return{defaultDomainRoot:n??t,constants:[...r.values()],ensure:i.ensure&&e.ensure?async o=>{await i.ensure(o),await e.ensure(o)}:e.ensure??i.ensure}}class Je{constructor(e={},t={},n={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...t}),this.bootstrap=Object.freeze({defaultDomainRoot:n.defaultDomainRoot,constants:Object.freeze([...n.constants??[]]),ensure:n.ensure})}and(e){return new Je({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},Xe(this.bootstrap,e.bootstrap))}}class P{constructor(e,t,n){this.field=e,this.expr=t,this.direction=n}static new(e,t){return new P(e,null,t)}static expr(e,t){return new P("",e,t)}static asc(e){return P.new(e,"Asc")}static desc(e){return P.new(e,"Desc")}}class ae{constructor(e,t,n,r){this.enabledValue=e,this.cacheExpiredMillis=t,this.propagateValue=n,this.propagateCacheExpiredMillis=r}static enabled(e){return new ae(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}}let Ft=class Ze{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,t,n,r=!0,o){return this.facets.push({facetName:e,relationName:t,query:n.toQuery(),includeAllFacets:r,operation:o}),this}clone(){const e=M(this);for(const t of["commentText","purposeText","_comment","_purpose"]){const n=Object.getOwnPropertyDescriptor(e,t);n&&"value"in n&&n.configurable&&Object.defineProperty(e,t,{...n,writable:!0})}return e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,t){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:t},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,t,n){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(n)||n<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:t,maxIds:n},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const t=new Ze(this.entity);return t.filterCondition=M(this.filterCondition),t.commentText=this.commentText,t.purposeText=this.purposeText,t.aggregate("Count","id",e),Q(this,t),t}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const t of this.relations)t.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,t,n="id",r="id",o=!0,s){return this.relations.push({name:e,query:t,localKey:n,foreignKey:r,many:o,operation:s}),this}relationAggregate(e,t,n,r=!0,o){return this.relationAggregates.push({relationName:e,alias:t,query:n,singleResult:r,operation:o}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=ae.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=ae.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,t,n){return this.aggregateItems.push({function:e,field:t,alias:n}),this}groupBy(e){return this.groupByItems.push(e),this}};function Bt(i,e){if(i.logMode!=="masked")throw new Error("Telemetry requires safe SQL projection");const t=(n=[])=>JSON.stringify(n.map(r=>({kind:r.kind,name:r.name,detail:r.detail??""})));return Object.freeze({body:"TeaQL SQL execution",correlation:e,attributes:Object.freeze({"teaql.trace_chain":t(i.traceChain),"teaql.trace_path":t(i.tracePath),"teaql.mutation_lineage":t(i.mutationLineage),"teaql.intent.comment":i.comment??i.auditReason??"","teaql.intent.purpose":i.purpose??"","teaql.sql.debug":i.debugSQL,"teaql.sql.log_mode":i.logMode,"teaql.sql.operation":i.operation,"teaql.sql.outcome":i.executionOutcome??"unknown","teaql.sql.elapsed_us":i.elapsedMicros,...i.resultCount===void 0?{}:{"teaql.sql.result_count":i.resultCount},...i.affectedRows===void 0?{}:{"teaql.sql.affected_rows":i.affectedRows}})})}function fe(i,e=!1){try{e?console.warn(i):console.info(i)}catch{}}class Y extends Array{static get[Symbol.species](){return Array}constructor(e=[],t={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,Y.prototype),this.totalCount=t.totalCount,this.aggregations=t.aggregations??{},this.summary=t.summary??{},this.facets=t.facets??{},this.isLoaded=t.isLoaded??!0}static empty(){return new Y([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,t){return this.facets[e]=t,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}}function Qt(i){return i.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function Ie(i){if(i&&typeof i=="object"){const e=i;return e.id??e.Id}return i}function zt(i,e){const t=Qt(e);for(const n of[e,`${e}Id`,t,`${t}_id`]){const r=Ie(i[n]);if(r!=null)return r}}function Ut(i){const e=i.function.toLowerCase();return e==="count"||e==="sum"?0:null}function Vt(i,e){return typeof i=="number"&&typeof e=="number"?i-e:i instanceof Date&&e instanceof Date?i.getTime()-e.getTime():String(i).localeCompare(String(e))}async function Kt(i,e,t,n,r,o){const s=n.clone();s.facets=[],s.relations=[],s.relationAggregates=[],s.orderItems=[],s.aggregateItems=[],s.groupByItems=[],s.offsetValue=0,s.limitValue=0,s.selectItems=[...new Set([r,...o.map(l=>l.field)])],s.comment(`aggregate ${r}`),Q(n,s);const a=await i.executeQuery(t.deriveHelper(e(s),`aggregate ${r}`).query),c=new Map,u=new Map;for(const l of a){const f=zt(l,r);if(f==null)continue;const g=String(f),h=c.get(g)??{},p=u.get(g)??{};for(const m of o){const y=m.function.toLowerCase(),d=l[m.field];if(y==="count")d!=null&&(h[m.alias]=Number(h[m.alias]??0)+1);else if(y==="sum"||y==="avg"){if(d!=null){const b=Number(d);if(!Number.isFinite(b))throw new Error(`Facet aggregate ${m.alias} requires numeric values`);h[m.alias]=Number(h[m.alias]??0)+b,y==="avg"&&(p[m.alias]=(p[m.alias]??0)+1)}}else if(y==="min"||y==="max"){if(d!=null){const b=h[m.alias],E=b==null?0:Vt(d,b);(b==null||y==="min"&&E<0||y==="max"&&E>0)&&(h[m.alias]=d)}}else throw new Error(`Unsupported facet aggregate: ${m.function}`)}c.set(g,h),u.set(g,p)}for(const[l,f]of c){const g=u.get(l)??{};for(const h of o){if(h.function.toLowerCase()!=="avg")continue;const p=g[h.alias]??0;f[h.alias]=p?Number(f[h.alias]??0)/p:null}}return c}async function et(i,e,t,n){const r=new L(t);t=r.query;const o={};for(const s of n){const a=r.deriveOperation(t,s.operation??{kind:"facet",relation:s.relationName,alias:s.facetName}),c=a.deriveChild(s.query.clone(),s.relationName),u=c.query,l=u.facets;u.facets=[];const f=u.aggregateItems.map(d=>({function:String(d.function),field:String(d.field),alias:String(d.alias)})),g=f.length?f:[{function:"Count",field:"id",alias:"__teaql_facet_membership_count"}];let h;if(i.executeFacetAggregates)h=await i.executeFacetAggregates(a.deriveHelper(e(t.clone()),`aggregate ${s.relationName}`).query,s.relationName,g);else if(i.executeFacetMembership&&g.every(d=>d.function.toLowerCase()==="count")){const d=await i.executeFacetMembership(a.deriveHelper(e(t.clone()),`aggregate ${s.relationName}`).query,s.relationName);h=new Map([...d].map(([b,E])=>[b,Object.fromEntries(g.map(S=>[S.alias,E]))]))}else h=await Kt(i,e,a,t,s.relationName,g);u.aggregateItems=[],u.groupByItems=[];for(const d of u.relationAggregates){if(d.query.entity!==t.entity)continue;const b=t.clone();b.selectItems=["id"],b.properties=[],b.relations=[],b.relationAggregates=[],b.facets=[],b.aggregateItems=[],b.groupByItems=[],b.orderItems=[],b.offsetValue=0,b.limitValue=0;const E={id:{$inSubquery:{query:b,field:"id"}}};d.query.filterCondition=d.query.filterCondition?{$and:[d.query.filterCondition,E]}:E,Q(t,d.query)}if(!s.includeAllFacets){const d={id:{$in:[...h.keys()]}};u.filterCondition=u.filterCondition?{$and:[u.filterCondition,d]}:d}Q(t,u);const m=(await i.executeQuery(c.withQuery(e(u)).query)).map(d=>{const b=String(Ie(d.id??d.Id)),E=h.get(b),S={...d};for(const w of f)S[w.alias]=E?.[w.alias]??Ut(w);return S}).filter(d=>s.includeAllFacets||h.has(String(Ie(d.id??d.Id)))),y=new Y(m);l.length&&(y.facets=await et(i,e,c.withQuery(u).query,l)),o[s.facetName]=y}return o}function Wt(i){const e=new Map;for(const t of Object.values(i))for(const n of Object.values(t.relations||{})){if(!n.many)continue;const r=i[n.targetEntity],o=r?.columns[n.foreignKey]?.columnName,s=r?.columns.id?.columnName;if(!r||!o||!s)continue;const a=`idx_${r.table}_${o}_${s}`;let c=2166136261;for(let f=0;f>>0).toString(36),l=a.length<=30?a:`${a.slice(0,Math.max(1,29-u.length))}_${u}`;e.set(l,{name:l,table:r.table,foreignColumn:o,idColumn:s})}return[...e.values()]}async function Gt(i,e,t,n){const r=Number(n);if(!Number.isSafeInteger(r)||r<0)throw new Error(`Invalid ID space floor ${n} for ${t}`);for(let o=1;o<=100;o+=1){const s=await i.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[t]);if(!s.rowCount){try{if((await i.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[t,r])).rowCount===1)return}catch(u){if(!(await i.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[t])).rowCount)throw u}continue}const a=Number(s.rows[0].id);if(a>=r)return;const c=await i.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[r,t,a]);if(c.rowCount===1)return;if(c.rowCount!==0)throw new Error(`ID space floor update for ${t} changed ${c.rowCount} rows on attempt ${o}`)}throw new Error(`Unable to synchronize ID space floor for ${t} after 100 optimistic-lock attempts`)}function Ht(i,e){return i===e?!0:(i instanceof Date&&(i=i.getTime()),e instanceof Date&&(e=e.getTime()),i!=null&&e!==null&&e!==void 0&&String(i)===String(e))}function ee(i){return Object.freeze(i.map((e,t)=>Object.freeze({...e,level:t})))}function ge(i,e,t,n,r,o){const s=i.traceFor({entity:String(e.entity),id:r}),a=ye([...s,{kind:"entity",name:String(e.entity),entityId:r,detail:""}],t,n);return{auditReason:i.comment,tracePath:ee(a.tracePath),mutationLineage:s,targetID:r,inheritedBindings:R(o,i.graphSession?.logBindings)}}class Yt{constructor(e=t=>console.debug(t)){this.writer=e}write(e){e=Ke(e),this.writer(`[TeaQL SQL][${e.operation}][${e.elapsedMicros}us] ${e.resultSummary}${e.executionOutcome?` outcome=${e.executionOutcome}`:""} +comment=${e.comment??""} purpose=${e.purpose??""} auditReason=${e.auditReason??""} tracePath=${pe(e.tracePath)} traceChain=${pe(e.traceChain??[])} mutationLineage=${pe(e.mutationLineage??[])} +`+(e.omissionReason?`SQL omitted: ${e.omissionReason} +`:"")+`Debug SQL: ${e.debugSQL}`)}}function pe(i){return JSON.stringify(i,(e,t)=>typeof t=="bigint"?t.toString():t)}class ui{constructor(){this.mode="all",this.entries=[]}record(e){const t=e.operation==="select";this.mode==="disabled"||this.mode==="select"&&!t||this.mode==="mutation"&&t||this.entries.push(Object.freeze({...e,...e.traceChain?{traceChain:C(e.traceChain)}:{},parameters:Object.freeze([...e.parameters])}))}setMode(e){return this.mode=e,this.entries=[],this}enableAll(){return this.setMode("all")}enableSelect(){return this.setMode("select")}enableMutation(){return this.setMode("mutation")}disable(){return this.setMode("disabled")}snapshot(){return[...this.entries]}}class Xt{constructor(e,t){this.driver=e,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.bindLogPolicies=new WeakMap,this.bindOperandSources=new WeakMap,this.derivedQueryBindings=new WeakMap,this.derivedRelationAssembly=new WeakMap,this.auditEvents=[],this.diagnosticSQLLogSink=new Yt,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.customTelemetry=!1,this.checkers={},this.userContext=new Dt,this.bootstrap={},this.graphAuditActions=[],this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve(),this.schemas={...t}}fieldLogPolicy(e,t){const n=e.columns[t],r=n?.modelName??n?.columnName??t;return W(r)||W(t)?"credential":e.auditMaskFields?e.auditMaskFields?.includes(r)||e.auditMaskFields?.includes(t)?"masked":n?.logPolicy??"unknown":"unknown"}bindValue(e,t,n,r){const o=this.bindLogPolicies.get(e)??e.map(()=>"unknown");e.push(t),o.push(n),this.bindLogPolicies.set(e,o),r!==void 0&&this.bindOperandSources.set(e,R({parameterizedSQL:"",parameters:[r],parameterLogPolicies:[n],sqlOrigin:"generated"},this.bindOperandSources.get(e)))}queryLogBindings(e,t){return R({parameterizedSQL:e,parameters:t,parameterLogPolicies:this.bindLogPolicies.get(t),sqlOrigin:"generated"},this.bindOperandSources.get(t))}install(e){return Object.assign(this.schemas,e.schemas),Object.assign(this.checkers,e.checkers),this.bootstrap=Xe(this.bootstrap,e.bootstrap),this}setUserContext(e){return this.userContext=e,this}schema(e){const t=this.schemas[e];if(!t)throw new Error(`Unknown TeaQL entity: ${e}`);return t}toRuntimeMutationRecord(e,t){const n={};for(const[r,o]of Object.entries(t)){const s=e.columns[r]?r:Object.keys(e.columns).find(a=>e.columns[a].modelName===r||e.columns[a].columnName===r);s&&(n[s]=o)}return n}encode(e,t){const n=e?.id??e;if(n!==void 0)return this.driver.encode(n,t)}decodeRow(e,t,n=[]){const r=this.schema(e),o={...t};for(const[s,a]of Object.entries(r.columns)){const c=o[s];c!=null&&(a.decode==="number"&&(o[s]=Number(c)),a.decode==="string"&&(o[s]=String(c)),a.decode==="date"&&c instanceof Date&&(o[s]=c.toISOString()),a.logicalType==="boolean"&&(o[s]=!!c))}for(const s of n)o[s]!==null&&o[s]!==void 0&&(o[s]=Number(o[s]));return o}get auditTrace(){return[...this.auditEvents]}setAuditSink(e){return this.auditSink=e,this}setRuntimeTelemetrySink(e){return this.telemetrySink=e,this}setDiagnosticSQLLogSink(e){return this.diagnosticSQLLogSink=e,this}setQueryLoggingEnabled(e){return this.queryLoggingEnabled=e,this}setMutationLoggingEnabled(e){return this.mutationLoggingEnabled=e,this}setRuntimeTelemetry(e){return this.customTelemetry=!0,this.runtimeTelemetry=e,this}attachStandardTelemetryStartup(e){this.telemetryStartup=e.then(async t=>{if(t){if(this.customTelemetry){await t.release();return}this.standardTelemetryHandle=t,this.runtimeTelemetry=t.telemetry}}).catch(()=>{fe("TeaQL telemetry: initialization failed; business continues without export.",!0)})}async flushTelemetry(){await this.telemetryStartup;try{await this.standardTelemetryHandle?.flush()}catch{fe("TeaQL telemetry: export flush failed; business outcome unchanged.",!0)}}async withQueryRequest(e,t){return new L(e),await this.telemetryStartup,D(this.runtimeTelemetry,{family:"query",name:`${String(e.entity)}.request`,attributes:{"teaql.entity.type":String(e.entity)}},t)}recordSQL(e,t,n,r,o,s,a={},c="success",u,l){const g=e==="select"?this.queryLoggingEnabled:this.mutationLoggingEnabled,{targetID:h,inheritedBindings:p,...m}=a,y=Object.freeze({operation:e,...m,executionOutcome:c,traceChain:C(a.traceChain??[]),tracePath:ee(a.tracePath??[]),...a.traceChain?{traceChain:C(a.traceChain)}:{},...a.mutationLineage?{mutationLineage:C(a.mutationLineage)}:{},parameterizedSQL:t,parameters:Object.freeze([...n]),debugSQL:"",databaseKind:this.driver.databaseKind,sqlOrigin:"generated",parameterLogPolicies:Object.freeze([...this.bindLogPolicies.get(n)??n.map(()=>"unknown")]),elapsedMicros:Math.max(0,(Date.now()-r)*1e3),resultCount:o,affectedRows:s,resultSummary:o!==void 0?`${o} rows returned`:s!==void 0?`${s} rows affected`:`statement ${c}; row count unknown`}),d=p&&u?R(u,p):p??u,b=this.bindOperandSources.get(n),E=b?R(b,d):d;if(ke(y,E,h===void 0?[]:[h]),this.runtimeTelemetry?.recordDiagnostic)try{this.runtimeTelemetry.recordsSQLDiagnostics?.()!==!1&&this.runtimeTelemetry.recordDiagnostic(Bt(It(y),l))}catch{fe("TeaQL telemetry: SQL diagnostic rejected; business outcome unchanged.",!0)}if(!this.telemetrySink&&!(g&&this.diagnosticSQLLogSink))return y;try{const S=Ke(y);try{this.telemetrySink?.record(S)}catch{}if(g)try{this.diagnosticSQLLogSink?.write(S)}catch{}}catch{}return y}queryLogIntent(e){const t=new L(e),n=ye(t.traceSource,this.driver.databaseKind,"select");return{comment:t.intent.comment,purpose:t.purpose,traceChain:t.traceChain,tracePath:ee(n.tracePath)}}async executeLoggedSQL(e,t,n,r,o,s,a){await this.telemetryStartup;const c=N(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.${e}`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":e==="select"?"query":e}}),u=c.correlation?.(),l=Date.now();let f;try{f=await(c.run?c.run(o):o())}catch(h){try{const p=this.recordSQL(e,t,n,l,void 0,void 0,r,"failure",s,u);a?.push(p)}finally{throw c.failure(h),h}}const g=this.recordSQL(e,t,n,l,e==="select"?f.rowCount:void 0,e==="select"?void 0:f.rowCount,r,"success",s,u);return a?.push(g),c.success({attributes:{"teaql.result.cardinality":f.rowCount}}),f}async[Qe](e){await this.telemetryStartup,this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const t=this.bootstrapTail;let n;this.bootstrapTail=new Promise(s=>{n=s}),await t,this.userContext=e;const r=e.getResource("bootstrapActor"),o=e.getResource("bootstrapCategory");e.insertResource("bootstrapActor","teaql-generated-bootstrap"),e.insertResource("bootstrapCategory","runtime-bootstrap");try{this.bootstrap.ensure?await this.bootstrap.ensure(e):await this.ensureBootstrapData()}finally{r===void 0?e.removeResource("bootstrapActor"):e.insertResource("bootstrapActor",r),o===void 0?e.removeResource("bootstrapCategory"):e.insertResource("bootstrapCategory",o),n()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const e=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];e.length&&await this.executeGraphSave(new z("reconcile model bootstrap data"),async t=>{const n=this.graphMutationSession,r=[];for(const o of e){const s=await this.planBootstrapMutation(n,o);s&&r.push({record:o,request:t.request(s)})}for(const{request:o}of r)this.preflightMutation(o);for(const{request:o}of r)await this.executeMutation(o);for(const o of e)await this.driver.ensureIdFloor(n,o.entity,o.id)})}async planBootstrapMutation(e,t){const n=this.schema(t.entity),r=Object.entries(t.values??{}).map(([g,h])=>{const p=n.columns[g];if(!p)throw new Error(`Unknown bootstrap field ${t.entity}.${g}`);return{column:p.columnName,value:this.driver.encode(h,p)}}),o=new Ft(t.entity).filter({id:{$eq:t.id}}).limit(1).comment("inspect model bootstrap record").purpose("ensure model-defined root and constants");o.prepareForList();const s=new L(o),a=`SELECT * FROM ${this.driver.identifier(n.table)} WHERE ${this.driver.identifier(n.columns.id?.columnName??"id")} = ${this.driver.placeholder(1)}`,c=[t.id];this.bindLogPolicies.set(c,[this.fieldLogPolicy(n,"id")]);const u=await this.executeLoggedSQL("select",a,c,this.queryLogIntent(s.query),()=>e.query(a,c));if(!u.rowCount)return{entity:t.entity,action:"Create",id:t.id,version:0,payload:{...t.values}};const l=u.rows[0];if(r.filter(g=>!Ht(l[g.column],g.value)).length)return{entity:t.entity,action:"Update",id:t.id,version:Number(l[n.columns.version?.columnName??"version"]),payload:{...this.decodeRowForSchema(n,l),...t.values}}}async executeGraphSave(e,t){const n=new Ot(e);await this.telemetryStartup;const r=async()=>{const o=this.graphSaveTail;let s;this.graphSaveTail=new Promise(l=>{s=l}),await o;let a=!1,c=!1,u=!1;try{this.graphCommitActions=[],this.graphRollbackActions=[],this.graphAuditActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence(),a=!0,this.userContext.beginMutationPolicyGraph(),c=!0;const l=await this.driver.transaction(async h=>{this.graphMutationSession=h,this.activeGraph=n;try{const p=await t(n);return this.userContext.ensureMutationPolicyGraphComplete(),p}finally{this.graphMutationSession=void 0,this.activeGraph=void 0}});u=!0;let f,g=!1;for(const h of[...this.graphCommitActions,...this.graphAuditActions])try{await h()}catch(p){g||(f=p),g=!0}if(g)throw new qe(f);return l}catch(l){if(!u)for(const f of[...this.graphRollbackActions].reverse())try{f()}catch{}throw l}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.graphAuditActions=[],c&&this.userContext.endMutationPolicyGraph(),this.userContext.removeResource("fixTime"),a&&this.userContext.finishFixEvidence(),s()}};return D(this.runtimeTelemetry,{family:"mutation",name:"graph.save",attributes:{"teaql.entity.type":"graph","teaql.mutation.kind":"graph"}},r)}afterGraphCommit(e){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(e)}afterGraphRollback(e){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(e)}requireGraphOwnership(e){if(e.graphSession!==this.activeGraph||this.graphMutationSession!==void 0&&e.graphSession===void 0)throw new Error("GRAPH_MUTATION_SESSION_REQUIRED: use the explicit active graph request capability")}async withMutationSession(e,t){return this.requireGraphOwnership(e),e.graphSession?t(this.graphMutationSession):this.driver.transaction(t)}preflightMutation(e){const t=e instanceof x?e:new x(e);if(this.requireGraphOwnership(t),e=this.checkAndFixMutation(t),t.graphSession){const n=this.schema(e.entity);t.graphSession.captureLogBindings(this.mutationLogBindings(t,e,n))}return this.userContext.recordMutationPolicyPreflight(e),e}mutationLogBindings(e,t,n){const r=o=>{const s=this.toRuntimeMutationRecord(n,o),a=Object.keys(s);return{parameterizedSQL:"",sqlOrigin:"generated",parameters:a.map(c=>s[c]),parameterLogPolicies:a.map(c=>this.fieldLogPolicy(n,c))}};return R(r(t.payload||{}),r(e.loadedValues()))}checkAndFixMutation(e){const t=e instanceof x?e:new x(e);this.requireGraphOwnership(t),e=t.mutation,e={...e,payload:{...e?.payload??{}}},Object.defineProperty(e,"comment",{value:t.comment,enumerable:!0});const n=this.checkers[String(e.entity)];if(!n)return e;const r=[],o=this.userContext.getResource("fixTime")===void 0;o&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(n.checkAndFix(this.userContext,e,r),e.ledgerKey&&e.ledgerRoot)for(const[s,a]of Object.entries(e.payload||{}))e.ledgerRoot.set(e.ledgerKey,s,a);if(this.userContext.translateCheckResults(r),r.length)throw new ot(r);return e}finally{o&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(e){await this.telemetryStartup;const t=e instanceof x?e:new x(e);this.requireGraphOwnership(t),e=t.mutation;const n=N(this.runtimeTelemetry,{family:"mutation",name:`${String(e?.entity||"unknown")}.${String(e?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(e?.entity||"unknown"),"teaql.mutation.kind":String(e?.action||"unknown").toLowerCase()}}),r=async()=>{try{e=this.checkAndFixMutation(t);const o=this.userContext.enterMutationPolicy(e),s=this.schema(e.entity),a=this.toRuntimeMutationRecord(s,e.payload||{}),c=this.mutationLogBindings(t,e,s),u=this.driver.identifier(s.table),l=[],f=await D(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(e.action).toLowerCase()}},()=>this.withMutationSession(t,async y=>{if(e.action==="Create"){const d=e.id?String(e.id):await this.driver.nextId(y,e.entity);e.id&&await this.driver.ensureIdFloor(y,e.entity,d);const b=Number(e.version||0)+1,E={...a,id:d,version:b},S=Object.keys(s.columns).filter($=>E[$]!==void 0),w=S.map($=>this.driver.identifier(s.columns[$].columnName)).join(", "),v=S.map(($,A)=>this.driver.placeholder(A+1)).join(", "),I=S.map($=>this.encode(E[$],s.columns[$]));this.bindLogPolicies.set(I,S.map($=>this.fieldLogPolicy(s,$)));const T=`INSERT INTO ${u} (${w}) VALUES (${v})`,O=ge(t,e,this.driver.databaseKind,"insert",d,c);return await this.executeLoggedSQL("insert",T,I,O,()=>y.query(T,I),void 0,l),{success:!0,id:d,version:b,persistedRecord:await this.readPersistedRecord(y,s,d,O,T,I,l)}}if(e.action==="Update"){const d=Object.keys(s.columns).filter($=>$!=="id"&&$!=="version"&&a[$]!==void 0),b=d.map($=>this.encode(a[$],s.columns[$]));this.bindLogPolicies.set(b,d.map($=>this.fieldLogPolicy(s,$)));const E=d.map(($,A)=>`${this.driver.identifier(s.columns[$].columnName)} = `+this.driver.placeholder(A+1)),S=this.driver.identifier("version");E.push(`${S} = ${S} + 1`),this.bindValue(b,String(e.id),this.fieldLogPolicy(s,"id"));const w=[`${this.driver.identifier("id")} = ${this.driver.placeholder(b.length)}`];e.version!==void 0&&e.version!==null&&(this.bindValue(b,Number(e.version),this.fieldLogPolicy(s,"version")),w.push(`${S} = ${this.driver.placeholder(b.length)}`));const v=`UPDATE ${u} SET ${E.join(", ")} WHERE ${w.join(" AND ")}`,I=ge(t,e,this.driver.databaseKind,"update",String(e.id),c);if((await this.executeLoggedSQL("update",v,b,I,()=>y.query(v,b),void 0,l)).rowCount!==1)throw new Error(`Optimistic lock failed or ${e.entity}(${e.id}) does not exist`);const O=await this.readPersistedRecord(y,s,String(e.id),I,v,b,l);return{success:!0,id:String(e.id),version:Number(O.version),persistedRecord:O}}if(e.action==="Delete"){const d=this.driver.identifier("version"),b=[String(e.id)];this.bindLogPolicies.set(b,[this.fieldLogPolicy(s,"id")]);const E=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];e.version!==void 0&&e.version!==null&&(this.bindValue(b,Number(e.version),this.fieldLogPolicy(s,"version")),E.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(b.length)));const S=`UPDATE ${u} SET ${d} = -(${d} + 1) WHERE ${E.join(" AND ")}`,w=ge(t,e,this.driver.databaseKind,"delete",String(e.id),c);if((await this.executeLoggedSQL("delete",S,b,w,()=>y.query(S,b),void 0,l)).rowCount!==1)throw new Error(`Optimistic lock failed or ${e.entity}(${e.id}) does not exist`);const I=await this.readPersistedRecord(y,s,String(e.id),w,S,b,l);return{success:!0,id:String(e.id),version:Number(I.version),deleted:!0,persistedRecord:I}}throw new Error(`Unsupported mutation action: ${e.action}`)})),g=t.auditProjection({entity:String(e.entity),id:f.id},e.payload,c),h=Object.freeze({entity:e.entity,action:e.action,id:String(f.id),...g,recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.freeze(Object.keys(e.payload||{}).sort()),version:f.version,mutationGovernance:o}),p=async()=>{this.auditEvents.push(h),this.auditSink&&await D(this.runtimeTelemetry,{family:"audit",name:`${e.entity}.audit`,attributes:{"teaql.entity.type":String(e.entity),"teaql.mutation.kind":String(e.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(e.payload||{}).length}},async()=>this.auditSink(h))};if(t.graphSession)this.graphAuditActions.push(p);else try{await p()}catch(y){throw new qe(y)}n.success();const m=Object.freeze({...l[0],statements:Object.freeze([...l])});return ke(m,R(c,t.graphSession?.logBindings),[f.id]),{...f,metadata:m}}catch(o){throw n.failure(o),o}};return n.run?n.run(r):r()}async readPersistedRecord(e,t,n,r,o,s,a){const u=`SELECT ${Object.entries(t.columns).map(([S,w])=>`${this.driver.identifier(w.columnName)} AS ${this.driver.identifier(S)}`).join(", ")} FROM ${this.driver.identifier(t.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,l=[n];this.bindLogPolicies.set(l,[this.fieldLogPolicy(t,"id")]);const f=N(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.readback`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}}),g=Date.now();let h;const p={parameterizedSQL:o,parameters:s,parameterLogPolicies:this.bindLogPolicies.get(s),sqlOrigin:"generated"},m=r.tracePath?.find(S=>S.kind==="operation")?.name??"unknown",y=ye([...ze(m,r.auditReason,"verify persisted mutation result"),...(r.tracePath??[]).filter(S=>S.kind==="relation")],this.driver.databaseKind,"select"),d={...r,tracePath:ee(y.tracePath),comment:r.auditReason,purpose:"verify persisted mutation result"},b=S=>a.push(this.recordSQL("select",u,l,g,h?.rowCount,void 0,d,S,p,f.correlation?.()));let E;try{if(h=await(f.run?f.run(()=>e.query(u,l)):e.query(u,l)),f.success({attributes:{"teaql.result.cardinality":h.rowCount}}),h.rowCount!==1)throw new Error(`Persisted ${t.table}(${n}) could not be read back`);E=this.decodeRowForSchema(t,h.rows[0])}catch(S){h||f.failure(S);const w=h?"success":S instanceof Error&&(S.name==="AbortError"||S.name==="TimeoutError")?"cancelled":"failure";try{b(w)}finally{throw S}}return b("success"),E}decodeRowForSchema(e,t){const n={...t};for(const[r,o]of Object.entries(e.columns)){const s=n[r];s!=null&&(o.decode==="number"&&(n[r]=Number(s)),o.decode==="string"&&(n[r]=String(s)),o.decode==="date"&&s instanceof Date&&(n[r]=s.toISOString()),o.logicalType==="boolean"&&(n[r]=!!s))}return n}compileExpression(e,t,n){if(Array.isArray(e?.$and))return`(${e.$and.map(s=>this.compileExpression(s,t,n)).join(" AND ")})`;const r=Object.entries(e||{}).map(([o,s])=>{const a=t.columns[o];if(!a)throw new Error(`Unknown field ${o} for SQL query`);const c=this.driver.identifier(a.columnName),u=this.fieldLogPolicy(t,o);if(s?.$eq!==void 0){const l=s.$eq?.id??s.$eq;return l===null?`${c} IS NULL`:(this.bindValue(n,this.encode(l,a),u),`${c} = ${this.driver.placeholder(n.length)}`)}if(s?.$ne!==void 0){const l=s.$ne?.id??s.$ne;return l===null?`${c} IS NOT NULL`:(this.bindValue(n,this.encode(l,a),u),`${c} <> ${this.driver.placeholder(n.length)}`)}if(s?.$soundLike!==void 0)return this.bindValue(n,String(s.$soundLike),u),`SOUNDEX(${c}) = SOUNDEX(${this.driver.placeholder(n.length)})`;if(s?.$contains!==void 0)return this.bindValue(n,String(s.$contains),u),this.driver.contains(c,this.driver.placeholder(n.length));if(s?.$notContains!==void 0)return this.bindValue(n,String(s.$notContains),u),`NOT (${this.driver.contains(c,this.driver.placeholder(n.length))})`;for(const[l,f,g,h]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(s?.[l]!==void 0){const p=String(s[l]);this.bindValue(n,`${f}${p}${g}`,u,p);const m=`${c} LIKE ${this.driver.placeholder(n.length)}`;return h?`NOT (${m})`:m}if(Array.isArray(s?.$in)){if(!s.$in.length)return"FALSE";const l=s.$in.map(f=>(this.bindValue(n,this.encode(f?.id??f,a),u),this.driver.placeholder(n.length)));return`${c} IN (${l.join(", ")})`}if(Array.isArray(s?.$notIn)){if(!s.$notIn.length)return"TRUE";const l=s.$notIn.map(f=>(this.bindValue(n,this.encode(f?.id??f,a),u),this.driver.placeholder(n.length)));return`${c} NOT IN (${l.join(", ")})`}for(const[l,f]of[["$inSubquery",!1],["$notInSubquery",!0]]){const g=s?.[l];if(g!==void 0){const h=g.query,p=this.schema(h?.entity),m=String(g.field),y=p.columns[m];if(!y)throw new Error(`Unknown subquery projection ${m} for ${h?.entity}`);const d=this.filters(h).map(S=>this.compileExpression(S,p,n));p.columns.version&&d.push(`${this.driver.identifier(p.columns.version.columnName)} > 0`),f&&d.push(`${this.driver.identifier(y.columnName)} IS NOT NULL`);const b=d.length?` WHERE ${d.join(" AND ")}`:"",E=`SELECT ${this.driver.identifier(y.columnName)} FROM ${this.driver.identifier(p.table)}${b}`;return`${c} ${f?"NOT IN":"IN"} (${E})`}}if(Array.isArray(s?.$between)&&s.$between.length===2){this.bindValue(n,this.encode(s.$between[0],a),u);const l=this.driver.placeholder(n.length);this.bindValue(n,this.encode(s.$between[1],a),u);const f=this.driver.placeholder(n.length);return`${c} BETWEEN ${l} AND ${f}`}if(s?.$isNull===!0)return`${c} IS NULL`;if(s?.$isNull===!1)return`${c} IS NOT NULL`;if(s?.$gte!==void 0)return this.bindValue(n,this.encode(s.$gte,a),u),`${c} >= ${this.driver.placeholder(n.length)}`;if(s?.$lte!==void 0)return this.bindValue(n,this.encode(s.$lte,a),u),`${c} <= ${this.driver.placeholder(n.length)}`;if(s?.$gt!==void 0)return this.bindValue(n,this.encode(s.$gt,a),u),`${c} > ${this.driver.placeholder(n.length)}`;if(s?.$lt!==void 0)return this.bindValue(n,this.encode(s.$lt,a),u),`${c} < ${this.driver.placeholder(n.length)}`;throw new Error(`Unsupported query predicate for ${o}: ${JSON.stringify(s)}`)});return r.length?`(${r.join(" AND ")})`:"TRUE"}filters(e){return Array.isArray(e._filters)&&e._filters.length?e._filters:e.filterCondition?[e.filterCondition]:[]}groupBy(e){return e._groupBy||e.groupByItems||[]}aggregates(e){return Array.isArray(e._aggregates)?e._aggregates:(e.aggregateItems||[]).map(t=>({func:t.function,field:t.field,retName:t.alias}))}orders(e){return Array.isArray(e._orderBy)?e._orderBy.map(t=>({field:t.f,direction:t.d})):(e.orderItems||[]).map(t=>({field:t.field,direction:t.direction}))}async compileQuery(e,t=!0,n=[]){new se(e?.commentText??e?._comment,e?.purposeText??e?._purpose);const r=this.schema(e.entity),o=[],s=this.groupBy(e),a=s.map(w=>{if(!r.columns[w])throw new Error(`Unknown group field: ${w}`);return this.driver.identifier(r.columns[w].columnName)}),c=s.map(w=>`${this.driver.identifier(r.columns[w].columnName)} AS `+this.driver.identifier(w)),u=[],l=Array.isArray(e.selectItems)&&e.selectItems.length?[...new Set(["id","version",...e.selectItems])]:Object.keys(r.columns);if(!s.length&&!this.aggregates(e).length){for(const v of n)l.includes(v)||l.push(v);const w=[...(e.relations??[]).map(v=>v.name),...(e.relationAggregates??[]).map(v=>v.relationName)];for(const v of w){const I=r.relations?.[v];if(!I)throw new Error(`Missing relation ${e.entity}.${v}`);l.includes(I.localKey)||l.push(I.localKey)}}for(const w of l)if(!r.columns[w])throw new Error(`Unknown selected field: ${w}`);let f=l.map(w=>{const v=r.columns[w];return`${this.driver.identifier(v.columnName)} AS ${this.driver.identifier(w)}`}).join(", ");const g=this.aggregates(e);if(g.length){const w=g.map(v=>{if(!r.columns[v.field])throw new Error(`Unknown aggregate field: ${v.field}`);return u.push(v.retName),`${this.driver.aggregateFunction(v.func)}(${this.driver.identifier(r.columns[v.field].columnName)}) AS `+this.driver.identifier(v.retName)});f=[...c,...w].join(", ")}const h=e.__teaqlPartitionBy,p=this.orders(e),m=p.map(w=>{if(!r.columns[w.field])throw new Error(`Unknown order field: ${w.field}`);const v=String(w.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(r.columns[w.field].columnName)} ${v}`});if(h){const w=r.columns[h];if(!w)throw new Error(`Unknown partition field: ${h}`);const v=m.length?` ORDER BY ${m.join(", ")}`:"";f+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier(w.columnName)}${v}) AS `+this.driver.identifier("__teaql_partition_rank")}let y=`SELECT ${f} FROM ${this.driver.identifier(r.table)}`;const b=this.filters(e).map(w=>this.compileExpression(w,r,o));r.columns.version&&b.push(`${this.driver.identifier(r.columns.version.columnName)} > 0`),b.length&&(y+=` WHERE ${b.join(" AND ")}`),a.length&&(y+=` GROUP BY ${a.join(", ")}`);const E=e._limit!==void 0?Number(e._limit):Number(e.limitValue||0),S=e._offset!==void 0?Number(e._offset):Number(e.offsetValue||0);if(h){const w=this.driver.identifier("__teaql_partition_rank"),v=[];this.bindValue(o,S,"plain"),v.push(`${w} > ${this.driver.placeholder(o.length)}`),E>0&&(this.bindValue(o,S+E,"plain"),v.push(`${w} <= ${this.driver.placeholder(o.length)}`)),y=`SELECT * FROM (${y}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${v.join(" AND ")} ORDER BY ${w}`}else p.length&&(y+=` ORDER BY ${m.join(", ")}`);return!h&&E>0&&(this.bindValue(o,E,"plain"),y+=` LIMIT ${this.driver.placeholder(o.length)}`),!h&&S>0&&(this.bindValue(o,S,"plain"),y+=` OFFSET ${this.driver.placeholder(o.length)}`),t&&this.sqlTrace.push(y),{sql:y,values:o,aggregateNames:u}}async executeQuery(e){const t=e instanceof L?e:new L(e);return!(e instanceof L)&&e?.[this.internalQueryToken]!==!0&&typeof e?.prepareForList=="function"&&e.prepareForList(),this.executeQueryWithIntent(t.query,this.derivedQueryBindings.get(e),this.derivedRelationAssembly.get(e))}async executeDerivedQuery(e,t,n,r){const o=new L(e,n).query;t&&this.derivedQueryBindings.set(o,t),r&&this.derivedRelationAssembly.set(o,r);try{return await this.executeQuery(o)}finally{this.derivedQueryBindings.delete(o),this.derivedRelationAssembly.delete(o)}}descendantBindings(e,t,n,r){if(!(!e.relations?.length&&!e.relationAggregates?.length))return R(this.queryLogBindings(t,n),r)}async queryTreeBindings(e,t,n,r){let o=R(this.queryLogBindings(t,n),r);const s=new L(e).intent,a=[e],c=new Set;for(;a.length;){const u=a.pop();if(!u||c.has(u))continue;if(c.add(u),u!==e){const f=await this.compileQuery(new L(u,s).query,!1);o=R(this.queryLogBindings(f.sql,f.values),o)}const l=$t(u);l&&a.push(l);for(const f of[...u.relations??[],...u.relationAggregates??[]])f.query&&a.push(f.query);for(const f of u.facets??[]){if(!f.query)continue;const g=f.query.clone();g.aggregateItems=[],g.groupByItems=[],a.push(g)}}return o}async executeQueryWithIntent(e,t,n){await this.telemetryStartup;const r=N(this.runtimeTelemetry,{family:"query",name:`${String(e?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(e?.entity||"unknown")}}),o=async()=>{try{const s=e?.[this.internalQueryToken]===!0;if(!s){if(typeof e?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");e.prepareForList()}const a=s?{query:e,execution:void 0}:await this.prepareIdSetPage(e,t),c=s?a:await this.prepareContinuousPage(a.query);e=new L(e).withQuery(c.query).query;const{sql:u,values:l,aggregateNames:f}=await this.compileQuery(e,!0,n?[n.field]:[]);t=await this.queryTreeBindings(e,u,l,t);const h=(await this.executeLoggedSQL("select",u,l,this.queryLogIntent(e),()=>this.driver.query(u,l),t)).rows.map(m=>this.decodeRow(e.entity,m,f));if(a.execution?.pageIds){const m=new Map(a.execution.pageIds.map((y,d)=>[String(y),d]));h.sort((y,d)=>(m.get(String(y.id))??Number.MAX_SAFE_INTEGER)-(m.get(String(d.id))??Number.MAX_SAFE_INTEGER))}const p=this.descendantBindings(e,u,l,t);if(n)for(const m of h)n.keys.set(m,m[n.field]);if(await this.enhanceQueryRows(h,e,p),n&&Array.isArray(e.selectItems)&&e.selectItems.length&&!["id","version",...e.selectItems,...this.groupBy(e)].includes(n.field)){const m=this.schema(e.entity);if(![...(e.relations??[]).map(d=>d.name),...(e.relationAggregates??[]).map(d=>d.relationName)].some(d=>m.relations?.[d]?.localKey===n.field))for(const d of h)delete d[n.field]}return s||await this.registerContinuousPage(e,c.execution,h),r.success({attributes:{"teaql.result.cardinality":h.length}}),h}catch(s){throw r.failure(s),s}};return r.run?r.run(o):o()}async prepareIdSetPage(e,t){const n=e.localIdSetPaginationOptions?.(),r=e.localIdSetPaginationRuntime?.();if(!n||!r)return r?.observe("ID_SET_DISABLED"),{query:e};const o=this.queryLimit(e);if(!o||e.localContinuousPageOptions?.()||this.aggregates(e).length||this.groupBy(e).length||e.__teaqlPartitionBy)return r.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:e};if((e.orderItems||[]).some(m=>m.expr!=null))return r.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:e};this.orders(e).some(m=>m.field==="id")||(e=e.clone().order(P.asc("id")));const s=e.clone();s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.relations=[],s.commentText=void 0,s.purposeText=void 0,s.clearIdSetPaginationRuntime(),s.clearContinuousPageRuntime();const a=`${n.namespace}|${r.scope}|${JSON.stringify(s)}`;let c=2166136261;for(let m=0;m>>0).toString(16)}`;let l,f=!1;try{l=r.get(u)}catch{return r.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:e}}if(l)f=!0,r.observe("ID_SET_HIT",l.ids.length);else{let m;try{m=await r.build(u,async()=>{const y=r.get(u);if(y)return y;const d=e.clone();d.selectItems=["id"],d.relations=[],d.relationAggregates=[],d.facets=[],d.offsetValue=0,d.limitValue=n.maxIds+1,d.clearIdSetPaginationRuntime(),d.clearContinuousPageRuntime(),d[this.internalQueryToken]=!0;const b=new L(e).deriveHelper(d,`collect ${e.entity} IDs for pagination`),E=await this.compileQuery(e,!1),S=await this.queryTreeBindings(e,E.sql,E.values,t),w=await this.executeDerivedQuery(b.query,S,b.intent);if(w.length>n.maxIds)return;let v;try{v=BigUint64Array.from(w.map(T=>BigInt(T.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const I={ids:v,expiresAt:Date.now()+n.ttlSeconds*1e3};return r.put(u,I),I})}catch(y){return r.observe(y instanceof Error&&y.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:e}}if(l=m.value,!l)return r.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",n.maxIds+1),{query:e};f=!m.built,r.observe(f?"ID_SET_HIT":"ID_SET_BUILD",l.ids.length)}const g=Number(e.offsetValue||e._offset||0),h=Array.from(l.ids.slice(g,g+o)),p=e.clone();return p.offsetValue=0,p.limitValue=Math.max(h.length,1),p.filterCondition=p.filterCondition?{$and:[p.filterCondition,{id:{$in:h}}]}:{id:{$in:h}},p.clearIdSetPaginationRuntime(),r.observe(f?"ID_SET_HIT":"ID_SET_BUILD",l.ids.length),{query:p,execution:{pageIds:h,totalCount:l.ids.length}}}async executeFacetMembership(e,t,n=[]){const r=await this.executeFacetAggregates(e,t,[{function:"Count",field:"id",alias:"__teaql_facet_count"}]);return new Map([...r].map(([o,s])=>[o,Number(s.__teaql_facet_count??0)]))}async executeFacetAggregates(e,t,n){const r=new L(e);e=r.query;const o=r.withQuery(e.clone()).query;Q(e,o),o.facets=[],o.relations=[],o.relationAggregates=[],o.orderItems=[],o.offsetValue=0,o.limitValue=0,o.selectItems=[],o.groupByItems=[t],o.aggregateItems=n.map(a=>({...a})),o[this.internalQueryToken]=!0;const s=await this.executeQuery(o);return new Map(s.flatMap(a=>{const c=a[t];if(c==null)return[];const u={};for(const l of n)u[l.alias]=a[l.alias];return[[String(c),u]]}))}async executeCount(e,t,n){const r=e instanceof L?e:new L(e);if(e=r.query,typeof e?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const o=t??"__teaql_total",s=r.deriveOperation(e.forExactCount(o),n??{kind:"named-count",...t!==void 0?{alias:t}:{}}),c=(await this.executeQuery(s.query))[0]?.[o];if(typeof c!="number"||!Number.isFinite(c))throw new Error(`TeaQL provider did not return exact count alias ${o}`);return c}async prepareContinuousPage(e){const t=e.localContinuousPageOptions?.(),n=e.localContinuousPageRuntime?.();if(!t||!n)return n?.observe("DISABLED"),{query:e};const r=this.orders(e),o=this.queryLimit(e);if(!o||r.length!==1||r[0].field!=="id"||this.aggregates(e).length||this.groupBy(e).length||e.__teaqlPartitionBy)return n.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:e};const s=Object.assign(Object.create(Object.getPrototypeOf(e)),e);s.orderItems=[...e.orderItems||[]],s.relations=[...e.relations||[]],Object.defineProperty(s,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:t}),Object.defineProperty(s,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:n});const a=Number(e.offsetValue||e._offset||0),c={...JSON.parse(JSON.stringify(s)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},u=`${t.namespace}|${n.owner}|${JSON.stringify(c)}`;let l=2166136261;for(let m=0;m>>0).toString(16)}`,g={queryKey:f,offset:a,limit:o,direction:String(r[0].direction).toLowerCase(),ttlSeconds:t.ttlSeconds,runtime:n,optimized:!1};if(a===0)return n.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:s,execution:g};let h;try{h=await D(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>n.get(f,a))}catch{return n.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:s,execution:g}}if(!h)return n.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:s,execution:g};const p={id:{[g.direction==="desc"?"$lt":"$gt"]:h.boundary}};return s.filterCondition=s.filterCondition?{$and:[s.filterCondition,p]}:p,s.offsetValue=0,s._offset!==void 0&&(s._offset=0),g.optimized=!0,g.cursorId=h.cursorId,n.observe("CURSOR_SEEK",h.cursorId),{query:s,execution:g}}async registerContinuousPage(e,t,n){if(!(!t||n.length!==t.limit||!n.length||n[n.length-1].id===void 0)){try{await D(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>t.runtime.put(t.queryKey,t.offset+n.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:n[n.length-1].id,expiresAt:Date.now()+t.ttlSeconds*1e3}))}catch{t.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}t.optimized&&t.runtime.observe("CURSOR_SEEK",t.cursorId)}}executeForStream(e,t=1e3){try{const n=e instanceof L?new L(e.query,e.intent):new L(e);return this.executeCapturedStream(n.query,t)}catch(n){return(async function*(){throw n})()}}async*executeCapturedStream(e,t){if(await this.telemetryStartup,!Number.isInteger(t)||t<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(e.facets)&&e.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:n,values:r,aggregateNames:o}=await this.compileQuery(e),s=await this.queryTreeBindings(e,n,r),a=N(this.runtimeTelemetry,{family:"query",name:`${String(e.entity)}.stream`,attributes:{"teaql.entity.type":String(e.entity)}});let c;const u=async()=>{c=N(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.stream`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}})};await(a.run?a.run(u):u());const l=c.correlation?.(),f=this.driver.stream(n,r)[Symbol.asyncIterator](),g=Date.now();let h="cancelled",p=0,m=[];const y=this.descendantBindings(e,n,r,s);try{for(;;){const d=await(c.run?c.run(()=>f.next()):f.next());if(d.done)break;m.push(this.decodeRow(e.entity,d.value,o)),m.length===t&&(await this.enhanceQueryRows(m,e,y),p+=m.length,yield m,m=[])}m.length&&(await this.enhanceQueryRows(m,e,y),p+=m.length,yield m),h="success"}catch(d){throw h="failure",c.failure(d),a.failure(d),d}finally{try{await f.return?.()}catch(d){if(h!=="failure")throw h="failure",c.failure(d),a.failure(d),d}finally{if(h==="failure")try{this.recordSQL("select",n,r,g,p,void 0,this.queryLogIntent(e),h,s,l)}catch{}else this.recordSQL("select",n,r,g,p,void 0,this.queryLogIntent(e),h,s,l),c.success({attributes:{"teaql.result.cardinality":p}}),a.success({attributes:{"teaql.result.cardinality":p}})}}}async enhanceQueryRows(e,t,n){if(!e.length)return;const r=[...(t.relations??[]).map(a=>a.name),...(t.relationAggregates??[]).map(a=>a.relationName)];if(!r.length)return;const o=this.schema(t.entity),s=new Map;for(const a of r){const c=o.relations?.[a];if(!c)throw new Error(`Missing relation ${t.entity}.${a}`);s.has(c.localKey)||s.set(c.localKey,e.map(u=>u[c.localKey]))}await this.enhanceRelationAggregates(e,t,s,n),await this.enhanceRelations(e,t,s,n)}async enhanceRelations(e,t,n,r){if(!e.length||!Array.isArray(t.relations)||!t.relations.length)return;const o=this.schema(t.entity),s=new L(t).intent;for(const a of t.relations){const c=o.relations?.[a.name];if(!c)throw new Error(`Missing relation ${t.entity}.${a.name}`);const u=n.get(c.localKey),l=u.filter(S=>S!=null),f=a.query?this.queryLimit(a.query):void 0,g=a.query?.localTopNProbeParentThreshold?.(),h=c.many&&f!==void 0,p=Array.isArray(a.query?.selectItems)?a.query.selectItems:[],m=p.length>0&&!p.includes(c.foreignKey),y=this.driver.topNRelationPlanPolicy==="alwaysProbe",d=h&&(g===void 0?y:g>0&&l.length<=g),b=d?"bounded_probes":"window",E=N(this.runtimeTelemetry,{family:"relation_load",name:`${t.entity}.${String(a.name)}`,attributes:{"teaql.entity.type":String(t.entity),"teaql.relation.name":String(a.name),"teaql.relation.parent_count":l.length,"teaql.relation.per_parent_limit":f??0,"teaql.relation.configured_probe_threshold":g??"provider-default","teaql.relation.selected_plan":b,"teaql.relation.probe_count":d?l.length:0}});try{if(!l.length&&!(c.many&&a.query?.facets?.length)){for(const T of e)T[a.name]=c.many?[]:null;E.success({attributes:{"teaql.result.cardinality":0}});continue}const S={...a.query||{},entity:c.targetEntity,selectItems:m?[...p,c.foreignKey]:p,_filters:[...this.filters(a.query||{})],relations:[...a.query?.relations||[]],orderItems:[...a.query?.orderItems||[]],__teaqlPartitionBy:h&&!d?c.foreignKey:void 0};if(h){const T=this.groupBy(S),O=T.length||this.aggregates(S).length?T:["id"];for(const $ of O)S.orderItems.some(A=>A.field===$)||S.orderItems.push(P.asc($))}typeof S.clearContinuousPageRuntime=="function"&&S.clearContinuousPageRuntime(),S[this.internalQueryToken]=!0;const w=[],v={field:c.foreignKey,keys:new WeakMap};if(d)for(const T of l){const O={...S,_filters:[...S._filters,{[c.foreignKey]:{$eq:T}}],__teaqlPartitionBy:void 0};w.push(...await this.executeDerivedQuery(new L(t).derive(O,a.name,a.operation).query,r,s,v))}else S._filters.push({[c.foreignKey]:{$in:l}}),w.push(...await this.executeDerivedQuery(new L(t).derive(S,a.name,a.operation).query,r,s,v));for(const T of w)delete T.__teaql_partition_rank;const I=new Map;for(const T of w){if(!v.keys.has(T))throw new Error("Relation assembly lost its captured row identity");const O=v.keys.get(T),$=I.get(O)||[];$.push(T),I.set(O,$)}if(m)for(const T of w)delete T[c.foreignKey];for(const[T,O]of e.entries()){const $=I.get(u[T])||[];if(c.many&&a.query?.facets?.length){const A=a.query.clone();A.entity=c.targetEntity;const le=u[T],Te={[c.foreignKey]:le==null?{$in:[]}:{$eq:le}};A.filterCondition=A.filterCondition?{$and:[A.filterCondition,Te]}:Te,Q(t,A);const it=new L(t).derive(A,a.name,a.operation).query;O[a.name]=new Y($,{facets:await et(this,nt=>nt,it,A.facets)})}else{const A=u[T];O[a.name]=c.many?$:$[0]??(A==null?null:{[c.foreignKey]:A})}}E.success({attributes:{"teaql.result.cardinality":w.length}})}catch(S){throw E.failure(S),S}}}async enhanceRelationAggregates(e,t,n,r){const o=t.relationAggregates;if(!e.length||!Array.isArray(o)||!o.length)return;const s=this.schema(t.entity),a=new L(t).intent;for(const c of o){const u=s.relations?.[c.relationName];if(!u)throw new Error(`Missing relation ${t.entity}.${c.relationName}`);const l=n.get(u.localKey),f=l.filter(y=>y!=null);if(!f.length){for(const y of e)y[c.alias]=c.singleResult?this.emptyAggregateValue(c.query):{};continue}const g=c.query.clone();g.entity=u.targetEntity,g.selectItems=[],g.properties=[],g.orderItems=[],g.limitValue=0,g.offsetValue=0,g.relations=[],g.relationAggregates=[],g.aggregateItems.length||g.aggregate("Count","id",c.alias),g.groupByItems.includes(u.foreignKey)||g.groupBy(u.foreignKey);const h={[u.foreignKey]:{$in:f}};g.filterCondition=g.filterCondition?{$and:[g.filterCondition,h]}:h,g[this.internalQueryToken]=!0;const p=await this.executeDerivedQuery(new L(t).deriveAggregate(g,c.relationName,c.operation??{kind:"relation-count",relation:c.relationName,alias:c.alias}).query,r,a),m=new Map;for(const y of p)m.set(y[u.foreignKey],y);for(const[y,d]of e.entries()){const b=m.get(l[y]);b?c.singleResult?d[c.alias]=b[g.aggregateItems[0].alias]??null:d[c.alias]=Object.fromEntries(Object.entries(b).filter(([E])=>E!==u.foreignKey)):d[c.alias]=c.singleResult?this.emptyAggregateValue(c.query):{}}}}emptyAggregateValue(e){const t=e.aggregateItems[0];return!t||String(t.function).toLowerCase()==="count"?0:null}queryLimit(e){if(e._limit!==void 0)return Number(e._limit);if(e.limitValue!==void 0&&Number(e.limitValue)>0)return Number(e.limitValue)}async close(){try{await this.driver.close()}finally{await this.telemetryStartup,await this.standardTelemetryHandle?.release(),this.standardTelemetryHandle=void 0}}}function Jt(i){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i))throw new Error(`Unsafe SQL identifier: ${i}`);return i}function Zt(i){const t={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(i).toLowerCase()];if(!t)throw new Error(`Unsupported aggregate: ${i}`);return t}class ei{constructor(e){this.worker=e,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=t=>{const n=t.data;if(!n||n.type!=="teaql-browser-sqlite-response")return;const r=this.pending.get(n.requestId);if(r)if(this.pending.delete(n.requestId),n.error){const o=new Error(n.error.message);o.name=n.error.name,n.error.code&&(o.code=n.error.code),r.reject(o)}else r.resolve(n.result)},this.onError=t=>{const n=new Error(t.message||"Browser SQLite worker failed");n.name="BrowserSQLiteWorkerError";for(const r of this.pending.values())r.reject(n);this.pending.clear()},e.addEventListener("message",this.onMessage),e.addEventListener("error",this.onError)}request(e,t){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const n=this.nextRequestId++;return new Promise((r,o)=>{this.pending.set(n,{resolve:s=>r(s),reject:o}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:n,operation:e,payload:t})})}async close(e){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),e&&this.worker.terminate?.();const t=new Error("Browser SQLite worker is closed");for(const n of this.pending.values())n.reject(t);this.pending.clear()}}}class ti{constructor(e){this.transport=e}query(e,t=[]){return this.transport.request("query",{sql:e,values:t})}}class $e{constructor(e,t){this.transport=e,this.options=t,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,t={}){const n={storage:t.storage??"memory",databaseName:ni(t.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:t.terminateWorkerOnClose??!0},r=new ei(e);return await r.request("open",n),new $e(r,n)}identifier(e){return`"${Jt(e)}"`}placeholder(e){return"?"}contains(e,t){return`CAST(${e} AS TEXT) LIKE '%' || ${t} || '%'`}aggregateFunction(e){return Zt(e)}encode(e,t){return e==null?e:t?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):t?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const t=this.accessTail;let n;this.accessTail=new Promise(r=>{n=r}),await t;try{return await e()}finally{n()}}query(e,t=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:t}))}async*stream(e,t=[]){const n=await this.query(e,t);for(const r of n.rows)yield r}transaction(e){return this.exclusive(async()=>{const t=new ti(this.transport);await t.query("BEGIN IMMEDIATE");try{const n=await e(t);return await t.query("COMMIT"),n}catch(n){try{await t.query("ROLLBACK")}catch{}throw n}})}async ensureSchema(e){for(const t of Object.values(e)){const n=this.identifier(t.table);await this.query(`CREATE TABLE IF NOT EXISTS ${n} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const r=await this.query(`PRAGMA table_info(${n})`),o=new Set(r.rows.map(s=>String(s.name)));for(const[s,a]of Object.entries(t.columns))s==="id"||s==="version"||o.has(a.columnName)||await this.query(`ALTER TABLE ${n} ADD COLUMN ${this.identifier(a.columnName)} ${ii(a.logicalType)}${a.nullable===!1?" NOT NULL":""}`)}for(const t of Wt(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(t.name)} ON ${this.identifier(t.table)} (${this.identifier(t.foreignColumn)}, ${this.identifier(t.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,t){for(let n=1;n<=100;n+=1){const r=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t]);if(!r.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[t])).rowCount===1)return"1"}catch(c){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t])).rowCount)throw c}continue}const o=Number(r.rows[0].id),s=o+1,a=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[s,t,o]);if(a.rowCount===1)return String(s);if(a.rowCount!==0)throw new Error(`ID space update for ${t} changed ${a.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${t} after 100 optimistic-lock attempts`)}ensureIdFloor(e,t,n){return Gt(e,r=>this.placeholder(r),t,n)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}}class tt extends Xt{constructor(e,t){super(e,t),this.browserDriver=e}static async open(e,t,n={}){return new tt(await $e.open(e,n),t)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}}function ii(i){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[i]}function ni(i){const e=i.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}function hi(i,e,t,n){const r=o=>{if(o.includes("."))throw new Error("Dynamic search requires a trusted relation binding");const s=t[i.entity]?.queryFields;if(!s||!Object.prototype.hasOwnProperty.call(s,o))throw new Error("Missing generated scalar search binding");return s[o]};return ri(i,e,t,{filter:(o,s)=>{const[a,c]=Object.entries(s)[0];if(c===null&&a!=="$eq"&&a!=="$ne")throw new Error("Null supports only equality predicates");return{[r(o)]:s}},order:(o,s)=>s==="asc"?P.asc(r(o)):P.desc(r(o))},n)}function ri(i,e,t,n,r=o=>console.warn({...o,fieldPath:""})){const o=ai(e,i.entity,t,()=>{}),s=Object.entries(o.search.filter??{}).map(([f,g])=>n.filter(f,g)),a=(o.search.orderBy??[]).map(f=>n.order(f.field,f.direction));if(s.some(f=>!U(f)))throw new Error("Invalid trusted search filter binding");if(a.some(f=>!(f instanceof P)))throw new Error("Invalid trusted search order binding");const c=i.clone(),u=i._filters??[],l=[...u,...i.filterCondition?[i.filterCondition]:[]];return(s.length||u.length)&&c.filter({$and:[...l,...s]}),c.orderItems.push(...a),o.warnings.forEach(f=>r({...f})),{query:c,warnings:o.warnings}}const Z=(i,e)=>Object.prototype.hasOwnProperty.call(i,e),U=i=>typeof i=="object"&&i!==null&&!Array.isArray(i),si=new Set(["__proto__","prototype","constructor"]),oi=new Set(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$notIn","$contains"]);function ai(i,e,t,n=o=>console.warn({...o,fieldPath:""}),r=100){if(!Number.isSafeInteger(r)||r<1)throw new Error("Invalid search limit");if(!Z(t,e))throw new Error("Unknown search entity");let o;try{o=typeof i=="string"?JSON.parse(i):i}catch{throw new Error("Dynamic search requires valid JSON")}if(!U(o)||Object.keys(o).some(h=>!["filter","orderBy"].includes(h)))throw new Error("Unsupported dynamic search input or control");if(o.filter!==void 0&&!U(o.filter))throw new Error("Invalid search filter");if(o.orderBy!==void 0&&!Array.isArray(o.orderBy))throw new Error("Invalid search ordering");const s=Object.entries(o.filter??{}),a=o.orderBy??[];if(s.length+a.length>r)throw new Error("Dynamic search exceeds clause limit");const c=[],u={filter:Object.create(null),orderBy:[]};function l(h){const p=h.split(".");if(p.length>16||p.some(d=>!d||d.startsWith("$")||si.has(d)))throw new Error("Invalid dynamic search field path");let m=t[e];for(const d of p.slice(0,-1)){if(!Z(m.relations,d))return;const b=m.relations[d];if(!Z(t,b))throw new Error("Invalid trusted search relation metadata");m=t[b]}const y=p[p.length-1];return Z(m.fields,y)?m.fields[y]:void 0}function f(h,p){c.push({code:"DYNAMIC_SEARCH_UNKNOWN_FIELD",entity:e,clause:p,fieldPath:h})}function g(h,p){if(h===null)return;if(!(p==="date"?typeof h=="string"&&/^\d{4}-\d{2}-\d{2}$/.test(h)&&!h.startsWith("0000-")&&Number.isFinite(Date.parse(h+"T00:00:00Z"))&&new Date(h+"T00:00:00Z").toISOString().slice(0,10)===h:p==="decimal"?typeof h=="string"&&/^[+-]?\d+(?:\.\d+)?$/.test(h)||typeof h=="number"&&Number.isFinite(h):p==="integer"||p==="timestamp"?typeof h=="number"&&Number.isSafeInteger(h):p==="number"?typeof h=="number"&&Number.isFinite(h):typeof h===p))throw new Error("Invalid value for known search field")}for(const[h,p]of s){const m=U(p)?Object.entries(p):[["$eq",p]];if(m.length!==1||!oi.has(m[0][0]))throw new Error("Unsupported or malformed dynamic search operator");const[y,d]=m[0];if((y==="$in"||y==="$notIn")&&(!Array.isArray(d)||d.length>1e3))throw new Error("Invalid or oversized search value list");const b=l(h);if(b===void 0){f(h,"FILTER");continue}if(b==="unsupported")throw new Error("Known search field has no supported scalar binding");if(y==="$contains"&&b!=="string")throw new Error("String operator requires a string field");if(Array.isArray(d)){if(y!=="$in"&&y!=="$notIn")throw new Error("Unexpected search value list");d.forEach(E=>g(E,b))}else g(d,b);u.filter[h]={[y]:Array.isArray(d)?[...d]:d}}for(const h of a){if(!U(h)||Object.keys(h).some(m=>!["field","direction"].includes(m))||typeof h.field!="string"||!["asc","desc"].includes(h.direction))throw new Error("Invalid dynamic search ordering");const p=l(h.field);if(p===void 0){f(h.field,"ORDER_BY");continue}if(p==="unsupported")throw new Error("Known search field has no supported scalar binding");u.orderBy.push({field:h.field,direction:h.direction})}return c.forEach(h=>n({...h})),{search:u,warnings:c}}export{tt as B,ot as C,ci as D,Le as L,z as M,P as O,se as Q,Je as R,Ft as S,Dt as U,Y as a,ui as b,li as c,hi as d,et as e,C as f,ri as m}; diff --git a/dist/assets/index-3Oa_Nwum.js b/dist/assets/index-3Oa_Nwum.js deleted file mode 100644 index 97de65e23b83a85c8c57bca60d8f22f205d0a772..0000000000000000000000000000000000000000 --- a/dist/assets/index-3Oa_Nwum.js +++ /dev/null @@ -1,5 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function i(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(s){if(s.ep)return;s.ep=!0;const n=i(s);fetch(s.href,n)}})();var we={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},Ce=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],G=class extends Error{constructor(e){super(`Unsupported locale: ${e}`),this.localeCode=e}},be={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function ne(t){if(typeof t!="string"||!t.trim())throw new G(t);const e=t.trim().replace(/_/g,"-").toLowerCase(),i=Ce.find(s=>s.toLowerCase()===e);if(i)return i;const r=be[e];if(!r)throw new G(t);return r}var j=class{constructor(e,i){if(this.data=e,this.fallback=i,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(ne)}message(e,i){return this.data.locales[e]?.messages[i]??this.fallback?.data.locales[e]?.messages[i]??this.data.locales.en?.messages[i]??this.fallback?.data.locales.en?.messages[i]??i}translate(e,i){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(i,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};j.builtin=new j(we);var ve=j,ue=Symbol("teaql.context.schema-capability"),H=new WeakMap,Ie=1;function Se(t){if(!t||typeof t!="object"&&typeof t!="function")return String(t);const e=t;let i=H.get(e);return i||(i=Ie++,H.set(e,i)),String(i)}var X=class extends Error{constructor(t,e,i){super(`context root ${t}: expected ${e}`),this.reason=t,this.expectedType=e,this.activeRoot=i,this.name="ContextRootError"}},oe=class{constructor(){this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(t,e)=>this.getContinuousPageCursor(t,e),put:(t,e,i)=>this.putContinuousPageCursor(t,e,i),observe:(t,e)=>{this.continuousPagePlan=t,this.continuousPageCursorId=e}},this.idSetPaginationRuntime={owner:"",scope:"",get:t=>this.idSetStore().get(t),put:(t,e)=>this.idSetStore().put(t,e),build:(t,e)=>this.singleFlightIdSetBuild(t,e),observe:(t,e)=>{this.idSetPaginationPlan=t,this.idSetPaginationCount=e,this.idSetPaginationCountAccuracy=t==="ID_SET_BUILD"||t==="ID_SET_HIT"?"EXACT":t==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=ve.builtin}setLocaleCode(t){const e=ne(t);return this.locale=e,this}setLanguageCode(t){return this.setLocaleCode(t)}installI18nCatalog(t){if(!t)throw new Error("catalog is required");return this.i18nCatalog=t,this}installIdSetPaginationStore(t){if(!t)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",t)}translateCheckResults(t){return t.map(e=>this.i18nCatalog.translate(e,this.locale))}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(t){const e=String(t.sourceLabel||""),i=e.toLowerCase();if(!t.entityType||!t.modelPath||!e||i.includes("authorization")||i.includes("cookie")||i.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const r=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",r),r.push(Object.freeze({...t})),this}finishFixEvidence(){const t=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...t])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(t,e){return this.resources.set(t,e),this}getResource(t){return this.resources.get(t)}removeResource(t){return this.resources.delete(t),this}requireResource(t){const e=this.getResource(t);if(e===void 0)throw new Error(`Required UserContext resource is missing: ${t}`);return e}ensureSchema(){const t=this.requireResource("dataService"),e=t[ue];if(!e)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return e.call(t,this)}withActiveRoot(t){if(!t||!t.entity||t.id===void 0||t.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...t}))}requireActiveRoot(t){const e=this.getResource("activeRoot");if(!e)throw new X("missing",t);if(e.entity!==t)throw new X("type_mismatch",t,e);return e}prepareQuery(t){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const e=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,e?`${e.entity}:${String(e.id)}`:"-",Se(this.getResource("dataService"))].join("|"),t.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(t,e){const i=`${t}:${e}`,r=this.continuousPageCursors.get(i);if(r&&r.expiresAt<=Date.now()){this.continuousPageCursors.delete(i);return}return r}putContinuousPageCursor(t,e,i){if(this.continuousPageCursors.size>=4096){const r=[...this.continuousPageCursors.entries()].sort((s,n)=>s[1].expiresAt-n[1].expiresAt)[0];r&&this.continuousPageCursors.delete(r[0])}this.continuousPageCursors.set(`${t}:${e}`,i)}getRetainedIdSet(t){const e=this.retainedIdSets.get(t);if(e&&e.expiresAt<=Date.now()){this.retainedIdSets.delete(t);return}return e}idSetStore(){return this.getResource("idSetPaginationStore")??{get:t=>this.getRetainedIdSet(t),put:(t,e)=>this.putRetainedIdSet(t,e),invalidate:t=>{this.retainedIdSets.delete(t)}}}putRetainedIdSet(t,e){if(e.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const r=()=>[...this.retainedIdSets.values()].reduce((s,n)=>s+n.ids.byteLength,0);for(;this.retainedIdSets.size>=64||r()+e.ids.byteLength>268435456;){const s=[...this.retainedIdSets.entries()].sort((n,o)=>n[1].expiresAt-o[1].expiresAt)[0];if(!s)break;this.retainedIdSets.delete(s[0])}this.retainedIdSets.set(t,e)}async singleFlightIdSetBuild(t,e){const i=this.idSetBuilds.get(t);if(i)return{value:await i,built:!1};const r=e();this.idSetBuilds.set(t,r);try{return{value:await r,built:!0}}finally{this.idSetBuilds.delete(t)}}},_e=class extends Error{constructor(e){super(`Check failed: ${e.map(i=>i.message??`${i.ruleId}:${i.location}`).join("; ")}`),this.violations=e,this.name="CheckException"}};function ke(t,e){const i=t.defaultDomainRoot,r=e.defaultDomainRoot;if(i&&r&&(i.entity!==r.entity||i.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...t.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??i,constants:[...s.values()],ensure:t.ensure&&e.ensure?async n=>{await t.ensure(n),await e.ensure(n)}:e.ensure??t.ensure}}var Y=class B{constructor(e,i,r){this.field=e,this.expr=i,this.direction=r}static new(e,i){return new B(e,null,i)}static expr(e,i){return new B("",e,i)}static asc(e){return B.new(e,"Asc")}static desc(e){return B.new(e,"Desc")}},J=Object.freeze({success:()=>{},failure:()=>{}}),$e=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function Ae(t){const e={"teaql.operation.family":t.family,"teaql.operation.name":t.name};for(const[i,r]of Object.entries(t.attributes||{}))$e.has(i)||(e[i]=r);return Object.freeze({...t,attributes:Object.freeze(e)})}function D(t,e){if(!t)return J;try{const i=t.start(Ae(e));let r=!1;return{run:i.run?s=>i.run(s):s=>s(),success(s){if(!r){r=!0;try{i?.success(s)}catch{}}},failure(s){if(!r){r=!0;try{i?.failure(s)}catch{}}}}}catch{return J}}async function T(t,e,i,r){const s=D(t,e);try{const n=await(s.run?s.run(i):i());return s.success(r?.(n)),n}catch(n){throw s.failure(n),n}}function qe(t){const e=new Map;for(const i of Object.values(t))for(const r of Object.values(i.relations||{})){if(!r.many)continue;const s=t[r.targetEntity],n=s?.columns[r.foreignKey]?.columnName,o=s?.columns.id?.columnName;if(!s||!n||!o)continue;const u=`idx_${s.table}_${n}_${o}`;let a=2166136261;for(let l=0;l>>0).toString(36),h=u.length<=30?u:`${u.slice(0,Math.max(1,29-c.length))}_${c}`;e.set(h,{name:h,table:s.table,foreignColumn:n,idColumn:o})}return[...e.values()]}async function xe(t,e,i,r){const s=Number(r);if(!Number.isSafeInteger(s)||s<0)throw new Error(`Invalid ID space floor ${r} for ${i}`);for(let n=1;n<=100;n+=1){const o=await t.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[i]);if(!o.rowCount){try{if((await t.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[i,s])).rowCount===1)return}catch(c){if(!(await t.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[i])).rowCount)throw c}continue}const u=Number(o.rows[0].id);if(u>=s)return;const a=await t.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[s,i,u]);if(a.rowCount===1)return;if(a.rowCount!==0)throw new Error(`ID space floor update for ${i} changed ${a.rowCount} rows on attempt ${n}`)}throw new Error(`Unable to synchronize ID space floor for ${i} after 100 optimistic-lock attempts`)}function Le(t){return t.startsWith('"')&&t.endsWith('"')||t.startsWith("`")&&t.endsWith("`")?t.slice(1,-1).replace(/""/g,'"').replace(/``/g,"`"):t}function Te(t,e){return t===e?!0:(t instanceof Date&&(t=t.getTime()),e instanceof Date&&(e=e.getTime()),t!=null&&e!==null&&e!==void 0&&String(t)===String(e))}function N(t,e,i){return[{level:0,kind:"operation",name:"mutation"},{level:1,kind:"entity",name:String(t.entity)},{level:2,kind:"provider",name:e},{level:3,kind:"sql",name:i}]}function Be(t,e,i="sqlite"){let r=0,s="",n="sql";for(let o=0;o=0&&h=0&&hi.toString(16).padStart(2,"0")).join("")}'`:_(typeof t=="object"?JSON.stringify(t):String(t))}function _(t){return`'${t.replace(/'/g,"''")}'`}var Re=class{constructor(t=e=>console.debug(e)){this.writer=t}write(t){this.writer(`[TeaQL SQL][${t.operation}][${t.elapsedMicros}us] ${t.resultSummary} -comment=${t.comment??""} purpose=${t.purpose??""} auditReason=${t.auditReason??""} tracePath=${Z(t.tracePath)} -Parameterized SQL: ${t.parameterizedSQL} params=${Z(t.parameters)} -Debug SQL: ${t.debugSQL}`)}};function Z(t){return JSON.stringify(t,(e,i)=>typeof i=="bigint"?i.toString():i)}var Fe=class{constructor(t,e){this.driver=t,this.schemas=e,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.auditEvents=[],this.diagnosticSQLLogSink=new Re,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.checkers={},this.userContext=new oe,this.bootstrap={},this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve()}install(t){return Object.assign(this.schemas,t.schemas),Object.assign(this.checkers,t.checkers),this.bootstrap=ke(this.bootstrap,t.bootstrap),this}setUserContext(t){return this.userContext=t,this}schema(t){const e=this.schemas[t];if(!e)throw new Error(`Unknown TeaQL entity: ${t}`);return e}toRuntimeMutationRecord(t,e){const i={};for(const[r,s]of Object.entries(e)){const n=t.columns[r]?r:Object.keys(t.columns).find(o=>t.columns[o].modelName===r||t.columns[o].columnName===r);n&&(i[n]=s)}return i}encode(t,e){const i=t?.id??t;if(i!==void 0)return this.driver.encode(i,e)}decodeRow(t,e,i=[]){const r=this.schema(t),s={...e};for(const[n,o]of Object.entries(r.columns)){const u=s[n];u!=null&&(o.decode==="number"&&(s[n]=Number(u)),o.decode==="string"&&(s[n]=String(u)),o.decode==="date"&&u instanceof Date&&(s[n]=u.toISOString()),o.logicalType==="boolean"&&(s[n]=!!u))}for(const n of i)s[n]!==null&&s[n]!==void 0&&(s[n]=Number(s[n]));return s}get auditTrace(){return[...this.auditEvents]}setAuditSink(t){return this.auditSink=t,this}setRuntimeTelemetrySink(t){return this.telemetrySink=t,this}setDiagnosticSQLLogSink(t){return this.diagnosticSQLLogSink=t,this}setQueryLoggingEnabled(t){return this.queryLoggingEnabled=t,this}setMutationLoggingEnabled(t){return this.mutationLoggingEnabled=t,this}setRuntimeTelemetry(t){return this.runtimeTelemetry=t,this}recordSQL(t,e,i,r,s,n,o={}){const u=t==="select";if(u&&!this.queryLoggingEnabled||!u&&!this.mutationLoggingEnabled||!this.telemetrySink&&!this.diagnosticSQLLogSink)return;const a=Object.freeze({operation:t,...o,tracePath:Object.freeze([...o.tracePath??[]]),parameterizedSQL:e,parameters:Object.freeze([...i]),debugSQL:Be(e,i,this.driver.databaseKind),elapsedMicros:Math.max(0,(Date.now()-r)*1e3),resultCount:s,affectedRows:n,resultSummary:s!==void 0?`${s} rows returned`:`${n??0} rows affected`});this.telemetrySink?.record(a),this.diagnosticSQLLogSink?.write(a)}async[ue](t){this.userContext=t,this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const e=this.bootstrapTail;let i;this.bootstrapTail=new Promise(r=>{i=r}),await e;try{if(this.bootstrap.ensure){t.insertResource("bootstrapActor","teaql-generated-bootstrap"),t.insertResource("bootstrapCategory","runtime-bootstrap");try{await this.bootstrap.ensure(t)}finally{t.removeResource("bootstrapActor"),t.removeResource("bootstrapCategory")}}else await this.ensureBootstrapData()}finally{i()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const t=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];t.length&&await this.driver.transaction(async e=>{for(const i of t)await this.reconcileBootstrapEntity(e,i)})}async reconcileBootstrapEntity(t,e){const i=this.schema(e.entity),r=this.driver.identifier(i.table),s=this.driver.identifier(i.columns.id?.columnName??"id"),n=this.driver.identifier(i.columns.version?.columnName??"version"),o=Object.entries(e.values??{}).map(([a,c])=>{const h=i.columns[a];if(!h)throw new Error(`Unknown bootstrap field ${e.entity}.${a}`);return{column:this.driver.identifier(h.columnName),value:this.driver.encode(c,h)}}),u=await t.query(`SELECT * FROM ${r} WHERE ${s} = ${this.driver.placeholder(1)}`,[e.id]);if(u.rowCount){const a=u.rows[0],c=o.filter(h=>!Te(a[Le(h.column)],h.value));if(c.length){const h=c.map((l,m)=>`${l.column} = ${this.driver.placeholder(m+1)}`);h.push(`${n} = ${n} + 1`),await t.query(`UPDATE ${r} SET ${h.join(", ")} WHERE ${s} = `+this.driver.placeholder(c.length+1),[...c.map(l=>l.value),e.id])}}else{const a=[s,n,...o.map(l=>l.column)],c=[e.id,1,...o.map(l=>l.value)],h=c.map((l,m)=>this.driver.placeholder(m+1));await t.query(`INSERT INTO ${r} (${a.join(", ")}) VALUES (${h.join(", ")})`,c)}await this.driver.ensureIdFloor(t,e.entity,e.id)}async executeGraphSave(t){const e=this.graphSaveTail;let i;this.graphSaveTail=new Promise(r=>{i=r}),await e,this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence();try{const r=await this.driver.transaction(async s=>{this.graphMutationSession=s;try{return await t()}finally{this.graphMutationSession=void 0}});for(const s of this.graphCommitActions)s();return r}catch(r){for(const s of[...this.graphRollbackActions].reverse())s();throw r}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.removeResource("fixTime").finishFixEvidence(),i()}}afterGraphCommit(t){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(t)}afterGraphRollback(t){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(t)}async withMutationSession(t){return this.graphMutationSession?t(this.graphMutationSession):this.driver.transaction(t)}preflightMutation(t){if(!String(t?.comment||"").trim())throw new Error("Security audit failure: audit reason is required before mutation");t={...t,payload:{...t?.payload??{}}};const e=this.checkers[String(t.entity)];if(!e)return t;const i=[],r=this.userContext.getResource("fixTime")===void 0;r&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(e.checkAndFix(this.userContext,t,i),t.ledgerKey&&t.ledgerRoot)for(const[s,n]of Object.entries(t.payload||{}))t.ledgerRoot.set(t.ledgerKey,s,n);if(this.userContext.translateCheckResults(i),i.length)throw new _e(i);return t}finally{r&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(t){const e=D(this.runtimeTelemetry,{family:"mutation",name:`${String(t?.entity||"unknown")}.${String(t?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(t?.entity||"unknown"),"teaql.mutation.kind":String(t?.action||"unknown").toLowerCase()}});try{t=this.preflightMutation(t);const i=this.schema(t.entity),r=this.toRuntimeMutationRecord(i,t.payload||{}),s=this.driver.identifier(i.table),n=await T(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(t.action).toLowerCase()}},()=>this.withMutationSession(async u=>{if(t.action==="Create"){const a=t.id?String(t.id):await this.driver.nextId(u,t.entity);t.id&&await this.driver.ensureIdFloor(u,t.entity,a);const c=Number(t.version||0)+1,h={...r,id:a,version:c},l=Object.keys(i.columns).filter(w=>h[w]!==void 0),m=l.map(w=>this.driver.identifier(i.columns[w].columnName)).join(", "),d=l.map((w,k)=>this.driver.placeholder(k+1)).join(", "),p=l.map(w=>this.encode(h[w],i.columns[w])),f=`INSERT INTO ${s} (${m}) VALUES (${d})`,g=Date.now(),E=await u.query(f,p);return this.recordSQL("insert",f,p,g,void 0,E.rowCount,{auditReason:String(t.comment),tracePath:N(t,this.driver.databaseKind,"insert")}),{success:!0,id:a,version:c,persistedRecord:await this.readPersistedRecord(u,i,a)}}if(t.action==="Update"){const a=Object.keys(i.columns).filter(E=>E!=="id"&&E!=="version"&&r[E]!==void 0),c=a.map(E=>this.encode(r[E],i.columns[E])),h=a.map((E,w)=>`${this.driver.identifier(i.columns[E].columnName)} = `+this.driver.placeholder(w+1)),l=this.driver.identifier("version");h.push(`${l} = ${l} + 1`),c.push(String(t.id));const m=[`${this.driver.identifier("id")} = ${this.driver.placeholder(c.length)}`];t.version!==void 0&&t.version!==null&&(c.push(Number(t.version)),m.push(`${l} = ${this.driver.placeholder(c.length)}`));const d=`UPDATE ${s} SET ${h.join(", ")} WHERE ${m.join(" AND ")}`,p=Date.now(),f=await u.query(d,c);if(this.recordSQL("update",d,c,p,void 0,f.rowCount,{auditReason:String(t.comment),tracePath:N(t,this.driver.databaseKind,"update")}),f.rowCount!==1)throw new Error(`Optimistic lock failed or ${t.entity}(${t.id}) does not exist`);const g=await this.readPersistedRecord(u,i,String(t.id));return{success:!0,id:String(t.id),version:Number(g.version),persistedRecord:g}}if(t.action==="Delete"){const a=this.driver.identifier("version"),c=[String(t.id)],h=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];t.version!==void 0&&t.version!==null&&(c.push(Number(t.version)),h.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(c.length)));const l=`UPDATE ${s} SET ${a} = -(${a} + 1) WHERE ${h.join(" AND ")}`,m=Date.now(),d=await u.query(l,c);if(this.recordSQL("delete",l,c,m,void 0,d.rowCount,{auditReason:String(t.comment),tracePath:N(t,this.driver.databaseKind,"delete")}),d.rowCount!==1)throw new Error(`Optimistic lock failed or ${t.entity}(${t.id}) does not exist`);const p=await this.readPersistedRecord(u,i,String(t.id));return{success:!0,id:String(t.id),version:Number(p.version),deleted:!0,persistedRecord:p}}throw new Error(`Unsupported mutation action: ${t.action}`)})),o=Object.freeze({entity:t.entity,action:t.action,id:String(n.id),reason:String(t.comment),recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.keys(t.payload||{}).sort(),version:n.version});return this.auditEvents.push(o),this.auditSink&&await T(this.runtimeTelemetry,{family:"audit",name:`${t.entity}.audit`,attributes:{"teaql.entity.type":String(t.entity),"teaql.mutation.kind":String(t.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(t.payload||{}).length}},async()=>this.auditSink(o)),e.success(),n}catch(i){throw e.failure(i),i}}async readPersistedRecord(t,e,i){const r=Object.entries(e.columns).map(([n,o])=>`${this.driver.identifier(o.columnName)} AS ${this.driver.identifier(n)}`).join(", "),s=await t.query(`SELECT ${r} FROM ${this.driver.identifier(e.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,[i]);if(s.rowCount!==1)throw new Error(`Persisted ${e.table}(${i}) could not be read back`);return this.decodeRowForSchema(e,s.rows[0])}decodeRowForSchema(t,e){const i={...e};for(const[r,s]of Object.entries(t.columns)){const n=i[r];n!=null&&(s.decode==="number"&&(i[r]=Number(n)),s.decode==="string"&&(i[r]=String(n)),s.decode==="date"&&n instanceof Date&&(i[r]=n.toISOString()),s.logicalType==="boolean"&&(i[r]=!!n))}return i}compileExpression(t,e,i){if(Array.isArray(t?.$and))return`(${t.$and.map(n=>this.compileExpression(n,e,i)).join(" AND ")})`;const r=Object.entries(t||{}).map(([s,n])=>{const o=e.columns[s];if(!o)throw new Error(`Unknown field ${s} for SQL query`);const u=this.driver.identifier(o.columnName);if(n?.$eq!==void 0){const a=n.$eq?.id??n.$eq;return a===null?`${u} IS NULL`:(i.push(this.encode(a,o)),`${u} = ${this.driver.placeholder(i.length)}`)}if(n?.$ne!==void 0){const a=n.$ne?.id??n.$ne;return a===null?`${u} IS NOT NULL`:(i.push(this.encode(a,o)),`${u} <> ${this.driver.placeholder(i.length)}`)}if(n?.$soundLike!==void 0)return i.push(String(n.$soundLike)),`SOUNDEX(${u}) = SOUNDEX(${this.driver.placeholder(i.length)})`;if(n?.$contains!==void 0)return i.push(String(n.$contains)),this.driver.contains(u,this.driver.placeholder(i.length));if(n?.$notContains!==void 0)return i.push(String(n.$notContains)),`NOT (${this.driver.contains(u,this.driver.placeholder(i.length))})`;for(const[a,c,h,l]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(n?.[a]!==void 0){i.push(`${c}${String(n[a])}${h}`);const m=`${u} LIKE ${this.driver.placeholder(i.length)}`;return l?`NOT (${m})`:m}if(Array.isArray(n?.$in)){if(!n.$in.length)return"FALSE";const a=n.$in.map(c=>(i.push(this.encode(c?.id??c,o)),this.driver.placeholder(i.length)));return`${u} IN (${a.join(", ")})`}if(Array.isArray(n?.$notIn)){if(!n.$notIn.length)return"TRUE";const a=n.$notIn.map(c=>(i.push(this.encode(c?.id??c,o)),this.driver.placeholder(i.length)));return`${u} NOT IN (${a.join(", ")})`}for(const[a,c]of[["$inSubquery",!1],["$notInSubquery",!0]]){const h=n?.[a];if(h!==void 0){const l=h.query,m=this.schema(l?.entity),d=String(h.field),p=m.columns[d];if(!p)throw new Error(`Unknown subquery projection ${d} for ${l?.entity}`);const f=this.filters(l).map(w=>this.compileExpression(w,m,i));m.columns.version&&f.push(`${this.driver.identifier(m.columns.version.columnName)} > 0`),c&&f.push(`${this.driver.identifier(p.columnName)} IS NOT NULL`);const g=f.length?` WHERE ${f.join(" AND ")}`:"",E=`SELECT ${this.driver.identifier(p.columnName)} FROM ${this.driver.identifier(m.table)}${g}`;return`${u} ${c?"NOT IN":"IN"} (${E})`}}if(Array.isArray(n?.$between)&&n.$between.length===2){i.push(this.encode(n.$between[0],o));const a=this.driver.placeholder(i.length);i.push(this.encode(n.$between[1],o));const c=this.driver.placeholder(i.length);return`${u} BETWEEN ${a} AND ${c}`}if(n?.$isNull===!0)return`${u} IS NULL`;if(n?.$isNull===!1)return`${u} IS NOT NULL`;if(n?.$gte!==void 0)return i.push(this.encode(n.$gte,o)),`${u} >= ${this.driver.placeholder(i.length)}`;if(n?.$lte!==void 0)return i.push(this.encode(n.$lte,o)),`${u} <= ${this.driver.placeholder(i.length)}`;if(n?.$gt!==void 0)return i.push(this.encode(n.$gt,o)),`${u} > ${this.driver.placeholder(i.length)}`;if(n?.$lt!==void 0)return i.push(this.encode(n.$lt,o)),`${u} < ${this.driver.placeholder(i.length)}`;throw new Error(`Unsupported query predicate for ${s}: ${JSON.stringify(n)}`)});return r.length?`(${r.join(" AND ")})`:"TRUE"}filters(t){return Array.isArray(t._filters)&&t._filters.length?t._filters:t.filterCondition?[t.filterCondition]:[]}groupBy(t){return t._groupBy||t.groupByItems||[]}aggregates(t){return Array.isArray(t._aggregates)?t._aggregates:(t.aggregateItems||[]).map(e=>({func:e.function,field:e.field,retName:e.alias}))}orders(t){return Array.isArray(t._orderBy)?t._orderBy.map(e=>({field:e.f,direction:e.d})):(t.orderItems||[]).map(e=>({field:e.field,direction:e.direction}))}async compileQuery(t){const e=t?.[this.internalQueryToken]===!0,i=t?._purpose??t?.purposeText,r=t?._comment??t?.commentText;if(!e&&(!String(i||"").trim()||!String(r||"").trim()))throw new Error("Security audit failure: purpose and comment are required before query execution");const s=this.schema(t.entity),n=[],o=this.groupBy(t),u=o.map(y=>{if(!s.columns[y])throw new Error(`Unknown group field: ${y}`);return this.driver.identifier(s.columns[y].columnName)}),a=o.map(y=>`${this.driver.identifier(s.columns[y].columnName)} AS `+this.driver.identifier(y)),c=[],h=Array.isArray(t.selectItems)&&t.selectItems.length?[...new Set(["id","version",...t.selectItems])]:Object.keys(s.columns);for(const y of h)if(!s.columns[y])throw new Error(`Unknown selected field: ${y}`);let l=h.map(y=>{const C=s.columns[y];return`${this.driver.identifier(C.columnName)} AS ${this.driver.identifier(y)}`}).join(", ");const m=this.aggregates(t);if(m.length){const y=m.map(C=>{if(!s.columns[C.field])throw new Error(`Unknown aggregate field: ${C.field}`);return c.push(C.retName),`${this.driver.aggregateFunction(C.func)}(${this.driver.identifier(s.columns[C.field].columnName)}) AS `+this.driver.identifier(C.retName)});l=[...a,...y].join(", ")}const d=t.__teaqlPartitionBy,p=this.orders(t),f=p.map(y=>{if(!s.columns[y.field])throw new Error(`Unknown order field: ${y.field}`);const C=String(y.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(s.columns[y.field].columnName)} ${C}`});if(d){const y=s.columns[d];if(!y)throw new Error(`Unknown partition field: ${d}`);const C=f.length?` ORDER BY ${f.join(", ")}`:"";l+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier(y.columnName)}${C}) AS `+this.driver.identifier("__teaql_partition_rank")}let g=`SELECT ${l} FROM ${this.driver.identifier(s.table)}`;const w=this.filters(t).map(y=>this.compileExpression(y,s,n));s.columns.version&&w.push(`${this.driver.identifier(s.columns.version.columnName)} > 0`),w.length&&(g+=` WHERE ${w.join(" AND ")}`),u.length&&(g+=` GROUP BY ${u.join(", ")}`);const k=t._limit!==void 0?Number(t._limit):Number(t.limitValue||0),F=t._offset!==void 0?Number(t._offset):Number(t.offsetValue||0);if(d){const y=this.driver.identifier("__teaql_partition_rank"),C=[];n.push(F),C.push(`${y} > ${this.driver.placeholder(n.length)}`),k>0&&(n.push(F+k),C.push(`${y} <= ${this.driver.placeholder(n.length)}`)),g=`SELECT * FROM (${g}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${C.join(" AND ")} ORDER BY ${y}`}else p.length&&(g+=` ORDER BY ${f.join(", ")}`);return!d&&k>0&&(n.push(k),g+=` LIMIT ${this.driver.placeholder(n.length)}`),!d&&F>0&&(n.push(F),g+=` OFFSET ${this.driver.placeholder(n.length)}`),this.sqlTrace.push(g),{sql:g,values:n,aggregateNames:c}}async executeQuery(t){const e=D(this.runtimeTelemetry,{family:"query",name:`${String(t?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(t?.entity||"unknown")}});try{const i=t?.[this.internalQueryToken]===!0;if(!i){if(typeof t?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");t.prepareForList()}const r=i?{query:t,execution:void 0}:await this.prepareIdSetPage(t),s=i?r:await this.prepareContinuousPage(r.query);t=s.query;const{sql:n,values:o,aggregateNames:u}=await this.compileQuery(t),a=Date.now(),c=await T(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.query`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}},()=>this.driver.query(n,o)),h=t?._comment??t?.commentText,l=t?._purpose??t?.purposeText,m=Array.isArray(t?.__teaqlTracePath)?t.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(t.entity)}],d=[...m,{level:m.length,kind:"provider",name:this.driver.databaseKind},{level:m.length+1,kind:"sql",name:"select"}];this.recordSQL("select",n,o,a,c.rowCount,void 0,{comment:h,purpose:l,tracePath:d});const p=c.rows.map(f=>this.decodeRow(t.entity,f,u));if(r.execution?.pageIds){const f=new Map(r.execution.pageIds.map((g,E)=>[String(g),E]));p.sort((g,E)=>(f.get(String(g.id))??Number.MAX_SAFE_INTEGER)-(f.get(String(E.id))??Number.MAX_SAFE_INTEGER))}return await this.enhanceRelations(p,t),await this.enhanceRelationAggregates(p,t),i||await this.registerContinuousPage(t,s.execution,p),e.success({attributes:{"teaql.result.cardinality":p.length}}),p}catch(i){throw e.failure(i),i}}async prepareIdSetPage(t){const e=t.localIdSetPaginationOptions?.(),i=t.localIdSetPaginationRuntime?.();if(!e||!i)return i?.observe("ID_SET_DISABLED"),{query:t};const r=this.queryLimit(t);if(!r||t.localContinuousPageOptions?.()||this.aggregates(t).length||this.groupBy(t).length||t.__teaqlPartitionBy)return i.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:t};if((t.orderItems||[]).some(d=>d.expr!=null))return i.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:t};this.orders(t).some(d=>d.field==="id")||(t=t.clone().order(Y.asc("id")));const s=t.clone();s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.relations=[],s.commentText=void 0,s.purposeText=void 0,s.clearIdSetPaginationRuntime(),s.clearContinuousPageRuntime();const n=`${e.namespace}|${i.scope}|${JSON.stringify(s)}`;let o=2166136261;for(let d=0;d>>0).toString(16)}`;let a,c=!1;try{a=i.get(u)}catch{return i.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:t}}if(a)c=!0,i.observe("ID_SET_HIT",a.ids.length);else{let d;try{d=await i.build(u,async()=>{const p=i.get(u);if(p)return p;const f=t.clone();f.selectItems=["id"],f.relations=[],f.relationAggregates=[],f.facets=[],f.offsetValue=0,f.limitValue=e.maxIds+1,f.clearIdSetPaginationRuntime(),f.clearContinuousPageRuntime(),f[this.internalQueryToken]=!0;const g=await this.executeQuery(f);if(g.length>e.maxIds)return;let E;try{E=BigUint64Array.from(g.map(k=>BigInt(k.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const w={ids:E,expiresAt:Date.now()+e.ttlSeconds*1e3};return i.put(u,w),w})}catch(p){return i.observe(p instanceof Error&&p.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:t}}if(a=d.value,!a)return i.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",e.maxIds+1),{query:t};c=!d.built,i.observe(c?"ID_SET_HIT":"ID_SET_BUILD",a.ids.length)}const h=Number(t.offsetValue||t._offset||0),l=Array.from(a.ids.slice(h,h+r)),m=t.clone();return m.offsetValue=0,m.limitValue=Math.max(l.length,1),m.filterCondition=m.filterCondition?{$and:[m.filterCondition,{id:{$in:l}}]}:{id:{$in:l}},m.clearIdSetPaginationRuntime(),i.observe(c?"ID_SET_HIT":"ID_SET_BUILD",a.ids.length),{query:m,execution:{pageIds:l,totalCount:a.ids.length}}}async executeFacetMembership(t,e){const i=t.clone();i.facets=[],i.relations=[],i.orderItems=[],i.offsetValue=0,i.limitValue=0,i.selectItems=[],i.groupByItems=[e],i.aggregateItems=[{function:"Count",field:"id",alias:"__teaql_facet_count"}],i[this.internalQueryToken]=!0;const r=await this.executeQuery(i);return new Map(r.flatMap(s=>{const n=s[e],o=Number(s.__teaql_facet_count??0);return n==null?[]:[[String(n),o]]}))}async executeCount(t){if(typeof t?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const e="__teaql_total",r=(await this.executeQuery(t.forExactCount(e)))[0]?.[e];if(typeof r!="number"||!Number.isFinite(r))throw new Error(`TeaQL provider did not return exact count alias ${e}`);return r}async prepareContinuousPage(t){const e=t.localContinuousPageOptions?.(),i=t.localContinuousPageRuntime?.();if(!e||!i)return i?.observe("DISABLED"),{query:t};const r=this.orders(t),s=this.queryLimit(t);if(!s||r.length!==1||r[0].field!=="id"||this.aggregates(t).length||this.groupBy(t).length||t.__teaqlPartitionBy)return i.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:t};const n=Object.assign(Object.create(Object.getPrototypeOf(t)),t);n.orderItems=[...t.orderItems||[]],n.relations=[...t.relations||[]],Object.defineProperty(n,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:e}),Object.defineProperty(n,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:i});const o=Number(t.offsetValue||t._offset||0),u={...JSON.parse(JSON.stringify(n)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},a=`${e.namespace}|${i.owner}|${JSON.stringify(u)}`;let c=2166136261;for(let p=0;p>>0).toString(16)}`,l={queryKey:h,offset:o,limit:s,direction:String(r[0].direction).toLowerCase(),ttlSeconds:e.ttlSeconds,runtime:i,optimized:!1};if(o===0)return i.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:n,execution:l};let m;try{m=await T(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>i.get(h,o))}catch{return i.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:n,execution:l}}if(!m)return i.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:n,execution:l};const d={id:{[l.direction==="desc"?"$lt":"$gt"]:m.boundary}};return n.filterCondition=n.filterCondition?{$and:[n.filterCondition,d]}:d,n.offsetValue=0,n._offset!==void 0&&(n._offset=0),l.optimized=!0,l.cursorId=m.cursorId,i.observe("CURSOR_SEEK",m.cursorId),{query:n,execution:l}}async registerContinuousPage(t,e,i){if(!(!e||i.length!==e.limit||!i.length||i[i.length-1].id===void 0)){try{await T(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>e.runtime.put(e.queryKey,e.offset+i.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:i[i.length-1].id,expiresAt:Date.now()+e.ttlSeconds*1e3}))}catch{e.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}e.optimized&&e.runtime.observe("CURSOR_SEEK",e.cursorId)}}async*executeForStream(t,e=1e3){if(!Number.isInteger(e)||e<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(t.facets)&&t.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:i,values:r,aggregateNames:s}=await this.compileQuery(t);let n=[];for await(const o of this.driver.stream(i,r))n.push(this.decodeRow(t.entity,o,s)),n.length===e&&(await this.enhanceRelations(n,t),yield n,n=[]);n.length&&(await this.enhanceRelations(n,t),yield n)}async enhanceRelations(t,e){if(!t.length||!Array.isArray(e.relations)||!e.relations.length)return;const i=this.schema(e.entity);for(const r of e.relations){const s=i.relations?.[r.name];if(!s)throw new Error(`Missing relation ${e.entity}.${r.name}`);const n=t.map(d=>d[s.localKey]).filter(d=>d!=null),o=r.query?this.queryLimit(r.query):void 0,u=r.query?.localTopNProbeParentThreshold?.(),a=s.many&&o!==void 0,c=this.driver.topNRelationPlanPolicy==="alwaysProbe",h=a&&(u===void 0?c:u>0&&n.length<=u),l=h?"bounded_probes":"window",m=D(this.runtimeTelemetry,{family:"relation_load",name:`${e.entity}.${String(r.name)}`,attributes:{"teaql.entity.type":String(e.entity),"teaql.relation.name":String(r.name),"teaql.relation.parent_count":n.length,"teaql.relation.per_parent_limit":o??0,"teaql.relation.configured_probe_threshold":u??"provider-default","teaql.relation.selected_plan":l,"teaql.relation.probe_count":h?n.length:0}});try{if(!n.length){for(const g of t)g[r.name]=s.many?[]:null;m.success({attributes:{"teaql.result.cardinality":0}});continue}const d={...r.query||{},entity:s.targetEntity,_filters:[...this.filters(r.query||{})],relations:[...r.query?.relations||[]],orderItems:[...r.query?.orderItems||[]],__teaqlPartitionBy:a&&!h?s.foreignKey:void 0,__teaqlTracePath:[...Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(e.entity)}],{level:Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath.length:2,kind:"relation",name:`${String(e.entity)}.${String(r.name)}`}],commentText:e?._comment??e?.commentText,purposeText:e?._purpose??e?.purposeText};a&&!d.orderItems.some(g=>g.field==="id")&&d.orderItems.push(Y.asc("id")),typeof d.clearContinuousPageRuntime=="function"&&d.clearContinuousPageRuntime(),d[this.internalQueryToken]=!0;const p=[];if(h)for(const g of n){const E={...d,_filters:[...d._filters,{[s.foreignKey]:{$eq:g}}],__teaqlPartitionBy:void 0};p.push(...await this.executeQuery(E))}else d._filters.push({[s.foreignKey]:{$in:n}}),p.push(...await this.executeQuery(d));for(const g of p)delete g.__teaql_partition_rank;const f=new Map;for(const g of p){const E=g[s.foreignKey],w=f.get(E)||[];w.push(g),f.set(E,w)}for(const g of t){const E=f.get(g[s.localKey])||[];g[r.name]=s.many?E:E[0]??null}m.success({attributes:{"teaql.result.cardinality":p.length}})}catch(d){throw m.failure(d),d}}}async enhanceRelationAggregates(t,e){const i=e.relationAggregates;if(!t.length||!Array.isArray(i)||!i.length)return;const r=this.schema(e.entity);for(const s of i){const n=r.relations?.[s.relationName];if(!n)throw new Error(`Missing relation ${e.entity}.${s.relationName}`);const o=t.map(h=>h[n.localKey]).filter(h=>h!=null);if(!o.length){for(const h of t)h[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{};continue}const u=s.query.clone();u.entity=n.targetEntity,u.selectItems=[],u.properties=[],u.orderItems=[],u.limitValue=0,u.offsetValue=0,u.relations=[],u.relationAggregates=[],u.aggregateItems.length||u.aggregate("Count","id",s.alias),u.groupByItems.includes(n.foreignKey)||u.groupBy(n.foreignKey),u.filterCondition={...u.filterCondition||{},[n.foreignKey]:{$in:o}},u[this.internalQueryToken]=!0;const a=await this.executeQuery(u),c=new Map;for(const h of a)c.set(h[n.foreignKey],h);for(const h of t){const l=c.get(h[n.localKey]);l?s.singleResult?h[s.alias]=l[u.aggregateItems[0].alias]??null:h[s.alias]=Object.fromEntries(Object.entries(l).filter(([m])=>m!==n.foreignKey)):h[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{}}}}emptyAggregateValue(t){const e=t.aggregateItems[0];return!e||String(e.function).toLowerCase()==="count"?0:null}queryLimit(t){if(t._limit!==void 0)return Number(t._limit);if(t.limitValue!==void 0&&Number(t.limitValue)>0)return Number(t.limitValue)}async close(){await this.driver.close()}};function De(t){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))throw new Error(`Unsafe SQL identifier: ${t}`);return t}function Ne(t){const i={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(t).toLowerCase()];if(!i)throw new Error(`Unsupported aggregate: ${t}`);return i}var Pe=class{constructor(t){this.worker=t,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=e=>{const i=e.data;if(!i||i.type!=="teaql-browser-sqlite-response")return;const r=this.pending.get(i.requestId);if(r)if(this.pending.delete(i.requestId),i.error){const s=new Error(i.error.message);s.name=i.error.name,i.error.code&&(s.code=i.error.code),r.reject(s)}else r.resolve(i.result)},this.onError=e=>{const i=new Error(e.message||"Browser SQLite worker failed");i.name="BrowserSQLiteWorkerError";for(const r of this.pending.values())r.reject(i);this.pending.clear()},t.addEventListener("message",this.onMessage),t.addEventListener("error",this.onError)}request(t,e){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const i=this.nextRequestId++;return new Promise((r,s)=>{this.pending.set(i,{resolve:n=>r(n),reject:s}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:i,operation:t,payload:e})})}async close(t){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),t&&this.worker.terminate?.();const e=new Error("Browser SQLite worker is closed");for(const i of this.pending.values())i.reject(e);this.pending.clear()}}},Oe=class{constructor(t){this.transport=t}query(t,e=[]){return this.transport.request("query",{sql:t,values:e})}},je=class ae{constructor(e,i){this.transport=e,this.options=i,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,i={}){const r={storage:i.storage??"memory",databaseName:We(i.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:i.terminateWorkerOnClose??!0},s=new Pe(e);return await s.request("open",r),new ae(s,r)}identifier(e){return`"${De(e)}"`}placeholder(e){return"?"}contains(e,i){return`CAST(${e} AS TEXT) LIKE '%' || ${i} || '%'`}aggregateFunction(e){return Ne(e)}encode(e,i){return e==null?e:i?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):i?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const i=this.accessTail;let r;this.accessTail=new Promise(s=>{r=s}),await i;try{return await e()}finally{r()}}query(e,i=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:i}))}async*stream(e,i=[]){const r=await this.query(e,i);for(const s of r.rows)yield s}transaction(e){return this.exclusive(async()=>{const i=new Oe(this.transport);await i.query("BEGIN IMMEDIATE");try{const r=await e(i);return await i.query("COMMIT"),r}catch(r){try{await i.query("ROLLBACK")}catch{}throw r}})}async ensureSchema(e){for(const i of Object.values(e)){const r=this.identifier(i.table);await this.query(`CREATE TABLE IF NOT EXISTS ${r} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const s=await this.query(`PRAGMA table_info(${r})`),n=new Set(s.rows.map(o=>String(o.name)));for(const[o,u]of Object.entries(i.columns))o==="id"||o==="version"||n.has(u.columnName)||await this.query(`ALTER TABLE ${r} ADD COLUMN ${this.identifier(u.columnName)} ${Me(u.logicalType)}${u.nullable===!1?" NOT NULL":""}`)}for(const i of qe(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(i.name)} ON ${this.identifier(i.table)} (${this.identifier(i.foreignColumn)}, ${this.identifier(i.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,i){for(let r=1;r<=100;r+=1){const s=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[i]);if(!s.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[i])).rowCount===1)return"1"}catch(a){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[i])).rowCount)throw a}continue}const n=Number(s.rows[0].id),o=n+1,u=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[o,i,n]);if(u.rowCount===1)return String(o);if(u.rowCount!==0)throw new Error(`ID space update for ${i} changed ${u.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${i} after 100 optimistic-lock attempts`)}ensureIdFloor(e,i,r){return xe(e,s=>this.placeholder(s),i,r)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}},Ve=class le extends Fe{constructor(e,i){super(e,i),this.browserDriver=e}static async open(e,i,r={}){return new le(await je.open(e,r),i)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}};function Me(t){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[t]}function We(t){const e=t.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}var Ue={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},Ke=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],ee=class extends Error{constructor(t){super(`Unsupported locale: ${t}`),this.localeCode=t}},Qe={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function ze(t){if(typeof t!="string"||!t.trim())throw new ee(t);const e=t.trim().replace(/_/g,"-").toLowerCase(),i=Ke.find(s=>s.toLowerCase()===e);if(i)return i;const r=Qe[e];if(!r)throw new ee(t);return r}var te=class{constructor(e,i){if(this.data=e,this.fallback=i,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(ze)}message(e,i){return this.data.locales[e]?.messages[i]??this.fallback?.data.locales[e]?.messages[i]??this.data.locales.en?.messages[i]??this.fallback?.data.locales.en?.messages[i]??i}translate(e,i){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(i,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};te.builtin=new te(Ue);var x=class extends Error{constructor(t){super(`Check failed: ${t.map(e=>e.message??`${e.ruleId}:${e.location}`).join("; ")}`),this.violations=t,this.name="CheckException"}};function Ge(t,e){const i=t.defaultDomainRoot,r=e.defaultDomainRoot;if(i&&r&&(i.entity!==r.entity||i.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...t.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??i,constants:[...s.values()],ensure:t.ensure&&e.ensure?async n=>{await t.ensure(n),await e.ensure(n)}:e.ensure??t.ensure}}var He=class ce{constructor(e={},i={},r={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...i}),this.bootstrap=Object.freeze({defaultDomainRoot:r.defaultDomainRoot,constants:Object.freeze([...r.constants??[]]),ensure:r.ensure})}and(e){return new ce({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},Ge(this.bootstrap,e.bootstrap))}},ie=class he{constructor(e,i,r,s){this.enabledValue=e,this.cacheExpiredMillis=i,this.propagateValue=r,this.propagateCacheExpiredMillis=s}static enabled(e){return new he(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}},Xe=class V{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,i,r,s=!0){return this.facets.push({facetName:e,relationName:i,query:r.toQuery(),includeAllFacets:s}),this}clone(){const e=new V(this.entity);return e.filterCondition=this.filterCondition,e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.orderItems=[...this.orderItems],e.selectItems=[...this.selectItems],e.properties=[...this.properties],e.joins=[...this.joins],e.groupByItems=[...this.groupByItems],e.aggregateItems=this.aggregateItems.map(i=>({...i})),e.aggregationCache=this.aggregationCache,e.facets=this.facets.map(i=>({...i,query:i.query.clone()})),e.relations=this.relations.map(i=>({...i,query:i.query?.clone()})),e.relationAggregates=this.relationAggregates.map(i=>({...i,query:i.query.clone()})),e.commentText=this.commentText,e.purposeText=this.purposeText,e.idSetPaginationOptions=this.idSetPaginationOptions,e.idSetPaginationRuntimeContext=this.idSetPaginationRuntimeContext,e.topNProbeThreshold=this.topNProbeThreshold,e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,i){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(i)||i<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:i},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,i,r){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(i)||i<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(r)||r<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:i,maxIds:r},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const i=new V(this.entity);return i.filterCondition=this.filterCondition,i.commentText=this.commentText,i.purposeText=this.purposeText,i.aggregate("Count","id",e),i}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const i of this.relations)i.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,i,r="id",s="id",n=!0){return this.relations.push({name:e,query:i,localKey:r,foreignKey:s,many:n}),this}relationAggregate(e,i,r,s=!0){return this.relationAggregates.push({relationName:e,alias:i,query:r,singleResult:s}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=ie.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=ie.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,i,r){return this.aggregateItems.push({function:e,field:i,alias:r}),this}groupBy(e){return this.groupByItems.push(e),this}},I=t=>`${t.entity}\0${typeof t.id}:${String(t.id)}`,A=class{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map}set(t,e,i){if(!e.trim())throw new TypeError("field is required");const r=I(t),s=this.changes.get(r)??{key:Object.freeze({...t}),values:{}};s.values[e]=i,this.changes.set(r,s)}snapshot(){return[...this.changes.values()].map(t=>({key:Object.freeze({...t.key}),values:Object.freeze({...t.values})}))}change(t){return Object.freeze({...this.changes.get(I(t))?.values??{}})}mergeFrom(t){if(t!==this){for(const e of t.snapshot())for(const[i,r]of Object.entries(e.values))this.set(e.key,i,r);for(const e of t.newKeys.values())this.markAsNew(e);for(const e of t.deletedKeys.values())this.markAsDeleted(e);for(const e of t.snapshotVersions())this.setOriginalVersion(e.key,e.version)}}snapshotVersions(){return[...this.originalVersions.values()]}rekey(t,e){const i=I(t),r=I(e);if(i===r)return;const s=this.changes.get(i);if(s){this.changes.delete(i);for(const[o,u]of Object.entries(s.values))this.set(e,o,u)}const n=this.originalVersions.get(i);n!==void 0&&(this.originalVersions.delete(i),this.originalVersions.set(r,{key:Object.freeze({...e}),version:n.version})),this.newKeys.delete(i)&&this.newKeys.set(r,Object.freeze({...e})),this.deletedKeys.delete(i)&&this.deletedKeys.set(r,Object.freeze({...e}))}clearEntity(t){const e=I(t);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e)}setOriginalVersion(t,e){this.originalVersions.set(I(t),{key:Object.freeze({...t}),version:e})}originalVersion(t){return this.originalVersions.get(I(t))?.version}markAsNew(t){this.newKeys.set(I(t),Object.freeze({...t}))}isNew(t){return this.newKeys.has(I(t))}markAsDeleted(t){const e=I(t);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...t}))}isDeleted(t){return this.deletedKeys.has(I(t))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear()}};function de(t){const e=t.split("_");return e[0]+e.slice(1).map(i=>i?i[0].toUpperCase()+i.slice(1):"").join("")}function Ye(t,e){if(e==="snake_case")return t;const i=de(t);return e==="camelCase"||!i?i:i[0].toUpperCase()+i.slice(1)}function Je(t){return t.replace(/~/g,"~0").replace(/\//g,"~1")}var S=class L{constructor(e){this.segments=e}static root(){return new L([])}static property(e){return L.root().property(e)}property(e){return new L([...this.segments,{kind:"property",name:e}])}index(e){return new L([...this.segments,{kind:"index",index:e}])}prefixedBy(e){return new L([...e.segments,...this.segments])}modelPath(){return this.render(e=>e)}nativePath(){return this.render(de)}instancePath(e="camelCase"){return this.segments.map(i=>i.kind==="index"?String(i.index):Je(Ye(i.name,e))).map(i=>`/${i}`).join("")}toString(){return this.nativePath()}render(e){let i="";for(const r of this.segments)r.kind==="index"?i+=`[${r.index}]`:i+=`${i?".":""}${e(r.name)}`;return i}},q=class M extends Array{static get[Symbol.species](){return Array}constructor(e=[],i={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,M.prototype),this.totalCount=i.totalCount,this.aggregations=i.aggregations??{},this.summary=i.summary??{},this.facets=i.facets??{},this.isLoaded=i.isLoaded??!0}static empty(){return new M([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,i){return this.facets[e]=i,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}};function Ze(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function W(t){if(t&&typeof t=="object"){const e=t;return e.id??e.Id}return t}function et(t,e){const i=Ze(e);for(const r of[e,`${e}Id`,i,`${i}_id`]){const s=W(t[r]);if(s!=null)return s}}async function me(t,e,i,r){const s={};for(const n of r){let o;if(t.executeFacetMembership)o=await t.executeFacetMembership(e(i.clone()),n.relationName);else{const l=i.clone();l.facets=[],l.relations=[],l.orderItems=[],l.aggregateItems=[],l.groupByItems=[],l.offsetValue=0,l.limitValue=0,l.selectItems=[n.relationName];const m=await t.executeQuery(e(l));o=new Map;for(const d of m){const p=et(d,n.relationName);if(p==null)continue;const f=String(p);o.set(f,(o.get(f)??0)+1)}}const u=n.query.clone();u.facets=[];const a=u.aggregateItems.filter(l=>String(l.function).toLowerCase()==="count").map(l=>String(l.alias));u.aggregateItems=[],u.groupByItems=[];const h=(await t.executeQuery(e(u))).map(l=>{const m=o.get(String(W(l.id??l.Id)))??0,d={...l};for(const p of a)d[p]=m;return d}).filter(l=>n.includeAllFacets||o.has(String(W(l.id??l.Id))));s[n.facetName]=new q(h)}return s}class R extends Xe{orderBy(e,i){return this.order({field:e,expr:null,direction:i==="desc"?"Desc":"Asc"})}relationQuery(e,i,r="id",s="id",n=!0){return this.relations.push({name:e,query:i,localKey:r,foreignKey:s,many:n}),this}}class b{static teaqlTemporaryId=0;id;title;description;platform;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--b.teaqlTemporaryId,writable:!0,enumerable:!1}),e){const r={...e};Object.assign(this,r),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof v?e.platform:v.fromRecord(e.platform),this.markLoaded("platform"))}const i=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(i):this.version!==void 0&&this._root.setOriginalVersion(i,Number(this.version))}teaqlEntityKey(){return{entity:"WorkItem",id:this._ledgerId}}teaqlAttachRoot(e){return this._root!==e&&(e.mergeFrom(this._root),this._root=e),this}static fromRecord(e,i){const r=new b(e);return i?r.teaqlAttachRoot(i):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const i of e)this._loadedFields.add(i);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new b({id:String(e)})}static teaqlBootstrapNew(e){return new b().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const i=e.requireResource("dataService");return i.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,i),this.teaqlSaveWithinGraph(e,i)))}teaqlPreflightGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"title",canonical:"title"},{member:"description",canonical:"description"},{member:"platform",canonical:"platform"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new x([{ruleId:"invalid_type",location:S.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}i.preflightMutation({entity:"WorkItem",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root})}async teaqlSaveWithinGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"WorkItem",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},o=await i.executeMutation(n);for(const[h,l]of Object.entries(n.payload))h!=="id"&&h!=="version"&&this._root.set(this.teaqlEntityKey(),h,l);if(!o.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},a=this.teaqlEntityKey();Object.assign(this,o.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();return this._root.rekey(a,c),i.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(c,a)}),this._loadedFields=new Set(Object.keys(o.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update"),i.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.setOriginalVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,title:this.title,description:this.description,platform:this.platform,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateTitle(e){return this.title=e,this.markLoaded("title"),this._root.set(this.teaqlEntityKey(),"title",e),this}updateDescription(e){return this.description=e,this.markLoaded("description"),this._root.set(this.teaqlEntityKey(),"description",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}}class v{static teaqlTemporaryId=0;id;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--v.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_workItemList",{value:[],writable:!0,enumerable:!1}),e){const r={...e};delete r.workItemList,Object.assign(this,r),Array.isArray(e.workItemList)&&(this._workItemList=e.workItemList.map(s=>s instanceof b?s:b.fromRecord(s)),this.markLoaded("workItemList"))}const i=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(i):this.version!==void 0&&this._root.setOriginalVersion(i,Number(this.version))}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const i of this._workItemList)i.teaqlAttachRoot(e);return this}static fromRecord(e,i){const r=new v(e);return i?r.teaqlAttachRoot(i):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const i of e)this._loadedFields.add(i);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new v({id:String(e)})}static teaqlBootstrapNew(e){return new v().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const i=e.requireResource("dataService");return i.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,i),this.teaqlSaveWithinGraph(e,i)))}teaqlPreflightGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new x([{ruleId:"invalid_type",location:S.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}i.preflightMutation({entity:"Platform",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root});for(const[s,n]of this._workItemList.entries()){n.teaqlAttachRoot(this._root),n.updatePlatform(this),n.auditAs(this._comment);try{n.teaqlPreflightGraph(e,i)}catch(o){if(!(o instanceof x))throw o;const u=S.property("work_item_list").index(s);throw new x(o.violations.map(a=>({...a,location:a.location.prefixedBy(u)})))}}}async teaqlSaveWithinGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"Platform",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},o=await i.executeMutation(n);for(const[h,l]of Object.entries(n.payload))h!=="id"&&h!=="version"&&this._root.set(this.teaqlEntityKey(),h,l);if(!o.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},a=this.teaqlEntityKey();Object.assign(this,o.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(a,c),i.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(c,a)}),this._loadedFields=new Set(Object.keys(o.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update");for(const[h,l]of this._workItemList.entries()){l.teaqlAttachRoot(this._root),l.updatePlatform(this),l.auditAs(this._comment);try{await l.teaqlSaveWithinGraph(e,e.requireResource("dataService"))}catch(m){if(!(m instanceof x))throw m;const d=S.property("work_item_list").index(h);throw new x(m.violations.map(p=>({...p,location:p.location.prefixedBy(d)})))}}return i.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.setOriginalVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}workItemList(){return this._workItemList}}class re{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new R("Platform"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new tt(i=>this.executeForListInternal(i),i=>this.executeForRowsInternal(i),(i,r,s)=>this.executeForPageInternal(i,r,s),(i,r)=>this.executeForStreamInternal(i,r),()=>this.limit(1),i=>this.comment(i),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,i){return this.query.optimizeForContinuousPageFetchWith(e,i),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,i,r){return this.query.optimizePaginationWithIdSetConfig(e,i,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectWorkItemListWith(e){return this.query.relationQuery("workItemList",e.toQuery(),"id","platform",!0),this}haveWorkItems(){return this.withWorkItemListMatching({toQuery:()=>new R("WorkItem")})}haveNoWorkItems(){return this.withoutWorkItemListMatching({toQuery:()=>new R("WorkItem")})}withWorkItemListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutWorkItemListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}countWorkItems(){return this.countWorkItemsAs("countWorkItems")}countWorkItemsAs(e){const i=new R("WorkItem").filter({version:{$gte:1}});return this.countWorkItemsWith(e,{toQuery:()=>i})}countWorkItemsWith(e,i){return i.toQuery().aggregate("Count","id",e),this.query.relationAggregate("workItemList",e,i.toQuery(),!0),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,i){return this.filters.push({id:{$between:[e,i]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,i){return this.filters.push({name:{$between:[e,i]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,i){return this.filters.push({version:{$between:[e,i]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),r=await i.executeQuery(e.prepareQuery(this.query)),s=new A,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:r.map(a=>a instanceof v?a:v.fromRecord(a,s)),u=new q(o);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await me(i,a=>e.prepareQuery(a),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService");return new q(await i.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,i,r){this.ensureIntent(),this.query.offset(i).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),a=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:o??await s.executeCount(this.query),c=new A,h=new q(u.map(l=>l instanceof v?l:v.fromRecord(l,c)));return h.totalCount=a,{data:h,totalCount:a,offset:i,limit:r}}async*executeForStreamInternal(e,i){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new A;for await(const n of r.executeForStream(this.query,i))for(const o of n)yield o instanceof v?o:v.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class tt{constructor(e,i,r,s,n,o,u){this.execute=e,this.executeRows=i,this.page=r,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new v}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,i,r){return this.ensureIntent(),this.page(e,i,r)}executeForStream(e,i=1e3){return this.ensureIntent(),this.stream(e,i)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class se{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new R("WorkItem"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new it(i=>this.executeForListInternal(i),i=>this.executeForRowsInternal(i),(i,r,s)=>this.executeForPageInternal(i,r,s),(i,r)=>this.executeForStreamInternal(i,r),()=>this.limit(1),i=>this.comment(i),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,i){return this.query.optimizeForContinuousPageFetchWith(e,i),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,i,r){return this.query.optimizePaginationWithIdSetConfig(e,i,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","title","description","platform","version"]),this}selectId(){return this.query.select(["id"]),this}selectTitle(){return this.query.select(["title"]),this}selectDescription(){return this.query.select(["description"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,i){return this.filters.push({id:{$between:[e,i]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withTitleContaining(e){return this.filters.push({title:{$contains:e}}),this}withTitleIs(e){return this.filters.push({title:{$eq:e}}),this}withTitleIsNot(e){return this.filters.push({title:{$ne:e}}),this}withTitleIn(...e){return this.filters.push({title:{$in:e}}),this}withTitleNotIn(...e){return this.filters.push({title:{$notIn:e}}),this}withTitleGreaterThan(e){return this.filters.push({title:{$gt:e}}),this}withTitleGreaterThanOrEqualTo(e){return this.filters.push({title:{$gte:e}}),this}withTitleLessThan(e){return this.filters.push({title:{$lt:e}}),this}withTitleLessThanOrEqualTo(e){return this.filters.push({title:{$lte:e}}),this}withTitleBetween(e,i){return this.filters.push({title:{$between:[e,i]}}),this}withTitleIsKnown(){return this.filters.push({title:{$isNull:!1}}),this}withTitleIsUnknown(){return this.filters.push({title:{$isNull:!0}}),this}withTitleNotContaining(e){return this.filters.push({title:{$notContains:e}}),this}withTitleStartingWith(e){return this.filters.push({title:{$startsWith:e}}),this}withTitleNotStartingWith(e){return this.filters.push({title:{$notStartsWith:e}}),this}withTitleEndingWith(e){return this.filters.push({title:{$endsWith:e}}),this}withTitleNotEndingWith(e){return this.filters.push({title:{$notEndsWith:e}}),this}withTitleSoundingLike(e){return this.filters.push({title:{$soundLike:e}}),this}withDescriptionContaining(e){return this.filters.push({description:{$contains:e}}),this}withDescriptionIs(e){return this.filters.push({description:{$eq:e}}),this}withDescriptionIsNot(e){return this.filters.push({description:{$ne:e}}),this}withDescriptionIn(...e){return this.filters.push({description:{$in:e}}),this}withDescriptionNotIn(...e){return this.filters.push({description:{$notIn:e}}),this}withDescriptionGreaterThan(e){return this.filters.push({description:{$gt:e}}),this}withDescriptionGreaterThanOrEqualTo(e){return this.filters.push({description:{$gte:e}}),this}withDescriptionLessThan(e){return this.filters.push({description:{$lt:e}}),this}withDescriptionLessThanOrEqualTo(e){return this.filters.push({description:{$lte:e}}),this}withDescriptionBetween(e,i){return this.filters.push({description:{$between:[e,i]}}),this}withDescriptionIsKnown(){return this.filters.push({description:{$isNull:!1}}),this}withDescriptionIsUnknown(){return this.filters.push({description:{$isNull:!0}}),this}withDescriptionNotContaining(e){return this.filters.push({description:{$notContains:e}}),this}withDescriptionStartingWith(e){return this.filters.push({description:{$startsWith:e}}),this}withDescriptionNotStartingWith(e){return this.filters.push({description:{$notStartsWith:e}}),this}withDescriptionEndingWith(e){return this.filters.push({description:{$endsWith:e}}),this}withDescriptionNotEndingWith(e){return this.filters.push({description:{$notEndsWith:e}}),this}withDescriptionSoundingLike(e){return this.filters.push({description:{$soundLike:e}}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,i){return this.filters.push({version:{$between:[e,i]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByTitleAscending(){return this.query.orderBy("title","asc"),this}orderByTitleDescending(){return this.query.orderBy("title","desc"),this}orderByDescriptionAscending(){return this.query.orderBy("description","asc"),this}orderByDescriptionDescending(){return this.query.orderBy("description","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByTitle(){return this.query.groupBy("title"),this}groupByTitleAs(e){return this.query.groupBy("title"),this}groupByDescription(){return this.query.groupBy("description"),this}groupByDescriptionAs(e){return this.query.groupBy("description"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,i,r=!0){return this.query.facetBy(e,"platform",i,r),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),r=await i.executeQuery(e.prepareQuery(this.query)),s=new A,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:r.map(a=>a instanceof b?a:b.fromRecord(a,s)),u=new q(o);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await me(i,a=>e.prepareQuery(a),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService");return new q(await i.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,i,r){this.ensureIntent(),this.query.offset(i).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),a=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:o??await s.executeCount(this.query),c=new A,h=new q(u.map(l=>l instanceof b?l:b.fromRecord(l,c)));return h.totalCount=a,{data:h,totalCount:a,offset:i,limit:r}}async*executeForStreamInternal(e,i){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new A;for await(const n of r.executeForStream(this.query,i))for(const o of n)yield o instanceof b?o:b.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class it{constructor(e,i,r,s,n,o,u){this.execute=e,this.executeRows=i,this.page=r,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new b}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,i,r){return this.ensureIntent(),this.page(e,i,r)}executeForStream(e,i=1e3){return this.ensureIntent(),this.stream(e,i)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class K{static platforms(){return new re(!1)}static platformsWithMinimalFields(){return new re(!0)}static workItems(){return new se(!1)}static workItemsWithMinimalFields(){return new se(!0)}}const pe={Platform:{table:"platform_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}};async function rt(t){let e=(await K.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(t))[0];e||(e=v.teaqlBootstrapNew("1"),e.updateName("Runtime Example"),await e.auditAs("create generated Domain Root Platform").save(t)),t.withActiveRoot({entity:"Platform",id:e.id})}const st=new He(pe,{Platform:{checkAndFix(t,e,i){t.getResource("fixTime"),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&i.push({ruleId:"required",location:S.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&i.push({ruleId:"max_length",location:S.property("name"),inputValue:e.payload.name,systemValue:100})}},WorkItem:{checkAndFix(t,e,i){t.getResource("fixTime"),(e.action==="Create"&&e.payload.title===void 0||e.payload.title===null)&&i.push({ruleId:"required",location:S.property("title")}),e.payload.title!=null&&!([...String(e.payload.title)].length>=1)&&i.push({ruleId:"min_length",location:S.property("title"),inputValue:e.payload.title,systemValue:1}),e.payload.title!=null&&[...String(e.payload.title)].length>80&&i.push({ruleId:"max_length",location:S.property("title"),inputValue:e.payload.title,systemValue:80}),e.payload.description!=null&&[...String(e.payload.description)].length>100&&i.push({ruleId:"max_length",location:S.property("description"),inputValue:e.payload.description,systemValue:100}),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&i.push({ruleId:"required",location:S.property("platform")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Runtime Example"}},constants:[],ensure:rt}),Q=document.querySelector("#status"),nt=document.querySelector("#result"),U=document.querySelector("#persist"),O=document.querySelector("#reset");let $;const fe=localStorage.getItem("teaql-browser-storage")==="opfs"?"opfs":"memory";U.checked=fe==="opfs";async function ut(t){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),i=await Ve.open(e,{...pe},{storage:t,databaseName:"teaql-browser-example.sqlite3"});i.install(st);const r=new oe().insertResource("dataService",i);return i.setUserContext(r),await r.ensureSchema(),{client:i,context:r}}async function ge({context:t}){if(!(await K.workItemsWithMinimalFields().comment("what: detect existing browser demo records").purpose("why: keep generated mutation bootstrap idempotent").executeForList(t)).length)for(const i of["Evaluate semantic model","Generate typed library","Verify browser runtime"])await new b().updateTitle(i).updatePlatform("1").auditAs("seed deterministic browser demo data").save(t)}async function Ee(t){const e=await K.workItems().selectTitle().orderByIdAscending().limit(20).comment("what: load browser-local work items").purpose("why: prove the generated Q API runs without a backend").executeForList(t.context);nt.textContent=JSON.stringify(e,null,2),Q.textContent=`${t.client.storage.toUpperCase()} · ${e.length} rows · ready`}async function ye(t){Q.textContent=`Opening ${t.toUpperCase()} SQLite/WASM…`;const e=$;$=void 0,await e?.client.close();const i=await ut(t);$=i,await ge(i),await Ee(i)}U.addEventListener("change",()=>{const t=U.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",t),ye(t).catch(z)});O.addEventListener("click",async()=>{if($){O.disabled=!0;try{await $.client.reset($.context),await ge($),await Ee($)}catch(t){z(t)}finally{O.disabled=!1}}});function z(t){const e=t instanceof Error?t:new Error(String(t));Q.textContent=`${e.name}: ${e.message}`}ye(fe).catch(z); diff --git a/dist/assets/index-BMClFIER.css b/dist/assets/index-BMClFIER.css deleted file mode 100644 index c4e7e4a90b396223654574378a4b8e189f0a7e23..0000000000000000000000000000000000000000 --- a/dist/assets/index-BMClFIER.css +++ /dev/null @@ -1 +0,0 @@ -:root{font:16px/1.5 Inter,system-ui,sans-serif;color:#e8edf5;background:#090b10}body{margin:0}main{width:min(760px,calc(100% - 40px));margin:10vh auto}.eyebrow{color:#d9ff52;font-size:12px;font-weight:800;letter-spacing:.16em}h1{margin:8px 0;font-size:clamp(36px,7vw,68px);letter-spacing:-.05em}.controls{display:flex;gap:18px;align-items:center;margin:32px 0}button{border:0;border-radius:5px;padding:10px 14px;background:#d9ff52;font-weight:800}#status{color:#aab4c4}pre{min-height:260px;padding:22px;overflow:auto;border:1px solid #2b323e;border-radius:8px;background:#11151c;color:#c6d1df} diff --git a/dist/assets/index-CSFBt0NB.js b/dist/assets/index-CSFBt0NB.js deleted file mode 100644 index 73e07c14a5047bac0f9b3ddcf4ea310a8b984992..0000000000000000000000000000000000000000 --- a/dist/assets/index-CSFBt0NB.js +++ /dev/null @@ -1,29 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))i(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function t(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function i(s){if(s.ep)return;s.ep=!0;const n=t(s);fetch(s.href,n)}})();var Fr=r=>{throw TypeError(r)},Mr=(r,e,t)=>e.has(r)||Fr("Cannot "+t),Q=(r,e,t)=>(Mr(r,e,"read from private field"),t?t.call(r):e.get(r)),Y=(r,e,t)=>e.has(r)?Fr("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(r):e.set(r,t),H=(r,e,t,i)=>(Mr(r,e,"write to private field"),e.set(r,t),t),Ki={},zi={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},Gi=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],fr=class extends Error{constructor(r){super(`Unsupported locale: ${r}`),this.localeCode=r}},Yi={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function jr(r){if(typeof r!="string"||!r.trim())throw new fr(r);const e=r.trim().replace(/_/g,"-").toLowerCase(),t=Gi.find(s=>s.toLowerCase()===e);if(t)return t;const i=Yi[e];if(!i)throw new fr(r);return i}var jt=class{constructor(e,t){if(this.data=e,this.fallback=t,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(jr)}message(e,t){return this.data.locales[e]?.messages[t]??this.fallback?.data.locales[e]?.messages[t]??this.data.locales.en?.messages[t]??this.fallback?.data.locales.en?.messages[t]??t}translate(e,t){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(t,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};jt.builtin=new jt(zi);var Hi=jt,Vr=Symbol("teaql.context.schema-capability");function me(r){return Object.freeze(r.map(e=>Object.freeze({...e})))}var mt,ft,Xi=class{constructor(r,e){Y(this,mt),Y(this,ft),H(this,mt,r),H(this,ft,Object.freeze({...e})),Object.freeze(this)}recover(){const r=[];let e=this;for(;e;)r.push(Q(e,ft)),e=Q(e,mt);return me(r.reverse())}};mt=new WeakMap;ft=new WeakMap;function Ji(r,e,t,i,s){const n=r?s:i;if(r&&(typeof n!="string"||new RegExp("^\\p{White_Space}*$","u").test(n)))return r;const o=String(t),a=/^(0|[1-9][0-9]*)$/.test(o)&&BigInt(o)<=18446744073709551615n?t:void 0;return new Xi(r,{kind:"auditReason",name:e,entityId:a,detail:n})}var Zi=new Set(["comment","purpose","auditReason"]),Rt=r=>!new RegExp("^\\p{White_Space}*$","u").test(r);function Vt(r,e,t){const i=o=>{for(let a=r.length-1;a>=0;a--)if(r[a].kind===o)return r[a].detail??""},s=["operation","provider","sql"].every(o=>r.some(a=>a.kind===o));let n;if(s)n=r.filter(o=>!Zi.has(o.kind));else{const o=r.find(u=>Rt(u.name))?.name??"unknown";let a=o;if(t!=="select")for(const u of r)u.kind==="entity"&&Rt(u.name)&&(a=u.name);n=[{kind:"operation",name:o,detail:t==="select"?"query":"mutation"},{kind:t==="select"?"request":"entity",name:t==="select"?o:a,detail:""},...r.filter(u=>u.kind==="relation"),{kind:"provider",name:Rt(e)?e:"unknown",detail:""},{kind:"sql",name:t,detail:""}]}return Object.freeze({tracePath:me(n),comment:i("comment"),purpose:i("purpose"),auditReason:i("auditReason")})}function Wr(r,e,t){return me([{kind:"comment",name:r,detail:e},{kind:"purpose",name:r,detail:t}])}function es(r,e,t,i){if(i&&!r.trim())throw new Error("Missing SQL template");let s=0;const n=new Set,o=h=>{if(h<0||h>=e.length)throw new Error("SQL bind count mismatch");return n.add(h),i?i(h):Ur(e[h],t)};let a="",u="sql";for(let h=0;h=0&&f=0&&ft.toString(16).padStart(2,"0")).join("")}'`:le(typeof r=="object"?JSON.stringify(r):String(r))}function le(r){return`'${r.replace(/'/g,"''")}'`}var ts="TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS",rs="I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK",bt="[REDACTED]",kt="[REDACTED SQL; NOT REPLAYABLE]",is=`-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN -`,pr=!1;function ss(r){const e=Array.from(r);return e.length<8||/^[0-9]+$/.test(r)?"*".repeat(e.length):e.slice(0,2).join("")+"*".repeat(e.length-4)+e.slice(-2).join("")}function ns(){const e=Ki?.[ts]===rs;return e&&!pr&&(pr=!0,console.warn("TeaQL: sensitive plaintext logging enabled; application data may be written to disk. Authentication secrets remain redacted.")),e}function Ze(r){const e=r.toLowerCase().replace(/[^a-z0-9]/g,"");return["password","passwd","passphrase","privatekey","secret","accesstoken","refreshtoken","idtoken","apikey","authorization","credential","sessiontoken","magiclinktoken"].some(t=>e.includes(t))}function Wt(r){return Array.isArray(r)?r.some(Wt):r&&typeof r=="object"?Object.entries(r).some(([e,t])=>Ze(e)||Wt(t)):!1}function ye(r){return r==null||r===""?[]:Array.isArray(r)?r.flatMap(ye):r instanceof Date?[r.toISOString()]:typeof r=="object"?Object.values(r).flatMap(ye):[String(r)]}function Je(r,e){return[...new Set(e)].sort((t,i)=>i.length-t.length).reduce((t,i)=>t?.split(i).join(bt),r)}var xt=new WeakMap,gr=new WeakMap,Kr=new WeakMap;function yr(r,e,t=[]){Kr.set(r,{bindings:e?re(e):void 0,intentValues:Object.freeze(t.map(et))})}function Lt(r){const e=r.parameterLogPolicies,t=!!e&&e.length===r.parameters.length,i=Ze(r.parameterizedSQL)&&(r.sqlOrigin!=="generated"||!t);return r.parameters.map((s,n)=>{if(i||Wt(s))return"credential";const o=t?e[n]:void 0;return o==="plain"||o==="masked"||o==="credential"?o:"unknown"})}function Ut(r,e){return r==="credential"||r==="unknown"||!e&&r!=="plain"}function wr(r){if(!r)return[];const e=Lt(r);return r.parameters.flatMap((t,i)=>Ut(e[i],!1)?ye(t):[])}function et(r){return r instanceof Date?new Date(r.getTime()):r instanceof Uint8Array?new Uint8Array(r):Array.isArray(r)?Object.freeze(r.map(et)):r&&typeof r=="object"?Object.freeze(Object.fromEntries(Object.entries(r).map(([e,t])=>[e,et(t)]))):r}function re(r,e){const t=e?[e,r]:[r];return Object.freeze({parameterizedSQL:"",sqlOrigin:"generated",parameters:Object.freeze(t.flatMap(i=>i.parameters.map(et))),parameterLogPolicies:Object.freeze(t.flatMap(Lt))})}function Kt(r){return r==null?null:Array.isArray(r)?r.map(Kt):r&&typeof r=="object"&&"type"in r?Kt(r.value):typeof r=="object"&&!(r instanceof Date)?bt:ss(r instanceof Date?r.toISOString():String(r))}function zr(r,e,t=[]){const i=ns()&&r.logMode!=="masked",s=xt.get(r);if(s!==void 0&&(!s||i))return r;const n=gr.get(r);if(!i&&n)return n;const o=zt(r,i,e,t);if(xt.set(o,i),i){const a=zt(r,!1,e,t);xt.set(a,!1),gr.set(o,a)}return o}function zt(r,e,t,i=[]){const s=Kr.get(r);s?.bindings&&(t=re(s.bindings,t)),s&&(i=[...i,...s.intentValues]);const n=r.parameterLogPolicies,o=!n||n.length===r.parameters.length,a=Ze(r.parameterizedSQL)&&(r.sqlOrigin!=="generated"||!n||!o),u=Lt(r),h=u.map(A=>Ut(A,e)),l=r.parameters.flatMap((A,k)=>h[k]?ye(A):[]);if(t){const A=Lt(t);l.push(...t.parameters.flatMap((k,M)=>Ut(A[M],e)?ye(k):[]))}const d=[...l,...i.flatMap(ye)],c=!e&&r.logMode==="debug-plaintext"&&!t,f=A=>c&&A?bt:Je(A,d),y=r.parameters.map((A,k)=>h[k]?u[k]==="masked"?Kt(A):bt:et(A)),O=r.parameterizedSQL.replace(/\$[0-9]+|@p[0-9]+/gi,"?"),w=(!e||a)&&r.sqlOrigin!=="generated"&&/['"`$]|--|\/\*|\b\d+\b|:[A-Za-z_]/.test(O),I=r.databaseKind??"sqlite";let S=kt,R=w?"untrusted-literal-sql":o?void 0:"policy-count-mismatch";if(!w&&o)try{S=es(r.parameterizedSQL,y,I,A=>Ur(y[A],I)+(h[A]?" /* masked */":"")),S=(e?h.some(Boolean)?`-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN; PARTIALLY MASKED; NOT REPLAYABLE -`:is:`-- TeaQL MASKED; NOT REPLAYABLE -`)+S}catch{S=kt,R="unsupported-or-mismatched-bindings"}return Object.freeze({...r,...r.statements?{statements:Object.freeze(r.statements.map(A=>zt(A,e,re(r,t),i)))}:{},parameterizedSQL:w?kt:r.sqlOrigin==="generated"?r.parameterizedSQL:Je(r.parameterizedSQL,l),parameters:Object.freeze(y),parameterLogPolicies:Object.freeze(u),maskedParameters:Object.freeze(h),logMode:e?"debug-plaintext":"masked",omissionReason:R,debugSQL:S,comment:f(r.comment),purpose:f(r.purpose),auditReason:f(r.auditReason),...r.traceChain?{traceChain:Object.freeze(r.traceChain.map(A=>Object.freeze(Object.fromEntries(Object.entries(A).map(([k,M])=>[k,k!=="entityId"&&typeof M=="string"?f(M):M])))))}:{},resultSummary:r.resultCount!==void 0?`${r.resultCount} rows returned`:r.affectedRows!==void 0?`${r.affectedRows} rows affected`:Je(r.resultSummary,l),tracePath:Object.freeze(r.tracePath.map(A=>Object.freeze(Object.fromEntries(Object.entries(A).map(([k,M])=>[k,k!=="entityId"&&typeof M=="string"?f(M):M]))))),...r.mutationLineage?{mutationLineage:Object.freeze(r.mutationLineage.map(A=>Object.freeze(Object.fromEntries(Object.entries(A).map(([k,M])=>[k,k!=="entityId"&&typeof M=="string"?f(M):M])))))}:{}})}var tt=new WeakMap,Ct=new WeakMap;function Or(r){return Ct.get(r)}function os(r,e){Ct.set(r,e)}function as(r){return tt.get(r)}function Fe(r,e){tt.set(e,tt.get(r)??Pe(r))}function Pe(r,e=new Map){if(!r||typeof r!="object")return r;if(e.has(r))return e.get(r);if(r instanceof Date)return new Date(r.getTime());if(r instanceof Uint8Array)return new Uint8Array(r);const t=Array.isArray(r)?[]:Object.create(Object.getPrototypeOf(r));e.set(r,t);for(const n of Reflect.ownKeys(r)){const o=Object.getOwnPropertyDescriptor(r,n);"value"in o&&o.enumerable&&(o.value=Pe(o.value,e)),Object.defineProperty(t,n,o)}const i=tt.get(r);i&&tt.set(t,i);const s=Ct.get(r);return s&&Ct.set(t,s),t}var pt,ue=class{constructor(r={}){Y(this,pt),H(this,pt,Pe(r)),Object.freeze(this)}values(){return Pe(Q(this,pt))}};pt=new WeakMap;var vr=new WeakMap,Dt=new WeakMap,Gt=new WeakMap,Gr=new WeakMap;function Yr(r){if(!["named-count","facet","relation-count","relation-select","aggregate","pagination"].includes(r.kind)||r.method!==void 0&&!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r.method)||r.alias!==void 0&&typeof r.alias!="string"||r.relation!==void 0&&typeof r.relation!="string")throw new Error("QUERY_OPERATION_INVALID: invalid generated operation descriptor");return Object.freeze({kind:r.kind,method:r.method,alias:r.alias,relation:r.relation})}function us(r){const e=Yr(r),t=i=>"'"+i.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+"'";return e.method?e.method+"("+(e.alias!==void 0?t(e.alias):e.kind==="relation-select"?"...":"")+")":"framework: "+e.kind+(e.relation?" "+e.relation:"")+(e.alias!==void 0?" "+t(e.alias):"")}var Ne=Symbol("runtime request binding"),hs=class extends Error{constructor(r,e,t){super(`${r}: ${t} request requires a non-blank ${e}; supply it at the request entry point`),this.code=r,this.field=e,this.requestKind=t,this.name="RequestIntentError"}};function Me(r,e,t){if(typeof r!="string"||new RegExp("^\\p{White_Space}*$","u").test(r))throw new hs(e==="comment"?"REQUEST_COMMENT_REQUIRED":"QUERY_PURPOSE_REQUIRED",e,t);return r}var gt,yt,_e=class{constructor(r,e){Y(this,gt),Y(this,yt),H(this,gt,Me(r,"comment","query")),H(this,yt,Me(e,"purpose","query")),Object.freeze(this)}get comment(){return Q(this,gt)}get purpose(){return Q(this,yt)}};gt=new WeakMap;yt=new WeakMap;var Te,he=class{constructor(r){Y(this,Te),H(this,Te,Me(r,"comment","mutation")),Object.freeze(this)}get comment(){return Q(this,Te)}get auditReason(){return Q(this,Te)}readbackIntent(){return new _e(Q(this,Te),"verify persisted mutation result")}};Te=new WeakMap;var ve,Re,wt,Ot,vt,qt,qe,ls=class Ie{constructor(e,t,i){Y(this,ve),Y(this,Re),Y(this,wt),Y(this,Ot),Y(this,vt),Y(this,qt),Y(this,qe);const s=e;if(H(this,ve,t===void 0?new _e(s?._comment??s?.commentText,s?._purpose??s?.purposeText):new _e(t?.comment,t?.purpose)),i&&i[Ne]!==!0)throw new Error("QUERY_REQUEST_OWNERSHIP_INVALID: request binding is runtime-owned");const n=Or(e),o=n instanceof Ie&&n.intent.comment===Q(this,ve).comment&&n.purpose===Q(this,ve).purpose?n:void 0;H(this,qe,i?.invocation??(i?.parent?Q(i.parent,qe):void 0)??(o?Q(o,qe):void 0)??Object.freeze({})),H(this,wt,i?i.parent:o?.parentRequest),H(this,Ot,Me(i?.comment??o?.comment??Q(this,ve).comment,"comment","query")),H(this,vt,i?.name??o?.requestName??String(s.entity??"query")),H(this,qt,i?.operation??o?.operation),H(this,Re,Pe(e));const a=Q(this,Re);for(const[u,h]of[["commentText",this.intent.comment],["purposeText",this.purpose],["_comment",this.intent.comment],["_purpose",this.purpose]])Object.defineProperty(a,u,{value:h,enumerable:!u.startsWith("_"),configurable:!0,writable:!1});Dt.set(a,me(i?.source??o?.traceSource??Dt.get(e)??Wr(String(s.entity),this.intent.comment,this.purpose))),os(a,this),Object.freeze(this)}get intent(){return Q(this,ve)}get query(){return Q(this,Re)}get comment(){return Q(this,Ot)}get purpose(){return Q(this,ve).purpose}get traceSource(){return Dt.get(Q(this,Re))}get parentRequest(){return Q(this,wt)}get rootRequest(){let e=this;for(;e.parentRequest;)e=e.parentRequest;return e}get requestName(){return Q(this,vt)}get operation(){return Q(this,qt)}get traceChain(){const e=[];for(let t=this;t;t=t.parentRequest)e.push({kind:"comment",name:t.requestName,detail:t.comment});return me([{kind:"purpose",name:this.rootRequest.requestName,detail:this.purpose},...e.reverse()])}withQuery(e){const t=Or(e);if(t instanceof Ie&&Q(t,qe)!==Q(this,qe))throw new Error("QUERY_SCOPE_OWNER_MISMATCH: replacement belongs to another query invocation");return new Ie(e,this.intent,{[Ne]:!0,parent:this.parentRequest,comment:this.comment,name:this.requestName,operation:this.operation,source:this.traceSource,invocation:Q(this,qe)})}deriveOperation(e,t){const i=Yr(t);return new Ie(e,this.intent,{[Ne]:!0,parent:this,comment:us(i),name:String(e.entity??this.requestName),operation:i,source:this.traceSource})}deriveHelper(e,t){return new Ie(e,this.intent,{[Ne]:!0,parent:this,comment:Me(t,"comment","query"),name:String(e.entity??this.requestName),source:this.traceSource})}derive(e,t,i){return this.deriveOperation(this.query,i??{kind:"relation-select",relation:t}).deriveChild(e,t)}deriveAggregate(e,t,i){const s=this.parentRequest?.operation?.kind==="facet"?this.parentRequest:void 0,n=s?s.deriveHelper(e,"aggregate "+s.operation.relation):this.deriveOperation(e,i),o=[...this.traceSource,{kind:"relation",name:t,detail:`${String(this.query.entity)}.${t}`}],a=new Ie(e,this.intent,{[Ne]:!0,parent:n.parentRequest,comment:n.comment,name:n.requestName,operation:n.operation,source:o});return(e._comment??e.commentText)===void 0?a:a.deriveChild(e)}deriveChild(e,t,i){const s=e,n=s._comment??s.commentText;return new Ie(e,this.intent,{[Ne]:!0,parent:this,comment:n===void 0?i??"load "+String(s.entity):Me(n,"comment","query"),name:String(s.entity),source:t===void 0?this.traceSource:[...this.traceSource,{kind:"relation",name:t,detail:`${String(this.query.entity)}.${t}`}]})}};ve=new WeakMap;Re=new WeakMap;wt=new WeakMap;Ot=new WeakMap;vt=new WeakMap;qt=new WeakMap;qe=new WeakMap;var U=ls,ke,Le,Ce=class{constructor(r,e){Y(this,ke),Y(this,Le),H(this,ke,new he(e===void 0?r?.comment:e?.comment)),H(this,Le,{...r}),Object.defineProperty(Q(this,Le),"comment",{value:Q(this,ke).comment,enumerable:!0,writable:!1,configurable:!1}),Object.freeze(this)}get intent(){return Q(this,ke)}get mutation(){return Q(this,Le)}get comment(){return Q(this,ke).comment}withLoadedSnapshot(r){return vr.set(this,new ue(r.values())),this}loadedValues(){return vr.get(this)?.values()??{}}get graphSession(){return Gt.get(this)?.session}scopeFor(r){const e=Gt.get(this),t=Ji(e?.parent,r.entity,r.id,this.comment,e?.localComment);return e&&Gr.set(t,e.session),t}traceFor(r){const e=Q(this,Le),t=e.ledgerRoot?.traceChain(e.ledgerKey??r);return t?.length?me(t):this.scopeFor(r).recover()}auditProjection(r,e,t){const i=[...ye(e),...ye(Q(this,Le).id),...t?wr(t):ye(this.loadedValues()),...wr(this.graphSession?.logBindings)];return Object.freeze({reason:Je(this.comment,i),mutationLineage:me(this.traceFor(r).map(s=>({...s,detail:Je(s.detail,i)})))})}};ke=new WeakMap;Le=new WeakMap;var Ge,Ye,ds=class{constructor(r){Y(this,Ge),Y(this,Ye),H(this,Ge,new he(r?.comment)),Object.freeze(this)}get intent(){return Q(this,Ge)}request(r,e,t){if(e&&Gr.get(e)!==this)throw new Error("GRAPH_TRACE_SCOPE_MISMATCH: parent scope belongs to another graph invocation");const i=new Ce(r,Q(this,Ge));return Gt.set(i,{session:this,parent:e,localComment:t}),i}captureLogBindings(r){H(this,Ye,re(r,Q(this,Ye)))}get logBindings(){return Q(this,Ye)}};Ge=new WeakMap;Ye=new WeakMap;var qr=class extends Error{constructor(r){super("GRAPH_ALREADY_COMMITTED: post-commit processing failed; do not retry as an uncommitted mutation"),this.cause=r,this.committed=!0,this.name="GraphCommittedError"}},cs="MUTATION-POLICY-001",ms="MUTATION-POLICY-002",ie=class extends Error{constructor(r){super(r),this.name="MutationPolicyError"}},fs=class{constructor(r){this.resolver=r}resolve(r){return this.resolver(r)}},ps=class{constructor(r){this.finder=r}findApproval(r){return this.finder(r)}},gs=class{onWarning(r,e){!e.firstOccurrence||typeof console>"u"||console.warn(`TeaQL mutation policy warning code=${e.warningCode} requestKey=${e.snapshot.requestKey} source=${e.snapshot.source} approval=${e.snapshot.approvalStatus}`)}},Ir=0,ys=class{constructor(){this.profile={warningSink:new gs},this.emittedWarnings=new Set,this.graphActive=!1,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.remaining=new Map}setRegistry(r){this.profile.registry=r}setApprovalProvider(r){this.profile.approvalProvider=r}setWarningSink(r){this.profile.warningSink=r}beginGraph(){if(this.graphActive)throw new ie("mutation policy graph is already active");this.graphActive=!0,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.rootEntity=void 0,this.auditReason=void 0,this.remaining.clear(),this.graphSnapshot=void 0}endGraph(){this.graphActive=!1,this.graphReviewed=!1,this.preflight=[],this.preflightKeys=[],this.rootEntity=void 0,this.auditReason=void 0,this.remaining.clear(),this.graphSnapshot=void 0}recordPreflight(r){if(!this.graphActive)return;if(this.graphReviewed)throw new ie("mutation preflight cannot change after policy review");const e=Ar(r);this.rootEntity??(this.rootEntity=e.entity),this.auditReason??(this.auditReason=dt(r)),this.preflight.push(e),this.preflightKeys.push(br(r,e))}enterMutation(r,e){const t=Ar(e);if(!this.graphActive)return{snapshot:this.review(r,this.plan(t.entity,dt(e),[t]))};if(!this.graphReviewed){if(this.profile.registry&&this.preflight.length===0)throw new ie("customer mutation policy requires complete graph preflight before provider mutation");if(!this.profile.registry&&this.preflight.length===0)return{snapshot:this.review(r,this.plan(t.entity,dt(e),[t]))};const i=this.preflight.length?this.preflight:[t];this.graphSnapshot=this.review(r,this.plan(this.rootEntity??i[0].entity,this.auditReason??dt(e),i)),this.remaining.clear();const s=this.preflight.length?this.preflightKeys:i.map(Xr);for(const n of s)this.remaining.set(n,(this.remaining.get(n)??0)+1);this.graphReviewed=!0}return this.consume(br(e,t)),{snapshot:this.graphSnapshot}}ensureGraphComplete(){if(this.graphReviewed&&this.remaining.size)throw new ie("reviewed mutation plan contains operations that were not executed")}review(r,e){ws(e);const t=Sr(e),i=this.profile.registry?.resolve(t.requestKey);let s,n,o,a;if(!i)s="generated_default",o="not_applicable",a=[cs];else{n=Os(i.identity);const h=i.review(r,t);if(!h||h.verdict!=="allow"&&h.verdict!=="deny")throw new ie("customer mutation policy returned an invalid decision");if(h.verdict==="deny")throw new ie(`[MUTATION POLICY DENIED] ${h.code||"MUTATION-POLICY-DENIED"}: ${h.message||"mutation rejected"}`);s="customer";const l=this.profile.approvalProvider?.findApproval(n);o=vs(l,n)?"approved":"missing",a=o==="approved"?[]:[ms]}const u=Object.freeze({executionId:t.executionId,requestKey:t.requestKey,source:s,policy:n,approvalStatus:o,warningCodes:Object.freeze([...a]),operations:Object.freeze(t.operations.map(h=>Object.freeze({kind:h.kind,entity:h.entity,entityId:$e(h.entityId),changedFields:Object.freeze(Object.keys(h.changedValues).sort())})))});for(const h of a)this.emitWarning(r,u,h);return u}plan(r,e,t){return Ir+=1,Sr({executionId:`teaql-mutation-${Ir}`,requestKey:`${r}.saveGraph`,rootEntityType:r,auditReason:new he(e).comment,operations:t})}consume(r){const e=this.remaining.get(r)??0;if(e<1)throw new ie("provider mutation is not present in the reviewed graph plan");e===1?this.remaining.delete(r):this.remaining.set(r,e-1)}emitWarning(r,e,t){const i=e.policy?`${e.policy.policyId}:${e.policy.version}:${e.policy.fingerprint}`:"none",s=`${e.requestKey}|${i}|${t}`,n=!this.emittedWarnings.has(s);this.emittedWarnings.add(s);try{this.profile.warningSink.onWarning(r,Object.freeze({snapshot:e,warningCode:t,firstOccurrence:n}))}catch{}}};function Ar(r){const e=String(r?.entity??"").trim(),t=String(r?.action??"").toLowerCase(),i={create:"create",update:"update",delete:"delete",recover:"recover"};if(!e||!i[t])throw new ie("mutation must contain a supported entity operation");const s=r?.payload&&typeof r.payload=="object"?r.payload:{};return Object.freeze({kind:i[t],entity:e,entityId:$e(r?.id??s.id),originalVersion:r?.version??r?.expectedVersion,changedValues:Hr(s)})}function dt(r){return new he(r?.comment).comment}function ws(r){if(new he(r?.auditReason),!r.executionId?.trim())throw new ie("execution id is required");if(!r.requestKey?.trim())throw new ie("request key is required");if(!r.rootEntityType?.trim())throw new ie("root entity type is required");if(!r.operations.length)throw new ie("mutation plan is empty")}function Os(r){if(!r||!r.policyId?.trim()||!r.version?.trim()||!r.fingerprint?.trim())throw new ie("customer mutation policy identity is invalid");return Object.freeze({policyId:r.policyId.trim(),version:r.version.trim(),fingerprint:r.fingerprint.trim()})}function vs(r,e){return!!r&&qs(r.policy,e)&&!!r.approvedBy?.trim()&&r.approvedAt instanceof Date&&Number.isFinite(r.approvedAt.getTime())&&r.approvedAt.getTime()!==0}function qs(r,e){return r.policyId===e.policyId&&r.version===e.version&&r.fingerprint===e.fingerprint}function Sr(r){return Object.freeze({executionId:r.executionId,requestKey:r.requestKey,rootEntityType:r.rootEntityType,auditReason:r.auditReason,operations:Object.freeze(r.operations.map(e=>Object.freeze({kind:e.kind,entity:e.entity,entityId:$e(e.entityId),originalVersion:e.originalVersion,changedValues:Hr(e.changedValues)})))})}function $e(r,e=new WeakSet){if(r==null||typeof r=="string"||typeof r=="number"||typeof r=="boolean"||typeof r=="bigint")return r;if(r instanceof Date)return r.toISOString();if(typeof r=="object"){if(e.has(r))throw new ie("mutation policy values must not contain cycles");e.add(r);try{if(Array.isArray(r))return Object.freeze(r.map(i=>$e(i,e)));const t=r;return"id"in t&&Object.keys(t).some(i=>i!=="id")?$e(t.id,e):Object.freeze(Object.fromEntries(Object.entries(t).map(([i,s])=>[i,$e(s,e)])))}finally{e.delete(r)}}return String(r)}function Hr(r){return Object.freeze(Object.fromEntries(Object.entries(r).map(([e,t])=>[e,$e(t)])))}function Xr(r){return _t({kind:r.kind,entity:r.entity,entityId:r.entityId,originalVersion:r.originalVersion,changedValues:r.changedValues})}function br(r,e){const t=r?.ledgerKey;return t&&typeof t=="object"&&String(t.entity??"").trim()&&t.id!==void 0&&t.id!==null?`ledger:${String(t.entity).trim()}:${_t(t.id)}`:`operation:${Xr(e)}`}function _t(r){return typeof r=="bigint"?JSON.stringify(`${r.toString()}n`):r===void 0?'""':r===null||typeof r!="object"?JSON.stringify(r):Array.isArray(r)?`[${r.map(_t).join(",")}]`:`{${Object.entries(r).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${_t(t)}`).join(",")}}`}var Lr=new WeakMap,Is=1;function As(r){if(!r||typeof r!="object"&&typeof r!="function")return String(r);const e=r;let t=Lr.get(e);return t||(t=Is++,Lr.set(e,t)),String(t)}var Cr=class extends Error{constructor(r,e,t){super(`context root ${r}: expected ${e}`),this.reason=r,this.expectedType=e,this.activeRoot=t,this.name="ContextRootError"}},Jr=class{constructor(){this.mutationPolicy=new ys,this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(r,e)=>this.getContinuousPageCursor(r,e),put:(r,e,t)=>this.putContinuousPageCursor(r,e,t),observe:(r,e)=>{this.continuousPagePlan=r,this.continuousPageCursorId=e}},this.idSetPaginationRuntime={owner:"",scope:"",get:r=>this.idSetStore().get(r),put:(r,e)=>this.idSetStore().put(r,e),build:(r,e)=>this.singleFlightIdSetBuild(r,e),observe:(r,e)=>{this.idSetPaginationPlan=r,this.idSetPaginationCount=e,this.idSetPaginationCountAccuracy=r==="ID_SET_BUILD"||r==="ID_SET_HIT"?"EXACT":r==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=Hi.builtin}setLocaleCode(r){const e=jr(r);return this.locale=e,this}setLanguageCode(r){return this.setLocaleCode(r)}installI18nCatalog(r){if(!r)throw new Error("catalog is required");return this.i18nCatalog=r,this}installIdSetPaginationStore(r){if(!r)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",r)}translateCheckResults(r){return r.map(e=>this.i18nCatalog.translate(e,this.locale))}withMutationPolicyRegistry(r){if(!r||typeof r.resolve!="function")throw new TypeError("mutation policy registry must expose resolve(requestKey)");return this.mutationPolicy.setRegistry(r),this}withMutationPolicyApprovalProvider(r){if(!r||typeof r.findApproval!="function")throw new TypeError("mutation policy approval provider must expose findApproval(identity)");return this.mutationPolicy.setApprovalProvider(r),this}withMutationGovernanceSink(r){if(!r||typeof r.onWarning!="function")throw new TypeError("mutation governance sink must expose onWarning(context, warning)");return this.mutationPolicy.setWarningSink(r),this}reviewMutationPlan(r){return this.mutationPolicy.review(this,r)}beginMutationPolicyGraph(){this.mutationPolicy.beginGraph()}recordMutationPolicyPreflight(r){this.mutationPolicy.recordPreflight(r)}enterMutationPolicy(r){return this.mutationPolicy.enterMutation(this,r).snapshot}ensureMutationPolicyGraphComplete(){this.mutationPolicy.ensureGraphComplete()}endMutationPolicyGraph(){this.mutationPolicy.endGraph()}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(r){const e=String(r.sourceLabel||""),t=e.toLowerCase();if(!r.entityType||!r.modelPath||!e||t.includes("authorization")||t.includes("cookie")||t.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const i=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",i),i.push(Object.freeze({...r})),this}finishFixEvidence(){const r=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...r])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(r,e){return this.resources.set(r,e),this}getResource(r){return this.resources.get(r)}removeResource(r){return this.resources.delete(r),this}requireResource(r){const e=this.getResource(r);if(e===void 0)throw new Error(`Required UserContext resource is missing: ${r}`);return e}ensureSchema(){const r=this.requireResource("dataService"),e=r[Vr];if(!e)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return e.call(r,this)}withActiveRoot(r){if(!r||!r.entity||r.id===void 0||r.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...r}))}requireActiveRoot(r){const e=this.getResource("activeRoot");if(!e)throw new Cr("missing",r);if(e.entity!==r)throw new Cr("type_mismatch",r,e);return e}prepareQuery(r){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const e=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,e?`${e.entity}:${String(e.id)}`:"-",As(this.getResource("dataService"))].join("|"),r.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(r,e){const t=`${r}:${e}`,i=this.continuousPageCursors.get(t);if(i&&i.expiresAt<=Date.now()){this.continuousPageCursors.delete(t);return}return i}putContinuousPageCursor(r,e,t){if(this.continuousPageCursors.size>=4096){const i=[...this.continuousPageCursors.entries()].sort((s,n)=>s[1].expiresAt-n[1].expiresAt)[0];i&&this.continuousPageCursors.delete(i[0])}this.continuousPageCursors.set(`${r}:${e}`,t)}getRetainedIdSet(r){const e=this.retainedIdSets.get(r);if(e&&e.expiresAt<=Date.now()){this.retainedIdSets.delete(r);return}return e}idSetStore(){return this.getResource("idSetPaginationStore")??{get:r=>this.getRetainedIdSet(r),put:(r,e)=>this.putRetainedIdSet(r,e),invalidate:r=>{this.retainedIdSets.delete(r)}}}putRetainedIdSet(r,e){if(e.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const i=()=>[...this.retainedIdSets.values()].reduce((s,n)=>s+n.ids.byteLength,0);for(;this.retainedIdSets.size>=64||i()+e.ids.byteLength>268435456;){const s=[...this.retainedIdSets.entries()].sort((n,o)=>n[1].expiresAt-o[1].expiresAt)[0];if(!s)break;this.retainedIdSets.delete(s[0])}this.retainedIdSets.set(r,e)}async singleFlightIdSetBuild(r,e){const t=this.idSetBuilds.get(r);if(t)return{value:await t,built:!1};const i=e();this.idSetBuilds.set(r,i);try{return{value:await i,built:!0}}finally{this.idSetBuilds.delete(r)}}},j=class extends Error{constructor(r){super(`Check failed: ${r.map(e=>e.message??`${e.ruleId}:${e.location}`).join("; ")}`),this.violations=r,this.name="CheckException"}},rt=class He{constructor(e,t,i){this.field=e,this.expr=t,this.direction=i}static new(e,t){return new He(e,null,t)}static expr(e,t){return new He("",e,t)}static asc(e){return He.new(e,"Asc")}static desc(e){return He.new(e,"Desc")}},_r=class Zr{constructor(e,t,i,s){this.enabledValue=e,this.cacheExpiredMillis=t,this.propagateValue=i,this.propagateCacheExpiredMillis=s}static enabled(e){return new Zr(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}},ei=class ti{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,t,i,s=!0,n){return this.facets.push({facetName:e,relationName:t,query:i.toQuery(),includeAllFacets:s,operation:n}),this}clone(){const e=Pe(this);for(const t of["commentText","purposeText","_comment","_purpose"]){const i=Object.getOwnPropertyDescriptor(e,t);i&&"value"in i&&i.configurable&&Object.defineProperty(e,t,{...i,writable:!0})}return e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,t){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:t},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,t,i){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(i)||i<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:t,maxIds:i},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const t=new ti(this.entity);return t.filterCondition=Pe(this.filterCondition),t.commentText=this.commentText,t.purposeText=this.purposeText,t.aggregate("Count","id",e),Fe(this,t),t}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const t of this.relations)t.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,t,i="id",s="id",n=!0,o){return this.relations.push({name:e,query:t,localKey:i,foreignKey:s,many:n,operation:o}),this}relationAggregate(e,t,i,s=!0,n){return this.relationAggregates.push({relationName:e,alias:t,query:i,singleResult:s,operation:n}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=_r.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=_r.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,t,i){return this.aggregateItems.push({function:e,field:t,alias:i}),this}groupBy(e){return this.groupByItems.push(e),this}};function ri(r,e){const t=r.defaultDomainRoot,i=e.defaultDomainRoot;if(t&&i&&(t.entity!==i.entity||t.id!==i.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...r.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:i??t,constants:[...s.values()],ensure:r.ensure&&e.ensure?async n=>{await r.ensure(n),await e.ensure(n)}:e.ensure??r.ensure}}var Ss=class ii{constructor(e={},t={},i={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...t}),this.bootstrap=Object.freeze({defaultDomainRoot:i.defaultDomainRoot,constants:Object.freeze([...i.constants??[]]),ensure:i.ensure})}and(e){return new ii({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},ri(this.bootstrap,e.bootstrap))}},X=class Yt extends Array{static get[Symbol.species](){return Array}constructor(e=[],t={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,Yt.prototype),this.totalCount=t.totalCount,this.aggregations=t.aggregations??{},this.summary=t.summary??{},this.facets=t.facets??{},this.isLoaded=t.isLoaded??!0}static empty(){return new Yt([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,t){return this.facets[e]=t,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}};function bs(r){return r.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function Ht(r){if(r&&typeof r=="object"){const e=r;return e.id??e.Id}return r}function Ls(r,e){const t=bs(e);for(const i of[e,`${e}Id`,t,`${t}_id`]){const s=Ht(r[i]);if(s!=null)return s}}async function oe(r,e,t,i){const s=new U(t);t=s.query;const n={};for(const o of i){const a=s.deriveOperation(t,o.operation??{kind:"facet",relation:o.relationName,alias:o.facetName}),u=o.query.aggregateItems.filter(w=>String(w.function).toLowerCase()==="count").map(w=>String(w.alias));let h;if(r.executeFacetMembership)h=await r.executeFacetMembership(a.deriveHelper(e(t.clone()),"aggregate "+o.relationName).query,o.relationName,u);else{const w=t.clone();Fe(t,w),w.facets=[],w.relations=[],w.relationAggregates=[],w.orderItems=[],w.aggregateItems=[],w.groupByItems=[],w.offsetValue=0,w.limitValue=0,w.selectItems=[o.relationName];const I=await r.executeQuery(a.deriveHelper(e(w),"aggregate "+o.relationName).query);h=new Map;for(const S of I){const R=Ls(S,o.relationName);if(R==null)continue;const $=String(R);h.set($,(h.get($)??0)+1)}}const l=a.deriveChild(o.query.clone(),o.relationName),d=l.query,c=d.facets;d.facets=[],d.aggregateItems=[],d.groupByItems=[];for(const w of d.relationAggregates){if(w.query.entity!==t.entity)continue;const I=t.clone();I.selectItems=["id"],I.properties=[],I.relations=[],I.relationAggregates=[],I.facets=[],I.aggregateItems=[],I.groupByItems=[],I.orderItems=[],I.offsetValue=0,I.limitValue=0;const S={id:{$inSubquery:{query:I,field:"id"}}};w.query.filterCondition=w.query.filterCondition?{$and:[w.query.filterCondition,S]}:S,Fe(t,w.query)}if(!o.includeAllFacets){const w={id:{$in:[...h.keys()]}};d.filterCondition=d.filterCondition?{$and:[d.filterCondition,w]}:w}Fe(t,d);const y=(await r.executeQuery(l.withQuery(e(d)).query)).map(w=>{const I=h.get(String(Ht(w.id??w.Id)))??0,S={...w};for(const R of u)S[R]=I;return S}).filter(w=>o.includeAllFacets||h.has(String(Ht(w.id??w.Id)))),O=new X(y);c.length&&(O.facets=await oe(r,e,l.withQuery(d).query,c)),n[o.facetName]=O}return n}var $r=Object.freeze({success:()=>{},failure:()=>{}}),Cs=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function _s(r){const e={"teaql.operation.family":r.family,"teaql.operation.name":r.name};for(const[t,i]of Object.entries(r.attributes||{}))Cs.has(t)||(e[t]=i);return Object.freeze({...r,attributes:Object.freeze(e)})}function It(r,e){if(!r)return $r;try{const t=r.start(_s(e));let i=!1;return{run:t.run?s=>t.run(s):s=>s(),success(s){if(!i){i=!0;try{t?.success(s)}catch{}}},failure(s){if(!i){i=!0;try{t?.failure(s)}catch{}}}}}catch{return $r}}async function ze(r,e,t,i){const s=It(r,e);try{const n=await(s.run?s.run(t):t());return s.success(i?.(n)),n}catch(n){throw s.failure(n),n}}function $s(r){const e=new Map;for(const t of Object.values(r))for(const i of Object.values(t.relations||{})){if(!i.many)continue;const s=r[i.targetEntity],n=s?.columns[i.foreignKey]?.columnName,o=s?.columns.id?.columnName;if(!s||!n||!o)continue;const a=`idx_${s.table}_${n}_${o}`;let u=2166136261;for(let d=0;d>>0).toString(36),l=a.length<=30?a:`${a.slice(0,Math.max(1,29-h.length))}_${h}`;e.set(l,{name:l,table:s.table,foreignColumn:n,idColumn:o})}return[...e.values()]}async function Ps(r,e,t,i){const s=Number(i);if(!Number.isSafeInteger(s)||s<0)throw new Error(`Invalid ID space floor ${i} for ${t}`);for(let n=1;n<=100;n+=1){const o=await r.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[t]);if(!o.rowCount){try{if((await r.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[t,s])).rowCount===1)return}catch(h){if(!(await r.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[t])).rowCount)throw h}continue}const a=Number(o.rows[0].id);if(a>=s)return;const u=await r.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[s,t,a]);if(u.rowCount===1)return;if(u.rowCount!==0)throw new Error(`ID space floor update for ${t} changed ${u.rowCount} rows on attempt ${n}`)}throw new Error(`Unable to synchronize ID space floor for ${t} after 100 optimistic-lock attempts`)}function Es(r,e){return r===e?!0:(r instanceof Date&&(r=r.getTime()),e instanceof Date&&(e=e.getTime()),r!=null&&e!==null&&e!==void 0&&String(r)===String(e))}function At(r){return Object.freeze(r.map((e,t)=>Object.freeze({...e,level:t})))}function Bt(r,e,t,i,s,n){const o=r.traceFor({entity:String(e.entity),id:s}),a=Vt([...o,{kind:"entity",name:String(e.entity),entityId:s,detail:""}],t,i);return{auditReason:r.comment,tracePath:At(a.tracePath),mutationLineage:o,targetID:s,inheritedBindings:re(n,r.graphSession?.logBindings)}}var Ns=class{constructor(r=e=>console.debug(e)){this.writer=r}write(r){r=zr(r),this.writer(`[TeaQL SQL][${r.operation}][${r.elapsedMicros}us] ${r.resultSummary}${r.executionOutcome?` outcome=${r.executionOutcome}`:""} -comment=${r.comment??""} purpose=${r.purpose??""} auditReason=${r.auditReason??""} tracePath=${Qt(r.tracePath)} traceChain=${Qt(r.traceChain??[])} mutationLineage=${Qt(r.mutationLineage??[])} -`+(r.omissionReason?`SQL omitted: ${r.omissionReason} -`:"")+`Debug SQL: ${r.debugSQL}`)}};function Qt(r){return JSON.stringify(r,(e,t)=>typeof t=="bigint"?t.toString():t)}var Ts=class{constructor(){this.mode="all",this.entries=[]}record(r){const e=r.operation==="select";this.mode==="disabled"||this.mode==="select"&&!e||this.mode==="mutation"&&e||this.entries.push(Object.freeze({...r,parameters:Object.freeze([...r.parameters])}))}setMode(r){return this.mode=r,this.entries=[],this}enableAll(){return this.setMode("all")}enableSelect(){return this.setMode("select")}enableMutation(){return this.setMode("mutation")}disable(){return this.setMode("disabled")}snapshot(){return[...this.entries]}},Rs=class{constructor(r,e){this.driver=r,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.bindLogPolicies=new WeakMap,this.bindOperandSources=new WeakMap,this.derivedQueryBindings=new WeakMap,this.derivedRelationAssembly=new WeakMap,this.auditEvents=[],this.diagnosticSQLLogSink=new Ns,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.checkers={},this.userContext=new Jr,this.bootstrap={},this.graphAuditActions=[],this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve(),this.schemas={...e}}fieldLogPolicy(r,e){const t=r.columns[e],i=t?.modelName??t?.columnName??e;return Ze(i)||Ze(e)?"credential":r.auditMaskFields?r.auditMaskFields?.includes(i)||r.auditMaskFields?.includes(e)?"masked":t?.logPolicy??"unknown":"unknown"}bindValue(r,e,t,i){const s=this.bindLogPolicies.get(r)??r.map(()=>"unknown");r.push(e),s.push(t),this.bindLogPolicies.set(r,s),i!==void 0&&this.bindOperandSources.set(r,re({parameterizedSQL:"",parameters:[i],parameterLogPolicies:[t],sqlOrigin:"generated"},this.bindOperandSources.get(r)))}queryLogBindings(r,e){return re({parameterizedSQL:r,parameters:e,parameterLogPolicies:this.bindLogPolicies.get(e),sqlOrigin:"generated"},this.bindOperandSources.get(e))}install(r){return Object.assign(this.schemas,r.schemas),Object.assign(this.checkers,r.checkers),this.bootstrap=ri(this.bootstrap,r.bootstrap),this}setUserContext(r){return this.userContext=r,this}schema(r){const e=this.schemas[r];if(!e)throw new Error(`Unknown TeaQL entity: ${r}`);return e}toRuntimeMutationRecord(r,e){const t={};for(const[i,s]of Object.entries(e)){const n=r.columns[i]?i:Object.keys(r.columns).find(o=>r.columns[o].modelName===i||r.columns[o].columnName===i);n&&(t[n]=s)}return t}encode(r,e){const t=r?.id??r;if(t!==void 0)return this.driver.encode(t,e)}decodeRow(r,e,t=[]){const i=this.schema(r),s={...e};for(const[n,o]of Object.entries(i.columns)){const a=s[n];a!=null&&(o.decode==="number"&&(s[n]=Number(a)),o.decode==="string"&&(s[n]=String(a)),o.decode==="date"&&a instanceof Date&&(s[n]=a.toISOString()),o.logicalType==="boolean"&&(s[n]=!!a))}for(const n of t)s[n]!==null&&s[n]!==void 0&&(s[n]=Number(s[n]));return s}get auditTrace(){return[...this.auditEvents]}setAuditSink(r){return this.auditSink=r,this}setRuntimeTelemetrySink(r){return this.telemetrySink=r,this}setDiagnosticSQLLogSink(r){return this.diagnosticSQLLogSink=r,this}setQueryLoggingEnabled(r){return this.queryLoggingEnabled=r,this}setMutationLoggingEnabled(r){return this.mutationLoggingEnabled=r,this}setRuntimeTelemetry(r){return this.runtimeTelemetry=r,this}recordSQL(r,e,t,i,s,n,o={},a="success",u){const l=r==="select"?this.queryLoggingEnabled:this.mutationLoggingEnabled,{targetID:d,inheritedBindings:c,...f}=o,y=Object.freeze({operation:r,...f,executionOutcome:a,tracePath:At(o.tracePath??[]),...o.traceChain?{traceChain:me(o.traceChain)}:{},...o.mutationLineage?{mutationLineage:me(o.mutationLineage)}:{},parameterizedSQL:e,parameters:Object.freeze([...t]),debugSQL:"",databaseKind:this.driver.databaseKind,sqlOrigin:"generated",parameterLogPolicies:Object.freeze([...this.bindLogPolicies.get(t)??t.map(()=>"unknown")]),elapsedMicros:Math.max(0,(Date.now()-i)*1e3),resultCount:s,affectedRows:n,resultSummary:s!==void 0?`${s} rows returned`:n!==void 0?`${n} rows affected`:`statement ${a}; row count unknown`}),O=c&&u?re(u,c):c??u,w=this.bindOperandSources.get(t),I=w?re(w,O):O;if(yr(y,I,d===void 0?[]:[d]),!this.telemetrySink&&!(l&&this.diagnosticSQLLogSink))return y;try{const S=zr(y);try{this.telemetrySink?.record(S)}catch{}if(l)try{this.diagnosticSQLLogSink?.write(S)}catch{}}catch{}return y}queryLogIntent(r){const e=new U(r),t=Vt(e.traceSource,this.driver.databaseKind,"select");return{comment:e.intent.comment,purpose:e.purpose,traceChain:e.traceChain,tracePath:At(t.tracePath)}}async executeLoggedSQL(r,e,t,i,s,n,o){const a=Date.now();let u;try{u=await s()}catch(l){try{const d=this.recordSQL(r,e,t,a,void 0,void 0,i,"failure",n);o?.push(d)}finally{throw l}}const h=this.recordSQL(r,e,t,a,r==="select"?u.rowCount:void 0,r==="select"?void 0:u.rowCount,i,"success",n);return o?.push(h),u}async[Vr](r){this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const e=this.bootstrapTail;let t;this.bootstrapTail=new Promise(n=>{t=n}),await e,this.userContext=r;const i=r.getResource("bootstrapActor"),s=r.getResource("bootstrapCategory");r.insertResource("bootstrapActor","teaql-generated-bootstrap"),r.insertResource("bootstrapCategory","runtime-bootstrap");try{this.bootstrap.ensure?await this.bootstrap.ensure(r):await this.ensureBootstrapData()}finally{i===void 0?r.removeResource("bootstrapActor"):r.insertResource("bootstrapActor",i),s===void 0?r.removeResource("bootstrapCategory"):r.insertResource("bootstrapCategory",s),t()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const r=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];r.length&&await this.executeGraphSave(new he("reconcile model bootstrap data"),async e=>{for(const t of r)await this.reconcileBootstrapEntity(this.graphMutationSession,e,t)})}async reconcileBootstrapEntity(r,e,t){const i=this.schema(t.entity),s=Object.entries(t.values??{}).map(([l,d])=>{const c=i.columns[l];if(!c)throw new Error(`Unknown bootstrap field ${t.entity}.${l}`);return{column:c.columnName,value:this.driver.encode(d,c)}}),n=new ei(t.entity).filter({id:{$eq:t.id}}).limit(1).comment("inspect model bootstrap record").purpose("ensure model-defined root and constants");n.prepareForList();const o=new U(n),a=`SELECT * FROM ${this.driver.identifier(i.table)} WHERE ${this.driver.identifier(i.columns.id?.columnName??"id")} = ${this.driver.placeholder(1)}`,u=[t.id];this.bindLogPolicies.set(u,[this.fieldLogPolicy(i,"id")]);const h=await this.executeLoggedSQL("select",a,u,this.queryLogIntent(o.query),()=>r.query(a,u));if(!h.rowCount)await this.executeMutation(e.request({entity:t.entity,action:"Create",id:t.id,version:0,payload:{...t.values}}));else{const l=h.rows[0];s.filter(c=>!Es(l[c.column],c.value)).length&&await this.executeMutation(e.request({entity:t.entity,action:"Update",id:t.id,version:Number(l[i.columns.version?.columnName??"version"]),payload:{...this.decodeRowForSchema(i,l),...t.values}}))}await this.driver.ensureIdFloor(r,t.entity,t.id)}async executeGraphSave(r,e){const t=new ds(r),i=this.graphSaveTail;let s;this.graphSaveTail=new Promise(u=>{s=u}),await i;let n=!1,o=!1,a=!1;try{this.graphCommitActions=[],this.graphRollbackActions=[],this.graphAuditActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence(),n=!0,this.userContext.beginMutationPolicyGraph(),o=!0;const u=await this.driver.transaction(async d=>{this.graphMutationSession=d,this.activeGraph=t;try{const c=await e(t);return this.userContext.ensureMutationPolicyGraphComplete(),c}finally{this.graphMutationSession=void 0,this.activeGraph=void 0}});a=!0;let h,l=!1;for(const d of[...this.graphCommitActions,...this.graphAuditActions])try{await d()}catch(c){l||(h=c),l=!0}if(l)throw new qr(h);return u}catch(u){if(!a)for(const h of[...this.graphRollbackActions].reverse())try{h()}catch{}throw u}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.graphAuditActions=[],o&&this.userContext.endMutationPolicyGraph(),this.userContext.removeResource("fixTime"),n&&this.userContext.finishFixEvidence(),s()}}afterGraphCommit(r){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(r)}afterGraphRollback(r){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(r)}requireGraphOwnership(r){if(r.graphSession!==this.activeGraph||this.graphMutationSession!==void 0&&r.graphSession===void 0)throw new Error("GRAPH_MUTATION_SESSION_REQUIRED: use the explicit active graph request capability")}async withMutationSession(r,e){return this.requireGraphOwnership(r),r.graphSession?e(this.graphMutationSession):this.driver.transaction(e)}preflightMutation(r){const e=r instanceof Ce?r:new Ce(r);if(this.requireGraphOwnership(e),r=this.checkAndFixMutation(e),e.graphSession){const t=this.schema(r.entity);e.graphSession.captureLogBindings(this.mutationLogBindings(e,r,t))}return this.userContext.recordMutationPolicyPreflight(r),r}mutationLogBindings(r,e,t){const i=s=>{const n=this.toRuntimeMutationRecord(t,s),o=Object.keys(n);return{parameterizedSQL:"",sqlOrigin:"generated",parameters:o.map(a=>n[a]),parameterLogPolicies:o.map(a=>this.fieldLogPolicy(t,a))}};return re(i(e.payload||{}),i(r.loadedValues()))}checkAndFixMutation(r){const e=r instanceof Ce?r:new Ce(r);this.requireGraphOwnership(e),r=e.mutation,r={...r,payload:{...r?.payload??{}}},Object.defineProperty(r,"comment",{value:e.comment,enumerable:!0});const t=this.checkers[String(r.entity)];if(!t)return r;const i=[],s=this.userContext.getResource("fixTime")===void 0;s&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(t.checkAndFix(this.userContext,r,i),r.ledgerKey&&r.ledgerRoot)for(const[n,o]of Object.entries(r.payload||{}))r.ledgerRoot.set(r.ledgerKey,n,o);if(this.userContext.translateCheckResults(i),i.length)throw new j(i);return r}finally{s&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(r){const e=r instanceof Ce?r:new Ce(r);this.requireGraphOwnership(e),r=e.mutation;const t=It(this.runtimeTelemetry,{family:"mutation",name:`${String(r?.entity||"unknown")}.${String(r?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(r?.entity||"unknown"),"teaql.mutation.kind":String(r?.action||"unknown").toLowerCase()}});try{r=this.checkAndFixMutation(e);const i=this.userContext.enterMutationPolicy(r),s=this.schema(r.entity),n=this.toRuntimeMutationRecord(s,r.payload||{}),o=this.mutationLogBindings(e,r,s),a=this.driver.identifier(s.table),u=[],h=await ze(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(r.action).toLowerCase()}},()=>this.withMutationSession(e,async y=>{if(r.action==="Create"){const O=r.id?String(r.id):await this.driver.nextId(y,r.entity);r.id&&await this.driver.ensureIdFloor(y,r.entity,O);const w=Number(r.version||0)+1,I={...n,id:O,version:w},S=Object.keys(s.columns).filter(B=>I[B]!==void 0),R=S.map(B=>this.driver.identifier(s.columns[B].columnName)).join(", "),$=S.map((B,fe)=>this.driver.placeholder(fe+1)).join(", "),A=S.map(B=>this.encode(I[B],s.columns[B]));this.bindLogPolicies.set(A,S.map(B=>this.fieldLogPolicy(s,B)));const k=`INSERT INTO ${a} (${R}) VALUES (${$})`,M=Bt(e,r,this.driver.databaseKind,"insert",O,o);return await this.executeLoggedSQL("insert",k,A,M,()=>y.query(k,A),void 0,u),{success:!0,id:O,version:w,persistedRecord:await this.readPersistedRecord(y,s,O,M,k,A,u)}}if(r.action==="Update"){const O=Object.keys(s.columns).filter(B=>B!=="id"&&B!=="version"&&n[B]!==void 0),w=O.map(B=>this.encode(n[B],s.columns[B]));this.bindLogPolicies.set(w,O.map(B=>this.fieldLogPolicy(s,B)));const I=O.map((B,fe)=>`${this.driver.identifier(s.columns[B].columnName)} = `+this.driver.placeholder(fe+1)),S=this.driver.identifier("version");I.push(`${S} = ${S} + 1`),this.bindValue(w,String(r.id),this.fieldLogPolicy(s,"id"));const R=[`${this.driver.identifier("id")} = ${this.driver.placeholder(w.length)}`];r.version!==void 0&&r.version!==null&&(this.bindValue(w,Number(r.version),this.fieldLogPolicy(s,"version")),R.push(`${S} = ${this.driver.placeholder(w.length)}`));const $=`UPDATE ${a} SET ${I.join(", ")} WHERE ${R.join(" AND ")}`,A=Bt(e,r,this.driver.databaseKind,"update",String(r.id),o);if((await this.executeLoggedSQL("update",$,w,A,()=>y.query($,w),void 0,u)).rowCount!==1)throw new Error(`Optimistic lock failed or ${r.entity}(${r.id}) does not exist`);const M=await this.readPersistedRecord(y,s,String(r.id),A,$,w,u);return{success:!0,id:String(r.id),version:Number(M.version),persistedRecord:M}}if(r.action==="Delete"){const O=this.driver.identifier("version"),w=[String(r.id)];this.bindLogPolicies.set(w,[this.fieldLogPolicy(s,"id")]);const I=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];r.version!==void 0&&r.version!==null&&(this.bindValue(w,Number(r.version),this.fieldLogPolicy(s,"version")),I.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(w.length)));const S=`UPDATE ${a} SET ${O} = -(${O} + 1) WHERE ${I.join(" AND ")}`,R=Bt(e,r,this.driver.databaseKind,"delete",String(r.id),o);if((await this.executeLoggedSQL("delete",S,w,R,()=>y.query(S,w),void 0,u)).rowCount!==1)throw new Error(`Optimistic lock failed or ${r.entity}(${r.id}) does not exist`);const A=await this.readPersistedRecord(y,s,String(r.id),R,S,w,u);return{success:!0,id:String(r.id),version:Number(A.version),deleted:!0,persistedRecord:A}}throw new Error(`Unsupported mutation action: ${r.action}`)})),l=e.auditProjection({entity:String(r.entity),id:h.id},r.payload,o),d=Object.freeze({entity:r.entity,action:r.action,id:String(h.id),...l,recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.freeze(Object.keys(r.payload||{}).sort()),version:h.version,mutationGovernance:i}),c=async()=>{this.auditEvents.push(d),this.auditSink&&await ze(this.runtimeTelemetry,{family:"audit",name:`${r.entity}.audit`,attributes:{"teaql.entity.type":String(r.entity),"teaql.mutation.kind":String(r.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(r.payload||{}).length}},async()=>this.auditSink(d))};if(e.graphSession)this.graphAuditActions.push(c);else try{await c()}catch(y){throw new qr(y)}t.success();const f=Object.freeze({...u[0],statements:Object.freeze([...u])});return yr(f,re(o,e.graphSession?.logBindings),[h.id]),{...h,metadata:f}}catch(i){throw t.failure(i),i}}async readPersistedRecord(r,e,t,i,s,n,o){const u=`SELECT ${Object.entries(e.columns).map(([S,R])=>`${this.driver.identifier(R.columnName)} AS ${this.driver.identifier(S)}`).join(", ")} FROM ${this.driver.identifier(e.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,h=[t];this.bindLogPolicies.set(h,[this.fieldLogPolicy(e,"id")]);const l=Date.now();let d;const c={parameterizedSQL:s,parameters:n,parameterLogPolicies:this.bindLogPolicies.get(n),sqlOrigin:"generated"},f=i.tracePath?.find(S=>S.kind==="operation")?.name??"unknown",y=Vt([...Wr(f,i.auditReason,"verify persisted mutation result"),...(i.tracePath??[]).filter(S=>S.kind==="relation")],this.driver.databaseKind,"select"),O={...i,tracePath:At(y.tracePath),comment:i.auditReason,purpose:"verify persisted mutation result"},w=S=>o.push(this.recordSQL("select",u,h,l,d?.rowCount,void 0,O,S,c));let I;try{if(d=await r.query(u,h),d.rowCount!==1)throw new Error(`Persisted ${e.table}(${t}) could not be read back`);I=this.decodeRowForSchema(e,d.rows[0])}catch(S){const R=d?"success":S instanceof Error&&(S.name==="AbortError"||S.name==="TimeoutError")?"cancelled":"failure";try{w(R)}finally{throw S}}return w("success"),I}decodeRowForSchema(r,e){const t={...e};for(const[i,s]of Object.entries(r.columns)){const n=t[i];n!=null&&(s.decode==="number"&&(t[i]=Number(n)),s.decode==="string"&&(t[i]=String(n)),s.decode==="date"&&n instanceof Date&&(t[i]=n.toISOString()),s.logicalType==="boolean"&&(t[i]=!!n))}return t}compileExpression(r,e,t){if(Array.isArray(r?.$and))return`(${r.$and.map(n=>this.compileExpression(n,e,t)).join(" AND ")})`;const i=Object.entries(r||{}).map(([s,n])=>{const o=e.columns[s];if(!o)throw new Error(`Unknown field ${s} for SQL query`);const a=this.driver.identifier(o.columnName),u=this.fieldLogPolicy(e,s);if(n?.$eq!==void 0){const h=n.$eq?.id??n.$eq;return h===null?`${a} IS NULL`:(this.bindValue(t,this.encode(h,o),u),`${a} = ${this.driver.placeholder(t.length)}`)}if(n?.$ne!==void 0){const h=n.$ne?.id??n.$ne;return h===null?`${a} IS NOT NULL`:(this.bindValue(t,this.encode(h,o),u),`${a} <> ${this.driver.placeholder(t.length)}`)}if(n?.$soundLike!==void 0)return this.bindValue(t,String(n.$soundLike),u),`SOUNDEX(${a}) = SOUNDEX(${this.driver.placeholder(t.length)})`;if(n?.$contains!==void 0)return this.bindValue(t,String(n.$contains),u),this.driver.contains(a,this.driver.placeholder(t.length));if(n?.$notContains!==void 0)return this.bindValue(t,String(n.$notContains),u),`NOT (${this.driver.contains(a,this.driver.placeholder(t.length))})`;for(const[h,l,d,c]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(n?.[h]!==void 0){const f=String(n[h]);this.bindValue(t,`${l}${f}${d}`,u,f);const y=`${a} LIKE ${this.driver.placeholder(t.length)}`;return c?`NOT (${y})`:y}if(Array.isArray(n?.$in)){if(!n.$in.length)return"FALSE";const h=n.$in.map(l=>(this.bindValue(t,this.encode(l?.id??l,o),u),this.driver.placeholder(t.length)));return`${a} IN (${h.join(", ")})`}if(Array.isArray(n?.$notIn)){if(!n.$notIn.length)return"TRUE";const h=n.$notIn.map(l=>(this.bindValue(t,this.encode(l?.id??l,o),u),this.driver.placeholder(t.length)));return`${a} NOT IN (${h.join(", ")})`}for(const[h,l]of[["$inSubquery",!1],["$notInSubquery",!0]]){const d=n?.[h];if(d!==void 0){const c=d.query,f=this.schema(c?.entity),y=String(d.field),O=f.columns[y];if(!O)throw new Error(`Unknown subquery projection ${y} for ${c?.entity}`);const w=this.filters(c).map(R=>this.compileExpression(R,f,t));f.columns.version&&w.push(`${this.driver.identifier(f.columns.version.columnName)} > 0`),l&&w.push(`${this.driver.identifier(O.columnName)} IS NOT NULL`);const I=w.length?` WHERE ${w.join(" AND ")}`:"",S=`SELECT ${this.driver.identifier(O.columnName)} FROM ${this.driver.identifier(f.table)}${I}`;return`${a} ${l?"NOT IN":"IN"} (${S})`}}if(Array.isArray(n?.$between)&&n.$between.length===2){this.bindValue(t,this.encode(n.$between[0],o),u);const h=this.driver.placeholder(t.length);this.bindValue(t,this.encode(n.$between[1],o),u);const l=this.driver.placeholder(t.length);return`${a} BETWEEN ${h} AND ${l}`}if(n?.$isNull===!0)return`${a} IS NULL`;if(n?.$isNull===!1)return`${a} IS NOT NULL`;if(n?.$gte!==void 0)return this.bindValue(t,this.encode(n.$gte,o),u),`${a} >= ${this.driver.placeholder(t.length)}`;if(n?.$lte!==void 0)return this.bindValue(t,this.encode(n.$lte,o),u),`${a} <= ${this.driver.placeholder(t.length)}`;if(n?.$gt!==void 0)return this.bindValue(t,this.encode(n.$gt,o),u),`${a} > ${this.driver.placeholder(t.length)}`;if(n?.$lt!==void 0)return this.bindValue(t,this.encode(n.$lt,o),u),`${a} < ${this.driver.placeholder(t.length)}`;throw new Error(`Unsupported query predicate for ${s}: ${JSON.stringify(n)}`)});return i.length?`(${i.join(" AND ")})`:"TRUE"}filters(r){return Array.isArray(r._filters)&&r._filters.length?r._filters:r.filterCondition?[r.filterCondition]:[]}groupBy(r){return r._groupBy||r.groupByItems||[]}aggregates(r){return Array.isArray(r._aggregates)?r._aggregates:(r.aggregateItems||[]).map(e=>({func:e.function,field:e.field,retName:e.alias}))}orders(r){return Array.isArray(r._orderBy)?r._orderBy.map(e=>({field:e.f,direction:e.d})):(r.orderItems||[]).map(e=>({field:e.field,direction:e.direction}))}async compileQuery(r,e=!0,t=[]){new _e(r?._comment??r?.commentText,r?._purpose??r?.purposeText);const i=this.schema(r.entity),s=[],n=this.groupBy(r),o=n.map($=>{if(!i.columns[$])throw new Error(`Unknown group field: ${$}`);return this.driver.identifier(i.columns[$].columnName)}),a=n.map($=>`${this.driver.identifier(i.columns[$].columnName)} AS `+this.driver.identifier($)),u=[],h=Array.isArray(r.selectItems)&&r.selectItems.length?[...new Set(["id","version",...r.selectItems])]:Object.keys(i.columns);if(!n.length&&!this.aggregates(r).length){for(const A of t)h.includes(A)||h.push(A);const $=[...(r.relations??[]).map(A=>A.name),...(r.relationAggregates??[]).map(A=>A.relationName)];for(const A of $){const k=i.relations?.[A];if(!k)throw new Error(`Missing relation ${r.entity}.${A}`);h.includes(k.localKey)||h.push(k.localKey)}}for(const $ of h)if(!i.columns[$])throw new Error(`Unknown selected field: ${$}`);let l=h.map($=>{const A=i.columns[$];return`${this.driver.identifier(A.columnName)} AS ${this.driver.identifier($)}`}).join(", ");const d=this.aggregates(r);if(d.length){const $=d.map(A=>{if(!i.columns[A.field])throw new Error(`Unknown aggregate field: ${A.field}`);return u.push(A.retName),`${this.driver.aggregateFunction(A.func)}(${this.driver.identifier(i.columns[A.field].columnName)}) AS `+this.driver.identifier(A.retName)});l=[...a,...$].join(", ")}const c=r.__teaqlPartitionBy,f=this.orders(r),y=f.map($=>{if(!i.columns[$.field])throw new Error(`Unknown order field: ${$.field}`);const A=String($.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(i.columns[$.field].columnName)} ${A}`});if(c){const $=i.columns[c];if(!$)throw new Error(`Unknown partition field: ${c}`);const A=y.length?` ORDER BY ${y.join(", ")}`:"";l+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier($.columnName)}${A}) AS `+this.driver.identifier("__teaql_partition_rank")}let O=`SELECT ${l} FROM ${this.driver.identifier(i.table)}`;const I=this.filters(r).map($=>this.compileExpression($,i,s));i.columns.version&&I.push(`${this.driver.identifier(i.columns.version.columnName)} > 0`),I.length&&(O+=` WHERE ${I.join(" AND ")}`),o.length&&(O+=` GROUP BY ${o.join(", ")}`);const S=r._limit!==void 0?Number(r._limit):Number(r.limitValue||0),R=r._offset!==void 0?Number(r._offset):Number(r.offsetValue||0);if(c){const $=this.driver.identifier("__teaql_partition_rank"),A=[];this.bindValue(s,R,"plain"),A.push(`${$} > ${this.driver.placeholder(s.length)}`),S>0&&(this.bindValue(s,R+S,"plain"),A.push(`${$} <= ${this.driver.placeholder(s.length)}`)),O=`SELECT * FROM (${O}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${A.join(" AND ")} ORDER BY ${$}`}else f.length&&(O+=` ORDER BY ${y.join(", ")}`);return!c&&S>0&&(this.bindValue(s,S,"plain"),O+=` LIMIT ${this.driver.placeholder(s.length)}`),!c&&R>0&&(this.bindValue(s,R,"plain"),O+=` OFFSET ${this.driver.placeholder(s.length)}`),e&&this.sqlTrace.push(O),{sql:O,values:s,aggregateNames:u}}async executeQuery(r){const e=r instanceof U?r:new U(r);return!(r instanceof U)&&r?.[this.internalQueryToken]!==!0&&typeof r?.prepareForList=="function"&&r.prepareForList(),this.executeQueryWithIntent(e.query,this.derivedQueryBindings.get(r),this.derivedRelationAssembly.get(r))}async executeDerivedQuery(r,e,t,i){const s=new U(r,t).query;e&&this.derivedQueryBindings.set(s,e),i&&this.derivedRelationAssembly.set(s,i);try{return await this.executeQuery(s)}finally{this.derivedQueryBindings.delete(s),this.derivedRelationAssembly.delete(s)}}descendantBindings(r,e,t,i){if(!(!r.relations?.length&&!r.relationAggregates?.length))return re(this.queryLogBindings(e,t),i)}async queryTreeBindings(r,e,t,i){let s=re(this.queryLogBindings(e,t),i);const n=new _e(r._comment??r.commentText,r._purpose??r.purposeText),o=[r],a=new Set;for(;o.length;){const u=o.pop();if(!u||a.has(u))continue;if(a.add(u),u!==r){const l=await this.compileQuery(new U(u,n).query,!1);s=re(this.queryLogBindings(l.sql,l.values),s)}const h=as(u);h&&o.push(h);for(const l of[...u.relations??[],...u.relationAggregates??[],...u.facets??[]])l.query&&o.push(l.query)}return s}async executeQueryWithIntent(r,e,t){const i=It(this.runtimeTelemetry,{family:"query",name:`${String(r?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(r?.entity||"unknown")}});try{const s=r?.[this.internalQueryToken]===!0;if(!s){if(typeof r?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");r.prepareForList()}const n=s?{query:r,execution:void 0}:await this.prepareIdSetPage(r,e),o=s?n:await this.prepareContinuousPage(n.query);r=new U(r).withQuery(o.query).query;const{sql:a,values:u,aggregateNames:h}=await this.compileQuery(r,!0,t?[t.field]:[]);e=await this.queryTreeBindings(r,a,u,e);const d=(await this.executeLoggedSQL("select",a,u,this.queryLogIntent(r),()=>ze(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.query`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}},()=>this.driver.query(a,u)),e)).rows.map(f=>this.decodeRow(r.entity,f,h));if(n.execution?.pageIds){const f=new Map(n.execution.pageIds.map((y,O)=>[String(y),O]));d.sort((y,O)=>(f.get(String(y.id))??Number.MAX_SAFE_INTEGER)-(f.get(String(O.id))??Number.MAX_SAFE_INTEGER))}const c=this.descendantBindings(r,a,u,e);if(t)for(const f of d)t.keys.set(f,f[t.field]);if(await this.enhanceQueryRows(d,r,c),t&&Array.isArray(r.selectItems)&&r.selectItems.length&&!["id","version",...r.selectItems,...this.groupBy(r)].includes(t.field)){const f=this.schema(r.entity);if(![...(r.relations??[]).map(O=>O.name),...(r.relationAggregates??[]).map(O=>O.relationName)].some(O=>f.relations?.[O]?.localKey===t.field))for(const O of d)delete O[t.field]}return s||await this.registerContinuousPage(r,o.execution,d),i.success({attributes:{"teaql.result.cardinality":d.length}}),d}catch(s){throw i.failure(s),s}}async prepareIdSetPage(r,e){const t=r.localIdSetPaginationOptions?.(),i=r.localIdSetPaginationRuntime?.();if(!t||!i)return i?.observe("ID_SET_DISABLED"),{query:r};const s=this.queryLimit(r);if(!s||r.localContinuousPageOptions?.()||this.aggregates(r).length||this.groupBy(r).length||r.__teaqlPartitionBy)return i.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:r};if((r.orderItems||[]).some(y=>y.expr!=null))return i.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:r};this.orders(r).some(y=>y.field==="id")||(r=r.clone().order(rt.asc("id")));const n=r.clone();n.offsetValue=0,n.limitValue=0,n.selectItems=[],n.relations=[],n.commentText=void 0,n.purposeText=void 0,n.clearIdSetPaginationRuntime(),n.clearContinuousPageRuntime();const o=`${t.namespace}|${i.scope}|${JSON.stringify(n)}`;let a=2166136261;for(let y=0;y>>0).toString(16)}`;let h,l=!1;try{h=i.get(u)}catch{return i.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:r}}if(h)l=!0,i.observe("ID_SET_HIT",h.ids.length);else{let y;try{y=await i.build(u,async()=>{const O=i.get(u);if(O)return O;const w=r.clone();w.selectItems=["id"],w.relations=[],w.relationAggregates=[],w.facets=[],w.offsetValue=0,w.limitValue=t.maxIds+1,w.clearIdSetPaginationRuntime(),w.clearContinuousPageRuntime(),w[this.internalQueryToken]=!0;const I=new U(r).deriveHelper(w,`collect ${r.entity} IDs for pagination`),S=await this.compileQuery(r,!1),R=await this.queryTreeBindings(r,S.sql,S.values,e),$=await this.executeDerivedQuery(I.query,R,I.intent);if($.length>t.maxIds)return;let A;try{A=BigUint64Array.from($.map(M=>BigInt(M.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const k={ids:A,expiresAt:Date.now()+t.ttlSeconds*1e3};return i.put(u,k),k})}catch(O){return i.observe(O instanceof Error&&O.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:r}}if(h=y.value,!h)return i.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",t.maxIds+1),{query:r};l=!y.built,i.observe(l?"ID_SET_HIT":"ID_SET_BUILD",h.ids.length)}const d=Number(r.offsetValue||r._offset||0),c=Array.from(h.ids.slice(d,d+s)),f=r.clone();return f.offsetValue=0,f.limitValue=Math.max(c.length,1),f.filterCondition=f.filterCondition?{$and:[f.filterCondition,{id:{$in:c}}]}:{id:{$in:c}},f.clearIdSetPaginationRuntime(),i.observe(l?"ID_SET_HIT":"ID_SET_BUILD",h.ids.length),{query:f,execution:{pageIds:c,totalCount:h.ids.length}}}async executeFacetMembership(r,e,t=[]){const i=new U(r);r=i.query;const s=i.withQuery(r.clone()).query;Fe(r,s),s.facets=[],s.relations=[],s.relationAggregates=[],s.orderItems=[],s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.groupByItems=[e];const n=t.length?[...t]:["__teaql_facet_count"];s.aggregateItems=n.map(a=>({function:"Count",field:"id",alias:a})),s[this.internalQueryToken]=!0;const o=await this.executeQuery(s);return new Map(o.flatMap(a=>{const u=a[e],h=Number(a[n[0]]??0);return u==null?[]:[[String(u),h]]}))}async executeCount(r,e,t){const i=r instanceof U?r:new U(r);if(r=i.query,typeof r?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const s=e??"__teaql_total",n=i.deriveOperation(r.forExactCount(s),t??{kind:"named-count",...e!==void 0?{alias:e}:{}}),a=(await this.executeQuery(n.query))[0]?.[s];if(typeof a!="number"||!Number.isFinite(a))throw new Error(`TeaQL provider did not return exact count alias ${s}`);return a}async prepareContinuousPage(r){const e=r.localContinuousPageOptions?.(),t=r.localContinuousPageRuntime?.();if(!e||!t)return t?.observe("DISABLED"),{query:r};const i=this.orders(r),s=this.queryLimit(r);if(!s||i.length!==1||i[0].field!=="id"||this.aggregates(r).length||this.groupBy(r).length||r.__teaqlPartitionBy)return t.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:r};const n=Object.assign(Object.create(Object.getPrototypeOf(r)),r);n.orderItems=[...r.orderItems||[]],n.relations=[...r.relations||[]],Object.defineProperty(n,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:e}),Object.defineProperty(n,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:t});const o=Number(r.offsetValue||r._offset||0),a={...JSON.parse(JSON.stringify(n)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},u=`${e.namespace}|${t.owner}|${JSON.stringify(a)}`;let h=2166136261;for(let y=0;y>>0).toString(16)}`,d={queryKey:l,offset:o,limit:s,direction:String(i[0].direction).toLowerCase(),ttlSeconds:e.ttlSeconds,runtime:t,optimized:!1};if(o===0)return t.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:n,execution:d};let c;try{c=await ze(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>t.get(l,o))}catch{return t.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:n,execution:d}}if(!c)return t.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:n,execution:d};const f={id:{[d.direction==="desc"?"$lt":"$gt"]:c.boundary}};return n.filterCondition=n.filterCondition?{$and:[n.filterCondition,f]}:f,n.offsetValue=0,n._offset!==void 0&&(n._offset=0),d.optimized=!0,d.cursorId=c.cursorId,t.observe("CURSOR_SEEK",c.cursorId),{query:n,execution:d}}async registerContinuousPage(r,e,t){if(!(!e||t.length!==e.limit||!t.length||t[t.length-1].id===void 0)){try{await ze(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>e.runtime.put(e.queryKey,e.offset+t.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:t[t.length-1].id,expiresAt:Date.now()+e.ttlSeconds*1e3}))}catch{e.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}e.optimized&&e.runtime.observe("CURSOR_SEEK",e.cursorId)}}executeForStream(r,e=1e3){try{const t=r instanceof U?new U(r.query,r.intent):new U(r);return this.executeCapturedStream(t.query,e)}catch(t){return(async function*(){throw t})()}}async*executeCapturedStream(r,e){if(!Number.isInteger(e)||e<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(r.facets)&&r.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:t,values:i,aggregateNames:s}=await this.compileQuery(r),n=await this.queryTreeBindings(r,t,i),o=Date.now();let a="cancelled",u=0,h=[];const l=this.descendantBindings(r,t,i,n);try{for await(const d of this.driver.stream(t,i))h.push(this.decodeRow(r.entity,d,s)),h.length===e&&(await this.enhanceQueryRows(h,r,l),u+=h.length,yield h,h=[]);h.length&&(await this.enhanceQueryRows(h,r,l),u+=h.length,yield h),a="success"}catch(d){throw a="failure",d}finally{if(a==="failure")try{this.recordSQL("select",t,i,o,u,void 0,this.queryLogIntent(r),a,n)}catch{}else this.recordSQL("select",t,i,o,u,void 0,this.queryLogIntent(r),a,n)}}async enhanceQueryRows(r,e,t){if(!r.length)return;const i=[...(e.relations??[]).map(o=>o.name),...(e.relationAggregates??[]).map(o=>o.relationName)];if(!i.length)return;const s=this.schema(e.entity),n=new Map;for(const o of i){const a=s.relations?.[o];if(!a)throw new Error(`Missing relation ${e.entity}.${o}`);n.has(a.localKey)||n.set(a.localKey,r.map(u=>u[a.localKey]))}await this.enhanceRelationAggregates(r,e,n,t),await this.enhanceRelations(r,e,n,t)}async enhanceRelations(r,e,t,i){if(!r.length||!Array.isArray(e.relations)||!e.relations.length)return;const s=this.schema(e.entity),n=new _e(e._comment??e.commentText,e._purpose??e.purposeText);for(const o of e.relations){const a=s.relations?.[o.name];if(!a)throw new Error(`Missing relation ${e.entity}.${o.name}`);const u=t.get(a.localKey),h=u.filter(I=>I!=null),l=o.query?this.queryLimit(o.query):void 0,d=o.query?.localTopNProbeParentThreshold?.(),c=a.many&&l!==void 0,f=this.driver.topNRelationPlanPolicy==="alwaysProbe",y=c&&(d===void 0?f:d>0&&h.length<=d),O=y?"bounded_probes":"window",w=It(this.runtimeTelemetry,{family:"relation_load",name:`${e.entity}.${String(o.name)}`,attributes:{"teaql.entity.type":String(e.entity),"teaql.relation.name":String(o.name),"teaql.relation.parent_count":h.length,"teaql.relation.per_parent_limit":l??0,"teaql.relation.configured_probe_threshold":d??"provider-default","teaql.relation.selected_plan":O,"teaql.relation.probe_count":y?h.length:0}});try{if(!h.length&&!(a.many&&o.query?.facets?.length)){for(const A of r)A[o.name]=a.many?[]:null;w.success({attributes:{"teaql.result.cardinality":0}});continue}const I={...o.query||{},entity:a.targetEntity,_filters:[...this.filters(o.query||{})],relations:[...o.query?.relations||[]],orderItems:[...o.query?.orderItems||[]],__teaqlPartitionBy:c&&!y?a.foreignKey:void 0};if(c){const A=this.groupBy(I),k=A.length||this.aggregates(I).length?A:["id"];for(const M of k)I.orderItems.some(B=>B.field===M)||I.orderItems.push(rt.asc(M))}typeof I.clearContinuousPageRuntime=="function"&&I.clearContinuousPageRuntime(),I[this.internalQueryToken]=!0;const S=[],R={field:a.foreignKey,keys:new WeakMap};if(y)for(const A of h){const k={...I,_filters:[...I._filters,{[a.foreignKey]:{$eq:A}}],__teaqlPartitionBy:void 0};S.push(...await this.executeDerivedQuery(new U(e).derive(k,o.name,o.operation).query,i,n,R))}else I._filters.push({[a.foreignKey]:{$in:h}}),S.push(...await this.executeDerivedQuery(new U(e).derive(I,o.name,o.operation).query,i,n,R));for(const A of S)delete A.__teaql_partition_rank;const $=new Map;for(const A of S){if(!R.keys.has(A))throw new Error("Relation assembly lost its captured row identity");const k=R.keys.get(A),M=$.get(k)||[];M.push(A),$.set(k,M)}for(const[A,k]of r.entries()){const M=$.get(u[A])||[];if(a.many&&o.query?.facets?.length){const B=o.query.clone();B.entity=a.targetEntity;const fe=u[A],Ve={[a.foreignKey]:fe==null?{$in:[]}:{$eq:fe}};B.filterCondition=B.filterCondition?{$and:[B.filterCondition,Ve]}:Ve,Fe(e,B);const Et=new U(e).derive(B,o.name,o.operation).query;k[o.name]=new X(M,{facets:await oe(this,We=>We,Et,B.facets)})}else{const B=u[A];k[o.name]=a.many?M:M[0]??(B==null?null:{[a.foreignKey]:B})}}w.success({attributes:{"teaql.result.cardinality":S.length}})}catch(I){throw w.failure(I),I}}}async enhanceRelationAggregates(r,e,t,i){const s=e.relationAggregates;if(!r.length||!Array.isArray(s)||!s.length)return;const n=this.schema(e.entity),o=new _e(e._comment??e.commentText,e._purpose??e.purposeText);for(const a of s){const u=n.relations?.[a.relationName];if(!u)throw new Error(`Missing relation ${e.entity}.${a.relationName}`);const h=t.get(u.localKey),l=h.filter(O=>O!=null);if(!l.length){for(const O of r)O[a.alias]=a.singleResult?this.emptyAggregateValue(a.query):{};continue}const d=a.query.clone();d.entity=u.targetEntity,d.selectItems=[],d.properties=[],d.orderItems=[],d.limitValue=0,d.offsetValue=0,d.relations=[],d.relationAggregates=[],d.aggregateItems.length||d.aggregate("Count","id",a.alias),d.groupByItems.includes(u.foreignKey)||d.groupBy(u.foreignKey);const c={[u.foreignKey]:{$in:l}};d.filterCondition=d.filterCondition?{$and:[d.filterCondition,c]}:c,d[this.internalQueryToken]=!0;const f=await this.executeDerivedQuery(new U(e).deriveAggregate(d,a.relationName,a.operation??{kind:"relation-count",relation:a.relationName,alias:a.alias}).query,i,o),y=new Map;for(const O of f)y.set(O[u.foreignKey],O);for(const[O,w]of r.entries()){const I=y.get(h[O]);I?a.singleResult?w[a.alias]=I[d.aggregateItems[0].alias]??null:w[a.alias]=Object.fromEntries(Object.entries(I).filter(([S])=>S!==u.foreignKey)):w[a.alias]=a.singleResult?this.emptyAggregateValue(a.query):{}}}}emptyAggregateValue(r){const e=r.aggregateItems[0];return!e||String(e.function).toLowerCase()==="count"?0:null}queryLimit(r){if(r._limit!==void 0)return Number(r._limit);if(r.limitValue!==void 0&&Number(r.limitValue)>0)return Number(r.limitValue)}async close(){await this.driver.close()}};function ks(r){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r))throw new Error(`Unsafe SQL identifier: ${r}`);return r}function xs(r){const t={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(r).toLowerCase()];if(!t)throw new Error(`Unsupported aggregate: ${r}`);return t}var Ds=class{constructor(r){this.worker=r,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=e=>{const t=e.data;if(!t||t.type!=="teaql-browser-sqlite-response")return;const i=this.pending.get(t.requestId);if(i)if(this.pending.delete(t.requestId),t.error){const s=new Error(t.error.message);s.name=t.error.name,t.error.code&&(s.code=t.error.code),i.reject(s)}else i.resolve(t.result)},this.onError=e=>{const t=new Error(e.message||"Browser SQLite worker failed");t.name="BrowserSQLiteWorkerError";for(const i of this.pending.values())i.reject(t);this.pending.clear()},r.addEventListener("message",this.onMessage),r.addEventListener("error",this.onError)}request(r,e){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const t=this.nextRequestId++;return new Promise((i,s)=>{this.pending.set(t,{resolve:n=>i(n),reject:s}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:t,operation:r,payload:e})})}async close(r){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),r&&this.worker.terminate?.();const e=new Error("Browser SQLite worker is closed");for(const t of this.pending.values())t.reject(e);this.pending.clear()}}},Bs=class{constructor(r){this.transport=r}query(r,e=[]){return this.transport.request("query",{sql:r,values:e})}},Qs=class si{constructor(e,t){this.transport=e,this.options=t,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,t={}){const i={storage:t.storage??"memory",databaseName:js(t.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:t.terminateWorkerOnClose??!0},s=new Ds(e);return await s.request("open",i),new si(s,i)}identifier(e){return`"${ks(e)}"`}placeholder(e){return"?"}contains(e,t){return`CAST(${e} AS TEXT) LIKE '%' || ${t} || '%'`}aggregateFunction(e){return xs(e)}encode(e,t){return e==null?e:t?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):t?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const t=this.accessTail;let i;this.accessTail=new Promise(s=>{i=s}),await t;try{return await e()}finally{i()}}query(e,t=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:t}))}async*stream(e,t=[]){const i=await this.query(e,t);for(const s of i.rows)yield s}transaction(e){return this.exclusive(async()=>{const t=new Bs(this.transport);await t.query("BEGIN IMMEDIATE");try{const i=await e(t);return await t.query("COMMIT"),i}catch(i){try{await t.query("ROLLBACK")}catch{}throw i}})}async ensureSchema(e){for(const t of Object.values(e)){const i=this.identifier(t.table);await this.query(`CREATE TABLE IF NOT EXISTS ${i} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const s=await this.query(`PRAGMA table_info(${i})`),n=new Set(s.rows.map(o=>String(o.name)));for(const[o,a]of Object.entries(t.columns))o==="id"||o==="version"||n.has(a.columnName)||await this.query(`ALTER TABLE ${i} ADD COLUMN ${this.identifier(a.columnName)} ${Ms(a.logicalType)}${a.nullable===!1?" NOT NULL":""}`)}for(const t of $s(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(t.name)} ON ${this.identifier(t.table)} (${this.identifier(t.foreignColumn)}, ${this.identifier(t.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,t){for(let i=1;i<=100;i+=1){const s=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t]);if(!s.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[t])).rowCount===1)return"1"}catch(u){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t])).rowCount)throw u}continue}const n=Number(s.rows[0].id),o=n+1,a=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[o,t,n]);if(a.rowCount===1)return String(o);if(a.rowCount!==0)throw new Error(`ID space update for ${t} changed ${a.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${t} after 100 optimistic-lock attempts`)}ensureIdFloor(e,t,i){return Ps(e,s=>this.placeholder(s),t,i)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}},Fs=class ni extends Rs{constructor(e,t){super(e,t),this.browserDriver=e}static async open(e,t,i={}){return new ni(await Qs.open(e,i),t)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}};function Ms(r){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[r]}function js(r){const e=r.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}var Z=r=>`${r.entity}\0${typeof r.id}:${String(r.id)}`,z=class{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map,this.traces=new Map}setTraceChain(r,e){this.traces.set(Z(r),{key:Object.freeze({...r}),nodes:me(e)})}traceChain(r){return this.traces.get(Z(r))?.nodes}set(r,e,t){if(!e.trim())throw new TypeError("field is required");const i=Z(r),s=this.changes.get(i)??{key:Object.freeze({...r}),values:{}};s.values[e]=t,this.changes.set(i,s)}snapshot(){return[...this.changes.values()].map(r=>({key:Object.freeze({...r.key}),values:Object.freeze({...r.values})}))}change(r){return Object.freeze({...this.changes.get(Z(r))?.values??{}})}mergeFrom(r){if(r!==this){for(const e of r.snapshotVersions())this.requireMatchingVersion(e.key,e.version);for(const e of r.snapshot())for(const[t,i]of Object.entries(e.values))this.set(e.key,t,i);for(const e of r.newKeys.values())this.markAsNew(e);for(const e of r.deletedKeys.values())this.markAsDeleted(e);for(const e of r.snapshotVersions())this.setOriginalVersion(e.key,e.version);for(const e of r.traces.values())this.setTraceChain(e.key,e.nodes)}}mergeEntityFrom(r,e){if(r===this)return;const t=r.originalVersion(e);t!==void 0&&this.requireMatchingVersion(e,t);for(const[s,n]of Object.entries(r.change(e)))this.set(e,s,n);r.isNew(e)&&this.markAsNew(e),r.isDeleted(e)&&this.markAsDeleted(e),t!==void 0&&this.setOriginalVersion(e,t);const i=r.traceChain(e);i&&this.setTraceChain(e,i)}hasPending(r){const e=Z(r);return this.newKeys.has(e)||this.deletedKeys.has(e)||Object.keys(this.changes.get(e)?.values??{}).length>0}snapshotVersions(){return[...this.originalVersions.values()]}rekey(r,e){const t=Z(r),i=Z(e);if(t===i)return;const s=this.originalVersion(r);s!==void 0&&this.requireMatchingVersion(e,s);const n=this.changes.get(t);if(n){this.changes.delete(t);for(const[u,h]of Object.entries(n.values))this.set(e,u,h)}const o=this.originalVersions.get(t);o!==void 0&&(this.originalVersions.delete(t),this.originalVersions.set(i,{key:Object.freeze({...e}),version:o.version})),this.newKeys.delete(t)&&this.newKeys.set(i,Object.freeze({...e})),this.deletedKeys.delete(t)&&this.deletedKeys.set(i,Object.freeze({...e}));const a=this.traces.get(t);a&&(this.traces.delete(t),this.setTraceChain(e,a.nodes))}clearEntity(r){const e=Z(r);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e),this.traces.delete(e)}requireMatchingVersion(r,e){const t=this.originalVersion(r);if(t!==void 0&&t!==e)throw new Error("ENTITY_VERSION_CONFLICT: one graph cannot contain different loaded versions of the same typed entity")}setOriginalVersion(r,e){this.requireMatchingVersion(r,e),this.originalVersions.set(Z(r),{key:Object.freeze({...r}),version:e})}acceptCommittedVersion(r,e){if(this.hasPending(r))throw new Error("ENTITY_COMMIT_PENDING: clear committed changes before accepting the persisted version");this.originalVersions.set(Z(r),{key:Object.freeze({...r}),version:e})}originalVersion(r){return this.originalVersions.get(Z(r))?.version}markAsNew(r){this.newKeys.set(Z(r),Object.freeze({...r}))}isNew(r){return this.newKeys.has(Z(r))}markAsDeleted(r){const e=Z(r);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...r}))}isDeleted(r){return this.deletedKeys.has(Z(r))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear(),this.traces.clear()}};function oi(r){const e=r.split("_");return e[0]+e.slice(1).map(t=>t?t[0].toUpperCase()+t.slice(1):"").join("")}function Vs(r,e){if(e==="snake_case")return r;const t=oi(r);return e==="camelCase"||!t?t:t[0].toUpperCase()+t.slice(1)}function Ws(r){return r.replace(/~/g,"~0").replace(/\//g,"~1")}var x=class xe{constructor(e){this.segments=e}static root(){return new xe([])}static property(e){return xe.root().property(e)}property(e){return new xe([...this.segments,{kind:"property",name:e}])}index(e){return new xe([...this.segments,{kind:"index",index:e}])}prefixedBy(e){return new xe([...e.segments,...this.segments])}modelPath(){return this.render(e=>e)}nativePath(){return this.render(oi)}instancePath(e="camelCase"){return this.segments.map(t=>t.kind==="index"?String(t.index):Ws(Vs(t.name,e))).map(t=>`/${t}`).join("")}toString(){return this.nativePath()}render(e){let t="";for(const i of this.segments)i.kind==="index"?t+=`[${i.index}]`:t+=`${t?".":""}${e(i.name)}`;return t}};function st(r,e,t,i){const s=n=>{if(n.includes("."))throw new Error("Dynamic search requires a trusted relation binding");const o=t[r.entity]?.queryFields;if(!o||!Object.prototype.hasOwnProperty.call(o,n))throw new Error("Missing generated scalar search binding");return o[n]};return Us(r,e,t,{filter:(n,o)=>{const[a,u]=Object.entries(o)[0];if(u===null&&a!=="$eq"&&a!=="$ne")throw new Error("Null supports only equality predicates");return{[s(n)]:o}},order:(n,o)=>o==="asc"?rt.asc(s(n)):rt.desc(s(n))},i)}function Us(r,e,t,i,s=n=>console.warn({...n,fieldPath:""})){const n=Gs(e,r.entity,t,()=>{}),o=Object.entries(n.search.filter??{}).map(([d,c])=>i.filter(d,c)),a=(n.search.orderBy??[]).map(d=>i.order(d.field,d.direction));if(o.some(d=>!Xe(d)))throw new Error("Invalid trusted search filter binding");if(a.some(d=>!(d instanceof rt)))throw new Error("Invalid trusted search order binding");const u=r.clone(),h=r._filters??[],l=[...h,...r.filterCondition?[r.filterCondition]:[]];return(o.length||h.length)&&u.filter({$and:[...l,...o]}),u.orderItems.push(...a),n.warnings.forEach(d=>s({...d})),{query:u,warnings:n.warnings}}var ct=(r,e)=>Object.prototype.hasOwnProperty.call(r,e),Xe=r=>typeof r=="object"&&r!==null&&!Array.isArray(r),Ks=new Set(["__proto__","prototype","constructor"]),zs=new Set(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$notIn","$contains"]);function Gs(r,e,t,i=n=>console.warn({...n,fieldPath:""}),s=100){if(!Number.isSafeInteger(s)||s<1)throw new Error("Invalid search limit");if(!ct(t,e))throw new Error("Unknown search entity");let n;try{n=typeof r=="string"?JSON.parse(r):r}catch{throw new Error("Dynamic search requires valid JSON")}if(!Xe(n)||Object.keys(n).some(f=>!["filter","orderBy"].includes(f)))throw new Error("Unsupported dynamic search input or control");if(n.filter!==void 0&&!Xe(n.filter))throw new Error("Invalid search filter");if(n.orderBy!==void 0&&!Array.isArray(n.orderBy))throw new Error("Invalid search ordering");const o=Object.entries(n.filter??{}),a=n.orderBy??[];if(o.length+a.length>s)throw new Error("Dynamic search exceeds clause limit");const u=[],h={filter:Object.create(null),orderBy:[]};function l(f){const y=f.split(".");if(y.length>16||y.some(I=>!I||I.startsWith("$")||Ks.has(I)))throw new Error("Invalid dynamic search field path");let O=t[e];for(const I of y.slice(0,-1)){if(!ct(O.relations,I))return;const S=O.relations[I];if(!ct(t,S))throw new Error("Invalid trusted search relation metadata");O=t[S]}const w=y[y.length-1];return ct(O.fields,w)?O.fields[w]:void 0}function d(f,y){u.push({code:"DYNAMIC_SEARCH_UNKNOWN_FIELD",entity:e,clause:y,fieldPath:f})}function c(f,y){if(f===null)return;if(!(y==="date"?typeof f=="string"&&/^\d{4}-\d{2}-\d{2}$/.test(f)&&!f.startsWith("0000-")&&Number.isFinite(Date.parse(f+"T00:00:00Z"))&&new Date(f+"T00:00:00Z").toISOString().slice(0,10)===f:y==="decimal"?typeof f=="string"&&/^[+-]?\d+(?:\.\d+)?$/.test(f)||typeof f=="number"&&Number.isFinite(f):y==="integer"||y==="timestamp"?typeof f=="number"&&Number.isSafeInteger(f):y==="number"?typeof f=="number"&&Number.isFinite(f):typeof f===y))throw new Error("Invalid value for known search field")}for(const[f,y]of o){const O=Xe(y)?Object.entries(y):[["$eq",y]];if(O.length!==1||!zs.has(O[0][0]))throw new Error("Unsupported or malformed dynamic search operator");const[w,I]=O[0];if((w==="$in"||w==="$notIn")&&(!Array.isArray(I)||I.length>1e3))throw new Error("Invalid or oversized search value list");const S=l(f);if(S===void 0){d(f,"FILTER");continue}if(S==="unsupported")throw new Error("Known search field has no supported scalar binding");if(w==="$contains"&&S!=="string")throw new Error("String operator requires a string field");if(Array.isArray(I)){if(w!=="$in"&&w!=="$notIn")throw new Error("Unexpected search value list");I.forEach(R=>c(R,S))}else c(I,S);h.filter[f]={[w]:Array.isArray(I)?[...I]:I}}for(const f of a){if(!Xe(f)||Object.keys(f).some(O=>!["field","direction"].includes(O))||typeof f.field!="string"||!["asc","desc"].includes(f.direction))throw new Error("Invalid dynamic search ordering");const y=l(f.field);if(y===void 0){d(f.field,"ORDER_BY");continue}if(y==="unsupported")throw new Error("Known search field has no supported scalar binding");h.orderBy.push({field:f.field,direction:f.direction})}return u.forEach(f=>i({...f})),{search:h,warnings:u}}var Pr=class extends SyntaxError{constructor(r,e,t,i){super(r),this.expected=e,this.found=t,this.location=i,this.name="SyntaxError"}format(r){let e="Error: "+this.message;if(this.location){let t=null;const i=r.find(a=>a.source===this.location.source);i&&(t=i.text.split(/\r\n|\n|\r/g));const s=this.location.start,n=this.location.source&&typeof this.location.source.offset=="function"?this.location.source.offset(s):s,o=this.location.source+":"+n.line+":"+n.column;if(t){const a=this.location.end,u="".padEnd(n.line.toString().length," "),h=t[s.line-1],d=(s.line===a.line?a.column:h.length+1)-s.column||1;e+=` - --> `+o+` -`+u+` | -`+n.line+" | "+h+` -`+u+" | "+"".padEnd(s.column-1," ")+"".padEnd(d,"^")}else e+=` - at `+o}return e}static buildMessage(r,e){function t(d){return d.codePointAt(0).toString(16).toUpperCase()}const i=Object.prototype.hasOwnProperty.call(RegExp.prototype,"unicode")?new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]","gu"):null;function s(d){return i?d.replace(i,c=>"\\u{"+t(c)+"}"):d}function n(d){return s(d.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,c=>"\\x0"+t(c)).replace(/[\x10-\x1F\x7F-\x9F]/g,c=>"\\x"+t(c)))}function o(d){return s(d.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,c=>"\\x0"+t(c)).replace(/[\x10-\x1F\x7F-\x9F]/g,c=>"\\x"+t(c)))}const a={literal(d){return'"'+n(d.text)+'"'},class(d){const c=d.parts.map(f=>Array.isArray(f)?o(f[0])+"-"+o(f[1]):o(f));return"["+(d.inverted?"^":"")+c.join("")+"]"+(d.unicode?"u":"")},any(){return"any character"},end(){return"end of input"},other(d){return d.description}};function u(d){return a[d.type](d)}function h(d){const c=d.map(u);if(c.sort(),c.length>0){let f=1;for(let y=1;yL[3])]}function _i(p){return p||[]}function $i(p){return JSON.parse(p)}function hn(p){return p}function Pi(p){return p.join("")}function Ei(p){return Number(p)}function Ni(){return!0}function Ti(){return!1}function Ri(){return null}function ln(p){return p}let m=e.peg$currPos|0;const Ee=[{line:1,column:1}];let ae=m,lt=e.peg$maxFailExpected||[],P=e.peg$silentFails|0,Ue;if(e.startRule){if(!(e.startRule in s))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=s[e.startRule]}function ki(p=m){const v=r.codePointAt(p);return v===void 0?"":String.fromCodePoint(v)}function ee(p,v){return{type:"literal",text:p,ignoreCase:v}}function Oe(p,v,L,q){return{type:"class",parts:p,inverted:v,ignoreCase:L,unicode:q}}function xi(){return{type:"any"}}function Di(){return{type:"end"}}function or(p){let v=Ee[p],L;if(v)return v;if(p>=Ee.length)L=Ee.length-1;else for(L=p;!Ee[--L];);for(v=Ee[L],v={line:v.line,column:v.column};Lae&&(ae=m,lt=[]),lt.push(p))}function Bi(p,v,L){return new Pr(Pr.buildMessage(p,v),p,v,L)}function ur(){let p,v;return p=m,J(),v=hr(),v!==t?(J(),r.charCodeAt(m)===59?m++:P===0&&E(Et),J(),p=v):(m=p,p=t),p}function hr(){let p,v,L,q,_,b,N,F;if(p=m,v=cr(),v!==t){if(L=[],q=m,_=J(),r.charCodeAt(m)===46?(b=o,m++):(b=t,P===0&&E(We)),b!==t?(N=J(),F=lr(),F!==t?(_=[_,b,N,F],q=_):(m=q,q=t)):(m=q,q=t),q!==t)for(;q!==t;)L.push(q),q=m,_=J(),r.charCodeAt(m)===46?(b=o,m++):(b=t,P===0&&E(We)),b!==t?(N=J(),F=lr(),F!==t?(_=[_,b,N,F],q=_):(m=q,q=t)):(m=q,q=t);else L=t;L!==t?p=bi(v,L):(m=p,p=t)}else m=p,p=t;return p}function lr(){let p,v,L,q,_;return p=m,v=cr(),v!==t?(J(),r.charCodeAt(m)===40?(L=a,m++):(L=t,P===0&&E(mi)),L!==t?(J(),q=dr(),q===t&&(q=null),J(),r.charCodeAt(m)===41?(_=u,m++):(_=t,P===0&&E(fi)),_!==t?p=Li(v,q):(m=p,p=t)):(m=p,p=t)):(m=p,p=t),p}function dr(){let p,v,L,q,_,b,N,F;if(p=m,v=Nt(),v!==t){for(L=[],q=m,_=J(),r.charCodeAt(m)===44?(b=h,m++):(b=t,P===0&&E(er)),b!==t?(N=J(),F=Nt(),F!==t?(_=[_,b,N,F],q=_):(m=q,q=t)):(m=q,q=t);q!==t;)L.push(q),q=m,_=J(),r.charCodeAt(m)===44?(b=h,m++):(b=t,P===0&&E(er)),b!==t?(N=J(),F=Nt(),F!==t?(_=[_,b,N,F],q=_):(m=q,q=t)):(m=q,q=t);p=Ci(v,L)}else m=p,p=t;return p}function Nt(){let p;return p=hr(),p===t&&(p=Qi(),p===t&&(p=Fi(),p===t&&(p=Mi(),p===t&&(p=ji(),p===t&&(p=Vi(),p===t&&(p=Wi())))))),p}function Qi(){let p,v,L,q;return p=m,r.charCodeAt(m)===91?(v=l,m++):(v=t,P===0&&E(pi)),v!==t?(J(),L=dr(),L===t&&(L=null),J(),r.charCodeAt(m)===93?(q=d,m++):(q=t,P===0&&E(gi)),q!==t?p=_i(L):(m=p,p=t)):(m=p,p=t),p}function Fi(){let p,v,L,q,_,b,N,F;if(p=m,v=m,L=m,r.charCodeAt(m)===34?(q=c,m++):(q=t,P===0&&E(tr)),q!==t){for(_=[],b=m,r.charCodeAt(m)===92?(N=f,m++):(N=t,P===0&&E(ut)),N!==t?(r.length>m?(F=r.charAt(m),m++):(F=t,P===0&&E(ht)),F!==t?(N=[N,F],b=N):(m=b,b=t)):(m=b,b=t),b===t&&(b=r.charAt(m),R.test(b)?m++:(b=t,P===0&&E(rr)));b!==t;)_.push(b),b=m,r.charCodeAt(m)===92?(N=f,m++):(N=t,P===0&&E(ut)),N!==t?(r.length>m?(F=r.charAt(m),m++):(F=t,P===0&&E(ht)),F!==t?(N=[N,F],b=N):(m=b,b=t)):(m=b,b=t),b===t&&(b=r.charAt(m),R.test(b)?m++:(b=t,P===0&&E(rr)));r.charCodeAt(m)===34?(b=c,m++):(b=t,P===0&&E(tr)),b!==t?(q=[q,_,b],L=q):(m=L,L=t)}else m=L,L=t;return L!==t?v=r.substring(v,m):v=L,v!==t&&(v=$i(v)),p=v,p}function Mi(){let p,v,L,q,_,b;if(p=m,r.charCodeAt(m)===39?(v=y,m++):(v=t,P===0&&E(ir)),v!==t){for(L=[],q=m,r.charCodeAt(m)===92?(_=f,m++):(_=t,P===0&&E(ut)),_!==t?(r.length>m?(b=r.charAt(m),m++):(b=t,P===0&&E(ht)),b!==t?q=b:(m=q,q=t)):(m=q,q=t),q===t&&(q=r.charAt(m),$.test(q)?m++:(q=t,P===0&&E(sr)));q!==t;)L.push(q),q=m,r.charCodeAt(m)===92?(_=f,m++):(_=t,P===0&&E(ut)),_!==t?(r.length>m?(b=r.charAt(m),m++):(b=t,P===0&&E(ht)),b!==t?q=b:(m=q,q=t)):(m=q,q=t),q===t&&(q=r.charAt(m),$.test(q)?m++:(q=t,P===0&&E(sr)));r.charCodeAt(m)===39?(q=y,m++):(q=t,P===0&&E(ir)),q!==t?p=Pi(L):(m=p,p=t)}else m=p,p=t;return p}function ji(){let p,v,L,q,_,b,N,F,te,pe;if(p=m,v=m,L=m,r.charCodeAt(m)===45?(q=O,m++):(q=t,P===0&&E(yi)),q===t&&(q=null),_=m,b=[],N=r.charAt(m),A.test(N)?m++:(N=t,P===0&&E(we)),N!==t)for(;N!==t;)b.push(N),N=r.charAt(m),A.test(N)?m++:(N=t,P===0&&E(we));else b=t;if(b!==t)if(r.charCodeAt(m)===46?(N=o,m++):(N=t,P===0&&E(We)),N!==t){if(F=[],te=r.charAt(m),A.test(te)?m++:(te=t,P===0&&E(we)),te!==t)for(;te!==t;)F.push(te),te=r.charAt(m),A.test(te)?m++:(te=t,P===0&&E(we));else F=t;F!==t?(b=[b,N,F],_=b):(m=_,_=t)}else m=_,_=t;else m=_,_=t;if(_===t)if(_=[],b=r.charAt(m),A.test(b)?m++:(b=t,P===0&&E(we)),b!==t)for(;b!==t;)_.push(b),b=r.charAt(m),A.test(b)?m++:(b=t,P===0&&E(we));else _=t;if(_!==t){if(b=m,N=r.charAt(m),k.test(N)?m++:(N=t,P===0&&E(wi)),N!==t){if(F=r.charAt(m),M.test(F)?m++:(F=t,P===0&&E(Oi)),F===t&&(F=null),te=[],pe=r.charAt(m),A.test(pe)?m++:(pe=t,P===0&&E(we)),pe!==t)for(;pe!==t;)te.push(pe),pe=r.charAt(m),A.test(pe)?m++:(pe=t,P===0&&E(we));else te=t;te!==t?(N=[N,F,te],b=N):(m=b,b=t)}else m=b,b=t;b===t&&(b=null),q=[q,_,b],L=q}else m=L,L=t;return L!==t?v=r.substring(v,m):v=L,v!==t&&(v=Ei(v)),p=v,p}function Vi(){let p,v,L,q;return p=m,r.substr(m,4)===w?(v=w,m+=4):(v=t,P===0&&E(vi)),v!==t?(L=m,P++,q=Ke(),P--,q===t?L=void 0:(m=L,L=t),L!==t?p=Ni():(m=p,p=t)):(m=p,p=t),p===t&&(p=m,r.substr(m,5)===I?(v=I,m+=5):(v=t,P===0&&E(qi)),v!==t?(L=m,P++,q=Ke(),P--,q===t?L=void 0:(m=L,L=t),L!==t?p=Ti():(m=p,p=t)):(m=p,p=t)),p}function Wi(){let p,v,L,q;return p=m,r.substr(m,4)===S?(v=S,m+=4):(v=t,P===0&&E(Ii)),v!==t?(L=m,P++,q=Ke(),P--,q===t?L=void 0:(m=L,L=t),L!==t?p=Ri():(m=p,p=t)):(m=p,p=t),p}function cr(){let p,v,L,q,_,b;if(p=m,v=m,L=m,q=r.charAt(m),B.test(q)?m++:(q=t,P===0&&E(Ai)),q!==t){for(_=[],b=Ke();b!==t;)_.push(b),b=Ke();q=[q,_],L=q}else m=L,L=t;return L!==t?v=r.substring(v,m):v=L,v!==t&&(v=v),p=v,p}function Ke(){let p;return p=r.charAt(m),fe.test(p)?m++:(p=t,P===0&&E(Si)),p}function J(){let p,v;for(p=[],v=r.charAt(m),Ve.test(v)?m++:(v=t,P===0&&E(nr));v!==t;)p.push(v),v=r.charAt(m),Ve.test(v)?m++:(v=t,P===0&&E(nr));return p}function Ui(p,v){return{type:"CallChain",target:p,calls:v.map(L=>L[3])}}Ue=n();const Tt=Ue!==t&&m===r.length;function mr(){throw Ue!==t&&mtypeof o=="object"&&o!==null&&!Array.isArray(o)?ai(o,e):o);t=s.apply(t,n)}return t}var Xs=class{static parse(r,e){const t=Ys(r,void 0);return ai(t,e)}};class C extends ei{orderBy(e,t){return this.order({field:e,expr:null,direction:t==="desc"?"Desc":"Asc"})}relationQuery(e,t,i="id",s="id",n=!0,o){return super.relationQuery(e,t,i,s,n,o)}}class G{static teaqlTemporaryId=0;id;platform;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--G.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerOrderList",{value:[],writable:!0,enumerable:!1}),e){const i={...e};delete i.customerOrderList,Object.assign(this,i),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof W?e.platform:W.fromRecord(e.platform),this.markLoaded("platform")),Array.isArray(e.customerOrderList)&&(this._customerOrderList=e.customerOrderList.map(s=>s instanceof K?s:K.fromRecord(s)),this.markLoaded("customerOrderList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"Customer",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._customerOrderList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const i=new G(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new G({id:String(e)})}static teaqlBootstrapNew(e){return new G().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const u=[{member:"id",canonical:"id"},{member:"platform",canonical:"platform"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new j([{ruleId:"invalid_type",location:x.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"Customer",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o);const a=o.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._customerOrderList.entries()){h.teaqlAttachRoot(this._root),h.updateCustomer(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("customer_order_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"Customer",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[y,O]of Object.entries(a.payload))y!=="id"&&y!=="version"&&this._root.set(this.teaqlEntityKey(),y,O);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update");const f=u.scopeFor(c);for(const[y,O]of this._customerOrderList.entries()){O.teaqlAttachRoot(this._root),O.updateCustomer(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("customer_order_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,platform:this.platform,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}customerOrderList(){return this._customerOrderList}}class se{static teaqlTemporaryId=0;id;customerOrder;productName;quantity;unitPrice;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--se.teaqlTemporaryId,writable:!0,enumerable:!1}),e){const i={...e};Object.assign(this,i),e.customerOrder&&typeof e.customerOrder=="object"&&(this.customerOrder=e.customerOrder instanceof K?e.customerOrder:K.fromRecord(e.customerOrder),this.markLoaded("customerOrder"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"OrderItem",id:this._ledgerId}}teaqlAttachRoot(e){return this._root!==e&&(e.mergeFrom(this._root),this._root=e),this}static fromRecord(e,t){const i=new se(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new se({id:String(e)})}static teaqlBootstrapNew(e){return new se().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const a=[{member:"id",canonical:"id"},{member:"customerOrder",canonical:"customer_order"},{member:"productName",canonical:"product_name"},{member:"quantity",canonical:"quantity"},{member:"unitPrice",canonical:"unit_price"},{member:"version",canonical:"version"}].find(u=>!this.isLoaded(u.member));if(a)throw new j([{ruleId:"invalid_type",location:x.property(a.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"OrderItem",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o),o.scopeFor(this.teaqlEntityKey())}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"OrderItem",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[f,y]of Object.entries(a.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,y);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();return this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update"),u.scopeFor(c),t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,customer_order:this.customerOrder,product_name:this.productName,quantity:this.quantity,unit_price:this.unitPrice,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateProductName(e){return this.productName=e,this.markLoaded("productName"),this._root.set(this.teaqlEntityKey(),"product_name",e),this}updateQuantity(e){return this.quantity=e,this.markLoaded("quantity"),this._root.set(this.teaqlEntityKey(),"quantity",e),this}updateUnitPrice(e){return this.unitPrice=e,this.markLoaded("unitPrice"),this._root.set(this.teaqlEntityKey(),"unit_price",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updateCustomerOrder(e){return this.customerOrder=e?.id??e,this.markLoaded("customerOrder"),this._root.set(this.teaqlEntityKey(),"customer_order",this.customerOrder),this}}class K{static teaqlTemporaryId=0;id;customer;status;orderNumber;orderDate;totalAmount;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--K.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_orderItemList",{value:[],writable:!0,enumerable:!1}),e){const i={...e};delete i.orderItemList,Object.assign(this,i),e.customer&&typeof e.customer=="object"&&(this.customer=e.customer instanceof G?e.customer:G.fromRecord(e.customer),this.markLoaded("customer")),e.status&&typeof e.status=="object"&&(this.status=e.status instanceof V?e.status:V.fromRecord(e.status),this.markLoaded("status")),Array.isArray(e.orderItemList)&&(this._orderItemList=e.orderItemList.map(s=>s instanceof se?s:se.fromRecord(s)),this.markLoaded("orderItemList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"CustomerOrder",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._orderItemList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const i=new K(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new K({id:String(e)})}static teaqlBootstrapNew(e){return new K().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const u=[{member:"id",canonical:"id"},{member:"customer",canonical:"customer"},{member:"status",canonical:"status"},{member:"orderNumber",canonical:"order_number"},{member:"orderDate",canonical:"order_date"},{member:"totalAmount",canonical:"total_amount"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new j([{ruleId:"invalid_type",location:x.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"CustomerOrder",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o);const a=o.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._orderItemList.entries()){h.teaqlAttachRoot(this._root),h.updateCustomerOrder(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("order_item_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"CustomerOrder",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[y,O]of Object.entries(a.payload))y!=="id"&&y!=="version"&&this._root.set(this.teaqlEntityKey(),y,O);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update");const f=u.scopeFor(c);for(const[y,O]of this._orderItemList.entries()){O.teaqlAttachRoot(this._root),O.updateCustomerOrder(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("order_item_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,customer:this.customer,status:this.status,order_number:this.orderNumber,order_date:this.orderDate,total_amount:this.totalAmount,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateOrderNumber(e){return this.orderNumber=e,this.markLoaded("orderNumber"),this._root.set(this.teaqlEntityKey(),"order_number",e),this}updateOrderDate(e){return this.orderDate=e,this.markLoaded("orderDate"),this._root.set(this.teaqlEntityKey(),"order_date",e),this}updateTotalAmount(e){return this.totalAmount=e,this.markLoaded("totalAmount"),this._root.set(this.teaqlEntityKey(),"total_amount",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updateCustomer(e){return this.customer=e?.id??e,this.markLoaded("customer"),this._root.set(this.teaqlEntityKey(),"customer",this.customer),this}updateStatus(e){return this.status=e?.id??e,this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToNew(){return this.status="1001",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToPaid(){return this.status="1002",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToCancelled(){return this.status="1003",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}orderItemList(){return this._orderItemList}}class V{static teaqlTemporaryId=0;platform;id;name;code;color;displayOrder;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--V.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerOrderList",{value:[],writable:!0,enumerable:!1}),e){const i={...e};delete i.customerOrderList,Object.assign(this,i),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof W?e.platform:W.fromRecord(e.platform),this.markLoaded("platform")),Array.isArray(e.customerOrderList)&&(this._customerOrderList=e.customerOrderList.map(s=>s instanceof K?s:K.fromRecord(s)),this.markLoaded("customerOrderList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"OrderStatus",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._customerOrderList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const i=new V(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new V({id:String(e)})}static teaqlBootstrapNew(e){return new V().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const u=[{member:"platform",canonical:"platform"},{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"code",canonical:"code"},{member:"color",canonical:"color"},{member:"displayOrder",canonical:"display_order"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new j([{ruleId:"invalid_type",location:x.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"OrderStatus",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o);const a=o.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._customerOrderList.entries()){h.teaqlAttachRoot(this._root),h.updateStatus(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("customer_order_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"OrderStatus",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[y,O]of Object.entries(a.payload))y!=="id"&&y!=="version"&&this._root.set(this.teaqlEntityKey(),y,O);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update");const f=u.scopeFor(c);for(const[y,O]of this._customerOrderList.entries()){O.teaqlAttachRoot(this._root),O.updateStatus(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("customer_order_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{platform:this.platform,id:this.id,name:this.name,code:this.code,color:this.color,display_order:this.displayOrder,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateCode(e){return this.code=e,this.markLoaded("code"),this._root.set(this.teaqlEntityKey(),"code",e),this}updateColor(e){return this.color=e,this.markLoaded("color"),this._root.set(this.teaqlEntityKey(),"color",e),this}updateDisplayOrder(e){return this.displayOrder=e,this.markLoaded("displayOrder"),this._root.set(this.teaqlEntityKey(),"display_order",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}customerOrderList(){return this._customerOrderList}}class W{static teaqlTemporaryId=0;id;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new z,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--W.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_orderStatusList",{value:[],writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerList",{value:[],writable:!0,enumerable:!1}),e){const i={...e};delete i.orderStatusList,delete i.customerList,Object.assign(this,i),Array.isArray(e.orderStatusList)&&(this._orderStatusList=e.orderStatusList.map(s=>s instanceof V?s:V.fromRecord(s)),this.markLoaded("orderStatusList")),Array.isArray(e.customerList)&&(this._customerList=e.customerList.map(s=>s instanceof G?s:G.fromRecord(s)),this.markLoaded("customerList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._orderStatusList)t.teaqlAttachRoot(e);for(const t of this._customerList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const i=new W(e);return t?i.teaqlAttachRoot(t):i}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new W({id:String(e)})}static teaqlBootstrapNew(e){return new W().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(new he(this._comment),async i=>(this.teaqlPreflightGraph(e,t,i),this.teaqlSaveWithinGraph(e,t,i)))}teaqlPreflightGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action;if(n==="Update"){const u=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new j([{ruleId:"invalid_type",location:x.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const o=i.request({entity:"Platform",action:n,payload:n==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload()));t.preflightMutation(o);const a=o.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._orderStatusList.entries()){h.teaqlAttachRoot(this._root),h.updatePlatform(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("order_status_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}for(const[u,h]of this._customerList.entries()){h.teaqlAttachRoot(this._root),h.updatePlatform(this);try{h.teaqlPreflightGraph(e,t,i,a)}catch(l){if(!(l instanceof j))throw l;const d=x.property("customer_list").index(u);throw new j(l.violations.map(c=>({...c,location:c.location.prefixedBy(d)})))}}}async teaqlSaveWithinGraph(e,t,i,s){if(!s&&!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const n=this._action,o=this._root.change(this.teaqlEntityKey()),a={entity:"Platform",action:this._action,payload:n==="Update"?o:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},u=i.request(a,s,this._comment).withLoadedSnapshot(new ue(this.teaqlMutationPayload())),h=await t.executeMutation(u);for(const[y,O]of Object.entries(a.payload))y!=="id"&&y!=="version"&&this._root.set(this.teaqlEntityKey(),y,O);if(!h.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const l={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},d=this.teaqlEntityKey();Object.assign(this,h.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(d,c),t.afterGraphRollback(()=>{Object.assign(this,l.payload),this._ledgerId=l.ledgerId,this._action=l.action,this._loadedFields=l.loadedFields,this._fullyLoaded=l.fullyLoaded,this._root.rekey(c,d)}),this._loadedFields=new Set(Object.keys(h.persistedRecord)),this._fullyLoaded=!1,a.action!=="Delete"&&(this._action="Update");const f=u.scopeFor(c);for(const[y,O]of this._orderStatusList.entries()){O.teaqlAttachRoot(this._root),O.updatePlatform(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("order_status_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}for(const[y,O]of this._customerList.entries()){O.teaqlAttachRoot(this._root),O.updatePlatform(this);try{await O.teaqlSaveWithinGraph(e,t,i,f)}catch(w){if(!(w instanceof j))throw w;const I=x.property("customer_list").index(y);throw new j(w.violations.map(S=>({...S,location:S.location.prefixedBy(I)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.acceptCommittedVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}orderStatusList(){return this._orderStatusList}customerList(){return this._customerList}}const nt=Object.freeze({Platform:Object.freeze({fields:Object.freeze({id:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",name:"name",version:"version"}),relations:Object.freeze({orderStatusList:"OrderStatus",customerList:"Customer"})}),OrderStatus:Object.freeze({fields:Object.freeze({platform:"integer",id:"integer",name:"string",code:"string",color:"string",display_order:"integer",displayOrder:"integer",version:"integer"}),queryFields:Object.freeze({platform:"platform",id:"id",name:"name",code:"code",color:"color",display_order:"displayOrder",displayOrder:"displayOrder",version:"version"}),relations:Object.freeze({platform:"Platform",customerOrderList:"CustomerOrder"})}),Customer:Object.freeze({fields:Object.freeze({id:"integer",platform:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",platform:"platform",name:"name",version:"version"}),relations:Object.freeze({platform:"Platform",customerOrderList:"CustomerOrder"})}),CustomerOrder:Object.freeze({fields:Object.freeze({id:"integer",customer:"integer",status:"integer",order_number:"string",orderNumber:"string",order_date:"date",orderDate:"date",total_amount:"decimal",totalAmount:"decimal",version:"integer"}),queryFields:Object.freeze({id:"id",customer:"customer",status:"status",order_number:"orderNumber",orderNumber:"orderNumber",order_date:"orderDate",orderDate:"orderDate",total_amount:"totalAmount",totalAmount:"totalAmount",version:"version"}),relations:Object.freeze({customer:"Customer",status:"OrderStatus",orderItemList:"OrderItem"})}),OrderItem:Object.freeze({fields:Object.freeze({id:"integer",customer_order:"integer",customerOrder:"integer",product_name:"string",productName:"string",quantity:"integer",unit_price:"decimal",unitPrice:"decimal",version:"integer"}),queryFields:Object.freeze({id:"id",customer_order:"customerOrder",customerOrder:"customerOrder",product_name:"productName",productName:"productName",quantity:"quantity",unit_price:"unitPrice",unitPrice:"unitPrice",version:"version"}),relations:Object.freeze({customer_order:"CustomerOrder",customerOrder:"CustomerOrder"})})});class Er{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("Platform"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new Js(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectOrderStatusListWith(e){return this.query.relationQuery("orderStatusList",e.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectOrderStatusListWith",relation:"orderStatusList"}),this}selectCustomerListWith(e){return this.query.relationQuery("customerList",e.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectCustomerListWith",relation:"customerList"}),this}haveOrderStatuses(){return this.withOrderStatusListMatching({toQuery:()=>new C("OrderStatus")})}haveNoOrderStatuses(){return this.withoutOrderStatusListMatching({toQuery:()=>new C("OrderStatus")})}withOrderStatusListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutOrderStatusListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}haveCustomers(){return this.withCustomerListMatching({toQuery:()=>new C("Customer")})}haveNoCustomers(){return this.withoutCustomerListMatching({toQuery:()=>new C("Customer")})}withCustomerListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutCustomerListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}countOrderStatuses(){return this.countOrderStatusesAs("countOrderStatuses")}countOrderStatusesAs(e){const t=new C("OrderStatus").filter({version:{$gte:1}});return this.countOrderStatusesWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countOrderStatusesAs",relation:"orderStatusList",alias:e},this}countOrderStatusesWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"relation-count",method:"countOrderStatusesWith",relation:"orderStatusList",alias:e}),this}minDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.minDisplayOrderOfOrderStatusesAs("minOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}minDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"minDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}maxDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.maxDisplayOrderOfOrderStatusesAs("maxOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}maxDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"maxDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}sumDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.sumDisplayOrderOfOrderStatusesAs("sumOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}sumDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"sumDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}avgDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.avgDisplayOrderOfOrderStatusesAs("avgOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}avgDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"avgDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}standardDeviationDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.standardDeviationDisplayOrderOfOrderStatusesAs("standardDeviationOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}standardDeviationDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"standardDeviationDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs("squareRootOfPopulationStandardDeviationOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}sampleVarianceDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.sampleVarianceDisplayOrderOfOrderStatusesAs("sampleVarianceOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}sampleVarianceDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"sampleVarianceDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}samplePopulationVarianceDisplayOrderOfOrderStatuses(){const e=new C("OrderStatus").filter({version:{$gte:1}});return this.samplePopulationVarianceDisplayOrderOfOrderStatusesAs("samplePopulationVarianceOfDisplayOrderOfOrderStatuses",{toQuery:()=>e})}samplePopulationVarianceDisplayOrderOfOrderStatusesAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","displayOrder",e),this.query.relationAggregate("orderStatusList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:e}),this}countCustomers(){return this.countCustomersAs("countCustomers")}countCustomersAs(e){const t=new C("Customer").filter({version:{$gte:1}});return this.countCustomersWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomersAs",relation:"customerList",alias:e},this}countCustomersWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("customerList",e,i,!0,{kind:"relation-count",method:"countCustomersWith",relation:"customerList",alias:e}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,t){return this.filters.push({name:{$between:[e,t]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof W?u:W.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof W?f:W.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof W?o:W.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class Js{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new W}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Nr{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("OrderStatus"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new Zs(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["platform","id","name","code","color","displayOrder","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectCode(){return this.query.select(["code"]),this}selectColor(){return this.query.select(["color"]),this}selectDisplayOrder(){return this.query.select(["displayOrder"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}selectCustomerOrderListWith(e){return this.query.relationQuery("customerOrderList",e.toQuery(),"id","status",!0,{kind:"relation-select",method:"selectCustomerOrderListWith",relation:"customerOrderList"}),this}haveCustomerOrders(){return this.withCustomerOrderListMatching({toQuery:()=>new C("CustomerOrder")})}haveNoCustomerOrders(){return this.withoutCustomerOrderListMatching({toQuery:()=>new C("CustomerOrder")})}withCustomerOrderListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"status"}}}),this}withoutCustomerOrderListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"status"}}}),this}countCustomerOrders(){return this.countCustomerOrdersAs("countCustomerOrders")}countCustomerOrdersAs(e){const t=new C("CustomerOrder").filter({version:{$gte:1}});return this.countCustomerOrdersWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomerOrdersAs",relation:"customerOrderList",alias:e},this}countCustomerOrdersWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"relation-count",method:"countCustomerOrdersWith",relation:"customerOrderList",alias:e}),this}minTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.minTotalAmountOfCustomerOrdersAs("minOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}minTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"minTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}maxTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.maxTotalAmountOfCustomerOrdersAs("maxOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}maxTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"maxTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}sumTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.sumTotalAmountOfCustomerOrdersAs("sumOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}sumTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"sumTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}avgTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.avgTotalAmountOfCustomerOrdersAs("avgOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}avgTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"avgTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}standardDeviationTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.standardDeviationTotalAmountOfCustomerOrdersAs("standardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}standardDeviationTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"standardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs("squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}sampleVarianceTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.sampleVarianceTotalAmountOfCustomerOrdersAs("sampleVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}sampleVarianceTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"sampleVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}samplePopulationVarianceTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs("samplePopulationVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}samplePopulationVarianceTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,t){return this.filters.push({name:{$between:[e,t]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withCodeContaining(e){return this.filters.push({code:{$contains:e}}),this}withCodeIs(e){return this.filters.push({code:{$eq:e}}),this}withCodeIsNot(e){return this.filters.push({code:{$ne:e}}),this}withCodeIn(...e){return this.filters.push({code:{$in:e}}),this}withCodeNotIn(...e){return this.filters.push({code:{$notIn:e}}),this}withCodeGreaterThan(e){return this.filters.push({code:{$gt:e}}),this}withCodeGreaterThanOrEqualTo(e){return this.filters.push({code:{$gte:e}}),this}withCodeLessThan(e){return this.filters.push({code:{$lt:e}}),this}withCodeLessThanOrEqualTo(e){return this.filters.push({code:{$lte:e}}),this}withCodeBetween(e,t){return this.filters.push({code:{$between:[e,t]}}),this}withCodeIsKnown(){return this.filters.push({code:{$isNull:!1}}),this}withCodeIsUnknown(){return this.filters.push({code:{$isNull:!0}}),this}withCodeNotContaining(e){return this.filters.push({code:{$notContains:e}}),this}withCodeStartingWith(e){return this.filters.push({code:{$startsWith:e}}),this}withCodeNotStartingWith(e){return this.filters.push({code:{$notStartsWith:e}}),this}withCodeEndingWith(e){return this.filters.push({code:{$endsWith:e}}),this}withCodeNotEndingWith(e){return this.filters.push({code:{$notEndsWith:e}}),this}withCodeSoundingLike(e){return this.filters.push({code:{$soundLike:e}}),this}withColorContaining(e){return this.filters.push({color:{$contains:e}}),this}withColorIs(e){return this.filters.push({color:{$eq:e}}),this}withColorIsNot(e){return this.filters.push({color:{$ne:e}}),this}withColorIn(...e){return this.filters.push({color:{$in:e}}),this}withColorNotIn(...e){return this.filters.push({color:{$notIn:e}}),this}withColorGreaterThan(e){return this.filters.push({color:{$gt:e}}),this}withColorGreaterThanOrEqualTo(e){return this.filters.push({color:{$gte:e}}),this}withColorLessThan(e){return this.filters.push({color:{$lt:e}}),this}withColorLessThanOrEqualTo(e){return this.filters.push({color:{$lte:e}}),this}withColorBetween(e,t){return this.filters.push({color:{$between:[e,t]}}),this}withColorIsKnown(){return this.filters.push({color:{$isNull:!1}}),this}withColorIsUnknown(){return this.filters.push({color:{$isNull:!0}}),this}withColorNotContaining(e){return this.filters.push({color:{$notContains:e}}),this}withColorStartingWith(e){return this.filters.push({color:{$startsWith:e}}),this}withColorNotStartingWith(e){return this.filters.push({color:{$notStartsWith:e}}),this}withColorEndingWith(e){return this.filters.push({color:{$endsWith:e}}),this}withColorNotEndingWith(e){return this.filters.push({color:{$notEndsWith:e}}),this}withColorSoundingLike(e){return this.filters.push({color:{$soundLike:e}}),this}withDisplayOrderIs(e){return this.filters.push({displayOrder:{$eq:e}}),this}withDisplayOrderIsNot(e){return this.filters.push({displayOrder:{$ne:e}}),this}withDisplayOrderIn(...e){return this.filters.push({displayOrder:{$in:e}}),this}withDisplayOrderNotIn(...e){return this.filters.push({displayOrder:{$notIn:e}}),this}withDisplayOrderGreaterThan(e){return this.filters.push({displayOrder:{$gt:e}}),this}withDisplayOrderGreaterThanOrEqualTo(e){return this.filters.push({displayOrder:{$gte:e}}),this}withDisplayOrderLessThan(e){return this.filters.push({displayOrder:{$lt:e}}),this}withDisplayOrderLessThanOrEqualTo(e){return this.filters.push({displayOrder:{$lte:e}}),this}withDisplayOrderBetween(e,t){return this.filters.push({displayOrder:{$between:[e,t]}}),this}withDisplayOrderIsKnown(){return this.filters.push({displayOrder:{$isNull:!1}}),this}withDisplayOrderIsUnknown(){return this.filters.push({displayOrder:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByCodeAscending(){return this.query.orderBy("code","asc"),this}orderByCodeDescending(){return this.query.orderBy("code","desc"),this}orderByColorAscending(){return this.query.orderBy("color","asc"),this}orderByColorDescending(){return this.query.orderBy("color","desc"),this}orderByDisplayOrderAscending(){return this.query.orderBy("displayOrder","asc"),this}orderByDisplayOrderDescending(){return this.query.orderBy("displayOrder","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}minDisplayOrder(){return this.minDisplayOrderAs("minOfDisplayOrder")}minDisplayOrderAs(e){return this.query.aggregate("min","displayOrder",e),this}maxDisplayOrder(){return this.maxDisplayOrderAs("maxOfDisplayOrder")}maxDisplayOrderAs(e){return this.query.aggregate("max","displayOrder",e),this}sumDisplayOrder(){return this.sumDisplayOrderAs("sumOfDisplayOrder")}sumDisplayOrderAs(e){return this.query.aggregate("sum","displayOrder",e),this}avgDisplayOrder(){return this.avgDisplayOrderAs("avgOfDisplayOrder")}avgDisplayOrderAs(e){return this.query.aggregate("avg","displayOrder",e),this}standardDeviationDisplayOrder(){return this.standardDeviationDisplayOrderAs("standardDeviationOfDisplayOrder")}standardDeviationDisplayOrderAs(e){return this.query.aggregate("stddev","displayOrder",e),this}squareRootOfPopulationStandardDeviationDisplayOrder(){return this.squareRootOfPopulationStandardDeviationDisplayOrderAs("squareRootOfPopulationStandardDeviationOfDisplayOrder")}squareRootOfPopulationStandardDeviationDisplayOrderAs(e){return this.query.aggregate("stddev_pop","displayOrder",e),this}sampleVarianceDisplayOrder(){return this.sampleVarianceDisplayOrderAs("sampleVarianceOfDisplayOrder")}sampleVarianceDisplayOrderAs(e){return this.query.aggregate("var_samp","displayOrder",e),this}samplePopulationVarianceDisplayOrder(){return this.samplePopulationVarianceDisplayOrderAs("samplePopulationVarianceOfDisplayOrder")}samplePopulationVarianceDisplayOrderAs(e){return this.query.aggregate("var_pop","displayOrder",e),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByCode(){return this.query.groupBy("code"),this}groupByCodeAs(e){return this.query.groupBy("code"),this}groupByColor(){return this.query.groupBy("color"),this}groupByColorAs(e){return this.query.groupBy("color"),this}groupByDisplayOrder(){return this.query.groupBy("displayOrder"),this}groupByDisplayOrderAs(e){return this.query.groupBy("displayOrder"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,t,i=!0){return this.query.facetBy(e,"platform",t,i,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:e}),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof V?u:V.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof V?f:V.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof V?o:V.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class Zs{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new V}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Tr{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("Customer"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new en(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","platform","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}selectCustomerOrderListWith(e){return this.query.relationQuery("customerOrderList",e.toQuery(),"id","customer",!0,{kind:"relation-select",method:"selectCustomerOrderListWith",relation:"customerOrderList"}),this}haveCustomerOrders(){return this.withCustomerOrderListMatching({toQuery:()=>new C("CustomerOrder")})}haveNoCustomerOrders(){return this.withoutCustomerOrderListMatching({toQuery:()=>new C("CustomerOrder")})}withCustomerOrderListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"customer"}}}),this}withoutCustomerOrderListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"customer"}}}),this}countCustomerOrders(){return this.countCustomerOrdersAs("countCustomerOrders")}countCustomerOrdersAs(e){const t=new C("CustomerOrder").filter({version:{$gte:1}});return this.countCustomerOrdersWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomerOrdersAs",relation:"customerOrderList",alias:e},this}countCustomerOrdersWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"relation-count",method:"countCustomerOrdersWith",relation:"customerOrderList",alias:e}),this}minTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.minTotalAmountOfCustomerOrdersAs("minOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}minTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"minTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}maxTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.maxTotalAmountOfCustomerOrdersAs("maxOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}maxTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"maxTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}sumTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.sumTotalAmountOfCustomerOrdersAs("sumOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}sumTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"sumTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}avgTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.avgTotalAmountOfCustomerOrdersAs("avgOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}avgTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"avgTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}standardDeviationTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.standardDeviationTotalAmountOfCustomerOrdersAs("standardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}standardDeviationTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"standardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs("squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}sampleVarianceTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.sampleVarianceTotalAmountOfCustomerOrdersAs("sampleVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}sampleVarianceTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"sampleVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}samplePopulationVarianceTotalAmountOfCustomerOrders(){const e=new C("CustomerOrder").filter({version:{$gte:1}});return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs("samplePopulationVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>e})}samplePopulationVarianceTotalAmountOfCustomerOrdersAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","totalAmount",e),this.query.relationAggregate("customerOrderList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:e}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,t){return this.filters.push({name:{$between:[e,t]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,t,i=!0){return this.query.facetBy(e,"platform",t,i,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:e}),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof G?u:G.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof G?f:G.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof G?o:G.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class en{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new G}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Rr{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("CustomerOrder"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new tn(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","customer","status","orderNumber","orderDate","totalAmount","version"]),this}selectId(){return this.query.select(["id"]),this}selectOrderNumber(){return this.query.select(["orderNumber"]),this}selectOrderDate(){return this.query.select(["orderDate"]),this}selectTotalAmount(){return this.query.select(["totalAmount"]),this}selectVersion(){return this.query.select(["version"]),this}selectCustomerWith(e){return this.query.select(["customer"]),this.query.relationQuery("customer",e.toQuery(),"customer","id",!1,{kind:"relation-select",method:"selectCustomerWith",relation:"customer"}),this}selectStatusWith(e){return this.query.select(["status"]),this.query.relationQuery("status",e.toQuery(),"status","id",!1,{kind:"relation-select",method:"selectStatusWith",relation:"status"}),this}withCustomerMatching(e){return this.filters.push({customer:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutCustomerMatching(e){return this.filters.push({customer:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withStatusMatching(e){return this.filters.push({status:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutStatusMatching(e){return this.filters.push({status:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}selectOrderItemListWith(e){return this.query.relationQuery("orderItemList",e.toQuery(),"id","customerOrder",!0,{kind:"relation-select",method:"selectOrderItemListWith",relation:"orderItemList"}),this}haveOrderItems(){return this.withOrderItemListMatching({toQuery:()=>new C("OrderItem")})}haveNoOrderItems(){return this.withoutOrderItemListMatching({toQuery:()=>new C("OrderItem")})}withOrderItemListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"customerOrder"}}}),this}withoutOrderItemListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"customerOrder"}}}),this}countOrderItems(){return this.countOrderItemsAs("countOrderItems")}countOrderItemsAs(e){const t=new C("OrderItem").filter({version:{$gte:1}});return this.countOrderItemsWith(e,{toQuery:()=>t}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countOrderItemsAs",relation:"orderItemList",alias:e},this}countOrderItemsWith(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"relation-count",method:"countOrderItemsWith",relation:"orderItemList",alias:e}),this}minQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.minQuantityOfOrderItemsAs("minOfQuantityOfOrderItems",{toQuery:()=>e})}minQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"minQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}maxQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.maxQuantityOfOrderItemsAs("maxOfQuantityOfOrderItems",{toQuery:()=>e})}maxQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"maxQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}sumQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.sumQuantityOfOrderItemsAs("sumOfQuantityOfOrderItems",{toQuery:()=>e})}sumQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"sumQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}avgQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.avgQuantityOfOrderItemsAs("avgOfQuantityOfOrderItems",{toQuery:()=>e})}avgQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"avgQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}standardDeviationQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.standardDeviationQuantityOfOrderItemsAs("standardDeviationOfQuantityOfOrderItems",{toQuery:()=>e})}standardDeviationQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"standardDeviationQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}squareRootOfPopulationStandardDeviationQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs("squareRootOfPopulationStandardDeviationOfQuantityOfOrderItems",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}sampleVarianceQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.sampleVarianceQuantityOfOrderItemsAs("sampleVarianceOfQuantityOfOrderItems",{toQuery:()=>e})}sampleVarianceQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"sampleVarianceQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}samplePopulationVarianceQuantityOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.samplePopulationVarianceQuantityOfOrderItemsAs("samplePopulationVarianceOfQuantityOfOrderItems",{toQuery:()=>e})}samplePopulationVarianceQuantityOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","quantity",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceQuantityOfOrderItemsAs",relation:"orderItemList",alias:e}),this}minUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.minUnitPriceOfOrderItemsAs("minOfUnitPriceOfOrderItems",{toQuery:()=>e})}minUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("min","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"minUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}maxUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.maxUnitPriceOfOrderItemsAs("maxOfUnitPriceOfOrderItems",{toQuery:()=>e})}maxUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("max","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"maxUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}sumUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.sumUnitPriceOfOrderItemsAs("sumOfUnitPriceOfOrderItems",{toQuery:()=>e})}sumUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("sum","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"sumUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}avgUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.avgUnitPriceOfOrderItemsAs("avgOfUnitPriceOfOrderItems",{toQuery:()=>e})}avgUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("avg","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"avgUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}standardDeviationUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.standardDeviationUnitPriceOfOrderItemsAs("standardDeviationOfUnitPriceOfOrderItems",{toQuery:()=>e})}standardDeviationUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"standardDeviationUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}squareRootOfPopulationStandardDeviationUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs("squareRootOfPopulationStandardDeviationOfUnitPriceOfOrderItems",{toQuery:()=>e})}squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("stddev_pop","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}sampleVarianceUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.sampleVarianceUnitPriceOfOrderItemsAs("sampleVarianceOfUnitPriceOfOrderItems",{toQuery:()=>e})}sampleVarianceUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_samp","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"sampleVarianceUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}samplePopulationVarianceUnitPriceOfOrderItems(){const e=new C("OrderItem").filter({version:{$gte:1}});return this.samplePopulationVarianceUnitPriceOfOrderItemsAs("samplePopulationVarianceOfUnitPriceOfOrderItems",{toQuery:()=>e})}samplePopulationVarianceUnitPriceOfOrderItemsAs(e,t){const i=t.toQuery().clone();return i.aggregateItems=[],i.aggregate("var_pop","unitPrice",e),this.query.relationAggregate("orderItemList",e,i,!0,{kind:"aggregate",method:"samplePopulationVarianceUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:e}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByCustomer(e){return this.filters.push({customer:{$eq:e}}),this}filterByCustomerIn(...e){return this.filters.push({customer:{$in:e}}),this}withCustomerIsKnown(){return this.filters.push({customer:{$isNull:!1}}),this}withCustomerIsUnknown(){return this.filters.push({customer:{$isNull:!0}}),this}filterByStatus(e){return this.filters.push({status:{$eq:e}}),this}filterByStatusIn(...e){return this.filters.push({status:{$in:e}}),this}withStatusIsKnown(){return this.filters.push({status:{$isNull:!1}}),this}withStatusIsUnknown(){return this.filters.push({status:{$isNull:!0}}),this}withStatusIsNew(){return this.filters.push({status:{$eq:"1001"}}),this}withStatusIsPaid(){return this.filters.push({status:{$eq:"1002"}}),this}withStatusIsCancelled(){return this.filters.push({status:{$eq:"1003"}}),this}withOrderNumberContaining(e){return this.filters.push({orderNumber:{$contains:e}}),this}withOrderNumberIs(e){return this.filters.push({orderNumber:{$eq:e}}),this}withOrderNumberIsNot(e){return this.filters.push({orderNumber:{$ne:e}}),this}withOrderNumberIn(...e){return this.filters.push({orderNumber:{$in:e}}),this}withOrderNumberNotIn(...e){return this.filters.push({orderNumber:{$notIn:e}}),this}withOrderNumberGreaterThan(e){return this.filters.push({orderNumber:{$gt:e}}),this}withOrderNumberGreaterThanOrEqualTo(e){return this.filters.push({orderNumber:{$gte:e}}),this}withOrderNumberLessThan(e){return this.filters.push({orderNumber:{$lt:e}}),this}withOrderNumberLessThanOrEqualTo(e){return this.filters.push({orderNumber:{$lte:e}}),this}withOrderNumberBetween(e,t){return this.filters.push({orderNumber:{$between:[e,t]}}),this}withOrderNumberIsKnown(){return this.filters.push({orderNumber:{$isNull:!1}}),this}withOrderNumberIsUnknown(){return this.filters.push({orderNumber:{$isNull:!0}}),this}withOrderNumberNotContaining(e){return this.filters.push({orderNumber:{$notContains:e}}),this}withOrderNumberStartingWith(e){return this.filters.push({orderNumber:{$startsWith:e}}),this}withOrderNumberNotStartingWith(e){return this.filters.push({orderNumber:{$notStartsWith:e}}),this}withOrderNumberEndingWith(e){return this.filters.push({orderNumber:{$endsWith:e}}),this}withOrderNumberNotEndingWith(e){return this.filters.push({orderNumber:{$notEndsWith:e}}),this}withOrderNumberSoundingLike(e){return this.filters.push({orderNumber:{$soundLike:e}}),this}withOrderDateIs(e){return this.filters.push({orderDate:{$eq:e}}),this}withOrderDateIsNot(e){return this.filters.push({orderDate:{$ne:e}}),this}withOrderDateIn(...e){return this.filters.push({orderDate:{$in:e}}),this}withOrderDateNotIn(...e){return this.filters.push({orderDate:{$notIn:e}}),this}withOrderDateGreaterThan(e){return this.filters.push({orderDate:{$gt:e}}),this}withOrderDateGreaterThanOrEqualTo(e){return this.filters.push({orderDate:{$gte:e}}),this}withOrderDateLessThan(e){return this.filters.push({orderDate:{$lt:e}}),this}withOrderDateLessThanOrEqualTo(e){return this.filters.push({orderDate:{$lte:e}}),this}withOrderDateBetween(e,t){return this.filters.push({orderDate:{$between:[e,t]}}),this}withOrderDateIsKnown(){return this.filters.push({orderDate:{$isNull:!1}}),this}withOrderDateIsUnknown(){return this.filters.push({orderDate:{$isNull:!0}}),this}withTotalAmountIs(e){return this.filters.push({totalAmount:{$eq:e}}),this}withTotalAmountIsNot(e){return this.filters.push({totalAmount:{$ne:e}}),this}withTotalAmountIn(...e){return this.filters.push({totalAmount:{$in:e}}),this}withTotalAmountNotIn(...e){return this.filters.push({totalAmount:{$notIn:e}}),this}withTotalAmountGreaterThan(e){return this.filters.push({totalAmount:{$gt:e}}),this}withTotalAmountGreaterThanOrEqualTo(e){return this.filters.push({totalAmount:{$gte:e}}),this}withTotalAmountLessThan(e){return this.filters.push({totalAmount:{$lt:e}}),this}withTotalAmountLessThanOrEqualTo(e){return this.filters.push({totalAmount:{$lte:e}}),this}withTotalAmountBetween(e,t){return this.filters.push({totalAmount:{$between:[e,t]}}),this}withTotalAmountIsKnown(){return this.filters.push({totalAmount:{$isNull:!1}}),this}withTotalAmountIsUnknown(){return this.filters.push({totalAmount:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByOrderNumberAscending(){return this.query.orderBy("orderNumber","asc"),this}orderByOrderNumberDescending(){return this.query.orderBy("orderNumber","desc"),this}orderByOrderDateAscending(){return this.query.orderBy("orderDate","asc"),this}orderByOrderDateDescending(){return this.query.orderBy("orderDate","desc"),this}orderByTotalAmountAscending(){return this.query.orderBy("totalAmount","asc"),this}orderByTotalAmountDescending(){return this.query.orderBy("totalAmount","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}minTotalAmount(){return this.minTotalAmountAs("minOfTotalAmount")}minTotalAmountAs(e){return this.query.aggregate("min","totalAmount",e),this}maxTotalAmount(){return this.maxTotalAmountAs("maxOfTotalAmount")}maxTotalAmountAs(e){return this.query.aggregate("max","totalAmount",e),this}sumTotalAmount(){return this.sumTotalAmountAs("sumOfTotalAmount")}sumTotalAmountAs(e){return this.query.aggregate("sum","totalAmount",e),this}avgTotalAmount(){return this.avgTotalAmountAs("avgOfTotalAmount")}avgTotalAmountAs(e){return this.query.aggregate("avg","totalAmount",e),this}standardDeviationTotalAmount(){return this.standardDeviationTotalAmountAs("standardDeviationOfTotalAmount")}standardDeviationTotalAmountAs(e){return this.query.aggregate("stddev","totalAmount",e),this}squareRootOfPopulationStandardDeviationTotalAmount(){return this.squareRootOfPopulationStandardDeviationTotalAmountAs("squareRootOfPopulationStandardDeviationOfTotalAmount")}squareRootOfPopulationStandardDeviationTotalAmountAs(e){return this.query.aggregate("stddev_pop","totalAmount",e),this}sampleVarianceTotalAmount(){return this.sampleVarianceTotalAmountAs("sampleVarianceOfTotalAmount")}sampleVarianceTotalAmountAs(e){return this.query.aggregate("var_samp","totalAmount",e),this}samplePopulationVarianceTotalAmount(){return this.samplePopulationVarianceTotalAmountAs("samplePopulationVarianceOfTotalAmount")}samplePopulationVarianceTotalAmountAs(e){return this.query.aggregate("var_pop","totalAmount",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByCustomer(){return this.query.groupBy("customer"),this}groupByCustomerAs(e){return this.query.groupBy("customer"),this}groupByStatus(){return this.query.groupBy("status"),this}groupByStatusAs(e){return this.query.groupBy("status"),this}groupByOrderNumber(){return this.query.groupBy("orderNumber"),this}groupByOrderNumberAs(e){return this.query.groupBy("orderNumber"),this}groupByOrderDate(){return this.query.groupBy("orderDate"),this}groupByOrderDateAs(e){return this.query.groupBy("orderDate"),this}groupByTotalAmount(){return this.query.groupBy("totalAmount"),this}groupByTotalAmountAs(e){return this.query.groupBy("totalAmount"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByCustomerAs(e,t,i=!0){return this.query.facetBy(e,"customer",t,i,{kind:"facet",method:"facetByCustomerAs",relation:"customer",alias:e}),this}facetByStatusAs(e,t,i=!0){return this.query.facetBy(e,"status",t,i,{kind:"facet",method:"facetByStatusAs",relation:"status",alias:e}),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof K?u:K.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof K?f:K.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof K?o:K.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class tn{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new K}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class kr{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(e=!1){this.query=new C("OrderItem"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}filterByJson(e,t){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const s=st(i,e,nt,t);return this.query=s.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...s.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(e=>({...e}))}purpose(e){return this.query.purpose(e),this._purpose=e,new rn(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,i,s)=>this.executeForPageInternal(t,i,s),(t,i)=>this.executeForStreamInternal(t,i),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,i){return this.query.optimizePaginationWithIdSetConfig(e,t,i),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","customerOrder","productName","quantity","unitPrice","version"]),this}selectId(){return this.query.select(["id"]),this}selectProductName(){return this.query.select(["productName"]),this}selectQuantity(){return this.query.select(["quantity"]),this}selectUnitPrice(){return this.query.select(["unitPrice"]),this}selectVersion(){return this.query.select(["version"]),this}selectCustomerOrderWith(e){return this.query.select(["customerOrder"]),this.query.relationQuery("customerOrder",e.toQuery(),"customerOrder","id",!1,{kind:"relation-select",method:"selectCustomerOrderWith",relation:"customerOrder"}),this}withCustomerOrderMatching(e){return this.filters.push({customerOrder:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutCustomerOrderMatching(e){return this.filters.push({customerOrder:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByCustomerOrder(e){return this.filters.push({customerOrder:{$eq:e}}),this}filterByCustomerOrderIn(...e){return this.filters.push({customerOrder:{$in:e}}),this}withCustomerOrderIsKnown(){return this.filters.push({customerOrder:{$isNull:!1}}),this}withCustomerOrderIsUnknown(){return this.filters.push({customerOrder:{$isNull:!0}}),this}withProductNameContaining(e){return this.filters.push({productName:{$contains:e}}),this}withProductNameIs(e){return this.filters.push({productName:{$eq:e}}),this}withProductNameIsNot(e){return this.filters.push({productName:{$ne:e}}),this}withProductNameIn(...e){return this.filters.push({productName:{$in:e}}),this}withProductNameNotIn(...e){return this.filters.push({productName:{$notIn:e}}),this}withProductNameGreaterThan(e){return this.filters.push({productName:{$gt:e}}),this}withProductNameGreaterThanOrEqualTo(e){return this.filters.push({productName:{$gte:e}}),this}withProductNameLessThan(e){return this.filters.push({productName:{$lt:e}}),this}withProductNameLessThanOrEqualTo(e){return this.filters.push({productName:{$lte:e}}),this}withProductNameBetween(e,t){return this.filters.push({productName:{$between:[e,t]}}),this}withProductNameIsKnown(){return this.filters.push({productName:{$isNull:!1}}),this}withProductNameIsUnknown(){return this.filters.push({productName:{$isNull:!0}}),this}withProductNameNotContaining(e){return this.filters.push({productName:{$notContains:e}}),this}withProductNameStartingWith(e){return this.filters.push({productName:{$startsWith:e}}),this}withProductNameNotStartingWith(e){return this.filters.push({productName:{$notStartsWith:e}}),this}withProductNameEndingWith(e){return this.filters.push({productName:{$endsWith:e}}),this}withProductNameNotEndingWith(e){return this.filters.push({productName:{$notEndsWith:e}}),this}withProductNameSoundingLike(e){return this.filters.push({productName:{$soundLike:e}}),this}withQuantityIs(e){return this.filters.push({quantity:{$eq:e}}),this}withQuantityIsNot(e){return this.filters.push({quantity:{$ne:e}}),this}withQuantityIn(...e){return this.filters.push({quantity:{$in:e}}),this}withQuantityNotIn(...e){return this.filters.push({quantity:{$notIn:e}}),this}withQuantityGreaterThan(e){return this.filters.push({quantity:{$gt:e}}),this}withQuantityGreaterThanOrEqualTo(e){return this.filters.push({quantity:{$gte:e}}),this}withQuantityLessThan(e){return this.filters.push({quantity:{$lt:e}}),this}withQuantityLessThanOrEqualTo(e){return this.filters.push({quantity:{$lte:e}}),this}withQuantityBetween(e,t){return this.filters.push({quantity:{$between:[e,t]}}),this}withQuantityIsKnown(){return this.filters.push({quantity:{$isNull:!1}}),this}withQuantityIsUnknown(){return this.filters.push({quantity:{$isNull:!0}}),this}withUnitPriceIs(e){return this.filters.push({unitPrice:{$eq:e}}),this}withUnitPriceIsNot(e){return this.filters.push({unitPrice:{$ne:e}}),this}withUnitPriceIn(...e){return this.filters.push({unitPrice:{$in:e}}),this}withUnitPriceNotIn(...e){return this.filters.push({unitPrice:{$notIn:e}}),this}withUnitPriceGreaterThan(e){return this.filters.push({unitPrice:{$gt:e}}),this}withUnitPriceGreaterThanOrEqualTo(e){return this.filters.push({unitPrice:{$gte:e}}),this}withUnitPriceLessThan(e){return this.filters.push({unitPrice:{$lt:e}}),this}withUnitPriceLessThanOrEqualTo(e){return this.filters.push({unitPrice:{$lte:e}}),this}withUnitPriceBetween(e,t){return this.filters.push({unitPrice:{$between:[e,t]}}),this}withUnitPriceIsKnown(){return this.filters.push({unitPrice:{$isNull:!1}}),this}withUnitPriceIsUnknown(){return this.filters.push({unitPrice:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByProductNameAscending(){return this.query.orderBy("productName","asc"),this}orderByProductNameDescending(){return this.query.orderBy("productName","desc"),this}orderByQuantityAscending(){return this.query.orderBy("quantity","asc"),this}orderByQuantityDescending(){return this.query.orderBy("quantity","desc"),this}orderByUnitPriceAscending(){return this.query.orderBy("unitPrice","asc"),this}orderByUnitPriceDescending(){return this.query.orderBy("unitPrice","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(e){return this.query.aggregate("Count","id",e),this._pageCountAlias=e,this._pageCountMethod="countAs",this}minQuantity(){return this.minQuantityAs("minOfQuantity")}minQuantityAs(e){return this.query.aggregate("min","quantity",e),this}maxQuantity(){return this.maxQuantityAs("maxOfQuantity")}maxQuantityAs(e){return this.query.aggregate("max","quantity",e),this}sumQuantity(){return this.sumQuantityAs("sumOfQuantity")}sumQuantityAs(e){return this.query.aggregate("sum","quantity",e),this}avgQuantity(){return this.avgQuantityAs("avgOfQuantity")}avgQuantityAs(e){return this.query.aggregate("avg","quantity",e),this}standardDeviationQuantity(){return this.standardDeviationQuantityAs("standardDeviationOfQuantity")}standardDeviationQuantityAs(e){return this.query.aggregate("stddev","quantity",e),this}squareRootOfPopulationStandardDeviationQuantity(){return this.squareRootOfPopulationStandardDeviationQuantityAs("squareRootOfPopulationStandardDeviationOfQuantity")}squareRootOfPopulationStandardDeviationQuantityAs(e){return this.query.aggregate("stddev_pop","quantity",e),this}sampleVarianceQuantity(){return this.sampleVarianceQuantityAs("sampleVarianceOfQuantity")}sampleVarianceQuantityAs(e){return this.query.aggregate("var_samp","quantity",e),this}samplePopulationVarianceQuantity(){return this.samplePopulationVarianceQuantityAs("samplePopulationVarianceOfQuantity")}samplePopulationVarianceQuantityAs(e){return this.query.aggregate("var_pop","quantity",e),this}minUnitPrice(){return this.minUnitPriceAs("minOfUnitPrice")}minUnitPriceAs(e){return this.query.aggregate("min","unitPrice",e),this}maxUnitPrice(){return this.maxUnitPriceAs("maxOfUnitPrice")}maxUnitPriceAs(e){return this.query.aggregate("max","unitPrice",e),this}sumUnitPrice(){return this.sumUnitPriceAs("sumOfUnitPrice")}sumUnitPriceAs(e){return this.query.aggregate("sum","unitPrice",e),this}avgUnitPrice(){return this.avgUnitPriceAs("avgOfUnitPrice")}avgUnitPriceAs(e){return this.query.aggregate("avg","unitPrice",e),this}standardDeviationUnitPrice(){return this.standardDeviationUnitPriceAs("standardDeviationOfUnitPrice")}standardDeviationUnitPriceAs(e){return this.query.aggregate("stddev","unitPrice",e),this}squareRootOfPopulationStandardDeviationUnitPrice(){return this.squareRootOfPopulationStandardDeviationUnitPriceAs("squareRootOfPopulationStandardDeviationOfUnitPrice")}squareRootOfPopulationStandardDeviationUnitPriceAs(e){return this.query.aggregate("stddev_pop","unitPrice",e),this}sampleVarianceUnitPrice(){return this.sampleVarianceUnitPriceAs("sampleVarianceOfUnitPrice")}sampleVarianceUnitPriceAs(e){return this.query.aggregate("var_samp","unitPrice",e),this}samplePopulationVarianceUnitPrice(){return this.samplePopulationVarianceUnitPriceAs("samplePopulationVarianceOfUnitPrice")}samplePopulationVarianceUnitPriceAs(e){return this.query.aggregate("var_pop","unitPrice",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByCustomerOrder(){return this.query.groupBy("customerOrder"),this}groupByCustomerOrderAs(e){return this.query.groupBy("customerOrder"),this}groupByProductName(){return this.query.groupBy("productName"),this}groupByProductNameAs(e){return this.query.groupBy("productName"),this}groupByQuantity(){return this.query.groupBy("quantity"),this}groupByQuantityAs(e){return this.query.groupBy("quantity"),this}groupByUnitPrice(){return this.query.groupBy("unitPrice"),this}groupByUnitPriceAs(e){return this.query.groupBy("unitPrice"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByCustomerOrderAs(e,t,i=!0){return this.query.facetBy(e,"customerOrder",t,i,{kind:"facet",method:"facetByCustomerOrderAs",relation:"customerOrder",alias:e}),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),i=await t.executeQuery(e.prepareQuery(this.query)),s=new z,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:i.map(u=>u instanceof se?u:se.fromRecord(u,s)),a=new X(o);return n&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await oe(t,u=>e.prepareQuery(u),this.query,this.query.facets)),a}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new X(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,i){this.ensureIntent(),this.query.offset(t).limit(i),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=n?void 0:await s.executeCount(this.query,this._pageCountAlias,o),u=this.query.clone();u.aggregateItems=u.aggregateItems.filter(f=>!(String(f.function).toLowerCase()==="count"&&f.alias===this._pageCountAlias));const h=await s.executeQuery(e.prepareQuery(u)),l=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query,this._pageCountAlias,o),d=new z,c=new X(h.map(f=>f instanceof se?f:se.fromRecord(f,d)));return c.totalCount=l,this._pageCountAlias!==void 0&&(c.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(c.facets=await oe(s,f=>e.prepareQuery(f),this.query,this.query.facets)),{data:c,totalCount:l,offset:t,limit:i}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),s=new z;for await(const n of i.executeForStream(this.query,t))for(const o of n)yield o instanceof se?o:se.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class rn{constructor(e,t,i,s,n,o,a){this.execute=e,this.executeRows=t,this.page=i,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=a}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new se}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,i){return this.ensureIntent(),this.page(e,t,i)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class de{static platforms(){return new Er(!1)}static platformsWithMinimalFields(){return new Er(!0)}static orderStatuses(){return new Nr(!1)}static orderStatusesWithMinimalFields(){return new Nr(!0)}static customers(){return new Tr(!1)}static customersWithMinimalFields(){return new Tr(!0)}static customerOrders(){return new Rr(!1)}static customerOrdersWithMinimalFields(){return new Rr(!0)}static orderItems(){return new kr(!1)}static orderItemsWithMinimalFields(){return new kr(!0)}}class D extends Error{constructor(e,t,i){const s=`select${i.charAt(0).toUpperCase()}${i.slice(1)}(...)`,n={error:"TeaQLNotLoadedError",root:e,accessPath:t.split("."),breakPoint:i,missingPreload:[i],suggestedFix:s,severity:"error",humanMessage:`访问 ${e}.${t} 时缺少预加载。请在查询中加入 ${s}`};super(JSON.stringify(n)),this.root=e,this.accessPath=t,this.breakPoint=i,this.name="TeaQLNotLoadedError",this.details=n}root;accessPath;breakPoint;details}function T(r,e){return r?`${r}.${e}`:e}class g{constructor(e,t=!0,i){this.value=e,this.present=t,this.notLoaded=i}value;present;notLoaded;static missing(){return new g(void 0,!1)}static notLoaded(e){return new g(void 0,!1,e)}eval(){if(this.notLoaded)throw this.notLoaded;return this.present?this.value:void 0}isPresent(){if(this.notLoaded)throw this.notLoaded;return this.present}orElse(e){const t=this.eval();return this.present&&t!=null?t:e}}class ge{constructor(e,t="Platform(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}name(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"name");return this.value.isLoaded("name")?new g(this.value.name):g.notLoaded(new D(this.root,e,"name"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}orderStatusList(){const e=T(this.path,"orderStatusList");return this.notLoaded?new De([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("orderStatusList")?new De(this.value.orderStatusList(),this.root,e):new De([],this.root,e,!1,new D(this.root,e,"orderStatusList")):De.missing(this.root,e)}customerList(){const e=T(this.path,"customerList");return this.notLoaded?new Be([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("customerList")?new Be(this.value.customerList(),this.root,e):new Be([],this.root,e,!1,new D(this.root,e,"customerList")):Be.missing(this.root,e)}}class Ae{constructor(e,t="OrderStatus(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}name(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"name");return this.value.isLoaded("name")?new g(this.value.name):g.notLoaded(new D(this.root,e,"name"))}code(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"code");return this.value.isLoaded("code")?new g(this.value.code):g.notLoaded(new D(this.root,e,"code"))}color(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"color");return this.value.isLoaded("color")?new g(this.value.color):g.notLoaded(new D(this.root,e,"color"))}displayOrder(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"displayOrder");return this.value.isLoaded("displayOrder")?new g(this.value.displayOrder):g.notLoaded(new D(this.root,e,"displayOrder"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}platformId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"platform");return this.value.isLoaded("platform")?new g(this.value.platform):g.notLoaded(new D(this.root,e,"platform"))}platform(){const e=T(this.path,"platform");if(this.notLoaded)return new ge(void 0,this.root,e,this.notLoaded);if(!this.value)return new ge(void 0,this.root,e);if(!this.value.isLoaded("platform"))return new ge(void 0,this.root,e,new D(this.root,e,"platform"));const t=this.value.platform,i=t==null?void 0:t instanceof W?t:W.fromRecord({id:t});return new ge(i,this.root,e)}customerOrderList(){const e=T(this.path,"customerOrderList");return this.notLoaded?new ce([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("customerOrderList")?new ce(this.value.customerOrderList(),this.root,e):new ce([],this.root,e,!1,new D(this.root,e,"customerOrderList")):ce.missing(this.root,e)}}class Se{constructor(e,t="Customer(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}name(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"name");return this.value.isLoaded("name")?new g(this.value.name):g.notLoaded(new D(this.root,e,"name"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}platformId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"platform");return this.value.isLoaded("platform")?new g(this.value.platform):g.notLoaded(new D(this.root,e,"platform"))}platform(){const e=T(this.path,"platform");if(this.notLoaded)return new ge(void 0,this.root,e,this.notLoaded);if(!this.value)return new ge(void 0,this.root,e);if(!this.value.isLoaded("platform"))return new ge(void 0,this.root,e,new D(this.root,e,"platform"));const t=this.value.platform,i=t==null?void 0:t instanceof W?t:W.fromRecord({id:t});return new ge(i,this.root,e)}customerOrderList(){const e=T(this.path,"customerOrderList");return this.notLoaded?new ce([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("customerOrderList")?new ce(this.value.customerOrderList(),this.root,e):new ce([],this.root,e,!1,new D(this.root,e,"customerOrderList")):ce.missing(this.root,e)}}class be{constructor(e,t="CustomerOrder(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}orderNumber(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"orderNumber");return this.value.isLoaded("orderNumber")?new g(this.value.orderNumber):g.notLoaded(new D(this.root,e,"orderNumber"))}orderDate(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"orderDate");return this.value.isLoaded("orderDate")?new g(this.value.orderDate):g.notLoaded(new D(this.root,e,"orderDate"))}totalAmount(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"totalAmount");return this.value.isLoaded("totalAmount")?new g(this.value.totalAmount):g.notLoaded(new D(this.root,e,"totalAmount"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}customerId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"customer");return this.value.isLoaded("customer")?new g(this.value.customer):g.notLoaded(new D(this.root,e,"customer"))}statusId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"status");return this.value.isLoaded("status")?new g(this.value.status):g.notLoaded(new D(this.root,e,"status"))}customer(){const e=T(this.path,"customer");if(this.notLoaded)return new Se(void 0,this.root,e,this.notLoaded);if(!this.value)return new Se(void 0,this.root,e);if(!this.value.isLoaded("customer"))return new Se(void 0,this.root,e,new D(this.root,e,"customer"));const t=this.value.customer,i=t==null?void 0:t instanceof G?t:G.fromRecord({id:t});return new Se(i,this.root,e)}status(){const e=T(this.path,"status");if(this.notLoaded)return new Ae(void 0,this.root,e,this.notLoaded);if(!this.value)return new Ae(void 0,this.root,e);if(!this.value.isLoaded("status"))return new Ae(void 0,this.root,e,new D(this.root,e,"status"));const t=this.value.status,i=t==null?void 0:t instanceof V?t:V.fromRecord({id:t});return new Ae(i,this.root,e)}orderItemList(){const e=T(this.path,"orderItemList");return this.notLoaded?new Qe([],this.root,e,!1,this.notLoaded):this.value?this.value.isLoaded("orderItemList")?new Qe(this.value.orderItemList(),this.root,e):new Qe([],this.root,e,!1,new D(this.root,e,"orderItemList")):Qe.missing(this.root,e)}}class St{constructor(e,t="OrderItem(null)",i="",s){this.value=e,this.root=t,this.path=i,this.notLoaded=s}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"id");return this.value.isLoaded("id")?new g(this.value.id):g.notLoaded(new D(this.root,e,"id"))}productName(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"productName");return this.value.isLoaded("productName")?new g(this.value.productName):g.notLoaded(new D(this.root,e,"productName"))}quantity(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"quantity");return this.value.isLoaded("quantity")?new g(this.value.quantity):g.notLoaded(new D(this.root,e,"quantity"))}unitPrice(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"unitPrice");return this.value.isLoaded("unitPrice")?new g(this.value.unitPrice):g.notLoaded(new D(this.root,e,"unitPrice"))}version(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"version");return this.value.isLoaded("version")?new g(this.value.version):g.notLoaded(new D(this.root,e,"version"))}customerOrderId(){if(this.notLoaded)return g.notLoaded(this.notLoaded);if(!this.value)return g.missing();const e=T(this.path,"customerOrder");return this.value.isLoaded("customerOrder")?new g(this.value.customerOrder):g.notLoaded(new D(this.root,e,"customerOrder"))}customerOrder(){const e=T(this.path,"customerOrder");if(this.notLoaded)return new be(void 0,this.root,e,this.notLoaded);if(!this.value)return new be(void 0,this.root,e);if(!this.value.isLoaded("customerOrder"))return new be(void 0,this.root,e,new D(this.root,e,"customerOrder"));const t=this.value.customerOrder,i=t==null?void 0:t instanceof K?t:K.fromRecord({id:t});return new be(i,this.root,e)}}class De{constructor(e,t="OrderStatus(null)",i="",s=!0,n){this.items=e,this.root=t,this.path=i,this.present=s,this.notLoaded=n}items;root;path;present;notLoaded;static missing(e,t=""){return new De([],e,t,!1)}size(){return this.notLoaded?g.notLoaded(this.notLoaded):this.present?new g(this.items.length):g.missing()}first(){return this.get(0)}get(e){const t=T(this.path,`get(${e})`);return this.notLoaded?new Ae(void 0,this.root,t,this.notLoaded):!this.present||e<0||e>=this.items.length?new Ae(void 0,this.root,t):new Ae(this.items[e],this.root,t)}}class Be{constructor(e,t="Customer(null)",i="",s=!0,n){this.items=e,this.root=t,this.path=i,this.present=s,this.notLoaded=n}items;root;path;present;notLoaded;static missing(e,t=""){return new Be([],e,t,!1)}size(){return this.notLoaded?g.notLoaded(this.notLoaded):this.present?new g(this.items.length):g.missing()}first(){return this.get(0)}get(e){const t=T(this.path,`get(${e})`);return this.notLoaded?new Se(void 0,this.root,t,this.notLoaded):!this.present||e<0||e>=this.items.length?new Se(void 0,this.root,t):new Se(this.items[e],this.root,t)}}class ce{constructor(e,t="CustomerOrder(null)",i="",s=!0,n){this.items=e,this.root=t,this.path=i,this.present=s,this.notLoaded=n}items;root;path;present;notLoaded;static missing(e,t=""){return new ce([],e,t,!1)}size(){return this.notLoaded?g.notLoaded(this.notLoaded):this.present?new g(this.items.length):g.missing()}first(){return this.get(0)}get(e){const t=T(this.path,`get(${e})`);return this.notLoaded?new be(void 0,this.root,t,this.notLoaded):!this.present||e<0||e>=this.items.length?new be(void 0,this.root,t):new be(this.items[e],this.root,t)}}class Qe{constructor(e,t="OrderItem(null)",i="",s=!0,n){this.items=e,this.root=t,this.path=i,this.present=s,this.notLoaded=n}items;root;path;present;notLoaded;static missing(e,t=""){return new Qe([],e,t,!1)}size(){return this.notLoaded?g.notLoaded(this.notLoaded):this.present?new g(this.items.length):g.missing()}first(){return this.get(0)}get(e){const t=T(this.path,`get(${e})`);return this.notLoaded?new St(void 0,this.root,t,this.notLoaded):!this.present||e<0||e>=this.items.length?new St(void 0,this.root,t):new St(this.items[e],this.root,t)}}class Ft{static platform(e){return new ge(e,`Platform(id=${e?.id??"null"})`)}static orderStatus(e){return new Ae(e,`OrderStatus(id=${e?.id??"null"})`)}static customer(e){return new Se(e,`Customer(id=${e?.id??"null"})`)}static customerOrder(e){return new be(e,`CustomerOrder(id=${e?.id??"null"})`)}static orderItem(e){return new St(e,`OrderItem(id=${e?.id??"null"})`)}}const ui={Platform:{table:"platform_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{orderStatusList:{targetEntity:"OrderStatus",localKey:"id",foreignKey:"platform",many:!0},customerList:{targetEntity:"Customer",localKey:"id",foreignKey:"platform",many:!0}}},OrderStatus:{table:"order_status_data",auditMaskFields:[],columns:{platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},code:{columnName:"code",modelName:"code",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},color:{columnName:"color",modelName:"color",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},displayOrder:{columnName:"display_order",modelName:"display_order",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1},customerOrderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"status",many:!0}}},Customer:{table:"customer_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1},customerOrderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"customer",many:!0}}},CustomerOrder:{table:"customer_order_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},customer:{columnName:"customer",modelName:"customer",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},status:{columnName:"status",modelName:"status",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},orderNumber:{columnName:"order_number",modelName:"order_number",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},orderDate:{columnName:"order_date",modelName:"order_date",logPolicy:"plain",logicalType:"date",decode:"date",nullable:!1},totalAmount:{columnName:"total_amount",modelName:"total_amount",logPolicy:"plain",logicalType:"decimal",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{customer:{targetEntity:"Customer",localKey:"customer",foreignKey:"id",many:!1},status:{targetEntity:"OrderStatus",localKey:"status",foreignKey:"id",many:!1},orderItemList:{targetEntity:"OrderItem",localKey:"id",foreignKey:"customerOrder",many:!0}}},OrderItem:{table:"order_item_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},customerOrder:{columnName:"customer_order",modelName:"customer_order",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},productName:{columnName:"product_name",modelName:"product_name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},quantity:{columnName:"quantity",modelName:"quantity",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1},unitPrice:{columnName:"unit_price",modelName:"unit_price",logPolicy:"plain",logicalType:"decimal",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{customerOrder:{targetEntity:"CustomerOrder",localKey:"customerOrder",foreignKey:"id",many:!1}}}};async function sn(r){let e=(await de.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(r))[0];e||(e=W.teaqlBootstrapNew("1"),e.updateName("Commerce Test Platform"),await e.auditAs("create generated Domain Root Platform").save(r)),r.withActiveRoot({entity:"Platform",id:e.id});let t=(await de.orderStatuses().withIdIs("1001").comment("what: locate generated constant OrderStatus(1001)").purpose("why: idempotent runtime bootstrap").executeForList(r))[0];if(!t)t=V.teaqlBootstrapNew("1001"),t.updatePlatform(e),t.updateName("New"),t.updateCode("NEW"),t.updateColor("#94A3B8"),t.updateDisplayOrder(1),await t.auditAs("create model constant OrderStatus(1001)").save(r);else{let n=!1;String(t.platform?.id??t.platform)!==String(e.id)&&(t.updatePlatform(e),n=!0),t.name!=="New"&&(t.updateName("New"),n=!0),t.code!=="NEW"&&(t.updateCode("NEW"),n=!0),t.color!=="#94A3B8"&&(t.updateColor("#94A3B8"),n=!0),t.displayOrder!==1&&(t.updateDisplayOrder(1),n=!0),n&&await t.auditAs("reconcile model constant OrderStatus(1001)").save(r)}let i=(await de.orderStatuses().withIdIs("1002").comment("what: locate generated constant OrderStatus(1002)").purpose("why: idempotent runtime bootstrap").executeForList(r))[0];if(!i)i=V.teaqlBootstrapNew("1002"),i.updatePlatform(e),i.updateName("Paid"),i.updateCode("PAID"),i.updateColor("#22C55E"),i.updateDisplayOrder(2),await i.auditAs("create model constant OrderStatus(1002)").save(r);else{let n=!1;String(i.platform?.id??i.platform)!==String(e.id)&&(i.updatePlatform(e),n=!0),i.name!=="Paid"&&(i.updateName("Paid"),n=!0),i.code!=="PAID"&&(i.updateCode("PAID"),n=!0),i.color!=="#22C55E"&&(i.updateColor("#22C55E"),n=!0),i.displayOrder!==2&&(i.updateDisplayOrder(2),n=!0),n&&await i.auditAs("reconcile model constant OrderStatus(1002)").save(r)}let s=(await de.orderStatuses().withIdIs("1003").comment("what: locate generated constant OrderStatus(1003)").purpose("why: idempotent runtime bootstrap").executeForList(r))[0];if(!s)s=V.teaqlBootstrapNew("1003"),s.updatePlatform(e),s.updateName("Cancelled"),s.updateCode("CANCELLED"),s.updateColor("#EF4444"),s.updateDisplayOrder(3),await s.auditAs("create model constant OrderStatus(1003)").save(r);else{let n=!1;String(s.platform?.id??s.platform)!==String(e.id)&&(s.updatePlatform(e),n=!0),s.name!=="Cancelled"&&(s.updateName("Cancelled"),n=!0),s.code!=="CANCELLED"&&(s.updateCode("CANCELLED"),n=!0),s.color!=="#EF4444"&&(s.updateColor("#EF4444"),n=!0),s.displayOrder!==3&&(s.updateDisplayOrder(3),n=!0),n&&await s.auditAs("reconcile model constant OrderStatus(1003)").save(r)}}const nn=new Ss(ui,{Platform:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&t.push({ruleId:"required",location:x.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&t.push({ruleId:"max_length",location:x.property("name"),inputValue:e.payload.name,systemValue:100})}},OrderStatus:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&t.push({ruleId:"required",location:x.property("platform")}),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&t.push({ruleId:"required",location:x.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&t.push({ruleId:"max_length",location:x.property("name"),inputValue:e.payload.name,systemValue:100}),(e.action==="Create"&&e.payload.code===void 0||e.payload.code===null)&&t.push({ruleId:"required",location:x.property("code")}),e.payload.code!=null&&[...String(e.payload.code)].length>100&&t.push({ruleId:"max_length",location:x.property("code"),inputValue:e.payload.code,systemValue:100}),(e.action==="Create"&&e.payload.color===void 0||e.payload.color===null)&&t.push({ruleId:"required",location:x.property("color")}),e.payload.color!=null&&[...String(e.payload.color)].length>100&&t.push({ruleId:"max_length",location:x.property("color"),inputValue:e.payload.color,systemValue:100}),(e.action==="Create"&&e.payload.display_order===void 0||e.payload.display_order===null)&&t.push({ruleId:"required",location:x.property("display_order")})}},Customer:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&t.push({ruleId:"required",location:x.property("platform")}),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&t.push({ruleId:"required",location:x.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&t.push({ruleId:"max_length",location:x.property("name"),inputValue:e.payload.name,systemValue:100})}},CustomerOrder:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.customer===void 0||e.payload.customer===null)&&t.push({ruleId:"required",location:x.property("customer")}),(e.action==="Create"&&e.payload.status===void 0||e.payload.status===null)&&t.push({ruleId:"required",location:x.property("status")}),(e.action==="Create"&&e.payload.order_number===void 0||e.payload.order_number===null)&&t.push({ruleId:"required",location:x.property("order_number")}),e.payload.order_number!=null&&[...String(e.payload.order_number)].length>100&&t.push({ruleId:"max_length",location:x.property("order_number"),inputValue:e.payload.order_number,systemValue:100}),(e.action==="Create"&&e.payload.order_date===void 0||e.payload.order_date===null)&&t.push({ruleId:"required",location:x.property("order_date")}),(e.action==="Create"&&e.payload.total_amount===void 0||e.payload.total_amount===null)&&t.push({ruleId:"required",location:x.property("total_amount")})}},OrderItem:{checkAndFix(r,e,t){r.getResource("fixTime"),(e.action==="Create"&&e.payload.customer_order===void 0||e.payload.customer_order===null)&&t.push({ruleId:"required",location:x.property("customer_order")}),(e.action==="Create"&&e.payload.product_name===void 0||e.payload.product_name===null)&&t.push({ruleId:"required",location:x.property("product_name")}),e.payload.product_name!=null&&[...String(e.payload.product_name)].length>100&&t.push({ruleId:"max_length",location:x.property("product_name"),inputValue:e.payload.product_name,systemValue:100}),(e.action==="Create"&&e.payload.quantity===void 0||e.payload.quantity===null)&&t.push({ruleId:"required",location:x.property("quantity")}),(e.action==="Create"&&e.payload.unit_price===void 0||e.payload.unit_price===null)&&t.push({ruleId:"required",location:x.property("unit_price")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Commerce Test Platform"}},constants:[{entity:"OrderStatus",id:"1001",values:{platform:"1",name:"New",code:"NEW",color:"#94A3B8",displayOrder:1}},{entity:"OrderStatus",id:"1002",values:{platform:"1",name:"Paid",code:"PAID",color:"#22C55E",displayOrder:2}},{entity:"OrderStatus",id:"1003",values:{platform:"1",name:"Cancelled",code:"CANCELLED",color:"#EF4444",displayOrder:3}}],ensure:sn});function on(r){const e=Object.fromEntries(Object.entries(r.facets).map(([t,i])=>[t,Array.from(i)]));return{data:Array.from(r),resultCode:0,status:"YES",recordCount:r.totalCountOrLength(),version:"1.001",...Object.keys(e).length?{facets:e}:{},...Object.keys(r.aggregations).length?{aggregations:r.aggregations}:{}}}const Jt=document.querySelector("#status"),xr=document.querySelector("#result"),Dr=document.querySelector("#trace"),Br=document.querySelector("#sql"),Qr=document.querySelector("#evidence-rows"),it=document.querySelector("#persist"),hi=document.querySelector("#logging"),Mt=document.querySelector("#reset"),je=document.querySelector("#query"),ot=document.querySelector("#search"),Xt=document.querySelector("#example"),li=JSON.stringify(JSON.stringify({filter:{orderNumber:{$contains:"KEEP"}}})),$t=`Q.customerOrdersWithMinimalFields() - .filterByJson(${li}) - .countAs("totalOrders") - .facetByStatusAs("statusCounts", Q.orderStatusesWithMinimalFields() - .selectName().selectColor().countAs("orderCount") - .sumTotalAmountOfCustomerOrdersAs("orderTotalAmount", Q.customerOrdersWithMinimalFields()) - .orderByDisplayOrderAscending().comment("load status facets")) - .selectOrderNumber().selectOrderDate() - .selectStatusWith(Q.orderStatusesWithMinimalFields() - .selectName().selectColor().comment("load status")) - .selectOrderItemListWith(Q.orderItemsWithMinimalFields() - .selectProductName().selectQuantity().orderByIdAscending().limit(3).comment("load item previews")) - .countOrderItemsAs("itemCount") - .orderByOrderDateDescending().orderByIdDescending() - .comment("load order list").purpose("render order list page")`;ot.value=$t;let ne;const Zt=globalThis.crossOriginIsolated&&typeof navigator.storage?.getDirectory=="function";it.checked=Zt&&localStorage.getItem("teaql-browser-order-storage")==="opfs";it.disabled=!Zt;Zt||(document.querySelector("#opfs-note").textContent="(not available on this host; memory remains fully browser-local)");async function an(r){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),t=await Fs.open(e,{...ui},{storage:r,databaseName:"teaql-browser-orders.sqlite3"});t.install(nn),t.setDiagnosticSQLLogSink(void 0).setMutationLoggingEnabled(!1);const i=Object.freeze({policyId:"browser-order-seed",version:"1",fingerprint:"sha256:browser-order-seed-v1"}),s=new Jr().insertResource("dataService",t).withMutationPolicyRegistry(new fs(()=>({identity:i,review:(n,o)=>o.operations.length>0?{verdict:"allow"}:{verdict:"deny",code:"EMPTY_GRAPH",message:"empty mutation graph"}}))).withMutationPolicyApprovalProvider(new ps(n=>({policy:n,approvedBy:"browser-demo-owner",approvedAt:new Date})));return t.setUserContext(s),await s.ensureSchema(),await s.ensureSchema(),{client:t,context:s,evidence:new Ts,diagnostics:[]}}async function di({context:r}){if((await de.customerOrdersWithMinimalFields().limit(1).comment("detect existing order demo").purpose("keep mutation seeding idempotent").executeForList(r)).length)return;const t=(await de.platforms().limit(2).comment("load bootstrap platform").purpose("prepare order demo").executeForList(r))[0],i=de.customers().comment("initialize demo customer").purpose("prepare order demo").newEntity(r);i.updateName("North Star Retail").updatePlatform(t.id),await i.auditAs("seed browser order customer").save(r);for(let s=1;s<=4;s++){const n=de.customerOrders().comment("initialize demo order").purpose("prepare order demo").newEntity(r);n.updateCustomer(i.id).updateOrderNumber(s<4?`KEEP-00${s}`:"DROP-004").updateOrderDate(`2026-10-0${s}`).updateTotalAmount(s<4?s*100:900),s===1?n.updateStatusToNew():n.updateStatusToPaid(),await n.auditAs("seed browser order").save(r);for(let o=1;o<=5;o++){const a=de.orderItems().comment("initialize demo item").purpose("prepare item previews").newEntity(r);a.updateCustomerOrder(n.id).updateProductName(`Box ${o}`).updateQuantity(o).updateUnitPrice(20),await a.auditAs("seed browser order item").save(r)}}}async function Pt(r){xr.textContent="",Dr.textContent="",Br.textContent="[]",Qr.replaceChildren(),r.evidence.enableAll(),r.diagnostics.length=0;const e=Xs.parse(ot.value,de);if(typeof e?.executeForPage!="function")throw new Error("The query must contain a generated executable Q request");r.client.setRuntimeTelemetrySink(r.evidence).setQueryLoggingEnabled(hi.checked).setDiagnosticSQLLogSink({write:a=>r.diagnostics.push(a)});const t=await e.executeForPage(r.context,1,1),i=on(t.data),s={resultCode:i.resultCode,status:i.status,version:i.version,recordCount:t.totalCount,data:t.data.map(a=>{const u=Ft.customerOrder(a),h=u.orderItemList().size().eval();if(h==null)throw new Error("Selected item list unexpectedly has a null size");return{id:a.id,version:a.version,orderNumber:u.orderNumber().eval(),orderDate:u.orderDate().eval(),status:{name:u.status().name().eval(),color:u.status().color().eval()},items:Array.from({length:h},(l,d)=>({productName:u.orderItemList().get(d).productName().eval(),quantity:u.orderItemList().get(d).quantity().eval()})),itemCount:a.itemCount}}),metadata:{totalCount:t.totalCount,pageOffset:1,pageSize:1,aggregations:t.data.aggregations,searchWarnings:e.dynamicSearchWarnings??[]},facets:{statusCounts:t.data.facets.statusCounts.map(a=>({id:a.id,name:Ft.orderStatus(V.fromRecord(a)).name().eval(),color:Ft.orderStatus(V.fromRecord(a)).color().eval(),orderCount:a.orderCount,orderTotalAmount:a.orderTotalAmount}))}};xr.textContent=JSON.stringify(s,null,2);const n=r.evidence.snapshot(),o=n.map(a=>{const u=a.traceChain??[],h=u.filter(c=>c.kind==="purpose"),l=h.length===1?`${h[0].detail}: ${u.filter(c=>c.kind==="comment").map(c=>c.detail).join(" → ")}`:"TraceChain unavailable",d=document.createElement("tr");for(const c of[`${a.elapsedMicros} µs`,a.tracePath.find(f=>f.kind==="request")?.name??"—",l,a.debugSQL]){const f=document.createElement("td");f.textContent=c,d.append(f)}return{row:d,businessTrace:l}});Qr.replaceChildren(...o.map(a=>a.row)),Dr.textContent=o.map(a=>a.businessTrace).join(` -`),Br.textContent=JSON.stringify(n,null,2),Jt.textContent=`${r.client.storage.toUpperCase()} · ${t.totalCount} matches · ${n.length} SQL statements · ${r.diagnostics.length} diagnostics · policy installed · ready`}async function ci(r){Jt.textContent=`Opening ${r.toUpperCase()} SQLite/WASM…`;const e=ne;ne=void 0,await e?.client.close();const t=await an(r);ne=t,await di(t),await Pt(t)}function at(r){Jt.textContent=r instanceof Error?`${r.name}: ${r.message}`:String(r)}je.addEventListener("click",async()=>{if(ne){je.disabled=!0;try{await Pt(ne)}catch(r){at(r)}finally{je.disabled=!1}}});document.querySelector("#preset").addEventListener("click",()=>{ot.value=$t,Xt.value="filtered",je.click()});Xt.addEventListener("change",()=>{ot.value=Xt.value==="all"?$t.replace(li,JSON.stringify("{}")):$t,je.click()});ot.addEventListener("keydown",r=>{(r.ctrlKey||r.metaKey)&&r.key==="Enter"&&je.click()});hi.addEventListener("change",()=>{ne&&Pt(ne).catch(at)});it.addEventListener("change",()=>{const r=it.checked?"opfs":"memory";localStorage.setItem("teaql-browser-order-storage",r),ci(r).catch(at)});Mt.addEventListener("click",async()=>{if(ne){Mt.disabled=!0;try{await ne.client.reset(ne.context),await di(ne),await Pt(ne)}catch(r){at(r)}finally{Mt.disabled=!1}}});ci(it.checked?"opfs":"memory").catch(at); diff --git a/dist/assets/index-DTZ5iA72.js b/dist/assets/index-DTZ5iA72.js deleted file mode 100644 index 0f52273536cb7098b6ffb379e828748cfe919c81..0000000000000000000000000000000000000000 --- a/dist/assets/index-DTZ5iA72.js +++ /dev/null @@ -1,31 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const a of n.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&r(a)}).observe(document,{childList:!0,subtree:!0});function t(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(s){if(s.ep)return;s.ep=!0;const n=t(s);fetch(s.href,n)}})();var Zt={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},ei=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],Me=class extends Error{constructor(e){super(`Unsupported locale: ${e}`),this.localeCode=e}},ti={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function et(i){if(typeof i!="string"||!i.trim())throw new Me(i);const e=i.trim().replace(/_/g,"-").toLowerCase(),t=ei.find(s=>s.toLowerCase()===e);if(t)return t;const r=ti[e];if(!r)throw new Me(i);return r}var Ce=class{constructor(e,t){if(this.data=e,this.fallback=t,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(et)}message(e,t){return this.data.locales[e]?.messages[t]??this.fallback?.data.locales[e]?.messages[t]??this.data.locales.en?.messages[t]??this.fallback?.data.locales.en?.messages[t]??t}translate(e,t){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),a=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(t,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(a)),e}};Ce.builtin=new Ce(Zt);var ii=Ce,tt=Symbol("teaql.context.schema-capability"),Ve=new WeakMap,ri=1;function si(i){if(!i||typeof i!="object"&&typeof i!="function")return String(i);const e=i;let t=Ve.get(e);return t||(t=ri++,Ve.set(e,t)),String(t)}var We=class extends Error{constructor(i,e,t){super(`context root ${i}: expected ${e}`),this.reason=i,this.expectedType=e,this.activeRoot=t,this.name="ContextRootError"}},it=class{constructor(){this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(i,e)=>this.getContinuousPageCursor(i,e),put:(i,e,t)=>this.putContinuousPageCursor(i,e,t),observe:(i,e)=>{this.continuousPagePlan=i,this.continuousPageCursorId=e}},this.idSetPaginationRuntime={owner:"",scope:"",get:i=>this.idSetStore().get(i),put:(i,e)=>this.idSetStore().put(i,e),build:(i,e)=>this.singleFlightIdSetBuild(i,e),observe:(i,e)=>{this.idSetPaginationPlan=i,this.idSetPaginationCount=e,this.idSetPaginationCountAccuracy=i==="ID_SET_BUILD"||i==="ID_SET_HIT"?"EXACT":i==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=ii.builtin}setLocaleCode(i){const e=et(i);return this.locale=e,this}setLanguageCode(i){return this.setLocaleCode(i)}installI18nCatalog(i){if(!i)throw new Error("catalog is required");return this.i18nCatalog=i,this}installIdSetPaginationStore(i){if(!i)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",i)}translateCheckResults(i){return i.map(e=>this.i18nCatalog.translate(e,this.locale))}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(i){const e=String(i.sourceLabel||""),t=e.toLowerCase();if(!i.entityType||!i.modelPath||!e||t.includes("authorization")||t.includes("cookie")||t.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const r=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",r),r.push(Object.freeze({...i})),this}finishFixEvidence(){const i=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...i])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(i,e){return this.resources.set(i,e),this}getResource(i){return this.resources.get(i)}removeResource(i){return this.resources.delete(i),this}requireResource(i){const e=this.getResource(i);if(e===void 0)throw new Error(`Required UserContext resource is missing: ${i}`);return e}ensureSchema(){const i=this.requireResource("dataService"),e=i[tt];if(!e)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return e.call(i,this)}withActiveRoot(i){if(!i||!i.entity||i.id===void 0||i.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...i}))}requireActiveRoot(i){const e=this.getResource("activeRoot");if(!e)throw new We("missing",i);if(e.entity!==i)throw new We("type_mismatch",i,e);return e}prepareQuery(i){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const e=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,e?`${e.entity}:${String(e.id)}`:"-",si(this.getResource("dataService"))].join("|"),i.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(i,e){const t=`${i}:${e}`,r=this.continuousPageCursors.get(t);if(r&&r.expiresAt<=Date.now()){this.continuousPageCursors.delete(t);return}return r}putContinuousPageCursor(i,e,t){if(this.continuousPageCursors.size>=4096){const r=[...this.continuousPageCursors.entries()].sort((s,n)=>s[1].expiresAt-n[1].expiresAt)[0];r&&this.continuousPageCursors.delete(r[0])}this.continuousPageCursors.set(`${i}:${e}`,t)}getRetainedIdSet(i){const e=this.retainedIdSets.get(i);if(e&&e.expiresAt<=Date.now()){this.retainedIdSets.delete(i);return}return e}idSetStore(){return this.getResource("idSetPaginationStore")??{get:i=>this.getRetainedIdSet(i),put:(i,e)=>this.putRetainedIdSet(i,e),invalidate:i=>{this.retainedIdSets.delete(i)}}}putRetainedIdSet(i,e){if(e.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const r=()=>[...this.retainedIdSets.values()].reduce((s,n)=>s+n.ids.byteLength,0);for(;this.retainedIdSets.size>=64||r()+e.ids.byteLength>268435456;){const s=[...this.retainedIdSets.entries()].sort((n,a)=>n[1].expiresAt-a[1].expiresAt)[0];if(!s)break;this.retainedIdSets.delete(s[0])}this.retainedIdSets.set(i,e)}async singleFlightIdSetBuild(i,e){const t=this.idSetBuilds.get(i);if(t)return{value:await t,built:!1};const r=e();this.idSetBuilds.set(i,r);try{return{value:await r,built:!0}}finally{this.idSetBuilds.delete(i)}}},ni=class extends Error{constructor(e){super(`Check failed: ${e.map(t=>t.message??`${t.ruleId}:${t.location}`).join("; ")}`),this.violations=e,this.name="CheckException"}};function oi(i,e){const t=i.defaultDomainRoot,r=e.defaultDomainRoot;if(t&&r&&(t.entity!==r.entity||t.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...i.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??t,constants:[...s.values()],ensure:i.ensure&&e.ensure?async n=>{await i.ensure(n),await e.ensure(n)}:e.ensure??i.ensure}}var Ue=class re{constructor(e,t,r){this.field=e,this.expr=t,this.direction=r}static new(e,t){return new re(e,null,t)}static expr(e,t){return new re("",e,t)}static asc(e){return re.new(e,"Asc")}static desc(e){return re.new(e,"Desc")}},Qe=Object.freeze({success:()=>{},failure:()=>{}}),ui=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function ai(i){const e={"teaql.operation.family":i.family,"teaql.operation.name":i.name};for(const[t,r]of Object.entries(i.attributes||{}))ui.has(t)||(e[t]=r);return Object.freeze({...i,attributes:Object.freeze(e)})}function le(i,e){if(!i)return Qe;try{const t=i.start(ai(e));let r=!1;return{run:t.run?s=>t.run(s):s=>s(),success(s){if(!r){r=!0;try{t?.success(s)}catch{}}},failure(s){if(!r){r=!0;try{t?.failure(s)}catch{}}}}}catch{return Qe}}async function ie(i,e,t,r){const s=le(i,e);try{const n=await(s.run?s.run(t):t());return s.success(r?.(n)),n}catch(n){throw s.failure(n),n}}function li(i){const e=new Map;for(const t of Object.values(i))for(const r of Object.values(t.relations||{})){if(!r.many)continue;const s=i[r.targetEntity],n=s?.columns[r.foreignKey]?.columnName,a=s?.columns.id?.columnName;if(!s||!n||!a)continue;const u=`idx_${s.table}_${n}_${a}`;let h=2166136261;for(let c=0;c>>0).toString(36),p=u.length<=30?u:`${u.slice(0,Math.max(1,29-m.length))}_${m}`;e.set(p,{name:p,table:s.table,foreignColumn:n,idColumn:a})}return[...e.values()]}async function ci(i,e,t,r){const s=Number(r);if(!Number.isSafeInteger(s)||s<0)throw new Error(`Invalid ID space floor ${r} for ${t}`);for(let n=1;n<=100;n+=1){const a=await i.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[t]);if(!a.rowCount){try{if((await i.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[t,s])).rowCount===1)return}catch(m){if(!(await i.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[t])).rowCount)throw m}continue}const u=Number(a.rows[0].id);if(u>=s)return;const h=await i.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[s,t,u]);if(h.rowCount===1)return;if(h.rowCount!==0)throw new Error(`ID space floor update for ${t} changed ${h.rowCount} rows on attempt ${n}`)}throw new Error(`Unable to synchronize ID space floor for ${t} after 100 optimistic-lock attempts`)}function hi(i){return i.startsWith('"')&&i.endsWith('"')||i.startsWith("`")&&i.endsWith("`")?i.slice(1,-1).replace(/""/g,'"').replace(/``/g,"`"):i}function di(i,e){return i===e?!0:(i instanceof Date&&(i=i.getTime()),e instanceof Date&&(e=e.getTime()),i!=null&&e!==null&&e!==void 0&&String(i)===String(e))}function Ee(i,e,t){return[{level:0,kind:"operation",name:"mutation"},{level:1,kind:"entity",name:String(i.entity)},{level:2,kind:"provider",name:e},{level:3,kind:"sql",name:t}]}function fi(i,e,t="sqlite"){let r=0,s="",n="sql";for(let a=0;a=0&&p=0&&pt.toString(16).padStart(2,"0")).join("")}'`:V(typeof i=="object"?JSON.stringify(i):String(i))}function V(i){return`'${i.replace(/'/g,"''")}'`}var mi=class{constructor(i=e=>console.debug(e)){this.writer=i}write(i){this.writer(`[TeaQL SQL][${i.operation}][${i.elapsedMicros}us] ${i.resultSummary} -comment=${i.comment??""} purpose=${i.purpose??""} auditReason=${i.auditReason??""} tracePath=${Ke(i.tracePath)} -Parameterized SQL: ${i.parameterizedSQL} params=${Ke(i.parameters)} -Debug SQL: ${i.debugSQL}`)}};function Ke(i){return JSON.stringify(i,(e,t)=>typeof t=="bigint"?t.toString():t)}var pi=class{constructor(i,e){this.driver=i,this.schemas=e,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.auditEvents=[],this.diagnosticSQLLogSink=new mi,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.checkers={},this.userContext=new it,this.bootstrap={},this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve()}install(i){return Object.assign(this.schemas,i.schemas),Object.assign(this.checkers,i.checkers),this.bootstrap=oi(this.bootstrap,i.bootstrap),this}setUserContext(i){return this.userContext=i,this}schema(i){const e=this.schemas[i];if(!e)throw new Error(`Unknown TeaQL entity: ${i}`);return e}toRuntimeMutationRecord(i,e){const t={};for(const[r,s]of Object.entries(e)){const n=i.columns[r]?r:Object.keys(i.columns).find(a=>i.columns[a].modelName===r||i.columns[a].columnName===r);n&&(t[n]=s)}return t}encode(i,e){const t=i?.id??i;if(t!==void 0)return this.driver.encode(t,e)}decodeRow(i,e,t=[]){const r=this.schema(i),s={...e};for(const[n,a]of Object.entries(r.columns)){const u=s[n];u!=null&&(a.decode==="number"&&(s[n]=Number(u)),a.decode==="string"&&(s[n]=String(u)),a.decode==="date"&&u instanceof Date&&(s[n]=u.toISOString()),a.logicalType==="boolean"&&(s[n]=!!u))}for(const n of t)s[n]!==null&&s[n]!==void 0&&(s[n]=Number(s[n]));return s}get auditTrace(){return[...this.auditEvents]}setAuditSink(i){return this.auditSink=i,this}setRuntimeTelemetrySink(i){return this.telemetrySink=i,this}setDiagnosticSQLLogSink(i){return this.diagnosticSQLLogSink=i,this}setQueryLoggingEnabled(i){return this.queryLoggingEnabled=i,this}setMutationLoggingEnabled(i){return this.mutationLoggingEnabled=i,this}setRuntimeTelemetry(i){return this.runtimeTelemetry=i,this}recordSQL(i,e,t,r,s,n,a={}){const u=i==="select";if(u&&!this.queryLoggingEnabled||!u&&!this.mutationLoggingEnabled||!this.telemetrySink&&!this.diagnosticSQLLogSink)return;const h=Object.freeze({operation:i,...a,tracePath:Object.freeze([...a.tracePath??[]]),parameterizedSQL:e,parameters:Object.freeze([...t]),debugSQL:fi(e,t,this.driver.databaseKind),elapsedMicros:Math.max(0,(Date.now()-r)*1e3),resultCount:s,affectedRows:n,resultSummary:s!==void 0?`${s} rows returned`:`${n??0} rows affected`});this.telemetrySink?.record(h),this.diagnosticSQLLogSink?.write(h)}async[tt](i){this.userContext=i,this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const e=this.bootstrapTail;let t;this.bootstrapTail=new Promise(r=>{t=r}),await e;try{if(this.bootstrap.ensure){i.insertResource("bootstrapActor","teaql-generated-bootstrap"),i.insertResource("bootstrapCategory","runtime-bootstrap");try{await this.bootstrap.ensure(i)}finally{i.removeResource("bootstrapActor"),i.removeResource("bootstrapCategory")}}else await this.ensureBootstrapData()}finally{t()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const i=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];i.length&&await this.driver.transaction(async e=>{for(const t of i)await this.reconcileBootstrapEntity(e,t)})}async reconcileBootstrapEntity(i,e){const t=this.schema(e.entity),r=this.driver.identifier(t.table),s=this.driver.identifier(t.columns.id?.columnName??"id"),n=this.driver.identifier(t.columns.version?.columnName??"version"),a=Object.entries(e.values??{}).map(([h,m])=>{const p=t.columns[h];if(!p)throw new Error(`Unknown bootstrap field ${e.entity}.${h}`);return{column:this.driver.identifier(p.columnName),value:this.driver.encode(m,p)}}),u=await i.query(`SELECT * FROM ${r} WHERE ${s} = ${this.driver.placeholder(1)}`,[e.id]);if(u.rowCount){const h=u.rows[0],m=a.filter(p=>!di(h[hi(p.column)],p.value));if(m.length){const p=m.map((c,g)=>`${c.column} = ${this.driver.placeholder(g+1)}`);p.push(`${n} = ${n} + 1`),await i.query(`UPDATE ${r} SET ${p.join(", ")} WHERE ${s} = `+this.driver.placeholder(m.length+1),[...m.map(c=>c.value),e.id])}}else{const h=[s,n,...a.map(c=>c.column)],m=[e.id,1,...a.map(c=>c.value)],p=m.map((c,g)=>this.driver.placeholder(g+1));await i.query(`INSERT INTO ${r} (${h.join(", ")}) VALUES (${p.join(", ")})`,m)}await this.driver.ensureIdFloor(i,e.entity,e.id)}async executeGraphSave(i){const e=this.graphSaveTail;let t;this.graphSaveTail=new Promise(r=>{t=r}),await e,this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence();try{const r=await this.driver.transaction(async s=>{this.graphMutationSession=s;try{return await i()}finally{this.graphMutationSession=void 0}});for(const s of this.graphCommitActions)s();return r}catch(r){for(const s of[...this.graphRollbackActions].reverse())s();throw r}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.removeResource("fixTime").finishFixEvidence(),t()}}afterGraphCommit(i){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(i)}afterGraphRollback(i){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(i)}async withMutationSession(i){return this.graphMutationSession?i(this.graphMutationSession):this.driver.transaction(i)}preflightMutation(i){if(!String(i?.comment||"").trim())throw new Error("Security audit failure: audit reason is required before mutation");i={...i,payload:{...i?.payload??{}}};const e=this.checkers[String(i.entity)];if(!e)return i;const t=[],r=this.userContext.getResource("fixTime")===void 0;r&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(e.checkAndFix(this.userContext,i,t),i.ledgerKey&&i.ledgerRoot)for(const[s,n]of Object.entries(i.payload||{}))i.ledgerRoot.set(i.ledgerKey,s,n);if(this.userContext.translateCheckResults(t),t.length)throw new ni(t);return i}finally{r&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(i){const e=le(this.runtimeTelemetry,{family:"mutation",name:`${String(i?.entity||"unknown")}.${String(i?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(i?.entity||"unknown"),"teaql.mutation.kind":String(i?.action||"unknown").toLowerCase()}});try{i=this.preflightMutation(i);const t=this.schema(i.entity),r=this.toRuntimeMutationRecord(t,i.payload||{}),s=this.driver.identifier(t.table),n=await ie(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(i.action).toLowerCase()}},()=>this.withMutationSession(async u=>{if(i.action==="Create"){const h=i.id?String(i.id):await this.driver.nextId(u,i.entity);i.id&&await this.driver.ensureIdFloor(u,i.entity,h);const m=Number(i.version||0)+1,p={...r,id:h,version:m},c=Object.keys(t.columns).filter(q=>p[q]!==void 0),g=c.map(q=>this.driver.identifier(t.columns[q].columnName)).join(", "),w=c.map((q,P)=>this.driver.placeholder(P+1)).join(", "),C=c.map(q=>this.encode(p[q],t.columns[q])),A=`INSERT INTO ${s} (${g}) VALUES (${w})`,I=Date.now(),x=await u.query(A,C);return this.recordSQL("insert",A,C,I,void 0,x.rowCount,{auditReason:String(i.comment),tracePath:Ee(i,this.driver.databaseKind,"insert")}),{success:!0,id:h,version:m,persistedRecord:await this.readPersistedRecord(u,t,h)}}if(i.action==="Update"){const h=Object.keys(t.columns).filter(x=>x!=="id"&&x!=="version"&&r[x]!==void 0),m=h.map(x=>this.encode(r[x],t.columns[x])),p=h.map((x,q)=>`${this.driver.identifier(t.columns[x].columnName)} = `+this.driver.placeholder(q+1)),c=this.driver.identifier("version");p.push(`${c} = ${c} + 1`),m.push(String(i.id));const g=[`${this.driver.identifier("id")} = ${this.driver.placeholder(m.length)}`];i.version!==void 0&&i.version!==null&&(m.push(Number(i.version)),g.push(`${c} = ${this.driver.placeholder(m.length)}`));const w=`UPDATE ${s} SET ${p.join(", ")} WHERE ${g.join(" AND ")}`,C=Date.now(),A=await u.query(w,m);if(this.recordSQL("update",w,m,C,void 0,A.rowCount,{auditReason:String(i.comment),tracePath:Ee(i,this.driver.databaseKind,"update")}),A.rowCount!==1)throw new Error(`Optimistic lock failed or ${i.entity}(${i.id}) does not exist`);const I=await this.readPersistedRecord(u,t,String(i.id));return{success:!0,id:String(i.id),version:Number(I.version),persistedRecord:I}}if(i.action==="Delete"){const h=this.driver.identifier("version"),m=[String(i.id)],p=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];i.version!==void 0&&i.version!==null&&(m.push(Number(i.version)),p.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(m.length)));const c=`UPDATE ${s} SET ${h} = -(${h} + 1) WHERE ${p.join(" AND ")}`,g=Date.now(),w=await u.query(c,m);if(this.recordSQL("delete",c,m,g,void 0,w.rowCount,{auditReason:String(i.comment),tracePath:Ee(i,this.driver.databaseKind,"delete")}),w.rowCount!==1)throw new Error(`Optimistic lock failed or ${i.entity}(${i.id}) does not exist`);const C=await this.readPersistedRecord(u,t,String(i.id));return{success:!0,id:String(i.id),version:Number(C.version),deleted:!0,persistedRecord:C}}throw new Error(`Unsupported mutation action: ${i.action}`)})),a=Object.freeze({entity:i.entity,action:i.action,id:String(n.id),reason:String(i.comment),recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.keys(i.payload||{}).sort(),version:n.version});return this.auditEvents.push(a),this.auditSink&&await ie(this.runtimeTelemetry,{family:"audit",name:`${i.entity}.audit`,attributes:{"teaql.entity.type":String(i.entity),"teaql.mutation.kind":String(i.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(i.payload||{}).length}},async()=>this.auditSink(a)),e.success(),n}catch(t){throw e.failure(t),t}}async readPersistedRecord(i,e,t){const r=Object.entries(e.columns).map(([n,a])=>`${this.driver.identifier(a.columnName)} AS ${this.driver.identifier(n)}`).join(", "),s=await i.query(`SELECT ${r} FROM ${this.driver.identifier(e.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,[t]);if(s.rowCount!==1)throw new Error(`Persisted ${e.table}(${t}) could not be read back`);return this.decodeRowForSchema(e,s.rows[0])}decodeRowForSchema(i,e){const t={...e};for(const[r,s]of Object.entries(i.columns)){const n=t[r];n!=null&&(s.decode==="number"&&(t[r]=Number(n)),s.decode==="string"&&(t[r]=String(n)),s.decode==="date"&&n instanceof Date&&(t[r]=n.toISOString()),s.logicalType==="boolean"&&(t[r]=!!n))}return t}compileExpression(i,e,t){if(Array.isArray(i?.$and))return`(${i.$and.map(n=>this.compileExpression(n,e,t)).join(" AND ")})`;const r=Object.entries(i||{}).map(([s,n])=>{const a=e.columns[s];if(!a)throw new Error(`Unknown field ${s} for SQL query`);const u=this.driver.identifier(a.columnName);if(n?.$eq!==void 0){const h=n.$eq?.id??n.$eq;return h===null?`${u} IS NULL`:(t.push(this.encode(h,a)),`${u} = ${this.driver.placeholder(t.length)}`)}if(n?.$ne!==void 0){const h=n.$ne?.id??n.$ne;return h===null?`${u} IS NOT NULL`:(t.push(this.encode(h,a)),`${u} <> ${this.driver.placeholder(t.length)}`)}if(n?.$soundLike!==void 0)return t.push(String(n.$soundLike)),`SOUNDEX(${u}) = SOUNDEX(${this.driver.placeholder(t.length)})`;if(n?.$contains!==void 0)return t.push(String(n.$contains)),this.driver.contains(u,this.driver.placeholder(t.length));if(n?.$notContains!==void 0)return t.push(String(n.$notContains)),`NOT (${this.driver.contains(u,this.driver.placeholder(t.length))})`;for(const[h,m,p,c]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(n?.[h]!==void 0){t.push(`${m}${String(n[h])}${p}`);const g=`${u} LIKE ${this.driver.placeholder(t.length)}`;return c?`NOT (${g})`:g}if(Array.isArray(n?.$in)){if(!n.$in.length)return"FALSE";const h=n.$in.map(m=>(t.push(this.encode(m?.id??m,a)),this.driver.placeholder(t.length)));return`${u} IN (${h.join(", ")})`}if(Array.isArray(n?.$notIn)){if(!n.$notIn.length)return"TRUE";const h=n.$notIn.map(m=>(t.push(this.encode(m?.id??m,a)),this.driver.placeholder(t.length)));return`${u} NOT IN (${h.join(", ")})`}for(const[h,m]of[["$inSubquery",!1],["$notInSubquery",!0]]){const p=n?.[h];if(p!==void 0){const c=p.query,g=this.schema(c?.entity),w=String(p.field),C=g.columns[w];if(!C)throw new Error(`Unknown subquery projection ${w} for ${c?.entity}`);const A=this.filters(c).map(q=>this.compileExpression(q,g,t));g.columns.version&&A.push(`${this.driver.identifier(g.columns.version.columnName)} > 0`),m&&A.push(`${this.driver.identifier(C.columnName)} IS NOT NULL`);const I=A.length?` WHERE ${A.join(" AND ")}`:"",x=`SELECT ${this.driver.identifier(C.columnName)} FROM ${this.driver.identifier(g.table)}${I}`;return`${u} ${m?"NOT IN":"IN"} (${x})`}}if(Array.isArray(n?.$between)&&n.$between.length===2){t.push(this.encode(n.$between[0],a));const h=this.driver.placeholder(t.length);t.push(this.encode(n.$between[1],a));const m=this.driver.placeholder(t.length);return`${u} BETWEEN ${h} AND ${m}`}if(n?.$isNull===!0)return`${u} IS NULL`;if(n?.$isNull===!1)return`${u} IS NOT NULL`;if(n?.$gte!==void 0)return t.push(this.encode(n.$gte,a)),`${u} >= ${this.driver.placeholder(t.length)}`;if(n?.$lte!==void 0)return t.push(this.encode(n.$lte,a)),`${u} <= ${this.driver.placeholder(t.length)}`;if(n?.$gt!==void 0)return t.push(this.encode(n.$gt,a)),`${u} > ${this.driver.placeholder(t.length)}`;if(n?.$lt!==void 0)return t.push(this.encode(n.$lt,a)),`${u} < ${this.driver.placeholder(t.length)}`;throw new Error(`Unsupported query predicate for ${s}: ${JSON.stringify(n)}`)});return r.length?`(${r.join(" AND ")})`:"TRUE"}filters(i){return Array.isArray(i._filters)&&i._filters.length?i._filters:i.filterCondition?[i.filterCondition]:[]}groupBy(i){return i._groupBy||i.groupByItems||[]}aggregates(i){return Array.isArray(i._aggregates)?i._aggregates:(i.aggregateItems||[]).map(e=>({func:e.function,field:e.field,retName:e.alias}))}orders(i){return Array.isArray(i._orderBy)?i._orderBy.map(e=>({field:e.f,direction:e.d})):(i.orderItems||[]).map(e=>({field:e.field,direction:e.direction}))}async compileQuery(i){const e=i?.[this.internalQueryToken]===!0,t=i?._purpose??i?.purposeText,r=i?._comment??i?.commentText;if(!e&&(!String(t||"").trim()||!String(r||"").trim()))throw new Error("Security audit failure: purpose and comment are required before query execution");const s=this.schema(i.entity),n=[],a=this.groupBy(i),u=a.map(_=>{if(!s.columns[_])throw new Error(`Unknown group field: ${_}`);return this.driver.identifier(s.columns[_].columnName)}),h=a.map(_=>`${this.driver.identifier(s.columns[_].columnName)} AS `+this.driver.identifier(_)),m=[],p=Array.isArray(i.selectItems)&&i.selectItems.length?[...new Set(["id","version",...i.selectItems])]:Object.keys(s.columns);for(const _ of p)if(!s.columns[_])throw new Error(`Unknown selected field: ${_}`);let c=p.map(_=>{const L=s.columns[_];return`${this.driver.identifier(L.columnName)} AS ${this.driver.identifier(_)}`}).join(", ");const g=this.aggregates(i);if(g.length){const _=g.map(L=>{if(!s.columns[L.field])throw new Error(`Unknown aggregate field: ${L.field}`);return m.push(L.retName),`${this.driver.aggregateFunction(L.func)}(${this.driver.identifier(s.columns[L.field].columnName)}) AS `+this.driver.identifier(L.retName)});c=[...h,..._].join(", ")}const w=i.__teaqlPartitionBy,C=this.orders(i),A=C.map(_=>{if(!s.columns[_.field])throw new Error(`Unknown order field: ${_.field}`);const L=String(_.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(s.columns[_.field].columnName)} ${L}`});if(w){const _=s.columns[w];if(!_)throw new Error(`Unknown partition field: ${w}`);const L=A.length?` ORDER BY ${A.join(", ")}`:"";c+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier(_.columnName)}${L}) AS `+this.driver.identifier("__teaql_partition_rank")}let I=`SELECT ${c} FROM ${this.driver.identifier(s.table)}`;const q=this.filters(i).map(_=>this.compileExpression(_,s,n));s.columns.version&&q.push(`${this.driver.identifier(s.columns.version.columnName)} > 0`),q.length&&(I+=` WHERE ${q.join(" AND ")}`),u.length&&(I+=` GROUP BY ${u.join(", ")}`);const P=i._limit!==void 0?Number(i._limit):Number(i.limitValue||0),z=i._offset!==void 0?Number(i._offset):Number(i.offsetValue||0);if(w){const _=this.driver.identifier("__teaql_partition_rank"),L=[];n.push(z),L.push(`${_} > ${this.driver.placeholder(n.length)}`),P>0&&(n.push(z+P),L.push(`${_} <= ${this.driver.placeholder(n.length)}`)),I=`SELECT * FROM (${I}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${L.join(" AND ")} ORDER BY ${_}`}else C.length&&(I+=` ORDER BY ${A.join(", ")}`);return!w&&P>0&&(n.push(P),I+=` LIMIT ${this.driver.placeholder(n.length)}`),!w&&z>0&&(n.push(z),I+=` OFFSET ${this.driver.placeholder(n.length)}`),this.sqlTrace.push(I),{sql:I,values:n,aggregateNames:m}}async executeQuery(i){const e=le(this.runtimeTelemetry,{family:"query",name:`${String(i?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(i?.entity||"unknown")}});try{const t=i?.[this.internalQueryToken]===!0;if(!t){if(typeof i?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");i.prepareForList()}const r=t?{query:i,execution:void 0}:await this.prepareIdSetPage(i),s=t?r:await this.prepareContinuousPage(r.query);i=s.query;const{sql:n,values:a,aggregateNames:u}=await this.compileQuery(i),h=Date.now(),m=await ie(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.query`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}},()=>this.driver.query(n,a)),p=i?._comment??i?.commentText,c=i?._purpose??i?.purposeText,g=Array.isArray(i?.__teaqlTracePath)?i.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(i.entity)}],w=[...g,{level:g.length,kind:"provider",name:this.driver.databaseKind},{level:g.length+1,kind:"sql",name:"select"}];this.recordSQL("select",n,a,h,m.rowCount,void 0,{comment:p,purpose:c,tracePath:w});const C=m.rows.map(A=>this.decodeRow(i.entity,A,u));if(r.execution?.pageIds){const A=new Map(r.execution.pageIds.map((I,x)=>[String(I),x]));C.sort((I,x)=>(A.get(String(I.id))??Number.MAX_SAFE_INTEGER)-(A.get(String(x.id))??Number.MAX_SAFE_INTEGER))}return await this.enhanceRelations(C,i),await this.enhanceRelationAggregates(C,i),t||await this.registerContinuousPage(i,s.execution,C),e.success({attributes:{"teaql.result.cardinality":C.length}}),C}catch(t){throw e.failure(t),t}}async prepareIdSetPage(i){const e=i.localIdSetPaginationOptions?.(),t=i.localIdSetPaginationRuntime?.();if(!e||!t)return t?.observe("ID_SET_DISABLED"),{query:i};const r=this.queryLimit(i);if(!r||i.localContinuousPageOptions?.()||this.aggregates(i).length||this.groupBy(i).length||i.__teaqlPartitionBy)return t.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:i};if((i.orderItems||[]).some(w=>w.expr!=null))return t.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:i};this.orders(i).some(w=>w.field==="id")||(i=i.clone().order(Ue.asc("id")));const s=i.clone();s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.relations=[],s.commentText=void 0,s.purposeText=void 0,s.clearIdSetPaginationRuntime(),s.clearContinuousPageRuntime();const n=`${e.namespace}|${t.scope}|${JSON.stringify(s)}`;let a=2166136261;for(let w=0;w>>0).toString(16)}`;let h,m=!1;try{h=t.get(u)}catch{return t.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:i}}if(h)m=!0,t.observe("ID_SET_HIT",h.ids.length);else{let w;try{w=await t.build(u,async()=>{const C=t.get(u);if(C)return C;const A=i.clone();A.selectItems=["id"],A.relations=[],A.relationAggregates=[],A.facets=[],A.offsetValue=0,A.limitValue=e.maxIds+1,A.clearIdSetPaginationRuntime(),A.clearContinuousPageRuntime(),A[this.internalQueryToken]=!0;const I=await this.executeQuery(A);if(I.length>e.maxIds)return;let x;try{x=BigUint64Array.from(I.map(P=>BigInt(P.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const q={ids:x,expiresAt:Date.now()+e.ttlSeconds*1e3};return t.put(u,q),q})}catch(C){return t.observe(C instanceof Error&&C.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:i}}if(h=w.value,!h)return t.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",e.maxIds+1),{query:i};m=!w.built,t.observe(m?"ID_SET_HIT":"ID_SET_BUILD",h.ids.length)}const p=Number(i.offsetValue||i._offset||0),c=Array.from(h.ids.slice(p,p+r)),g=i.clone();return g.offsetValue=0,g.limitValue=Math.max(c.length,1),g.filterCondition=g.filterCondition?{$and:[g.filterCondition,{id:{$in:c}}]}:{id:{$in:c}},g.clearIdSetPaginationRuntime(),t.observe(m?"ID_SET_HIT":"ID_SET_BUILD",h.ids.length),{query:g,execution:{pageIds:c,totalCount:h.ids.length}}}async executeFacetMembership(i,e){const t=i.clone();t.facets=[],t.relations=[],t.orderItems=[],t.offsetValue=0,t.limitValue=0,t.selectItems=[],t.groupByItems=[e],t.aggregateItems=[{function:"Count",field:"id",alias:"__teaql_facet_count"}],t[this.internalQueryToken]=!0;const r=await this.executeQuery(t);return new Map(r.flatMap(s=>{const n=s[e],a=Number(s.__teaql_facet_count??0);return n==null?[]:[[String(n),a]]}))}async executeCount(i){if(typeof i?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const e="__teaql_total",r=(await this.executeQuery(i.forExactCount(e)))[0]?.[e];if(typeof r!="number"||!Number.isFinite(r))throw new Error(`TeaQL provider did not return exact count alias ${e}`);return r}async prepareContinuousPage(i){const e=i.localContinuousPageOptions?.(),t=i.localContinuousPageRuntime?.();if(!e||!t)return t?.observe("DISABLED"),{query:i};const r=this.orders(i),s=this.queryLimit(i);if(!s||r.length!==1||r[0].field!=="id"||this.aggregates(i).length||this.groupBy(i).length||i.__teaqlPartitionBy)return t.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:i};const n=Object.assign(Object.create(Object.getPrototypeOf(i)),i);n.orderItems=[...i.orderItems||[]],n.relations=[...i.relations||[]],Object.defineProperty(n,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:e}),Object.defineProperty(n,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:t});const a=Number(i.offsetValue||i._offset||0),u={...JSON.parse(JSON.stringify(n)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},h=`${e.namespace}|${t.owner}|${JSON.stringify(u)}`;let m=2166136261;for(let C=0;C>>0).toString(16)}`,c={queryKey:p,offset:a,limit:s,direction:String(r[0].direction).toLowerCase(),ttlSeconds:e.ttlSeconds,runtime:t,optimized:!1};if(a===0)return t.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:n,execution:c};let g;try{g=await ie(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>t.get(p,a))}catch{return t.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:n,execution:c}}if(!g)return t.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:n,execution:c};const w={id:{[c.direction==="desc"?"$lt":"$gt"]:g.boundary}};return n.filterCondition=n.filterCondition?{$and:[n.filterCondition,w]}:w,n.offsetValue=0,n._offset!==void 0&&(n._offset=0),c.optimized=!0,c.cursorId=g.cursorId,t.observe("CURSOR_SEEK",g.cursorId),{query:n,execution:c}}async registerContinuousPage(i,e,t){if(!(!e||t.length!==e.limit||!t.length||t[t.length-1].id===void 0)){try{await ie(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>e.runtime.put(e.queryKey,e.offset+t.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:t[t.length-1].id,expiresAt:Date.now()+e.ttlSeconds*1e3}))}catch{e.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}e.optimized&&e.runtime.observe("CURSOR_SEEK",e.cursorId)}}async*executeForStream(i,e=1e3){if(!Number.isInteger(e)||e<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(i.facets)&&i.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:t,values:r,aggregateNames:s}=await this.compileQuery(i);let n=[];for await(const a of this.driver.stream(t,r))n.push(this.decodeRow(i.entity,a,s)),n.length===e&&(await this.enhanceRelations(n,i),yield n,n=[]);n.length&&(await this.enhanceRelations(n,i),yield n)}async enhanceRelations(i,e){if(!i.length||!Array.isArray(e.relations)||!e.relations.length)return;const t=this.schema(e.entity);for(const r of e.relations){const s=t.relations?.[r.name];if(!s)throw new Error(`Missing relation ${e.entity}.${r.name}`);const n=i.map(w=>w[s.localKey]).filter(w=>w!=null),a=r.query?this.queryLimit(r.query):void 0,u=r.query?.localTopNProbeParentThreshold?.(),h=s.many&&a!==void 0,m=this.driver.topNRelationPlanPolicy==="alwaysProbe",p=h&&(u===void 0?m:u>0&&n.length<=u),c=p?"bounded_probes":"window",g=le(this.runtimeTelemetry,{family:"relation_load",name:`${e.entity}.${String(r.name)}`,attributes:{"teaql.entity.type":String(e.entity),"teaql.relation.name":String(r.name),"teaql.relation.parent_count":n.length,"teaql.relation.per_parent_limit":a??0,"teaql.relation.configured_probe_threshold":u??"provider-default","teaql.relation.selected_plan":c,"teaql.relation.probe_count":p?n.length:0}});try{if(!n.length){for(const I of i)I[r.name]=s.many?[]:null;g.success({attributes:{"teaql.result.cardinality":0}});continue}const w={...r.query||{},entity:s.targetEntity,_filters:[...this.filters(r.query||{})],relations:[...r.query?.relations||[]],orderItems:[...r.query?.orderItems||[]],__teaqlPartitionBy:h&&!p?s.foreignKey:void 0,__teaqlTracePath:[...Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(e.entity)}],{level:Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath.length:2,kind:"relation",name:`${String(e.entity)}.${String(r.name)}`}],commentText:e?._comment??e?.commentText,purposeText:e?._purpose??e?.purposeText};h&&!w.orderItems.some(I=>I.field==="id")&&w.orderItems.push(Ue.asc("id")),typeof w.clearContinuousPageRuntime=="function"&&w.clearContinuousPageRuntime(),w[this.internalQueryToken]=!0;const C=[];if(p)for(const I of n){const x={...w,_filters:[...w._filters,{[s.foreignKey]:{$eq:I}}],__teaqlPartitionBy:void 0};C.push(...await this.executeQuery(x))}else w._filters.push({[s.foreignKey]:{$in:n}}),C.push(...await this.executeQuery(w));for(const I of C)delete I.__teaql_partition_rank;const A=new Map;for(const I of C){const x=I[s.foreignKey],q=A.get(x)||[];q.push(I),A.set(x,q)}for(const I of i){const x=A.get(I[s.localKey])||[];I[r.name]=s.many?x:x[0]??null}g.success({attributes:{"teaql.result.cardinality":C.length}})}catch(w){throw g.failure(w),w}}}async enhanceRelationAggregates(i,e){const t=e.relationAggregates;if(!i.length||!Array.isArray(t)||!t.length)return;const r=this.schema(e.entity);for(const s of t){const n=r.relations?.[s.relationName];if(!n)throw new Error(`Missing relation ${e.entity}.${s.relationName}`);const a=i.map(p=>p[n.localKey]).filter(p=>p!=null);if(!a.length){for(const p of i)p[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{};continue}const u=s.query.clone();u.entity=n.targetEntity,u.selectItems=[],u.properties=[],u.orderItems=[],u.limitValue=0,u.offsetValue=0,u.relations=[],u.relationAggregates=[],u.aggregateItems.length||u.aggregate("Count","id",s.alias),u.groupByItems.includes(n.foreignKey)||u.groupBy(n.foreignKey),u.filterCondition={...u.filterCondition||{},[n.foreignKey]:{$in:a}},u[this.internalQueryToken]=!0;const h=await this.executeQuery(u),m=new Map;for(const p of h)m.set(p[n.foreignKey],p);for(const p of i){const c=m.get(p[n.localKey]);c?s.singleResult?p[s.alias]=c[u.aggregateItems[0].alias]??null:p[s.alias]=Object.fromEntries(Object.entries(c).filter(([g])=>g!==n.foreignKey)):p[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{}}}}emptyAggregateValue(i){const e=i.aggregateItems[0];return!e||String(e.function).toLowerCase()==="count"?0:null}queryLimit(i){if(i._limit!==void 0)return Number(i._limit);if(i.limitValue!==void 0&&Number(i.limitValue)>0)return Number(i.limitValue)}async close(){await this.driver.close()}};function gi(i){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i))throw new Error(`Unsafe SQL identifier: ${i}`);return i}function Ei(i){const t={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(i).toLowerCase()];if(!t)throw new Error(`Unsupported aggregate: ${i}`);return t}var yi=class{constructor(i){this.worker=i,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=e=>{const t=e.data;if(!t||t.type!=="teaql-browser-sqlite-response")return;const r=this.pending.get(t.requestId);if(r)if(this.pending.delete(t.requestId),t.error){const s=new Error(t.error.message);s.name=t.error.name,t.error.code&&(s.code=t.error.code),r.reject(s)}else r.resolve(t.result)},this.onError=e=>{const t=new Error(e.message||"Browser SQLite worker failed");t.name="BrowserSQLiteWorkerError";for(const r of this.pending.values())r.reject(t);this.pending.clear()},i.addEventListener("message",this.onMessage),i.addEventListener("error",this.onError)}request(i,e){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const t=this.nextRequestId++;return new Promise((r,s)=>{this.pending.set(t,{resolve:n=>r(n),reject:s}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:t,operation:i,payload:e})})}async close(i){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),i&&this.worker.terminate?.();const e=new Error("Browser SQLite worker is closed");for(const t of this.pending.values())t.reject(e);this.pending.clear()}}},wi=class{constructor(i){this.transport=i}query(i,e=[]){return this.transport.request("query",{sql:i,values:e})}},Ci=class rt{constructor(e,t){this.transport=e,this.options=t,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,t={}){const r={storage:t.storage??"memory",databaseName:$i(t.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:t.terminateWorkerOnClose??!0},s=new yi(e);return await s.request("open",r),new rt(s,r)}identifier(e){return`"${gi(e)}"`}placeholder(e){return"?"}contains(e,t){return`CAST(${e} AS TEXT) LIKE '%' || ${t} || '%'`}aggregateFunction(e){return Ei(e)}encode(e,t){return e==null?e:t?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):t?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const t=this.accessTail;let r;this.accessTail=new Promise(s=>{r=s}),await t;try{return await e()}finally{r()}}query(e,t=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:t}))}async*stream(e,t=[]){const r=await this.query(e,t);for(const s of r.rows)yield s}transaction(e){return this.exclusive(async()=>{const t=new wi(this.transport);await t.query("BEGIN IMMEDIATE");try{const r=await e(t);return await t.query("COMMIT"),r}catch(r){try{await t.query("ROLLBACK")}catch{}throw r}})}async ensureSchema(e){for(const t of Object.values(e)){const r=this.identifier(t.table);await this.query(`CREATE TABLE IF NOT EXISTS ${r} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const s=await this.query(`PRAGMA table_info(${r})`),n=new Set(s.rows.map(a=>String(a.name)));for(const[a,u]of Object.entries(t.columns))a==="id"||a==="version"||n.has(u.columnName)||await this.query(`ALTER TABLE ${r} ADD COLUMN ${this.identifier(u.columnName)} ${vi(u.logicalType)}${u.nullable===!1?" NOT NULL":""}`)}for(const t of li(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(t.name)} ON ${this.identifier(t.table)} (${this.identifier(t.foreignColumn)}, ${this.identifier(t.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,t){for(let r=1;r<=100;r+=1){const s=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t]);if(!s.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[t])).rowCount===1)return"1"}catch(h){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[t])).rowCount)throw h}continue}const n=Number(s.rows[0].id),a=n+1,u=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[a,t,n]);if(u.rowCount===1)return String(a);if(u.rowCount!==0)throw new Error(`ID space update for ${t} changed ${u.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${t} after 100 optimistic-lock attempts`)}ensureIdFloor(e,t,r){return ci(e,s=>this.placeholder(s),t,r)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}},bi=class st extends pi{constructor(e,t){super(e,t),this.browserDriver=e}static async open(e,t,r={}){return new st(await Ci.open(e,r),t)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}};function vi(i){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[i]}function $i(i){const e=i.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}var Si="1.001",Ii=class X{constructor(e={}){this.data=Array.from(e.data??[]),this.resultCode=e.resultCode??0,this.status=e.status??"YES",this.message=e.message,this.recordCount=e.recordCount??this.data.length,this.facets=e.facets,this.version=e.version??Si,this.traceId=e.traceId}static success(){return new X}static fail(e){return new X({resultCode:1,status:"NO",message:e})}static ofSingle(e){return new X({data:[e]})}static ofList(e){return new X({data:e})}static fromSmartList(e){const t=Object.fromEntries(Object.entries(e.facets).map(([r,s])=>[r,Array.from(s)]));return new X({data:e,recordCount:e.totalCountOrLength(),facets:Object.keys(t).length?t:void 0})}withTraceId(e){return this.traceId=e,this}},ze=class extends SyntaxError{constructor(i,e,t,r){super(i),this.expected=e,this.found=t,this.location=r,this.name="SyntaxError"}format(i){let e="Error: "+this.message;if(this.location){let t=null;const r=i.find(u=>u.source===this.location.source);r&&(t=r.text.split(/\r\n|\n|\r/g));const s=this.location.start,n=this.location.source&&typeof this.location.source.offset=="function"?this.location.source.offset(s):s,a=this.location.source+":"+n.line+":"+n.column;if(t){const u=this.location.end,h="".padEnd(n.line.toString().length," "),m=t[s.line-1],c=(s.line===u.line?u.column:m.length+1)-s.column||1;e+=` - --> `+a+` -`+h+` | -`+n.line+" | "+m+` -`+h+" | "+"".padEnd(s.column-1," ")+"".padEnd(c,"^")}else e+=` - at `+a}return e}static buildMessage(i,e){function t(c){return c.codePointAt(0).toString(16).toUpperCase()}const r=Object.prototype.hasOwnProperty.call(RegExp.prototype,"unicode")?new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]","gu"):null;function s(c){return r?c.replace(r,g=>"\\u{"+t(g)+"}"):c}function n(c){return s(c.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,g=>"\\x0"+t(g)).replace(/[\x10-\x1F\x7F-\x9F]/g,g=>"\\x"+t(g)))}function a(c){return s(c.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,g=>"\\x0"+t(g)).replace(/[\x10-\x1F\x7F-\x9F]/g,g=>"\\x"+t(g)))}const u={literal(c){return'"'+n(c.text)+'"'},class(c){const g=c.parts.map(w=>Array.isArray(w)?a(w[0])+"-"+a(w[1]):a(w));return"["+(c.inverted?"^":"")+g.join("")+"]"+(c.unicode?"u":"")},any(){return"any character"},end(){return"end of input"},other(c){return c.description}};function h(c){return u[c.type](c)}function m(c){const g=c.map(h);if(g.sort(),g.length>0){let w=1;for(let C=1;Cy[3])]}function Rt(l){return l||[]}function Dt(l){return JSON.parse(l)}function Gi(l){return l}function Nt(l){return l.join("")}function Pt(l){return Number(l)}function Ot(){return!0}function jt(){return!1}function Mt(){return null}function Hi(l){return l}let o=e.peg$currPos|0;const H=[{line:1,column:1}];let O=o,ae=e.peg$maxFailExpected||[],v=e.peg$silentFails|0,ee;if(e.startRule){if(!(e.startRule in s))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=s[e.startRule]}function Vt(l=o){const d=i.codePointAt(l);return d===void 0?"":String.fromCodePoint(d)}function R(l,d){return{type:"literal",text:l,ignoreCase:d}}function Q(l,d,y,f){return{type:"class",parts:l,inverted:d,ignoreCase:y,unicode:f}}function Wt(){return{type:"any"}}function Ut(){return{type:"end"}}function Be(l){let d=H[l],y;if(d)return d;if(l>=H.length)y=H.length-1;else for(y=l;!H[--y];);for(d=H[y],d={line:d.line,column:d.column};yO&&(O=o,ae=[]),ae.push(l))}function Qt(l,d,y){return new ze(ze.buildMessage(l,d),l,d,y)}function Re(){let l,d;return l=o,T(),d=De(),d!==t?(T(),i.charCodeAt(o)===59?o++:v===0&&$(wt),T(),l=d):(o=l,l=t),l}function De(){let l,d,y,f,b,E,S,k;if(l=o,d=Oe(),d!==t){if(y=[],f=o,b=T(),i.charCodeAt(o)===46?(E=a,o++):(E=t,v===0&&$(me)),E!==t?(S=T(),k=Ne(),k!==t?(b=[b,E,S,k],f=b):(o=f,f=t)):(o=f,f=t),f!==t)for(;f!==t;)y.push(f),f=o,b=T(),i.charCodeAt(o)===46?(E=a,o++):(E=t,v===0&&$(me)),E!==t?(S=T(),k=Ne(),k!==t?(b=[b,E,S,k],f=b):(o=f,f=t)):(o=f,f=t);else y=t;y!==t?l=Tt(d,y):(o=l,l=t)}else o=l,l=t;return l}function Ne(){let l,d,y,f,b;return l=o,d=Oe(),d!==t?(T(),i.charCodeAt(o)===40?(y=u,o++):(y=t,v===0&&$(Ct)),y!==t?(T(),f=Pe(),f===t&&(f=null),T(),i.charCodeAt(o)===41?(b=h,o++):(b=t,v===0&&$(bt)),b!==t?l=Bt(d,f):(o=l,l=t)):(o=l,l=t)):(o=l,l=t),l}function Pe(){let l,d,y,f,b,E,S,k;if(l=o,d=pe(),d!==t){for(y=[],f=o,b=T(),i.charCodeAt(o)===44?(E=m,o++):(E=t,v===0&&$(_e)),E!==t?(S=T(),k=pe(),k!==t?(b=[b,E,S,k],f=b):(o=f,f=t)):(o=f,f=t);f!==t;)y.push(f),f=o,b=T(),i.charCodeAt(o)===44?(E=m,o++):(E=t,v===0&&$(_e)),E!==t?(S=T(),k=pe(),k!==t?(b=[b,E,S,k],f=b):(o=f,f=t)):(o=f,f=t);l=Ft(d,y)}else o=l,l=t;return l}function pe(){let l;return l=De(),l===t&&(l=Kt(),l===t&&(l=zt(),l===t&&(l=Gt(),l===t&&(l=Ht(),l===t&&(l=Xt(),l===t&&(l=Yt())))))),l}function Kt(){let l,d,y,f;return l=o,i.charCodeAt(o)===91?(d=p,o++):(d=t,v===0&&$(vt)),d!==t?(T(),y=Pe(),y===t&&(y=null),T(),i.charCodeAt(o)===93?(f=c,o++):(f=t,v===0&&$($t)),f!==t?l=Rt(y):(o=l,l=t)):(o=l,l=t),l}function zt(){let l,d,y,f,b,E,S,k;if(l=o,d=o,y=o,i.charCodeAt(o)===34?(f=g,o++):(f=t,v===0&&$(ke)),f!==t){for(b=[],E=o,i.charCodeAt(o)===92?(S=w,o++):(S=t,v===0&&$(oe)),S!==t?(i.length>o?(k=i.charAt(o),o++):(k=t,v===0&&$(ue)),k!==t?(S=[S,k],E=S):(o=E,E=t)):(o=E,E=t),E===t&&(E=i.charAt(o),P.test(E)?o++:(E=t,v===0&&$(xe)));E!==t;)b.push(E),E=o,i.charCodeAt(o)===92?(S=w,o++):(S=t,v===0&&$(oe)),S!==t?(i.length>o?(k=i.charAt(o),o++):(k=t,v===0&&$(ue)),k!==t?(S=[S,k],E=S):(o=E,E=t)):(o=E,E=t),E===t&&(E=i.charAt(o),P.test(E)?o++:(E=t,v===0&&$(xe)));i.charCodeAt(o)===34?(E=g,o++):(E=t,v===0&&$(ke)),E!==t?(f=[f,b,E],y=f):(o=y,y=t)}else o=y,y=t;return y!==t?d=i.substring(d,o):d=y,d!==t&&(d=Dt(d)),l=d,l}function Gt(){let l,d,y,f,b,E;if(l=o,i.charCodeAt(o)===39?(d=C,o++):(d=t,v===0&&$(qe)),d!==t){for(y=[],f=o,i.charCodeAt(o)===92?(b=w,o++):(b=t,v===0&&$(oe)),b!==t?(i.length>o?(E=i.charAt(o),o++):(E=t,v===0&&$(ue)),E!==t?f=E:(o=f,f=t)):(o=f,f=t),f===t&&(f=i.charAt(o),z.test(f)?o++:(f=t,v===0&&$(Le)));f!==t;)y.push(f),f=o,i.charCodeAt(o)===92?(b=w,o++):(b=t,v===0&&$(oe)),b!==t?(i.length>o?(E=i.charAt(o),o++):(E=t,v===0&&$(ue)),E!==t?f=E:(o=f,f=t)):(o=f,f=t),f===t&&(f=i.charAt(o),z.test(f)?o++:(f=t,v===0&&$(Le)));i.charCodeAt(o)===39?(f=C,o++):(f=t,v===0&&$(qe)),f!==t?l=Nt(y):(o=l,l=t)}else o=l,l=t;return l}function Ht(){let l,d,y,f,b,E,S,k,D,W;if(l=o,d=o,y=o,i.charCodeAt(o)===45?(f=A,o++):(f=t,v===0&&$(St)),f===t&&(f=null),b=o,E=[],S=i.charAt(o),_.test(S)?o++:(S=t,v===0&&$(U)),S!==t)for(;S!==t;)E.push(S),S=i.charAt(o),_.test(S)?o++:(S=t,v===0&&$(U));else E=t;if(E!==t)if(i.charCodeAt(o)===46?(S=a,o++):(S=t,v===0&&$(me)),S!==t){if(k=[],D=i.charAt(o),_.test(D)?o++:(D=t,v===0&&$(U)),D!==t)for(;D!==t;)k.push(D),D=i.charAt(o),_.test(D)?o++:(D=t,v===0&&$(U));else k=t;k!==t?(E=[E,S,k],b=E):(o=b,b=t)}else o=b,b=t;else o=b,b=t;if(b===t)if(b=[],E=i.charAt(o),_.test(E)?o++:(E=t,v===0&&$(U)),E!==t)for(;E!==t;)b.push(E),E=i.charAt(o),_.test(E)?o++:(E=t,v===0&&$(U));else b=t;if(b!==t){if(E=o,S=i.charAt(o),L.test(S)?o++:(S=t,v===0&&$(It)),S!==t){if(k=i.charAt(o),gt.test(k)?o++:(k=t,v===0&&$(At)),k===t&&(k=null),D=[],W=i.charAt(o),_.test(W)?o++:(W=t,v===0&&$(U)),W!==t)for(;W!==t;)D.push(W),W=i.charAt(o),_.test(W)?o++:(W=t,v===0&&$(U));else D=t;D!==t?(S=[S,k,D],E=S):(o=E,E=t)}else o=E,E=t;E===t&&(E=null),f=[f,b,E],y=f}else o=y,y=t;return y!==t?d=i.substring(d,o):d=y,d!==t&&(d=Pt(d)),l=d,l}function Xt(){let l,d,y,f;return l=o,i.substr(o,4)===I?(d=I,o+=4):(d=t,v===0&&$(_t)),d!==t?(y=o,v++,f=te(),v--,f===t?y=void 0:(o=y,y=t),y!==t?l=Ot():(o=l,l=t)):(o=l,l=t),l===t&&(l=o,i.substr(o,5)===x?(d=x,o+=5):(d=t,v===0&&$(kt)),d!==t?(y=o,v++,f=te(),v--,f===t?y=void 0:(o=y,y=t),y!==t?l=jt():(o=l,l=t)):(o=l,l=t)),l}function Yt(){let l,d,y,f;return l=o,i.substr(o,4)===q?(d=q,o+=4):(d=t,v===0&&$(xt)),d!==t?(y=o,v++,f=te(),v--,f===t?y=void 0:(o=y,y=t),y!==t?l=Mt():(o=l,l=t)):(o=l,l=t),l}function Oe(){let l,d,y,f,b,E;if(l=o,d=o,y=o,f=i.charAt(o),Et.test(f)?o++:(f=t,v===0&&$(qt)),f!==t){for(b=[],E=te();E!==t;)b.push(E),E=te();f=[f,b],y=f}else o=y,y=t;return y!==t?d=i.substring(d,o):d=y,d!==t&&(d=d),l=d,l}function te(){let l;return l=i.charAt(o),yt.test(l)?o++:(l=t,v===0&&$(Lt)),l}function T(){let l,d;for(l=[],d=i.charAt(o),Ae.test(d)?o++:(d=t,v===0&&$(Te));d!==t;)l.push(d),d=i.charAt(o),Ae.test(d)?o++:(d=t,v===0&&$(Te));return l}function Jt(l,d){return{type:"CallChain",target:l,calls:d.map(y=>y[3])}}ee=n();const ge=ee!==t&&o===i.length;function je(){throw ee!==t&&otypeof a=="object"&&a!==null&&!Array.isArray(a)?nt(a,e):a);t=s.apply(t,n)}return t}var ki=class{static parse(i,e){const t=Ai(i,void 0);return nt(t,e)}},xi={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},qi=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],Ge=class extends Error{constructor(i){super(`Unsupported locale: ${i}`),this.localeCode=i}},Li={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function Ti(i){if(typeof i!="string"||!i.trim())throw new Ge(i);const e=i.trim().replace(/_/g,"-").toLowerCase(),t=qi.find(s=>s.toLowerCase()===e);if(t)return t;const r=Li[e];if(!r)throw new Ge(i);return r}var He=class{constructor(e,t){if(this.data=e,this.fallback=t,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(Ti)}message(e,t){return this.data.locales[e]?.messages[t]??this.fallback?.data.locales[e]?.messages[t]??this.data.locales.en?.messages[t]??this.fallback?.data.locales.en?.messages[t]??t}translate(e,t){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),a=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(t,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(a)),e}};He.builtin=new He(xi);var Y=class extends Error{constructor(i){super(`Check failed: ${i.map(e=>e.message??`${e.ruleId}:${e.location}`).join("; ")}`),this.violations=i,this.name="CheckException"}};function Bi(i,e){const t=i.defaultDomainRoot,r=e.defaultDomainRoot;if(t&&r&&(t.entity!==r.entity||t.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...i.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??t,constants:[...s.values()],ensure:i.ensure&&e.ensure?async n=>{await i.ensure(n),await e.ensure(n)}:e.ensure??i.ensure}}var Fi=class ot{constructor(e={},t={},r={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...t}),this.bootstrap=Object.freeze({defaultDomainRoot:r.defaultDomainRoot,constants:Object.freeze([...r.constants??[]]),ensure:r.ensure})}and(e){return new ot({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},Bi(this.bootstrap,e.bootstrap))}},Xe=class ut{constructor(e,t,r,s){this.enabledValue=e,this.cacheExpiredMillis=t,this.propagateValue=r,this.propagateCacheExpiredMillis=s}static enabled(e){return new ut(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}},Ri=class be{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,t,r,s=!0){return this.facets.push({facetName:e,relationName:t,query:r.toQuery(),includeAllFacets:s}),this}clone(){const e=new be(this.entity);return e.filterCondition=this.filterCondition,e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.orderItems=[...this.orderItems],e.selectItems=[...this.selectItems],e.properties=[...this.properties],e.joins=[...this.joins],e.groupByItems=[...this.groupByItems],e.aggregateItems=this.aggregateItems.map(t=>({...t})),e.aggregationCache=this.aggregationCache,e.facets=this.facets.map(t=>({...t,query:t.query.clone()})),e.relations=this.relations.map(t=>({...t,query:t.query?.clone()})),e.relationAggregates=this.relationAggregates.map(t=>({...t,query:t.query.clone()})),e.commentText=this.commentText,e.purposeText=this.purposeText,e.idSetPaginationOptions=this.idSetPaginationOptions,e.idSetPaginationRuntimeContext=this.idSetPaginationRuntimeContext,e.topNProbeThreshold=this.topNProbeThreshold,e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,t){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:t},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,t,r){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(t)||t<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(r)||r<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:t,maxIds:r},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const t=new be(this.entity);return t.filterCondition=this.filterCondition,t.commentText=this.commentText,t.purposeText=this.purposeText,t.aggregate("Count","id",e),t}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const t of this.relations)t.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,t,r="id",s="id",n=!0){return this.relations.push({name:e,query:t,localKey:r,foreignKey:s,many:n}),this}relationAggregate(e,t,r,s=!0){return this.relationAggregates.push({relationName:e,alias:t,query:r,singleResult:s}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=Xe.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=Xe.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,t,r){return this.aggregateItems.push({function:e,field:t,alias:r}),this}groupBy(e){return this.groupByItems.push(e),this}},j=i=>`${i.entity}\0${typeof i.id}:${String(i.id)}`,K=class{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map}set(i,e,t){if(!e.trim())throw new TypeError("field is required");const r=j(i),s=this.changes.get(r)??{key:Object.freeze({...i}),values:{}};s.values[e]=t,this.changes.set(r,s)}snapshot(){return[...this.changes.values()].map(i=>({key:Object.freeze({...i.key}),values:Object.freeze({...i.values})}))}change(i){return Object.freeze({...this.changes.get(j(i))?.values??{}})}mergeFrom(i){if(i!==this){for(const e of i.snapshot())for(const[t,r]of Object.entries(e.values))this.set(e.key,t,r);for(const e of i.newKeys.values())this.markAsNew(e);for(const e of i.deletedKeys.values())this.markAsDeleted(e);for(const e of i.snapshotVersions())this.setOriginalVersion(e.key,e.version)}}snapshotVersions(){return[...this.originalVersions.values()]}rekey(i,e){const t=j(i),r=j(e);if(t===r)return;const s=this.changes.get(t);if(s){this.changes.delete(t);for(const[a,u]of Object.entries(s.values))this.set(e,a,u)}const n=this.originalVersions.get(t);n!==void 0&&(this.originalVersions.delete(t),this.originalVersions.set(r,{key:Object.freeze({...e}),version:n.version})),this.newKeys.delete(t)&&this.newKeys.set(r,Object.freeze({...e})),this.deletedKeys.delete(t)&&this.deletedKeys.set(r,Object.freeze({...e}))}clearEntity(i){const e=j(i);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e)}setOriginalVersion(i,e){this.originalVersions.set(j(i),{key:Object.freeze({...i}),version:e})}originalVersion(i){return this.originalVersions.get(j(i))?.version}markAsNew(i){this.newKeys.set(j(i),Object.freeze({...i}))}isNew(i){return this.newKeys.has(j(i))}markAsDeleted(i){const e=j(i);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...i}))}isDeleted(i){return this.deletedKeys.has(j(i))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear()}};function at(i){const e=i.split("_");return e[0]+e.slice(1).map(t=>t?t[0].toUpperCase()+t.slice(1):"").join("")}function Di(i,e){if(e==="snake_case")return i;const t=at(i);return e==="camelCase"||!t?t:t[0].toUpperCase()+t.slice(1)}function Ni(i){return i.replace(/~/g,"~0").replace(/\//g,"~1")}var M=class J{constructor(e){this.segments=e}static root(){return new J([])}static property(e){return J.root().property(e)}property(e){return new J([...this.segments,{kind:"property",name:e}])}index(e){return new J([...this.segments,{kind:"index",index:e}])}prefixedBy(e){return new J([...e.segments,...this.segments])}modelPath(){return this.render(e=>e)}nativePath(){return this.render(at)}instancePath(e="camelCase"){return this.segments.map(t=>t.kind==="index"?String(t.index):Ni(Di(t.name,e))).map(t=>`/${t}`).join("")}toString(){return this.nativePath()}render(e){let t="";for(const r of this.segments)r.kind==="index"?t+=`[${r.index}]`:t+=`${t?".":""}${e(r.name)}`;return t}},G=class ve extends Array{static get[Symbol.species](){return Array}constructor(e=[],t={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,ve.prototype),this.totalCount=t.totalCount,this.aggregations=t.aggregations??{},this.summary=t.summary??{},this.facets=t.facets??{},this.isLoaded=t.isLoaded??!0}static empty(){return new ve([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,t){return this.facets[e]=t,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}};function Pi(i){return i.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function $e(i){if(i&&typeof i=="object"){const e=i;return e.id??e.Id}return i}function Oi(i,e){const t=Pi(e);for(const r of[e,`${e}Id`,t,`${t}_id`]){const s=$e(i[r]);if(s!=null)return s}}async function lt(i,e,t,r){const s={};for(const n of r){let a;if(i.executeFacetMembership)a=await i.executeFacetMembership(e(t.clone()),n.relationName);else{const c=t.clone();c.facets=[],c.relations=[],c.orderItems=[],c.aggregateItems=[],c.groupByItems=[],c.offsetValue=0,c.limitValue=0,c.selectItems=[n.relationName];const g=await i.executeQuery(e(c));a=new Map;for(const w of g){const C=Oi(w,n.relationName);if(C==null)continue;const A=String(C);a.set(A,(a.get(A)??0)+1)}}const u=n.query.clone();u.facets=[],u.commentText??(u.commentText=t.commentText),u.purposeText??(u.purposeText=t.purposeText);const h=u.aggregateItems.filter(c=>String(c.function).toLowerCase()==="count").map(c=>String(c.alias));u.aggregateItems=[],u.groupByItems=[];const p=(await i.executeQuery(e(u))).map(c=>{const g=a.get(String($e(c.id??c.Id)))??0,w={...c};for(const C of h)w[C]=g;return w}).filter(c=>n.includeAllFacets||a.has(String($e(c.id??c.Id))));s[n.facetName]=new G(p)}return s}class se extends Ri{orderBy(e,t){return this.order({field:e,expr:null,direction:t==="desc"?"Desc":"Asc"})}relationQuery(e,t,r="id",s="id",n=!0){return this.relations.push({name:e,query:t,localKey:r,foreignKey:s,many:n}),this}}class B{static teaqlTemporaryId=0;id;title;description;platform;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new K,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--B.teaqlTemporaryId,writable:!0,enumerable:!1}),e){const r={...e};Object.assign(this,r),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof F?e.platform:F.fromRecord(e.platform),this.markLoaded("platform"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"WorkItem",id:this._ledgerId}}teaqlAttachRoot(e){return this._root!==e&&(e.mergeFrom(this._root),this._root=e),this}static fromRecord(e,t){const r=new B(e);return t?r.teaqlAttachRoot(t):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new B({id:String(e)})}static teaqlBootstrapNew(e){return new B().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,t),this.teaqlSaveWithinGraph(e,t)))}teaqlPreflightGraph(e,t){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"title",canonical:"title"},{member:"description",canonical:"description"},{member:"platform",canonical:"platform"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new Y([{ruleId:"invalid_type",location:M.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}t.preflightMutation({entity:"WorkItem",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root})}async teaqlSaveWithinGraph(e,t){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"WorkItem",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},a=await t.executeMutation(n);for(const[p,c]of Object.entries(n.payload))p!=="id"&&p!=="version"&&this._root.set(this.teaqlEntityKey(),p,c);if(!a.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},h=this.teaqlEntityKey();Object.assign(this,a.persistedRecord),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();return this._root.rekey(h,m),t.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(m,h)}),this._loadedFields=new Set(Object.keys(a.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update"),t.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.setOriginalVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,title:this.title,description:this.description,platform:this.platform,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateTitle(e){return this.title=e,this.markLoaded("title"),this._root.set(this.teaqlEntityKey(),"title",e),this}updateDescription(e){return this.description=e,this.markLoaded("description"),this._root.set(this.teaqlEntityKey(),"description",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}}class F{static teaqlTemporaryId=0;id;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new K,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--F.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_workItemList",{value:[],writable:!0,enumerable:!1}),e){const r={...e};delete r.workItemList,Object.assign(this,r),Array.isArray(e.workItemList)&&(this._workItemList=e.workItemList.map(s=>s instanceof B?s:B.fromRecord(s)),this.markLoaded("workItemList"))}const t=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(t):this.version!==void 0&&this._root.setOriginalVersion(t,Number(this.version))}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const t of this._workItemList)t.teaqlAttachRoot(e);return this}static fromRecord(e,t){const r=new F(e);return t?r.teaqlAttachRoot(t):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const t of e)this._loadedFields.add(t);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new F({id:String(e)})}static teaqlBootstrapNew(e){return new F().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const t=e.requireResource("dataService");return t.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,t),this.teaqlSaveWithinGraph(e,t)))}teaqlPreflightGraph(e,t){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new Y([{ruleId:"invalid_type",location:M.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}t.preflightMutation({entity:"Platform",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root});for(const[s,n]of this._workItemList.entries()){n.teaqlAttachRoot(this._root),n.updatePlatform(this),n.auditAs(this._comment);try{n.teaqlPreflightGraph(e,t)}catch(a){if(!(a instanceof Y))throw a;const u=M.property("work_item_list").index(s);throw new Y(a.violations.map(h=>({...h,location:h.location.prefixedBy(u)})))}}}async teaqlSaveWithinGraph(e,t){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"Platform",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},a=await t.executeMutation(n);for(const[p,c]of Object.entries(n.payload))p!=="id"&&p!=="version"&&this._root.set(this.teaqlEntityKey(),p,c);if(!a.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},h=this.teaqlEntityKey();Object.assign(this,a.persistedRecord),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(h,m),t.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(m,h)}),this._loadedFields=new Set(Object.keys(a.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update");for(const[p,c]of this._workItemList.entries()){c.teaqlAttachRoot(this._root),c.updatePlatform(this),c.auditAs(this._comment);try{await c.teaqlSaveWithinGraph(e,e.requireResource("dataService"))}catch(g){if(!(g instanceof Y))throw g;const w=M.property("work_item_list").index(p);throw new Y(g.violations.map(C=>({...C,location:C.location.prefixedBy(w)})))}}return t.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.setOriginalVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}workItemList(){return this._workItemList}}class Ye{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new se("Platform"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new ji(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,r,s)=>this.executeForPageInternal(t,r,s),(t,r)=>this.executeForStreamInternal(t,r),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,r){return this.query.optimizePaginationWithIdSetConfig(e,t,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectWorkItemListWith(e){return this.query.relationQuery("workItemList",e.toQuery(),"id","platform",!0),this}haveWorkItems(){return this.withWorkItemListMatching({toQuery:()=>new se("WorkItem")})}haveNoWorkItems(){return this.withoutWorkItemListMatching({toQuery:()=>new se("WorkItem")})}withWorkItemListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutWorkItemListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}countWorkItems(){return this.countWorkItemsAs("countWorkItems")}countWorkItemsAs(e){const t=new se("WorkItem").filter({version:{$gte:1}});return this.countWorkItemsWith(e,{toQuery:()=>t})}countWorkItemsWith(e,t){return t.toQuery().aggregate("Count","id",e),this.query.relationAggregate("workItemList",e,t.toQuery(),!0),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,t){return this.filters.push({name:{$between:[e,t]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),r=await t.executeQuery(e.prepareQuery(this.query)),s=new K,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,a=n?[]:r.map(h=>h instanceof F?h:F.fromRecord(h,s)),u=new G(a);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await lt(t,h=>e.prepareQuery(h),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new G(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,r){this.ensureIntent(),this.query.offset(t).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,a=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),h=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query),m=new K,p=new G(u.map(c=>c instanceof F?c:F.fromRecord(c,m)));return p.totalCount=h,{data:p,totalCount:h,offset:t,limit:r}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new K;for await(const n of r.executeForStream(this.query,t))for(const a of n)yield a instanceof F?a:F.fromRecord(a,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class ji{constructor(e,t,r,s,n,a,u){this.execute=e,this.executeRows=t,this.page=r,this.stream=s,this.limitOne=n,this.addComment=a,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new F}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,r){return this.ensureIntent(),this.page(e,t,r)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Je{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new se("WorkItem"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new Mi(t=>this.executeForListInternal(t),t=>this.executeForRowsInternal(t),(t,r,s)=>this.executeForPageInternal(t,r,s),(t,r)=>this.executeForStreamInternal(t,r),()=>this.limit(1),t=>this.comment(t),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,t){return this.query.optimizeForContinuousPageFetchWith(e,t),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,t,r){return this.query.optimizePaginationWithIdSetConfig(e,t,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","title","description","platform","version"]),this}selectId(){return this.query.select(["id"]),this}selectTitle(){return this.query.select(["title"]),this}selectDescription(){return this.query.select(["description"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,t){return this.filters.push({id:{$between:[e,t]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withTitleContaining(e){return this.filters.push({title:{$contains:e}}),this}withTitleIs(e){return this.filters.push({title:{$eq:e}}),this}withTitleIsNot(e){return this.filters.push({title:{$ne:e}}),this}withTitleIn(...e){return this.filters.push({title:{$in:e}}),this}withTitleNotIn(...e){return this.filters.push({title:{$notIn:e}}),this}withTitleGreaterThan(e){return this.filters.push({title:{$gt:e}}),this}withTitleGreaterThanOrEqualTo(e){return this.filters.push({title:{$gte:e}}),this}withTitleLessThan(e){return this.filters.push({title:{$lt:e}}),this}withTitleLessThanOrEqualTo(e){return this.filters.push({title:{$lte:e}}),this}withTitleBetween(e,t){return this.filters.push({title:{$between:[e,t]}}),this}withTitleIsKnown(){return this.filters.push({title:{$isNull:!1}}),this}withTitleIsUnknown(){return this.filters.push({title:{$isNull:!0}}),this}withTitleNotContaining(e){return this.filters.push({title:{$notContains:e}}),this}withTitleStartingWith(e){return this.filters.push({title:{$startsWith:e}}),this}withTitleNotStartingWith(e){return this.filters.push({title:{$notStartsWith:e}}),this}withTitleEndingWith(e){return this.filters.push({title:{$endsWith:e}}),this}withTitleNotEndingWith(e){return this.filters.push({title:{$notEndsWith:e}}),this}withTitleSoundingLike(e){return this.filters.push({title:{$soundLike:e}}),this}withDescriptionContaining(e){return this.filters.push({description:{$contains:e}}),this}withDescriptionIs(e){return this.filters.push({description:{$eq:e}}),this}withDescriptionIsNot(e){return this.filters.push({description:{$ne:e}}),this}withDescriptionIn(...e){return this.filters.push({description:{$in:e}}),this}withDescriptionNotIn(...e){return this.filters.push({description:{$notIn:e}}),this}withDescriptionGreaterThan(e){return this.filters.push({description:{$gt:e}}),this}withDescriptionGreaterThanOrEqualTo(e){return this.filters.push({description:{$gte:e}}),this}withDescriptionLessThan(e){return this.filters.push({description:{$lt:e}}),this}withDescriptionLessThanOrEqualTo(e){return this.filters.push({description:{$lte:e}}),this}withDescriptionBetween(e,t){return this.filters.push({description:{$between:[e,t]}}),this}withDescriptionIsKnown(){return this.filters.push({description:{$isNull:!1}}),this}withDescriptionIsUnknown(){return this.filters.push({description:{$isNull:!0}}),this}withDescriptionNotContaining(e){return this.filters.push({description:{$notContains:e}}),this}withDescriptionStartingWith(e){return this.filters.push({description:{$startsWith:e}}),this}withDescriptionNotStartingWith(e){return this.filters.push({description:{$notStartsWith:e}}),this}withDescriptionEndingWith(e){return this.filters.push({description:{$endsWith:e}}),this}withDescriptionNotEndingWith(e){return this.filters.push({description:{$notEndsWith:e}}),this}withDescriptionSoundingLike(e){return this.filters.push({description:{$soundLike:e}}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,t){return this.filters.push({version:{$between:[e,t]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByTitleAscending(){return this.query.orderBy("title","asc"),this}orderByTitleDescending(){return this.query.orderBy("title","desc"),this}orderByDescriptionAscending(){return this.query.orderBy("description","asc"),this}orderByDescriptionDescending(){return this.query.orderBy("description","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByTitle(){return this.query.groupBy("title"),this}groupByTitleAs(e){return this.query.groupBy("title"),this}groupByDescription(){return this.query.groupBy("description"),this}groupByDescriptionAs(e){return this.query.groupBy("description"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,t,r=!0){return this.query.facetBy(e,"platform",t,r),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService"),r=await t.executeQuery(e.prepareQuery(this.query)),s=new K,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,a=n?[]:r.map(h=>h instanceof B?h:B.fromRecord(h,s)),u=new G(a);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await lt(t,h=>e.prepareQuery(h),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const t=e.requireResource("dataService");return new G(await t.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,t,r){this.ensureIntent(),this.query.offset(t).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,a=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),h=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:a??await s.executeCount(this.query),m=new K,p=new G(u.map(c=>c instanceof B?c:B.fromRecord(c,m)));return p.totalCount=h,{data:p,totalCount:h,offset:t,limit:r}}async*executeForStreamInternal(e,t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new K;for await(const n of r.executeForStream(this.query,t))for(const a of n)yield a instanceof B?a:B.fromRecord(a,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class Mi{constructor(e,t,r,s,n,a,u){this.execute=e,this.executeRows=t,this.page=r,this.stream=s,this.limitOne=n,this.addComment=a,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new B}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,t,r){return this.ensureIntent(),this.page(e,t,r)}executeForStream(e,t=1e3){return this.ensureIntent(),this.stream(e,t)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Ie{static platforms(){return new Ye(!1)}static platformsWithMinimalFields(){return new Ye(!0)}static workItems(){return new Je(!1)}static workItemsWithMinimalFields(){return new Je(!0)}}const ct={Platform:{table:"platform_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}};async function Vi(i){let e=(await Ie.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(i))[0];e||(e=F.teaqlBootstrapNew("1"),e.updateName("Runtime Example"),await e.auditAs("create generated Domain Root Platform").save(i)),i.withActiveRoot({entity:"Platform",id:e.id})}const Wi=new Fi(ct,{Platform:{checkAndFix(i,e,t){i.getResource("fixTime"),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&t.push({ruleId:"required",location:M.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&t.push({ruleId:"max_length",location:M.property("name"),inputValue:e.payload.name,systemValue:100})}},WorkItem:{checkAndFix(i,e,t){i.getResource("fixTime"),(e.action==="Create"&&e.payload.title===void 0||e.payload.title===null)&&t.push({ruleId:"required",location:M.property("title")}),e.payload.title!=null&&!([...String(e.payload.title)].length>=1)&&t.push({ruleId:"min_length",location:M.property("title"),inputValue:e.payload.title,systemValue:1}),e.payload.title!=null&&[...String(e.payload.title)].length>80&&t.push({ruleId:"max_length",location:M.property("title"),inputValue:e.payload.title,systemValue:80}),e.payload.description!=null&&[...String(e.payload.description)].length>100&&t.push({ruleId:"max_length",location:M.property("description"),inputValue:e.payload.description,systemValue:100}),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&t.push({ruleId:"required",location:M.property("platform")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Runtime Example"}},constants:[],ensure:Vi}),ce=document.querySelector("#status"),Ui=document.querySelector("#result"),he=document.querySelector("#persist"),Qi=document.querySelector("#opfs-note"),we=document.querySelector("#reset"),Ze=document.querySelector("#preset"),de=document.querySelector("#query"),Se=document.querySelector("#run"),ht={facet:`Q.workItems() - .selectTitle() - .facetByPlatformAs( - "platforms", - Q.platforms().selectName().countAs("workItemCount") - ) - .orderByIdAscending() - .limit(20) - .comment("what: load browser-local work items with a platform facet") - .purpose("why: demonstrate the complete TeaQL web response")`,filter:`Q.workItems() - .selectTitle() - .withTitleContaining("model") - .orderByIdAscending() - .limit(20) - .comment("what: find work items whose title contains model") - .purpose("why: demonstrate a generated string predicate")`,all:`Q.workItems() - .selectTitle() - .orderByIdAscending() - .limit(20) - .comment("what: load browser-local work items") - .purpose("why: demonstrate a bounded generated query")`};de.value=ht.facet;let N;const fe=globalThis.crossOriginIsolated&&typeof navigator.storage?.getDirectory=="function",dt=localStorage.getItem("teaql-browser-storage")==="opfs",ft=dt&&fe?"opfs":"memory";dt&&!fe&&localStorage.removeItem("teaql-browser-storage");he.checked=ft==="opfs";he.disabled=!fe;fe||(Qi.textContent="(unavailable on this static host; memory mode remains fully browser-local)");async function Ki(i){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),t=await bi.open(e,{...ct},{storage:i,databaseName:"teaql-browser-example.sqlite3"});t.install(Wi);const r=new it().insertResource("dataService",t);return t.setUserContext(r),await r.ensureSchema(),{client:t,context:r}}async function mt({context:i}){if(!(await Ie.workItemsWithMinimalFields().comment("what: detect existing browser demo records").purpose("why: keep generated mutation bootstrap idempotent").executeForList(i)).length)for(const t of["Evaluate semantic model","Generate typed library","Verify browser runtime"])await new B().updateTitle(t).updatePlatform("1").auditAs("seed deterministic browser demo data").save(i)}async function ne(i){Se.disabled=!0,ce.textContent=`${i.client.storage.toUpperCase()} · running controlled query…`;try{const e=ki.parse(de.value,Ie);if(typeof e?.executeForList!="function")throw new Error("The query must end with a generated executable request");const t=await e.executeForList(i.context),r=Ii.fromSmartList(t);Ui.textContent=JSON.stringify(r,null,2),ce.textContent=`${i.client.storage.toUpperCase()} · ${r.recordCount} records · ready`}finally{Se.disabled=!1}}async function pt(i){ce.textContent=`Opening ${i.toUpperCase()} SQLite/WASM…`;const e=N;N=void 0,await e?.client.close();const t=await Ki(i);N=t,await mt(t),await ne(t)}Ze.addEventListener("change",()=>{de.value=ht[Ze.value],N&&ne(N).catch(Z)});Se.addEventListener("click",()=>{N&&ne(N).catch(Z)});de.addEventListener("keydown",i=>{(i.ctrlKey||i.metaKey)&&i.key==="Enter"&&N&&ne(N).catch(Z)});he.addEventListener("change",()=>{const i=he.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",i),pt(i).catch(Z)});we.addEventListener("click",async()=>{if(N){we.disabled=!0;try{await N.client.reset(N.context),await mt(N),await ne(N)}catch(i){Z(i)}finally{we.disabled=!1}}});function Z(i){const e=i instanceof Error?i:new Error(String(i));ce.textContent=`${e.name}: ${e.message}`}pt(ft).catch(Z); diff --git a/dist/assets/index-DmPc8xp3.css b/dist/assets/index-DmPc8xp3.css deleted file mode 100644 index 0c0b5de1295b8c7c6e54d45257452c38878ba434..0000000000000000000000000000000000000000 --- a/dist/assets/index-DmPc8xp3.css +++ /dev/null @@ -1 +0,0 @@ -:root{font:16px/1.5 Inter,system-ui,sans-serif;color:#e8edf5;background:#090b10}body{margin:0}main{width:min(760px,calc(100% - 40px));margin:10vh auto}.eyebrow{color:#d9ff52;font-size:12px;font-weight:800;letter-spacing:.16em}h1{margin:8px 0;font-size:clamp(36px,7vw,68px);letter-spacing:-.05em}.controls{display:flex;gap:18px;align-items:center;margin:32px 0}button{border:0;border-radius:5px;padding:10px 14px;background:#d9ff52;font-weight:800}#status{color:#aab4c4}pre{min-height:260px;padding:22px;overflow:auto;border:1px solid #2b323e;border-radius:8px;background:#11151c;color:#c6d1df}.evidence-scroll{overflow-x:auto;margin:24px 0}.evidence-table{border-collapse:collapse;width:100%;text-align:left}.evidence-table th,.evidence-table td{padding:12px;border:1px solid #2b323e;vertical-align:top}.evidence-table td{white-space:pre-wrap;overflow-wrap:anywhere;min-width:110px}.evidence-table td:last-child{min-width:320px;font-family:monospace} diff --git a/dist/assets/index-LiMSU-HT.js b/dist/assets/index-LiMSU-HT.js deleted file mode 100644 index 341eb4c3a2b81d44239b3491458f1acc130d017b..0000000000000000000000000000000000000000 --- a/dist/assets/index-LiMSU-HT.js +++ /dev/null @@ -1,5 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const n of s)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function i(s){const n={};return s.integrity&&(n.integrity=s.integrity),s.referrerPolicy&&(n.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?n.credentials="include":s.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(s){if(s.ep)return;s.ep=!0;const n=i(s);fetch(s.href,n)}})();var be={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},ve=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],H=class extends Error{constructor(e){super(`Unsupported locale: ${e}`),this.localeCode=e}},Ie={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function ue(t){if(typeof t!="string"||!t.trim())throw new H(t);const e=t.trim().replace(/_/g,"-").toLowerCase(),i=ve.find(s=>s.toLowerCase()===e);if(i)return i;const r=Ie[e];if(!r)throw new H(t);return r}var M=class{constructor(e,i){if(this.data=e,this.fallback=i,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(ue)}message(e,i){return this.data.locales[e]?.messages[i]??this.fallback?.data.locales[e]?.messages[i]??this.data.locales.en?.messages[i]??this.fallback?.data.locales.en?.messages[i]??i}translate(e,i){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(i,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};M.builtin=new M(be);var Se=M,oe=Symbol("teaql.context.schema-capability"),X=new WeakMap,_e=1;function ke(t){if(!t||typeof t!="object"&&typeof t!="function")return String(t);const e=t;let i=X.get(e);return i||(i=_e++,X.set(e,i)),String(i)}var Y=class extends Error{constructor(t,e,i){super(`context root ${t}: expected ${e}`),this.reason=t,this.expectedType=e,this.activeRoot=i,this.name="ContextRootError"}},ae=class{constructor(){this.resources=new Map,this.continuousPageCursors=new Map,this.retainedIdSets=new Map,this.idSetBuilds=new Map,this.continuousPageRuntime={owner:"",get:(t,e)=>this.getContinuousPageCursor(t,e),put:(t,e,i)=>this.putContinuousPageCursor(t,e,i),observe:(t,e)=>{this.continuousPagePlan=t,this.continuousPageCursorId=e}},this.idSetPaginationRuntime={owner:"",scope:"",get:t=>this.idSetStore().get(t),put:(t,e)=>this.idSetStore().put(t,e),build:(t,e)=>this.singleFlightIdSetBuild(t,e),observe:(t,e)=>{this.idSetPaginationPlan=t,this.idSetPaginationCount=e,this.idSetPaginationCountAccuracy=t==="ID_SET_BUILD"||t==="ID_SET_HIT"?"EXACT":t==="ID_SET_FALLBACK_LIMIT_EXCEEDED"?"LOWER_BOUND":"UNKNOWN"}},this.userIdentifier="",this.continuousPagePlan="DISABLED",this.idSetPaginationPlan="ID_SET_DISABLED",this.idSetPaginationCountAccuracy="UNKNOWN",this.locale="en",this.i18nCatalog=Se.builtin}setLocaleCode(t){const e=ue(t);return this.locale=e,this}setLanguageCode(t){return this.setLocaleCode(t)}installI18nCatalog(t){if(!t)throw new Error("catalog is required");return this.i18nCatalog=t,this}installIdSetPaginationStore(t){if(!t)throw new Error("ID set pagination store is required");return this.insertResource("idSetPaginationStore",t)}translateCheckResults(t){return t.map(e=>this.i18nCatalog.translate(e,this.locale))}beginFixEvidence(){return this.insertResource("fixEvidenceCurrent",[])}recordFixEvidence(t){const e=String(t.sourceLabel||""),i=e.toLowerCase();if(!t.entityType||!t.modelPath||!e||i.includes("authorization")||i.includes("cookie")||i.includes("token="))throw new TypeError("Fix evidence must contain only safe framework provenance labels");const r=this.getResource("fixEvidenceCurrent")??[];return this.getResource("fixEvidenceCurrent")||this.insertResource("fixEvidenceCurrent",r),r.push(Object.freeze({...t})),this}finishFixEvidence(){const t=this.getResource("fixEvidenceCurrent")??[];return this.insertResource("fixEvidenceLast",Object.freeze([...t])),this.removeResource("fixEvidenceCurrent")}lastFixEvidence(){return this.getResource("fixEvidenceLast")??[]}insertResource(t,e){return this.resources.set(t,e),this}getResource(t){return this.resources.get(t)}removeResource(t){return this.resources.delete(t),this}requireResource(t){const e=this.getResource(t);if(e===void 0)throw new Error(`Required UserContext resource is missing: ${t}`);return e}ensureSchema(){const t=this.requireResource("dataService"),e=t[oe];if(!e)throw new Error("Configured dataService is not a schema-aware TeaQL provider");return e.call(t,this)}withActiveRoot(t){if(!t||!t.entity||t.id===void 0||t.id===null)throw new TypeError("active root must be a typed entity reference");return this.insertResource("activeRoot",Object.freeze({...t}))}requireActiveRoot(t){const e=this.getResource("activeRoot");if(!e)throw new Y("missing",t);if(e.entity!==t)throw new Y("type_mismatch",t,e);return e}prepareQuery(t){this.continuousPageRuntime.owner=this.userIdentifier,this.idSetPaginationRuntime.owner=this.userIdentifier;const e=this.getResource("activeRoot");return this.idSetPaginationRuntime.scope=[this.userIdentifier,e?`${e.entity}:${String(e.id)}`:"-",ke(this.getResource("dataService"))].join("|"),t.bindContinuousPageRuntime(this.continuousPageRuntime).bindIdSetPaginationRuntime(this.idSetPaginationRuntime)}getContinuousPageCursor(t,e){const i=`${t}:${e}`,r=this.continuousPageCursors.get(i);if(r&&r.expiresAt<=Date.now()){this.continuousPageCursors.delete(i);return}return r}putContinuousPageCursor(t,e,i){if(this.continuousPageCursors.size>=4096){const r=[...this.continuousPageCursors.entries()].sort((s,n)=>s[1].expiresAt-n[1].expiresAt)[0];r&&this.continuousPageCursors.delete(r[0])}this.continuousPageCursors.set(`${t}:${e}`,i)}getRetainedIdSet(t){const e=this.retainedIdSets.get(t);if(e&&e.expiresAt<=Date.now()){this.retainedIdSets.delete(t);return}return e}idSetStore(){return this.getResource("idSetPaginationStore")??{get:t=>this.getRetainedIdSet(t),put:(t,e)=>this.putRetainedIdSet(t,e),invalidate:t=>{this.retainedIdSets.delete(t)}}}putRetainedIdSet(t,e){if(e.ids.byteLength>268435456)throw new Error("ID set exceeds the process-local store memory ceiling");const r=()=>[...this.retainedIdSets.values()].reduce((s,n)=>s+n.ids.byteLength,0);for(;this.retainedIdSets.size>=64||r()+e.ids.byteLength>268435456;){const s=[...this.retainedIdSets.entries()].sort((n,o)=>n[1].expiresAt-o[1].expiresAt)[0];if(!s)break;this.retainedIdSets.delete(s[0])}this.retainedIdSets.set(t,e)}async singleFlightIdSetBuild(t,e){const i=this.idSetBuilds.get(t);if(i)return{value:await i,built:!1};const r=e();this.idSetBuilds.set(t,r);try{return{value:await r,built:!0}}finally{this.idSetBuilds.delete(t)}}},$e=class extends Error{constructor(e){super(`Check failed: ${e.map(i=>i.message??`${i.ruleId}:${i.location}`).join("; ")}`),this.violations=e,this.name="CheckException"}};function Ae(t,e){const i=t.defaultDomainRoot,r=e.defaultDomainRoot;if(i&&r&&(i.entity!==r.entity||i.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...t.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??i,constants:[...s.values()],ensure:t.ensure&&e.ensure?async n=>{await t.ensure(n),await e.ensure(n)}:e.ensure??t.ensure}}var J=class B{constructor(e,i,r){this.field=e,this.expr=i,this.direction=r}static new(e,i){return new B(e,null,i)}static expr(e,i){return new B("",e,i)}static asc(e){return B.new(e,"Asc")}static desc(e){return B.new(e,"Desc")}},Z=Object.freeze({success:()=>{},failure:()=>{}}),qe=new Set(["teaql.entity.id","teaql.user.id","teaql.tenant.id","teaql.query.parameters","teaql.field.values","teaql.audit.reason","db.query.parameter_values","http.request.body","url.full"]);function xe(t){const e={"teaql.operation.family":t.family,"teaql.operation.name":t.name};for(const[i,r]of Object.entries(t.attributes||{}))qe.has(i)||(e[i]=r);return Object.freeze({...t,attributes:Object.freeze(e)})}function D(t,e){if(!t)return Z;try{const i=t.start(xe(e));let r=!1;return{run:i.run?s=>i.run(s):s=>s(),success(s){if(!r){r=!0;try{i?.success(s)}catch{}}},failure(s){if(!r){r=!0;try{i?.failure(s)}catch{}}}}}catch{return Z}}async function T(t,e,i,r){const s=D(t,e);try{const n=await(s.run?s.run(i):i());return s.success(r?.(n)),n}catch(n){throw s.failure(n),n}}function Le(t){const e=new Map;for(const i of Object.values(t))for(const r of Object.values(i.relations||{})){if(!r.many)continue;const s=t[r.targetEntity],n=s?.columns[r.foreignKey]?.columnName,o=s?.columns.id?.columnName;if(!s||!n||!o)continue;const u=`idx_${s.table}_${n}_${o}`;let a=2166136261;for(let l=0;l>>0).toString(36),h=u.length<=30?u:`${u.slice(0,Math.max(1,29-c.length))}_${c}`;e.set(h,{name:h,table:s.table,foreignColumn:n,idColumn:o})}return[...e.values()]}async function Te(t,e,i,r){const s=Number(r);if(!Number.isSafeInteger(s)||s<0)throw new Error(`Invalid ID space floor ${r} for ${i}`);for(let n=1;n<=100;n+=1){const o=await t.query(`SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${e(1)}`,[i]);if(!o.rowCount){try{if((await t.query(`INSERT INTO teaql_id_space(type_name, current_level) VALUES (${e(1)}, ${e(2)})`,[i,s])).rowCount===1)return}catch(c){if(!(await t.query(`SELECT current_level FROM teaql_id_space WHERE type_name = ${e(1)}`,[i])).rowCount)throw c}continue}const u=Number(o.rows[0].id);if(u>=s)return;const a=await t.query(`UPDATE teaql_id_space SET current_level = ${e(1)} WHERE type_name = ${e(2)} AND current_level = ${e(3)}`,[s,i,u]);if(a.rowCount===1)return;if(a.rowCount!==0)throw new Error(`ID space floor update for ${i} changed ${a.rowCount} rows on attempt ${n}`)}throw new Error(`Unable to synchronize ID space floor for ${i} after 100 optimistic-lock attempts`)}function Be(t){return t.startsWith('"')&&t.endsWith('"')||t.startsWith("`")&&t.endsWith("`")?t.slice(1,-1).replace(/""/g,'"').replace(/``/g,"`"):t}function Re(t,e){return t===e?!0:(t instanceof Date&&(t=t.getTime()),e instanceof Date&&(e=e.getTime()),t!=null&&e!==null&&e!==void 0&&String(t)===String(e))}function O(t,e,i){return[{level:0,kind:"operation",name:"mutation"},{level:1,kind:"entity",name:String(t.entity)},{level:2,kind:"provider",name:e},{level:3,kind:"sql",name:i}]}function Fe(t,e,i="sqlite"){let r=0,s="",n="sql";for(let o=0;o=0&&h=0&&hi.toString(16).padStart(2,"0")).join("")}'`:_(typeof t=="object"?JSON.stringify(t):String(t))}function _(t){return`'${t.replace(/'/g,"''")}'`}var De=class{constructor(t=e=>console.debug(e)){this.writer=t}write(t){this.writer(`[TeaQL SQL][${t.operation}][${t.elapsedMicros}us] ${t.resultSummary} -comment=${t.comment??""} purpose=${t.purpose??""} auditReason=${t.auditReason??""} tracePath=${ee(t.tracePath)} -Parameterized SQL: ${t.parameterizedSQL} params=${ee(t.parameters)} -Debug SQL: ${t.debugSQL}`)}};function ee(t){return JSON.stringify(t,(e,i)=>typeof i=="bigint"?i.toString():i)}var Ne=class{constructor(t,e){this.driver=t,this.schemas=e,this.bootstrapTail=Promise.resolve(),this.sqlTrace=[],this.internalQueryToken=Symbol("teaql-internal-query"),this.auditEvents=[],this.diagnosticSQLLogSink=new De,this.queryLoggingEnabled=!0,this.mutationLoggingEnabled=!0,this.checkers={},this.userContext=new ae,this.bootstrap={},this.graphCommitActions=[],this.graphRollbackActions=[],this.graphSaveTail=Promise.resolve()}install(t){return Object.assign(this.schemas,t.schemas),Object.assign(this.checkers,t.checkers),this.bootstrap=Ae(this.bootstrap,t.bootstrap),this}setUserContext(t){return this.userContext=t,this}schema(t){const e=this.schemas[t];if(!e)throw new Error(`Unknown TeaQL entity: ${t}`);return e}toRuntimeMutationRecord(t,e){const i={};for(const[r,s]of Object.entries(e)){const n=t.columns[r]?r:Object.keys(t.columns).find(o=>t.columns[o].modelName===r||t.columns[o].columnName===r);n&&(i[n]=s)}return i}encode(t,e){const i=t?.id??t;if(i!==void 0)return this.driver.encode(i,e)}decodeRow(t,e,i=[]){const r=this.schema(t),s={...e};for(const[n,o]of Object.entries(r.columns)){const u=s[n];u!=null&&(o.decode==="number"&&(s[n]=Number(u)),o.decode==="string"&&(s[n]=String(u)),o.decode==="date"&&u instanceof Date&&(s[n]=u.toISOString()),o.logicalType==="boolean"&&(s[n]=!!u))}for(const n of i)s[n]!==null&&s[n]!==void 0&&(s[n]=Number(s[n]));return s}get auditTrace(){return[...this.auditEvents]}setAuditSink(t){return this.auditSink=t,this}setRuntimeTelemetrySink(t){return this.telemetrySink=t,this}setDiagnosticSQLLogSink(t){return this.diagnosticSQLLogSink=t,this}setQueryLoggingEnabled(t){return this.queryLoggingEnabled=t,this}setMutationLoggingEnabled(t){return this.mutationLoggingEnabled=t,this}setRuntimeTelemetry(t){return this.runtimeTelemetry=t,this}recordSQL(t,e,i,r,s,n,o={}){const u=t==="select";if(u&&!this.queryLoggingEnabled||!u&&!this.mutationLoggingEnabled||!this.telemetrySink&&!this.diagnosticSQLLogSink)return;const a=Object.freeze({operation:t,...o,tracePath:Object.freeze([...o.tracePath??[]]),parameterizedSQL:e,parameters:Object.freeze([...i]),debugSQL:Fe(e,i,this.driver.databaseKind),elapsedMicros:Math.max(0,(Date.now()-r)*1e3),resultCount:s,affectedRows:n,resultSummary:s!==void 0?`${s} rows returned`:`${n??0} rows affected`});this.telemetrySink?.record(a),this.diagnosticSQLLogSink?.write(a)}async[oe](t){this.userContext=t,this.schemaReady||(this.schemaReady=this.driver.ensureSchema(this.schemas)),await this.schemaReady;const e=this.bootstrapTail;let i;this.bootstrapTail=new Promise(r=>{i=r}),await e;try{if(this.bootstrap.ensure){t.insertResource("bootstrapActor","teaql-generated-bootstrap"),t.insertResource("bootstrapCategory","runtime-bootstrap");try{await this.bootstrap.ensure(t)}finally{t.removeResource("bootstrapActor"),t.removeResource("bootstrapCategory")}}else await this.ensureBootstrapData()}finally{i()}}invalidateSchemaState(){this.schemaReady=void 0}async ensureBootstrapData(){const t=[...this.bootstrap.defaultDomainRoot?[this.bootstrap.defaultDomainRoot]:[],...this.bootstrap.constants??[]];t.length&&await this.driver.transaction(async e=>{for(const i of t)await this.reconcileBootstrapEntity(e,i)})}async reconcileBootstrapEntity(t,e){const i=this.schema(e.entity),r=this.driver.identifier(i.table),s=this.driver.identifier(i.columns.id?.columnName??"id"),n=this.driver.identifier(i.columns.version?.columnName??"version"),o=Object.entries(e.values??{}).map(([a,c])=>{const h=i.columns[a];if(!h)throw new Error(`Unknown bootstrap field ${e.entity}.${a}`);return{column:this.driver.identifier(h.columnName),value:this.driver.encode(c,h)}}),u=await t.query(`SELECT * FROM ${r} WHERE ${s} = ${this.driver.placeholder(1)}`,[e.id]);if(u.rowCount){const a=u.rows[0],c=o.filter(h=>!Re(a[Be(h.column)],h.value));if(c.length){const h=c.map((l,m)=>`${l.column} = ${this.driver.placeholder(m+1)}`);h.push(`${n} = ${n} + 1`),await t.query(`UPDATE ${r} SET ${h.join(", ")} WHERE ${s} = `+this.driver.placeholder(c.length+1),[...c.map(l=>l.value),e.id])}}else{const a=[s,n,...o.map(l=>l.column)],c=[e.id,1,...o.map(l=>l.value)],h=c.map((l,m)=>this.driver.placeholder(m+1));await t.query(`INSERT INTO ${r} (${a.join(", ")}) VALUES (${h.join(", ")})`,c)}await this.driver.ensureIdFloor(t,e.entity,e.id)}async executeGraphSave(t){const e=this.graphSaveTail;let i;this.graphSaveTail=new Promise(r=>{i=r}),await e,this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.insertResource("fixTime",new Date),this.userContext.beginFixEvidence();try{const r=await this.driver.transaction(async s=>{this.graphMutationSession=s;try{return await t()}finally{this.graphMutationSession=void 0}});for(const s of this.graphCommitActions)s();return r}catch(r){for(const s of[...this.graphRollbackActions].reverse())s();throw r}finally{this.graphCommitActions=[],this.graphRollbackActions=[],this.userContext.removeResource("fixTime").finishFixEvidence(),i()}}afterGraphCommit(t){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphCommitActions.push(t)}afterGraphRollback(t){if(!this.graphMutationSession)throw new Error("No graph save is active");this.graphRollbackActions.push(t)}async withMutationSession(t){return this.graphMutationSession?t(this.graphMutationSession):this.driver.transaction(t)}preflightMutation(t){if(!String(t?.comment||"").trim())throw new Error("Security audit failure: audit reason is required before mutation");t={...t,payload:{...t?.payload??{}}};const e=this.checkers[String(t.entity)];if(!e)return t;const i=[],r=this.userContext.getResource("fixTime")===void 0;r&&this.userContext.insertResource("fixTime",new Date).beginFixEvidence();try{if(e.checkAndFix(this.userContext,t,i),t.ledgerKey&&t.ledgerRoot)for(const[s,n]of Object.entries(t.payload||{}))t.ledgerRoot.set(t.ledgerKey,s,n);if(this.userContext.translateCheckResults(i),i.length)throw new $e(i);return t}finally{r&&this.userContext.removeResource("fixTime").finishFixEvidence()}}async executeMutation(t){const e=D(this.runtimeTelemetry,{family:"mutation",name:`${String(t?.entity||"unknown")}.${String(t?.action||"unknown").toLowerCase()}`,attributes:{"teaql.entity.type":String(t?.entity||"unknown"),"teaql.mutation.kind":String(t?.action||"unknown").toLowerCase()}});try{t=this.preflightMutation(t);const i=this.schema(t.entity),r=this.toRuntimeMutationRecord(i,t.payload||{}),s=this.driver.identifier(i.table),n=await T(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.mutation`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":String(t.action).toLowerCase()}},()=>this.withMutationSession(async u=>{if(t.action==="Create"){const a=t.id?String(t.id):await this.driver.nextId(u,t.entity);t.id&&await this.driver.ensureIdFloor(u,t.entity,a);const c=Number(t.version||0)+1,h={...r,id:a,version:c},l=Object.keys(i.columns).filter(w=>h[w]!==void 0),m=l.map(w=>this.driver.identifier(i.columns[w].columnName)).join(", "),d=l.map((w,k)=>this.driver.placeholder(k+1)).join(", "),p=l.map(w=>this.encode(h[w],i.columns[w])),f=`INSERT INTO ${s} (${m}) VALUES (${d})`,g=Date.now(),E=await u.query(f,p);return this.recordSQL("insert",f,p,g,void 0,E.rowCount,{auditReason:String(t.comment),tracePath:O(t,this.driver.databaseKind,"insert")}),{success:!0,id:a,version:c,persistedRecord:await this.readPersistedRecord(u,i,a)}}if(t.action==="Update"){const a=Object.keys(i.columns).filter(E=>E!=="id"&&E!=="version"&&r[E]!==void 0),c=a.map(E=>this.encode(r[E],i.columns[E])),h=a.map((E,w)=>`${this.driver.identifier(i.columns[E].columnName)} = `+this.driver.placeholder(w+1)),l=this.driver.identifier("version");h.push(`${l} = ${l} + 1`),c.push(String(t.id));const m=[`${this.driver.identifier("id")} = ${this.driver.placeholder(c.length)}`];t.version!==void 0&&t.version!==null&&(c.push(Number(t.version)),m.push(`${l} = ${this.driver.placeholder(c.length)}`));const d=`UPDATE ${s} SET ${h.join(", ")} WHERE ${m.join(" AND ")}`,p=Date.now(),f=await u.query(d,c);if(this.recordSQL("update",d,c,p,void 0,f.rowCount,{auditReason:String(t.comment),tracePath:O(t,this.driver.databaseKind,"update")}),f.rowCount!==1)throw new Error(`Optimistic lock failed or ${t.entity}(${t.id}) does not exist`);const g=await this.readPersistedRecord(u,i,String(t.id));return{success:!0,id:String(t.id),version:Number(g.version),persistedRecord:g}}if(t.action==="Delete"){const a=this.driver.identifier("version"),c=[String(t.id)],h=[`${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`];t.version!==void 0&&t.version!==null&&(c.push(Number(t.version)),h.push(`${this.driver.identifier("version")} = `+this.driver.placeholder(c.length)));const l=`UPDATE ${s} SET ${a} = -(${a} + 1) WHERE ${h.join(" AND ")}`,m=Date.now(),d=await u.query(l,c);if(this.recordSQL("delete",l,c,m,void 0,d.rowCount,{auditReason:String(t.comment),tracePath:O(t,this.driver.databaseKind,"delete")}),d.rowCount!==1)throw new Error(`Optimistic lock failed or ${t.entity}(${t.id}) does not exist`);const p=await this.readPersistedRecord(u,i,String(t.id));return{success:!0,id:String(t.id),version:Number(p.version),deleted:!0,persistedRecord:p}}throw new Error(`Unsupported mutation action: ${t.action}`)})),o=Object.freeze({entity:t.entity,action:t.action,id:String(n.id),reason:String(t.comment),recordedAt:new Date().toISOString(),actor:this.userContext.getResource("bootstrapActor"),category:this.userContext.getResource("bootstrapCategory"),changedFields:Object.keys(t.payload||{}).sort(),version:n.version});return this.auditEvents.push(o),this.auditSink&&await T(this.runtimeTelemetry,{family:"audit",name:`${t.entity}.audit`,attributes:{"teaql.entity.type":String(t.entity),"teaql.mutation.kind":String(t.action).toLowerCase(),"teaql.audit.changed_field_count":Object.keys(t.payload||{}).length}},async()=>this.auditSink(o)),e.success(),n}catch(i){throw e.failure(i),i}}async readPersistedRecord(t,e,i){const r=Object.entries(e.columns).map(([n,o])=>`${this.driver.identifier(o.columnName)} AS ${this.driver.identifier(n)}`).join(", "),s=await t.query(`SELECT ${r} FROM ${this.driver.identifier(e.table)} WHERE ${this.driver.identifier("id")} = ${this.driver.placeholder(1)}`,[i]);if(s.rowCount!==1)throw new Error(`Persisted ${e.table}(${i}) could not be read back`);return this.decodeRowForSchema(e,s.rows[0])}decodeRowForSchema(t,e){const i={...e};for(const[r,s]of Object.entries(t.columns)){const n=i[r];n!=null&&(s.decode==="number"&&(i[r]=Number(n)),s.decode==="string"&&(i[r]=String(n)),s.decode==="date"&&n instanceof Date&&(i[r]=n.toISOString()),s.logicalType==="boolean"&&(i[r]=!!n))}return i}compileExpression(t,e,i){if(Array.isArray(t?.$and))return`(${t.$and.map(n=>this.compileExpression(n,e,i)).join(" AND ")})`;const r=Object.entries(t||{}).map(([s,n])=>{const o=e.columns[s];if(!o)throw new Error(`Unknown field ${s} for SQL query`);const u=this.driver.identifier(o.columnName);if(n?.$eq!==void 0){const a=n.$eq?.id??n.$eq;return a===null?`${u} IS NULL`:(i.push(this.encode(a,o)),`${u} = ${this.driver.placeholder(i.length)}`)}if(n?.$ne!==void 0){const a=n.$ne?.id??n.$ne;return a===null?`${u} IS NOT NULL`:(i.push(this.encode(a,o)),`${u} <> ${this.driver.placeholder(i.length)}`)}if(n?.$soundLike!==void 0)return i.push(String(n.$soundLike)),`SOUNDEX(${u}) = SOUNDEX(${this.driver.placeholder(i.length)})`;if(n?.$contains!==void 0)return i.push(String(n.$contains)),this.driver.contains(u,this.driver.placeholder(i.length));if(n?.$notContains!==void 0)return i.push(String(n.$notContains)),`NOT (${this.driver.contains(u,this.driver.placeholder(i.length))})`;for(const[a,c,h,l]of[["$startsWith","","%",!1],["$notStartsWith","","%",!0],["$endsWith","%","",!1],["$notEndsWith","%","",!0]])if(n?.[a]!==void 0){i.push(`${c}${String(n[a])}${h}`);const m=`${u} LIKE ${this.driver.placeholder(i.length)}`;return l?`NOT (${m})`:m}if(Array.isArray(n?.$in)){if(!n.$in.length)return"FALSE";const a=n.$in.map(c=>(i.push(this.encode(c?.id??c,o)),this.driver.placeholder(i.length)));return`${u} IN (${a.join(", ")})`}if(Array.isArray(n?.$notIn)){if(!n.$notIn.length)return"TRUE";const a=n.$notIn.map(c=>(i.push(this.encode(c?.id??c,o)),this.driver.placeholder(i.length)));return`${u} NOT IN (${a.join(", ")})`}for(const[a,c]of[["$inSubquery",!1],["$notInSubquery",!0]]){const h=n?.[a];if(h!==void 0){const l=h.query,m=this.schema(l?.entity),d=String(h.field),p=m.columns[d];if(!p)throw new Error(`Unknown subquery projection ${d} for ${l?.entity}`);const f=this.filters(l).map(w=>this.compileExpression(w,m,i));m.columns.version&&f.push(`${this.driver.identifier(m.columns.version.columnName)} > 0`),c&&f.push(`${this.driver.identifier(p.columnName)} IS NOT NULL`);const g=f.length?` WHERE ${f.join(" AND ")}`:"",E=`SELECT ${this.driver.identifier(p.columnName)} FROM ${this.driver.identifier(m.table)}${g}`;return`${u} ${c?"NOT IN":"IN"} (${E})`}}if(Array.isArray(n?.$between)&&n.$between.length===2){i.push(this.encode(n.$between[0],o));const a=this.driver.placeholder(i.length);i.push(this.encode(n.$between[1],o));const c=this.driver.placeholder(i.length);return`${u} BETWEEN ${a} AND ${c}`}if(n?.$isNull===!0)return`${u} IS NULL`;if(n?.$isNull===!1)return`${u} IS NOT NULL`;if(n?.$gte!==void 0)return i.push(this.encode(n.$gte,o)),`${u} >= ${this.driver.placeholder(i.length)}`;if(n?.$lte!==void 0)return i.push(this.encode(n.$lte,o)),`${u} <= ${this.driver.placeholder(i.length)}`;if(n?.$gt!==void 0)return i.push(this.encode(n.$gt,o)),`${u} > ${this.driver.placeholder(i.length)}`;if(n?.$lt!==void 0)return i.push(this.encode(n.$lt,o)),`${u} < ${this.driver.placeholder(i.length)}`;throw new Error(`Unsupported query predicate for ${s}: ${JSON.stringify(n)}`)});return r.length?`(${r.join(" AND ")})`:"TRUE"}filters(t){return Array.isArray(t._filters)&&t._filters.length?t._filters:t.filterCondition?[t.filterCondition]:[]}groupBy(t){return t._groupBy||t.groupByItems||[]}aggregates(t){return Array.isArray(t._aggregates)?t._aggregates:(t.aggregateItems||[]).map(e=>({func:e.function,field:e.field,retName:e.alias}))}orders(t){return Array.isArray(t._orderBy)?t._orderBy.map(e=>({field:e.f,direction:e.d})):(t.orderItems||[]).map(e=>({field:e.field,direction:e.direction}))}async compileQuery(t){const e=t?.[this.internalQueryToken]===!0,i=t?._purpose??t?.purposeText,r=t?._comment??t?.commentText;if(!e&&(!String(i||"").trim()||!String(r||"").trim()))throw new Error("Security audit failure: purpose and comment are required before query execution");const s=this.schema(t.entity),n=[],o=this.groupBy(t),u=o.map(y=>{if(!s.columns[y])throw new Error(`Unknown group field: ${y}`);return this.driver.identifier(s.columns[y].columnName)}),a=o.map(y=>`${this.driver.identifier(s.columns[y].columnName)} AS `+this.driver.identifier(y)),c=[],h=Array.isArray(t.selectItems)&&t.selectItems.length?[...new Set(["id","version",...t.selectItems])]:Object.keys(s.columns);for(const y of h)if(!s.columns[y])throw new Error(`Unknown selected field: ${y}`);let l=h.map(y=>{const C=s.columns[y];return`${this.driver.identifier(C.columnName)} AS ${this.driver.identifier(y)}`}).join(", ");const m=this.aggregates(t);if(m.length){const y=m.map(C=>{if(!s.columns[C.field])throw new Error(`Unknown aggregate field: ${C.field}`);return c.push(C.retName),`${this.driver.aggregateFunction(C.func)}(${this.driver.identifier(s.columns[C.field].columnName)}) AS `+this.driver.identifier(C.retName)});l=[...a,...y].join(", ")}const d=t.__teaqlPartitionBy,p=this.orders(t),f=p.map(y=>{if(!s.columns[y.field])throw new Error(`Unknown order field: ${y.field}`);const C=String(y.direction).toLowerCase()==="desc"?"DESC":"ASC";return`${this.driver.identifier(s.columns[y.field].columnName)} ${C}`});if(d){const y=s.columns[d];if(!y)throw new Error(`Unknown partition field: ${d}`);const C=f.length?` ORDER BY ${f.join(", ")}`:"";l+=`, ROW_NUMBER() OVER (PARTITION BY ${this.driver.identifier(y.columnName)}${C}) AS `+this.driver.identifier("__teaql_partition_rank")}let g=`SELECT ${l} FROM ${this.driver.identifier(s.table)}`;const w=this.filters(t).map(y=>this.compileExpression(y,s,n));s.columns.version&&w.push(`${this.driver.identifier(s.columns.version.columnName)} > 0`),w.length&&(g+=` WHERE ${w.join(" AND ")}`),u.length&&(g+=` GROUP BY ${u.join(", ")}`);const k=t._limit!==void 0?Number(t._limit):Number(t.limitValue||0),F=t._offset!==void 0?Number(t._offset):Number(t.offsetValue||0);if(d){const y=this.driver.identifier("__teaql_partition_rank"),C=[];n.push(F),C.push(`${y} > ${this.driver.placeholder(n.length)}`),k>0&&(n.push(F+k),C.push(`${y} <= ${this.driver.placeholder(n.length)}`)),g=`SELECT * FROM (${g}) AS ${this.driver.identifier("__teaql_partitioned")} WHERE ${C.join(" AND ")} ORDER BY ${y}`}else p.length&&(g+=` ORDER BY ${f.join(", ")}`);return!d&&k>0&&(n.push(k),g+=` LIMIT ${this.driver.placeholder(n.length)}`),!d&&F>0&&(n.push(F),g+=` OFFSET ${this.driver.placeholder(n.length)}`),this.sqlTrace.push(g),{sql:g,values:n,aggregateNames:c}}async executeQuery(t){const e=D(this.runtimeTelemetry,{family:"query",name:`${String(t?.entity||"unknown")}.list`,attributes:{"teaql.entity.type":String(t?.entity||"unknown")}});try{const i=t?.[this.internalQueryToken]===!0;if(!i){if(typeof t?.prepareForList!="function")throw new Error("TeaQL list execution requires the formal runtime SelectQuery");t.prepareForList()}const r=i?{query:t,execution:void 0}:await this.prepareIdSetPage(t),s=i?r:await this.prepareContinuousPage(r.query);t=s.query;const{sql:n,values:o,aggregateNames:u}=await this.compileQuery(t),a=Date.now(),c=await T(this.runtimeTelemetry,{family:"provider",name:`${this.driver.databaseKind}.query`,attributes:{"teaql.provider.kind":this.driver.databaseKind,"teaql.provider.operation":"query"}},()=>this.driver.query(n,o)),h=t?._comment??t?.commentText,l=t?._purpose??t?.purposeText,m=Array.isArray(t?.__teaqlTracePath)?t.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(t.entity)}],d=[...m,{level:m.length,kind:"provider",name:this.driver.databaseKind},{level:m.length+1,kind:"sql",name:"select"}];this.recordSQL("select",n,o,a,c.rowCount,void 0,{comment:h,purpose:l,tracePath:d});const p=c.rows.map(f=>this.decodeRow(t.entity,f,u));if(r.execution?.pageIds){const f=new Map(r.execution.pageIds.map((g,E)=>[String(g),E]));p.sort((g,E)=>(f.get(String(g.id))??Number.MAX_SAFE_INTEGER)-(f.get(String(E.id))??Number.MAX_SAFE_INTEGER))}return await this.enhanceRelations(p,t),await this.enhanceRelationAggregates(p,t),i||await this.registerContinuousPage(t,s.execution,p),e.success({attributes:{"teaql.result.cardinality":p.length}}),p}catch(i){throw e.failure(i),i}}async prepareIdSetPage(t){const e=t.localIdSetPaginationOptions?.(),i=t.localIdSetPaginationRuntime?.();if(!e||!i)return i?.observe("ID_SET_DISABLED"),{query:t};const r=this.queryLimit(t);if(!r||t.localContinuousPageOptions?.()||this.aggregates(t).length||this.groupBy(t).length||t.__teaqlPartitionBy)return i.observe("ID_SET_FALLBACK_UNSUPPORTED_SHAPE"),{query:t};if((t.orderItems||[]).some(d=>d.expr!=null))return i.observe("ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER"),{query:t};this.orders(t).some(d=>d.field==="id")||(t=t.clone().order(J.asc("id")));const s=t.clone();s.offsetValue=0,s.limitValue=0,s.selectItems=[],s.relations=[],s.commentText=void 0,s.purposeText=void 0,s.clearIdSetPaginationRuntime(),s.clearContinuousPageRuntime();const n=`${e.namespace}|${i.scope}|${JSON.stringify(s)}`;let o=2166136261;for(let d=0;d>>0).toString(16)}`;let a,c=!1;try{a=i.get(u)}catch{return i.observe("ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:t}}if(a)c=!0,i.observe("ID_SET_HIT",a.ids.length);else{let d;try{d=await i.build(u,async()=>{const p=i.get(u);if(p)return p;const f=t.clone();f.selectItems=["id"],f.relations=[],f.relationAggregates=[],f.facets=[],f.offsetValue=0,f.limitValue=e.maxIds+1,f.clearIdSetPaginationRuntime(),f.clearContinuousPageRuntime(),f[this.internalQueryToken]=!0;const g=await this.executeQuery(f);if(g.length>e.maxIds)return;let E;try{E=BigUint64Array.from(g.map(k=>BigInt(k.id)))}catch{throw new Error("ID_SET_UNSUPPORTED_ID")}const w={ids:E,expiresAt:Date.now()+e.ttlSeconds*1e3};return i.put(u,w),w})}catch(p){return i.observe(p instanceof Error&&p.message==="ID_SET_UNSUPPORTED_ID"?"ID_SET_FALLBACK_UNSUPPORTED_SHAPE":"ID_SET_FALLBACK_STORE_UNAVAILABLE"),{query:t}}if(a=d.value,!a)return i.observe("ID_SET_FALLBACK_LIMIT_EXCEEDED",e.maxIds+1),{query:t};c=!d.built,i.observe(c?"ID_SET_HIT":"ID_SET_BUILD",a.ids.length)}const h=Number(t.offsetValue||t._offset||0),l=Array.from(a.ids.slice(h,h+r)),m=t.clone();return m.offsetValue=0,m.limitValue=Math.max(l.length,1),m.filterCondition=m.filterCondition?{$and:[m.filterCondition,{id:{$in:l}}]}:{id:{$in:l}},m.clearIdSetPaginationRuntime(),i.observe(c?"ID_SET_HIT":"ID_SET_BUILD",a.ids.length),{query:m,execution:{pageIds:l,totalCount:a.ids.length}}}async executeFacetMembership(t,e){const i=t.clone();i.facets=[],i.relations=[],i.orderItems=[],i.offsetValue=0,i.limitValue=0,i.selectItems=[],i.groupByItems=[e],i.aggregateItems=[{function:"Count",field:"id",alias:"__teaql_facet_count"}],i[this.internalQueryToken]=!0;const r=await this.executeQuery(i);return new Map(r.flatMap(s=>{const n=s[e],o=Number(s.__teaql_facet_count??0);return n==null?[]:[[String(n),o]]}))}async executeCount(t){if(typeof t?.forExactCount!="function")throw new Error("TeaQL exact count requires the formal runtime SelectQuery");const e="__teaql_total",r=(await this.executeQuery(t.forExactCount(e)))[0]?.[e];if(typeof r!="number"||!Number.isFinite(r))throw new Error(`TeaQL provider did not return exact count alias ${e}`);return r}async prepareContinuousPage(t){const e=t.localContinuousPageOptions?.(),i=t.localContinuousPageRuntime?.();if(!e||!i)return i?.observe("DISABLED"),{query:t};const r=this.orders(t),s=this.queryLimit(t);if(!s||r.length!==1||r[0].field!=="id"||this.aggregates(t).length||this.groupBy(t).length||t.__teaqlPartitionBy)return i.observe("OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE"),{query:t};const n=Object.assign(Object.create(Object.getPrototypeOf(t)),t);n.orderItems=[...t.orderItems||[]],n.relations=[...t.relations||[]],Object.defineProperty(n,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:e}),Object.defineProperty(n,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:i});const o=Number(t.offsetValue||t._offset||0),u={...JSON.parse(JSON.stringify(n)),offsetValue:0,_offset:0,commentText:void 0,purposeText:void 0},a=`${e.namespace}|${i.owner}|${JSON.stringify(u)}`;let c=2166136261;for(let p=0;p>>0).toString(16)}`,l={queryKey:h,offset:o,limit:s,direction:String(r[0].direction).toLowerCase(),ttlSeconds:e.ttlSeconds,runtime:i,optimized:!1};if(o===0)return i.observe("OFFSET_FALLBACK:FIRST_PAGE"),{query:n,execution:l};let m;try{m=await T(this.runtimeTelemetry,{family:"cache",name:"continuous_page.get",attributes:{"teaql.cache.operation":"get"}},()=>i.get(h,o))}catch{return i.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE"),{query:n,execution:l}}if(!m)return i.observe("OFFSET_FALLBACK:CACHE_MISS"),{query:n,execution:l};const d={id:{[l.direction==="desc"?"$lt":"$gt"]:m.boundary}};return n.filterCondition=n.filterCondition?{$and:[n.filterCondition,d]}:d,n.offsetValue=0,n._offset!==void 0&&(n._offset=0),l.optimized=!0,l.cursorId=m.cursorId,i.observe("CURSOR_SEEK",m.cursorId),{query:n,execution:l}}async registerContinuousPage(t,e,i){if(!(!e||i.length!==e.limit||!i.length||i[i.length-1].id===void 0)){try{await T(this.runtimeTelemetry,{family:"cache",name:"continuous_page.put",attributes:{"teaql.cache.operation":"put"}},()=>e.runtime.put(e.queryKey,e.offset+i.length,{cursorId:`cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`,boundary:i[i.length-1].id,expiresAt:Date.now()+e.ttlSeconds*1e3}))}catch{e.runtime.observe("OFFSET_FALLBACK:STORE_UNAVAILABLE");return}e.optimized&&e.runtime.observe("CURSOR_SEEK",e.cursorId)}}async*executeForStream(t,e=1e3){if(!Number.isInteger(e)||e<=0)throw new Error("stream chunk size must be a positive integer");if(Array.isArray(t.facets)&&t.facets.length>0)throw new Error("QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList");const{sql:i,values:r,aggregateNames:s}=await this.compileQuery(t);let n=[];for await(const o of this.driver.stream(i,r))n.push(this.decodeRow(t.entity,o,s)),n.length===e&&(await this.enhanceRelations(n,t),yield n,n=[]);n.length&&(await this.enhanceRelations(n,t),yield n)}async enhanceRelations(t,e){if(!t.length||!Array.isArray(e.relations)||!e.relations.length)return;const i=this.schema(e.entity);for(const r of e.relations){const s=i.relations?.[r.name];if(!s)throw new Error(`Missing relation ${e.entity}.${r.name}`);const n=t.map(d=>d[s.localKey]).filter(d=>d!=null),o=r.query?this.queryLimit(r.query):void 0,u=r.query?.localTopNProbeParentThreshold?.(),a=s.many&&o!==void 0,c=this.driver.topNRelationPlanPolicy==="alwaysProbe",h=a&&(u===void 0?c:u>0&&n.length<=u),l=h?"bounded_probes":"window",m=D(this.runtimeTelemetry,{family:"relation_load",name:`${e.entity}.${String(r.name)}`,attributes:{"teaql.entity.type":String(e.entity),"teaql.relation.name":String(r.name),"teaql.relation.parent_count":n.length,"teaql.relation.per_parent_limit":o??0,"teaql.relation.configured_probe_threshold":u??"provider-default","teaql.relation.selected_plan":l,"teaql.relation.probe_count":h?n.length:0}});try{if(!n.length){for(const g of t)g[r.name]=s.many?[]:null;m.success({attributes:{"teaql.result.cardinality":0}});continue}const d={...r.query||{},entity:s.targetEntity,_filters:[...this.filters(r.query||{})],relations:[...r.query?.relations||[]],orderItems:[...r.query?.orderItems||[]],__teaqlPartitionBy:a&&!h?s.foreignKey:void 0,__teaqlTracePath:[...Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath:[{level:0,kind:"operation",name:"query"},{level:1,kind:"request",name:String(e.entity)}],{level:Array.isArray(e.__teaqlTracePath)?e.__teaqlTracePath.length:2,kind:"relation",name:`${String(e.entity)}.${String(r.name)}`}],commentText:e?._comment??e?.commentText,purposeText:e?._purpose??e?.purposeText};a&&!d.orderItems.some(g=>g.field==="id")&&d.orderItems.push(J.asc("id")),typeof d.clearContinuousPageRuntime=="function"&&d.clearContinuousPageRuntime(),d[this.internalQueryToken]=!0;const p=[];if(h)for(const g of n){const E={...d,_filters:[...d._filters,{[s.foreignKey]:{$eq:g}}],__teaqlPartitionBy:void 0};p.push(...await this.executeQuery(E))}else d._filters.push({[s.foreignKey]:{$in:n}}),p.push(...await this.executeQuery(d));for(const g of p)delete g.__teaql_partition_rank;const f=new Map;for(const g of p){const E=g[s.foreignKey],w=f.get(E)||[];w.push(g),f.set(E,w)}for(const g of t){const E=f.get(g[s.localKey])||[];g[r.name]=s.many?E:E[0]??null}m.success({attributes:{"teaql.result.cardinality":p.length}})}catch(d){throw m.failure(d),d}}}async enhanceRelationAggregates(t,e){const i=e.relationAggregates;if(!t.length||!Array.isArray(i)||!i.length)return;const r=this.schema(e.entity);for(const s of i){const n=r.relations?.[s.relationName];if(!n)throw new Error(`Missing relation ${e.entity}.${s.relationName}`);const o=t.map(h=>h[n.localKey]).filter(h=>h!=null);if(!o.length){for(const h of t)h[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{};continue}const u=s.query.clone();u.entity=n.targetEntity,u.selectItems=[],u.properties=[],u.orderItems=[],u.limitValue=0,u.offsetValue=0,u.relations=[],u.relationAggregates=[],u.aggregateItems.length||u.aggregate("Count","id",s.alias),u.groupByItems.includes(n.foreignKey)||u.groupBy(n.foreignKey),u.filterCondition={...u.filterCondition||{},[n.foreignKey]:{$in:o}},u[this.internalQueryToken]=!0;const a=await this.executeQuery(u),c=new Map;for(const h of a)c.set(h[n.foreignKey],h);for(const h of t){const l=c.get(h[n.localKey]);l?s.singleResult?h[s.alias]=l[u.aggregateItems[0].alias]??null:h[s.alias]=Object.fromEntries(Object.entries(l).filter(([m])=>m!==n.foreignKey)):h[s.alias]=s.singleResult?this.emptyAggregateValue(s.query):{}}}}emptyAggregateValue(t){const e=t.aggregateItems[0];return!e||String(e.function).toLowerCase()==="count"?0:null}queryLimit(t){if(t._limit!==void 0)return Number(t._limit);if(t.limitValue!==void 0&&Number(t.limitValue)>0)return Number(t.limitValue)}async close(){await this.driver.close()}};function Pe(t){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))throw new Error(`Unsafe SQL identifier: ${t}`);return t}function Oe(t){const i={count:"COUNT",sum:"SUM",avg:"AVG",min:"MIN",max:"MAX"}[String(t).toLowerCase()];if(!i)throw new Error(`Unsupported aggregate: ${t}`);return i}var je=class{constructor(t){this.worker=t,this.nextRequestId=1,this.pending=new Map,this.closed=!1,this.onMessage=e=>{const i=e.data;if(!i||i.type!=="teaql-browser-sqlite-response")return;const r=this.pending.get(i.requestId);if(r)if(this.pending.delete(i.requestId),i.error){const s=new Error(i.error.message);s.name=i.error.name,i.error.code&&(s.code=i.error.code),r.reject(s)}else r.resolve(i.result)},this.onError=e=>{const i=new Error(e.message||"Browser SQLite worker failed");i.name="BrowserSQLiteWorkerError";for(const r of this.pending.values())r.reject(i);this.pending.clear()},t.addEventListener("message",this.onMessage),t.addEventListener("error",this.onError)}request(t,e){if(this.closed)return Promise.reject(new Error("Browser SQLite worker is closed"));const i=this.nextRequestId++;return new Promise((r,s)=>{this.pending.set(i,{resolve:n=>r(n),reject:s}),this.worker.postMessage({type:"teaql-browser-sqlite-request",requestId:i,operation:t,payload:e})})}async close(t){if(!this.closed)try{await this.request("close")}finally{this.closed=!0,this.worker.removeEventListener("message",this.onMessage),this.worker.removeEventListener("error",this.onError),t&&this.worker.terminate?.();const e=new Error("Browser SQLite worker is closed");for(const i of this.pending.values())i.reject(e);this.pending.clear()}}},Ve=class{constructor(t){this.transport=t}query(t,e=[]){return this.transport.request("query",{sql:t,values:e})}},Me=class le{constructor(e,i){this.transport=e,this.options=i,this.databaseKind="sqlite",this.accessTail=Promise.resolve()}static async open(e,i={}){const r={storage:i.storage??"memory",databaseName:Ke(i.databaseName??"teaql-browser.sqlite3"),terminateWorkerOnClose:i.terminateWorkerOnClose??!0},s=new je(e);return await s.request("open",r),new le(s,r)}identifier(e){return`"${Pe(e)}"`}placeholder(e){return"?"}contains(e,i){return`CAST(${e} AS TEXT) LIKE '%' || ${i} || '%'`}aggregateFunction(e){return Oe(e)}encode(e,i){return e==null?e:i?.logicalType==="json"&&typeof e!="string"?JSON.stringify(e):i?.logicalType==="boolean"?e?1:0:e instanceof Date?e.toISOString():e}async exclusive(e){const i=this.accessTail;let r;this.accessTail=new Promise(s=>{r=s}),await i;try{return await e()}finally{r()}}query(e,i=[]){return this.exclusive(()=>this.transport.request("query",{sql:e,values:i}))}async*stream(e,i=[]){const r=await this.query(e,i);for(const s of r.rows)yield s}transaction(e){return this.exclusive(async()=>{const i=new Ve(this.transport);await i.query("BEGIN IMMEDIATE");try{const r=await e(i);return await i.query("COMMIT"),r}catch(r){try{await i.query("ROLLBACK")}catch{}throw r}})}async ensureSchema(e){for(const i of Object.values(e)){const r=this.identifier(i.table);await this.query(`CREATE TABLE IF NOT EXISTS ${r} ("id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)`);const s=await this.query(`PRAGMA table_info(${r})`),n=new Set(s.rows.map(o=>String(o.name)));for(const[o,u]of Object.entries(i.columns))o==="id"||o==="version"||n.has(u.columnName)||await this.query(`ALTER TABLE ${r} ADD COLUMN ${this.identifier(u.columnName)} ${Ue(u.logicalType)}${u.nullable===!1?" NOT NULL":""}`)}for(const i of Le(e))await this.query(`CREATE INDEX IF NOT EXISTS ${this.identifier(i.name)} ON ${this.identifier(i.table)} (${this.identifier(i.foreignColumn)}, ${this.identifier(i.idColumn)} DESC)`);await this.query("CREATE TABLE IF NOT EXISTS teaql_id_space (type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)")}async nextId(e,i){for(let r=1;r<=100;r+=1){const s=await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[i]);if(!s.rowCount){try{if((await e.query("INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)",[i])).rowCount===1)return"1"}catch(a){if(!(await e.query("SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?",[i])).rowCount)throw a}continue}const n=Number(s.rows[0].id),o=n+1,u=await e.query("UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?",[o,i,n]);if(u.rowCount===1)return String(o);if(u.rowCount!==0)throw new Error(`ID space update for ${i} changed ${u.rowCount} rows`)}throw new Error(`Unable to allocate ID for ${i} after 100 optimistic-lock attempts`)}ensureIdFloor(e,i,r){return Te(e,s=>this.placeholder(s),i,r)}reset(){return this.exclusive(()=>this.transport.request("reset",this.options))}close(){return this.exclusive(()=>this.transport.close(this.options.terminateWorkerOnClose))}},We=class ce extends Ne{constructor(e,i){super(e,i),this.browserDriver=e}static async open(e,i,r={}){return new ce(await Me.open(e,r),i)}get storage(){return this.browserDriver.options.storage}async reset(e){await this.browserDriver.reset(),this.invalidateSchemaState(),await e.ensureSchema()}};function Ue(t){return{boolean:"INTEGER",double:"REAL",decimal:"NUMERIC",date:"TEXT",datetime:"TEXT",json:"TEXT",integer:"INTEGER",text:"TEXT"}[t]}function Ke(t){const e=t.trim();if(!e||e.includes("/")||e.includes("\\")||e==="."||e==="..")throw new TypeError("Browser SQLite databaseName must be a simple file name");return e}var Qe={schema:"teaql.i18n/v1",defaultLocale:"en",locales:{en:{messages:{"checker.required":"The {location} is required","checker.min":"The {location} should be equal or greater than {system}, but input is {input}","checker.max":"The {location} should be equal or less than {system}, but input is {input}","checker.minLength":"The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}","checker.maxLength":"The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}"},vocabulary:{}},"zh-CN":{messages:{"checker.required":"{location} 是必填项","checker.min":"{location} 应该大于等于 {system},但输入值为 {input}","checker.max":"{location} 应该小于等于 {system},但输入值为 {input}","checker.minLength":"{location} 的长度应大于等于 {system},但实际长度为 {input_len}","checker.maxLength":"{location} 的长度应小于等于 {system},但实际长度为 {input_len}"},vocabulary:{}},"zh-TW":{messages:{"checker.required":"{location} 是必填的","checker.min":"{location} 應該等於或大於 {system},但輸入為 {input}","checker.max":"{location} 應該等於或小於 {system},但輸入為 {input}","checker.minLength":"{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}","checker.maxLength":"{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}"},vocabulary:{}},ja:{messages:{"checker.required":"{location} は必須です","checker.min":"{location} は {system} 以上である必要があります。入力値は {input} です","checker.max":"{location} は {system} 以下である必要があります。入力値は {input} です","checker.minLength":"{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です","checker.maxLength":"{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です"},vocabulary:{}},ko:{messages:{"checker.required":"{location}은(는) 필수입니다","checker.min":"{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다","checker.max":"{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다","checker.minLength":"{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다","checker.maxLength":"{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다"},vocabulary:{}},de:{messages:{"checker.required":"{location} ist erforderlich","checker.min":"{location} muss mindestens {system} sein, aber die Eingabe ist {input}","checker.max":"{location} darf höchstens {system} sein, aber die Eingabe ist {input}","checker.minLength":"Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}","checker.maxLength":"Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}"},vocabulary:{}},fr:{messages:{"checker.required":"{location} est obligatoire","checker.min":"{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}","checker.max":"{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}","checker.minLength":"La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}","checker.maxLength":"La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}"},vocabulary:{}},es:{messages:{"checker.required":"{location} es requerido/a","checker.min":"{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}","checker.max":"{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}","checker.minLength":"La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}","checker.maxLength":"La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}"},vocabulary:{}},pt:{messages:{"checker.required":"{location} é obrigatório","checker.min":"{location} deve ser maior ou igual a {system}, mas a entrada é {input}","checker.max":"{location} deve ser menor ou igual a {system}, mas a entrada é {input}","checker.minLength":"O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}","checker.maxLength":"O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}"},vocabulary:{}},ar:{messages:{"checker.required":"{location} مطلوب","checker.min":"يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}","checker.max":"يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}","checker.minLength":"يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}","checker.maxLength":"يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}"},vocabulary:{}},th:{messages:{"checker.required":"{location} เป็นสิ่งจำเป็น","checker.min":"{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.max":"{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}","checker.minLength":"ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}","checker.maxLength":"ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}"},vocabulary:{}},id:{messages:{"checker.required":"{location} wajib diisi","checker.min":"{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}","checker.max":"{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}","checker.minLength":"Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}","checker.maxLength":"Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}"},vocabulary:{}},fil:{messages:{"checker.required":"Ang {location} ay kinakailangan","checker.min":"Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}","checker.max":"Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}","checker.minLength":"Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}","checker.maxLength":"Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}"},vocabulary:{}},uk:{messages:{"checker.required":"{location} є обов'язковим","checker.min":"{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}","checker.max":"{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}","checker.minLength":"Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}","checker.maxLength":"Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}"},vocabulary:{}},vi:{messages:{"checker.required":"{location} là bắt buộc","checker.min":"{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.max":"{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}","checker.minLength":"Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}","checker.maxLength":"Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}"},vocabulary:{}}}},ze=["en","zh-CN","zh-TW","ja","ko","de","fr","es","pt","ar","th","id","fil","uk","vi"],te=class extends Error{constructor(t){super(`Unsupported locale: ${t}`),this.localeCode=t}},Ge={"en-us":"en","en-gb":"en",zh:"zh-CN","zh-hans":"zh-CN","zh-sg":"zh-CN",cn:"zh-CN","zh-hant":"zh-TW","zh-hk":"zh-TW","zh-mo":"zh-TW",tw:"zh-TW","ja-jp":"ja","ko-kr":"ko","de-de":"de","fr-fr":"fr","es-mx":"es","pt-br":"pt","pt-pt":"pt","ar-sa":"ar","th-th":"th","id-id":"id",tl:"fil","fil-ph":"fil","uk-ua":"uk","vi-vn":"vi"};function He(t){if(typeof t!="string"||!t.trim())throw new te(t);const e=t.trim().replace(/_/g,"-").toLowerCase(),i=ze.find(s=>s.toLowerCase()===e);if(i)return i;const r=Ge[e];if(!r)throw new te(t);return r}var ie=class{constructor(e,i){if(this.data=e,this.fallback=i,e.schema!=="teaql.i18n/v1")throw new Error("Unsupported i18n schema");Object.keys(e.locales).forEach(He)}message(e,i){return this.data.locales[e]?.messages[i]??this.fallback?.data.locales[e]?.messages[i]??this.data.locales.en?.messages[i]??this.fallback?.data.locales.en?.messages[i]??i}translate(e,i){const s={required:"checker.required",min:"checker.min",max:"checker.max",min_str_len:"checker.minLength",min_length:"checker.minLength",max_str_len:"checker.maxLength",max_length:"checker.maxLength"}[e.ruleId.toLowerCase()]??`checker.${e.ruleId.toLowerCase()}`,n=String(e.inputValue),o=typeof e.inputValue=="string"?[...e.inputValue].length:0;return e.message=this.message(i,s).split("{location}").join(e.location.nativePath()).split("{system}").join(String(e.systemValue)).split("{input}").join(n).split("{input_len}").join(String(o)),e}};ie.builtin=new ie(Qe);var x=class extends Error{constructor(t){super(`Check failed: ${t.map(e=>e.message??`${e.ruleId}:${e.location}`).join("; ")}`),this.violations=t,this.name="CheckException"}};function Xe(t,e){const i=t.defaultDomainRoot,r=e.defaultDomainRoot;if(i&&r&&(i.entity!==r.entity||i.id!==r.id))throw new Error("Cannot compose Runtime Modules with different Default Domain Roots");const s=new Map;for(const n of[...t.constants??[],...e.constants??[]])s.set(`${n.entity}:${n.id}`,n);return{defaultDomainRoot:r??i,constants:[...s.values()],ensure:t.ensure&&e.ensure?async n=>{await t.ensure(n),await e.ensure(n)}:e.ensure??t.ensure}}var Ye=class he{constructor(e={},i={},r={}){this.schemas=Object.freeze({...e}),this.checkers=Object.freeze({...i}),this.bootstrap=Object.freeze({defaultDomainRoot:r.defaultDomainRoot,constants:Object.freeze([...r.constants??[]]),ensure:r.ensure})}and(e){return new he({...this.schemas,...e.schemas},{...this.checkers,...e.checkers},Xe(this.bootstrap,e.bootstrap))}},re=class de{constructor(e,i,r,s){this.enabledValue=e,this.cacheExpiredMillis=i,this.propagateValue=r,this.propagateCacheExpiredMillis=s}static enabled(e){return new de(!0,e,!1,0)}propagate(e){return this.propagateValue=!0,this.propagateCacheExpiredMillis=e,this}},Je=class W{constructor(e){this.hardLimitValue=1e4,this.filterCondition=null,this.limitValue=0,this.offsetValue=0,this.orderItems=[],this.selectItems=[],this.properties=[],this.joins=[],this.groupByItems=[],this.aggregateItems=[],this.facets=[],this.relations=[],this.relationAggregates=[],this.entity=e,Object.defineProperty(this,"hardLimitValue",{enumerable:!1,writable:!0,value:1e4}),Object.defineProperty(this,"continuousPageFetchOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"continuousPageRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationOptions",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"idSetPaginationRuntimeContext",{enumerable:!1,writable:!0,value:void 0}),Object.defineProperty(this,"topNProbeThreshold",{enumerable:!1,writable:!0,value:void 0})}comment(e){return this.commentText=e,this}purpose(e){return this.purposeText=e,this}facetBy(e,i,r,s=!0){return this.facets.push({facetName:e,relationName:i,query:r.toQuery(),includeAllFacets:s}),this}clone(){const e=new W(this.entity);return e.filterCondition=this.filterCondition,e.limitValue=this.limitValue,e.offsetValue=this.offsetValue,e.orderItems=[...this.orderItems],e.selectItems=[...this.selectItems],e.properties=[...this.properties],e.joins=[...this.joins],e.groupByItems=[...this.groupByItems],e.aggregateItems=this.aggregateItems.map(i=>({...i})),e.aggregationCache=this.aggregationCache,e.facets=this.facets.map(i=>({...i,query:i.query.clone()})),e.relations=this.relations.map(i=>({...i,query:i.query?.clone()})),e.relationAggregates=this.relationAggregates.map(i=>({...i,query:i.query.clone()})),e.commentText=this.commentText,e.purposeText=this.purposeText,e.idSetPaginationOptions=this.idSetPaginationOptions,e.idSetPaginationRuntimeContext=this.idSetPaginationRuntimeContext,e.topNProbeThreshold=this.topNProbeThreshold,e}filter(e){return this.filterCondition=e,this}limit(e){if(!Number.isSafeInteger(e)||e<1)throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.limitValue=e,this}optimizeForContinuousPageFetch(){return this.optimizeForContinuousPageFetchWith("default",600)}optimizeForContinuousPageFetchWith(e,i){if(!e?.trim())throw new Error("continuous page namespace must not be empty");if(!Number.isSafeInteger(i)||i<=0)throw new Error("continuous page ttlSeconds must be a positive integer");return this.continuousPageFetchOptions={namespace:e,ttlSeconds:i},this}bindContinuousPageRuntime(e){return this.continuousPageRuntimeContext=e,this}localContinuousPageOptions(){return this.continuousPageFetchOptions}localContinuousPageRuntime(){return this.continuousPageRuntimeContext}clearContinuousPageRuntime(){return this.continuousPageRuntimeContext=void 0,this}optimizePaginationWithIdSet(){return this.optimizePaginationWithIdSetConfig("default",600,3e6)}optimizePaginationWithIdSetConfig(e,i,r){if(!e?.trim())throw new Error("ID set namespace must not be empty");if(!Number.isSafeInteger(i)||i<=0)throw new Error("ID set ttlSeconds must be a positive integer");if(!Number.isSafeInteger(r)||r<=0)throw new Error("ID set maxIds must be a positive integer");return this.idSetPaginationOptions={namespace:e,ttlSeconds:i,maxIds:r},this}bindIdSetPaginationRuntime(e){return this.idSetPaginationRuntimeContext=e,this}localIdSetPaginationOptions(){return this.idSetPaginationOptions}localIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext}clearIdSetPaginationRuntime(){return this.idSetPaginationRuntimeContext=void 0,this}topNProbeParentThreshold(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("topNProbeParentThreshold must be a non-negative safe integer");return this.topNProbeThreshold=e,this}localTopNProbeParentThreshold(){return this.topNProbeThreshold}prepareForList(){if(!Number.isSafeInteger(this.offsetValue)||this.offsetValue<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");if(this.limitValue&&(!Number.isSafeInteger(this.limitValue)||this.limitValue<1))throw new Error("QUERY_INVALID_LIMIT: limit must be a positive safe integer");return this.applyListLimit(this.hardLimitValue),this}forExactCount(e="__teaql_total"){const i=new W(this.entity);return i.filterCondition=this.filterCondition,i.commentText=this.commentText,i.purposeText=this.purposeText,i.aggregate("Count","id",e),i}applyListLimit(e){if(this.limitValue||(this.limitValue=e),this.limitValue>e)throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${e}`);for(const i of this.relations)i.query?.applyListLimit(1e4)}offset(e){if(!Number.isSafeInteger(e)||e<0)throw new Error("QUERY_INVALID_OFFSET: offset must be a non-negative safe integer");return this.offsetValue=e,this}relation(e){return this.relations.push({name:e}),this}relationQuery(e,i,r="id",s="id",n=!0){return this.relations.push({name:e,query:i,localKey:r,foreignKey:s,many:n}),this}relationAggregate(e,i,r,s=!0){return this.relationAggregates.push({relationName:e,alias:i,query:r,singleResult:s}),this}order(e){return this.orderItems.push(e),this}select(e){return this.selectItems.push(...e),this}enableAggregationCacheFor(e){return this.aggregationCache=re.enabled(e),this}propagateAggregationCache(e){return this.aggregationCache||(this.aggregationCache=re.enabled(0)),this.aggregationCache.propagate(e),this}aggregate(e,i,r){return this.aggregateItems.push({function:e,field:i,alias:r}),this}groupBy(e){return this.groupByItems.push(e),this}},I=t=>`${t.entity}\0${typeof t.id}:${String(t.id)}`,A=class{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map}set(t,e,i){if(!e.trim())throw new TypeError("field is required");const r=I(t),s=this.changes.get(r)??{key:Object.freeze({...t}),values:{}};s.values[e]=i,this.changes.set(r,s)}snapshot(){return[...this.changes.values()].map(t=>({key:Object.freeze({...t.key}),values:Object.freeze({...t.values})}))}change(t){return Object.freeze({...this.changes.get(I(t))?.values??{}})}mergeFrom(t){if(t!==this){for(const e of t.snapshot())for(const[i,r]of Object.entries(e.values))this.set(e.key,i,r);for(const e of t.newKeys.values())this.markAsNew(e);for(const e of t.deletedKeys.values())this.markAsDeleted(e);for(const e of t.snapshotVersions())this.setOriginalVersion(e.key,e.version)}}snapshotVersions(){return[...this.originalVersions.values()]}rekey(t,e){const i=I(t),r=I(e);if(i===r)return;const s=this.changes.get(i);if(s){this.changes.delete(i);for(const[o,u]of Object.entries(s.values))this.set(e,o,u)}const n=this.originalVersions.get(i);n!==void 0&&(this.originalVersions.delete(i),this.originalVersions.set(r,{key:Object.freeze({...e}),version:n.version})),this.newKeys.delete(i)&&this.newKeys.set(r,Object.freeze({...e})),this.deletedKeys.delete(i)&&this.deletedKeys.set(r,Object.freeze({...e}))}clearEntity(t){const e=I(t);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e)}setOriginalVersion(t,e){this.originalVersions.set(I(t),{key:Object.freeze({...t}),version:e})}originalVersion(t){return this.originalVersions.get(I(t))?.version}markAsNew(t){this.newKeys.set(I(t),Object.freeze({...t}))}isNew(t){return this.newKeys.has(I(t))}markAsDeleted(t){const e=I(t);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...t}))}isDeleted(t){return this.deletedKeys.has(I(t))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear()}};function me(t){const e=t.split("_");return e[0]+e.slice(1).map(i=>i?i[0].toUpperCase()+i.slice(1):"").join("")}function Ze(t,e){if(e==="snake_case")return t;const i=me(t);return e==="camelCase"||!i?i:i[0].toUpperCase()+i.slice(1)}function et(t){return t.replace(/~/g,"~0").replace(/\//g,"~1")}var S=class L{constructor(e){this.segments=e}static root(){return new L([])}static property(e){return L.root().property(e)}property(e){return new L([...this.segments,{kind:"property",name:e}])}index(e){return new L([...this.segments,{kind:"index",index:e}])}prefixedBy(e){return new L([...e.segments,...this.segments])}modelPath(){return this.render(e=>e)}nativePath(){return this.render(me)}instancePath(e="camelCase"){return this.segments.map(i=>i.kind==="index"?String(i.index):et(Ze(i.name,e))).map(i=>`/${i}`).join("")}toString(){return this.nativePath()}render(e){let i="";for(const r of this.segments)r.kind==="index"?i+=`[${r.index}]`:i+=`${i?".":""}${e(r.name)}`;return i}},q=class U extends Array{static get[Symbol.species](){return Array}constructor(e=[],i={}){typeof e=="number"?super(e):super(...e),Object.setPrototypeOf(this,U.prototype),this.totalCount=i.totalCount,this.aggregations=i.aggregations??{},this.summary=i.summary??{},this.facets=i.facets??{},this.isLoaded=i.isLoaded??!0}static empty(){return new U([],{isLoaded:!1})}get data(){return this}withTotalCount(e){return this.totalCount=e,this}withFacet(e,i){return this.facets[e]=i,this}facet(e){return this.facets[e]}totalCountOrLength(){return this.totalCount??this.length}};function tt(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase()}function K(t){if(t&&typeof t=="object"){const e=t;return e.id??e.Id}return t}function it(t,e){const i=tt(e);for(const r of[e,`${e}Id`,i,`${i}_id`]){const s=K(t[r]);if(s!=null)return s}}async function pe(t,e,i,r){const s={};for(const n of r){let o;if(t.executeFacetMembership)o=await t.executeFacetMembership(e(i.clone()),n.relationName);else{const l=i.clone();l.facets=[],l.relations=[],l.orderItems=[],l.aggregateItems=[],l.groupByItems=[],l.offsetValue=0,l.limitValue=0,l.selectItems=[n.relationName];const m=await t.executeQuery(e(l));o=new Map;for(const d of m){const p=it(d,n.relationName);if(p==null)continue;const f=String(p);o.set(f,(o.get(f)??0)+1)}}const u=n.query.clone();u.facets=[];const a=u.aggregateItems.filter(l=>String(l.function).toLowerCase()==="count").map(l=>String(l.alias));u.aggregateItems=[],u.groupByItems=[];const h=(await t.executeQuery(e(u))).map(l=>{const m=o.get(String(K(l.id??l.Id)))??0,d={...l};for(const p of a)d[p]=m;return d}).filter(l=>n.includeAllFacets||o.has(String(K(l.id??l.Id))));s[n.facetName]=new q(h)}return s}class R extends Je{orderBy(e,i){return this.order({field:e,expr:null,direction:i==="desc"?"Desc":"Asc"})}relationQuery(e,i,r="id",s="id",n=!0){return this.relations.push({name:e,query:i,localKey:r,foreignKey:s,many:n}),this}}class b{static teaqlTemporaryId=0;id;title;description;platform;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--b.teaqlTemporaryId,writable:!0,enumerable:!1}),e){const r={...e};Object.assign(this,r),e.platform&&typeof e.platform=="object"&&(this.platform=e.platform instanceof v?e.platform:v.fromRecord(e.platform),this.markLoaded("platform"))}const i=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(i):this.version!==void 0&&this._root.setOriginalVersion(i,Number(this.version))}teaqlEntityKey(){return{entity:"WorkItem",id:this._ledgerId}}teaqlAttachRoot(e){return this._root!==e&&(e.mergeFrom(this._root),this._root=e),this}static fromRecord(e,i){const r=new b(e);return i?r.teaqlAttachRoot(i):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const i of e)this._loadedFields.add(i);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new b({id:String(e)})}static teaqlBootstrapNew(e){return new b().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const i=e.requireResource("dataService");return i.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,i),this.teaqlSaveWithinGraph(e,i)))}teaqlPreflightGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"title",canonical:"title"},{member:"description",canonical:"description"},{member:"platform",canonical:"platform"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new x([{ruleId:"invalid_type",location:S.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}i.preflightMutation({entity:"WorkItem",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root})}async teaqlSaveWithinGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"WorkItem",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},o=await i.executeMutation(n);for(const[h,l]of Object.entries(n.payload))h!=="id"&&h!=="version"&&this._root.set(this.teaqlEntityKey(),h,l);if(!o.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},a=this.teaqlEntityKey();Object.assign(this,o.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();return this._root.rekey(a,c),i.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(c,a)}),this._loadedFields=new Set(Object.keys(o.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update"),i.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.setOriginalVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,title:this.title,description:this.description,platform:this.platform,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateTitle(e){return this.title=e,this.markLoaded("title"),this._root.set(this.teaqlEntityKey(),"title",e),this}updateDescription(e){return this.description=e,this.markLoaded("description"),this._root.set(this.teaqlEntityKey(),"description",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}updatePlatform(e){return this.platform=e?.id??e,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}}class v{static teaqlTemporaryId=0;id;name;version;constructor(e){if(Object.defineProperty(this,"_action",{value:e&&e.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!e||!e.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(e||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:e?.id??--v.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_workItemList",{value:[],writable:!0,enumerable:!1}),e){const r={...e};delete r.workItemList,Object.assign(this,r),Array.isArray(e.workItemList)&&(this._workItemList=e.workItemList.map(s=>s instanceof b?s:b.fromRecord(s)),this.markLoaded("workItemList"))}const i=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(i):this.version!==void 0&&this._root.setOriginalVersion(i,Number(this.version))}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(e){this._root!==e&&(e.mergeFrom(this._root),this._root=e);for(const i of this._workItemList)i.teaqlAttachRoot(e);return this}static fromRecord(e,i){const r=new v(e);return i?r.teaqlAttachRoot(i):r}isLoaded(e){return this._fullyLoaded||this._loadedFields.has(e)}markLoaded(...e){for(const i of e)this._loadedFields.add(i);return this}markLoadedOnly(...e){return this._fullyLoaded=!1,this._loadedFields=new Set(e),this}static refer(e){return new v({id:String(e)})}static teaqlBootstrapNew(e){return new v().updateId(String(e))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(e){if(!e?.trim())throw new Error("Security audit failure: auditAs() requires a non-empty reason");return this._comment=e,this}async save(e){const i=e.requireResource("dataService");return i.executeGraphSave(async()=>(this.teaqlPreflightGraph(e,i),this.teaqlSaveWithinGraph(e,i)))}teaqlPreflightGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action;if(r==="Update"){const s=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(n=>!this.isLoaded(n.member));if(s)throw new x([{ruleId:"invalid_type",location:S.property(s.canonical),message:"Mutation requires a fully loaded entity"}])}i.preflightMutation({entity:"Platform",action:r,payload:r==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root});for(const[s,n]of this._workItemList.entries()){n.teaqlAttachRoot(this._root),n.updatePlatform(this),n.auditAs(this._comment);try{n.teaqlPreflightGraph(e,i)}catch(o){if(!(o instanceof x))throw o;const u=S.property("work_item_list").index(s);throw new x(o.violations.map(a=>({...a,location:a.location.prefixedBy(u)})))}}}async teaqlSaveWithinGraph(e,i){if(!this._comment?.trim())throw new Error("Security audit failure: auditAs() must be called before save()");const r=this._action,s=this._root.change(this.teaqlEntityKey()),n={entity:"Platform",action:this._action,payload:r==="Update"?s:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},o=await i.executeMutation(n);for(const[h,l]of Object.entries(n.payload))h!=="id"&&h!=="version"&&this._root.set(this.teaqlEntityKey(),h,l);if(!o.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const u={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded},a=this.teaqlEntityKey();Object.assign(this,o.persistedRecord),this._ledgerId=this.id??this._ledgerId;const c=this.teaqlEntityKey();this._root.rekey(a,c),i.afterGraphRollback(()=>{Object.assign(this,u.payload),this._ledgerId=u.ledgerId,this._action=u.action,this._loadedFields=u.loadedFields,this._fullyLoaded=u.fullyLoaded,this._root.rekey(c,a)}),this._loadedFields=new Set(Object.keys(o.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update");for(const[h,l]of this._workItemList.entries()){l.teaqlAttachRoot(this._root),l.updatePlatform(this),l.auditAs(this._comment);try{await l.teaqlSaveWithinGraph(e,e.requireResource("dataService"))}catch(m){if(!(m instanceof x))throw m;const d=S.property("work_item_list").index(h);throw new x(m.violations.map(p=>({...p,location:p.location.prefixedBy(d)})))}}return i.afterGraphCommit(()=>{this._root.clearEntity(c),this.version!==void 0&&this._root.setOriginalVersion(c,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(e){return this.id=e,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",e),this}updateName(e){return this.name=e,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",e),this}updateVersion(e){return this.version=e,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",e),this}workItemList(){return this._workItemList}}class se{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new R("Platform"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new rt(i=>this.executeForListInternal(i),i=>this.executeForRowsInternal(i),(i,r,s)=>this.executeForPageInternal(i,r,s),(i,r)=>this.executeForStreamInternal(i,r),()=>this.limit(1),i=>this.comment(i),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,i){return this.query.optimizeForContinuousPageFetchWith(e,i),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,i,r){return this.query.optimizePaginationWithIdSetConfig(e,i,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectWorkItemListWith(e){return this.query.relationQuery("workItemList",e.toQuery(),"id","platform",!0),this}haveWorkItems(){return this.withWorkItemListMatching({toQuery:()=>new R("WorkItem")})}haveNoWorkItems(){return this.withoutWorkItemListMatching({toQuery:()=>new R("WorkItem")})}withWorkItemListMatching(e){return this.filters.push({id:{$inSubquery:{query:e.toQuery(),field:"platform"}}}),this}withoutWorkItemListMatching(e){return this.filters.push({id:{$notInSubquery:{query:e.toQuery(),field:"platform"}}}),this}countWorkItems(){return this.countWorkItemsAs("countWorkItems")}countWorkItemsAs(e){const i=new R("WorkItem").filter({version:{$gte:1}});return this.countWorkItemsWith(e,{toQuery:()=>i})}countWorkItemsWith(e,i){return i.toQuery().aggregate("Count","id",e),this.query.relationAggregate("workItemList",e,i.toQuery(),!0),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,i){return this.filters.push({id:{$between:[e,i]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(e){return this.filters.push({name:{$contains:e}}),this}withNameIs(e){return this.filters.push({name:{$eq:e}}),this}withNameIsNot(e){return this.filters.push({name:{$ne:e}}),this}withNameIn(...e){return this.filters.push({name:{$in:e}}),this}withNameNotIn(...e){return this.filters.push({name:{$notIn:e}}),this}withNameGreaterThan(e){return this.filters.push({name:{$gt:e}}),this}withNameGreaterThanOrEqualTo(e){return this.filters.push({name:{$gte:e}}),this}withNameLessThan(e){return this.filters.push({name:{$lt:e}}),this}withNameLessThanOrEqualTo(e){return this.filters.push({name:{$lte:e}}),this}withNameBetween(e,i){return this.filters.push({name:{$between:[e,i]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(e){return this.filters.push({name:{$notContains:e}}),this}withNameStartingWith(e){return this.filters.push({name:{$startsWith:e}}),this}withNameNotStartingWith(e){return this.filters.push({name:{$notStartsWith:e}}),this}withNameEndingWith(e){return this.filters.push({name:{$endsWith:e}}),this}withNameNotEndingWith(e){return this.filters.push({name:{$notEndsWith:e}}),this}withNameSoundingLike(e){return this.filters.push({name:{$soundLike:e}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,i){return this.filters.push({version:{$between:[e,i]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(e){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),r=await i.executeQuery(e.prepareQuery(this.query)),s=new A,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:r.map(a=>a instanceof v?a:v.fromRecord(a,s)),u=new q(o);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await pe(i,a=>e.prepareQuery(a),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService");return new q(await i.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,i,r){this.ensureIntent(),this.query.offset(i).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),a=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:o??await s.executeCount(this.query),c=new A,h=new q(u.map(l=>l instanceof v?l:v.fromRecord(l,c)));return h.totalCount=a,{data:h,totalCount:a,offset:i,limit:r}}async*executeForStreamInternal(e,i){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new A;for await(const n of r.executeForStream(this.query,i))for(const o of n)yield o instanceof v?o:v.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class rt{constructor(e,i,r,s,n,o,u){this.execute=e,this.executeRows=i,this.page=r,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new v}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,i,r){return this.ensureIntent(),this.page(e,i,r)}executeForStream(e,i=1e3){return this.ensureIntent(),this.stream(e,i)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class ne{query;filters=[];_purpose;_comment;constructor(e=!1){this.query=new R("WorkItem"),this.filters.push({version:{$gte:1}}),e?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(e){return this.query.comment(e),this._comment=e,this}purpose(e){return this.query.purpose(e),this._purpose=e,new st(i=>this.executeForListInternal(i),i=>this.executeForRowsInternal(i),(i,r,s)=>this.executeForPageInternal(i,r,s),(i,r)=>this.executeForStreamInternal(i,r),()=>this.limit(1),i=>this.comment(i),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(e,i){return this.query.optimizeForContinuousPageFetchWith(e,i),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(e,i,r){return this.query.optimizePaginationWithIdSetConfig(e,i,r),this}topNProbeParentThreshold(e){return this.query.topNProbeParentThreshold(e),this}limit(e){return this.query.limit(e),this}offset(e){return this.query.offset(e),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(e=>!("version"in e)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","title","description","platform","version"]),this}selectId(){return this.query.select(["id"]),this}selectTitle(){return this.query.select(["title"]),this}selectDescription(){return this.query.select(["description"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(e){return this.query.select(["platform"]),this.query.relationQuery("platform",e.toQuery(),"platform","id",!1),this}withPlatformMatching(e){return this.filters.push({platform:{$inSubquery:{query:e.toQuery(),field:"id"}}}),this}withoutPlatformMatching(e){return this.filters.push({platform:{$notInSubquery:{query:e.toQuery(),field:"id"}}}),this}withIdIs(e){return this.filters.push({id:{$eq:e}}),this}withIdIsNot(e){return this.filters.push({id:{$ne:e}}),this}withIdIn(...e){return this.filters.push({id:{$in:e}}),this}withIdNotIn(...e){return this.filters.push({id:{$notIn:e}}),this}withIdGreaterThan(e){return this.filters.push({id:{$gt:e}}),this}withIdGreaterThanOrEqualTo(e){return this.filters.push({id:{$gte:e}}),this}withIdLessThan(e){return this.filters.push({id:{$lt:e}}),this}withIdLessThanOrEqualTo(e){return this.filters.push({id:{$lte:e}}),this}withIdBetween(e,i){return this.filters.push({id:{$between:[e,i]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withTitleContaining(e){return this.filters.push({title:{$contains:e}}),this}withTitleIs(e){return this.filters.push({title:{$eq:e}}),this}withTitleIsNot(e){return this.filters.push({title:{$ne:e}}),this}withTitleIn(...e){return this.filters.push({title:{$in:e}}),this}withTitleNotIn(...e){return this.filters.push({title:{$notIn:e}}),this}withTitleGreaterThan(e){return this.filters.push({title:{$gt:e}}),this}withTitleGreaterThanOrEqualTo(e){return this.filters.push({title:{$gte:e}}),this}withTitleLessThan(e){return this.filters.push({title:{$lt:e}}),this}withTitleLessThanOrEqualTo(e){return this.filters.push({title:{$lte:e}}),this}withTitleBetween(e,i){return this.filters.push({title:{$between:[e,i]}}),this}withTitleIsKnown(){return this.filters.push({title:{$isNull:!1}}),this}withTitleIsUnknown(){return this.filters.push({title:{$isNull:!0}}),this}withTitleNotContaining(e){return this.filters.push({title:{$notContains:e}}),this}withTitleStartingWith(e){return this.filters.push({title:{$startsWith:e}}),this}withTitleNotStartingWith(e){return this.filters.push({title:{$notStartsWith:e}}),this}withTitleEndingWith(e){return this.filters.push({title:{$endsWith:e}}),this}withTitleNotEndingWith(e){return this.filters.push({title:{$notEndsWith:e}}),this}withTitleSoundingLike(e){return this.filters.push({title:{$soundLike:e}}),this}withDescriptionContaining(e){return this.filters.push({description:{$contains:e}}),this}withDescriptionIs(e){return this.filters.push({description:{$eq:e}}),this}withDescriptionIsNot(e){return this.filters.push({description:{$ne:e}}),this}withDescriptionIn(...e){return this.filters.push({description:{$in:e}}),this}withDescriptionNotIn(...e){return this.filters.push({description:{$notIn:e}}),this}withDescriptionGreaterThan(e){return this.filters.push({description:{$gt:e}}),this}withDescriptionGreaterThanOrEqualTo(e){return this.filters.push({description:{$gte:e}}),this}withDescriptionLessThan(e){return this.filters.push({description:{$lt:e}}),this}withDescriptionLessThanOrEqualTo(e){return this.filters.push({description:{$lte:e}}),this}withDescriptionBetween(e,i){return this.filters.push({description:{$between:[e,i]}}),this}withDescriptionIsKnown(){return this.filters.push({description:{$isNull:!1}}),this}withDescriptionIsUnknown(){return this.filters.push({description:{$isNull:!0}}),this}withDescriptionNotContaining(e){return this.filters.push({description:{$notContains:e}}),this}withDescriptionStartingWith(e){return this.filters.push({description:{$startsWith:e}}),this}withDescriptionNotStartingWith(e){return this.filters.push({description:{$notStartsWith:e}}),this}withDescriptionEndingWith(e){return this.filters.push({description:{$endsWith:e}}),this}withDescriptionNotEndingWith(e){return this.filters.push({description:{$notEndsWith:e}}),this}withDescriptionSoundingLike(e){return this.filters.push({description:{$soundLike:e}}),this}filterByPlatform(e){return this.filters.push({platform:{$eq:e}}),this}filterByPlatformIn(...e){return this.filters.push({platform:{$in:e}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withVersionIs(e){return this.filters.push({version:{$eq:e}}),this}withVersionIsNot(e){return this.filters.push({version:{$ne:e}}),this}withVersionIn(...e){return this.filters.push({version:{$in:e}}),this}withVersionNotIn(...e){return this.filters.push({version:{$notIn:e}}),this}withVersionGreaterThan(e){return this.filters.push({version:{$gt:e}}),this}withVersionGreaterThanOrEqualTo(e){return this.filters.push({version:{$gte:e}}),this}withVersionLessThan(e){return this.filters.push({version:{$lt:e}}),this}withVersionLessThanOrEqualTo(e){return this.filters.push({version:{$lte:e}}),this}withVersionBetween(e,i){return this.filters.push({version:{$between:[e,i]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByTitleAscending(){return this.query.orderBy("title","asc"),this}orderByTitleDescending(){return this.query.orderBy("title","desc"),this}orderByDescriptionAscending(){return this.query.orderBy("description","asc"),this}orderByDescriptionDescending(){return this.query.orderBy("description","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this}countAs(e){return this.query.aggregate("Count","id",e),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(e){return this.query.groupBy("id"),this}groupByTitle(){return this.query.groupBy("title"),this}groupByTitleAs(e){return this.query.groupBy("title"),this}groupByDescription(){return this.query.groupBy("description"),this}groupByDescriptionAs(e){return this.query.groupBy("description"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(e){return this.query.groupBy("platform"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(e){return this.query.groupBy("version"),this}facetByPlatformAs(e,i,r=!0){return this.query.facetBy(e,"platform",i,r),this}async executeForListInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService"),r=await i.executeQuery(e.prepareQuery(this.query)),s=new A,n=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,o=n?[]:r.map(a=>a instanceof b?a:b.fromRecord(a,s)),u=new q(o);return n&&r[0]&&Object.assign(u.aggregations,r[0]),this.query.facets.length>0&&(u.facets=await pe(i,a=>e.prepareQuery(a),this.query,this.query.facets)),u}async executeForRowsInternal(e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=e.requireResource("dataService");return new q(await i.executeQuery(e.prepareQuery(this.query)))}async executeForPageInternal(e,i,r){this.ensureIntent(),this.query.offset(i).limit(r),this.filters.length>0&&this.query.filter({$and:this.filters});const s=e.requireResource("dataService"),n=this.query.localIdSetPaginationOptions()!==void 0,o=n?void 0:await s.executeCount(this.query),u=await s.executeQuery(e.prepareQuery(this.query)),a=n&&e.idSetPaginationCountAccuracy==="EXACT"?e.idSetPaginationCount:o??await s.executeCount(this.query),c=new A,h=new q(u.map(l=>l instanceof b?l:b.fromRecord(l,c)));return h.totalCount=a,{data:h,totalCount:a,offset:i,limit:r}}async*executeForStreamInternal(e,i){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=e.requireResource("dataService"),s=new A;for await(const n of r.executeForStream(this.query,i))for(const o of n)yield o instanceof b?o:b.fromRecord(o,s)}ensureIntent(){if(!this._comment?.trim())throw new Error("Security audit failure: non-empty comment() is required before execution");if(!this._purpose?.trim())throw new Error("Security audit failure: non-empty purpose() is required before execution")}}class st{constructor(e,i,r,s,n,o,u){this.execute=e,this.executeRows=i,this.page=r,this.stream=s,this.limitOne=n,this.addComment=o,this.ensureIntent=u}execute;executeRows;page;stream;limitOne;addComment;ensureIntent;comment(e){return this.addComment(e),this}newEntity(e){return this.ensureIntent(),new b}executeForList(e){return this.ensureIntent(),this.execute(e)}executeForRows(e){return this.ensureIntent(),this.executeRows(e)}executeForPage(e,i,r){return this.ensureIntent(),this.page(e,i,r)}executeForStream(e,i=1e3){return this.ensureIntent(),this.stream(e,i)}async executeForOne(e){return this.limitOne(),(await this.executeForList(e))[0]}}class Q{static platforms(){return new se(!1)}static platformsWithMinimalFields(){return new se(!0)}static workItems(){return new ne(!1)}static workItemsWithMinimalFields(){return new ne(!0)}}const fe={Platform:{table:"platform_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}};async function nt(t){let e=(await Q.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(t))[0];e||(e=v.teaqlBootstrapNew("1"),e.updateName("Runtime Example"),await e.auditAs("create generated Domain Root Platform").save(t)),t.withActiveRoot({entity:"Platform",id:e.id})}const ut=new Ye(fe,{Platform:{checkAndFix(t,e,i){t.getResource("fixTime"),(e.action==="Create"&&e.payload.name===void 0||e.payload.name===null)&&i.push({ruleId:"required",location:S.property("name")}),e.payload.name!=null&&[...String(e.payload.name)].length>100&&i.push({ruleId:"max_length",location:S.property("name"),inputValue:e.payload.name,systemValue:100})}},WorkItem:{checkAndFix(t,e,i){t.getResource("fixTime"),(e.action==="Create"&&e.payload.title===void 0||e.payload.title===null)&&i.push({ruleId:"required",location:S.property("title")}),e.payload.title!=null&&!([...String(e.payload.title)].length>=1)&&i.push({ruleId:"min_length",location:S.property("title"),inputValue:e.payload.title,systemValue:1}),e.payload.title!=null&&[...String(e.payload.title)].length>80&&i.push({ruleId:"max_length",location:S.property("title"),inputValue:e.payload.title,systemValue:80}),e.payload.description!=null&&[...String(e.payload.description)].length>100&&i.push({ruleId:"max_length",location:S.property("description"),inputValue:e.payload.description,systemValue:100}),(e.action==="Create"&&e.payload.platform===void 0||e.payload.platform===null)&&i.push({ruleId:"required",location:S.property("platform")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Runtime Example"}},constants:[],ensure:nt}),z=document.querySelector("#status"),ot=document.querySelector("#result"),N=document.querySelector("#persist"),at=document.querySelector("#opfs-note"),V=document.querySelector("#reset");let $;const P=globalThis.crossOriginIsolated&&typeof navigator.storage?.getDirectory=="function",ge=localStorage.getItem("teaql-browser-storage")==="opfs",Ee=ge&&P?"opfs":"memory";ge&&!P&&localStorage.removeItem("teaql-browser-storage");N.checked=Ee==="opfs";N.disabled=!P;P||(at.textContent="(unavailable on this static host; memory mode remains fully browser-local)");async function lt(t){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),i=await We.open(e,{...fe},{storage:t,databaseName:"teaql-browser-example.sqlite3"});i.install(ut);const r=new ae().insertResource("dataService",i);return i.setUserContext(r),await r.ensureSchema(),{client:i,context:r}}async function ye({context:t}){if(!(await Q.workItemsWithMinimalFields().comment("what: detect existing browser demo records").purpose("why: keep generated mutation bootstrap idempotent").executeForList(t)).length)for(const i of["Evaluate semantic model","Generate typed library","Verify browser runtime"])await new b().updateTitle(i).updatePlatform("1").auditAs("seed deterministic browser demo data").save(t)}async function we(t){const e=await Q.workItems().selectTitle().orderByIdAscending().limit(20).comment("what: load browser-local work items").purpose("why: prove the generated Q API runs without a backend").executeForList(t.context);ot.textContent=JSON.stringify(e,null,2),z.textContent=`${t.client.storage.toUpperCase()} · ${e.length} rows · ready`}async function Ce(t){z.textContent=`Opening ${t.toUpperCase()} SQLite/WASM…`;const e=$;$=void 0,await e?.client.close();const i=await lt(t);$=i,await ye(i),await we(i)}N.addEventListener("change",()=>{const t=N.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",t),Ce(t).catch(G)});V.addEventListener("click",async()=>{if($){V.disabled=!0;try{await $.client.reset($.context),await ye($),await we($)}catch(t){G(t)}finally{V.disabled=!1}}});function G(t){const e=t instanceof Error?t:new Error(String(t));z.textContent=`${e.name}: ${e.message}`}Ce(Ee).catch(G); diff --git a/dist/assets/index-inj2slTy.css b/dist/assets/index-inj2slTy.css deleted file mode 100644 index 8a15c8cb5bb0fef5d11ec596f176f905a1a9aced..0000000000000000000000000000000000000000 --- a/dist/assets/index-inj2slTy.css +++ /dev/null @@ -1 +0,0 @@ -:root{font:16px/1.5 Inter,system-ui,sans-serif;color:#e8edf5;background:#090b10;color-scheme:dark}body{margin:0}main{width:min(1120px,calc(100% - 40px));margin:6vh auto}.eyebrow{color:#d9ff52;font-size:12px;font-weight:800;letter-spacing:.16em}h1{margin:8px 0;font-size:clamp(36px,7vw,68px);letter-spacing:-.05em}.controls{display:flex;gap:18px;align-items:center;margin:32px 0}button,select{border:0;border-radius:5px;padding:10px 14px;font:inherit;font-weight:700}button{background:#d9ff52;color:#111;cursor:pointer}button:disabled{cursor:wait;opacity:.55}select{background:#202630;color:#e8edf5}#status{color:#aab4c4}.query-panel,.response-panel{margin-top:22px;border:1px solid #2b323e;border-radius:10px;background:#11151c;overflow:hidden}.query-toolbar,.response-heading{display:flex;gap:12px;align-items:center;padding:14px 16px;border-bottom:1px solid #2b323e}.query-toolbar label{color:#aab4c4;font-size:13px;font-weight:800;text-transform:uppercase;letter-spacing:.08em}.query-toolbar .run{margin-left:auto;min-width:120px}textarea{box-sizing:border-box;width:100%;min-height:330px;resize:vertical;border:0;outline:0;padding:22px;background:#0c1016;color:#d9ff52;font:15px/1.65 ui-monospace,SFMono-Regular,Menlo,monospace;tab-size:2}.hint{margin:0;padding:10px 16px;border-top:1px solid #2b323e;color:#7f8a9a;font-size:13px}.response-heading{justify-content:space-between}.response-heading h2{margin:0;font-size:18px}.response-heading span{color:#8c98a8;font:12px ui-monospace,monospace}pre{box-sizing:border-box;min-height:360px;margin:0;padding:22px;overflow:auto;background:#11151c;color:#c6d1df;font-size:14px}@media(max-width:640px){main{width:min(100% - 24px,1120px);margin:24px auto}.controls,.query-toolbar{align-items:stretch;flex-direction:column}.query-toolbar .run{margin-left:0}} diff --git a/dist/assets/main-gHLGx1pH.js b/dist/assets/main-gHLGx1pH.js new file mode 100644 index 0000000000000000000000000000000000000000..5de35f55d321681eb889d38d979c8068d7a7b040 --- /dev/null +++ b/dist/assets/main-gHLGx1pH.js @@ -0,0 +1,102 @@ +import{S as T,m as Te,a as ie,e as de,O as R,B as Qe,b as $e,R as Re,U as Be,D as Fe,c as ke,M as We}from"./dynamic-search-BBmdgl4H.js";/* empty css */const C=t=>({columnName:t,modelName:t,logicalType:"integer",decode:"string"}),y=t=>({columnName:t,modelName:t,logicalType:"text",decode:"native"}),ze=t=>({columnName:t,modelName:t,logicalType:"date",decode:"date"}),K=t=>({columnName:t,modelName:t,logicalType:"datetime",decode:"date"}),I=(t,e="decimal")=>({columnName:t,modelName:t,logicalType:e,decode:"number"}),f=Object.freeze({PENDING_PAYMENT:"1001",PAID:"1002",SHIPPED:"1003",DELIVERED:"1004",CANCELLED:"1005"}),_e=[{entity:"OrderStatus",id:f.PENDING_PAYMENT,values:{name:"Pending payment",code:"PENDING_PAYMENT",color:"#D97706",displayOrder:10}},{entity:"OrderStatus",id:f.PAID,values:{name:"Paid",code:"PAID",color:"#2563EB",displayOrder:20}},{entity:"OrderStatus",id:f.SHIPPED,values:{name:"Shipped",code:"SHIPPED",color:"#16A34A",displayOrder:30}},{entity:"OrderStatus",id:f.DELIVERED,values:{name:"Delivered",code:"DELIVERED",color:"#047857",displayOrder:40}},{entity:"OrderStatus",id:f.CANCELLED,values:{name:"Cancelled",code:"CANCELLED",color:"#9F1239",displayOrder:50}}],ce={Platform:{table:"platform_data",columns:{id:C("id"),name:y("name"),code:y("code"),region:y("region"),currency:y("currency"),version:I("version","integer")},relations:{customerList:{targetEntity:"Customer",localKey:"id",foreignKey:"platformId",many:!0},orderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"platformId",many:!0}}},Customer:{table:"customer_data",columns:{id:C("id"),name:y("name"),email:y("email"),city:y("city"),tier:y("tier"),platformId:C("platform_id"),version:I("version","integer")},relations:{platform:{targetEntity:"Platform",localKey:"platformId",foreignKey:"id",many:!1},orderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"customerId",many:!0}}},CustomerOrder:{table:"customer_order_data",columns:{id:C("id"),orderNumber:y("order_number"),orderDate:ze("order_date"),status:C("status_id"),totalAmount:I("total_amount"),currency:y("currency"),customerId:C("customer_id"),platformId:C("platform_id"),version:I("version","integer")},relations:{platform:{targetEntity:"Platform",localKey:"platformId",foreignKey:"id",many:!1},customer:{targetEntity:"Customer",localKey:"customerId",foreignKey:"id",many:!1},status:{targetEntity:"OrderStatus",localKey:"status",foreignKey:"id",many:!1},itemList:{targetEntity:"OrderItem",localKey:"id",foreignKey:"orderId",many:!0},paymentList:{targetEntity:"Payment",localKey:"id",foreignKey:"orderId",many:!0},shipmentList:{targetEntity:"Shipment",localKey:"id",foreignKey:"orderId",many:!0}}},OrderStatus:{table:"order_status_data",columns:{id:C("id"),name:y("name"),code:y("code"),color:y("color"),displayOrder:I("display_order","integer"),version:I("version","integer")},relations:{orderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"status",many:!0}}},OrderItem:{table:"order_item_data",columns:{id:C("id"),orderId:C("order_id"),productName:y("product_name"),sku:y("sku"),quantity:I("quantity","integer"),unitPrice:I("unit_price"),lineAmount:I("line_amount"),version:I("version","integer")},relations:{order:{targetEntity:"CustomerOrder",localKey:"orderId",foreignKey:"id",many:!1}}},Payment:{table:"payment_data",columns:{id:C("id"),orderId:C("order_id"),provider:y("provider"),status:y("status"),amount:I("amount"),currency:y("currency"),transactionId:y("transaction_id"),paidAt:K("paid_at"),version:I("version","integer")},relations:{order:{targetEntity:"CustomerOrder",localKey:"orderId",foreignKey:"id",many:!1}}},Shipment:{table:"shipment_data",columns:{id:C("id"),orderId:C("order_id"),carrier:y("carrier"),status:y("status"),trackingNumber:y("tracking_number"),shipToCity:y("ship_to_city"),shippedAt:K("shipped_at"),deliveredAt:K("delivered_at"),version:I("version","integer")},relations:{order:{targetEntity:"CustomerOrder",localKey:"orderId",foreignKey:"id",many:!1}}}},he=[{entity:"Platform",id:"1",payload:{name:"TeaQL Store",code:"TEAQL-CN",region:"China",currency:"CNY"}},{entity:"Platform",id:"2",payload:{name:"TeaQL Global",code:"TEAQL-GLOBAL",region:"Global",currency:"USD"}},{entity:"Customer",id:"101",payload:{name:"Lin Xiao",email:"lin.xiao@example.com",city:"Shanghai",tier:"GOLD",platformId:"1"}},{entity:"Customer",id:"102",payload:{name:"Zhou Ran",email:"zhou.ran@example.com",city:"Hangzhou",tier:"SILVER",platformId:"1"}},{entity:"Customer",id:"103",payload:{name:"Maya Patel",email:"maya.patel@example.com",city:"Singapore",tier:"GOLD",platformId:"2"}},{entity:"Customer",id:"104",payload:{name:"Lucas Martin",email:"lucas.martin@example.com",city:"Paris",tier:"SILVER",platformId:"2"}},{entity:"Customer",id:"105",payload:{name:"Wang Ning",email:"wang.ning@example.com",city:"Chengdu",tier:"BRONZE",platformId:"1"}},{entity:"CustomerOrder",id:"1001",payload:{orderNumber:"TQL-2026-1001",orderDate:"2026-08-28",status:f.DELIVERED,totalAmount:499,currency:"CNY",customerId:"101",platformId:"1"}},{entity:"CustomerOrder",id:"1002",payload:{orderNumber:"TQL-2026-1002",orderDate:"2026-09-02",status:f.SHIPPED,totalAmount:1299,currency:"CNY",customerId:"102",platformId:"1"}},{entity:"CustomerOrder",id:"1003",payload:{orderNumber:"TQL-2026-1003",orderDate:"2026-09-06",status:f.PAID,totalAmount:328.8,currency:"CNY",customerId:"101",platformId:"1"}},{entity:"CustomerOrder",id:"1004",payload:{orderNumber:"TQL-2026-1004",orderDate:"2026-09-11",status:f.PENDING_PAYMENT,totalAmount:79.9,currency:"CNY",customerId:"105",platformId:"1"}},{entity:"CustomerOrder",id:"1005",payload:{orderNumber:"TQL-2026-1005",orderDate:"2026-09-14",status:f.DELIVERED,totalAmount:219,currency:"USD",customerId:"103",platformId:"2"}},{entity:"CustomerOrder",id:"1006",payload:{orderNumber:"TQL-2026-1006",orderDate:"2026-09-18",status:f.PAID,totalAmount:640,currency:"USD",customerId:"104",platformId:"2"}},{entity:"CustomerOrder",id:"1007",payload:{orderNumber:"TQL-2026-1007",orderDate:"2026-09-21",status:f.CANCELLED,totalAmount:159,currency:"CNY",customerId:"102",platformId:"1"}},{entity:"CustomerOrder",id:"1008",payload:{orderNumber:"TQL-2026-1008",orderDate:"2026-09-25",status:f.SHIPPED,totalAmount:268,currency:"CNY",customerId:"105",platformId:"1"}},{entity:"OrderItem",id:"2001",payload:{orderId:"1001",productName:"TeaQL Mechanical Keyboard",sku:"KB-TQL-87",quantity:1,unitPrice:299,lineAmount:299}},{entity:"OrderItem",id:"2002",payload:{orderId:"1001",productName:"Silent Wireless Mouse",sku:"MS-SILENT",quantity:2,unitPrice:100,lineAmount:200}},{entity:"OrderItem",id:"2003",payload:{orderId:"1002",productName:"27-inch Developer Monitor",sku:"MON-27-4K",quantity:1,unitPrice:1299,lineAmount:1299}},{entity:"OrderItem",id:"2004",payload:{orderId:"1003",productName:"White Porcelain Travel Tea Set",sku:"TEA-TRAVEL",quantity:1,unitPrice:168.8,lineAmount:168.8}},{entity:"OrderItem",id:"2005",payload:{orderId:"1003",productName:"Pre-Qingming Longjing Tea",sku:"TEA-LJ-100",quantity:2,unitPrice:80,lineAmount:160}},{entity:"OrderItem",id:"2006",payload:{orderId:"1004",productName:"Double-wall Glass Tumbler",sku:"CUP-GLASS",quantity:1,unitPrice:79.9,lineAmount:79.9}},{entity:"OrderItem",id:"2007",payload:{orderId:"1005",productName:"Travel Brew Kit",sku:"BREW-KIT",quantity:1,unitPrice:219,lineAmount:219}},{entity:"OrderItem",id:"2008",payload:{orderId:"1006",productName:"Desktop Studio Speaker",sku:"SPK-STUDIO",quantity:2,unitPrice:260,lineAmount:520}},{entity:"OrderItem",id:"2009",payload:{orderId:"1006",productName:"Speaker Stand",sku:"SPK-STAND",quantity:1,unitPrice:120,lineAmount:120}},{entity:"OrderItem",id:"2010",payload:{orderId:"1007",productName:"Desktop Reading Lamp",sku:"LAMP-DESK",quantity:1,unitPrice:159,lineAmount:159}},{entity:"OrderItem",id:"2011",payload:{orderId:"1008",productName:"TeaQL Portable Keyboard",sku:"KB-TQL-68",quantity:1,unitPrice:268,lineAmount:268}},{entity:"Payment",id:"3001",payload:{orderId:"1001",provider:"Alipay",status:"CAPTURED",amount:499,currency:"CNY",transactionId:"ALI-260828-01",paidAt:"2026-08-28T10:14:00Z"}},{entity:"Payment",id:"3002",payload:{orderId:"1002",provider:"WeChat Pay",status:"CAPTURED",amount:1299,currency:"CNY",transactionId:"WX-260902-08",paidAt:"2026-09-02T03:20:00Z"}},{entity:"Payment",id:"3003",payload:{orderId:"1003",provider:"Alipay",status:"CAPTURED",amount:328.8,currency:"CNY",transactionId:"ALI-260906-11",paidAt:"2026-09-06T11:42:00Z"}},{entity:"Payment",id:"3004",payload:{orderId:"1004",provider:"WeChat Pay",status:"PENDING",amount:79.9,currency:"CNY",transactionId:"WX-260911-02",paidAt:null}},{entity:"Payment",id:"3005",payload:{orderId:"1005",provider:"Stripe",status:"CAPTURED",amount:219,currency:"USD",transactionId:"PI-260914-05",paidAt:"2026-09-14T06:10:00Z"}},{entity:"Payment",id:"3006",payload:{orderId:"1006",provider:"Stripe",status:"CAPTURED",amount:640,currency:"USD",transactionId:"PI-260918-03",paidAt:"2026-09-18T15:08:00Z"}},{entity:"Payment",id:"3007",payload:{orderId:"1007",provider:"Alipay",status:"REFUNDED",amount:159,currency:"CNY",transactionId:"ALI-260921-07",paidAt:"2026-09-21T02:55:00Z"}},{entity:"Payment",id:"3008",payload:{orderId:"1008",provider:"WeChat Pay",status:"CAPTURED",amount:268,currency:"CNY",transactionId:"WX-260925-06",paidAt:"2026-09-25T08:31:00Z"}},{entity:"Shipment",id:"4001",payload:{orderId:"1001",carrier:"SF Express",status:"DELIVERED",trackingNumber:"SF2608281001",shipToCity:"Shanghai",shippedAt:"2026-08-29T02:00:00Z",deliveredAt:"2026-08-30T07:26:00Z"}},{entity:"Shipment",id:"4002",payload:{orderId:"1002",carrier:"JD Logistics",status:"IN_TRANSIT",trackingNumber:"JD2609021002",shipToCity:"Hangzhou",shippedAt:"2026-09-03T04:12:00Z",deliveredAt:null}},{entity:"Shipment",id:"4003",payload:{orderId:"1003",carrier:"SF Express",status:"READY",trackingNumber:"SF2609061003",shipToCity:"Shanghai",shippedAt:null,deliveredAt:null}},{entity:"Shipment",id:"4004",payload:{orderId:"1005",carrier:"DHL",status:"DELIVERED",trackingNumber:"DHL2609141005",shipToCity:"Singapore",shippedAt:"2026-09-15T01:10:00Z",deliveredAt:"2026-09-17T09:22:00Z"}},{entity:"Shipment",id:"4005",payload:{orderId:"1006",carrier:"DHL",status:"READY",trackingNumber:"DHL2609181006",shipToCity:"Paris",shippedAt:null,deliveredAt:null}},{entity:"Shipment",id:"4006",payload:{orderId:"1008",carrier:"SF Express",status:"IN_TRANSIT",trackingNumber:"SF2609251008",shipToCity:"Chengdu",shippedAt:"2026-09-26T03:18:00Z",deliveredAt:null}}],L=t=>`'${t.replaceAll("\\","\\\\").replaceAll("'","\\'").replaceAll(` +`,"\\n")}'`,U=t=>t.toQExpression().replace(/\s*\n\s*/g,""),Me={CustomerOrder:{fields:{id:"integer",orderNumber:"string",orderDate:"date",status:"integer",totalAmount:"decimal",currency:"string",customerId:"integer",platformId:"integer"},relations:{status:"OrderStatus",itemList:"OrderItem"}},OrderStatus:{fields:{id:"integer",name:"string",code:"string",color:"string",displayOrder:"integer"},relations:{}},OrderItem:{fields:{id:"integer",orderId:"integer",productName:"string",sku:"string"},relations:{}}};function Ke(t){if(!t||typeof t!="object"||Array.isArray(t))return t;const e=structuredClone(t),r=e.filter;if(!r||typeof r!="object"||Array.isArray(r)||!("status"in r))return e;const n=r,o=n.status,s=d=>{const a=f[String(d)];return a===void 0?d:Number(a)};return o&&typeof o=="object"&&!Array.isArray(o)&&"$in"in o?n.status={$in:Array.isArray(o.$in)?o.$in.map(s):o.$in}:n.status=s(o),e}class D{query;filters=[];qRoot;qSteps=[];auditComment="";queryPurpose="";pageTotalAlias;constructor(e,r){this.query=new T(e),this.qRoot=r}comment(e){return this.auditComment=e,this.query.comment(e),this.record(`comment(${L(e)})`),this}purpose(e){return this.queryPurpose=e,this.query.purpose(e),this.record(`purpose(${L(e)})`),this}limit(e){return this.query.limit(e),this.record(`limit(${e})`),this}offset(e){return this.query.offset(e),this.record(`offset(${e})`),this}toQExpression(e){const r=e?[...this.qSteps,e]:this.qSteps;return[this.qRoot,...r.map(n=>` .${n}`)].join(` +`)}toQuery(){const e=this.query.clone();return this.filters.length&&e.filter({$and:[...this.filters]}),e}async executeForList(e){this.ensureIntent();const r=this.service(e),n=this.toQuery(),o=await r.executeQuery(e.prepareQuery(n)),s=new ie(o);return n.facets.length&&(s.facets=await de(r,d=>e.prepareQuery(d),n,n.facets)),s}async executeForRows(e){return this.executeForList(e)}async executeForPage(e,r,n){this.ensureIntent();const o=this.service(e),s=this.toQuery(),d=await o.executeCount(s,this.pageTotalAlias,this.pageTotalAlias?{kind:"named-count",method:"countAs",alias:this.pageTotalAlias}:void 0),a=this.toQuery().offset(r).limit(n),c=new ie(await o.executeQuery(e.prepareQuery(a)),{totalCount:d});return this.pageTotalAlias&&(c.aggregations[this.pageTotalAlias]=d),s.facets.length&&(c.facets=await de(o,m=>e.prepareQuery(m),s,s.facets)),{data:c,totalCount:d,offset:r,limit:n}}addFilter(e){return this.filters.push(e),this}select(...e){return this.query.select(e),this}order(e,r){return this.query.order(r==="asc"?R.asc(e):R.desc(e)),this}group(e){return this.query.groupBy(e),this}aggregate(e,r,n){return this.query.aggregate(e,r,n),this}record(e){return this.qSteps.push(e),this}includePageTotalAs(e){return this.pageTotalAlias=e,this}service(e){return e.requireResource("dataService")}ensureIntent(){if(!this.auditComment.trim()||!this.queryPurpose.trim())throw new Error("Generated Q requests require comment() and purpose() before execution")}}class Ue extends D{constructor(){super("Platform","Q.platforms()")}selectId(){return this.select("id")}selectName(){return this.select("name")}selectCode(){return this.select("code")}withIdIs(e){return this.addFilter({id:{$eq:e}})}}class Ye extends D{constructor(){super("Customer","Q.customers()")}selectId(){return this.select("id")}selectName(){return this.select("name")}selectCity(){return this.select("city")}selectTier(){return this.select("tier")}selectPlatformWith(e){return this.query.relationQuery("platform",e.toQuery(),"platformId","id",!1),this}countOrderListAs(e){return this.query.relationAggregate("orderList",e,new T("CustomerOrder").aggregate("Count","id",e)),this}orderByNameAscending(){return this.order("name","asc")}}class Ge extends D{constructor(){super("OrderItem","Q.orderItems()")}selectId(){return this.select("id"),this.record("selectId()")}selectOrderId(){return this.select("orderId"),this.record("selectOrderId()")}selectProductName(){return this.select("productName"),this.record("selectProductName()")}selectSku(){return this.select("sku"),this.record("selectSku()")}selectQuantity(){return this.select("quantity"),this.record("selectQuantity()")}withProductNameContaining(e){return this.addFilter({productName:{$contains:e}})}orderByIdAscending(){return this.order("id","asc"),this.record("orderByIdAscending()")}groupByProductName(){return this.group("productName")}sumQuantityAs(e){return this.aggregate("Sum","quantity",e)}sumLineAmountAs(e){return this.aggregate("Sum","lineAmount",e)}countAs(e){return this.aggregate("Count","id",e)}}class je extends D{constructor(){super("OrderStatus","Q.orderStatuses()")}selectId(){return this.select("id"),this.record("selectId()")}selectName(){return this.select("name"),this.record("selectName()")}selectCode(){return this.select("code"),this.record("selectCode()")}selectColor(){return this.select("color"),this.record("selectColor()")}selectDisplayOrder(){return this.select("displayOrder"),this.record("selectDisplayOrder()")}withCodeIs(e){return this.addFilter({code:{$eq:e}})}countAs(e){return this.aggregate("Count","id",e),this.record(`countAs(${L(e)})`)}sumOrderTotalAmountAs(e){return this.aggregate("Sum","totalAmount",e),this.record(`sumOrderTotalAmountAs(${L(e)})`)}orderByDisplayOrderAscending(){return this.order("displayOrder","asc"),this.record("orderByDisplayOrderAscending()")}}class He extends D{constructor(){super("Payment","Q.payments()")}groupByCurrency(){return this.group("currency")}groupByProvider(){return this.group("provider")}groupByStatus(){return this.group("status")}countAs(e){return this.aggregate("Count","id",e)}sumAmountAs(e){return this.aggregate("Sum","amount",e)}orderByCurrencyAscending(){return this.order("currency","asc")}orderByProviderAscending(){return this.order("provider","asc")}orderByIdAscending(){return this.order("id","asc")}}class Ve extends D{constructor(){super("Shipment","Q.shipments()")}withStatusIn(...e){return this.addFilter({status:{$in:e}})}selectOrderWith(e){return this.query.relationQuery("order",e.toQuery(),"orderId","id",!1),this}orderByStatusAscending(){return this.order("status","asc")}orderByIdAscending(){return this.order("id","asc")}}class ue extends D{dynamicWarnings=[];countAlias;rowCountApplied=!1;constructor(e=!1){super("CustomerOrder",e?"Q.customerOrdersWithMinimalFields()":"Q.customerOrders()"),e?this.query.select(["id","version"]):this.query.select(["id","orderNumber","orderDate","status","totalAmount","currency","customerId","platformId","version"])}selectId(){return this.select("id")}selectOrderNumber(){return this.select("orderNumber"),this.record("selectOrderNumber()")}selectOrderDate(){return this.select("orderDate"),this.record("selectOrderDate()")}selectStatus(){return this.select("status")}selectTotalAmount(){return this.select("totalAmount")}selectCurrency(){return this.select("currency")}withOrderNumberIs(e){return this.addFilter({orderNumber:{$eq:e}})}withOrderNumberContaining(e){return this.addFilter({orderNumber:{$contains:e}})}withStatusMatching(e){return this.addFilter({status:{$inSubquery:{query:e.toQuery(),field:"id"}}})}withStatusIsPendingPayment(){return this.addFilter({status:{$eq:f.PENDING_PAYMENT}})}withStatusIsPaid(){return this.addFilter({status:{$eq:f.PAID}})}withStatusIsShipped(){return this.addFilter({status:{$eq:f.SHIPPED}})}withStatusIsDelivered(){return this.addFilter({status:{$eq:f.DELIVERED}})}withStatusIsCancelled(){return this.addFilter({status:{$eq:f.CANCELLED}})}withCurrencyIs(e){return this.addFilter({currency:{$eq:e}})}withTotalAmountGreaterThanOrEqualTo(e){return this.addFilter({totalAmount:{$gte:e}})}withOrderDateGreaterThanOrEqualTo(e){return this.addFilter({orderDate:{$gte:e}})}withPlatformIdIs(e){return this.addFilter({platformId:{$eq:e}})}withItemListMatching(e){return this.addFilter({id:{$inSubquery:{query:e.toQuery(),field:"orderId"}}})}filterByJson(e){const{query:r,warnings:n}=Te(this.toQuery(),Ke(e),Me,{filter:(o,s)=>o==="status.code"?{status:{$inSubquery:{query:new T("OrderStatus").filter({code:s}),field:"id"}}}:o==="itemList.productName"?{id:{$inSubquery:{query:new T("OrderItem").filter({productName:s}),field:"orderId"}}}:{[o]:s},order:(o,s)=>s==="asc"?R.asc(o):R.desc(o)});return this.dynamicWarnings=n,this.query.filterCondition=r.filterCondition,this.query.orderItems=[...r.orderItems],this.record("filterByJson(searchParams)"),this}warnings(){return this.dynamicWarnings}selectPlatformWith(e){return this.query.relationQuery("platform",e.toQuery(),"platformId","id",!1),this}selectCustomerWith(e){return this.query.relationQuery("customer",e.toQuery(),"customerId","id",!1),this}selectStatusWith(e){return this.query.select(["status"]),this.query.relationQuery("status",e.toQuery(),"status","id",!1,{kind:"relation-select",method:"selectStatusWith",relation:"status"}),this.record(`selectStatusWith(${U(e)})`)}selectItemListWith(e){return this.query.relationQuery("itemList",e.toQuery(),"id","orderId",!0,{kind:"relation-select",method:"selectItemListWith",relation:"itemList"}),this.record(`selectItemListWith(${U(e)})`)}selectPaymentListWith(e){return this.query.relationQuery("paymentList",e.toQuery(),"id","orderId",!0),this}selectShipmentListWith(e){return this.query.relationQuery("shipmentList",e.toQuery(),"id","orderId",!0),this}countItemListAs(e){return this.query.relationAggregate("itemList",e,new T("OrderItem").aggregate("Count","id",e).comment("count items"),!0,{kind:"relation-count",method:"countItemListAs",relation:"itemList",alias:e}),this.record(`countItemListAs(${L(e)})`)}facetByStatusAs(e,r,n=!0){const o=r.toQuery();return o.commentText||o.comment("load status facets"),this.query.facetBy(e,"status",{toQuery:()=>o},n,{kind:"facet",method:"facetByStatusAs",relation:"status",alias:e}),this.record(`facetByStatusAs(${L(e)}, ${U(r)})`)}orderByOrderDateDescending(){return this.order("orderDate","desc"),this.record("orderByOrderDateDescending()")}orderByOrderDateAscending(){return this.order("orderDate","asc")}orderByIdDescending(){return this.order("id","desc"),this.record("orderByIdDescending()")}orderByTotalAmountDescending(){return this.order("totalAmount","desc")}groupByCurrency(){return this.group("currency")}groupByStatus(){return this.group("status")}countAs(e){return this.countAlias=e,this.record(`countAs(${L(e)})`)}sumTotalAmountAs(e){return this.aggregate("Sum","totalAmount",e)}averageTotalAmountAs(e){return this.aggregate("Avg","totalAmount",e)}executeForList(e){return this.applyRowCount(),super.executeForList(e)}executeForRows(e){return this.applyRowCount(),super.executeForList(e)}executeForPage(e,r,n){return this.countAlias&&this.includePageTotalAs(this.countAlias),super.executeForPage(e,r,n)}applyRowCount(){!this.countAlias||this.rowCountApplied||(this.query.aggregate("Count","id",this.countAlias),this.rowCountApplied=!0)}}class u{static platforms(){return new Ue}static customers(){return new Ye}static customerOrders(){return new ue}static customerOrdersWithMinimalFields(){return new ue(!0)}static orderItems(){return new Ge}static orderStatuses(){return new je}static payments(){return new He}static shipments(){return new Ve}}const k=document.querySelector("#status"),B=document.querySelector("#persist"),Y=document.querySelector("#reset"),F=document.querySelector("#query-catalog"),b=document.querySelector("#result"),ge=document.querySelector("#result-title"),fe=document.querySelector("#result-description"),J=document.querySelector("#result-meta"),le=document.querySelector("#query-code"),Ze=document.querySelector("#query-params-block"),Je=document.querySelector("#query-params-code"),Xe=document.querySelector("#result-grid"),$=document.querySelector("#result-view-label"),et=document.querySelector("#sql-count"),me=document.querySelector("#sql-output"),X=document.querySelector("#expand-all"),tt=document.querySelector("#collapse-all"),Q=document.querySelector("#view-table"),H=document.querySelector("#view-tree"),Ae=Array.from(document.querySelectorAll("[data-locale]")),rt={heroTitle:{en:"Understand TeaQL queries through a familiar order model.",zh:"用一个熟悉的订单模型,看懂 TeaQL 查询。"},heroIntro:{en:"Platform, customer, order, item, payment, and shipment data all run in the browser. Order status is backed by a constant model. Choose a query below to inspect real SQLite/WASM results.",zh:"平台、用户、订单、明细、支付和物流数据都在浏览器中运行;订单状态由常数模型提供。选择下面的查询,查看真实的 SQLite/WASM 结果。"},platform:{en:"Platform",zh:"平台"},customer:{en:"Customer",zh:"用户"},order:{en:"Order",zh:"订单"},item:{en:"Item",zh:"明细"},payment:{en:"Payment",zh:"支付"},shipment:{en:"Shipment",zh:"物流"},constantModel:{en:"Constant model",zh:"常数模型"},persist:{en:"Persist locally with OPFS",zh:"使用 OPFS 保存在本地"},reset:{en:"Reset demo data",zh:"重置演示数据"},chooseQuery:{en:"Choose a query",zh:"选择一个查询"},queryIntro:{en:"Queries are grouped by purpose and share the same order dataset.",zh:"查询按用途分组,并共用同一份订单数据。"},table:{en:"Table",zh:"表格"},resultTree:{en:"Result Tree",zh:"结果树"},expandAll:{en:"Expand all",zh:"全部展开"},collapseAll:{en:"Collapse all",zh:"全部折叠"},waiting:{en:"Waiting for query…",zh:"等待查询…"},queryNote:{en:"The Q expression stays fixed; search, status cards, and pagination only update dynamic parameters. The underlying SelectQuery remains inside the generated request implementation.",zh:"Q 表达式保持不变;搜索、状态卡片和分页只更新动态参数。底层 SelectQuery 仍封装在生成的请求实现中。"},executionEvidence:{en:"EXECUTION EVIDENCE",zh:"执行证据"},evidenceTime:{en:"Time",zh:"时间"},identity:{en:"Identity",zh:"身份"},traceChain:{en:"Trace chain",zh:"追踪链"},sqlNote:{en:"One plain-text line per statement: time, identity, trace chain, and the SQL SQLite executed.",zh:"每条语句使用一行纯文本:时间、身份、追踪链,以及 SQLite 实际执行的 SQL。"},localData:{en:"Data stays in this browser",zh:"数据只保留在当前浏览器中"}},nt={基本查询:"Basic queries","从订单、用户和关联对象开始":"Start with orders, customers, and related objects",汇总查询:"Aggregations","分组、计数、求和与平均值":"Grouping, counts, sums, and averages",过滤查询:"Filtered queries","精确、范围与组合条件":"Exact, range, and combined predicates",动态查询:"Dynamic queries","由页面条件安全生成,不使用 eval":"Safely generated from page criteria without eval","综合:订单管理中心":"Comprehensive: Order management center","一个真实的综合查询页面:状态指标、搜索、商品预览和分页都由 TeaQL 查询驱动。":"A real composite query page: status metrics, search, product previews, and pagination are all driven by TeaQL.",最近订单:"Recent orders","按下单日期倒序浏览全部订单,并带出所属平台与用户。":"Browse all orders by date descending, including their platform and customer.",完整订单详情:"Complete order details","查看一个订单及其用户、商品明细、支付和物流,体现完整对象图。":"Inspect one order with its customer, items, payments, and shipments as a complete object graph.",用户与订单数:"Customers with order counts","列出用户,并通过关联汇总显示每位用户的订单数量。":"List customers and show each customer’s order count through a relation aggregate.",订单状态汇总:"Orders by status","按币种与订单状态统计订单数、总额和平均客单价。":"Aggregate order count, gross amount, and average order value by currency and status.",商品销售汇总:"Product sales summary","按商品汇总销量与销售额,找出最受欢迎的订单明细。":"Aggregate units and revenue by product to identify the most popular order items.",支付渠道对账:"Payment reconciliation","按币种、支付渠道和状态汇总笔数与金额。":"Aggregate transaction count and amount by currency, payment provider, and status.",待支付订单:"Orders awaiting payment","筛选尚未完成付款的订单,并带出对应支付记录。":"Find orders that have not completed payment and include their payment records.",国内大额订单:"High-value domestic orders","组合平台与金额条件,找出 TeaQL 商城中金额不低于 500 元的订单。":"Combine platform and amount filters to find TeaQL Store orders worth at least CNY 500.",运输中的包裹:"Active shipments","筛选待揽收和运输中的物流单,并关联订单信息。":"Find shipments that are ready or in transit and include their order information.","动态:已付款国内订单":"Dynamic: paid domestic orders","从动态条件对象生成查询:人民币、金额至少 250,且状态为已付款或已发货。":"Build a query from dynamic criteria: CNY, at least 250, and status PAID or SHIPPED.","动态:九月新订单":"Dynamic: new September orders","运行时传入日期范围与排序方式,查询 9 月 15 日之后的订单。":"Pass a date range and sort order at runtime to find orders after September 15.","动态:字段白名单":"Dynamic: field allowlist","未知字段会被报告并忽略;合法条件仍可安全执行。":"Unknown fields are reported and ignored while valid predicates still execute safely."};let i=localStorage.getItem("teaql-browser-locale")==="zh"?"zh":"en";function st(t){return rt[t]?.[i]??t}function O(t){return i==="en"?nt[t]??t:t}let E,W=window.location.hash.slice(1)||"order-center";window.location.hash||history.replaceState(null,"","#order-center");let w="tree",v,Se=0,ee;const A={search:"",page:0,pageSize:4},Ce=localStorage.getItem("teaql-browser-storage")==="opfs"?"opfs":"memory";B.checked=Ce==="opfs";async function G(t,e){const r=u.customerOrders().filterByJson(e).limit(20).comment("what: execute a validated browser search").purpose("why: demonstrate safe dynamic order discovery"),n=await r.executeForList(t.context);return{request:e,warnings:r.warnings(),data:n}}const ot=Object.fromEntries(Object.entries(f).map(([t,e])=>[e,t]));function te(t){const e=String(t.code??"");return e&&e in f?e:"color"in t?ot[String(t.id??"")]??"":""}function Ie(t){const e=t.trim();if(!e)return{filter:{}};const r=e.toUpperCase(),n=["PENDING_PAYMENT","PAID","SHIPPED","DELIVERED","CANCELLED"].find(o=>o.includes(r));return n?{filter:{"status.code":n}}:/^(TQL-|\d)/i.test(e)?{filter:{orderNumber:{$contains:r}}}:{filter:{"itemList.productName":{$contains:e}}}}async function at(t){const e=Ie(A.search),r=u.customerOrdersWithMinimalFields().filterByJson(e).countAs("totalOrders").facetByStatusAs("statusCounts",u.orderStatuses().selectName().selectColor().countAs("orderCount").sumOrderTotalAmountAs("orderTotalAmount").orderByDisplayOrderAscending().comment("load status facets")).selectOrderNumber().selectOrderDate().selectStatusWith(u.orderStatuses().selectName().selectColor().comment("load status")).selectItemListWith(u.orderItems().selectProductName().selectQuantity().orderByIdAscending().limit(3).comment("load item previews")).countItemListAs("itemCount").orderByOrderDateDescending().orderByIdDescending().comment("load order list").purpose("render order list page"),n=await r.executeForPage(t.context,A.page*A.pageSize,A.pageSize),o=n.data.facet("statusCounts")??[];return{orders:n.data,totalOrders:Number(n.data.aggregations.totalOrders??n.totalCount),filteredOrders:n.totalCount,statusFacets:o.map(s=>({code:te(s),name:String(s.name??""),color:String(s.color??""),orderCount:Number(s.orderCount??0),orderTotalAmount:Number(s.orderTotalAmount??0)})).filter(s=>s.code&&s.name),search:A.search,page:A.page,pageSize:A.pageSize,queryExpression:r.toQExpression("executeForPage(ctx, pageOffset, pageSize);")}}const we=[{label:"基本查询",description:"从订单、用户和关联对象开始",queries:[{id:"order-center",title:"综合:订单管理中心",description:"一个真实的综合查询页面:状态指标、搜索、商品预览和分页都由 TeaQL 查询驱动。",code:"",view:"dashboard",run:at},{id:"recent-orders",title:"最近订单",description:"按下单日期倒序浏览全部订单,并带出所属平台与用户。",code:`await Q.customerOrders() + .selectPlatformWith(Q.platforms().selectName()) + .selectCustomerWith(Q.customers().selectName().selectCity().selectTier()) + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .orderByOrderDateDescending() + .orderByIdDescending() + .limit(8) + .comment('what: list recent commerce orders') + .purpose('why: provide the default order overview') + .executeForList(ctx)`,run:t=>u.customerOrders().selectPlatformWith(u.platforms().selectName()).selectCustomerWith(u.customers().selectName().selectCity().selectTier()).selectStatusWith(u.orderStatuses().selectName().selectColor()).orderByOrderDateDescending().orderByIdDescending().limit(8).comment("what: list recent commerce orders").purpose("why: provide the default order overview").executeForList(t.context)},{id:"order-detail",title:"完整订单详情",description:"查看一个订单及其用户、商品明细、支付和物流,体现完整对象图。",code:`await Q.customerOrders() + .withOrderNumberIs('TQL-2026-1003') + .selectPlatformWith(Q.platforms()) + .selectCustomerWith(Q.customers()) + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectItemListWith(Q.orderItems().orderByIdAscending()) + .selectPaymentListWith(Q.payments().orderByIdAscending()) + .selectShipmentListWith(Q.shipments().orderByIdAscending()) + .limit(1) + .comment('what: load one complete order graph') + .purpose('why: inspect items, payment and fulfillment together') + .executeForList(ctx)`,run:t=>u.customerOrders().withOrderNumberIs("TQL-2026-1003").selectPlatformWith(u.platforms()).selectCustomerWith(u.customers()).selectStatusWith(u.orderStatuses().selectName().selectColor()).selectItemListWith(u.orderItems().orderByIdAscending()).selectPaymentListWith(u.payments().orderByIdAscending()).selectShipmentListWith(u.shipments().orderByIdAscending()).limit(1).comment("what: load one complete order graph").purpose("why: inspect items, payment and fulfillment together").executeForList(t.context)},{id:"customers-with-order-count",title:"用户与订单数",description:"列出用户,并通过关联汇总显示每位用户的订单数量。",code:`await Q.customers() + .selectPlatformWith(Q.platforms().selectName()) + .countOrderListAs('orderCount') + .orderByNameAscending() + .comment('what: list customers with related order counts') + .purpose('why: compare customer activity at a glance') + .executeForList(ctx)`,run:t=>u.customers().selectPlatformWith(u.platforms().selectName()).countOrderListAs("orderCount").orderByNameAscending().comment("what: list customers with related order counts").purpose("why: compare customer activity at a glance").executeForList(t.context)}]},{label:"汇总查询",description:"分组、计数、求和与平均值",queries:[{id:"orders-by-status",title:"订单状态汇总",description:"按币种与订单状态统计订单数、总额和平均客单价。",code:`await Q.customerOrders() + .groupByCurrency().groupByStatus() + .countAs('orderCount') + .sumTotalAmountAs('grossAmount') + .averageTotalAmountAs('averageOrderValue') + .comment('what: aggregate orders by currency and status') + .purpose('why: show the current order funnel') + .executeForRows(ctx)`,run:t=>u.customerOrders().groupByCurrency().groupByStatus().countAs("orderCount").sumTotalAmountAs("grossAmount").averageTotalAmountAs("averageOrderValue").comment("what: aggregate orders by currency and status").purpose("why: show the current order funnel").executeForRows(t.context)},{id:"product-sales",title:"商品销售汇总",description:"按商品汇总销量与销售额,找出最受欢迎的订单明细。",code:`await Q.orderItems() + .groupByProductName() + .sumQuantityAs('units') + .sumLineAmountAs('revenue') + .comment('what: aggregate sold units and line revenue') + .purpose('why: identify the strongest products in the demo data') + .executeForRows(ctx)`,run:t=>u.orderItems().groupByProductName().sumQuantityAs("units").sumLineAmountAs("revenue").comment("what: aggregate sold units and line revenue").purpose("why: identify the strongest products in the demo data").executeForRows(t.context)},{id:"payment-reconciliation",title:"支付渠道对账",description:"按币种、支付渠道和状态汇总笔数与金额。",code:`await Q.payments() + .groupByCurrency().groupByProvider().groupByStatus() + .countAs('paymentCount').sumAmountAs('paymentAmount') + .orderByCurrencyAscending().orderByProviderAscending() + .comment('what: reconcile payment totals by provider') + .purpose('why: compare captured, pending and refunded money') + .executeForRows(ctx)`,run:t=>u.payments().groupByCurrency().groupByProvider().groupByStatus().countAs("paymentCount").sumAmountAs("paymentAmount").orderByCurrencyAscending().orderByProviderAscending().comment("what: reconcile payment totals by provider").purpose("why: compare captured, pending and refunded money").executeForRows(t.context)}]},{label:"过滤查询",description:"精确、范围与组合条件",queries:[{id:"pending-payment",title:"待支付订单",description:"筛选尚未完成付款的订单,并带出对应支付记录。",code:`await Q.customerOrders() + .withStatusIsPendingPayment() + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectCustomerWith(Q.customers().selectName()) + .selectPaymentListWith(Q.payments()) + .comment('what: find orders awaiting payment') + .purpose('why: support payment follow-up') + .executeForList(ctx)`,run:t=>u.customerOrders().withStatusIsPendingPayment().selectStatusWith(u.orderStatuses().selectName().selectColor()).selectCustomerWith(u.customers().selectName()).selectPaymentListWith(u.payments()).comment("what: find orders awaiting payment").purpose("why: support payment follow-up").executeForList(t.context)},{id:"large-cn-orders",title:"国内大额订单",description:"组合平台与金额条件,找出 TeaQL 商城中金额不低于 500 元的订单。",code:`await Q.customerOrders() + .withPlatformIdIs('1') + .withTotalAmountGreaterThanOrEqualTo(500) + .selectCustomerWith(Q.customers().selectName().selectCity()) + .orderByTotalAmountDescending() + .comment('what: find high-value domestic orders') + .purpose('why: prioritize valuable fulfillment work') + .executeForList(ctx)`,run:t=>u.customerOrders().withPlatformIdIs("1").withTotalAmountGreaterThanOrEqualTo(500).selectCustomerWith(u.customers().selectName().selectCity()).orderByTotalAmountDescending().comment("what: find high-value domestic orders").purpose("why: prioritize valuable fulfillment work").executeForList(t.context)},{id:"open-shipments",title:"运输中的包裹",description:"筛选待揽收和运输中的物流单,并关联订单信息。",code:`await Q.shipments() + .withStatusIn('READY', 'IN_TRANSIT') + .selectOrderWith(Q.customerOrders().selectOrderNumber().selectOrderDate().selectStatusWith(Q.orderStatuses().selectName().selectColor()).selectTotalAmount().selectCurrency()) + .orderByStatusAscending().orderByIdAscending() + .comment('what: find shipments that are not delivered') + .purpose('why: monitor active fulfillment') + .executeForList(ctx)`,run:t=>u.shipments().withStatusIn("READY","IN_TRANSIT").selectOrderWith(u.customerOrders().selectOrderNumber().selectOrderDate().selectStatusWith(u.orderStatuses().selectName().selectColor()).selectTotalAmount().selectCurrency()).orderByStatusAscending().orderByIdAscending().comment("what: find shipments that are not delivered").purpose("why: monitor active fulfillment").executeForList(t.context)}]},{label:"动态查询",description:"由页面条件安全生成,不使用 eval",queries:[{id:"dynamic-paid-cn",title:"动态:已付款国内订单",description:"从动态条件对象生成查询:人民币、金额至少 250,且状态为已付款或已发货。",code:`const input = { + "filter": { + "currency": "CNY", + "totalAmount": { "$gte": 250 }, + "status": { "$in": ["PAID", "SHIPPED"] } + }, + "orderBy": [{ "field": "totalAmount", "direction": "desc" }] +}; +const data = await Q.customerOrders() + .filterByJson(input) + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx);`,run:t=>G(t,{filter:{currency:"CNY",totalAmount:{$gte:250},status:{$in:["PAID","SHIPPED"]}},orderBy:[{field:"totalAmount",direction:"desc"}]})},{id:"dynamic-date-range",title:"动态:九月新订单",description:"运行时传入日期范围与排序方式,查询 9 月 15 日之后的订单。",code:`const input = { + "filter": { "orderDate": { "$gte": "2026-09-15" } }, + "orderBy": [{ "field": "orderDate", "direction": "asc" }] +}; +const data = await Q.customerOrders() + .filterByJson(input) + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx);`,run:t=>G(t,{filter:{orderDate:{$gte:"2026-09-15"}},orderBy:[{field:"orderDate",direction:"asc"}]})},{id:"dynamic-safe-fields",title:"动态:字段白名单",description:"未知字段会被报告并忽略;合法条件仍可安全执行。",code:`const input = { + "filter": { + "status": "DELIVERED", + "internalNote": { "$contains": "not queryable" } + } +}; +const request = Q.customerOrders().filterByJson(input); +const data = await request + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx); +const warnings = request.warnings();`,run:t=>G(t,{filter:{status:"DELIVERED",internalNote:{$contains:"not queryable"}}})}]}],pe=we.flatMap(t=>t.queries);async function it(t){const e=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),r=await Qe.open(e,{...ce},{storage:t,databaseName:"teaql-order-playground-v3.sqlite3"}),n=new $e().enableSelect();r.install(new Re(ce,{},{constants:_e})),r.setRuntimeTelemetrySink(n).setDiagnosticSQLLogSink(void 0);const o=Object.freeze({policyId:"browser-order-demo-seed",version:"1",fingerprint:"sha256:browser-order-demo-seed-v1"}),s=new Be().insertResource("dataService",r).withMutationPolicyRegistry(new Fe(()=>({identity:o,review:(d,a)=>a.operations.length>0?{verdict:"allow"}:{verdict:"deny",code:"EMPTY_GRAPH",message:"empty mutation graph"}}))).withMutationPolicyApprovalProvider(new ke(d=>({policy:d,approvedBy:"browser-demo-owner",approvedAt:new Date})));return r.setUserContext(s),await s.ensureSchema(),{client:r,context:s,evidence:n}}async function be(t){if((await u.customerOrders().selectId().limit(1).comment("what: detect existing order playground data").purpose("why: keep deterministic browser bootstrap idempotent").executeForList(t.context)).length)return;const r=new We("Seed deterministic order playground data");await t.client.executeGraphSave(r,async n=>{const o=he.map(s=>n.request({entity:s.entity,action:"Create",id:s.id,payload:s.payload}));for(const s of o)t.client.preflightMutation(s);for(const s of o)await t.client.executeMutation(s)})}function dt(){F.replaceChildren();for(const t of we){const e=document.createElement("section");e.className="query-group";const r=document.createElement("div");r.className="query-group-heading";const n=document.createElement("h2");n.textContent=O(t.label);const o=document.createElement("p");o.textContent=O(t.description),r.append(n,o);const s=document.createElement("div");s.className="query-links";for(const d of t.queries){const a=document.createElement("a");a.href=`#${d.id}`,a.dataset.queryId=d.id,a.textContent=O(d.title),a.addEventListener("click",c=>{c.preventDefault(),W=d.id,history.replaceState(null,"",`#${d.id}`),V(),E&&P(d,E).catch(N)}),s.append(a)}e.append(r,s),F.append(e)}V()}function V(){F.querySelectorAll("a[data-query-id]").forEach(t=>{const e=t.dataset.queryId===W;t.classList.toggle("active",e),e?t.setAttribute("aria-current","page"):t.removeAttribute("aria-current")})}async function P(t,e){const r=performance.now(),n=new Date;e.evidence.enableSelect(),b.classList.add("loading"),b.setAttribute("aria-busy","true"),ge.textContent=O(t.title),fe.textContent=O(t.description),le.textContent=t.code,Ze.classList.toggle("hidden",t.view!=="dashboard"),Je.textContent=t.view==="dashboard"?JSON.stringify({searchParams:Ie(A.search),pageOffset:A.page*A.pageSize,pageSize:A.pageSize},null,2):"",Xe.classList.toggle("dashboard-mode",t.view==="dashboard"),b.classList.toggle("dashboard-result",t.view==="dashboard"),X.closest(".tree-actions")?.classList.toggle("hidden",t.view==="dashboard"),$.textContent=t.view==="dashboard"?i==="en"?"Order management center":"订单管理中心":i==="en"?"Result tree":"结果树",J.textContent=i==="en"?"Running query…":"查询中…";try{const o=await t.run(e);t.view==="dashboard"&&(le.textContent=o.queryExpression),v={data:o,query:t,active:e},w=t.view==="dashboard"||Z(o)?"table":"tree",z();const s=Math.max(1,Math.round(performance.now()-r));Se=s,ee=n;const d=e.evidence.snapshot();Ee(d,n),Pe(o,t,s)}finally{b.classList.remove("loading"),b.removeAttribute("aria-busy")}}function Ee(t,e=ee){me.replaceChildren(),et.textContent=i==="en"?`${t.length} statement${t.length===1?"":"s"}`:`${t.length} 条语句`,t.forEach((r,n)=>{const o=document.createElement("tr");o.className="evidence-row";const s=[...r.tracePath].reverse().find(l=>l.kind==="relation"||l.kind==="request"||l.kind==="entity"),d=document.createElement("td");d.className="evidence-time",d.dataset.executedAt=e?.toISOString()??"",d.textContent=`${e?.toISOString()??"—"} · ${Math.max(.01,r.elapsedMicros/1e3).toFixed(2)} ms`;const a=document.createElement("td");a.textContent=`${v?.query.id??"query"} · #${n+1} · ${s?.name??"query"}`;const c=document.createElement("td");if(c.className="evidence-trace",r.traceChain?.length){const l=r.traceChain.find(g=>g.kind==="purpose"),S=r.traceChain.filter(g=>g.kind==="comment").map(g=>g.detail||g.name);c.textContent=`${l?.detail||l?.name||""}: ${S.join(" → ")}`}else c.textContent=r.tracePath.map(l=>l.detail||l.name).join(" → ");const m=document.createElement("td");m.className="evidence-sql";const h=r.parameters.length?r.parameters.map(l=>String(l)).join(", "):"none";m.textContent=`${r.parameterizedSQL} · bindings: ${h}`,o.append(d,a,c,m),me.append(o)})}function Z(t){return Array.isArray(t)&&t.every(e=>e!==null&&typeof e=="object"&&!Array.isArray(e))}function z(){if(!v)return;const{data:t,query:e,active:r}=v,n=e.view==="dashboard"||Z(t);if(n||(w="tree"),Q.disabled=!n,Q.classList.toggle("active",w==="table"),H.classList.toggle("active",w==="tree"),Q.setAttribute("aria-pressed",String(w==="table")),H.setAttribute("aria-pressed",String(w==="tree")),X.closest(".tree-actions")?.classList.toggle("hidden",w!=="tree"),w==="table"&&e.view==="dashboard"){$.textContent=i==="en"?"Result table":"结果表格",mt(t,r,e);return}if(w==="table"&&Z(t)){$.textContent=i==="en"?"Result table":"结果表格",ut(t);return}$.textContent=i==="en"?"Result tree":"结果树",Le(e.view==="dashboard"?ct(t):t)}function ct(t){return{orders:t.orders,totalOrders:t.totalOrders,filteredOrders:t.filteredOrders,statusFacets:t.statusFacets,search:t.search,page:t.page,pageSize:t.pageSize}}function ut(t){const e=document.createElement("div");if(e.className="result-table-shell",!t.length){const a=document.createElement("p");a.className="result-table-empty",a.textContent=i==="en"?"The query returned no records.":"查询没有返回记录。",e.append(a),b.replaceChildren(e);return}const r=[...new Set(t.flatMap(a=>Object.keys(a)))],n=document.createElement("table");n.className="result-table";const o=document.createElement("thead"),s=document.createElement("tr");for(const a of r){const c=document.createElement("th");c.scope="col",c.textContent=a,s.append(c)}o.append(s);const d=document.createElement("tbody");for(const a of t){const c=document.createElement("tr");for(const m of r){const h=document.createElement("td");h.textContent=lt(a[m]),c.append(h)}d.append(c)}n.append(o,d),e.append(n),b.replaceChildren(e)}function lt(t){if(t==null)return"—";if(Array.isArray(t))return i==="en"?`${t.length} items`:`${t.length} 项`;if(t instanceof Date)return t.toISOString();if(typeof t=="object"){const e=t,r=te(e);if(r)return Ne(r);const n=e.name??e.orderNumber??e.code??e.id;return n===void 0?i==="en"?`${Object.keys(e).length} fields`:`${Object.keys(e).length} 个字段`:String(n)}return String(t)}function mt(t,e,r){const n=document.createElement("div");n.className="order-center";const o=document.createElement("div");o.className="order-center-toolbar";const s=document.createElement("div"),d=document.createElement("h3");d.textContent=i==="en"?"Order Management Center":"订单管理中心";const a=document.createElement("p");a.textContent=i==="en"?"One generated Q expression describes the entire page":"一个生成式 Q 表达式描述整个页面",s.append(d,a);const c=document.createElement("form");c.className="order-search";const m=document.createElement("input");m.type="search",m.placeholder=i==="en"?"Order number, status, or product…":"订单号、状态或商品名称…",m.value=t.search,m.setAttribute("aria-label",i==="en"?"Search orders":"搜索订单");const h=document.createElement("button");h.type="submit",h.className="order-search-submit",h.setAttribute("aria-label",i==="en"?"Run order query":"执行订单查询"),h.title=i==="en"?"Search":"查询";const l=document.createElement("span");l.className="search-icon",l.setAttribute("aria-hidden","true"),h.append(l),c.append(m,h),c.addEventListener("submit",p=>{p.preventDefault(),A.search=m.value.trim(),A.page=0,P(r,e).catch(N)}),o.append(s,c);const S=document.createElement("div");S.className="order-metrics",S.append(ye(i==="en"?"All orders":"全部订单",t.totalOrders,"total","#2B66D9",!t.search,()=>{A.search="",A.page=0,P(r,e).catch(N)}));for(const p of t.statusFacets)S.append(ye(p.name,p.orderCount,p.code.toLowerCase(),p.color,t.search.toUpperCase()===p.code,()=>{A.search=p.code,A.page=0,P(r,e).catch(N)},`${i==="en"?"Total":"总额"} ${pt(p.orderTotalAmount)}`));const g=document.createElement("div");g.className="order-table";const _=document.createElement("div");_.className="order-row order-row-head";const xe=i==="en"?["Order number","Order date","Status","Product details"]:["订单号","订单日期","状态","商品明细"];for(const p of xe){const x=document.createElement("span");x.textContent=p,_.append(x)}if(g.append(_),!t.orders.length){const p=document.createElement("div");p.className="order-empty",p.textContent=i==="en"?"No matching orders. Try an order number, status code, or product name.":"没有匹配的订单,请尝试订单号、状态英文或商品名称。",g.append(p)}for(const p of t.orders)g.append(yt(p));const M=document.createElement("div");M.className="order-center-footer";const ne=document.createElement("p"),se=t.filteredOrders?t.page*t.pageSize+1:0,oe=Math.min(t.filteredOrders,(t.page+1)*t.pageSize);ne.textContent=i==="en"?`Showing ${se}–${oe} of ${t.filteredOrders} orders`:`显示 ${se}–${oe},共 ${t.filteredOrders} 条订单`;const q=document.createElement("div");q.className="pagination";const ae=Math.max(1,Math.ceil(t.filteredOrders/t.pageSize));q.append(j("‹",t.page-1,t.page===0,e,r));for(let p=0;p=ae-1,e,r)),M.append(ne,q),n.append(o,S,g,M),b.replaceChildren(n)}function ye(t,e,r,n,o,s,d){const a=document.createElement("button");a.type="button",a.className=`metric-card metric-${r}`,n&&a.style.setProperty("--metric-color",n),a.classList.toggle("active",o);const c=document.createElement("span");c.textContent=t;const m=document.createElement("strong");if(m.textContent=String(e),a.append(c,m),d){const h=document.createElement("small");h.textContent=d,a.append(h)}return a.addEventListener("click",s),a}function pt(t){return new Intl.NumberFormat(i==="en"?"en-US":"zh-CN",{minimumFractionDigits:2,maximumFractionDigits:2}).format(t)}function yt(t){const e=document.createElement("div");e.className="order-row";const r=t.status??{},n=Array.isArray(t.itemList)?t.itemList:[];[String(t.orderNumber??""),String(t.orderDate??"")].forEach(l=>{const S=document.createElement("span");S.className="order-primary",S.textContent=l,e.append(S)});const s=document.createElement("span"),d=document.createElement("span"),a=te(r);d.className=`status-badge status-${a.toLowerCase()}`,d.textContent=Ne(a)||String(r.name??a);const c=String(r.color??"");c&&(d.style.color=c,d.style.backgroundColor=`${c}18`),s.append(d),e.append(s);const m=document.createElement("span");m.className="product-preview",n.forEach((l,S)=>{const g=document.createElement("span");g.className=`product-thumb product-tone-${S%3}`,g.textContent=String(l.productName??"?").slice(0,1),g.title=`${String(l.productName??"")} × ${String(l.quantity??1)}`,m.append(g)});const h=Number(t.itemCount??n.length)-n.length;if(h>0){const l=document.createElement("small");l.textContent=`+${h}`,m.append(l)}return e.append(m),e}function j(t,e,r,n,o){const s=document.createElement("button");return s.type="button",s.textContent=t,s.disabled=r,s.addEventListener("click",()=>{A.page=e,P(o,n).catch(N)}),s}function Ne(t){return(i==="en"?{PENDING_PAYMENT:"Pending payment",PAID:"Paid",SHIPPED:"Shipped",DELIVERED:"Delivered",CANCELLED:"Cancelled"}:{PENDING_PAYMENT:"待支付",PAID:"已支付",SHIPPED:"运输中",DELIVERED:"已完成",CANCELLED:"已取消"})[t]??t}function Le(t){b.replaceChildren(Oe(t,"result",0))}function Oe(t,e,r){if(t!==null&&typeof t=="object"){const d=Array.isArray(t)?t.map((S,g)=>[String(g),S]):Object.entries(t),a=document.createElement("details");a.className="tree-branch",a.open=r===0;const c=document.createElement("summary"),m=document.createElement("span");m.className="tree-key",m.textContent=e;const h=document.createElement("span");h.className="tree-preview",h.textContent=ht(t,d.length),c.append(m,h),a.append(c);const l=document.createElement("div");l.className="tree-children";for(const[S,g]of d)l.append(Oe(g,Array.isArray(t)?`#${Number(S)+1}`:S,r+1));return a.append(l),a}const n=document.createElement("div");n.className="tree-leaf";const o=document.createElement("span");o.className="tree-key",o.textContent=e;const s=document.createElement("span");return s.className=`tree-value tree-${t===null?"null":typeof t}`,s.textContent=t===null?"null":typeof t=="string"?`“${t}”`:String(t),n.append(o,s),n}function ht(t,e){if(Array.isArray(t))return i==="en"?`${e} items`:`${e} 项`;const r=t,n=r.orderNumber??r.name??r.productName??r.transactionId??r.trackingNumber;return n?String(n):i==="en"?`${e} fields`:`${e} 个字段`}function gt(t){return Array.isArray(t)?t.length:Array.isArray(t?.data)?t.data.length:1}function Pe(t,e,r){const n=e.view==="dashboard"?t.filteredOrders:gt(t),o=i==="en"?`${n} ${e.view==="dashboard"?`matching order${n===1?"":"s"}`:`result${n===1?"":"s"}`}`:`${n} 条${e.view==="dashboard"?"匹配订单":"结果"}`;J.textContent=`${o} · ${r} ms · ${i==="en"?"in-browser SQLite":"浏览器内 SQLite"}`}function De(t){const e=he.filter(r=>r.entity==="CustomerOrder").length;k.textContent=i==="en"?`${t.toUpperCase()} · ${e} orders · 7 entities · policy installed · ready`:`${t.toUpperCase()} · ${e} 个订单 · 7 个实体 · 已安装策略 · 就绪`}function ve(){document.documentElement.lang=i==="en"?"en":"zh-CN",document.title=i==="en"?"TeaQL Order Query Playground":"TeaQL 订单查询演练场";const t=document.querySelector('meta[name="description"]');if(t&&(t.content=i==="en"?"A TeaQL order-query playground running entirely in the browser":"完全运行在浏览器中的 TeaQL 订单查询演练场"),document.querySelectorAll("[data-i18n]").forEach(e=>{const r=e.dataset.i18n;r&&(e.textContent=st(r))}),Ae.forEach(e=>{const r=e.dataset.locale===i;e.classList.toggle("active",r),e.setAttribute("aria-pressed",String(r))}),document.querySelector(".language-switch")?.setAttribute("aria-label",i==="en"?"Language":"语言"),document.querySelector(".brand")?.setAttribute("aria-label",i==="en"?"TeaQL Playground home":"TeaQL 演练场首页"),document.querySelector(".model-map")?.setAttribute("aria-label",i==="en"?"Order domain model":"订单领域模型"),document.querySelector(".runtime-bar")?.setAttribute("aria-label",i==="en"?"Runtime settings":"运行时设置"),F.setAttribute("aria-label",i==="en"?"Example queries":"示例查询"),document.querySelector(".result-view-switch")?.setAttribute("aria-label",i==="en"?"Result views":"结果视图"),document.querySelector(".tree-actions")?.setAttribute("aria-label",i==="en"?"Result tree actions":"结果树操作"),dt(),v){const{data:e,query:r,active:n}=v;ge.textContent=O(r.title),fe.textContent=O(r.description),z(),Ee(n.evidence.snapshot(),ee),Pe(e,r,Se),De(B.checked?"opfs":"memory")}else k.textContent=i==="en"?"Starting SQLite/WASM…":"正在启动 SQLite/WASM…"}function re(){return pe.find(t=>t.id===W)??pe[0]}async function qe(t){k.textContent=i==="en"?`Opening ${t.toUpperCase()} SQLite/WASM…`:`正在打开 ${t.toUpperCase()} SQLite/WASM…`;const e=E;E=void 0,await e?.client.close();const r=await it(t);E=r,await be(r),await P(re(),r),De(t)}B.addEventListener("change",()=>{const t=B.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",t),qe(t).catch(N)});Y.addEventListener("click",async()=>{if(E){Y.disabled=!0;try{await E.client.reset(E.context),await be(E),await P(re(),E)}catch(t){N(t)}finally{Y.disabled=!1}}});X.addEventListener("click",()=>{b.querySelectorAll("details").forEach(t=>{t.open=!0})});Q.addEventListener("click",()=>{Q.disabled||(w="table",z())});H.addEventListener("click",()=>{w="tree",z()});tt.addEventListener("click",()=>{b.querySelectorAll("details").forEach((t,e)=>{t.open=e===0})});Ae.forEach(t=>{t.addEventListener("click",()=>{i=t.dataset.locale==="zh"?"zh":"en",localStorage.setItem("teaql-browser-locale",i),ve()})});function N(t){const e=t instanceof Error?t:new Error(String(t));k.textContent=`${e.name}: ${e.message}`,J.textContent=i==="en"?"Query failed":"查询失败",Le({error:e.name,message:e.message})}ve();W=re().id;V();qe(Ce).catch(N); diff --git a/dist/assets/object-location-xgYMemK6.js b/dist/assets/object-location-xgYMemK6.js new file mode 100644 index 0000000000000000000000000000000000000000..8c8bc4aa545522c7f661771b17aa4cfc4635714b --- /dev/null +++ b/dist/assets/object-location-xgYMemK6.js @@ -0,0 +1 @@ +import{f as u}from"./dynamic-search-BBmdgl4H.js";const i=n=>`${n.entity}\0${typeof n.id}:${String(n.id)}`;class V{constructor(){this.changes=new Map,this.originalVersions=new Map,this.newKeys=new Map,this.deletedKeys=new Map,this.traces=new Map}setTraceChain(s,e){this.traces.set(i(s),{key:Object.freeze({...s}),nodes:u(e)})}traceChain(s){return this.traces.get(i(s))?.nodes}set(s,e,t){if(!e.trim())throw new TypeError("field is required");const r=i(s),a=this.changes.get(r)??{key:Object.freeze({...s}),values:{}};a.values[e]=t,this.changes.set(r,a)}snapshot(){return[...this.changes.values()].map(s=>({key:Object.freeze({...s.key}),values:Object.freeze({...s.values})}))}change(s){return Object.freeze({...this.changes.get(i(s))?.values??{}})}mergeFrom(s){if(s!==this){for(const e of s.snapshotVersions())this.requireMatchingVersion(e.key,e.version);for(const e of s.snapshot())for(const[t,r]of Object.entries(e.values))this.set(e.key,t,r);for(const e of s.newKeys.values())this.markAsNew(e);for(const e of s.deletedKeys.values())this.markAsDeleted(e);for(const e of s.snapshotVersions())this.setOriginalVersion(e.key,e.version);for(const e of s.traces.values())this.setTraceChain(e.key,e.nodes)}}mergeEntityFrom(s,e){if(s===this)return;const t=s.originalVersion(e);t!==void 0&&this.requireMatchingVersion(e,t);for(const[a,c]of Object.entries(s.change(e)))this.set(e,a,c);s.isNew(e)&&this.markAsNew(e),s.isDeleted(e)&&this.markAsDeleted(e),t!==void 0&&this.setOriginalVersion(e,t);const r=s.traceChain(e);r&&this.setTraceChain(e,r)}hasPending(s){const e=i(s);return this.newKeys.has(e)||this.deletedKeys.has(e)||Object.keys(this.changes.get(e)?.values??{}).length>0}snapshotVersions(){return[...this.originalVersions.values()]}rekey(s,e){const t=i(s),r=i(e);if(t===r)return;const a=this.originalVersion(s);a!==void 0&&this.requireMatchingVersion(e,a);const c=this.changes.get(t);if(c){this.changes.delete(t);for(const[f,g]of Object.entries(c.values))this.set(e,f,g)}const h=this.originalVersions.get(t);h!==void 0&&(this.originalVersions.delete(t),this.originalVersions.set(r,{key:Object.freeze({...e}),version:h.version})),this.newKeys.delete(t)&&this.newKeys.set(r,Object.freeze({...e})),this.deletedKeys.delete(t)&&this.deletedKeys.set(r,Object.freeze({...e}));const l=this.traces.get(t);l&&(this.traces.delete(t),this.setTraceChain(e,l.nodes))}clearEntity(s){const e=i(s);this.changes.delete(e),this.newKeys.delete(e),this.deletedKeys.delete(e),this.traces.delete(e)}requireMatchingVersion(s,e){const t=this.originalVersion(s);if(t!==void 0&&t!==e)throw new Error("ENTITY_VERSION_CONFLICT: one graph cannot contain different loaded versions of the same typed entity")}setOriginalVersion(s,e){this.requireMatchingVersion(s,e),this.originalVersions.set(i(s),{key:Object.freeze({...s}),version:e})}acceptCommittedVersion(s,e){if(this.hasPending(s))throw new Error("ENTITY_COMMIT_PENDING: clear committed changes before accepting the persisted version");this.originalVersions.set(i(s),{key:Object.freeze({...s}),version:e})}originalVersion(s){return this.originalVersions.get(i(s))?.version}markAsNew(s){this.newKeys.set(i(s),Object.freeze({...s}))}isNew(s){return this.newKeys.has(i(s))}markAsDeleted(s){const e=i(s);this.changes.delete(e),this.deletedKeys.set(e,Object.freeze({...s}))}isDeleted(s){return this.deletedKeys.has(i(s))}clearCommitted(){this.changes.clear(),this.newKeys.clear(),this.deletedKeys.clear(),this.traces.clear()}}function d(n){const s=n.split("_");return s[0]+s.slice(1).map(e=>e?e[0].toUpperCase()+e.slice(1):"").join("")}function p(n,s){if(s==="snake_case")return n;const e=d(n);return s==="camelCase"||!e?e:e[0].toUpperCase()+e.slice(1)}function m(n){return n.replace(/~/g,"~0").replace(/\//g,"~1")}class o{constructor(s){this.segments=s}static root(){return new o([])}static property(s){return o.root().property(s)}property(s){return new o([...this.segments,{kind:"property",name:s}])}index(s){return new o([...this.segments,{kind:"index",index:s}])}prefixedBy(s){return new o([...s.segments,...this.segments])}modelPath(){return this.render(s=>s)}nativePath(){return this.render(d)}instancePath(s="camelCase"){return this.segments.map(e=>e.kind==="index"?String(e.index):m(p(e.name,s))).map(e=>`/${e}`).join("")}toString(){return this.nativePath()}render(s){let e="";for(const t of this.segments)t.kind==="index"?e+=`[${t.index}]`:e+=`${e?".":""}${s(t.name)}`;return e}}export{V as E,o as O}; diff --git a/dist/assets/orders-CQOGX0kN.js b/dist/assets/orders-CQOGX0kN.js new file mode 100644 index 0000000000000000000000000000000000000000..7d712fbdeea59f2a682869956b591f9018f3c8d5 --- /dev/null +++ b/dist/assets/orders-CQOGX0kN.js @@ -0,0 +1,2 @@ +import{S as yt,a as A,L as v,M as b,C as L,d as G,e as F,Q as z,R as pt,B as ft,U as gt,D as Ot,c as wt,b as qt}from"./dynamic-search-BBmdgl4H.js";import{E as T,O as w}from"./object-location-xgYMemK6.js";/* empty css */class c extends yt{orderBy(t,e){return this.order({field:t,expr:null,direction:e==="desc"?"Desc":"Asc"})}relationQuery(t,e,r="id",i="id",s=!0,h){return super.relationQuery(t,e,r,i,s,h)}}class Q{static teaqlTemporaryId=0;id;platform;name;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--Q.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerOrderList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),t){const r={...t};if(delete r.customerOrderList,Object.assign(this,r),t.platform&&typeof t.platform=="object"&&(this.platform=t.platform instanceof N?t.platform:N.fromRecord(t.platform),this.markLoaded("platform")),Array.isArray(t.customerOrderList)){const i=t.customerOrderList;this._customerOrderList=new A(i.map(s=>s instanceof $?s:$.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("customerOrderList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"Customer",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._customerOrderList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const r=new Q(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new Q({id:String(t)})}static teaqlBootstrapNew(t){return new Q().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const l=[{member:"id",canonical:"id"},{member:"platform",canonical:"platform"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(a=>!this.isLoaded(a.member));if(l)throw new L([{ruleId:"invalid_type",location:w.property(l.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"Customer",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o);const p=o.scopeFor(this.teaqlEntityKey());for(const[l,a]of this._customerOrderList.entries()){a.teaqlAttachRoot(this._root);const u=a.customer;(this.id===void 0||!a.isLoaded("customer")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updateCustomer(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("customer_order_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"Customer",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=p.scopeFor(this.teaqlEntityKey());for(const[g,y]of this._customerOrderList.entries()){y.teaqlAttachRoot(this._root);const O=y.customer;(this.id===void 0||!y.isLoaded("customer")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updateCustomer(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("customer_order_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}return this}const l=await e.executeMutation(p);for(const[f,g]of Object.entries(o.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,g);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update");const C=p.scopeFor(m);for(const[f,g]of this._customerOrderList.entries()){g.teaqlAttachRoot(this._root);const y=g.customer;(this.id===void 0||!g.isLoaded("customer")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updateCustomer(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("customer_order_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,platform:this.platform,name:this.name,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateName(t){return this.name=t,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updatePlatform(t){return this.platform=t?.id??t,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}customerOrderList(){return this._customerOrderList}}class B{static teaqlTemporaryId=0;id;customerOrder;productName;quantity;unitPrice;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--B.teaqlTemporaryId,writable:!0,enumerable:!1}),t){const r={...t};Object.assign(this,r),t.customerOrder&&typeof t.customerOrder=="object"&&(this.customerOrder=t.customerOrder instanceof $?t.customerOrder:$.fromRecord(t.customerOrder),this.markLoaded("customerOrder"))}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"OrderItem",id:this._ledgerId}}teaqlAttachRoot(t){return this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t),this}static fromRecord(t,e){const r=new B(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new B({id:String(t)})}static teaqlBootstrapNew(t){return new B().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const p=[{member:"id",canonical:"id"},{member:"customerOrder",canonical:"customer_order"},{member:"productName",canonical:"product_name"},{member:"quantity",canonical:"quantity"},{member:"unitPrice",canonical:"unit_price"},{member:"version",canonical:"version"}].find(l=>!this.isLoaded(l.member));if(p)throw new L([{ruleId:"invalid_type",location:w.property(p.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"OrderItem",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o),o.scopeFor(this.teaqlEntityKey())}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"OrderItem",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey()))return p.scopeFor(this.teaqlEntityKey()),this;const l=await e.executeMutation(p);for(const[C,f]of Object.entries(o.payload))C!=="id"&&C!=="version"&&this._root.set(this.teaqlEntityKey(),C,f);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();return this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update"),p.scopeFor(m),e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,customer_order:this.customerOrder,product_name:this.productName,quantity:this.quantity,unit_price:this.unitPrice,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateProductName(t){return this.productName=t,this.markLoaded("productName"),this._root.set(this.teaqlEntityKey(),"product_name",t),this}updateQuantity(t){return this.quantity=t,this.markLoaded("quantity"),this._root.set(this.teaqlEntityKey(),"quantity",t),this}updateUnitPrice(t){return this.unitPrice=t,this.markLoaded("unitPrice"),this._root.set(this.teaqlEntityKey(),"unit_price",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updateCustomerOrder(t){return this.customerOrder=t?.id??t,this.markLoaded("customerOrder"),this._root.set(this.teaqlEntityKey(),"customer_order",this.customerOrder),this}}class ${static teaqlTemporaryId=0;id;customer;status;orderNumber;orderDate;totalAmount;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--$.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_orderItemList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),t){const r={...t};if(delete r.orderItemList,Object.assign(this,r),t.customer&&typeof t.customer=="object"&&(this.customer=t.customer instanceof Q?t.customer:Q.fromRecord(t.customer),this.markLoaded("customer")),t.status&&typeof t.status=="object"&&(this.status=t.status instanceof S?t.status:S.fromRecord(t.status),this.markLoaded("status")),Array.isArray(t.orderItemList)){const i=t.orderItemList;this._orderItemList=new A(i.map(s=>s instanceof B?s:B.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("orderItemList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"CustomerOrder",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._orderItemList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const r=new $(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new $({id:String(t)})}static teaqlBootstrapNew(t){return new $().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const l=[{member:"id",canonical:"id"},{member:"customer",canonical:"customer"},{member:"status",canonical:"status"},{member:"orderNumber",canonical:"order_number"},{member:"orderDate",canonical:"order_date"},{member:"totalAmount",canonical:"total_amount"},{member:"version",canonical:"version"}].find(a=>!this.isLoaded(a.member));if(l)throw new L([{ruleId:"invalid_type",location:w.property(l.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"CustomerOrder",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o);const p=o.scopeFor(this.teaqlEntityKey());for(const[l,a]of this._orderItemList.entries()){a.teaqlAttachRoot(this._root);const u=a.customerOrder;(this.id===void 0||!a.isLoaded("customerOrder")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updateCustomerOrder(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("order_item_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"CustomerOrder",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=p.scopeFor(this.teaqlEntityKey());for(const[g,y]of this._orderItemList.entries()){y.teaqlAttachRoot(this._root);const O=y.customerOrder;(this.id===void 0||!y.isLoaded("customerOrder")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updateCustomerOrder(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("order_item_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}return this}const l=await e.executeMutation(p);for(const[f,g]of Object.entries(o.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,g);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update");const C=p.scopeFor(m);for(const[f,g]of this._orderItemList.entries()){g.teaqlAttachRoot(this._root);const y=g.customerOrder;(this.id===void 0||!g.isLoaded("customerOrder")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updateCustomerOrder(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("order_item_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,customer:this.customer,status:this.status,order_number:this.orderNumber,order_date:this.orderDate,total_amount:this.totalAmount,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateOrderNumber(t){return this.orderNumber=t,this.markLoaded("orderNumber"),this._root.set(this.teaqlEntityKey(),"order_number",t),this}updateOrderDate(t){return this.orderDate=t,this.markLoaded("orderDate"),this._root.set(this.teaqlEntityKey(),"order_date",t),this}updateTotalAmount(t){return this.totalAmount=t,this.markLoaded("totalAmount"),this._root.set(this.teaqlEntityKey(),"total_amount",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updateCustomer(t){return this.customer=t?.id??t,this.markLoaded("customer"),this._root.set(this.teaqlEntityKey(),"customer",this.customer),this}updateStatus(t){return this.status=t?.id??t,this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToNew(){return this.status="1001",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToPaid(){return this.status="1002",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}updateStatusToCancelled(){return this.status="1003",this.markLoaded("status"),this._root.set(this.teaqlEntityKey(),"status",this.status),this}orderItemList(){return this._orderItemList}}class S{static teaqlTemporaryId=0;platform;id;name;code;color;displayOrder;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--S.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerOrderList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),t){const r={...t};if(delete r.customerOrderList,Object.assign(this,r),t.platform&&typeof t.platform=="object"&&(this.platform=t.platform instanceof N?t.platform:N.fromRecord(t.platform),this.markLoaded("platform")),Array.isArray(t.customerOrderList)){const i=t.customerOrderList;this._customerOrderList=new A(i.map(s=>s instanceof $?s:$.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("customerOrderList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"OrderStatus",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._customerOrderList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const r=new S(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new S({id:String(t)})}static teaqlBootstrapNew(t){return new S().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const l=[{member:"platform",canonical:"platform"},{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"code",canonical:"code"},{member:"color",canonical:"color"},{member:"displayOrder",canonical:"display_order"},{member:"version",canonical:"version"}].find(a=>!this.isLoaded(a.member));if(l)throw new L([{ruleId:"invalid_type",location:w.property(l.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"OrderStatus",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o);const p=o.scopeFor(this.teaqlEntityKey());for(const[l,a]of this._customerOrderList.entries()){a.teaqlAttachRoot(this._root);const u=a.status;(this.id===void 0||!a.isLoaded("status")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updateStatus(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("customer_order_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"OrderStatus",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=p.scopeFor(this.teaqlEntityKey());for(const[g,y]of this._customerOrderList.entries()){y.teaqlAttachRoot(this._root);const O=y.status;(this.id===void 0||!y.isLoaded("status")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updateStatus(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("customer_order_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}return this}const l=await e.executeMutation(p);for(const[f,g]of Object.entries(o.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,g);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update");const C=p.scopeFor(m);for(const[f,g]of this._customerOrderList.entries()){g.teaqlAttachRoot(this._root);const y=g.status;(this.id===void 0||!g.isLoaded("status")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updateStatus(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("customer_order_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{platform:this.platform,id:this.id,name:this.name,code:this.code,color:this.color,display_order:this.displayOrder,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateName(t){return this.name=t,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",t),this}updateCode(t){return this.code=t,this.markLoaded("code"),this._root.set(this.teaqlEntityKey(),"code",t),this}updateColor(t){return this.color=t,this.markLoaded("color"),this._root.set(this.teaqlEntityKey(),"color",t),this}updateDisplayOrder(t){return this.displayOrder=t,this.markLoaded("displayOrder"),this._root.set(this.teaqlEntityKey(),"display_order",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updatePlatform(t){return this.platform=t?.id??t,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}customerOrderList(){return this._customerOrderList}}class N{static teaqlTemporaryId=0;id;name;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new T,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--N.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_orderStatusList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),Object.defineProperty(this,"_customerList",{value:t?.id?A.empty():new A,writable:!0,enumerable:!1}),t){const r={...t};if(delete r.orderStatusList,delete r.customerList,Object.assign(this,r),Array.isArray(t.orderStatusList)){const i=t.orderStatusList;this._orderStatusList=new A(i.map(s=>s instanceof S?s:S.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("orderStatusList")}if(Array.isArray(t.customerList)){const i=t.customerList;this._customerList=new A(i.map(s=>s instanceof Q?s:Q.fromRecord(s)),{totalCount:i.totalCount,aggregations:i.aggregations,summary:i.summary,facets:i.facets,isLoaded:i.isLoaded??!0}),this.markLoaded("customerList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),v.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._orderStatusList)e.teaqlAttachRoot(t);for(const e of this._customerList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const r=new N(t);return e?r.teaqlAttachRoot(e):r}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new N({id:String(t)})}static teaqlBootstrapNew(t){return new N().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new b(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new b(this._comment),async r=>(this.teaqlPreflightGraph(t,e,r),this.teaqlSaveWithinGraph(t,e,r)))}teaqlPreflightGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&h){const l=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(a=>!this.isLoaded(a.member));if(l)throw new L([{ruleId:"invalid_type",location:w.property(l.canonical),message:"Mutation requires a fully loaded entity"}])}const o=r.request({entity:"Platform",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);h&&e.preflightMutation(o);const p=o.scopeFor(this.teaqlEntityKey());for(const[l,a]of this._orderStatusList.entries()){a.teaqlAttachRoot(this._root);const u=a.platform;(this.id===void 0||!a.isLoaded("platform")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updatePlatform(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("order_status_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}for(const[l,a]of this._customerList.entries()){a.teaqlAttachRoot(this._root);const u=a.platform;(this.id===void 0||!a.isLoaded("platform")||(typeof u=="object"&&u!==null?u.id:u)!==this.id)&&a.updatePlatform(this);try{a.teaqlPreflightGraph(t,e,r,p)}catch(m){if(!(m instanceof L))throw m;const C=w.property("customer_list").index(l);throw new L(m.violations.map(f=>({...f,location:f.location.prefixedBy(C)})))}}}async teaqlSaveWithinGraph(t,e,r,i){i||new b(this._comment);const s=this._action,h=this._root.change(this.teaqlEntityKey()),o={entity:"Platform",action:this._action,payload:s==="Update"?h:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},p=r.request(o,i,this._comment).withLoadedSnapshot(v.forEntity(this)??new v);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=p.scopeFor(this.teaqlEntityKey());for(const[g,y]of this._orderStatusList.entries()){y.teaqlAttachRoot(this._root);const O=y.platform;(this.id===void 0||!y.isLoaded("platform")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updatePlatform(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("order_status_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}for(const[g,y]of this._customerList.entries()){y.teaqlAttachRoot(this._root);const O=y.platform;(this.id===void 0||!y.isLoaded("platform")||(typeof O=="object"&&O!==null?O.id:O)!==this.id)&&y.updatePlatform(this);try{await y.teaqlSaveWithinGraph(t,e,r,f)}catch(_){if(!(_ instanceof L))throw _;const P=w.property("customer_list").index(g);throw new L(_.violations.map(D=>({...D,location:D.location.prefixedBy(P)})))}}return this}const l=await e.executeMutation(p);for(const[f,g]of Object.entries(o.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,g);if(!l.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const a={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:v.forEntity(this)},u=this.teaqlEntityKey();Object.assign(this,l.persistedRecord),v.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const m=this.teaqlEntityKey();this._root.rekey(u,m),e.afterGraphRollback(()=>{Object.assign(this,a.payload),this._ledgerId=a.ledgerId,this._action=a.action,this._loadedFields=a.loadedFields,this._fullyLoaded=a.fullyLoaded,v.restoreFor(this,a.loadedSnapshot),this._root.rekey(m,u)}),this._loadedFields=new Set(Object.keys(l.persistedRecord)),this._fullyLoaded=!1,o.action!=="Delete"&&(this._action="Update");const C=p.scopeFor(m);for(const[f,g]of this._orderStatusList.entries()){g.teaqlAttachRoot(this._root);const y=g.platform;(this.id===void 0||!g.isLoaded("platform")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updatePlatform(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("order_status_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}for(const[f,g]of this._customerList.entries()){g.teaqlAttachRoot(this._root);const y=g.platform;(this.id===void 0||!g.isLoaded("platform")||(typeof y=="object"&&y!==null?y.id:y)!==this.id)&&g.updatePlatform(this);try{await g.teaqlSaveWithinGraph(t,e,r,C)}catch(O){if(!(O instanceof L))throw O;const _=w.property("customer_list").index(f);throw new L(O.violations.map(P=>({...P,location:P.location.prefixedBy(_)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(m),this.version!==void 0&&this._root.acceptCommittedVersion(m,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateName(t){return this.name=t,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}orderStatusList(){return this._orderStatusList}customerList(){return this._customerList}}const J=Object.freeze({Platform:Object.freeze({fields:Object.freeze({id:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",name:"name",version:"version"}),relations:Object.freeze({orderStatusList:"OrderStatus",customerList:"Customer"})}),OrderStatus:Object.freeze({fields:Object.freeze({platform:"integer",id:"integer",name:"string",code:"string",color:"string",display_order:"integer",displayOrder:"integer",version:"integer"}),queryFields:Object.freeze({platform:"platform",id:"id",name:"name",code:"code",color:"color",display_order:"displayOrder",displayOrder:"displayOrder",version:"version"}),relations:Object.freeze({platform:"Platform",customerOrderList:"CustomerOrder"})}),Customer:Object.freeze({fields:Object.freeze({id:"integer",platform:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",platform:"platform",name:"name",version:"version"}),relations:Object.freeze({platform:"Platform",customerOrderList:"CustomerOrder"})}),CustomerOrder:Object.freeze({fields:Object.freeze({id:"integer",customer:"integer",status:"integer",order_number:"string",orderNumber:"string",order_date:"date",orderDate:"date",total_amount:"decimal",totalAmount:"decimal",version:"integer"}),queryFields:Object.freeze({id:"id",customer:"customer",status:"status",order_number:"orderNumber",orderNumber:"orderNumber",order_date:"orderDate",orderDate:"orderDate",total_amount:"totalAmount",totalAmount:"totalAmount",version:"version"}),relations:Object.freeze({customer:"Customer",status:"OrderStatus",orderItemList:"OrderItem"})}),OrderItem:Object.freeze({fields:Object.freeze({id:"integer",customer_order:"integer",customerOrder:"integer",product_name:"string",productName:"string",quantity:"integer",unit_price:"decimal",unitPrice:"decimal",version:"integer"}),queryFields:Object.freeze({id:"id",customer_order:"customerOrder",customerOrder:"customerOrder",product_name:"productName",productName:"productName",quantity:"quantity",unit_price:"unitPrice",unitPrice:"unitPrice",version:"version"}),relations:Object.freeze({customer_order:"CustomerOrder",customerOrder:"CustomerOrder"})})});class st{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("Platform"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new vt(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectOrderStatusListWith(t){return this.query.relationQuery("orderStatusList",t.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectOrderStatusListWith",relation:"orderStatusList"}),this}selectCustomerListWith(t){return this.query.relationQuery("customerList",t.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectCustomerListWith",relation:"customerList"}),this}haveOrderStatuses(){return this.withOrderStatusListMatching({toQuery:()=>new c("OrderStatus")})}haveNoOrderStatuses(){return this.withoutOrderStatusListMatching({toQuery:()=>new c("OrderStatus")})}withOrderStatusListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"platform"}}}),this}withoutOrderStatusListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"platform"}}}),this}haveCustomers(){return this.withCustomerListMatching({toQuery:()=>new c("Customer")})}haveNoCustomers(){return this.withoutCustomerListMatching({toQuery:()=>new c("Customer")})}withCustomerListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"platform"}}}),this}withoutCustomerListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"platform"}}}),this}countOrderStatuses(){return this.countOrderStatusesAs("countOrderStatuses")}countOrderStatusesAs(t){const e=new c("OrderStatus").filter({version:{$gte:1}});return this.countOrderStatusesWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countOrderStatusesAs",relation:"orderStatusList",alias:t},this}countOrderStatusesWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"relation-count",method:"countOrderStatusesWith",relation:"orderStatusList",alias:t}),this}minDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.minDisplayOrderOfOrderStatusesAs("minOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}minDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"minDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}maxDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.maxDisplayOrderOfOrderStatusesAs("maxOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}maxDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"maxDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}sumDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.sumDisplayOrderOfOrderStatusesAs("sumOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}sumDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"sumDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}avgDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.avgDisplayOrderOfOrderStatusesAs("avgOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}avgDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"avgDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}standardDeviationDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.standardDeviationDisplayOrderOfOrderStatusesAs("standardDeviationOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}standardDeviationDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"standardDeviationDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs("squareRootOfPopulationStandardDeviationOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}sampleVarianceDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.sampleVarianceDisplayOrderOfOrderStatusesAs("sampleVarianceOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}sampleVarianceDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"sampleVarianceDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}samplePopulationVarianceDisplayOrderOfOrderStatuses(){const t=new c("OrderStatus").filter({version:{$gte:1}});return this.samplePopulationVarianceDisplayOrderOfOrderStatusesAs("samplePopulationVarianceOfDisplayOrderOfOrderStatuses",{toQuery:()=>t})}samplePopulationVarianceDisplayOrderOfOrderStatusesAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","displayOrder",t),this.query.relationAggregate("orderStatusList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceDisplayOrderOfOrderStatusesAs",relation:"orderStatusList",alias:t}),this}countCustomers(){return this.countCustomersAs("countCustomers")}countCustomersAs(t){const e=new c("Customer").filter({version:{$gte:1}});return this.countCustomersWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomersAs",relation:"customerList",alias:t},this}countCustomersWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("customerList",t,r,!0,{kind:"relation-count",method:"countCustomersWith",relation:"customerList",alias:t}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(t){return this.filters.push({name:{$contains:t}}),this}withNameIs(t){return this.filters.push({name:{$eq:t}}),this}withNameIsNot(t){return this.filters.push({name:{$ne:t}}),this}withNameIn(...t){return this.filters.push({name:{$in:t}}),this}withNameNotIn(...t){return this.filters.push({name:{$notIn:t}}),this}withNameGreaterThan(t){return this.filters.push({name:{$gt:t}}),this}withNameGreaterThanOrEqualTo(t){return this.filters.push({name:{$gte:t}}),this}withNameLessThan(t){return this.filters.push({name:{$lt:t}}),this}withNameLessThanOrEqualTo(t){return this.filters.push({name:{$lte:t}}),this}withNameBetween(t,e){return this.filters.push({name:{$between:[t,e]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(t){return this.filters.push({name:{$notContains:t}}),this}withNameStartingWith(t){return this.filters.push({name:{$startsWith:t}}),this}withNameNotStartingWith(t){return this.filters.push({name:{$notStartsWith:t}}),this}withNameEndingWith(t){return this.filters.push({name:{$endsWith:t}}),this}withNameNotEndingWith(t){return this.filters.push({name:{$notEndsWith:t}}),this}withNameSoundingLike(t){return this.filters.push({name:{$soundLike:t}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(t){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof N?o:N.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof N?u:N.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof N?o:N.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class vt{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new N}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class ot{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("OrderStatus"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new It(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["platform","id","name","code","color","displayOrder","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectCode(){return this.query.select(["code"]),this}selectColor(){return this.query.select(["color"]),this}selectDisplayOrder(){return this.query.select(["displayOrder"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(t){return this.query.select(["platform"]),this.query.relationQuery("platform",t.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(t){return this.filters.push({platform:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutPlatformMatching(t){return this.filters.push({platform:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}selectCustomerOrderListWith(t){return this.query.relationQuery("customerOrderList",t.toQuery(),"id","status",!0,{kind:"relation-select",method:"selectCustomerOrderListWith",relation:"customerOrderList"}),this}haveCustomerOrders(){return this.withCustomerOrderListMatching({toQuery:()=>new c("CustomerOrder")})}haveNoCustomerOrders(){return this.withoutCustomerOrderListMatching({toQuery:()=>new c("CustomerOrder")})}withCustomerOrderListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"status"}}}),this}withoutCustomerOrderListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"status"}}}),this}countCustomerOrders(){return this.countCustomerOrdersAs("countCustomerOrders")}countCustomerOrdersAs(t){const e=new c("CustomerOrder").filter({version:{$gte:1}});return this.countCustomerOrdersWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomerOrdersAs",relation:"customerOrderList",alias:t},this}countCustomerOrdersWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"relation-count",method:"countCustomerOrdersWith",relation:"customerOrderList",alias:t}),this}minTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.minTotalAmountOfCustomerOrdersAs("minOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}minTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"minTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}maxTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.maxTotalAmountOfCustomerOrdersAs("maxOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}maxTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"maxTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}sumTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.sumTotalAmountOfCustomerOrdersAs("sumOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}sumTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"sumTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}avgTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.avgTotalAmountOfCustomerOrdersAs("avgOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}avgTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"avgTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}standardDeviationTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.standardDeviationTotalAmountOfCustomerOrdersAs("standardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}standardDeviationTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"standardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs("squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}sampleVarianceTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.sampleVarianceTotalAmountOfCustomerOrdersAs("sampleVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}sampleVarianceTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"sampleVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}samplePopulationVarianceTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs("samplePopulationVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}samplePopulationVarianceTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}filterByPlatform(t){return this.filters.push({platform:{$eq:t}}),this}filterByPlatformIn(...t){return this.filters.push({platform:{$in:t}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(t){return this.filters.push({name:{$contains:t}}),this}withNameIs(t){return this.filters.push({name:{$eq:t}}),this}withNameIsNot(t){return this.filters.push({name:{$ne:t}}),this}withNameIn(...t){return this.filters.push({name:{$in:t}}),this}withNameNotIn(...t){return this.filters.push({name:{$notIn:t}}),this}withNameGreaterThan(t){return this.filters.push({name:{$gt:t}}),this}withNameGreaterThanOrEqualTo(t){return this.filters.push({name:{$gte:t}}),this}withNameLessThan(t){return this.filters.push({name:{$lt:t}}),this}withNameLessThanOrEqualTo(t){return this.filters.push({name:{$lte:t}}),this}withNameBetween(t,e){return this.filters.push({name:{$between:[t,e]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(t){return this.filters.push({name:{$notContains:t}}),this}withNameStartingWith(t){return this.filters.push({name:{$startsWith:t}}),this}withNameNotStartingWith(t){return this.filters.push({name:{$notStartsWith:t}}),this}withNameEndingWith(t){return this.filters.push({name:{$endsWith:t}}),this}withNameNotEndingWith(t){return this.filters.push({name:{$notEndsWith:t}}),this}withNameSoundingLike(t){return this.filters.push({name:{$soundLike:t}}),this}withCodeContaining(t){return this.filters.push({code:{$contains:t}}),this}withCodeIs(t){return this.filters.push({code:{$eq:t}}),this}withCodeIsNot(t){return this.filters.push({code:{$ne:t}}),this}withCodeIn(...t){return this.filters.push({code:{$in:t}}),this}withCodeNotIn(...t){return this.filters.push({code:{$notIn:t}}),this}withCodeGreaterThan(t){return this.filters.push({code:{$gt:t}}),this}withCodeGreaterThanOrEqualTo(t){return this.filters.push({code:{$gte:t}}),this}withCodeLessThan(t){return this.filters.push({code:{$lt:t}}),this}withCodeLessThanOrEqualTo(t){return this.filters.push({code:{$lte:t}}),this}withCodeBetween(t,e){return this.filters.push({code:{$between:[t,e]}}),this}withCodeIsKnown(){return this.filters.push({code:{$isNull:!1}}),this}withCodeIsUnknown(){return this.filters.push({code:{$isNull:!0}}),this}withCodeNotContaining(t){return this.filters.push({code:{$notContains:t}}),this}withCodeStartingWith(t){return this.filters.push({code:{$startsWith:t}}),this}withCodeNotStartingWith(t){return this.filters.push({code:{$notStartsWith:t}}),this}withCodeEndingWith(t){return this.filters.push({code:{$endsWith:t}}),this}withCodeNotEndingWith(t){return this.filters.push({code:{$notEndsWith:t}}),this}withCodeSoundingLike(t){return this.filters.push({code:{$soundLike:t}}),this}withColorContaining(t){return this.filters.push({color:{$contains:t}}),this}withColorIs(t){return this.filters.push({color:{$eq:t}}),this}withColorIsNot(t){return this.filters.push({color:{$ne:t}}),this}withColorIn(...t){return this.filters.push({color:{$in:t}}),this}withColorNotIn(...t){return this.filters.push({color:{$notIn:t}}),this}withColorGreaterThan(t){return this.filters.push({color:{$gt:t}}),this}withColorGreaterThanOrEqualTo(t){return this.filters.push({color:{$gte:t}}),this}withColorLessThan(t){return this.filters.push({color:{$lt:t}}),this}withColorLessThanOrEqualTo(t){return this.filters.push({color:{$lte:t}}),this}withColorBetween(t,e){return this.filters.push({color:{$between:[t,e]}}),this}withColorIsKnown(){return this.filters.push({color:{$isNull:!1}}),this}withColorIsUnknown(){return this.filters.push({color:{$isNull:!0}}),this}withColorNotContaining(t){return this.filters.push({color:{$notContains:t}}),this}withColorStartingWith(t){return this.filters.push({color:{$startsWith:t}}),this}withColorNotStartingWith(t){return this.filters.push({color:{$notStartsWith:t}}),this}withColorEndingWith(t){return this.filters.push({color:{$endsWith:t}}),this}withColorNotEndingWith(t){return this.filters.push({color:{$notEndsWith:t}}),this}withColorSoundingLike(t){return this.filters.push({color:{$soundLike:t}}),this}withDisplayOrderIs(t){return this.filters.push({displayOrder:{$eq:t}}),this}withDisplayOrderIsNot(t){return this.filters.push({displayOrder:{$ne:t}}),this}withDisplayOrderIn(...t){return this.filters.push({displayOrder:{$in:t}}),this}withDisplayOrderNotIn(...t){return this.filters.push({displayOrder:{$notIn:t}}),this}withDisplayOrderGreaterThan(t){return this.filters.push({displayOrder:{$gt:t}}),this}withDisplayOrderGreaterThanOrEqualTo(t){return this.filters.push({displayOrder:{$gte:t}}),this}withDisplayOrderLessThan(t){return this.filters.push({displayOrder:{$lt:t}}),this}withDisplayOrderLessThanOrEqualTo(t){return this.filters.push({displayOrder:{$lte:t}}),this}withDisplayOrderBetween(t,e){return this.filters.push({displayOrder:{$between:[t,e]}}),this}withDisplayOrderIsKnown(){return this.filters.push({displayOrder:{$isNull:!1}}),this}withDisplayOrderIsUnknown(){return this.filters.push({displayOrder:{$isNull:!0}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByCodeAscending(){return this.query.orderBy("code","asc"),this}orderByCodeDescending(){return this.query.orderBy("code","desc"),this}orderByColorAscending(){return this.query.orderBy("color","asc"),this}orderByColorDescending(){return this.query.orderBy("color","desc"),this}orderByDisplayOrderAscending(){return this.query.orderBy("displayOrder","asc"),this}orderByDisplayOrderDescending(){return this.query.orderBy("displayOrder","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}minDisplayOrder(){return this.minDisplayOrderAs("minOfDisplayOrder")}minDisplayOrderAs(t){return this.query.aggregate("min","displayOrder",t),this}maxDisplayOrder(){return this.maxDisplayOrderAs("maxOfDisplayOrder")}maxDisplayOrderAs(t){return this.query.aggregate("max","displayOrder",t),this}sumDisplayOrder(){return this.sumDisplayOrderAs("sumOfDisplayOrder")}sumDisplayOrderAs(t){return this.query.aggregate("sum","displayOrder",t),this}avgDisplayOrder(){return this.avgDisplayOrderAs("avgOfDisplayOrder")}avgDisplayOrderAs(t){return this.query.aggregate("avg","displayOrder",t),this}standardDeviationDisplayOrder(){return this.standardDeviationDisplayOrderAs("standardDeviationOfDisplayOrder")}standardDeviationDisplayOrderAs(t){return this.query.aggregate("stddev","displayOrder",t),this}squareRootOfPopulationStandardDeviationDisplayOrder(){return this.squareRootOfPopulationStandardDeviationDisplayOrderAs("squareRootOfPopulationStandardDeviationOfDisplayOrder")}squareRootOfPopulationStandardDeviationDisplayOrderAs(t){return this.query.aggregate("stddev_pop","displayOrder",t),this}sampleVarianceDisplayOrder(){return this.sampleVarianceDisplayOrderAs("sampleVarianceOfDisplayOrder")}sampleVarianceDisplayOrderAs(t){return this.query.aggregate("var_samp","displayOrder",t),this}samplePopulationVarianceDisplayOrder(){return this.samplePopulationVarianceDisplayOrderAs("samplePopulationVarianceOfDisplayOrder")}samplePopulationVarianceDisplayOrderAs(t){return this.query.aggregate("var_pop","displayOrder",t),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(t){return this.query.groupBy("platform"),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(t){return this.query.groupBy("name"),this}groupByCode(){return this.query.groupBy("code"),this}groupByCodeAs(t){return this.query.groupBy("code"),this}groupByColor(){return this.query.groupBy("color"),this}groupByColorAs(t){return this.query.groupBy("color"),this}groupByDisplayOrder(){return this.query.groupBy("displayOrder"),this}groupByDisplayOrderAs(t){return this.query.groupBy("displayOrder"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByPlatformAs(t,e,r=!0){return this.query.facetBy(t,"platform",e,r,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof S?o:S.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof S?u:S.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof S?o:S.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class It{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new S}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class nt{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("Customer"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new Lt(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","platform","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(t){return this.query.select(["platform"]),this.query.relationQuery("platform",t.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(t){return this.filters.push({platform:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutPlatformMatching(t){return this.filters.push({platform:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}selectCustomerOrderListWith(t){return this.query.relationQuery("customerOrderList",t.toQuery(),"id","customer",!0,{kind:"relation-select",method:"selectCustomerOrderListWith",relation:"customerOrderList"}),this}haveCustomerOrders(){return this.withCustomerOrderListMatching({toQuery:()=>new c("CustomerOrder")})}haveNoCustomerOrders(){return this.withoutCustomerOrderListMatching({toQuery:()=>new c("CustomerOrder")})}withCustomerOrderListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"customer"}}}),this}withoutCustomerOrderListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"customer"}}}),this}countCustomerOrders(){return this.countCustomerOrdersAs("countCustomerOrders")}countCustomerOrdersAs(t){const e=new c("CustomerOrder").filter({version:{$gte:1}});return this.countCustomerOrdersWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countCustomerOrdersAs",relation:"customerOrderList",alias:t},this}countCustomerOrdersWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"relation-count",method:"countCustomerOrdersWith",relation:"customerOrderList",alias:t}),this}minTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.minTotalAmountOfCustomerOrdersAs("minOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}minTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"minTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}maxTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.maxTotalAmountOfCustomerOrdersAs("maxOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}maxTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"maxTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}sumTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.sumTotalAmountOfCustomerOrdersAs("sumOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}sumTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"sumTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}avgTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.avgTotalAmountOfCustomerOrdersAs("avgOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}avgTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"avgTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}standardDeviationTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.standardDeviationTotalAmountOfCustomerOrdersAs("standardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}standardDeviationTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"standardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs("squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}sampleVarianceTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.sampleVarianceTotalAmountOfCustomerOrdersAs("sampleVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}sampleVarianceTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"sampleVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}samplePopulationVarianceTotalAmountOfCustomerOrders(){const t=new c("CustomerOrder").filter({version:{$gte:1}});return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs("samplePopulationVarianceOfTotalAmountOfCustomerOrders",{toQuery:()=>t})}samplePopulationVarianceTotalAmountOfCustomerOrdersAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","totalAmount",t),this.query.relationAggregate("customerOrderList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceTotalAmountOfCustomerOrdersAs",relation:"customerOrderList",alias:t}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByPlatform(t){return this.filters.push({platform:{$eq:t}}),this}filterByPlatformIn(...t){return this.filters.push({platform:{$in:t}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withNameContaining(t){return this.filters.push({name:{$contains:t}}),this}withNameIs(t){return this.filters.push({name:{$eq:t}}),this}withNameIsNot(t){return this.filters.push({name:{$ne:t}}),this}withNameIn(...t){return this.filters.push({name:{$in:t}}),this}withNameNotIn(...t){return this.filters.push({name:{$notIn:t}}),this}withNameGreaterThan(t){return this.filters.push({name:{$gt:t}}),this}withNameGreaterThanOrEqualTo(t){return this.filters.push({name:{$gte:t}}),this}withNameLessThan(t){return this.filters.push({name:{$lt:t}}),this}withNameLessThanOrEqualTo(t){return this.filters.push({name:{$lte:t}}),this}withNameBetween(t,e){return this.filters.push({name:{$between:[t,e]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(t){return this.filters.push({name:{$notContains:t}}),this}withNameStartingWith(t){return this.filters.push({name:{$startsWith:t}}),this}withNameNotStartingWith(t){return this.filters.push({name:{$notStartsWith:t}}),this}withNameEndingWith(t){return this.filters.push({name:{$endsWith:t}}),this}withNameNotEndingWith(t){return this.filters.push({name:{$notEndsWith:t}}),this}withNameSoundingLike(t){return this.filters.push({name:{$soundLike:t}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(t){return this.query.groupBy("platform"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(t){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByPlatformAs(t,e,r=!0){return this.query.facetBy(t,"platform",e,r,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof Q?o:Q.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof Q?u:Q.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof Q?o:Q.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class Lt{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new Q}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class at{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("CustomerOrder"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new At(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","customer","status","orderNumber","orderDate","totalAmount","version"]),this}selectId(){return this.query.select(["id"]),this}selectOrderNumber(){return this.query.select(["orderNumber"]),this}selectOrderDate(){return this.query.select(["orderDate"]),this}selectTotalAmount(){return this.query.select(["totalAmount"]),this}selectVersion(){return this.query.select(["version"]),this}selectCustomerWith(t){return this.query.select(["customer"]),this.query.relationQuery("customer",t.toQuery(),"customer","id",!1,{kind:"relation-select",method:"selectCustomerWith",relation:"customer"}),this}selectStatusWith(t){return this.query.select(["status"]),this.query.relationQuery("status",t.toQuery(),"status","id",!1,{kind:"relation-select",method:"selectStatusWith",relation:"status"}),this}withCustomerMatching(t){return this.filters.push({customer:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutCustomerMatching(t){return this.filters.push({customer:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}withStatusMatching(t){return this.filters.push({status:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutStatusMatching(t){return this.filters.push({status:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}selectOrderItemListWith(t){return this.query.relationQuery("orderItemList",t.toQuery(),"id","customerOrder",!0,{kind:"relation-select",method:"selectOrderItemListWith",relation:"orderItemList"}),this}haveOrderItems(){return this.withOrderItemListMatching({toQuery:()=>new c("OrderItem")})}haveNoOrderItems(){return this.withoutOrderItemListMatching({toQuery:()=>new c("OrderItem")})}withOrderItemListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"customerOrder"}}}),this}withoutOrderItemListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"customerOrder"}}}),this}countOrderItems(){return this.countOrderItemsAs("countOrderItems")}countOrderItemsAs(t){const e=new c("OrderItem").filter({version:{$gte:1}});return this.countOrderItemsWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countOrderItemsAs",relation:"orderItemList",alias:t},this}countOrderItemsWith(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("Count","id",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"relation-count",method:"countOrderItemsWith",relation:"orderItemList",alias:t}),this}minQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.minQuantityOfOrderItemsAs("minOfQuantityOfOrderItems",{toQuery:()=>t})}minQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"minQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}maxQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.maxQuantityOfOrderItemsAs("maxOfQuantityOfOrderItems",{toQuery:()=>t})}maxQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"maxQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}sumQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.sumQuantityOfOrderItemsAs("sumOfQuantityOfOrderItems",{toQuery:()=>t})}sumQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"sumQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}avgQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.avgQuantityOfOrderItemsAs("avgOfQuantityOfOrderItems",{toQuery:()=>t})}avgQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"avgQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}standardDeviationQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.standardDeviationQuantityOfOrderItemsAs("standardDeviationOfQuantityOfOrderItems",{toQuery:()=>t})}standardDeviationQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"standardDeviationQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}squareRootOfPopulationStandardDeviationQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs("squareRootOfPopulationStandardDeviationOfQuantityOfOrderItems",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}sampleVarianceQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.sampleVarianceQuantityOfOrderItemsAs("sampleVarianceOfQuantityOfOrderItems",{toQuery:()=>t})}sampleVarianceQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"sampleVarianceQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}samplePopulationVarianceQuantityOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.samplePopulationVarianceQuantityOfOrderItemsAs("samplePopulationVarianceOfQuantityOfOrderItems",{toQuery:()=>t})}samplePopulationVarianceQuantityOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","quantity",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceQuantityOfOrderItemsAs",relation:"orderItemList",alias:t}),this}minUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.minUnitPriceOfOrderItemsAs("minOfUnitPriceOfOrderItems",{toQuery:()=>t})}minUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("min","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"minUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}maxUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.maxUnitPriceOfOrderItemsAs("maxOfUnitPriceOfOrderItems",{toQuery:()=>t})}maxUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("max","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"maxUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}sumUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.sumUnitPriceOfOrderItemsAs("sumOfUnitPriceOfOrderItems",{toQuery:()=>t})}sumUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("sum","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"sumUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}avgUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.avgUnitPriceOfOrderItemsAs("avgOfUnitPriceOfOrderItems",{toQuery:()=>t})}avgUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("avg","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"avgUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}standardDeviationUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.standardDeviationUnitPriceOfOrderItemsAs("standardDeviationOfUnitPriceOfOrderItems",{toQuery:()=>t})}standardDeviationUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"standardDeviationUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}squareRootOfPopulationStandardDeviationUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs("squareRootOfPopulationStandardDeviationOfUnitPriceOfOrderItems",{toQuery:()=>t})}squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("stddev_pop","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}sampleVarianceUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.sampleVarianceUnitPriceOfOrderItemsAs("sampleVarianceOfUnitPriceOfOrderItems",{toQuery:()=>t})}sampleVarianceUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_samp","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"sampleVarianceUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}samplePopulationVarianceUnitPriceOfOrderItems(){const t=new c("OrderItem").filter({version:{$gte:1}});return this.samplePopulationVarianceUnitPriceOfOrderItemsAs("samplePopulationVarianceOfUnitPriceOfOrderItems",{toQuery:()=>t})}samplePopulationVarianceUnitPriceOfOrderItemsAs(t,e){const r=e.toQuery().clone();return r.aggregateItems=[],r.aggregate("var_pop","unitPrice",t),this.query.relationAggregate("orderItemList",t,r,!0,{kind:"aggregate",method:"samplePopulationVarianceUnitPriceOfOrderItemsAs",relation:"orderItemList",alias:t}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByCustomer(t){return this.filters.push({customer:{$eq:t}}),this}filterByCustomerIn(...t){return this.filters.push({customer:{$in:t}}),this}withCustomerIsKnown(){return this.filters.push({customer:{$isNull:!1}}),this}withCustomerIsUnknown(){return this.filters.push({customer:{$isNull:!0}}),this}filterByStatus(t){return this.filters.push({status:{$eq:t}}),this}filterByStatusIn(...t){return this.filters.push({status:{$in:t}}),this}withStatusIsKnown(){return this.filters.push({status:{$isNull:!1}}),this}withStatusIsUnknown(){return this.filters.push({status:{$isNull:!0}}),this}withStatusIsNew(){return this.filters.push({status:{$eq:"1001"}}),this}withStatusIsPaid(){return this.filters.push({status:{$eq:"1002"}}),this}withStatusIsCancelled(){return this.filters.push({status:{$eq:"1003"}}),this}withOrderNumberContaining(t){return this.filters.push({orderNumber:{$contains:t}}),this}withOrderNumberIs(t){return this.filters.push({orderNumber:{$eq:t}}),this}withOrderNumberIsNot(t){return this.filters.push({orderNumber:{$ne:t}}),this}withOrderNumberIn(...t){return this.filters.push({orderNumber:{$in:t}}),this}withOrderNumberNotIn(...t){return this.filters.push({orderNumber:{$notIn:t}}),this}withOrderNumberGreaterThan(t){return this.filters.push({orderNumber:{$gt:t}}),this}withOrderNumberGreaterThanOrEqualTo(t){return this.filters.push({orderNumber:{$gte:t}}),this}withOrderNumberLessThan(t){return this.filters.push({orderNumber:{$lt:t}}),this}withOrderNumberLessThanOrEqualTo(t){return this.filters.push({orderNumber:{$lte:t}}),this}withOrderNumberBetween(t,e){return this.filters.push({orderNumber:{$between:[t,e]}}),this}withOrderNumberIsKnown(){return this.filters.push({orderNumber:{$isNull:!1}}),this}withOrderNumberIsUnknown(){return this.filters.push({orderNumber:{$isNull:!0}}),this}withOrderNumberNotContaining(t){return this.filters.push({orderNumber:{$notContains:t}}),this}withOrderNumberStartingWith(t){return this.filters.push({orderNumber:{$startsWith:t}}),this}withOrderNumberNotStartingWith(t){return this.filters.push({orderNumber:{$notStartsWith:t}}),this}withOrderNumberEndingWith(t){return this.filters.push({orderNumber:{$endsWith:t}}),this}withOrderNumberNotEndingWith(t){return this.filters.push({orderNumber:{$notEndsWith:t}}),this}withOrderNumberSoundingLike(t){return this.filters.push({orderNumber:{$soundLike:t}}),this}withOrderDateIs(t){return this.filters.push({orderDate:{$eq:t}}),this}withOrderDateIsNot(t){return this.filters.push({orderDate:{$ne:t}}),this}withOrderDateIn(...t){return this.filters.push({orderDate:{$in:t}}),this}withOrderDateNotIn(...t){return this.filters.push({orderDate:{$notIn:t}}),this}withOrderDateGreaterThan(t){return this.filters.push({orderDate:{$gt:t}}),this}withOrderDateGreaterThanOrEqualTo(t){return this.filters.push({orderDate:{$gte:t}}),this}withOrderDateLessThan(t){return this.filters.push({orderDate:{$lt:t}}),this}withOrderDateLessThanOrEqualTo(t){return this.filters.push({orderDate:{$lte:t}}),this}withOrderDateBetween(t,e){return this.filters.push({orderDate:{$between:[t,e]}}),this}withOrderDateIsKnown(){return this.filters.push({orderDate:{$isNull:!1}}),this}withOrderDateIsUnknown(){return this.filters.push({orderDate:{$isNull:!0}}),this}withTotalAmountIs(t){return this.filters.push({totalAmount:{$eq:t}}),this}withTotalAmountIsNot(t){return this.filters.push({totalAmount:{$ne:t}}),this}withTotalAmountIn(...t){return this.filters.push({totalAmount:{$in:t}}),this}withTotalAmountNotIn(...t){return this.filters.push({totalAmount:{$notIn:t}}),this}withTotalAmountGreaterThan(t){return this.filters.push({totalAmount:{$gt:t}}),this}withTotalAmountGreaterThanOrEqualTo(t){return this.filters.push({totalAmount:{$gte:t}}),this}withTotalAmountLessThan(t){return this.filters.push({totalAmount:{$lt:t}}),this}withTotalAmountLessThanOrEqualTo(t){return this.filters.push({totalAmount:{$lte:t}}),this}withTotalAmountBetween(t,e){return this.filters.push({totalAmount:{$between:[t,e]}}),this}withTotalAmountIsKnown(){return this.filters.push({totalAmount:{$isNull:!1}}),this}withTotalAmountIsUnknown(){return this.filters.push({totalAmount:{$isNull:!0}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByOrderNumberAscending(){return this.query.orderBy("orderNumber","asc"),this}orderByOrderNumberDescending(){return this.query.orderBy("orderNumber","desc"),this}orderByOrderDateAscending(){return this.query.orderBy("orderDate","asc"),this}orderByOrderDateDescending(){return this.query.orderBy("orderDate","desc"),this}orderByTotalAmountAscending(){return this.query.orderBy("totalAmount","asc"),this}orderByTotalAmountDescending(){return this.query.orderBy("totalAmount","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}minTotalAmount(){return this.minTotalAmountAs("minOfTotalAmount")}minTotalAmountAs(t){return this.query.aggregate("min","totalAmount",t),this}maxTotalAmount(){return this.maxTotalAmountAs("maxOfTotalAmount")}maxTotalAmountAs(t){return this.query.aggregate("max","totalAmount",t),this}sumTotalAmount(){return this.sumTotalAmountAs("sumOfTotalAmount")}sumTotalAmountAs(t){return this.query.aggregate("sum","totalAmount",t),this}avgTotalAmount(){return this.avgTotalAmountAs("avgOfTotalAmount")}avgTotalAmountAs(t){return this.query.aggregate("avg","totalAmount",t),this}standardDeviationTotalAmount(){return this.standardDeviationTotalAmountAs("standardDeviationOfTotalAmount")}standardDeviationTotalAmountAs(t){return this.query.aggregate("stddev","totalAmount",t),this}squareRootOfPopulationStandardDeviationTotalAmount(){return this.squareRootOfPopulationStandardDeviationTotalAmountAs("squareRootOfPopulationStandardDeviationOfTotalAmount")}squareRootOfPopulationStandardDeviationTotalAmountAs(t){return this.query.aggregate("stddev_pop","totalAmount",t),this}sampleVarianceTotalAmount(){return this.sampleVarianceTotalAmountAs("sampleVarianceOfTotalAmount")}sampleVarianceTotalAmountAs(t){return this.query.aggregate("var_samp","totalAmount",t),this}samplePopulationVarianceTotalAmount(){return this.samplePopulationVarianceTotalAmountAs("samplePopulationVarianceOfTotalAmount")}samplePopulationVarianceTotalAmountAs(t){return this.query.aggregate("var_pop","totalAmount",t),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByCustomer(){return this.query.groupBy("customer"),this}groupByCustomerAs(t){return this.query.groupBy("customer"),this}groupByStatus(){return this.query.groupBy("status"),this}groupByStatusAs(t){return this.query.groupBy("status"),this}groupByOrderNumber(){return this.query.groupBy("orderNumber"),this}groupByOrderNumberAs(t){return this.query.groupBy("orderNumber"),this}groupByOrderDate(){return this.query.groupBy("orderDate"),this}groupByOrderDateAs(t){return this.query.groupBy("orderDate"),this}groupByTotalAmount(){return this.query.groupBy("totalAmount"),this}groupByTotalAmountAs(t){return this.query.groupBy("totalAmount"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByCustomerAs(t,e,r=!0){return this.query.facetBy(t,"customer",e,r,{kind:"facet",method:"facetByCustomerAs",relation:"customer",alias:t}),this}facetByStatusAs(t,e,r=!0){return this.query.facetBy(t,"status",e,r,{kind:"facet",method:"facetByStatusAs",relation:"status",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof $?o:$.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof $?u:$.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof $?o:$.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class At{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new $}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class ut{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new c("OrderItem"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const r=this.query.clone();this.filters.length>0&&r.filter({$and:this.filters});const i=G(r,t,J,e);return this.query=i.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...i.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new _t(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,r)=>this.executeForStreamInternal(e,r),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,r){return this.query.optimizePaginationWithIdSetConfig(t,e,r),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","customerOrder","productName","quantity","unitPrice","version"]),this}selectId(){return this.query.select(["id"]),this}selectProductName(){return this.query.select(["productName"]),this}selectQuantity(){return this.query.select(["quantity"]),this}selectUnitPrice(){return this.query.select(["unitPrice"]),this}selectVersion(){return this.query.select(["version"]),this}selectCustomerOrderWith(t){return this.query.select(["customerOrder"]),this.query.relationQuery("customerOrder",t.toQuery(),"customerOrder","id",!1,{kind:"relation-select",method:"selectCustomerOrderWith",relation:"customerOrder"}),this}withCustomerOrderMatching(t){return this.filters.push({customerOrder:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutCustomerOrderMatching(t){return this.filters.push({customerOrder:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}filterByCustomerOrder(t){return this.filters.push({customerOrder:{$eq:t}}),this}filterByCustomerOrderIn(...t){return this.filters.push({customerOrder:{$in:t}}),this}withCustomerOrderIsKnown(){return this.filters.push({customerOrder:{$isNull:!1}}),this}withCustomerOrderIsUnknown(){return this.filters.push({customerOrder:{$isNull:!0}}),this}withProductNameContaining(t){return this.filters.push({productName:{$contains:t}}),this}withProductNameIs(t){return this.filters.push({productName:{$eq:t}}),this}withProductNameIsNot(t){return this.filters.push({productName:{$ne:t}}),this}withProductNameIn(...t){return this.filters.push({productName:{$in:t}}),this}withProductNameNotIn(...t){return this.filters.push({productName:{$notIn:t}}),this}withProductNameGreaterThan(t){return this.filters.push({productName:{$gt:t}}),this}withProductNameGreaterThanOrEqualTo(t){return this.filters.push({productName:{$gte:t}}),this}withProductNameLessThan(t){return this.filters.push({productName:{$lt:t}}),this}withProductNameLessThanOrEqualTo(t){return this.filters.push({productName:{$lte:t}}),this}withProductNameBetween(t,e){return this.filters.push({productName:{$between:[t,e]}}),this}withProductNameIsKnown(){return this.filters.push({productName:{$isNull:!1}}),this}withProductNameIsUnknown(){return this.filters.push({productName:{$isNull:!0}}),this}withProductNameNotContaining(t){return this.filters.push({productName:{$notContains:t}}),this}withProductNameStartingWith(t){return this.filters.push({productName:{$startsWith:t}}),this}withProductNameNotStartingWith(t){return this.filters.push({productName:{$notStartsWith:t}}),this}withProductNameEndingWith(t){return this.filters.push({productName:{$endsWith:t}}),this}withProductNameNotEndingWith(t){return this.filters.push({productName:{$notEndsWith:t}}),this}withProductNameSoundingLike(t){return this.filters.push({productName:{$soundLike:t}}),this}withQuantityIs(t){return this.filters.push({quantity:{$eq:t}}),this}withQuantityIsNot(t){return this.filters.push({quantity:{$ne:t}}),this}withQuantityIn(...t){return this.filters.push({quantity:{$in:t}}),this}withQuantityNotIn(...t){return this.filters.push({quantity:{$notIn:t}}),this}withQuantityGreaterThan(t){return this.filters.push({quantity:{$gt:t}}),this}withQuantityGreaterThanOrEqualTo(t){return this.filters.push({quantity:{$gte:t}}),this}withQuantityLessThan(t){return this.filters.push({quantity:{$lt:t}}),this}withQuantityLessThanOrEqualTo(t){return this.filters.push({quantity:{$lte:t}}),this}withQuantityBetween(t,e){return this.filters.push({quantity:{$between:[t,e]}}),this}withQuantityIsKnown(){return this.filters.push({quantity:{$isNull:!1}}),this}withQuantityIsUnknown(){return this.filters.push({quantity:{$isNull:!0}}),this}withUnitPriceIs(t){return this.filters.push({unitPrice:{$eq:t}}),this}withUnitPriceIsNot(t){return this.filters.push({unitPrice:{$ne:t}}),this}withUnitPriceIn(...t){return this.filters.push({unitPrice:{$in:t}}),this}withUnitPriceNotIn(...t){return this.filters.push({unitPrice:{$notIn:t}}),this}withUnitPriceGreaterThan(t){return this.filters.push({unitPrice:{$gt:t}}),this}withUnitPriceGreaterThanOrEqualTo(t){return this.filters.push({unitPrice:{$gte:t}}),this}withUnitPriceLessThan(t){return this.filters.push({unitPrice:{$lt:t}}),this}withUnitPriceLessThanOrEqualTo(t){return this.filters.push({unitPrice:{$lte:t}}),this}withUnitPriceBetween(t,e){return this.filters.push({unitPrice:{$between:[t,e]}}),this}withUnitPriceIsKnown(){return this.filters.push({unitPrice:{$isNull:!1}}),this}withUnitPriceIsUnknown(){return this.filters.push({unitPrice:{$isNull:!0}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByProductNameAscending(){return this.query.orderBy("productName","asc"),this}orderByProductNameDescending(){return this.query.orderBy("productName","desc"),this}orderByQuantityAscending(){return this.query.orderBy("quantity","asc"),this}orderByQuantityDescending(){return this.query.orderBy("quantity","desc"),this}orderByUnitPriceAscending(){return this.query.orderBy("unitPrice","asc"),this}orderByUnitPriceDescending(){return this.query.orderBy("unitPrice","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}minQuantity(){return this.minQuantityAs("minOfQuantity")}minQuantityAs(t){return this.query.aggregate("min","quantity",t),this}maxQuantity(){return this.maxQuantityAs("maxOfQuantity")}maxQuantityAs(t){return this.query.aggregate("max","quantity",t),this}sumQuantity(){return this.sumQuantityAs("sumOfQuantity")}sumQuantityAs(t){return this.query.aggregate("sum","quantity",t),this}avgQuantity(){return this.avgQuantityAs("avgOfQuantity")}avgQuantityAs(t){return this.query.aggregate("avg","quantity",t),this}standardDeviationQuantity(){return this.standardDeviationQuantityAs("standardDeviationOfQuantity")}standardDeviationQuantityAs(t){return this.query.aggregate("stddev","quantity",t),this}squareRootOfPopulationStandardDeviationQuantity(){return this.squareRootOfPopulationStandardDeviationQuantityAs("squareRootOfPopulationStandardDeviationOfQuantity")}squareRootOfPopulationStandardDeviationQuantityAs(t){return this.query.aggregate("stddev_pop","quantity",t),this}sampleVarianceQuantity(){return this.sampleVarianceQuantityAs("sampleVarianceOfQuantity")}sampleVarianceQuantityAs(t){return this.query.aggregate("var_samp","quantity",t),this}samplePopulationVarianceQuantity(){return this.samplePopulationVarianceQuantityAs("samplePopulationVarianceOfQuantity")}samplePopulationVarianceQuantityAs(t){return this.query.aggregate("var_pop","quantity",t),this}minUnitPrice(){return this.minUnitPriceAs("minOfUnitPrice")}minUnitPriceAs(t){return this.query.aggregate("min","unitPrice",t),this}maxUnitPrice(){return this.maxUnitPriceAs("maxOfUnitPrice")}maxUnitPriceAs(t){return this.query.aggregate("max","unitPrice",t),this}sumUnitPrice(){return this.sumUnitPriceAs("sumOfUnitPrice")}sumUnitPriceAs(t){return this.query.aggregate("sum","unitPrice",t),this}avgUnitPrice(){return this.avgUnitPriceAs("avgOfUnitPrice")}avgUnitPriceAs(t){return this.query.aggregate("avg","unitPrice",t),this}standardDeviationUnitPrice(){return this.standardDeviationUnitPriceAs("standardDeviationOfUnitPrice")}standardDeviationUnitPriceAs(t){return this.query.aggregate("stddev","unitPrice",t),this}squareRootOfPopulationStandardDeviationUnitPrice(){return this.squareRootOfPopulationStandardDeviationUnitPriceAs("squareRootOfPopulationStandardDeviationOfUnitPrice")}squareRootOfPopulationStandardDeviationUnitPriceAs(t){return this.query.aggregate("stddev_pop","unitPrice",t),this}sampleVarianceUnitPrice(){return this.sampleVarianceUnitPriceAs("sampleVarianceOfUnitPrice")}sampleVarianceUnitPriceAs(t){return this.query.aggregate("var_samp","unitPrice",t),this}samplePopulationVarianceUnitPrice(){return this.samplePopulationVarianceUnitPriceAs("samplePopulationVarianceOfUnitPrice")}samplePopulationVarianceUnitPriceAs(t){return this.query.aggregate("var_pop","unitPrice",t),this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByCustomerOrder(){return this.query.groupBy("customerOrder"),this}groupByCustomerOrderAs(t){return this.query.groupBy("customerOrder"),this}groupByProductName(){return this.query.groupBy("productName"),this}groupByProductNameAs(t){return this.query.groupBy("productName"),this}groupByQuantity(){return this.query.groupBy("quantity"),this}groupByQuantityAs(t){return this.query.groupBy("quantity"),this}groupByUnitPrice(){return this.query.groupBy("unitPrice"),this}groupByUnitPriceAs(t){return this.query.groupBy("unitPrice"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByCustomerOrderAs(t,e,r=!0){return this.query.facetBy(t,"customerOrder",e,r,{kind:"facet",method:"facetByCustomerOrderAs",relation:"customerOrder",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=await e.executeQuery(t.prepareQuery(this.query)),i=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=i?[]:r.map(o=>o instanceof B?o:B.fromRecord(o,new T)),h=new A(s);return i&&r[0]&&Object.assign(h.aggregations,r[0]),this.query.facets.length>0&&(h.facets=await F(e,o=>t.prepareQuery(o),this.query,this.query.facets)),h}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new A(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),r=t.prepareQuery(this.query),i=r.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},h=i?void 0:await e.executeCount(r,this._pageCountAlias,s),o=r.clone();o.aggregateItems=o.aggregateItems.filter(u=>!(String(u.function).toLowerCase()==="count"&&u.alias===this._pageCountAlias));const p=await e.executeQuery(o),l=i&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:h??await e.executeCount(r,this._pageCountAlias,s),a=new A(p.map(u=>u instanceof B?u:B.fromRecord(u,new T)));return a.totalCount=l,this._pageCountAlias!==void 0&&(a.aggregations[this._pageCountAlias]=l),this.query.facets.length>0&&(a.facets=await F(e,u=>t.prepareQuery(u),r,r.facets)),a}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const r=t.requireResource("dataService"),i=t.prepareQuery(this.query),s=r.executeForStream(i,e);return(async function*(){for await(const h of s)for(const o of h)yield o instanceof B?o:B.fromRecord(o,new T)})()}ensureIntent(){new z(this._comment,this._purpose)}}class _t{constructor(t,e,r,i,s,h){this.execute=t,this.executeRows=e,this.stream=r,this.limitOne=i,this.addComment=s,this.ensureIntent=h}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new B}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class E{static platforms(){return new st(!1)}static platformsWithMinimalFields(){return new st(!0)}static orderStatuses(){return new ot(!1)}static orderStatusesWithMinimalFields(){return new ot(!0)}static customers(){return new nt(!1)}static customersWithMinimalFields(){return new nt(!0)}static customerOrders(){return new at(!1)}static customerOrdersWithMinimalFields(){return new at(!0)}static orderItems(){return new ut(!1)}static orderItemsWithMinimalFields(){return new ut(!0)}}class I extends Error{constructor(t,e,r){const i=`select${r.charAt(0).toUpperCase()}${r.slice(1)}(...)`,s={error:"TeaQLNotLoadedError",root:t,accessPath:e.split("."),breakPoint:r,missingPreload:[r],suggestedFix:i,severity:"error",humanMessage:`访问 ${t}.${e} 时缺少预加载。请在查询中加入 ${i}`};super(JSON.stringify(s)),this.root=t,this.accessPath=e,this.breakPoint=r,this.name="TeaQLNotLoadedError",this.details=s}root;accessPath;breakPoint;details}function q(d,t){return d?`${d}.${t}`:t}class n{constructor(t,e=!0,r){this.value=t,this.present=e,this.notLoaded=r}value;present;notLoaded;static missing(){return new n(void 0,!1)}static notLoaded(t){return new n(void 0,!1,t)}eval(){if(this.notLoaded)throw this.notLoaded;return this.present?this.value:void 0}isPresent(){if(this.notLoaded)throw this.notLoaded;return this.present}orElse(t){const e=this.eval();return this.present&&e!=null?e:t}}class x{constructor(t,e="Platform(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}name(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"name");return this.value.isLoaded("name")?new n(this.value.name):n.notLoaded(new I(this.root,t,"name"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}orderStatusList(){const t=q(this.path,"orderStatusList");return this.notLoaded?new U([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("orderStatusList")?new U(this.value.orderStatusList(),this.root,t):new U([],this.root,t,!1,new I(this.root,t,"orderStatusList")):U.missing(this.root,t)}customerList(){const t=q(this.path,"customerList");return this.notLoaded?new M([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("customerList")?new M(this.value.customerList(),this.root,t):new M([],this.root,t,!1,new I(this.root,t,"customerList")):M.missing(this.root,t)}}class V{constructor(t,e="OrderStatus(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}name(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"name");return this.value.isLoaded("name")?new n(this.value.name):n.notLoaded(new I(this.root,t,"name"))}code(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"code");return this.value.isLoaded("code")?new n(this.value.code):n.notLoaded(new I(this.root,t,"code"))}color(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"color");return this.value.isLoaded("color")?new n(this.value.color):n.notLoaded(new I(this.root,t,"color"))}displayOrder(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"displayOrder");return this.value.isLoaded("displayOrder")?new n(this.value.displayOrder):n.notLoaded(new I(this.root,t,"displayOrder"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}platformId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"platform");if(!this.value.isLoaded("platform"))return n.notLoaded(new I(this.root,t,"platform"));const e=this.value.platform;return new n(e instanceof N?e.id:e)}platform(){const t=q(this.path,"platform");if(this.notLoaded)return new x(void 0,this.root,t,this.notLoaded);if(!this.value)return new x(void 0,this.root,t);if(!this.value.isLoaded("platform"))return new x(void 0,this.root,t,new I(this.root,t,"platform"));const e=this.value.platform,r=e==null?void 0:e instanceof N?e:N.fromRecord({id:e});return new x(r,this.root,t)}customerOrderList(){const t=q(this.path,"customerOrderList");return this.notLoaded?new k([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("customerOrderList")?new k(this.value.customerOrderList(),this.root,t):new k([],this.root,t,!1,new I(this.root,t,"customerOrderList")):k.missing(this.root,t)}}class W{constructor(t,e="Customer(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}name(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"name");return this.value.isLoaded("name")?new n(this.value.name):n.notLoaded(new I(this.root,t,"name"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}platformId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"platform");if(!this.value.isLoaded("platform"))return n.notLoaded(new I(this.root,t,"platform"));const e=this.value.platform;return new n(e instanceof N?e.id:e)}platform(){const t=q(this.path,"platform");if(this.notLoaded)return new x(void 0,this.root,t,this.notLoaded);if(!this.value)return new x(void 0,this.root,t);if(!this.value.isLoaded("platform"))return new x(void 0,this.root,t,new I(this.root,t,"platform"));const e=this.value.platform,r=e==null?void 0:e instanceof N?e:N.fromRecord({id:e});return new x(r,this.root,t)}customerOrderList(){const t=q(this.path,"customerOrderList");return this.notLoaded?new k([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("customerOrderList")?new k(this.value.customerOrderList(),this.root,t):new k([],this.root,t,!1,new I(this.root,t,"customerOrderList")):k.missing(this.root,t)}}class K{constructor(t,e="CustomerOrder(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}orderNumber(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"orderNumber");return this.value.isLoaded("orderNumber")?new n(this.value.orderNumber):n.notLoaded(new I(this.root,t,"orderNumber"))}orderDate(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"orderDate");return this.value.isLoaded("orderDate")?new n(this.value.orderDate):n.notLoaded(new I(this.root,t,"orderDate"))}totalAmount(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"totalAmount");return this.value.isLoaded("totalAmount")?new n(this.value.totalAmount):n.notLoaded(new I(this.root,t,"totalAmount"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}customerId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"customer");if(!this.value.isLoaded("customer"))return n.notLoaded(new I(this.root,t,"customer"));const e=this.value.customer;return new n(e instanceof Q?e.id:e)}statusId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"status");if(!this.value.isLoaded("status"))return n.notLoaded(new I(this.root,t,"status"));const e=this.value.status;return new n(e instanceof S?e.id:e)}customer(){const t=q(this.path,"customer");if(this.notLoaded)return new W(void 0,this.root,t,this.notLoaded);if(!this.value)return new W(void 0,this.root,t);if(!this.value.isLoaded("customer"))return new W(void 0,this.root,t,new I(this.root,t,"customer"));const e=this.value.customer,r=e==null?void 0:e instanceof Q?e:Q.fromRecord({id:e});return new W(r,this.root,t)}status(){const t=q(this.path,"status");if(this.notLoaded)return new V(void 0,this.root,t,this.notLoaded);if(!this.value)return new V(void 0,this.root,t);if(!this.value.isLoaded("status"))return new V(void 0,this.root,t,new I(this.root,t,"status"));const e=this.value.status,r=e==null?void 0:e instanceof S?e:S.fromRecord({id:e});return new V(r,this.root,t)}orderItemList(){const t=q(this.path,"orderItemList");return this.notLoaded?new j([],this.root,t,!1,this.notLoaded):this.value?this.value.isLoaded("orderItemList")?new j(this.value.orderItemList(),this.root,t):new j([],this.root,t,!1,new I(this.root,t,"orderItemList")):j.missing(this.root,t)}}class H{constructor(t,e="OrderItem(null)",r="",i){this.value=t,this.root=e,this.path=r,this.notLoaded=i}value;root;path;notLoaded;eval(){if(this.notLoaded)throw this.notLoaded;return this.value}id(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"id");return this.value.isLoaded("id")?new n(this.value.id):n.notLoaded(new I(this.root,t,"id"))}productName(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"productName");return this.value.isLoaded("productName")?new n(this.value.productName):n.notLoaded(new I(this.root,t,"productName"))}quantity(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"quantity");return this.value.isLoaded("quantity")?new n(this.value.quantity):n.notLoaded(new I(this.root,t,"quantity"))}unitPrice(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"unitPrice");return this.value.isLoaded("unitPrice")?new n(this.value.unitPrice):n.notLoaded(new I(this.root,t,"unitPrice"))}version(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"version");return this.value.isLoaded("version")?new n(this.value.version):n.notLoaded(new I(this.root,t,"version"))}customerOrderId(){if(this.notLoaded)return n.notLoaded(this.notLoaded);if(!this.value)return n.missing();const t=q(this.path,"customerOrder");if(!this.value.isLoaded("customerOrder"))return n.notLoaded(new I(this.root,t,"customerOrder"));const e=this.value.customerOrder;return new n(e instanceof $?e.id:e)}customerOrder(){const t=q(this.path,"customerOrder");if(this.notLoaded)return new K(void 0,this.root,t,this.notLoaded);if(!this.value)return new K(void 0,this.root,t);if(!this.value.isLoaded("customerOrder"))return new K(void 0,this.root,t,new I(this.root,t,"customerOrder"));const e=this.value.customerOrder,r=e==null?void 0:e instanceof $?e:$.fromRecord({id:e});return new K(r,this.root,t)}}class U{constructor(t,e="OrderStatus(null)",r="",i=!0,s){this.items=t,this.root=e,this.path=r,this.present=i,this.notLoaded=s}items;root;path;present;notLoaded;static missing(t,e=""){return new U([],t,e,!1)}size(){return this.notLoaded?n.notLoaded(this.notLoaded):this.present?new n(this.items.length):n.missing()}first(){return this.get(0)}get(t){const e=q(this.path,`get(${t})`);return this.notLoaded?new V(void 0,this.root,e,this.notLoaded):!this.present||t<0||t>=this.items.length?new V(void 0,this.root,e):new V(this.items[t],this.root,e)}}class M{constructor(t,e="Customer(null)",r="",i=!0,s){this.items=t,this.root=e,this.path=r,this.present=i,this.notLoaded=s}items;root;path;present;notLoaded;static missing(t,e=""){return new M([],t,e,!1)}size(){return this.notLoaded?n.notLoaded(this.notLoaded):this.present?new n(this.items.length):n.missing()}first(){return this.get(0)}get(t){const e=q(this.path,`get(${t})`);return this.notLoaded?new W(void 0,this.root,e,this.notLoaded):!this.present||t<0||t>=this.items.length?new W(void 0,this.root,e):new W(this.items[t],this.root,e)}}class k{constructor(t,e="CustomerOrder(null)",r="",i=!0,s){this.items=t,this.root=e,this.path=r,this.present=i,this.notLoaded=s}items;root;path;present;notLoaded;static missing(t,e=""){return new k([],t,e,!1)}size(){return this.notLoaded?n.notLoaded(this.notLoaded):this.present?new n(this.items.length):n.missing()}first(){return this.get(0)}get(t){const e=q(this.path,`get(${t})`);return this.notLoaded?new K(void 0,this.root,e,this.notLoaded):!this.present||t<0||t>=this.items.length?new K(void 0,this.root,e):new K(this.items[t],this.root,e)}}class j{constructor(t,e="OrderItem(null)",r="",i=!0,s){this.items=t,this.root=e,this.path=r,this.present=i,this.notLoaded=s}items;root;path;present;notLoaded;static missing(t,e=""){return new j([],t,e,!1)}size(){return this.notLoaded?n.notLoaded(this.notLoaded):this.present?new n(this.items.length):n.missing()}first(){return this.get(0)}get(t){const e=q(this.path,`get(${t})`);return this.notLoaded?new H(void 0,this.root,e,this.notLoaded):!this.present||t<0||t>=this.items.length?new H(void 0,this.root,e):new H(this.items[t],this.root,e)}}class et{static platform(t){return new x(t,`Platform(id=${t?.id??"null"})`)}static orderStatus(t){return new V(t,`OrderStatus(id=${t?.id??"null"})`)}static customer(t){return new W(t,`Customer(id=${t?.id??"null"})`)}static customerOrder(t){return new K(t,`CustomerOrder(id=${t?.id??"null"})`)}static orderItem(t){return new H(t,`OrderItem(id=${t?.id??"null"})`)}}const ht={Platform:{table:"platform_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{orderStatusList:{targetEntity:"OrderStatus",localKey:"id",foreignKey:"platform",many:!0},customerList:{targetEntity:"Customer",localKey:"id",foreignKey:"platform",many:!0}}},OrderStatus:{table:"order_status_data",auditMaskFields:[],columns:{platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},code:{columnName:"code",modelName:"code",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},color:{columnName:"color",modelName:"color",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},displayOrder:{columnName:"display_order",modelName:"display_order",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1},customerOrderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"status",many:!0}}},Customer:{table:"customer_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1},customerOrderList:{targetEntity:"CustomerOrder",localKey:"id",foreignKey:"customer",many:!0}}},CustomerOrder:{table:"customer_order_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},customer:{columnName:"customer",modelName:"customer",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},status:{columnName:"status",modelName:"status",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},orderNumber:{columnName:"order_number",modelName:"order_number",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},orderDate:{columnName:"order_date",modelName:"order_date",logPolicy:"plain",logicalType:"date",decode:"date",nullable:!1},totalAmount:{columnName:"total_amount",modelName:"total_amount",logPolicy:"plain",logicalType:"decimal",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{customer:{targetEntity:"Customer",localKey:"customer",foreignKey:"id",many:!1},status:{targetEntity:"OrderStatus",localKey:"status",foreignKey:"id",many:!1},orderItemList:{targetEntity:"OrderItem",localKey:"id",foreignKey:"customerOrder",many:!0}}},OrderItem:{table:"order_item_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},customerOrder:{columnName:"customer_order",modelName:"customer_order",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},productName:{columnName:"product_name",modelName:"product_name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},quantity:{columnName:"quantity",modelName:"quantity",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1},unitPrice:{columnName:"unit_price",modelName:"unit_price",logPolicy:"plain",logicalType:"decimal",decode:"number",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{customerOrder:{targetEntity:"CustomerOrder",localKey:"customerOrder",foreignKey:"id",many:!1}}}};async function Ct(d){let t=(await E.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(d))[0];t||(t=N.teaqlBootstrapNew("1"),t.updateName("Commerce Test Platform"),await t.auditAs("create generated Domain Root Platform").save(d)),d.withActiveRoot({entity:"Platform",id:t.id});let e=(await E.orderStatuses().withIdIs("1001").comment("what: locate generated constant OrderStatus(1001)").purpose("why: idempotent runtime bootstrap").executeForList(d))[0];if(!e)e=S.teaqlBootstrapNew("1001"),e.updatePlatform(t),e.updateName("New"),e.updateCode("NEW"),e.updateColor("#94A3B8"),e.updateDisplayOrder(1),await e.auditAs("create model constant OrderStatus(1001)").save(d);else{let s=!1;String(e.platform?.id??e.platform)!==String(t.id)&&(e.updatePlatform(t),s=!0),e.name!=="New"&&(e.updateName("New"),s=!0),e.code!=="NEW"&&(e.updateCode("NEW"),s=!0),e.color!=="#94A3B8"&&(e.updateColor("#94A3B8"),s=!0),e.displayOrder!==1&&(e.updateDisplayOrder(1),s=!0),s&&await e.auditAs("reconcile model constant OrderStatus(1001)").save(d)}let r=(await E.orderStatuses().withIdIs("1002").comment("what: locate generated constant OrderStatus(1002)").purpose("why: idempotent runtime bootstrap").executeForList(d))[0];if(!r)r=S.teaqlBootstrapNew("1002"),r.updatePlatform(t),r.updateName("Paid"),r.updateCode("PAID"),r.updateColor("#22C55E"),r.updateDisplayOrder(2),await r.auditAs("create model constant OrderStatus(1002)").save(d);else{let s=!1;String(r.platform?.id??r.platform)!==String(t.id)&&(r.updatePlatform(t),s=!0),r.name!=="Paid"&&(r.updateName("Paid"),s=!0),r.code!=="PAID"&&(r.updateCode("PAID"),s=!0),r.color!=="#22C55E"&&(r.updateColor("#22C55E"),s=!0),r.displayOrder!==2&&(r.updateDisplayOrder(2),s=!0),s&&await r.auditAs("reconcile model constant OrderStatus(1002)").save(d)}let i=(await E.orderStatuses().withIdIs("1003").comment("what: locate generated constant OrderStatus(1003)").purpose("why: idempotent runtime bootstrap").executeForList(d))[0];if(!i)i=S.teaqlBootstrapNew("1003"),i.updatePlatform(t),i.updateName("Cancelled"),i.updateCode("CANCELLED"),i.updateColor("#EF4444"),i.updateDisplayOrder(3),await i.auditAs("create model constant OrderStatus(1003)").save(d);else{let s=!1;String(i.platform?.id??i.platform)!==String(t.id)&&(i.updatePlatform(t),s=!0),i.name!=="Cancelled"&&(i.updateName("Cancelled"),s=!0),i.code!=="CANCELLED"&&(i.updateCode("CANCELLED"),s=!0),i.color!=="#EF4444"&&(i.updateColor("#EF4444"),s=!0),i.displayOrder!==3&&(i.updateDisplayOrder(3),s=!0),s&&await i.auditAs("reconcile model constant OrderStatus(1003)").save(d)}}const Pt=new pt(ht,{Platform:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.name===void 0||t.payload.name===null)&&e.push({ruleId:"required",location:w.property("name")}),t.payload.name!=null&&[...String(t.payload.name)].length>100&&e.push({ruleId:"max_length",location:w.property("name"),inputValue:t.payload.name,systemValue:100})}},OrderStatus:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.platform===void 0||t.payload.platform===null)&&e.push({ruleId:"required",location:w.property("platform")}),(t.action==="Create"&&t.payload.name===void 0||t.payload.name===null)&&e.push({ruleId:"required",location:w.property("name")}),t.payload.name!=null&&[...String(t.payload.name)].length>100&&e.push({ruleId:"max_length",location:w.property("name"),inputValue:t.payload.name,systemValue:100}),(t.action==="Create"&&t.payload.code===void 0||t.payload.code===null)&&e.push({ruleId:"required",location:w.property("code")}),t.payload.code!=null&&[...String(t.payload.code)].length>100&&e.push({ruleId:"max_length",location:w.property("code"),inputValue:t.payload.code,systemValue:100}),(t.action==="Create"&&t.payload.color===void 0||t.payload.color===null)&&e.push({ruleId:"required",location:w.property("color")}),t.payload.color!=null&&[...String(t.payload.color)].length>100&&e.push({ruleId:"max_length",location:w.property("color"),inputValue:t.payload.color,systemValue:100}),(t.action==="Create"&&t.payload.display_order===void 0||t.payload.display_order===null)&&e.push({ruleId:"required",location:w.property("display_order")})}},Customer:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.platform===void 0||t.payload.platform===null)&&e.push({ruleId:"required",location:w.property("platform")}),(t.action==="Create"&&t.payload.name===void 0||t.payload.name===null)&&e.push({ruleId:"required",location:w.property("name")}),t.payload.name!=null&&[...String(t.payload.name)].length>100&&e.push({ruleId:"max_length",location:w.property("name"),inputValue:t.payload.name,systemValue:100})}},CustomerOrder:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.customer===void 0||t.payload.customer===null)&&e.push({ruleId:"required",location:w.property("customer")}),(t.action==="Create"&&t.payload.status===void 0||t.payload.status===null)&&e.push({ruleId:"required",location:w.property("status")}),(t.action==="Create"&&t.payload.order_number===void 0||t.payload.order_number===null)&&e.push({ruleId:"required",location:w.property("order_number")}),t.payload.order_number!=null&&[...String(t.payload.order_number)].length>100&&e.push({ruleId:"max_length",location:w.property("order_number"),inputValue:t.payload.order_number,systemValue:100}),(t.action==="Create"&&t.payload.order_date===void 0||t.payload.order_date===null)&&e.push({ruleId:"required",location:w.property("order_date")}),(t.action==="Create"&&t.payload.total_amount===void 0||t.payload.total_amount===null)&&e.push({ruleId:"required",location:w.property("total_amount")})}},OrderItem:{checkAndFix(d,t,e){d.getResource("fixTime"),(t.action==="Create"&&t.payload.customer_order===void 0||t.payload.customer_order===null)&&e.push({ruleId:"required",location:w.property("customer_order")}),(t.action==="Create"&&t.payload.product_name===void 0||t.payload.product_name===null)&&e.push({ruleId:"required",location:w.property("product_name")}),t.payload.product_name!=null&&[...String(t.payload.product_name)].length>100&&e.push({ruleId:"max_length",location:w.property("product_name"),inputValue:t.payload.product_name,systemValue:100}),(t.action==="Create"&&t.payload.quantity===void 0||t.payload.quantity===null)&&e.push({ruleId:"required",location:w.property("quantity")}),(t.action==="Create"&&t.payload.unit_price===void 0||t.payload.unit_price===null)&&e.push({ruleId:"required",location:w.property("unit_price")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Commerce Test Platform"}},constants:[{entity:"OrderStatus",id:"1001",values:{platform:"1",name:"New",code:"NEW",color:"#94A3B8",displayOrder:1}},{entity:"OrderStatus",id:"1002",values:{platform:"1",name:"Paid",code:"PAID",color:"#22C55E",displayOrder:2}},{entity:"OrderStatus",id:"1003",values:{platform:"1",name:"Cancelled",code:"CANCELLED",color:"#EF4444",displayOrder:3}}],ensure:Ct}),it=document.querySelector("#status"),St=document.querySelector("#result"),Nt=document.querySelector("#trace"),$t=document.querySelector("#sql"),bt=document.querySelector("#evidence-rows"),Z=document.querySelector("#persist"),dt=document.querySelector("#logging"),rt=document.querySelector("#reset"),Y=document.querySelector("#query"),lt=document.querySelector("#search"),Tt={filter:{orderNumber:{$contains:"KEEP"}}};let R;Z.checked=localStorage.getItem("teaql-browser-order-storage")==="opfs";async function Qt(d){const t=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),e=await ft.open(t,{...ht},{storage:d,databaseName:"teaql-browser-orders.sqlite3"});e.install(Pt),e.setDiagnosticSQLLogSink(void 0).setMutationLoggingEnabled(!1);const r=Object.freeze({policyId:"browser-order-seed",version:"1",fingerprint:"sha256:browser-order-seed-v1"}),i=new gt().insertResource("dataService",e).withMutationPolicyRegistry(new Ot(()=>({identity:r,review:(s,h)=>h.operations.length>0?{verdict:"allow"}:{verdict:"deny",code:"EMPTY_GRAPH",message:"empty mutation graph"}}))).withMutationPolicyApprovalProvider(new wt(s=>({policy:s,approvedBy:"browser-demo-owner",approvedAt:new Date})));return e.setUserContext(i),await i.ensureSchema(),await i.ensureSchema(),{client:e,context:i,evidence:new qt,diagnostics:[]}}async function ct({context:d}){if((await E.customerOrdersWithMinimalFields().limit(1).comment("detect existing order demo").purpose("keep mutation seeding idempotent").executeForList(d)).length)return;const e=(await E.platforms().limit(2).comment("load bootstrap platform").purpose("prepare order demo").executeForList(d))[0],r=E.customers().comment("initialize demo customer").purpose("prepare order demo").newEntity(d);r.updateName("North Star Retail").updatePlatform(e.id),await r.auditAs("seed browser order customer").save(d);for(let i=1;i<=4;i++){const s=E.customerOrders().comment("initialize demo order").purpose("prepare order demo").newEntity(d);s.updateCustomer(r.id).updateOrderNumber(i<4?`KEEP-00${i}`:"DROP-004").updateOrderDate(`2026-10-0${i}`).updateTotalAmount(i<4?i*100:900),i===1?s.updateStatusToNew():s.updateStatusToPaid(),await s.auditAs("seed browser order").save(d);for(let h=1;h<=5;h++){const o=E.orderItems().comment("initialize demo item").purpose("prepare item previews").newEntity(d);o.updateCustomerOrder(s.id).updateProductName(`Box ${h}`).updateQuantity(h).updateUnitPrice(20),await o.auditAs("seed browser order item").save(d)}}}async function tt(d){const t=JSON.parse(lt.value),e=E.customerOrdersWithMinimalFields().filterByJson(t);d.evidence.enableAll(),d.diagnostics.length=0,d.client.setRuntimeTelemetrySink(d.evidence).setQueryLoggingEnabled(dt.checked).setDiagnosticSQLLogSink({write:o=>d.diagnostics.push(o)});const r=await e.countAs("totalOrders").facetByStatusAs("statusCounts",E.orderStatusesWithMinimalFields().selectName().selectColor().countAs("orderCount").sumTotalAmountOfCustomerOrdersAs("orderTotalAmount",E.customerOrdersWithMinimalFields()).orderByDisplayOrderAscending().comment("load status facets")).selectOrderNumber().selectOrderDate().selectStatusWith(E.orderStatusesWithMinimalFields().selectName().selectColor().comment("load status")).selectOrderItemListWith(E.orderItemsWithMinimalFields().selectProductName().selectQuantity().orderByIdAscending().limit(3).comment("load item previews")).countOrderItemsAs("itemCount").orderByOrderDateDescending().orderByIdDescending().offset(1).limit(1).comment("load order list").purpose("render order list page").executeForList(d.context),i={data:r.data.map(o=>{const p=et.customerOrder(o),l=p.orderItemList().size().eval();if(l==null)throw new Error("Selected item list unexpectedly has a null size");return{id:o.id,version:o.version,orderNumber:p.orderNumber().eval(),orderDate:p.orderDate().eval(),status:{name:p.status().name().eval(),color:p.status().color().eval()},items:Array.from({length:l},(a,u)=>({productName:p.orderItemList().get(u).productName().eval(),quantity:p.orderItemList().get(u).quantity().eval()})),itemCount:o.itemCount}}),metadata:{totalCount:r.totalCount,pageOffset:1,pageSize:1,aggregations:r.data.aggregations,searchWarnings:e.dynamicSearchWarnings},facets:{statusCounts:r.data.facets.statusCounts.map(o=>({id:o.id,name:et.orderStatus(S.fromRecord(o)).name().eval(),color:et.orderStatus(S.fromRecord(o)).color().eval(),orderCount:o.orderCount,orderTotalAmount:o.orderTotalAmount}))}};St.textContent=JSON.stringify(i,null,2);const s=d.evidence.snapshot(),h=s.map(o=>{const p=o.traceChain??[],l=p.filter(m=>m.kind==="purpose"),a=l.length===1?`${l[0].detail}: ${p.filter(m=>m.kind==="comment").map(m=>m.detail).join(" → ")}`:"TraceChain unavailable",u=document.createElement("tr");for(const m of[`${o.elapsedMicros} µs`,o.tracePath.find(C=>C.kind==="request")?.name??"—",a,o.debugSQL]){const C=document.createElement("td");C.textContent=m,u.append(C)}return{row:u,businessTrace:a}});bt.replaceChildren(...h.map(o=>o.row)),Nt.textContent=h.map(o=>o.businessTrace).join(` +`),$t.textContent=JSON.stringify(s,null,2),it.textContent=`${d.client.storage.toUpperCase()} · ${r.totalCount} matches · ${s.length} SQL statements · ${d.diagnostics.length} diagnostics · policy installed · ready`}async function mt(d){it.textContent=`Opening ${d.toUpperCase()} SQLite/WASM…`;const t=R;R=void 0,await t?.client.close();const e=await Qt(d);R=e,await ct(e),await tt(e)}function X(d){it.textContent=d instanceof Error?`${d.name}: ${d.message}`:String(d)}Y.addEventListener("click",async()=>{if(R){Y.disabled=!0;try{await tt(R)}catch(d){X(d)}finally{Y.disabled=!1}}});document.querySelector("#preset").addEventListener("click",()=>{lt.value=JSON.stringify(Tt,null,2),Y.click()});dt.addEventListener("change",()=>{R&&tt(R).catch(X)});Z.addEventListener("change",()=>{const d=Z.checked?"opfs":"memory";localStorage.setItem("teaql-browser-order-storage",d),mt(d).catch(X)});rt.addEventListener("click",async()=>{if(R){rt.disabled=!0;try{await R.client.reset(R.context),await ct(R),await tt(R)}catch(d){X(d)}finally{rt.disabled=!1}}});mt(Z.checked?"opfs":"memory").catch(X); diff --git a/dist/assets/style-SCdXWqgK.css b/dist/assets/style-SCdXWqgK.css new file mode 100644 index 0000000000000000000000000000000000000000..8274d2f8ef8b83862a47b0c69f23f755fda89d67 --- /dev/null +++ b/dist/assets/style-SCdXWqgK.css @@ -0,0 +1 @@ +:root{font:16px/1.5 Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;color:#17231b;background:#f5f4ed;font-synthesis:none;--ink: #17231b;--muted: #677067;--paper: #fffef8;--line: #d8ddd3;--green: #145b37;--green-deep: #0e4329;--lime: #dff45c;--orange: #ef8354;--blue: #2b66d9}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;min-width:320px;background:#f5f4ed}button,input{font:inherit}button,a{-webkit-tap-highlight-color:transparent}.page-shell{width:min(1440px,100%);margin:0 auto;padding:0 42px}.site-header{height:76px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--line)}.brand,.docs-link{color:var(--ink);text-decoration:none;font-weight:750}.brand{display:inline-flex;align-items:center;gap:11px;letter-spacing:-.02em}.brand-mark{width:30px;height:30px;display:grid;place-items:center;border-radius:50%;color:var(--lime);background:var(--green-deep);font-family:Georgia,serif;font-style:italic}.docs-link{color:var(--green);font-size:14px}.header-actions{display:flex;align-items:center;gap:18px}.language-switch{display:flex;gap:3px;padding:3px;border:1px solid var(--line);border-radius:8px}.language-switch button{padding:3px 7px;border:0;border-radius:5px;color:var(--muted);background:transparent;font-size:11px;cursor:pointer}.language-switch button.active{color:#fff;background:var(--green)}.hero{min-height:460px;display:grid;grid-template-columns:minmax(0,1.1fr) minmax(440px,.9fr);align-items:center;gap:72px;padding:76px 0 66px}.eyebrow,.section-index,.query-card-label{margin:0 0 14px;color:var(--green);font-size:11px;font-weight:850;letter-spacing:.18em}h1{margin:0;max-width:820px;font-family:Georgia,"Noto Serif SC",serif;font-size:clamp(42px,5.6vw,78px);font-weight:500;line-height:1.08;letter-spacing:-.055em}.hero-intro{max-width:680px;margin:26px 0 0;color:var(--muted);font-size:18px}.model-map{position:relative;min-height:310px;padding:38px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:12px;border:1px solid #bfc8bb;border-radius:28px;background:linear-gradient(145deg,#fdfdf8,#e9eee5);box-shadow:0 18px 48px #213c280f;overflow:hidden}.model-map:before{content:"DOMAIN MODEL";position:absolute;top:18px;left:22px;color:#708073;font-size:10px;font-weight:800;letter-spacing:.16em}.model-flow{width:100%;display:grid;grid-template-columns:1fr auto 1fr auto 1fr;align-items:center;gap:10px}.model-flow>span:not(.model-arrow),.model-leaves span{min-width:0;padding:15px 17px;border:1px solid #b8c2b7;border-radius:12px;background:#fffffadb;font:750 14px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;box-shadow:0 8px 22px #1e3a260d}.model-map small{display:block;margin-top:7px;color:var(--muted);font:12px/1.2 Inter,sans-serif}.model-flow>span.model-root{color:#fff;border-color:var(--green);background:var(--green)}.model-map .model-root small{color:#cce4d4}.model-arrow{color:#809087;font-size:22px;text-align:center}.model-arrow-split{height:22px;line-height:18px}.model-leaves{width:100%;display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.runtime-bar{min-height:72px;padding:14px 18px 14px 22px;display:flex;align-items:center;justify-content:space-between;gap:24px;border-radius:14px;color:#e7f1e9;background:var(--green-deep)}#status{margin:0;color:#c8d9ce;font:12px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.controls{display:flex;align-items:center;gap:18px}.toggle{display:inline-flex;align-items:center;gap:9px;font-size:13px;cursor:pointer}.toggle input{position:absolute;opacity:0;pointer-events:none}.toggle span{position:relative;width:38px;height:22px;border-radius:999px;background:#55705f;transition:background .2s ease}.toggle span:after{content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;background:#fff;transition:transform .2s ease}.toggle input:checked+span{background:var(--lime)}.toggle input:checked+span:after{transform:translate(16px);background:var(--green-deep)}.secondary-button,.tree-actions button{border:1px solid currentColor;border-radius:8px;background:transparent;cursor:pointer}.secondary-button{padding:8px 12px;color:#fff;font-size:12px}.secondary-button:disabled{opacity:.45;cursor:wait}.query-browser{padding:96px 0 82px}.section-heading,.result-heading{display:flex;align-items:end;justify-content:space-between;gap:36px;margin-bottom:40px}.section-heading h2,.result-heading h2{margin:0;font-family:Georgia,"Noto Serif SC",serif;font-size:clamp(34px,4vw,52px);font-weight:500;letter-spacing:-.045em}.section-heading>p{max-width:420px;margin:0;color:var(--muted)}.query-group{display:grid;grid-template-columns:230px 1fr;gap:36px;padding:24px 0;border-top:1px solid var(--line)}.query-group:last-child{border-bottom:1px solid var(--line)}.query-group-heading h2{margin:0 0 4px;font-size:16px}.query-group-heading p{margin:0;color:var(--muted);font-size:12px}.query-links{display:flex;flex-wrap:wrap;align-items:center;gap:10px 24px}.query-links a{position:relative;padding:5px 0;color:#34443a;text-decoration-color:#a6b1a8;text-underline-offset:5px;font-weight:650;transition:color .16s ease}.query-links a:after{content:" ↗";color:#9aa49b;font-weight:400}.query-links a:hover{color:var(--green)}.query-links a.active{color:var(--green);text-decoration-color:var(--orange);text-decoration-thickness:2px}.result-panel{margin:0 -42px;padding:82px 42px 92px;color:#eef5f0;background:#111a15}.result-heading{align-items:center}.result-heading .section-index{color:var(--lime)}.result-heading h2{color:#fff}#result-description{max-width:620px;margin:10px 0 0;color:#9fb0a4}.result-actions{display:flex;align-items:center;gap:10px}.result-view-switch,.tree-actions{display:flex;gap:6px}.result-view-switch button,.tree-actions button{padding:8px 11px;border:1px solid #536159;border-radius:8px;color:#aebdb3;background:transparent;font-size:12px;cursor:pointer}.result-view-switch button.active{color:#17231b;border-color:var(--lime);background:var(--lime)}.result-view-switch button:disabled{opacity:.35;cursor:default}.tree-actions button:hover{color:var(--lime)}.result-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:18px;align-items:start}.tree-card,.query-card,.sql-card{border:1px solid #2f3d34;border-radius:14px;background:#17231b}.tree-card{min-height:520px;overflow:hidden}.tree-card-bar{min-height:48px;padding:0 18px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #2f3d34;color:#b8c9bd;font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase;letter-spacing:.08em}#result-meta{margin:0;color:#829188;text-transform:none;letter-spacing:0}.json-tree{min-height:470px;max-height:680px;padding:18px 20px 28px;overflow:auto;font:13px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.json-tree.loading{opacity:.55}.tree-actions.hidden{display:none}.result-table-shell{width:100%;min-height:470px;overflow:auto}.result-table{width:100%;border-collapse:collapse;white-space:nowrap}.result-table th,.result-table td{padding:11px 14px;border-bottom:1px solid #2f3d34;text-align:left;vertical-align:top}.result-table th{position:sticky;top:0;z-index:1;color:#8ea095;background:#131d17;font:700 10px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.result-table td{color:#d9e5dc;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}.result-table tbody tr:hover{background:#ffffff06}.result-table-empty{margin:0;padding:48px 20px;color:#7f9185;text-align:center}.tree-branch{margin:2px 0}.tree-branch>summary{min-height:29px;display:flex;align-items:center;gap:9px;list-style:none;cursor:pointer;border-radius:5px}.tree-branch>summary::-webkit-details-marker{display:none}.tree-branch>summary:before{content:"›";width:15px;color:#73887a;font-size:18px;line-height:1;transform-origin:center;transition:transform .12s ease}.tree-branch[open]>summary:before{transform:rotate(90deg)}.tree-branch>summary:hover{background:#ffffff09}.tree-children{margin-left:8px;padding-left:20px;border-left:1px solid #314238}.tree-leaf{min-height:28px;display:grid;grid-template-columns:minmax(110px,180px) 1fr;align-items:baseline;gap:12px;padding-left:23px}.tree-key{color:#bdd0c2;font-weight:700}.tree-preview{overflow:hidden;color:#718079;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.tree-value{overflow-wrap:anywhere}.tree-string{color:#dff45c}.tree-number{color:#82b4ff}.tree-boolean{color:#f2a27f}.tree-null{color:#78847c;font-style:italic}.query-card,.sql-card{min-width:0;padding:22px}.query-card-label{color:var(--lime)}.query-card pre{max-height:430px;margin:0;padding:0;overflow:auto;color:#d5e2d8;background:transparent;font:12px/1.72 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap}.query-params{margin-top:24px;padding-top:18px;border-top:1px solid #2f3d34}.query-params.hidden{display:none}.query-params .query-card-label{margin-bottom:10px;color:#82b4ff}.query-params pre{max-height:220px;color:#b9caee}.query-note{margin:28px 0 0;padding-top:18px;border-top:1px solid #2f3d34;color:#829188;font-size:12px}.sql-card-heading{display:flex;align-items:center;justify-content:space-between;gap:16px}.sql-card-heading .query-card-label{margin-bottom:0}#sql-count{color:#7f9185;font:10px/1.3 ui-monospace,SFMono-Regular,Menlo,monospace}.execution-evidence-wrap{margin-top:18px;overflow-x:auto;border:1px solid #34433a;border-radius:8px}.execution-evidence{min-width:1500px;width:100%;border-collapse:collapse;color:#c7d5cb}.execution-evidence th,.execution-evidence td{padding:10px 12px;border-right:1px solid #34433a;border-bottom:1px solid #34433a;text-align:left;vertical-align:top;white-space:nowrap}.execution-evidence th:last-child,.execution-evidence td:last-child{border-right:0}.execution-evidence tbody tr:last-child td{border-bottom:0}.execution-evidence th{color:#7f9185;background:#131d17;font:700 10px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.execution-evidence td{color:#cbd8ce;background:#101813;font:10px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}.execution-evidence tbody tr:hover td{background:#141f18}.execution-evidence .evidence-trace{color:#b9caee}.execution-evidence .evidence-sql{color:#dff45c}.dashboard-result{max-height:none;padding:0;color:var(--ink);background:#f7f8f5;font:14px/1.45 Inter,system-ui,sans-serif}.order-center{min-width:880px;padding:24px}.order-center-toolbar{display:flex;align-items:end;justify-content:space-between;gap:24px;margin-bottom:20px}.order-center-toolbar h3{margin:0;color:#111d16;font:750 22px/1.2 Inter,system-ui,sans-serif;letter-spacing:-.025em}.order-center-toolbar p{margin:5px 0 0;color:#778078;font-size:12px}.order-search{width:min(390px,45%);display:flex;align-items:center;gap:6px}.order-search input{min-width:0;height:32px;flex:1;padding:6px 10px;border:1px solid #cfd5ce;border-radius:7px;outline:0;background:#fff;font-size:12px}.order-search input:focus{border-color:#8e9990}.order-search-submit{width:30px;height:30px;flex:0 0 30px;display:grid;place-items:center;padding:0;border:1px solid #cfd5ce;border-radius:7px;color:#536057;background:#fff;cursor:pointer}.order-search-submit:hover,.order-search-submit:focus-visible{color:var(--green);border-color:#93a097;outline:none}.search-icon{position:relative;width:13px;height:13px;display:block;border:1.5px solid currentColor;border-radius:50%}.search-icon:after{content:"";position:absolute;right:-3px;bottom:-2px;width:5px;height:1.5px;border-radius:1px;background:currentColor;transform:rotate(45deg);transform-origin:left center}.order-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-bottom:18px}.metric-card{padding:14px;display:grid;gap:8px;text-align:left;border:1px solid #dbe0da;border-radius:9px;color:#58625b;background:#fff;cursor:pointer}.metric-card strong{color:#16231a;font-size:23px;line-height:1}.metric-card small{color:#727b74;font-size:10px;font-variant-numeric:tabular-nums}.metric-card.active{border-color:var(--metric-color, var(--blue));box-shadow:inset 3px 0 0 var(--metric-color, var(--blue))}.order-table{overflow:hidden;border:1px solid #e0e4df;border-radius:10px;background:#fff}.order-row{min-width:720px;display:grid;grid-template-columns:1.05fr .85fr .75fr 2fr;align-items:center;gap:14px;min-height:68px;padding:10px 14px;border-top:1px solid #edf0ec}.order-row:first-child{border-top:0}.order-row-head{min-height:40px;color:#69736b;background:#f2f4f1;font-size:11px;font-weight:750}.order-primary{color:#26322a;font:650 12px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace}.status-badge{display:inline-block;padding:4px 8px;border-radius:999px;color:#2b5e39;background:#e3f4e8;font-size:10px;white-space:nowrap}.status-pending_payment{color:#92580a;background:#fff0d8}.status-paid{color:#215b9d;background:#e2efff}.status-shipped{color:#1d6e38;background:#ddf5e4}.status-cancelled{color:#7b4650;background:#f6e6e9}.product-preview{display:flex;align-items:center;gap:5px}.product-thumb{width:32px;height:28px;display:grid;place-items:center;border:1px solid #cad4ca;border-radius:6px;color:#315139;background:linear-gradient(135deg,#e5eddf,#bdceb8);font:800 11px/1 Inter,sans-serif}.product-tone-1{color:#725333;background:linear-gradient(135deg,#f1e5d4,#d3b58d)}.product-tone-2{color:#3d526b;background:linear-gradient(135deg,#e1e9ef,#adbecd)}.product-preview small{color:#68736a;font-size:10px}.order-empty{padding:48px 20px;color:#7a847c;text-align:center}.order-center-footer{display:flex;align-items:center;justify-content:space-between;gap:20px;padding-top:16px}.order-center-footer p{margin:0;color:#7a847c;font-size:11px}.pagination{display:flex;gap:5px}.pagination button{min-width:31px;height:31px;border:1px solid #d8ddd7;border-radius:6px;color:#465149;background:#fff;cursor:pointer}.pagination button.active{color:#fff;border-color:var(--blue);background:var(--blue)}.pagination button:disabled{opacity:.4;cursor:default}footer{min-height:86px;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:12px}@media(max-width:980px){.page-shell{padding:0 24px}.hero{grid-template-columns:1fr;gap:46px;padding-top:58px}.model-map{min-height:260px}.result-panel{margin:0 -24px;padding-left:24px;padding-right:24px}.result-grid{grid-template-columns:1fr}}@media(max-width:680px){.page-shell{padding:0 16px}.site-header{height:64px}.header-actions{gap:9px}.docs-link{display:none}h1{font-size:43px}.hero{min-height:auto;padding:48px 0}.hero-intro{font-size:16px}.model-map{gap:9px;padding:52px 22px 22px}.model-flow{grid-template-columns:1fr}.model-flow>span:not(.model-arrow),.model-leaves span{width:100%}.model-flow .model-arrow{transform:rotate(90deg)}.model-leaves{grid-template-columns:1fr}.runtime-bar,.section-heading,.result-heading{align-items:flex-start;flex-direction:column}.runtime-bar{padding:18px}.controls{width:100%;justify-content:space-between}.query-browser{padding:70px 0 64px}.query-group{grid-template-columns:1fr;gap:14px}.query-links{gap:8px 18px}.result-panel{margin:0 -16px;padding:64px 16px}.result-actions{width:100%;align-items:stretch;flex-direction:column}.result-view-switch,.tree-actions{width:100%}.result-view-switch button,.tree-actions button{flex:1}.tree-leaf{grid-template-columns:minmax(90px,120px) 1fr;padding-left:15px}.json-tree{padding-left:12px;padding-right:12px}} diff --git a/dist/assets/workItems-5mJKEgxC.css b/dist/assets/workItems-5mJKEgxC.css new file mode 100644 index 0000000000000000000000000000000000000000..7185e90c42246c0339bd4f8538ffbea3f177851f --- /dev/null +++ b/dist/assets/workItems-5mJKEgxC.css @@ -0,0 +1 @@ +:root{font:16px/1.5 Inter,system-ui,sans-serif;color:#e8edf5;background:#090b10}body{margin:0}main{width:min(760px,calc(100% - 40px));margin:10vh auto}.eyebrow{color:#d9ff52;font-size:12px;font-weight:800;letter-spacing:.16em}h1{margin:8px 0;font-size:clamp(36px,7vw,68px);letter-spacing:-.05em}a{color:#d9ff52}.controls{display:flex;gap:18px;align-items:center;margin:32px 0}button{border:0;border-radius:5px;padding:10px 14px;background:#d9ff52;font-weight:800}#status{color:#aab4c4}pre{min-height:260px;padding:22px;overflow:auto;border:1px solid #2b323e;border-radius:8px;background:#11151c;color:#c6d1df} diff --git a/dist/assets/workItems-DraVJWt7.js b/dist/assets/workItems-DraVJWt7.js new file mode 100644 index 0000000000000000000000000000000000000000..b0ae6062d03594b1ac8317d6b745a9cb72d5e143 --- /dev/null +++ b/dist/assets/workItems-DraVJWt7.js @@ -0,0 +1 @@ +import{S as G,L as c,M as k,C as v,a as I,d as O,e as C,Q as K,R as U,B as z,U as H,D as J,c as Y}from"./dynamic-search-BBmdgl4H.js";import{E as $,O as g}from"./object-location-xgYMemK6.js";class L extends G{orderBy(t,e){return this.order({field:t,expr:null,direction:e==="desc"?"Desc":"Asc"})}relationQuery(t,e,i="id",r="id",s=!0,a){return super.relationQuery(t,e,i,r,s,a)}}class m{static teaqlTemporaryId=0;id;title;description;platform;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new $,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--m.teaqlTemporaryId,writable:!0,enumerable:!1}),t){const i={...t};Object.assign(this,i),t.platform&&typeof t.platform=="object"&&(this.platform=t.platform instanceof y?t.platform:y.fromRecord(t.platform),this.markLoaded("platform"))}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),c.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"WorkItem",id:this._ledgerId}}teaqlAttachRoot(t){return this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t),this}static fromRecord(t,e){const i=new m(t);return e?i.teaqlAttachRoot(e):i}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new m({id:String(t)})}static teaqlBootstrapNew(t){return new m().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new k(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new k(this._comment),async i=>(this.teaqlPreflightGraph(t,e,i),this.teaqlSaveWithinGraph(t,e,i)))}teaqlPreflightGraph(t,e,i,r){r||new k(this._comment);const s=this._action,a=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&a){const d=[{member:"id",canonical:"id"},{member:"title",canonical:"title"},{member:"description",canonical:"description"},{member:"platform",canonical:"platform"},{member:"version",canonical:"version"}].find(u=>!this.isLoaded(u.member));if(d)throw new v([{ruleId:"invalid_type",location:g.property(d.canonical),message:"Mutation requires a fully loaded entity"}])}const n=i.request({entity:"WorkItem",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},r,this._comment).withLoadedSnapshot(c.forEntity(this)??new c);a&&e.preflightMutation(n),n.scopeFor(this.teaqlEntityKey())}async teaqlSaveWithinGraph(t,e,i,r){r||new k(this._comment);const s=this._action,a=this._root.change(this.teaqlEntityKey()),n={entity:"WorkItem",action:this._action,payload:s==="Update"?a:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},d=i.request(n,r,this._comment).withLoadedSnapshot(c.forEntity(this)??new c);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey()))return d.scopeFor(this.teaqlEntityKey()),this;const u=await e.executeMutation(d);for(const[S,f]of Object.entries(n.payload))S!=="id"&&S!=="version"&&this._root.set(this.teaqlEntityKey(),S,f);if(!u.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const h={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:c.forEntity(this)},l=this.teaqlEntityKey();Object.assign(this,u.persistedRecord),c.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const p=this.teaqlEntityKey();return this._root.rekey(l,p),e.afterGraphRollback(()=>{Object.assign(this,h.payload),this._ledgerId=h.ledgerId,this._action=h.action,this._loadedFields=h.loadedFields,this._fullyLoaded=h.fullyLoaded,c.restoreFor(this,h.loadedSnapshot),this._root.rekey(p,l)}),this._loadedFields=new Set(Object.keys(u.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update"),d.scopeFor(p),e.afterGraphCommit(()=>{this._root.clearEntity(p),this.version!==void 0&&this._root.acceptCommittedVersion(p,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,title:this.title,description:this.description,platform:this.platform,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateTitle(t){return this.title=t,this.markLoaded("title"),this._root.set(this.teaqlEntityKey(),"title",t),this}updateDescription(t){return this.description=t,this.markLoaded("description"),this._root.set(this.teaqlEntityKey(),"description",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}updatePlatform(t){return this.platform=t?.id??t,this.markLoaded("platform"),this._root.set(this.teaqlEntityKey(),"platform",this.platform),this}}class y{static teaqlTemporaryId=0;id;name;version;constructor(t){if(Object.defineProperty(this,"_action",{value:t&&t.id?"Update":"Create",writable:!0,enumerable:!1}),Object.defineProperty(this,"_comment",{value:void 0,writable:!0,enumerable:!1}),Object.defineProperty(this,"_fullyLoaded",{value:!t||!t.id,writable:!0,enumerable:!1}),Object.defineProperty(this,"_loadedFields",{value:new Set(Object.keys(t||{})),writable:!0,enumerable:!1}),Object.defineProperty(this,"_root",{value:new $,writable:!0,enumerable:!1}),Object.defineProperty(this,"_ledgerId",{value:t?.id??--y.teaqlTemporaryId,writable:!0,enumerable:!1}),Object.defineProperty(this,"_workItemList",{value:t?.id?I.empty():new I,writable:!0,enumerable:!1}),t){const i={...t};if(delete i.workItemList,Object.assign(this,i),Array.isArray(t.workItemList)){const r=t.workItemList;this._workItemList=new I(r.map(s=>s instanceof m?s:m.fromRecord(s)),{totalCount:r.totalCount,aggregations:r.aggregations,summary:r.summary,facets:r.facets,isLoaded:r.isLoaded??!0}),this.markLoaded("workItemList")}}const e=this.teaqlEntityKey();this._action==="Create"?this._root.markAsNew(e):this.version!==void 0&&this._root.setOriginalVersion(e,Number(this.version)),c.captureFor(this,this.teaqlMutationPayload())}teaqlEntityKey(){return{entity:"Platform",id:this._ledgerId}}teaqlAttachRoot(t){this._root!==t&&(t.mergeEntityFrom(this._root,this.teaqlEntityKey()),this._root=t);for(const e of this._workItemList)e.teaqlAttachRoot(t);return this}static fromRecord(t,e){const i=new y(t);return e?i.teaqlAttachRoot(e):i}isLoaded(t){return this._fullyLoaded||this._loadedFields.has(t)}markLoaded(...t){for(const e of t)this._loadedFields.add(e);return this}markLoadedOnly(...t){return this._fullyLoaded=!1,this._loadedFields=new Set(t),this}static refer(t){return new y({id:String(t)})}static teaqlBootstrapNew(t){return new y().updateId(String(t))}markForDeletion(){return this._action="Delete",this._root.markAsDeleted(this.teaqlEntityKey()),this}auditAs(t){return new k(t),this._comment=t,this}async save(t){const e=t.requireResource("dataService");return e.executeGraphSave(new k(this._comment),async i=>(this.teaqlPreflightGraph(t,e,i),this.teaqlSaveWithinGraph(t,e,i)))}teaqlPreflightGraph(t,e,i,r){r||new k(this._comment);const s=this._action,a=s!=="Update"||this._root.hasPending(this.teaqlEntityKey());if(s==="Update"&&a){const u=[{member:"id",canonical:"id"},{member:"name",canonical:"name"},{member:"version",canonical:"version"}].find(h=>!this.isLoaded(h.member));if(u)throw new v([{ruleId:"invalid_type",location:g.property(u.canonical),message:"Mutation requires a fully loaded entity"}])}const n=i.request({entity:"Platform",action:s,payload:s==="Update"?this._root.change(this.teaqlEntityKey()):this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},r,this._comment).withLoadedSnapshot(c.forEntity(this)??new c);a&&e.preflightMutation(n);const d=n.scopeFor(this.teaqlEntityKey());for(const[u,h]of this._workItemList.entries()){h.teaqlAttachRoot(this._root);const l=h.platform;(this.id===void 0||!h.isLoaded("platform")||(typeof l=="object"&&l!==null?l.id:l)!==this.id)&&h.updatePlatform(this);try{h.teaqlPreflightGraph(t,e,i,d)}catch(p){if(!(p instanceof v))throw p;const S=g.property("work_item_list").index(u);throw new v(p.violations.map(f=>({...f,location:f.location.prefixedBy(S)})))}}}async teaqlSaveWithinGraph(t,e,i,r){r||new k(this._comment);const s=this._action,a=this._root.change(this.teaqlEntityKey()),n={entity:"Platform",action:this._action,payload:s==="Update"?a:this.teaqlMutationPayload(),id:this.id,version:this.version,comment:this._comment,ledgerKey:this.teaqlEntityKey(),ledgerRoot:this._root},d=i.request(n,r,this._comment).withLoadedSnapshot(c.forEntity(this)??new c);if(s==="Update"&&!this._root.hasPending(this.teaqlEntityKey())){const f=d.scopeFor(this.teaqlEntityKey());for(const[q,w]of this._workItemList.entries()){w.teaqlAttachRoot(this._root);const _=w.platform;(this.id===void 0||!w.isLoaded("platform")||(typeof _=="object"&&_!==null?_.id:_)!==this.id)&&w.updatePlatform(this);try{await w.teaqlSaveWithinGraph(t,e,i,f)}catch(N){if(!(N instanceof v))throw N;const P=g.property("work_item_list").index(q);throw new v(N.violations.map(B=>({...B,location:B.location.prefixedBy(P)})))}}return this}const u=await e.executeMutation(d);for(const[f,q]of Object.entries(n.payload))f!=="id"&&f!=="version"&&this._root.set(this.teaqlEntityKey(),f,q);if(!u.persistedRecord)throw new Error("Mutation did not return the authoritative persisted record");const h={payload:this.teaqlMutationPayload(),ledgerId:this._ledgerId,action:this._action,loadedFields:new Set(this._loadedFields),fullyLoaded:this._fullyLoaded,loadedSnapshot:c.forEntity(this)},l=this.teaqlEntityKey();Object.assign(this,u.persistedRecord),c.captureFor(this,this.teaqlMutationPayload()),this._ledgerId=this.id??this._ledgerId;const p=this.teaqlEntityKey();this._root.rekey(l,p),e.afterGraphRollback(()=>{Object.assign(this,h.payload),this._ledgerId=h.ledgerId,this._action=h.action,this._loadedFields=h.loadedFields,this._fullyLoaded=h.fullyLoaded,c.restoreFor(this,h.loadedSnapshot),this._root.rekey(p,l)}),this._loadedFields=new Set(Object.keys(u.persistedRecord)),this._fullyLoaded=!1,n.action!=="Delete"&&(this._action="Update");const S=d.scopeFor(p);for(const[f,q]of this._workItemList.entries()){q.teaqlAttachRoot(this._root);const w=q.platform;(this.id===void 0||!q.isLoaded("platform")||(typeof w=="object"&&w!==null?w.id:w)!==this.id)&&q.updatePlatform(this);try{await q.teaqlSaveWithinGraph(t,e,i,S)}catch(_){if(!(_ instanceof v))throw _;const N=g.property("work_item_list").index(f);throw new v(_.violations.map(P=>({...P,location:P.location.prefixedBy(N)})))}}return e.afterGraphCommit(()=>{this._root.clearEntity(p),this.version!==void 0&&this._root.acceptCommittedVersion(p,Number(this.version))}),this}teaqlMutationPayload(){return{id:this.id,name:this.name,version:this.version}}updateId(t){return this.id=t,this.markLoaded("id"),this._root.set(this.teaqlEntityKey(),"id",t),this}updateName(t){return this.name=t,this.markLoaded("name"),this._root.set(this.teaqlEntityKey(),"name",t),this}updateVersion(t){return this.version=t,this.markLoaded("version"),this._root.set(this.teaqlEntityKey(),"version",t),this}workItemList(){return this._workItemList}}const D=Object.freeze({Platform:Object.freeze({fields:Object.freeze({id:"integer",name:"string",version:"integer"}),queryFields:Object.freeze({id:"id",name:"name",version:"version"}),relations:Object.freeze({workItemList:"WorkItem"})}),WorkItem:Object.freeze({fields:Object.freeze({id:"integer",title:"string",description:"string",platform:"integer",version:"integer"}),queryFields:Object.freeze({id:"id",title:"title",description:"description",platform:"platform",version:"version"}),relations:Object.freeze({platform:"Platform"})})});class A{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new L("Platform"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const r=O(i,t,D,e);return this.query=r.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...r.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new X(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,i)=>this.executeForStreamInternal(e,i),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,i){return this.query.optimizePaginationWithIdSetConfig(t,e,i),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","name","version"]),this}selectId(){return this.query.select(["id"]),this}selectName(){return this.query.select(["name"]),this}selectVersion(){return this.query.select(["version"]),this}selectWorkItemListWith(t){return this.query.relationQuery("workItemList",t.toQuery(),"id","platform",!0,{kind:"relation-select",method:"selectWorkItemListWith",relation:"workItemList"}),this}haveWorkItems(){return this.withWorkItemListMatching({toQuery:()=>new L("WorkItem")})}haveNoWorkItems(){return this.withoutWorkItemListMatching({toQuery:()=>new L("WorkItem")})}withWorkItemListMatching(t){return this.filters.push({id:{$inSubquery:{query:t.toQuery(),field:"platform"}}}),this}withoutWorkItemListMatching(t){return this.filters.push({id:{$notInSubquery:{query:t.toQuery(),field:"platform"}}}),this}countWorkItems(){return this.countWorkItemsAs("countWorkItems")}countWorkItemsAs(t){const e=new L("WorkItem").filter({version:{$gte:1}});return this.countWorkItemsWith(t,{toQuery:()=>e}),this.query.relationAggregates[this.query.relationAggregates.length-1].operation={kind:"relation-count",method:"countWorkItemsAs",relation:"workItemList",alias:t},this}countWorkItemsWith(t,e){const i=e.toQuery().clone();return i.aggregateItems=[],i.aggregate("Count","id",t),this.query.relationAggregate("workItemList",t,i,!0,{kind:"relation-count",method:"countWorkItemsWith",relation:"workItemList",alias:t}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withNameContaining(t){return this.filters.push({name:{$contains:t}}),this}withNameIs(t){return this.filters.push({name:{$eq:t}}),this}withNameIsNot(t){return this.filters.push({name:{$ne:t}}),this}withNameIn(...t){return this.filters.push({name:{$in:t}}),this}withNameNotIn(...t){return this.filters.push({name:{$notIn:t}}),this}withNameGreaterThan(t){return this.filters.push({name:{$gt:t}}),this}withNameGreaterThanOrEqualTo(t){return this.filters.push({name:{$gte:t}}),this}withNameLessThan(t){return this.filters.push({name:{$lt:t}}),this}withNameLessThanOrEqualTo(t){return this.filters.push({name:{$lte:t}}),this}withNameBetween(t,e){return this.filters.push({name:{$between:[t,e]}}),this}withNameIsKnown(){return this.filters.push({name:{$isNull:!1}}),this}withNameIsUnknown(){return this.filters.push({name:{$isNull:!0}}),this}withNameNotContaining(t){return this.filters.push({name:{$notContains:t}}),this}withNameStartingWith(t){return this.filters.push({name:{$startsWith:t}}),this}withNameNotStartingWith(t){return this.filters.push({name:{$notStartsWith:t}}),this}withNameEndingWith(t){return this.filters.push({name:{$endsWith:t}}),this}withNameNotEndingWith(t){return this.filters.push({name:{$notEndsWith:t}}),this}withNameSoundingLike(t){return this.filters.push({name:{$soundLike:t}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByNameAscending(){return this.query.orderBy("name","asc"),this}orderByNameDescending(){return this.query.orderBy("name","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByName(){return this.query.groupBy("name"),this}groupByNameAs(t){return this.query.groupBy("name"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),i=await e.executeQuery(t.prepareQuery(this.query)),r=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=r?[]:i.map(n=>n instanceof y?n:y.fromRecord(n,new $)),a=new I(s);return r&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await C(e,n=>t.prepareQuery(n),this.query,this.query.facets)),a}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new I(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),i=t.prepareQuery(this.query),r=i.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=r?void 0:await e.executeCount(i,this._pageCountAlias,s),n=i.clone();n.aggregateItems=n.aggregateItems.filter(l=>!(String(l.function).toLowerCase()==="count"&&l.alias===this._pageCountAlias));const d=await e.executeQuery(n),u=r&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:a??await e.executeCount(i,this._pageCountAlias,s),h=new I(d.map(l=>l instanceof y?l:y.fromRecord(l,new $)));return h.totalCount=u,this._pageCountAlias!==void 0&&(h.aggregations[this._pageCountAlias]=u),this.query.facets.length>0&&(h.facets=await C(e,l=>t.prepareQuery(l),i,i.facets)),h}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=t.requireResource("dataService"),r=t.prepareQuery(this.query),s=i.executeForStream(r,e);return(async function*(){for await(const a of s)for(const n of a)yield n instanceof y?n:y.fromRecord(n,new $)})()}ensureIntent(){new K(this._comment,this._purpose)}}class X{constructor(t,e,i,r,s,a){this.execute=t,this.executeRows=e,this.stream=i,this.limitOne=r,this.addComment=s,this.ensureIntent=a}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new y}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class x{query;filters=[];_purpose;_comment;_pageCountAlias;_pageCountMethod;_dynamicSearchWarnings=[];constructor(t=!1){this.query=new L("WorkItem"),this.filters.push({version:{$gte:1}}),t?(this.selectId(),this.selectVersion()):this.selectSelfFields()}comment(t){return this.query.comment(t),this._comment=t,this}filterByJson(t,e){const i=this.query.clone();this.filters.length>0&&i.filter({$and:this.filters});const r=O(i,t,D,e);return this.query=r.query,this.filters=this.query.filterCondition?[this.query.filterCondition]:[],this._dynamicSearchWarnings.push(...r.warnings),this}get dynamicSearchWarnings(){return this._dynamicSearchWarnings.map(t=>({...t}))}purpose(t){return this.query.purpose(t),this._purpose=t,new Z(e=>e.withQueryRequest(this.query,()=>this.executeForListInternal(e)),e=>e.withQueryRequest(this.query,()=>this.executeForRowsInternal(e)),(e,i)=>this.executeForStreamInternal(e,i),()=>this.limit(1),e=>this.comment(e),()=>this.ensureIntent())}optimizeForContinuousPageFetch(){return this.query.optimizeForContinuousPageFetch(),this}optimizeForContinuousPageFetchWith(t,e){return this.query.optimizeForContinuousPageFetchWith(t,e),this}optimizePaginationWithIdSet(){return this.query.optimizePaginationWithIdSet(),this}optimizePaginationWithIdSetConfig(t,e,i){return this.query.optimizePaginationWithIdSetConfig(t,e,i),this}topNProbeParentThreshold(t){return this.query.topNProbeParentThreshold(t),this}limit(t){return this.query.limit(t),this}offset(t){return this.query.offset(t),this}toQuery(){return this.filters.length>0&&this.query.filter({$and:this.filters}),this.query}withDeletedRows(){return this.filters=this.filters.filter(t=>!("version"in t)),this}deletedRowsOnly(){return this.withDeletedRows(),this.filters.push({version:{$lte:-1}}),this}selectSelfFields(){return this.query.select(["id","title","description","platform","version"]),this}selectId(){return this.query.select(["id"]),this}selectTitle(){return this.query.select(["title"]),this}selectDescription(){return this.query.select(["description"]),this}selectVersion(){return this.query.select(["version"]),this}selectPlatformWith(t){return this.query.select(["platform"]),this.query.relationQuery("platform",t.toQuery(),"platform","id",!1,{kind:"relation-select",method:"selectPlatformWith",relation:"platform"}),this}withPlatformMatching(t){return this.filters.push({platform:{$inSubquery:{query:t.toQuery(),field:"id"}}}),this}withoutPlatformMatching(t){return this.filters.push({platform:{$notInSubquery:{query:t.toQuery(),field:"id"}}}),this}withIdIs(t){return this.filters.push({id:{$eq:t}}),this}withIdIsNot(t){return this.filters.push({id:{$ne:t}}),this}withIdIn(...t){return this.filters.push({id:{$in:t}}),this}withIdNotIn(...t){return this.filters.push({id:{$notIn:t}}),this}withIdGreaterThan(t){return this.filters.push({id:{$gt:t}}),this}withIdGreaterThanOrEqualTo(t){return this.filters.push({id:{$gte:t}}),this}withIdLessThan(t){return this.filters.push({id:{$lt:t}}),this}withIdLessThanOrEqualTo(t){return this.filters.push({id:{$lte:t}}),this}withIdBetween(t,e){return this.filters.push({id:{$between:[t,e]}}),this}withIdIsKnown(){return this.filters.push({id:{$isNull:!1}}),this}withIdIsUnknown(){return this.filters.push({id:{$isNull:!0}}),this}withTitleContaining(t){return this.filters.push({title:{$contains:t}}),this}withTitleIs(t){return this.filters.push({title:{$eq:t}}),this}withTitleIsNot(t){return this.filters.push({title:{$ne:t}}),this}withTitleIn(...t){return this.filters.push({title:{$in:t}}),this}withTitleNotIn(...t){return this.filters.push({title:{$notIn:t}}),this}withTitleGreaterThan(t){return this.filters.push({title:{$gt:t}}),this}withTitleGreaterThanOrEqualTo(t){return this.filters.push({title:{$gte:t}}),this}withTitleLessThan(t){return this.filters.push({title:{$lt:t}}),this}withTitleLessThanOrEqualTo(t){return this.filters.push({title:{$lte:t}}),this}withTitleBetween(t,e){return this.filters.push({title:{$between:[t,e]}}),this}withTitleIsKnown(){return this.filters.push({title:{$isNull:!1}}),this}withTitleIsUnknown(){return this.filters.push({title:{$isNull:!0}}),this}withTitleNotContaining(t){return this.filters.push({title:{$notContains:t}}),this}withTitleStartingWith(t){return this.filters.push({title:{$startsWith:t}}),this}withTitleNotStartingWith(t){return this.filters.push({title:{$notStartsWith:t}}),this}withTitleEndingWith(t){return this.filters.push({title:{$endsWith:t}}),this}withTitleNotEndingWith(t){return this.filters.push({title:{$notEndsWith:t}}),this}withTitleSoundingLike(t){return this.filters.push({title:{$soundLike:t}}),this}withDescriptionContaining(t){return this.filters.push({description:{$contains:t}}),this}withDescriptionIs(t){return this.filters.push({description:{$eq:t}}),this}withDescriptionIsNot(t){return this.filters.push({description:{$ne:t}}),this}withDescriptionIn(...t){return this.filters.push({description:{$in:t}}),this}withDescriptionNotIn(...t){return this.filters.push({description:{$notIn:t}}),this}withDescriptionGreaterThan(t){return this.filters.push({description:{$gt:t}}),this}withDescriptionGreaterThanOrEqualTo(t){return this.filters.push({description:{$gte:t}}),this}withDescriptionLessThan(t){return this.filters.push({description:{$lt:t}}),this}withDescriptionLessThanOrEqualTo(t){return this.filters.push({description:{$lte:t}}),this}withDescriptionBetween(t,e){return this.filters.push({description:{$between:[t,e]}}),this}withDescriptionIsKnown(){return this.filters.push({description:{$isNull:!1}}),this}withDescriptionIsUnknown(){return this.filters.push({description:{$isNull:!0}}),this}withDescriptionNotContaining(t){return this.filters.push({description:{$notContains:t}}),this}withDescriptionStartingWith(t){return this.filters.push({description:{$startsWith:t}}),this}withDescriptionNotStartingWith(t){return this.filters.push({description:{$notStartsWith:t}}),this}withDescriptionEndingWith(t){return this.filters.push({description:{$endsWith:t}}),this}withDescriptionNotEndingWith(t){return this.filters.push({description:{$notEndsWith:t}}),this}withDescriptionSoundingLike(t){return this.filters.push({description:{$soundLike:t}}),this}filterByPlatform(t){return this.filters.push({platform:{$eq:t}}),this}filterByPlatformIn(...t){return this.filters.push({platform:{$in:t}}),this}withPlatformIsKnown(){return this.filters.push({platform:{$isNull:!1}}),this}withPlatformIsUnknown(){return this.filters.push({platform:{$isNull:!0}}),this}withVersionIs(t){return this.filters.push({version:{$eq:t}}),this}withVersionIsNot(t){return this.filters.push({version:{$ne:t}}),this}withVersionIn(...t){return this.filters.push({version:{$in:t}}),this}withVersionNotIn(...t){return this.filters.push({version:{$notIn:t}}),this}withVersionGreaterThan(t){return this.filters.push({version:{$gt:t}}),this}withVersionGreaterThanOrEqualTo(t){return this.filters.push({version:{$gte:t}}),this}withVersionLessThan(t){return this.filters.push({version:{$lt:t}}),this}withVersionLessThanOrEqualTo(t){return this.filters.push({version:{$lte:t}}),this}withVersionBetween(t,e){return this.filters.push({version:{$between:[t,e]}}),this}withVersionIsKnown(){return this.filters.push({version:{$isNull:!1}}),this}withVersionIsUnknown(){return this.filters.push({version:{$isNull:!0}}),this}orderByIdAscending(){return this.query.orderBy("id","asc"),this}orderByIdDescending(){return this.query.orderBy("id","desc"),this}orderByTitleAscending(){return this.query.orderBy("title","asc"),this}orderByTitleDescending(){return this.query.orderBy("title","desc"),this}orderByDescriptionAscending(){return this.query.orderBy("description","asc"),this}orderByDescriptionDescending(){return this.query.orderBy("description","desc"),this}orderByVersionAscending(){return this.query.orderBy("version","asc"),this}orderByVersionDescending(){return this.query.orderBy("version","desc"),this}count(){return this.query.aggregate("Count","id","count"),this._pageCountAlias="count",this._pageCountMethod="count",this}countAs(t){return this.query.aggregate("Count","id",t),this._pageCountAlias=t,this._pageCountMethod="countAs",this}groupById(){return this.query.groupBy("id"),this}groupByIdAs(t){return this.query.groupBy("id"),this}groupByTitle(){return this.query.groupBy("title"),this}groupByTitleAs(t){return this.query.groupBy("title"),this}groupByDescription(){return this.query.groupBy("description"),this}groupByDescriptionAs(t){return this.query.groupBy("description"),this}groupByPlatform(){return this.query.groupBy("platform"),this}groupByPlatformAs(t){return this.query.groupBy("platform"),this}groupByVersion(){return this.query.groupBy("version"),this}groupByVersionAs(t){return this.query.groupBy("version"),this}facetByPlatformAs(t,e,i=!0){return this.query.facetBy(t,"platform",e,i,{kind:"facet",method:"facetByPlatformAs",relation:"platform",alias:t}),this}async executeForListInternal(t){if(this.ensureIntent(),this._pageCountAlias!==void 0)return this.executeCountedListInternal(t);this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),i=await e.executeQuery(t.prepareQuery(this.query)),r=this.query.aggregateItems.length>0&&this.query.groupByItems.length===0,s=r?[]:i.map(n=>n instanceof m?n:m.fromRecord(n,new $)),a=new I(s);return r&&i[0]&&Object.assign(a.aggregations,i[0]),this.query.facets.length>0&&(a.facets=await C(e,n=>t.prepareQuery(n),this.query,this.query.facets)),a}async executeForRowsInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService");return new I(await e.executeQuery(t.prepareQuery(this.query)))}async executeCountedListInternal(t){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const e=t.requireResource("dataService"),i=t.prepareQuery(this.query),r=i.localIdSetPaginationOptions()!==void 0,s={kind:"named-count",method:this._pageCountMethod??"count",...this._pageCountMethod==="countAs"?{alias:this._pageCountAlias}:{}},a=r?void 0:await e.executeCount(i,this._pageCountAlias,s),n=i.clone();n.aggregateItems=n.aggregateItems.filter(l=>!(String(l.function).toLowerCase()==="count"&&l.alias===this._pageCountAlias));const d=await e.executeQuery(n),u=r&&t.idSetPaginationCountAccuracy==="EXACT"?t.idSetPaginationCount:a??await e.executeCount(i,this._pageCountAlias,s),h=new I(d.map(l=>l instanceof m?l:m.fromRecord(l,new $)));return h.totalCount=u,this._pageCountAlias!==void 0&&(h.aggregations[this._pageCountAlias]=u),this.query.facets.length>0&&(h.facets=await C(e,l=>t.prepareQuery(l),i,i.facets)),h}executeForStreamInternal(t,e){this.ensureIntent(),this.filters.length>0&&this.query.filter({$and:this.filters});const i=t.requireResource("dataService"),r=t.prepareQuery(this.query),s=i.executeForStream(r,e);return(async function*(){for await(const a of s)for(const n of a)yield n instanceof m?n:m.fromRecord(n,new $)})()}ensureIntent(){new K(this._comment,this._purpose)}}class Z{constructor(t,e,i,r,s,a){this.execute=t,this.executeRows=e,this.stream=i,this.limitOne=r,this.addComment=s,this.ensureIntent=a}execute;executeRows;stream;limitOne;addComment;ensureIntent;comment(t){return this.addComment(t),this}newEntity(t){return this.ensureIntent(),new m}executeForList(t){return this.ensureIntent(),this.execute(t)}executeForRows(t){return this.ensureIntent(),this.executeRows(t)}executeForStream(t,e=1e3){return this.ensureIntent(),this.stream(t,e)}async executeForOne(t){return this.limitOne(),(await this.executeForList(t))[0]}}class R{static platforms(){return new A(!1)}static platformsWithMinimalFields(){return new A(!0)}static workItems(){return new x(!1)}static workItemsWithMinimalFields(){return new x(!0)}}const tt={Platform:{table:"platform_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",auditMaskFields:[],columns:{id:{columnName:"id",modelName:"id",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logPolicy:"plain",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logPolicy:"plain",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logPolicy:"plain",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}};async function et(o){let t=(await R.platforms().withIdIs("1").comment("what: locate generated Domain Root").purpose("why: idempotent runtime bootstrap").executeForList(o))[0];t||(t=y.teaqlBootstrapNew("1"),t.updateName("Runtime Example"),await t.auditAs("create generated Domain Root Platform").save(o)),o.withActiveRoot({entity:"Platform",id:t.id})}const it=new U(tt,{Platform:{checkAndFix(o,t,e){o.getResource("fixTime"),(t.action==="Create"&&t.payload.name===void 0||t.payload.name===null)&&e.push({ruleId:"required",location:g.property("name")}),t.payload.name!=null&&[...String(t.payload.name)].length>100&&e.push({ruleId:"max_length",location:g.property("name"),inputValue:t.payload.name,systemValue:100})}},WorkItem:{checkAndFix(o,t,e){o.getResource("fixTime"),(t.action==="Create"&&t.payload.title===void 0||t.payload.title===null)&&e.push({ruleId:"required",location:g.property("title")}),t.payload.title!=null&&!([...String(t.payload.title)].length>=1)&&e.push({ruleId:"min_length",location:g.property("title"),inputValue:t.payload.title,systemValue:1}),t.payload.title!=null&&[...String(t.payload.title)].length>80&&e.push({ruleId:"max_length",location:g.property("title"),inputValue:t.payload.title,systemValue:80}),t.payload.description!=null&&[...String(t.payload.description)].length>100&&e.push({ruleId:"max_length",location:g.property("description"),inputValue:t.payload.description,systemValue:100}),(t.action==="Create"&&t.payload.platform===void 0||t.payload.platform===null)&&e.push({ruleId:"required",location:g.property("platform")})}}},{defaultDomainRoot:{entity:"Platform",id:"1",values:{name:"Runtime Example"}},constants:[],ensure:et}),rt={Platform:{table:"platform_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},name:{columnName:"name",modelName:"name",logicalType:"text",decode:"native",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{workItemList:{targetEntity:"WorkItem",localKey:"id",foreignKey:"platform",many:!0}}},WorkItem:{table:"work_item_data",columns:{id:{columnName:"id",modelName:"id",logicalType:"integer",decode:"string",nullable:!1},title:{columnName:"title",modelName:"title",logicalType:"text",decode:"native",nullable:!1},description:{columnName:"description",modelName:"description",logicalType:"text",decode:"native",nullable:!0},platform:{columnName:"platform",modelName:"platform",logicalType:"integer",decode:"string",nullable:!1},version:{columnName:"version",modelName:"version",logicalType:"integer",decode:"number",nullable:!1}},relations:{platform:{targetEntity:"Platform",localKey:"platform",foreignKey:"id",many:!1}}}},F=document.querySelector("#status"),st=document.querySelector("#result"),T=document.querySelector("#persist"),E=document.querySelector("#reset");let b;const M=localStorage.getItem("teaql-browser-storage")==="opfs"?"opfs":"memory";T.checked=M==="opfs";async function nt(o){const t=new Worker(new URL("/assets/sqlite.worker-DS5P4U1E.js",import.meta.url),{type:"module"}),e=await z.open(t,{...rt},{storage:o,databaseName:"teaql-browser-example.sqlite3"});e.install(it);const i=Object.freeze({policyId:"browser-demo-seed",version:"1",fingerprint:"sha256:browser-demo-seed-v1"}),r=new H().insertResource("dataService",e).withMutationPolicyRegistry(new J(()=>({identity:i,review:(s,a)=>a.operations.length>0?{verdict:"allow"}:{verdict:"deny",code:"EMPTY_GRAPH",message:"empty mutation graph"}}))).withMutationPolicyApprovalProvider(new Y(s=>({policy:s,approvedBy:"browser-demo-owner",approvedAt:new Date})));return e.setUserContext(r),await r.ensureSchema(),{client:e,context:r}}async function Q({context:o}){if(!(await R.workItemsWithMinimalFields().comment("what: detect existing browser demo records").purpose("why: keep generated mutation bootstrap idempotent").executeForList(o)).length)for(const e of["Evaluate semantic model","Generate typed library","Verify browser runtime"])await new m().updateTitle(e).updatePlatform("1").auditAs("seed deterministic browser demo data").save(o)}async function V(o){const t=await R.workItems().selectTitle().orderByIdAscending().limit(20).comment("what: load browser-local work items").purpose("why: prove the generated Q API runs without a backend").executeForList(o.context);st.textContent=JSON.stringify(t,null,2),F.textContent=`${o.client.storage.toUpperCase()} · ${t.length} rows · policy installed · ready`}async function j(o){F.textContent=`Opening ${o.toUpperCase()} SQLite/WASM…`;const t=b;b=void 0,await t?.client.close();const e=await nt(o);b=e,await Q(e),await V(e)}T.addEventListener("change",()=>{const o=T.checked?"opfs":"memory";localStorage.setItem("teaql-browser-storage",o),j(o).catch(W)});E.addEventListener("click",async()=>{if(b){E.disabled=!0;try{await b.client.reset(b.context),await Q(b),await V(b)}catch(o){W(o)}finally{E.disabled=!1}}});function W(o){const t=o instanceof Error?o:new Error(String(o));F.textContent=`${t.name}: ${t.message}`}j(M).catch(W); diff --git a/dist/index.html b/dist/index.html index 816ebe40b8e1621d87967e9ec06ed09b42260864..dfbc2fdc83b0c384a9dfa15482fc83bb3dfd8f08 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,45 +1,142 @@ - - - - - TeaQL browser order TraceChain - - - - -
-

GENERATED Q + E · SQLITE/WASM · NO BACKEND

-

Order query evidence

-

One filtered page, named total, status facets and bounded item previews.

-

Entirely browser-local · SQLite/WASM · Generated typed Order Q/E APIs

-

Runtime source · This demo's source snapshot

-
- - - + + + + + + TeaQL Order Query Playground + + + + + +
+ + +
+
+
+

BROWSER SQLITE · ORDER DOMAIN

+

Understand TeaQL queries through a familiar order model.

+

Platform, customer, order, item, payment, and shipment data all run in the browser. Order status is backed by a constant model. Choose a query below to inspect real SQLite/WASM results.

+
+
+
+ PlatformPlatform + → + CustomerCustomer + → + OrderOrder +
+ ↓ +
+ ItemItem + PaymentPayment + ShipmentShipment + OrderStatusConstant model +
+
+
+ +
+

Starting SQLite/WASM…

+
+ + +
+
+ +
+
+
+

01 / QUERIES

+

Choose a query

+
+

Queries are grouped by purpose and share the same order dataset.

+
+ +
+ +
+
+
+

02 / RESULT

+

Comprehensive: Order management center

+

+
+
+
+ + +
+
+ + +
+
+
+
+
+
+ Result tree +

Waiting for query…

+
+
+
+
+

GENERATED Q QUERY

+
+ +

The Q expression stays fixed; search, status cards, and pagination only update dynamic parameters. The underlying SelectQuery remains inside the generated request implementation.

+
+
+
+

EXECUTION EVIDENCE

+ 0 statements +
+
+ + + + + + + + + + +
TimeIdentityTrace chainSQL
+
+

One plain-text line per statement: time, identity, trace chain, and the SQL SQLite executed.

+
+
+
+
+ +
+ TeaQL TypeScript Runtime + Data stays in this browser +
- - - - -

No eval, imports, assignments or arbitrary JavaScript execution.

- - -

Starting SQLite/WASM…

-

Response data and metadata

-

-    

SQL execution evidence

-

Time is the recorded execution duration. Identity is the request entity from tracePath, not a user or object ID.

-
- - - -
TimeIdentityTrace chainSQL
-
-
Business TraceChain as text
-
Runtime metadata and physical tracePath
-
- + diff --git a/dist/orders.html b/dist/orders.html new file mode 100644 index 0000000000000000000000000000000000000000..da4005c10592e553808339dc4827e059ea60b5d5 --- /dev/null +++ b/dist/orders.html @@ -0,0 +1,43 @@ + + + + + + + TeaQL browser order TraceChain + + + + + + +
+

GENERATED Q + E · SQLITE/WASM · NO BACKEND

+

Order query evidence

+

One filtered page, named total, status facets and bounded item previews.

+

WorkItem demo · Runtime source

+
+ + + +
+ + + + +

Starting SQLite/WASM…

+

Response data and metadata

+

+    

SQL execution evidence

+

Time is the recorded execution duration. Identity is the request entity from tracePath, not a user or object ID.

+
+ + + +
TimeIdentityTrace chainSQL
+
+
Business TraceChain as text
+
Runtime metadata and physical tracePath
+
+ + diff --git a/dist/work-items.html b/dist/work-items.html new file mode 100644 index 0000000000000000000000000000000000000000..5678d61125ebad3bb4c143319b0d5ca5b52015e5 --- /dev/null +++ b/dist/work-items.html @@ -0,0 +1,28 @@ + + + + + + + TeaQL Browser SQLite WorkItems + + + + + + +
+

TEAQL TYPESCRIPT RUNTIME

+

Browser-local Data Service

+

Generated Q APIs and audited mutations, backed by SQLite/WASM.

+

Open the order management center

+

Open the generated order TraceChain page

+
+ + +
+

Starting SQLite/WASM…

+

+    
+ + diff --git a/evidence/live-browser.json b/evidence/live-browser.json deleted file mode 100644 index 2ee8639cf75d808ef7af824030ed8d4ffbddc5b2..0000000000000000000000000000000000000000 --- a/evidence/live-browser.json +++ /dev/null @@ -1,3813 +0,0 @@ -{ - "url": "https://teaql-browser-sqlite-playground.static.hf.space/", - "host": { - "crossOriginIsolated": false, - "opfsDisabled": true - }, - "receipts": [ - { - "label": "first", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 7000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "rendered": [ - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "7000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "diagnostics-off", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "rendered": [ - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "restored", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 5000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "rendered": [ - [ - "5000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "reset", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "rendered": [ - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "refresh", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 7000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 6000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 6000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "rendered": [ - [ - "7000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "6000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "6000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - } - ], - "queryPresetSwitch": true, - "forbiddenConstructorRejected": true, - "errors": [], - "passed": true -} diff --git a/evidence/local-browser.json b/evidence/local-browser.json deleted file mode 100644 index 672e0e2a049569819bc92cc4a3ce4e957e904fc1..0000000000000000000000000000000000000000 --- a/evidence/local-browser.json +++ /dev/null @@ -1,6096 +0,0 @@ -{ - "receipts": [ - { - "label": "memory-first", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 7000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 5000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "diagnostics": 8, - "renderedEvidence": [ - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "7000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "5000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "restored-preset", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 5000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "diagnostics": 8, - "renderedEvidence": [ - [ - "5000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "memory-refresh", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 5000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 6000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "diagnostics": 8, - "renderedEvidence": [ - [ - "5000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "6000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "memory-logging-off", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "diagnostics": 0, - "renderedEvidence": [ - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "memory-reset", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 6000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 1000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 2000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "diagnostics": 0, - "renderedEvidence": [ - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "6000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "1000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "2000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "opfs-first", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 5000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 6000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 8000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 6000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "diagnostics": 0, - "renderedEvidence": [ - [ - "5000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "6000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "8000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "6000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "opfs-refresh", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 5000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 7000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 6000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 5000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "diagnostics": 8, - "renderedEvidence": [ - [ - "5000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "7000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "6000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "5000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - }, - { - "label": "opfs-reset", - "response": { - "resultCode": 0, - "status": "YES", - "version": "1.001", - "recordCount": 3, - "data": [ - { - "id": "2", - "version": 1, - "orderNumber": "KEEP-002", - "orderDate": "2026-10-02", - "status": { - "name": "Paid", - "color": "#22C55E" - }, - "items": [ - { - "productName": "Box 1", - "quantity": 1 - }, - { - "productName": "Box 2", - "quantity": 2 - }, - { - "productName": "Box 3", - "quantity": 3 - } - ], - "itemCount": 5 - } - ], - "metadata": { - "totalCount": 3, - "pageOffset": 1, - "pageSize": 1, - "aggregations": { - "totalOrders": 3 - }, - "searchWarnings": [] - }, - "facets": { - "statusCounts": [ - { - "id": "1001", - "name": "New", - "color": "#94A3B8", - "orderCount": 1, - "orderTotalAmount": 100 - }, - { - "id": "1002", - "name": "Paid", - "color": "#22C55E", - "orderCount": 2, - "orderTotalAmount": 500 - }, - { - "id": "1003", - "name": "Cancelled", - "color": "#EF4444", - "orderCount": 0, - "orderTotalAmount": null - } - ] - } - }, - "evidence": [ - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "countAs('totalOrders')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "KEEP", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 10000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT ? OFFSET ?", - "parameters": [ - 1, - "KEEP", - 1, - 1 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 6000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "countOrderItemsAs('itemCount')" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= ?) AND (\"customer_order\" IN (?))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "parameters": [ - 1, - "2" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectStatusWith(...)" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND (\"id\" IN (?)) AND \"version\" > 0 LIMIT ?", - "parameters": [ - 1, - "1002", - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain" - ], - "elapsedMicros": 5000, - "resultCount": 1, - "resultSummary": "1 rows returned", - "maskedParameters": [ - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "selectOrderItemListWith(...)" - }, - { - "kind": "comment", - "name": "OrderItem", - "detail": "load item previews" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "orderItemList", - "detail": "CustomerOrder.orderItemList", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= ?)) AND (\"customer_order\" IN (?)) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > ? AND \"__teaql_partition_rank\" <= ? ORDER BY \"__teaql_partition_rank\"", - "parameters": [ - 1, - "2", - 0, - 3 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false, - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 2 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 3 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - "KEEP" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "OrderStatus", - "detail": "load status facets" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 3 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 4 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= ?)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT ?", - "parameters": [ - 1, - 10000 - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain" - ], - "elapsedMicros": 4000, - "resultCount": 3, - "resultSummary": "3 rows returned", - "maskedParameters": [ - false, - false - ], - "logMode": "masked" - }, - { - "operation": "select", - "comment": "load order list", - "purpose": "render order list page", - "traceChain": [ - { - "kind": "purpose", - "name": "CustomerOrder", - "detail": "render order list page" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "load order list" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "facetByStatusAs('statusCounts')" - }, - { - "kind": "comment", - "name": "CustomerOrder", - "detail": "aggregate status" - } - ], - "tracePath": [ - { - "kind": "operation", - "name": "CustomerOrder", - "detail": "query", - "level": 0 - }, - { - "kind": "request", - "name": "CustomerOrder", - "detail": "", - "level": 1 - }, - { - "kind": "relation", - "name": "status", - "detail": "CustomerOrder.status", - "level": 2 - }, - { - "kind": "relation", - "name": "customerOrderList", - "detail": "OrderStatus.customerOrderList", - "level": 3 - }, - { - "kind": "provider", - "name": "sqlite", - "detail": "", - "level": 4 - }, - { - "kind": "sql", - "name": "select", - "detail": "", - "level": 5 - } - ], - "executionOutcome": "success", - "parameterizedSQL": "SELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= ?)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || ? || '%'))) AND \"version\" > 0))) AND (\"status\" IN (?, ?, ?))) AND \"version\" > 0 GROUP BY \"status\"", - "parameters": [ - 1, - 1, - "KEEP", - "1001", - "1002", - "1003" - ], - "debugSQL": "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"", - "databaseKind": "sqlite", - "sqlOrigin": "generated", - "parameterLogPolicies": [ - "plain", - "plain", - "plain", - "plain", - "plain", - "plain" - ], - "elapsedMicros": 3000, - "resultCount": 2, - "resultSummary": "2 rows returned", - "maskedParameters": [ - false, - false, - false, - false, - false, - false - ], - "logMode": "masked" - } - ], - "diagnostics": 8, - "renderedEvidence": [ - [ - "10000 µs", - "CustomerOrder", - "render order list page: load order list → countAs('totalOrders')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT COUNT(\"id\") AS \"totalOrders\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 LIMIT 10000" - ], - [ - "6000 µs", - "CustomerOrder", - "render order list page: load order list", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"order_number\" AS \"orderNumber\", \"order_date\" AS \"orderDate\", \"status\" AS \"status\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 ORDER BY \"order_date\" DESC, \"id\" DESC LIMIT 1 OFFSET 1" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → countOrderItemsAs('itemCount')", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"customer_order\" AS \"customerOrder\", COUNT(\"id\") AS \"itemCount\" FROM \"order_item_data\" WHERE ((\"version\" >= 1) AND (\"customer_order\" IN ('2'))) AND \"version\" > 0 GROUP BY \"customer_order\"" - ], - [ - "5000 µs", - "CustomerOrder", - "render order list page: load order list → selectStatusWith(...) → load status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND (\"id\" IN ('1002')) AND \"version\" > 0 LIMIT 10000" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → selectOrderItemListWith(...) → load item previews", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT * FROM (SELECT \"id\" AS \"id\", \"version\" AS \"version\", \"product_name\" AS \"productName\", \"quantity\" AS \"quantity\", \"customer_order\" AS \"customerOrder\", ROW_NUMBER() OVER (PARTITION BY \"customer_order\" ORDER BY \"id\" ASC) AS \"__teaql_partition_rank\" FROM \"order_item_data\" WHERE ((\"version\" >= 1)) AND (\"customer_order\" IN ('2')) AND \"version\" > 0) AS \"__teaql_partitioned\" WHERE \"__teaql_partition_rank\" > 0 AND \"__teaql_partition_rank\" <= 3 ORDER BY \"__teaql_partition_rank\"" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", COUNT(\"id\") AS \"orderCount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0 GROUP BY \"status\"" - ], - [ - "4000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → load status facets", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"id\" AS \"id\", \"version\" AS \"version\", \"name\" AS \"name\", \"color\" AS \"color\" FROM \"order_status_data\" WHERE ((\"version\" >= 1)) AND \"version\" > 0 ORDER BY \"display_order\" ASC LIMIT 10000" - ], - [ - "3000 µs", - "CustomerOrder", - "render order list page: load order list → facetByStatusAs('statusCounts') → aggregate status", - "-- TeaQL MASKED; NOT REPLAYABLE\nSELECT \"status\" AS \"status\", SUM(\"total_amount\") AS \"orderTotalAmount\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (\"id\" IN (SELECT \"id\" FROM \"customer_order_data\" WHERE ((((\"version\" >= 1)) AND (CAST(\"order_number\" AS TEXT) LIKE '%' || 'KEEP' || '%'))) AND \"version\" > 0))) AND (\"status\" IN ('1001', '1002', '1003'))) AND \"version\" > 0 GROUP BY \"status\"" - ] - ] - } - ], - "queryPresetSwitch": true, - "forbiddenConstructorRejected": true, - "generatedLibraryUnchanged": true, - "browserErrors": [] -} diff --git a/index.html b/index.html index 816ebe40b8e1621d87967e9ec06ed09b42260864..dfbc2fdc83b0c384a9dfa15482fc83bb3dfd8f08 100644 --- a/index.html +++ b/index.html @@ -1,45 +1,142 @@ - - - - - TeaQL browser order TraceChain - - - - -
-

GENERATED Q + E · SQLITE/WASM · NO BACKEND

-

Order query evidence

-

One filtered page, named total, status facets and bounded item previews.

-

Entirely browser-local · SQLite/WASM · Generated typed Order Q/E APIs

-

Runtime source · This demo's source snapshot

-
- - - + + + + + + TeaQL Order Query Playground + + + + + +
+ + +
+
+
+

BROWSER SQLITE · ORDER DOMAIN

+

Understand TeaQL queries through a familiar order model.

+

Platform, customer, order, item, payment, and shipment data all run in the browser. Order status is backed by a constant model. Choose a query below to inspect real SQLite/WASM results.

+
+
+
+ PlatformPlatform + → + CustomerCustomer + → + OrderOrder +
+ ↓ +
+ ItemItem + PaymentPayment + ShipmentShipment + OrderStatusConstant model +
+
+
+ +
+

Starting SQLite/WASM…

+
+ + +
+
+ +
+
+
+

01 / QUERIES

+

Choose a query

+
+

Queries are grouped by purpose and share the same order dataset.

+
+ +
+ +
+
+
+

02 / RESULT

+

Comprehensive: Order management center

+

+
+
+
+ + +
+
+ + +
+
+
+
+
+
+ Result tree +

Waiting for query…

+
+
+
+
+

GENERATED Q QUERY

+
+ +

The Q expression stays fixed; search, status cards, and pagination only update dynamic parameters. The underlying SelectQuery remains inside the generated request implementation.

+
+
+
+

EXECUTION EVIDENCE

+ 0 statements +
+
+ + + + + + + + + + +
TimeIdentityTrace chainSQL
+
+

One plain-text line per statement: time, identity, trace chain, and the SQL SQLite executed.

+
+
+
+
+ +
+ TeaQL TypeScript Runtime + Data stays in this browser +
- - - - -

No eval, imports, assignments or arbitrary JavaScript execution.

- - -

Starting SQLite/WASM…

-

Response data and metadata

-

-    

SQL execution evidence

-

Time is the recorded execution duration. Identity is the request entity from tracePath, not a user or object ID.

-
- - - -
TimeIdentityTrace chainSQL
-
-
Business TraceChain as text
-
Runtime metadata and physical tracePath
-
- + diff --git a/orders.html b/orders.html new file mode 100644 index 0000000000000000000000000000000000000000..da4005c10592e553808339dc4827e059ea60b5d5 --- /dev/null +++ b/orders.html @@ -0,0 +1,43 @@ + + + + + + + TeaQL browser order TraceChain + + + + + + +
+

GENERATED Q + E · SQLITE/WASM · NO BACKEND

+

Order query evidence

+

One filtered page, named total, status facets and bounded item previews.

+

WorkItem demo · Runtime source

+
+ + + +
+ + + + +

Starting SQLite/WASM…

+

Response data and metadata

+

+    

SQL execution evidence

+

Time is the recorded execution duration. Identity is the request entity from tracePath, not a user or object ID.

+
+ + + +
TimeIdentityTrace chainSQL
+
+
Business TraceChain as text
+
Runtime metadata and physical tracePath
+
+ + diff --git a/source/browser-sqlite/generated-order-hashes.json b/source/browser-sqlite/generated-order-hashes.json deleted file mode 100644 index c2fe0e54bac56d3734ac10827906112e952f2fc5..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/generated-order-hashes.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "package.json" : "bbfaeef0b7488ec0f44377eecc68375124b8f0c4fcacd7d59df1755b0a127581", - "src/generated-bootstrap.ts" : "5f3065c1e4794c0d21ada7c2eef48f4694cec1cbc4771fa48bc7d6ff9221540b", - "src/generated-search-models.ts" : "7ece2e29eeb80306d09623c8685c8a0b8d3b25aad6b38f845d5c9f069bd6f7a3", - "src/generated/E.ts" : "c4c72de70c1b103343390acee51970dd1fa01cdbe1bdebd9b9aa34b3539d2039", - "src/generated/Q.ts" : "e03153a1477298d4b6568bdeab1b98cab21bf98fcafd6a2fb248a1129db0b46f", - "src/generated/models/Customer.ts" : "d134c6b78e25d86dacea5d4c738178c3629101269413bb45d62a2f490d9b4417", - "src/generated/models/CustomerOrder.ts" : "c65e857a6deb99599e34a06bb24ca948cc852e9a15b969ff4ffe21d041fcf05c", - "src/generated/models/OrderItem.ts" : "ce43fb172b461b74d53cb73933335a8fa055b6269738f44bf3e1deb04e1d8b85", - "src/generated/models/OrderStatus.ts" : "c6e3349c7da21267dee6940b61a9d43bc0413a7d68230b9c600b73ec82f96e16", - "src/generated/models/Platform.ts" : "6a2df07a3fc284d02639ecb530d0aaa58e448dbc77de7d97b46dc4e367cd58fd", - "src/generated/requests/CustomerOrderRequest.ts" : "0f2a2a3895c7245ea258354e6fc19e24b4e57adc48a29818abe7b8ce8126cb57", - "src/generated/requests/CustomerRequest.ts" : "109f1df30ccafb9e4a163fa5f94d8e77d915cd2bb5a2d8bf3e7adeadbe92e262", - "src/generated/requests/OrderItemRequest.ts" : "ab3fb698f606c848da983eaabc140268066b8d9bac73b54127733c98e48e19d9", - "src/generated/requests/OrderStatusRequest.ts" : "f9087a9084b3aaac46d91cd7006cf5b71214df711bfd0f51e17da83a53e633c9", - "src/generated/requests/PlatformRequest.ts" : "8a6dd581be256cad3332ca275ac3652ef1e01a0c4c9f0e6cefd2a6e14fc105e1", - "src/runtime-module.ts" : "f92fe9a9474678d26a233eb734b14493b4ddc216ed3b648bfad723b4b6a46eeb", - "src/teaql-schemas.ts" : "68cb7cacc725ff041d2289f17d7817ae56f37d035c92f2feb6c1318face6f806", - "src/teaql-ts.ts" : "cc705f9f7873450eae541311317db3402dc40b7cf068c440169bd7ba06dcb1ed", - "teaql-i18n.json" : "ee5dc28e916a8907555d5d5a4d0e3cf2fa37aad047af37abed0800582af18d96", - "tsconfig.json" : "cf9a9767019ac7f4035a6d16952a5ae75b964b1c10c4584822b90799e6ce2037" -} \ No newline at end of file diff --git a/source/browser-sqlite/scripts/verify-space.mjs b/source/browser-sqlite/scripts/verify-space.mjs deleted file mode 100644 index d9b29b7d4cffd0235ff83ae8a019516ff44443bf..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/scripts/verify-space.mjs +++ /dev/null @@ -1,63 +0,0 @@ -import assert from 'node:assert/strict'; -import {writeFileSync} from 'node:fs'; -import puppeteer from 'puppeteer-core'; - -const url = process.env.TEAQL_SPACE_URL || 'https://teaql-browser-sqlite-playground.static.hf.space/'; -const browser = await puppeteer.launch({executablePath: process.env.CHROME_BIN || '/usr/bin/google-chrome', - headless: true, args: ['--no-sandbox', '--disable-dev-shm-usage']}); -try { - const page = await browser.newPage(), errors = []; - page.on('pageerror', error => errors.push(error.message)); - page.on('console', event => { if (event.type() === 'error') errors.push(event.text()); }); - page.on('response', response => { if (response.status() >= 400) errors.push(`${response.status()} ${response.url()}`); }); - page.on('requestfailed', request => errors.push(`${request.failure()?.errorText} ${request.url()}`)); - await page.goto(url, {waitUntil: 'networkidle0', timeout: 60_000}); - const waitReady = () => page.waitForFunction(() => document.querySelector('#status')?.textContent?.includes('ready'), {timeout: 45_000}); - await waitReady(); - async function inspect(label) { - const response = JSON.parse(await page.$eval('#result', element => element.textContent)); - const evidence = JSON.parse(await page.$eval('#sql', element => element.textContent)); - assert.equal(response.resultCode, 0); assert.equal(response.status, 'YES'); - assert.equal(response.recordCount, 3); assert.equal(response.metadata.totalCount, 3); - assert.equal(response.data[0].orderNumber, 'KEEP-002'); assert.equal(response.data[0].itemCount, 5); - assert.deepEqual(response.data[0].items.map(item => item.productName), ['Box 1', 'Box 2', 'Box 3']); - assert.deepEqual(response.facets.statusCounts.map(row => [row.orderCount, row.orderTotalAmount]), [[1, 100], [2, 500], [0, null]]); - assert.equal(evidence.length, 8); - const chains = evidence.map(entry => entry.traceChain.filter(node => node.kind === 'comment').map(node => node.detail)); - for (const expected of [ - ['load order list', "countAs('totalOrders')"], - ['load order list', 'selectStatusWith(...)', 'load status'], - ['load order list', 'selectOrderItemListWith(...)', 'load item previews'], - ['load order list', "countOrderItemsAs('itemCount')"], - ['load order list', "facetByStatusAs('statusCounts')", 'aggregate status'], - ['load order list', "facetByStatusAs('statusCounts')", 'load status facets'], - ]) assert.ok(chains.some(chain => JSON.stringify(chain) === JSON.stringify(expected)), JSON.stringify(expected)); - const rendered = await page.$$eval('#evidence-rows tr', rows => rows.map(row => [...row.querySelectorAll('td')].map(cell => cell.textContent))); - assert.deepEqual(rendered, evidence.map(entry => [`${entry.elapsedMicros} µs`, - entry.tracePath.find(node => node.kind === 'request')?.name ?? '—', - `${entry.traceChain.find(node => node.kind === 'purpose').detail}: ${entry.traceChain.filter(node => node.kind === 'comment').map(node => node.detail).join(' → ')}`, - entry.debugSQL])); - return {label, response, evidence, rendered}; - } - const receipts = [await inspect('first')]; - const host = await page.evaluate(() => ({crossOriginIsolated, opfsDisabled: document.querySelector('#persist').disabled})); - if (!host.crossOriginIsolated) assert.equal(host.opfsDisabled, true); - await page.click('#logging'); - await page.waitForFunction(() => document.querySelector('#status')?.textContent?.includes('0 diagnostics')); - receipts.push(await inspect('diagnostics-off')); - await page.select('#example', 'all'); - await page.waitForFunction(() => { const text = document.querySelector('#result')?.textContent; return text && JSON.parse(text).recordCount === 4; }); - await page.$eval('#search', element => { element.value = 'Q.constructor("return globalThis")'; }); - await page.click('#query'); - await page.waitForFunction(() => document.querySelector('#status')?.textContent?.includes('not allowed')); - assert.equal(await page.$eval('#sql', element => element.textContent), '[]'); - await page.click('#preset'); await waitReady(); receipts.push(await inspect('restored')); - await page.click('#reset'); - await page.waitForFunction(() => !document.querySelector('#reset').disabled); - receipts.push(await inspect('reset')); - await page.reload({waitUntil: 'networkidle0'}); await waitReady(); receipts.push(await inspect('refresh')); - assert.deepEqual(errors, []); - if (process.env.TEAQL_SPACE_EVIDENCE) writeFileSync(process.env.TEAQL_SPACE_EVIDENCE, - JSON.stringify({url, host, receipts, queryPresetSwitch: true, forbiddenConstructorRejected: true, errors, passed: true}, null, 2) + '\n', {flag: 'wx'}); - console.log(`PASS live Static Space: new TraceChain, 8 SQL records, editor/presets, WebResponse/facets, diagnostics-off, reset/refresh; OPFS disabled=${host.opfsDisabled}`); -} finally { await browser.close(); } diff --git a/source/browser-sqlite/src/web-response.ts b/source/browser-sqlite/src/web-response.ts deleted file mode 100644 index 8fe7f9d71f62198ab9b66ea59f01244afde071cd..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/src/web-response.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { SmartList } from 'teaql-ts'; - -/** Application response projection; querying and facet computation stay in the runtime. */ -export function webResponse(rows: SmartList) { - const facets = Object.fromEntries(Object.entries(rows.facets) - .map(([name, values]) => [name, Array.from(values)])); - return { - data: Array.from(rows), - resultCode: 0, - status: 'YES' as const, - recordCount: rows.totalCountOrLength(), - version: '1.001', - ...(Object.keys(facets).length ? {facets} : {}), - ...(Object.keys(rows.aggregations).length ? {aggregations: rows.aggregations} : {}), - }; -} diff --git a/source/browser-sqlite/tsconfig.json b/source/browser-sqlite/tsconfig.json deleted file mode 100644 index aab456117bd4a49e9cef2aba4ee1d2329f0f7051..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2022", - "module": "ESNext", - "moduleResolution": "Bundler", - "strict": true, - "skipLibCheck": true, - "types": ["vite/client"], - "lib": ["ES2022", "DOM", "WebWorker"] - }, - "include": ["src"] -} diff --git a/source/browser-sqlite/vendor/teaql-teaql-0.3.0.tgz b/source/browser-sqlite/vendor/teaql-teaql-0.3.0.tgz deleted file mode 100644 index f45fb36f10c9940bac720301d4797ac52d9f1928..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/vendor/teaql-teaql-0.3.0.tgz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1d4e5cbaecc4fcc06fe3b357a4575d6e5ca4a92673b625ef2c7d5ec7d02b287d -size 349294 diff --git a/source/browser-sqlite/vite.config.ts b/source/browser-sqlite/vite.config.ts deleted file mode 100644 index 770111c296d7cc6f5cc7a65403cc3490eaf16c8d..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/vite.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { defineConfig } from 'vite'; - -export default defineConfig({ - resolve: { preserveSymlinks: true }, - optimizeDeps: { exclude: ['@sqlite.org/sqlite-wasm'] }, - server: { - headers: { - 'Cross-Origin-Opener-Policy': 'same-origin', - 'Cross-Origin-Embedder-Policy': 'require-corp', - }, - }, - preview: { - headers: { - 'Cross-Origin-Opener-Policy': 'same-origin', - 'Cross-Origin-Embedder-Policy': 'require-corp', - }, - }, -}); diff --git a/source/provenance.json b/source/provenance.json index e4a6a34443d38110416dadd7eab2f8d181c8503c..f6a9c0e7c3b1f2c5fa6db6ed011ce2d43ac73fb2 100644 --- a/source/provenance.json +++ b/source/provenance.json @@ -1,61 +1,19 @@ { "repository": "https://github.com/teaql/teaql-ts", - "baseCommit": "b4068dc", - "branch": "feature/polyglot-request-trace-chain-20261011", - "runtimeVersion": "0.3.0", - "unreleasedRequestTreeCandidate": true, - "runtimeArchiveSha256": "1d4e5cbaecc4fcc06fe3b357a4575d6e5ca4a92673b625ef2c7d5ec7d02b287d", - "modelSha256": "dd86f59d512c88f8f0f41957122b18eceeb696dc188b208f42ed7b7b636144ec", - "runtimeHashes": { - "src/core/ast.ts": "75a9756107e1f9ca33847a5107a337666cc400c2b506a8789e7fb861aa068b64", - "src/core/checker.ts": "ba4d997dc75dd69db810864d4c91f2ab3482eebd1fc0e27f14fac7a737a85ced", - "src/core/context.ts": "c6a11bb236ba0f4b847e8e9a016bd14b5d7451349875e1eb1464af430db80a62", - "src/core/dynamic-search.ts": "37fbea226c530af09f92ed7af4b7f3b90a98d2740f8dc38a73f0d57b244f92a7", - "src/core/entity-root.ts": "fe6b15988efdca2d5c09b5a134cbcf1a423fd6d316b1b4bc5f3917fa21616c32", - "src/core/facet.ts": "85a8efc8b2960ffb104528c9925e8685f2d2aef1b379cf7c0b0300fe0ff577f2", - "src/core/i18n.ts": "acbb07afb6aa2960fef0936ade71959309d4ae8bb4b1ac3aca60f476b09572ed", - "src/core/loaded-scalar-snapshot.ts": "86759e26ac8a0f669a64a1de7564171fa2e1d18bbaa0c9a6ae167ae23399ce7c", - "src/core/local-cache.ts": "efdccfc0dcb48868761d8ebbc0bb9cf4f158a9ae7dec76fce8a2c076a07b0b92", - "src/core/log-privacy.ts": "2c5165ca9141ed9d5c84df511102c69b4b492083db3e50fb2e74acd3437f4d16", - "src/core/mutation-policy.ts": "a5f1c2b6e961f508faebfc0037a257b1f4abbe1437b52b5f09a9c85c71d4efe0", - "src/core/object-location.ts": "b55ca8e966b25eb505c77181f358b2a8405edc1e60b23a58756ceb9ca6a552dc", - "src/core/query-snapshot.ts": "eb28bfb42775f26e431c90b3013766afbbfd2d23c855e90eca781601482eef39", - "src/core/request-intent.ts": "3daf7cf19f3bc94db42a6dcf5750a8af46d03e659113f9d946b9ac985517420e", - "src/core/runtime-module.ts": "87c082b295c83c5d9ffb5c389bd66a48caca3ee6b792e99fa7f582ea33243a10", - "src/core/schema-capability.ts": "a0aabc048fc3fc66b6606f5173810e1bb147651423820292cf660d466862bf79", - "src/core/smart-list.ts": "c7aad0f28417259aa0a89281ba3cb87e623e6db27880387e7061c052165185f8", - "src/core/telemetry.ts": "6c43a3d5cedcfe75ca195dfc2650a5e868b0c81d58168bfd92b2b210a8ee1964", - "src/core/tools.ts": "a3df66934678175f43dbe16315446a88fb7c9cd995f2119a37418db6706e3712", - "src/core/trace-chain.ts": "f0f932e25f5a7ef02e4447ca53a4c4269e1e3a79bd0c5facb652f9c69e3f25b3", - "src/core/value.ts": "0f3034b1b7ce60ef8fc1120bbe5290ad31def72f04dfad6cc0110188ff829846", - "src/core/wire-fields.ts": "9a52feef63c32d543af0da5ba91d5a7e199552b33267b3709678fc259011fe8f", - "src/index.ts": "4b2ba3c022eae0ff0b2f0cf32dd92777fbce855f425a2888f07e84c05b036ee1", - "src/meta/descriptors.ts": "3f2a1e44c77d411aba98ca233b9ebf111b07156cfb9080f028f8cb2b0421c970", - "src/parser/dsl.ts": "aaf4519fb1ab982759a615ace7ed67c377df52c8f4b86185685295504ff189d0", - "src/parser/query-parser.generated.ts": "007b490204d146e205d04e013458105dbe255bbc6a946f9927133c812bb75f97", - "src/sql/browser-sqlite-protocol.ts": "28df5a79b20c5acc2df345b8c5028c2d1d72657bc42bb432447bb013ae78714d", - "src/sql/browser-sqlite-worker.ts": "9b0ea0e17983ff924a53f3fde63a6e0a429a533dba2c5c6e86587a69dc250075", - "src/sql/browser-sqlite.ts": "43e00a5447efc103de4a3a07eb57eee41c265aa0d58a055ed90bd0d4630ad58d", - "src/sql/core.ts": "bdb9acf1eebd8fa103068e1d06c7e6e232849ecaff4714bb51df9525d9a80a62", - "src/sql/expo-sqlite.ts": "dfacc52e79dcd13cf61b0f50dffe887422781487e67cd57e65eb0d10c84a150d", - "src/sql/index.ts": "351d2eeea00f904926390f9c066fc68bbcf09987d8f7dbff5107a8a3586f52b7", - "src/sql/log-rendering.ts": "15aaa620adf13c4eef06aa43915c85fd9832e0b3715ea00dda307dfa8b64343d", - "src/sql/mysql.ts": "78132e0b172704d046f953f6350a9b9fccbae4336846c171d330db1f56edd054", - "src/sql/postgres.ts": "5e3c87839ba9e21a6ec1c924ec06a5dc14261d8ba94dcb684bcfbfee04a0591b", - "src/sql/sqlite.ts": "f5a9434e396f5aabdc6569eb399f773b25f86a913340be7da74ff1e877172831", - "src/telemetry/opentelemetry.ts": "330db640ea3da7d8a5894bed0981385b2df52acebbfe535e9bb176b9cb66c7ec", - "src/tfp/client.ts": "db1392951089179191b8ff10d72e047469ce8eb55ff27691fb6aee5eafde4101", - "package.json": "513cdc8c3fde7fa043e96562b75f15095e6fa68de88bb86f26ccd12cdebe65f7", - "package-lock.json": "effe883993399138ebe86c98ccd43fd18cbbee74b464f9bb458b004f218b31c9", - "tsconfig.json": "e2181002b045e53934f18d4f371236e39b143226f1dea9a671d62a7f42218276", - "LICENSE": "c95bae1d1ce0235ecccd3560b772ec1efb97f348a79f0fbe0a634f0c2ccefe2c" - }, - "build": { - "command": "npm ci && npm run build && npm run smoke", - "workingDirectory": "source/browser-sqlite" + "commit": "e87b5d843a1bc2ae5f677f402b6b3177a7d40b50", + "branch": "main", + "runtimeVersion": "0.3.1", + "sourceDirectory": "source/teaql-ts", + "applicationDirectory": "source/teaql-ts/examples/browser-sqlite", + "buildDirectory": "dist", + "validation": { + "runtimeSuitesPassed": 56, + "runtimeTestsPassed": 604, + "runtimeTestsSkipped": 6, + "browserSmoke": "passed", + "generatedOrderSmoke": "passed" }, "limitations": [ - "No npm/public runtime release implied", "No application backend", "OPFS requires host cross-origin isolation" ] diff --git a/source/runtime/src/core/facet.ts b/source/runtime/src/core/facet.ts deleted file mode 100644 index 8b6c3457332632a2643c64077ec7be63978149da..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/facet.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { FacetRequest, SelectQuery } from './ast'; -import { SmartList, SmartListRecord } from './smart-list'; -import { QueryRequest } from './request-intent'; -import { retainQueryDiagnosticOrigin } from './query-snapshot'; - -export interface FacetQueryService { - executeQuery(query: SelectQuery): Promise; - executeFacetMembership?( - outerQuery: SelectQuery, relationName: string, countAliases?: readonly string[], - ): Promise>; -} - -function snakeCase(value: string): string { - return value.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase(); -} - -function scalarId(value: unknown): unknown { - if (value && typeof value === 'object') { - const record = value as Record; - return record.id ?? record.Id; - } - return value; -} - -function relationId(row: SmartListRecord, relationName: string): unknown { - const snake = snakeCase(relationName); - for (const key of [relationName, `${relationName}Id`, snake, `${snake}_id`]) { - const value = scalarId(row[key]); - if (value !== undefined && value !== null) return value; - } - return undefined; -} - -/** - * Execute relation facets without crossing entity boundaries with the outer - * filter. The outer query determines relation membership; the nested query - * determines which facet entities and fields are returned. - */ -export async function executeRelationFacets( - service: FacetQueryService, - prepareQuery: (query: SelectQuery) => SelectQuery, - outerQuery: SelectQuery, - facets: readonly FacetRequest[], -): Promise>> { - const request = new QueryRequest(outerQuery); - outerQuery = request.query; - const result: Record> = {}; - for (const facet of facets) { - const operation = request.deriveOperation(outerQuery, facet.operation ?? { - kind: 'facet', relation: facet.relationName, alias: facet.facetName, - }); - const countAliases = facet.query.aggregateItems - .filter(item => String(item.function).toLowerCase() === 'count') - .map(item => String(item.alias)); - let counts: Map; - if (service.executeFacetMembership) { - counts = await service.executeFacetMembership( - operation.deriveHelper(prepareQuery(outerQuery.clone()), 'aggregate ' + facet.relationName).query, - facet.relationName, countAliases); - } else { - const membershipQuery = outerQuery.clone(); - retainQueryDiagnosticOrigin(outerQuery, membershipQuery); - membershipQuery.facets = []; - membershipQuery.relations = []; - membershipQuery.relationAggregates = []; - membershipQuery.orderItems = []; - membershipQuery.aggregateItems = []; - membershipQuery.groupByItems = []; - membershipQuery.offsetValue = 0; - membershipQuery.limitValue = 0; - membershipQuery.selectItems = [facet.relationName]; - const memberships = await service.executeQuery(operation.deriveHelper( - prepareQuery(membershipQuery), 'aggregate ' + facet.relationName).query); - counts = new Map(); - for (const row of memberships) { - const id = relationId(row, facet.relationName); - if (id === undefined || id === null) continue; - const key = String(id); - counts.set(key, (counts.get(key) ?? 0) + 1); - } - } - - const nestedRequest = operation.deriveChild(facet.query.clone(), facet.relationName); - const nestedQuery = nestedRequest.query; - const nestedFacets = nestedQuery.facets; - nestedQuery.facets = []; - nestedQuery.aggregateItems = []; - nestedQuery.groupByItems = []; - for (const aggregate of nestedQuery.relationAggregates) { - if (aggregate.query.entity !== outerQuery.entity) continue; - // Reverse facet sums share the complete source membership, not the - // returned page or all source rows pointing at the same facet value. - const membership = outerQuery.clone(); - membership.selectItems = ['id']; - membership.properties = []; - membership.relations = []; - membership.relationAggregates = []; - membership.facets = []; - membership.aggregateItems = []; - membership.groupByItems = []; - membership.orderItems = []; - membership.offsetValue = 0; - membership.limitValue = 0; - const filter = { id: { $inSubquery: { query: membership, field: 'id' } } }; - aggregate.query.filterCondition = aggregate.query.filterCondition - ? { $and: [aggregate.query.filterCondition, filter] } : filter; - retainQueryDiagnosticOrigin(outerQuery, aggregate.query); - } - // Restrict before pagination and before evaluating child facets. Filtering - // only the returned rows makes child counts include unrelated entities. - if (!facet.includeAllFacets) { - const membership = { id: { $in: [...counts.keys()] } }; - nestedQuery.filterCondition = nestedQuery.filterCondition - ? { $and: [nestedQuery.filterCondition, membership] } : membership; - } - retainQueryDiagnosticOrigin(outerQuery, nestedQuery); - const rows = await service.executeQuery(nestedRequest.withQuery(prepareQuery(nestedQuery)).query); - const decorated = rows - .map(row => { - const count = counts.get(String(scalarId(row.id ?? row.Id))) ?? 0; - const copy = { ...row }; - for (const alias of countAliases) copy[alias] = count; - return copy; - }) - .filter(row => facet.includeAllFacets || counts.has(String(scalarId(row.id ?? row.Id)))); - const list = new SmartList(decorated); - if (nestedFacets.length) { - list.facets = await executeRelationFacets(service, prepareQuery, - nestedRequest.withQuery(nestedQuery).query, nestedFacets); - } - result[facet.facetName] = list; - } - return result; -} diff --git a/source/runtime/src/core/loaded-scalar-snapshot.ts b/source/runtime/src/core/loaded-scalar-snapshot.ts deleted file mode 100644 index b11c84665f5ee0a6b0e597555cec19cf206665b4..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/loaded-scalar-snapshot.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { snapshotQuery } from './query-snapshot'; - -/** @internal Loaded scalar provenance. No relations, ownership, SQL or Context. */ -export class LoadedScalarSnapshot { - readonly #values: Readonly>; - - constructor(values: Record = {}) { - this.#values = snapshotQuery(values); - Object.freeze(this); - } - - /** Copies prevent callers or mutable JSON/date fields from rewriting history. */ - values(): Readonly> { return snapshotQuery(this.#values); } -} diff --git a/source/teaql-ts/.npmignore b/source/teaql-ts/.npmignore new file mode 100644 index 0000000000000000000000000000000000000000..8285f56f633ccc0403d0a88d1c6fad42f194f6ef --- /dev/null +++ b/source/teaql-ts/.npmignore @@ -0,0 +1 @@ +dist/.sql-root-owned-backup-*/ diff --git a/source/teaql-ts/LICENSE b/source/teaql-ts/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..57bc88a15a0ee8266c259b2667e64608d3f7e292 --- /dev/null +++ b/source/teaql-ts/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/source/teaql-ts/README.md b/source/teaql-ts/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f5ce049d8bf705f7ea9a42699b3faa05b152d47d --- /dev/null +++ b/source/teaql-ts/README.md @@ -0,0 +1,369 @@ +# TeaQL TypeScript + +An AI-native library and runtime for building reviewable business applications in TypeScript. + +TeaQL gives coding agents business-shaped APIs, model-aware guidance and +software checks. People review the business operation instead of reconstructing +pages of query-building, relationship-loading and persistence code. + +Automatic execution logs make those operations easier to debug and operate, +without adding logging statements to every business method. + +[Try with your coding agent](#try-it-with-your-coding-agent) · +[Run the local example](#run-the-local-example) · +[See automatic logs](#automatic-logs-without-handwritten-logging-code) + +## Why this is an AI native library + +AI-native does not mean the library was written by AI, or that every query +calls an LLM. It means the APIs, knowledge delivery and verification workflow +are designed for how coding agents work: limited context, incomplete knowledge +of a project and a tendency to guess unfamiliar operations. + +The semantic model describes your business objects, fields, relationships and +states. A generated domain library turns those words into language-native +**Q** queries, **E** expressions and mutation methods. This repository provides +the reusable, domain-independent **runtime** that executes them through +metadata, Context, Checker, Policy and database providers. + +The application workspace keeps business code and concise project guidance +together. Progressive **Assist** supplies the exact API guidance needed for +the next operation, instead of asking the agent to explore the entire generated +library. Compilation, runtime checks and tests provide feedback beyond a prompt. + +## Less code for a reviewer to reconstruct + +The benefit is visible in the application code: the query, data access path +and audited change stay together, while shared mechanics live in the library +and runtime. + +| Application code to review | Shared work handled by TeaQL | +| --- | --- | +| A composed Q request | SQL construction and selected relation loading | +| An E access path | Loaded-field checks and explicit NULL handling | +| A mutation with an audit reason | Change tracking, Checker and configured Policy execution | +| Business intent and audit reason | Automatic execution logs and trace context without per-operation logging code | + +Reviewers still decide whether the requested data, business rules and +authorization policy are correct. They have less application plumbing to +trace before making that decision; reuse does not make business logic correct +automatically. + +**Token savings have not yet been measured in a controlled comparison.** +We make no numerical token-saving claim. Loading guidance only when needed +is a context-management strategy; the smaller application review surface is +visible in the examples, not a measured percentage reduction in review time. + +## See a business operation execute + +The [Robot Task Board showcase](https://teaql.io/blog/robot-task-board-showcase/) +makes the idea concrete: move a task and follow the state change, generated +SQL, field-level audit and refreshed board. + +![TeaQL Robot Task Board](https://teaql.io/img/003-task-board.png) + +Explore the [open-source demo](https://github.com/teaql/robot-task-board). +The showcase is a Rust application; the examples below use this repository's +own TypeScript APIs. + +## Q API composes business queries + +These application-code excerpts assume the example's generated imports, trusted +Context and an existing object identity. `Q` and `E` belong to the generated +domain library, not a generic runtime object with arbitrary field strings. +See the [application source](examples/school-management/app.ts) for complete setup. + +```typescript +const schoolTypeDetails = Q.schoolTypesWithMinimalFields().selectName().selectCode(); + +const school = await Q.schools() + .withIdIs(schoolId) + .selectPlatformWith(Q.platformsWithMinimalFields().selectName().selectBaseUrl()) + .selectSchoolTypeWith(schoolTypeDetails) + .comment("what: load the school and its reference data") + .purpose("why: review a school before editing") + .executeForOne(context); +if (!school) throw new Error("School not found"); +``` + +The child request is a query in its own right. Give it a business name, +extract it into a helper and compose it into other requests like a Lego brick. +The reviewer can see which relationships are loaded without following a +separate set of SQL loops. `comment` describes **what**; `purpose` describes +**why**. Both must be non-empty, even when logging is disabled. + +## E API protects business reads + +```typescript +const schoolTypeId = E.school(school).schoolTypeId().eval(); +``` + +E reads the loaded graph without implicitly querying the database. A loaded +NULL and a field that was **NotLoaded** are different facts. A business rule +must not conclude that a value is absent merely because the query never +requested it. + +The access path is explicit, so the reviewer checks whether Q loaded the +required data and whether the code handles a real NULL appropriately. +Unloaded access produces the language-specific diagnostic; a NULL fallback +is not permission to ignore an unloaded property. + +## Mutation API keeps changes behind one Save boundary + +The application declares the change and its reason instead of writing its own +persistence loop. A graph can stage additions, updates and deletions before Save. + +Load the complete scalar fields of every persisted object you actually modify. +A display-only partial projection is not a complete mutation input. Unmodified +reference objects do not have to become fully loaded just to save their parent. + +```typescript +school.updateName("Riverside Academy"); +await school.auditAs("Rename the reviewed school").save(context); +``` + +Save traverses the reached mutation graph, runs Checker/Fix and the configured +customer Mutation Policy, then uses the provider transaction boundary. +An explicit policy denial blocks persistence. Missing customer policy or exact +approval emits a warning; it is not automatic rejection. Marking for deletion +stages a change—the audited Save performs it. Atomicity is provider/route scoped, +not a distributed transaction across unrelated databases. + +## Automatic logs without handwritten logging code + +**Debuggability and operability are core design goals.** The Q and Save +examples above contain no logging calls: you declare the business intent, +and the runtime produces the execution diagnostics and trace context. +Configured audit sinks receive change events without each application +method having to construct its own field-level diff. + +The intent declarations already belong to the business operation: + +- `comment` describes what the query does. +- `purpose` explains why it runs. +- `auditAs` gives the reason for a saved change. + +No-code logging means no handwritten logger calls in each business method, +not an application without code or intent declarations. Runtime startup +still configures any required sink; custom formats and destinations use the +logging extension points rather than edits to every business operation. + +- **Debugging:** connect a query's intent to generated SQL, execution outcome + and the trace path when a screen or business operation behaves unexpectedly. +- **Operations:** follow query and mutation activity and use audit reasons + and safely exposed changes to investigate incidents. +- **Review:** inspect the business operation without separately checking + that every TeaQL execution path has a matching application logging statement. + +Query and Mutation diagnostic logs are enabled by default and can be switched +off independently. Logging off does not disable intent validation or Policy. + +Illustrative, shortened view of the rename operation, not a literal logger +format or a captured test result; the SQL excerpt omits additional selected fields: + +```text +query entity=School comment="load the reviewed object" purpose="edit form" outcome=success +SQL: SELECT id, version, name FROM school_data WHERE id = 42; +trace: School -> request -> sqlite -> select +mutation entity=School auditReason="Rename the reviewed school" outcome=committed +change: name "Riverside Primary School" -> "Riverside Academy" +lineage: School#42("Rename the reviewed school") +``` + +The declarations explain **why**; SQL and audit evidence show **what happened**. +Together they help locate the relevant operation without reconstructing the +entire call path from scattered application code. + +SQL execution stays parameterized. Diagnostic SQL has parameters substituted +after field-aware masking; it is not a question-mark template you must manually +reconstruct. Ordinary bindings stay visible, sensitive bindings use the shared +mask algorithm, and credentials/unknown bindings stay hidden. A masked statement +is labeled `MASKED; NOT REPLAYABLE`; SQL that cannot be safely rendered is omitted. +Application mutation audits are delivered after commit and discarded on rollback. +This is not a durable audit outbox. Do not put secrets in comment or purpose. + +### Standard Node telemetry + +The local source candidate provides optional environment-driven telemetry for +Node applications. It is separate from default-on SQL logging and committed +business audit. No SDK setup or logging calls are needed in each business method. + +```bash +export TEAQL_TELEMETRY_ENABLED=true +export TEAQL_TELEMETRY_SERVICE_NAME=payment-service +export TEAQL_TELEMETRY_OTLP_ENDPOINT=http://localhost:4318 +``` + +Without enablement, startup reports support and these three settings without +loading the SDK or creating export resources. Enabled startup reports full +recording and masked SQL. The module owns its providers and HTTP agents; it +does not replace customer globals. Telemetry uses official SDK protobuf +serialization and bounded acknowledgements. Remote error text is never logged; +fixed diagnostics and loss/rejection counters explain export problems without +changing business outcomes. Partial acceptance never resends the entire batch, +following the [OTLP response contract](https://opentelemetry.io/docs/specs/otlp/#partial-success). + +Install the optional SDK cohort listed in this checkout's `package.json`, +including its pinned `@opentelemetry/otlp-transformer`, when using the standard +Node entry. Browser SQLite does not enable this Node-only module. Run +`bash scripts/verify-standard-telemetry.sh` for local startup and graph checks; +`bash scripts/verify-examples.sh` also verifies rollback, retry, selective update +and deletion. This is an unreleased source capability, not a published-package +installation claim. Local production-capacity tests qualify queue saturation, +recovery and backlogged shutdown. Span/log admission includes queued and exporting +records; fixed counters distinguish overflow, failed export, queued retirement +and late handoff. Flush waits for the records accepted before that call. Shutdown +has a six-second budget and closes only module-owned resources; closing telemetry +does not disable database operations or committed audit. Advanced graph/stream +and private artifact installation remain separate acceptance gates. + +## Discover only the API needed next + +A coding agent does not need every generated method in its context. Start with +the generated application's `AGENTS.md` and workspace guidance, request an +entity/action Assist, then ask for field-specific help only for the field +being used. + +For a model in `models/`, the TypeScript query path is: + +```bash +cargo teaql typescript-assist-query/school --input models/ +cargo teaql typescript-assist-query/school.established_date --input models/ +``` + +These commands call the model-aware service; the model must match the generated +library. Assist uses canonical KSML entity and field names, even when the +language-native API uses a different naming style. Cargo TeaQL is a service +client for multiple languages, not just Rust. + +Use Assist to discover operations instead of reading generated library source +or guessing names. If the required operation is missing, report +`MISSING_ASSIST` rather than inventing an API. The +[Agent Kit](https://github.com/teaql/teaql-agent-kit) defines this progressive +workflow. Library and runtime maintenance are separate from application coding. + +## Software checks complement agent instructions + +AI proposes the model and application logic; software checks the parts that +can be verified mechanically. The library is one part of the TeaQL harness, +not a replacement for business review. + +| Stage | TeaQL support | Feedback to inspect | +| --- | --- | --- | +| Model and repair | Semantic model evaluation | Errors, warnings and repair guidance | +| Generate | Domain library combined with this runtime | Language tooling checks the generated API contract | +| Customize the workspace | Progressive Assist, Q, E and mutation APIs | Build diagnostics, Checker and configured Policy results | +| Verify and operate | Tests, runtime startup, intent and audit evidence | Actual outcomes, remaining failures and execution paths | + +Build checks verify API use, not whether the business decision is right. +Tests must still verify the application's behavior. A prompt, successful +generation or a clean build alone does not prove the finished application correct. + +## Try it with your coding agent + +You can start with an agent you already use. Paste this prompt: + +```text +Follow the current instructions at https://github.com/teaql/teaql-agent-kit. +Build a small school-management application in TypeScript using SQLite. +Evaluate and repair the model, generate the domain library and prepare a runnable +application workspace. Verify Q, E, Checker and audited Save. +Finish with a report of commands, results and +remaining frictions. Include Q/E examples and relevant intent/audit logs. +Do not claim token savings without a measured comparison. +``` + +The [Agent Kit](https://github.com/teaql/teaql-agent-kit) guides modeling, +evaluation/repair, generation and application customization. It may install +toolchains and download dependencies; review installation permissions and the +final execution report. It is a workflow, not a guarantee of unattended correctness. + +## Run the local example + +Node.js/npm for the repository examples. Browser SQLite runs in a Web Worker with SQLite/WASM. From a checkout of this repository: + +```bash +cd examples/school-management +npm install +npx ts-node app.ts +``` + +The [School example](examples/school-management/README.md) +exercises SQLite schema/bootstrap and generated application APIs against this +repository's local runtime. No external database server or generator is needed +to run the retained generated example. Use only the example's test database; +reset/repeated-run behavior is documented in its README. + +## Use the published runtime + +Current documented runtime: **0.3.0**. Keep domain-library and runtime +versions compatible; regenerate older libraries when their provider or graph +adapter SPI has changed. + +```bash +npm install @teaql/teaql@0.3.0 +``` + +Use scoped imports such as `@teaql/teaql` or +`@teaql/teaql/sql/sqlite`. The default entry point is driver-free; choose only +the required profile and install its optional driver. Browser SQLite defaults +to memory; OPFS is an explicit persistence choice. + +Generation is a separate service; see the [Agent Kit](https://github.com/teaql/teaql-agent-kit) +for producing the application-specific library and workspace. Repository examples +use local source; isolated released-package regression is a separate gate. + +## Supported scope + +TypeScript supports browser/TFP, Node SQL, Expo SQLite and browser SQLite/WASM profiles. The browser is not a trusted server authorization boundary or a backend key store. Peggy parses a controlled query AST; it does not execute arbitrary JavaScript with eval or new Function. + +One semantic model can produce language-native applications across +[Java](https://github.com/teaql/teaql-java), +[Rust](https://github.com/teaql/teaql-rs), +[TypeScript](https://github.com/teaql/teaql-ts), +[Go](https://github.com/teaql/teaql-golang), +[Swift](https://github.com/teaql/teaql-swift), +[.NET](https://github.com/teaql/teaql-dotnet) and +[Python](https://github.com/teaql/teaql-python). +That does not imply identical APIs, providers or complete cross-language feature parity. +The semantic model defines business objects, fields, relationships and states; +it is not the language model used by a coding agent. +The [conformance matrices](https://github.com/teaql/teaql-conformance) +distinguish implemented source, executed examples, artifact verification and release. + +## Verification and customization + +```bash +npm test -- --runInBand +bash scripts/verify-examples.sh +``` + +The full example gate is the acceptance entry point for local runtime changes. +External-provider tests need their configured services; skips are not live-provider +evidence. A committed-operation error after audit delivery failure must not be +retried as if the business transaction rolled back. + +Install application-owned policies, ID/business-ID services, logging sinks, +transports and other supported SPIs through trusted runtime/Context setup. +Request JSON is not allowed to replace those trusted capabilities. + +- [Runtime guide: modules, SPI and advanced verification](RUNTIME_GUIDE.md) +- [Runtime profiles](RUNTIME_GUIDE.md#runtime-profiles) +- [Browser SQLite example](examples/browser-sqlite/README.md) +- [Facet example](examples/facet-trace/README.md) +- [Trace Chain example](examples/trace-chain/README.md) + +## Safe troubleshooting + +Default diagnostics do not authorize plaintext sensitive data. Controlled +debugging requires the exact acknowledgement below and any sensitive sink +required by the runtime: + +```bash +export TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS=I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK +``` + +Debug output is explicitly labeled. Credentials and unknown bindings remain +protected; the flag does not erase old files or govern application/driver +prints outside TeaQL. Restrict access and retention, then unset it and restart. +See the [runtime guide](RUNTIME_GUIDE.md) for log switches and extension details. diff --git a/source/teaql-ts/examples/browser-sqlite/AGENTS.md b/source/teaql-ts/examples/browser-sqlite/AGENTS.md new file mode 100644 index 0000000000000000000000000000000000000000..b7291306711ab955bd16c1276628b0b102e41956 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/AGENTS.md @@ -0,0 +1,10 @@ +# Browser SQLite example + +- Keep the existing WorkItem page and the generated Order page independently usable. +- Application-owned code lives in `src/`, HTML, and `scripts/`. Never hand-edit `orders-lib/`. +- Use `assist/query-*.md`, the required field help, and create/expression/debug Assist for API discovery. Do not inspect generated library source or guess method names. +- Order queries must remain bounded and carry non-empty comment/purpose; seeding uses generated audited mutation APIs with the trusted context. +- Search input is validated JSON. Never execute it with `eval` or `new Function`. +- Read actual statement `traceChain` and `tracePath`; UI rendering must not manufacture lineage from SQL, routes or known aliases. +- Dependencies resolve this repository's runtime, not a published package. +- Run `npm run build`, `npm run smoke`, and `npm run smoke:orders`. The latter checks generated-library hashes; the repository example gate runs both smoke tests. diff --git a/source/teaql-ts/examples/browser-sqlite/README.md b/source/teaql-ts/examples/browser-sqlite/README.md new file mode 100644 index 0000000000000000000000000000000000000000..41ae6eb627c02b5e2ce2be329a32c2b359aeff75 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/README.md @@ -0,0 +1,118 @@ +# Browser SQLite/WASM order playground + +This executable example uses a familiar commerce domain—platform, customer, +order, item, payment, and shipment—to demonstrate TeaQL queries entirely in a +dedicated browser worker. It includes deterministic, internally consistent demo +data and thirteen runnable examples organized as basic, aggregate, filtered, +and dynamic queries. + +`OrderStatus` is a seventh, constant model object rather than a string field. +Its five fixed values are reconciled through `RuntimeModule` bootstrap, orders +store the status object ID, and generated Q expressions select, filter, and +facet through the `status` relation. Visible status projections select `name` +and `color`—not `code`—and the queried color drives the metric cards and status +badges. Embedded relation Q expressions are displayed on one line so they align +with the horizontal element they populate. + +The interface defaults to English and can be switched to Chinese without +re-running the active query. Tabular results use a table by default and remain +available as an expandable Result Tree instead of a raw JSON text block. +Dynamic examples pass user-shaped filters through TeaQL's validated field +metadata and do not use `eval`. + +The first example is a complete order management center. Its status metrics, +search (including product-name subqueries), item previews, and pagination are +all driven by one generated `Q.customerOrders()` expression. Application code +uses the generated domain request API; the lower-level `SelectQuery` is confined +to `src/generated`. Every example shows the exact Q expression used by the page +and the parameterized SQL statements that SQLite executed, including timing, +row counts, and policy-safe bindings. The execution evidence table prints the +captured time, identity, intent, `tracePath`, and parameterized SQL on one row +per statement. Each trace is plain text with arrows between its original path +steps; no JSON metadata or decorative visualization is added, and no +application tracing code is required. + +The order-center Q expression is stable across free-text search, status-card +selection, and pagination. Those interactions only replace `searchParams`, +`pageOffset`, and `pageSize`; generated dynamic-search bindings compile order +number, `OrderStatus.code`, and item product-name paths without changing the +page query. + +The order-center projection intentionally contains only the four visible table +columns: order number, order date, the `OrderStatus` object, and item preview. +It does not load Platform or Customer. The Q chain follows the page vertically: +dynamic filter, `countAs('totalOrders')`, status facet, four table projections, then page +execution. + +```bash +npm install +npm run dev +``` + +Memory storage is the deterministic default. Refreshing recreates the data. The +optional OPFS mode persists within the current browser origin. Reset drops the +browser-local schema, explicitly runs `context.ensureSchema()` again, and +re-seeds the six mutable entities through governed, audited mutations; the five +`OrderStatus` constants are restored by runtime bootstrap. + +The same application-approved mutation policy is used by both storage profiles. +A denied plan is rejected before SQL is posted to the worker. + +The previous WorkItem example remains independently available at +`/work-items.html`. The Vite development server emits the COOP/COEP headers required by the SQLite +OPFS implementation. A production host must emit the same headers. This first +profile intentionally excludes multi-tab database coordination and true row +streaming. + +## Generated order TraceChain page + +Open `/orders.html` to run the shared request-tree Order model in the same +browser SQLite/WASM provider. The WorkItem page remains available at +`/work-items.html`, while `/` presents the full order management center. +`order-model.xml` defines the model; `orders-lib/` is generated by the local +Model-Aware Services producer, not handwritten Q or entity code. Model-aware +Assist outputs are retained under `assist/`. + +The order page uses generated audited mutation APIs to create four orders and +five items per order. Generated bootstrap provisions the platform and three +status constants. The example search matches three orders and loads the second +one: KEEP-002, Paid, three item previews, and a full item count of five. Status +facets retain counts and sums `(1,100)`, `(2,500)`, `(0,null)`. + +The textarea accepts runtime-validated search JSON, not executable JavaScript. +The actual query is compiled application code using the generated Q API. The +view reads selected fields through generated E expressions and displays data, +page metadata and facets. Business TraceChain rendering uses only each actual +statement's `traceChain`; `tracePath` is displayed separately. No SQL parsing, +known-alias branches or UI-owned lineage is used. + +Diagnostic logging is on by default. Disabling it suppresses the diagnostic +sink, while the explicitly installed evidence store still supplies the eight +actual statements for the view. Memory refresh resets the data; OPFS survives +refresh. Reset re-runs context-owned schema/bootstrap and generated mutations. + +```bash +npm run build +npm run smoke +npm run smoke:orders +``` + +The order smoke test runs real Chromium against the built deployment and +checks memory/OPFS refresh/reset, both diagnostic modes, Q/E results, exact +facet values, native operation comments, actual SQL count and unchanged +generated-library hashes. The repository's `scripts/verify-examples.sh` runs +both browser smoke tests. + +For maintainers with the generator checkout, regenerate the library and Assist: + +```bash +cd /path/to/teaql-code-gen +TEAQL_TEST_TYPESCRIPT_RUNTIME_PATH=/path/to/teaql-ts \ + mvn -q -pl generator -am \ + -Dtest=PolyglotRequestTreeSqliteTest#sharedOrderFixtureExportsBrowserLibraryAndAssist \ + -Dsurefire.failIfNoSpecifiedTests=false test +``` + +The generated library's local dependency points to this runtime repository. +Do not manually repair `orders-lib/`; change the model or upstream templates +and regenerate instead. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/create-customer.md b/source/teaql-ts/examples/browser-sqlite/assist/create-customer.md new file mode 100644 index 0000000000000000000000000000000000000000..699c893bc74bbd83e1c52695e895457b66b3a681 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/create-customer.md @@ -0,0 +1,82 @@ + + +# TypeScript Assist — Create `Customer` + +Use the exact generated `Q.customers()` entry point. The +trusted `UserContext` supplies actor, tenant, policy, provider, and audit sink; +none of those values may be accepted from the writable input. + +```typescript +import { UserContext } from '../teaql-ts'; +import { Q } from './Q'; +import { Customer } from './models/Customer'; + +export interface CreateCustomerInput { + platform: string | number; + name: string; + +} + +export async function createCustomer( + input: CreateCustomerInput, + context: UserContext, +): Promise { + const entity = Q.customers() + .comment('what: initialize Customer') + .purpose('why: create Customer') + .newEntity(context); + + entity.updatePlatform(input.platform); + entity.updateName(input.name); + + await entity + .auditAs('Create Customer for the requested business operation') + .save(context); + return entity; +} +``` + +Only the generated updater methods above are writable. Constant relation +candidates, when present, are also generated and must be copied exactly: + +Compile the result unchanged. Test persistence and query-back, and prove that +blank/missing intent, blank/missing audit reason, unknown fields, and attempted +trusted-context overrides fail. Do not edit generated sources. + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `create`. + +- Validate and allow-list writable business fields; never mass-assign dynamic JSON. +- Create through the generated request/entity API, attach a non-empty audit reason, + save with the same UserContext, and return the runtime's native save result. +- Add a negative test proving a missing audit reason cannot write. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/create-customer_order.md b/source/teaql-ts/examples/browser-sqlite/assist/create-customer_order.md new file mode 100644 index 0000000000000000000000000000000000000000..25e4ad7c6e890752a03135d6e3a69318075ba741 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/create-customer_order.md @@ -0,0 +1,92 @@ + + +# TypeScript Assist — Create `Customer Order` + +Use the exact generated `Q.customerOrders()` entry point. The +trusted `UserContext` supplies actor, tenant, policy, provider, and audit sink; +none of those values may be accepted from the writable input. + +```typescript +import { UserContext } from '../teaql-ts'; +import { Q } from './Q'; +import { CustomerOrder } from './models/CustomerOrder'; + +export interface CreateCustomerOrderInput { + customer: string | number; + status: string | number; + orderNumber: string; + orderDate: string; + totalAmount: number; + +} + +export async function createCustomerOrder( + input: CreateCustomerOrderInput, + context: UserContext, +): Promise { + const entity = Q.customerOrders() + .comment('what: initialize Customer Order') + .purpose('why: create Customer Order') + .newEntity(context); + + entity.updateCustomer(input.customer); + entity.updateStatus(input.status); + entity.updateOrderNumber(input.orderNumber); + entity.updateOrderDate(input.orderDate); + entity.updateTotalAmount(input.totalAmount); + + await entity + .auditAs('Create Customer Order for the requested business operation') + .save(context); + return entity; +} +``` + +Only the generated updater methods above are writable. Constant relation +candidates, when present, are also generated and must be copied exactly: +- `updateStatusToNew()` +- `updateStatusToPaid()` +- `updateStatusToCancelled()` + + +Compile the result unchanged. Test persistence and query-back, and prove that +blank/missing intent, blank/missing audit reason, unknown fields, and attempted +trusted-context overrides fail. Do not edit generated sources. + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `create`. + +- Validate and allow-list writable business fields; never mass-assign dynamic JSON. +- Create through the generated request/entity API, attach a non-empty audit reason, + save with the same UserContext, and return the runtime's native save result. +- Add a negative test proving a missing audit reason cannot write. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/create-order_item.md b/source/teaql-ts/examples/browser-sqlite/assist/create-order_item.md new file mode 100644 index 0000000000000000000000000000000000000000..570fa467c3825d766262eceeaee127024d23cd1b --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/create-order_item.md @@ -0,0 +1,86 @@ + + +# TypeScript Assist — Create `Order Item` + +Use the exact generated `Q.orderItems()` entry point. The +trusted `UserContext` supplies actor, tenant, policy, provider, and audit sink; +none of those values may be accepted from the writable input. + +```typescript +import { UserContext } from '../teaql-ts'; +import { Q } from './Q'; +import { OrderItem } from './models/OrderItem'; + +export interface CreateOrderItemInput { + customerOrder: string | number; + productName: string; + quantity: number; + unitPrice: number; + +} + +export async function createOrderItem( + input: CreateOrderItemInput, + context: UserContext, +): Promise { + const entity = Q.orderItems() + .comment('what: initialize Order Item') + .purpose('why: create Order Item') + .newEntity(context); + + entity.updateCustomerOrder(input.customerOrder); + entity.updateProductName(input.productName); + entity.updateQuantity(input.quantity); + entity.updateUnitPrice(input.unitPrice); + + await entity + .auditAs('Create Order Item for the requested business operation') + .save(context); + return entity; +} +``` + +Only the generated updater methods above are writable. Constant relation +candidates, when present, are also generated and must be copied exactly: + +Compile the result unchanged. Test persistence and query-back, and prove that +blank/missing intent, blank/missing audit reason, unknown fields, and attempted +trusted-context overrides fail. Do not edit generated sources. + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `create`. + +- Validate and allow-list writable business fields; never mass-assign dynamic JSON. +- Create through the generated request/entity API, attach a non-empty audit reason, + save with the same UserContext, and return the runtime's native save result. +- Add a negative test proving a missing audit reason cannot write. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/debug.md b/source/teaql-ts/examples/browser-sqlite/assist/debug.md new file mode 100644 index 0000000000000000000000000000000000000000..e03a34676b91d66208245b58588269099e3abea0 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/debug.md @@ -0,0 +1,101 @@ + + +# TeaQL safe SQL execution evidence (TypeScript) + +Attach a trusted evidence store to the server-created SQL client and project +only bounded fields before returning diagnostics to an application or Coding +Agent. + +```typescript +import type { SQLExecutionMetadata, SQLExecutionOperation } from 'teaql-ts/sql/core'; + +export type SafeSQLExecutionEvidence = Readonly<{ + operation: SQLExecutionOperation; + parameterizedSQL: string; + parameterCount: number; + elapsedMicros: number; + resultCount?: number; + affectedRows?: number; + resultSummary: string; + traceChain?: SQLExecutionMetadata['traceChain']; + tracePath: SQLExecutionMetadata['tracePath']; +}>; + +export function safeSQLEvidence( + entries: readonly SQLExecutionMetadata[], +): readonly SafeSQLExecutionEvidence[] { + return entries.map(entry => Object.freeze({ + operation: entry.operation, + parameterizedSQL: entry.parameterizedSQL, + parameterCount: entry.parameters.length, + elapsedMicros: entry.elapsedMicros, + resultCount: entry.resultCount, + affectedRows: entry.affectedRows, + resultSummary: entry.resultSummary, + traceChain: entry.traceChain, + tracePath: entry.tracePath, + })); +} +``` + +Create `SQLExecutionEvidenceStore`, attach it with +`client.setRuntimeTelemetrySink(store)`, and select `enableAll`, `enableSelect`, +`enableMutation`, or `disable`. Mode changes clear earlier entries. Raw +parameters, credentials, connection strings, and interpolated SQL remain inside +the trusted boundary and are intentionally absent above. + +Query and mutation logs, including the text diagnostic sink, are enabled by default. +The default sink is `new TextDiagnosticSQLLogSink()` and may be +replaced with `client.setDiagnosticSQLLogSink(...)`. Disable the two operation +families independently with +`client.setQueryLoggingEnabled(false)` and +`client.setMutationLoggingEnabled(false)`; passing `undefined` to +`setDiagnosticSQLLogSink` removes operator output entirely. Each metadata entry +retains structured `comment`, `purpose`, `auditReason`, typed multi-level +`tracePath`, business `traceChain`, parameterized SQL, copy-paste `debugSQL`, elapsed +time, result count, and affected rows. `traceChain` follows the root purpose and +request-parent comments, preserving both the native Q operation and a nested +explicit/default comment. `tracePath` describes the physical provider/SQL route; +do not derive one from the other or reconstruct either from SQL text. Runtime +evidence is policy-projected by default; keep that projection when exposing it. +Explicit debug plaintext is not ordinary telemetry and must not leave the trusted +debugging boundary. + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `debug`. + +- Capture purpose, comment, trace/correlation id, parameterized SQL summary, + duration, row count, provider, and the runtime's native response when available. +- Preserve the immutable row audit event and the customizable App Audit Sink as + separate paths. Redact credentials, tokens, connection strings, and customer data. +- Document only switches and hooks present in the selected runtime source. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/expression-customer_order.md b/source/teaql-ts/examples/browser-sqlite/assist/expression-customer_order.md new file mode 100644 index 0000000000000000000000000000000000000000..5a2afd7281378070a8a7de14157051d62726ea84 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/expression-customer_order.md @@ -0,0 +1,135 @@ + + +# TypeScript Assist — Expression `Customer Order` + +The generated E facade preserves Value, loaded null/undefined, and NotLoaded. +`eval()` returns a native value for the first two and throws +`TeaQLNotLoadedError` for the third. `orElse` is nullish-only and never hides +NotLoaded. + +```typescript +import { E } from './E'; +import { CustomerOrder } from './models/CustomerOrder'; + +export function extractId(entity: CustomerOrder) { + return E.customerOrder(entity).id().eval(); +} + +export function extractIdOrElse( + entity: CustomerOrder, fallback: NonNullable, +) { + return E.customerOrder(entity).id().orElse(fallback); +} + +export function extractOrderNumber(entity: CustomerOrder) { + return E.customerOrder(entity).orderNumber().eval(); +} + +export function extractOrderNumberOrElse( + entity: CustomerOrder, fallback: NonNullable, +) { + return E.customerOrder(entity).orderNumber().orElse(fallback); +} + +export function extractOrderDate(entity: CustomerOrder) { + return E.customerOrder(entity).orderDate().eval(); +} + +export function extractOrderDateOrElse( + entity: CustomerOrder, fallback: NonNullable, +) { + return E.customerOrder(entity).orderDate().orElse(fallback); +} + +export function extractTotalAmount(entity: CustomerOrder) { + return E.customerOrder(entity).totalAmount().eval(); +} + +export function extractTotalAmountOrElse( + entity: CustomerOrder, fallback: NonNullable, +) { + return E.customerOrder(entity).totalAmount().orElse(fallback); +} + +export function extractVersion(entity: CustomerOrder) { + return E.customerOrder(entity).version().eval(); +} + +export function extractVersionOrElse( + entity: CustomerOrder, fallback: NonNullable, +) { + return E.customerOrder(entity).version().orElse(fallback); +} + +export function extractCustomerId(entity: CustomerOrder) { + return E.customerOrder(entity).customerId().eval(); +} + +export function traverseCustomer(entity: CustomerOrder) { + return E.customerOrder(entity).customer().eval(); +} + +export function extractStatusId(entity: CustomerOrder) { + return E.customerOrder(entity).statusId().eval(); +} + +export function traverseStatus(entity: CustomerOrder) { + return E.customerOrder(entity).status().eval(); +} + +export function aggregateOrderItemListSize(entity: CustomerOrder) { + return E.customerOrder(entity).orderItemList().size().eval(); +} + +export function firstOrderItemListId(entity: CustomerOrder) { + return E.customerOrder(entity).orderItemList().first().id().eval(); +} + +export function getOrderItemListId(entity: CustomerOrder, index: number) { + return E.customerOrder(entity).orderItemList().get(index).id().eval(); +} + + +``` + +Select every traversed field and relation. Never catch +`TeaQLNotLoadedError` merely to supply a default, and never replace generated E +accessors with optional chaining. + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `expression`. + +- Distinguish a loaded null from a field or relation that was not projected. A + NotLoaded/coding error must remain visible; do not turn it into an ordinary null. +- Select every traversed relation first and use the generated E/expression API for + scalar, object, and list traversal. Do not translate Java accessor names by guess. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.md b/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.md new file mode 100644 index 0000000000000000000000000000000000000000..e8802eba2e3467b14ef6de45d83310bcdc95d7da --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.md @@ -0,0 +1,104 @@ + + +# TypeScript Assist — Query `Customer Order` + +Use the exact generated `Q.customerOrdersWithMinimalFields()` +entry point. Trusted runtime and policy state comes only from `UserContext`. + +```typescript +import { Q } from './Q'; +import { CustomerOrder } from './models/CustomerOrder'; +import { SmartList, UserContext } from '../teaql-ts'; + +export async function queryCustomerOrderById( + context: UserContext, + entityId: string, +): Promise> { + return Q.customerOrdersWithMinimalFields() + .withIdIs(entityId) + .orderByIdAscending() + .limit(20) + .comment('what: load the requested Customer Order row') + .purpose('why: serve the authorized Customer Order view') + .executeForList(context); +} +``` + +Compile and execute this source unchanged. Use only generated projection, +predicate, ordering, and relation-selection APIs. Missing or blank intent, +unknown fields, unbounded reads, and trusted-context inputs must fail. Use generated +relation loading rather than handwritten child-query loops; never guess a plural. + + +## Field-specific Query Assist + +Use the canonical KSML field name from this list. Do not substitute a language member name, JSON name, or database column. + +| KSML field | Type | Field help | +| --- | --- | --- | +| `id` | `id` | `typescript-assist-query/customer_order.id` | +| `customer` | `relation` | `typescript-assist-query/customer_order.customer` | +| `status` | `relation` | `typescript-assist-query/customer_order.status` | +| `order_number` | `string` | `typescript-assist-query/customer_order.order_number` | +| `order_date` | `date` | `typescript-assist-query/customer_order.order_date` | +| `total_amount` | `number` | `typescript-assist-query/customer_order.total_amount` | +| `version` | `version` | `typescript-assist-query/customer_order.version` | + +Generated reverse relations are derived from referencing KSML fields. Use their exact generated location for relation selection and access: + +| Generated reverse relation | Child entity | Field help | +| --- | --- | --- | +| `order_item_list` | `order_item` | `typescript-assist-query/customer_order.order_item_list` | + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `query`. + +- Use generated projection, relation, predicate, sort, and aggregate APIs; never + concatenate application SQL or silently ignore an unsupported filter. +- Rows, record count, facets, and aggregates must share the same active filter. +- Add negative tests for missing purpose/comment and forbidden dynamic fields. + +### Optional per-parent Top-N optimization + +- Configure `topNProbeParentThreshold(threshold)` on the nested child request before its intent/execution + stage. Use the field-specific relation Assist for the exact generated selector. +- Give the child a per-parent limit and deterministic ordering with an ID tie-breaker; + bound the parent query separately. A single-parent detail query is not batch Top-N. +- Server providers default to a window query (`threshold = 0`). A positive threshold + permits bounded probes only when the already-loaded parent count is at or below it; + above it, use the window plan. SQLite uses its internal AlwaysProbe policy by default. +- Measure before opting in. Do not infer a threshold from table size or execute COUNT + or statistics queries to choose a plan. Keep an index on foreign key + sort + ID. +- Inspect selected-plan, parent-count, per-parent-limit and probe-count telemetry. + Runtime-managed probes are not application-owned N+1 loops; neither strategy changes + authorization, loaded-state semantics or the required comment/purpose. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.order_item_list.md b/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.order_item_list.md new file mode 100644 index 0000000000000000000000000000000000000000..fb6d9cc9ca2da6b79a60e7540cd324b1ce0eeb0a --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.order_item_list.md @@ -0,0 +1,66 @@ + + +# Query Reverse-Relation Assist — `customer_order.order_item_list` + +KSML entity: `customer_order` +Derived reverse relation: `order_item_list` +Child entity: `order_item` + +| Capability | Generated API | +| --- | --- | +| Select | `.selectOrderItemListWith(Q.orderItemsWithMinimalFields())` | + +Reverse relations are model-derived and never perform an implicit database query. Select the relation explicitly before expression access. Apply query methods before the executable purpose stage, then execute with exactly one trusted context. + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `query`. + +- Use generated projection, relation, predicate, sort, and aggregate APIs; never + concatenate application SQL or silently ignore an unsupported filter. +- Rows, record count, facets, and aggregates must share the same active filter. +- Add negative tests for missing purpose/comment and forbidden dynamic fields. + +### Optional per-parent Top-N optimization + +- Configure `topNProbeParentThreshold(threshold)` on the nested child request before its intent/execution + stage. Use the field-specific relation Assist for the exact generated selector. +- Give the child a per-parent limit and deterministic ordering with an ID tie-breaker; + bound the parent query separately. A single-parent detail query is not batch Top-N. +- Server providers default to a window query (`threshold = 0`). A positive threshold + permits bounded probes only when the already-loaded parent count is at or below it; + above it, use the window plan. SQLite uses its internal AlwaysProbe policy by default. +- Measure before opting in. Do not infer a threshold from table size or execute COUNT + or statistics queries to choose a plan. Keep an index on foreign key + sort + ID. +- Inspect selected-plan, parent-count, per-parent-limit and probe-count telemetry. + Runtime-managed probes are not application-owned N+1 loops; neither strategy changes + authorization, loaded-state semantics or the required comment/purpose. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.status.md b/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.status.md new file mode 100644 index 0000000000000000000000000000000000000000..30c09ab3e3668a4c8fcdba07bd4dae8869a1ea9d --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/query-customer_order.status.md @@ -0,0 +1,72 @@ + + +# TypeScript Query Field Assist — `customer_order.status` + +KSML entity: `Customer Order` +KSML field: `Order Status` +Type: `Order Status` + +| Capability | Generated API | +| --- | --- | +| Select | `selectStatusWith(request)`` | +| Filter identity | `withStatusIs(id)`, `withStatusIn(ids)` | +| Filter nested request | `withStatusMatching(request)`, `withoutStatusMatching(request)` | +| Constant | `withStatusIs()` | +| Constant | `withStatusIs()` | +| Constant | `withStatusIs()` | +| Group | `groupByStatus()`, `groupByStatusAs(alias)` | +| Facet | `facetByStatusAs(name, request, includeAllFacets)` | +Execution requires `comment(...)`, `purpose(...)`, and exactly one `context`. + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `query`. + +- Use generated projection, relation, predicate, sort, and aggregate APIs; never + concatenate application SQL or silently ignore an unsupported filter. +- Rows, record count, facets, and aggregates must share the same active filter. +- Add negative tests for missing purpose/comment and forbidden dynamic fields. + +### Optional per-parent Top-N optimization + +- Configure `topNProbeParentThreshold(threshold)` on the nested child request before its intent/execution + stage. Use the field-specific relation Assist for the exact generated selector. +- Give the child a per-parent limit and deterministic ordering with an ID tie-breaker; + bound the parent query separately. A single-parent detail query is not batch Top-N. +- Server providers default to a window query (`threshold = 0`). A positive threshold + permits bounded probes only when the already-loaded parent count is at or below it; + above it, use the window plan. SQLite uses its internal AlwaysProbe policy by default. +- Measure before opting in. Do not infer a threshold from table size or execute COUNT + or statistics queries to choose a plan. Keep an index on foreign key + sort + ID. +- Inspect selected-plan, parent-count, per-parent-limit and probe-count telemetry. + Runtime-managed probes are not application-owned N+1 loops; neither strategy changes + authorization, loaded-state semantics or the required comment/purpose. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/query-order_item.md b/source/teaql-ts/examples/browser-sqlite/assist/query-order_item.md new file mode 100644 index 0000000000000000000000000000000000000000..7bfe7baf0ecbb99a4aa9b88f109742222b693b06 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/query-order_item.md @@ -0,0 +1,97 @@ + + +# TypeScript Assist — Query `Order Item` + +Use the exact generated `Q.orderItemsWithMinimalFields()` +entry point. Trusted runtime and policy state comes only from `UserContext`. + +```typescript +import { Q } from './Q'; +import { OrderItem } from './models/OrderItem'; +import { SmartList, UserContext } from '../teaql-ts'; + +export async function queryOrderItemById( + context: UserContext, + entityId: string, +): Promise> { + return Q.orderItemsWithMinimalFields() + .withIdIs(entityId) + .orderByIdAscending() + .limit(20) + .comment('what: load the requested Order Item row') + .purpose('why: serve the authorized Order Item view') + .executeForList(context); +} +``` + +Compile and execute this source unchanged. Use only generated projection, +predicate, ordering, and relation-selection APIs. Missing or blank intent, +unknown fields, unbounded reads, and trusted-context inputs must fail. Use generated +relation loading rather than handwritten child-query loops; never guess a plural. + + +## Field-specific Query Assist + +Use the canonical KSML field name from this list. Do not substitute a language member name, JSON name, or database column. + +| KSML field | Type | Field help | +| --- | --- | --- | +| `id` | `id` | `typescript-assist-query/order_item.id` | +| `customer_order` | `relation` | `typescript-assist-query/order_item.customer_order` | +| `product_name` | `string` | `typescript-assist-query/order_item.product_name` | +| `quantity` | `integer` | `typescript-assist-query/order_item.quantity` | +| `unit_price` | `number` | `typescript-assist-query/order_item.unit_price` | +| `version` | `version` | `typescript-assist-query/order_item.version` | + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `query`. + +- Use generated projection, relation, predicate, sort, and aggregate APIs; never + concatenate application SQL or silently ignore an unsupported filter. +- Rows, record count, facets, and aggregates must share the same active filter. +- Add negative tests for missing purpose/comment and forbidden dynamic fields. + +### Optional per-parent Top-N optimization + +- Configure `topNProbeParentThreshold(threshold)` on the nested child request before its intent/execution + stage. Use the field-specific relation Assist for the exact generated selector. +- Give the child a per-parent limit and deterministic ordering with an ID tie-breaker; + bound the parent query separately. A single-parent detail query is not batch Top-N. +- Server providers default to a window query (`threshold = 0`). A positive threshold + permits bounded probes only when the already-loaded parent count is at or below it; + above it, use the window plan. SQLite uses its internal AlwaysProbe policy by default. +- Measure before opting in. Do not infer a threshold from table size or execute COUNT + or statistics queries to choose a plan. Keep an index on foreign key + sort + ID. +- Inspect selected-plan, parent-count, per-parent-limit and probe-count telemetry. + Runtime-managed probes are not application-owned N+1 loops; neither strategy changes + authorization, loaded-state semantics or the required comment/purpose. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/query-order_status.customer_order_list.md b/source/teaql-ts/examples/browser-sqlite/assist/query-order_status.customer_order_list.md new file mode 100644 index 0000000000000000000000000000000000000000..d56ca5fb1c6b750eec6e9ea95d5ef4f1c0a71e4c --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/query-order_status.customer_order_list.md @@ -0,0 +1,66 @@ + + +# Query Reverse-Relation Assist — `order_status.customer_order_list` + +KSML entity: `order_status` +Derived reverse relation: `customer_order_list` +Child entity: `customer_order` + +| Capability | Generated API | +| --- | --- | +| Select | `.selectCustomerOrderListWith(Q.customerOrdersWithMinimalFields())` | + +Reverse relations are model-derived and never perform an implicit database query. Select the relation explicitly before expression access. Apply query methods before the executable purpose stage, then execute with exactly one trusted context. + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `query`. + +- Use generated projection, relation, predicate, sort, and aggregate APIs; never + concatenate application SQL or silently ignore an unsupported filter. +- Rows, record count, facets, and aggregates must share the same active filter. +- Add negative tests for missing purpose/comment and forbidden dynamic fields. + +### Optional per-parent Top-N optimization + +- Configure `topNProbeParentThreshold(threshold)` on the nested child request before its intent/execution + stage. Use the field-specific relation Assist for the exact generated selector. +- Give the child a per-parent limit and deterministic ordering with an ID tie-breaker; + bound the parent query separately. A single-parent detail query is not batch Top-N. +- Server providers default to a window query (`threshold = 0`). A positive threshold + permits bounded probes only when the already-loaded parent count is at or below it; + above it, use the window plan. SQLite uses its internal AlwaysProbe policy by default. +- Measure before opting in. Do not infer a threshold from table size or execute COUNT + or statistics queries to choose a plan. Keep an index on foreign key + sort + ID. +- Inspect selected-plan, parent-count, per-parent-limit and probe-count telemetry. + Runtime-managed probes are not application-owned N+1 loops; neither strategy changes + authorization, loaded-state semantics or the required comment/purpose. diff --git a/source/teaql-ts/examples/browser-sqlite/assist/query-order_status.md b/source/teaql-ts/examples/browser-sqlite/assist/query-order_status.md new file mode 100644 index 0000000000000000000000000000000000000000..f60c801d950a09212ce851164c7090bfdedc4ec4 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/assist/query-order_status.md @@ -0,0 +1,104 @@ + + +# TypeScript Assist — Query `Order Status` + +Use the exact generated `Q.orderStatusesWithMinimalFields()` +entry point. Trusted runtime and policy state comes only from `UserContext`. + +```typescript +import { Q } from './Q'; +import { OrderStatus } from './models/OrderStatus'; +import { SmartList, UserContext } from '../teaql-ts'; + +export async function queryOrderStatusById( + context: UserContext, + entityId: string, +): Promise> { + return Q.orderStatusesWithMinimalFields() + .withIdIs(entityId) + .orderByIdAscending() + .limit(20) + .comment('what: load the requested Order Status row') + .purpose('why: serve the authorized Order Status view') + .executeForList(context); +} +``` + +Compile and execute this source unchanged. Use only generated projection, +predicate, ordering, and relation-selection APIs. Missing or blank intent, +unknown fields, unbounded reads, and trusted-context inputs must fail. Use generated +relation loading rather than handwritten child-query loops; never guess a plural. + + +## Field-specific Query Assist + +Use the canonical KSML field name from this list. Do not substitute a language member name, JSON name, or database column. + +| KSML field | Type | Field help | +| --- | --- | --- | +| `platform` | `relation` | `typescript-assist-query/order_status.platform` | +| `id` | `id` | `typescript-assist-query/order_status.id` | +| `name` | `string` | `typescript-assist-query/order_status.name` | +| `code` | `string` | `typescript-assist-query/order_status.code` | +| `color` | `string` | `typescript-assist-query/order_status.color` | +| `display_order` | `integer` | `typescript-assist-query/order_status.display_order` | +| `version` | `version` | `typescript-assist-query/order_status.version` | + +Generated reverse relations are derived from referencing KSML fields. Use their exact generated location for relation selection and access: + +| Generated reverse relation | Child entity | Field help | +| --- | --- | --- | +| `customer_order_list` | `customer_order` | `typescript-assist-query/order_status.customer_order_list` | + + +--- + +## TeaQL seven-language assist contract + +Apply the verified Rust semantic ceiling while using only the exact TYPESCRIPT generated and +runtime APIs. Discover APIs through the generated application AGENTS.md and progressive +model-aware Assist. Do not inspect generated domain-library source. + +- Do not create plurals by appending `s` or `es`; use the centralized generated plural. +- Human and non-human entities use different generated predicate vocabularies. Preserve + forms such as “who are active” and “whose email is”; never infer them from English. +- Configure filters, projection, paging, and other query options before `purpose(...)`. + Comment may appear anywhere in the chain. Purpose enters the executable stage; execution + requires both values, but comment does not have to immediately precede purpose. +- Every execute/list/stream and every save accepts exactly one context argument: + `UserContext`. Name that argument `context`, never `runtime`; data services and global + policy are injected when the context is built. Reserve `runtime` for process-level + runtime ownership, provider/pool setup, and module assembly. +- Tenant, merchant, identity, permissions, request policy, purpose policy, hard limit, + and continuous-page cursor policy come only from trusted context, never dynamic JSON or TFP. +- If the required operation is absent after current entity/action and required field + Assist, stop that path and report MISSING_ASSIST. Do not guess an API or search the + generated library as a fallback. +- Create each application-owned source file once. After its first compile attempt, + repair only the smallest block identified by the exact compiler or test diagnostic. + Preserve unrelated code; do not rewrite the complete file as an error-recovery loop. +- Before a repair that would replace more than 25% of an existing application file, + stop and report LARGE_REWRITE_REQUEST with the file, exact diagnostic, reason, and + estimated scope. Initial creation and model-driven regeneration are not repairs. + +Capability: `query`. + +- Use generated projection, relation, predicate, sort, and aggregate APIs; never + concatenate application SQL or silently ignore an unsupported filter. +- Rows, record count, facets, and aggregates must share the same active filter. +- Add negative tests for missing purpose/comment and forbidden dynamic fields. + +### Optional per-parent Top-N optimization + +- Configure `topNProbeParentThreshold(threshold)` on the nested child request before its intent/execution + stage. Use the field-specific relation Assist for the exact generated selector. +- Give the child a per-parent limit and deterministic ordering with an ID tie-breaker; + bound the parent query separately. A single-parent detail query is not batch Top-N. +- Server providers default to a window query (`threshold = 0`). A positive threshold + permits bounded probes only when the already-loaded parent count is at or below it; + above it, use the window plan. SQLite uses its internal AlwaysProbe policy by default. +- Measure before opting in. Do not infer a threshold from table size or execute COUNT + or statistics queries to choose a plan. Keep an index on foreign key + sort + ID. +- Inspect selected-plan, parent-count, per-parent-limit and probe-count telemetry. + Runtime-managed probes are not application-owned N+1 loops; neither strategy changes + authorization, loaded-state semantics or the required comment/purpose. diff --git a/source/teaql-ts/examples/browser-sqlite/generated-order-hashes.json b/source/teaql-ts/examples/browser-sqlite/generated-order-hashes.json new file mode 100644 index 0000000000000000000000000000000000000000..bc6cc715fa94722884cac06592cba651dd46d2ad --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/generated-order-hashes.json @@ -0,0 +1,19 @@ +{ + "src/generated-bootstrap.ts": "5f3065c1e4794c0d21ada7c2eef48f4694cec1cbc4771fa48bc7d6ff9221540b", + "src/generated-search-models.ts": "7ece2e29eeb80306d09623c8685c8a0b8d3b25aad6b38f845d5c9f069bd6f7a3", + "src/generated/E.ts": "940a5dfa19912a7973ac44879488b37132d981cd3325f7f28aefdef0480c7542", + "src/generated/Q.ts": "e03153a1477298d4b6568bdeab1b98cab21bf98fcafd6a2fb248a1129db0b46f", + "src/generated/models/Customer.ts": "5ff4b46a58b2dad54858b7ed444f3b78c49941b8e01b150008d6f48ae11cc067", + "src/generated/models/CustomerOrder.ts": "94168486fb9dffd2f99296bf93eb0bfcfa83744d4516e706f8b144cec8317f1a", + "src/generated/models/OrderItem.ts": "e2884b4013b7478d8e3083b1a18ed9b3321c19b49004249b5486a31385c6797e", + "src/generated/models/OrderStatus.ts": "2bb7bfe245ab3dd75ca4359037769a3f760c90fed5ac214032f008c90fb39c14", + "src/generated/models/Platform.ts": "55d9146a4b42929e4f206beb9288921dfaee5c08ac9616100898d4c6e7817c5a", + "src/generated/requests/CustomerOrderRequest.ts": "167326d997fa314411fdad1349ea34aef3c1232c2c469253714318905f041744", + "src/generated/requests/CustomerRequest.ts": "7c1dfc760a67d523579ef0758731d7c6772930d8360e5594a37926aa5df3e5f3", + "src/generated/requests/OrderItemRequest.ts": "ee3fe2e2d3dc6eae0c1ff1697cb7f73626595682dd2b5a87218b855287468c0a", + "src/generated/requests/OrderStatusRequest.ts": "fbb8ed0507ec80f4b9a5d0d260f7e08ecc524d56cc4b78166326750629cfec24", + "src/generated/requests/PlatformRequest.ts": "dcf958694498114f744ea59570dc92e4fd2e93b84ddb2c831af99be04b08c2b7", + "src/runtime-module.ts": "f92fe9a9474678d26a233eb734b14493b4ddc216ed3b648bfad723b4b6a46eeb", + "src/teaql-schemas.ts": "68cb7cacc725ff041d2289f17d7817ae56f37d035c92f2feb6c1318face6f806", + "src/teaql-ts.ts": "cc705f9f7873450eae541311317db3402dc40b7cf068c440169bd7ba06dcb1ed" +} diff --git a/source/teaql-ts/examples/browser-sqlite/index.html b/source/teaql-ts/examples/browser-sqlite/index.html new file mode 100644 index 0000000000000000000000000000000000000000..6a34167138fc53442292c66bf6a6192dad4c5459 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/index.html @@ -0,0 +1,140 @@ + + + + + + + + TeaQL Order Query Playground + + +
+ + +
+
+
+

BROWSER SQLITE · ORDER DOMAIN

+

Understand TeaQL queries through a familiar order model.

+

Platform, customer, order, item, payment, and shipment data all run in the browser. Order status is backed by a constant model. Choose a query below to inspect real SQLite/WASM results.

+
+
+
+ PlatformPlatform + → + CustomerCustomer + → + OrderOrder +
+ ↓ +
+ ItemItem + PaymentPayment + ShipmentShipment + OrderStatusConstant model +
+
+
+ +
+

Starting SQLite/WASM…

+
+ + +
+
+ +
+
+
+

01 / QUERIES

+

Choose a query

+
+

Queries are grouped by purpose and share the same order dataset.

+
+ +
+ +
+
+
+

02 / RESULT

+

Comprehensive: Order management center

+

+
+
+
+ + +
+
+ + +
+
+
+
+
+
+ Result tree +

Waiting for query…

+
+
+
+
+

GENERATED Q QUERY

+
+ +

The Q expression stays fixed; search, status cards, and pagination only update dynamic parameters. The underlying SelectQuery remains inside the generated request implementation.

+
+
+
+

EXECUTION EVIDENCE

+ 0 statements +
+
+ + + + + + + + + + +
TimeIdentityTrace chainSQL
+
+

One plain-text line per statement: time, identity, trace chain, and the SQL SQLite executed.

+
+
+
+
+ +
+ TeaQL TypeScript Runtime + Data stays in this browser +
+
+ + + diff --git a/source/teaql-ts/examples/browser-sqlite/order-model.xml b/source/teaql-ts/examples/browser-sqlite/order-model.xml new file mode 100644 index 0000000000000000000000000000000000000000..58ff3e8c9f3b9fbdb63beec4ee1fcf8456ccf7dd --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/order-model.xml @@ -0,0 +1,21 @@ + + + + + <_value id="1001" name="New" code="NEW" color="#94A3B8" display_order="1"/> + <_value id="1002" name="Paid" code="PAID" color="#22C55E" display_order="2"/> + <_value id="1003" name="Cancelled" code="CANCELLED" color="#EF4444" display_order="3"/> + + + + + diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/package.json b/source/teaql-ts/examples/browser-sqlite/orders-lib/package.json new file mode 100644 index 0000000000000000000000000000000000000000..b91ad7420933e0d9b3dbb9ab9173e9bc3d815830 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/package.json @@ -0,0 +1,15 @@ +{ + "name" : "request-tree-order-service-lib", + "version" : "1.0.0", + "description" : "Generated typescript library", + "main" : "src/generated/Q.ts", + "scripts" : { + "build" : "tsc --noEmit" + }, + "dependencies" : { + "teaql-ts" : "file:../../.." + }, + "devDependencies" : { + "typescript" : "^5.0.0" + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated-bootstrap.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated-bootstrap.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0458cb91bdca98d6fbab0a1eb1c0c53fb73d305 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated-bootstrap.ts @@ -0,0 +1,69 @@ +import { UserContext } from './teaql-ts'; +import { Q } from './generated/Q'; +import { Platform } from './generated/models/Platform'; +import { OrderStatus } from './generated/models/OrderStatus'; + +/** @internal Generated typed Mutation bootstrap; never call from application code. */ +export async function ensureGeneratedBootstrap(context: UserContext): Promise { + let domainRoot = (await Q.platforms().withIdIs('1').comment('what: locate generated Domain Root').purpose('why: idempotent runtime bootstrap').executeForList(context))[0]; + if (!domainRoot) { + domainRoot = Platform.teaqlBootstrapNew('1'); + domainRoot.updateName("Commerce Test Platform"); + await domainRoot.auditAs('create generated Domain Root Platform').save(context); + } + context.withActiveRoot({ entity: 'Platform', id: domainRoot.id! }); + let constantOrderStatus1001 = (await Q.orderStatuses().withIdIs("1001").comment('what: locate generated constant OrderStatus(1001)').purpose('why: idempotent runtime bootstrap').executeForList(context))[0]; + if (!constantOrderStatus1001) { + constantOrderStatus1001 = OrderStatus.teaqlBootstrapNew("1001"); + constantOrderStatus1001.updatePlatform(domainRoot); + constantOrderStatus1001.updateName("New"); + constantOrderStatus1001.updateCode("NEW"); + constantOrderStatus1001.updateColor("#94A3B8"); + constantOrderStatus1001.updateDisplayOrder(1); + await constantOrderStatus1001.auditAs('create model constant OrderStatus(1001)').save(context); + } else { + let changed = false; + if (String((constantOrderStatus1001.platform as any)?.id ?? constantOrderStatus1001.platform) !== String(domainRoot.id)) { constantOrderStatus1001.updatePlatform(domainRoot); changed = true; } + if (constantOrderStatus1001.name !== "New") { constantOrderStatus1001.updateName("New"); changed = true; } + if (constantOrderStatus1001.code !== "NEW") { constantOrderStatus1001.updateCode("NEW"); changed = true; } + if (constantOrderStatus1001.color !== "#94A3B8") { constantOrderStatus1001.updateColor("#94A3B8"); changed = true; } + if (constantOrderStatus1001.displayOrder !== 1) { constantOrderStatus1001.updateDisplayOrder(1); changed = true; } + if (changed) await constantOrderStatus1001.auditAs('reconcile model constant OrderStatus(1001)').save(context); + } + let constantOrderStatus1002 = (await Q.orderStatuses().withIdIs("1002").comment('what: locate generated constant OrderStatus(1002)').purpose('why: idempotent runtime bootstrap').executeForList(context))[0]; + if (!constantOrderStatus1002) { + constantOrderStatus1002 = OrderStatus.teaqlBootstrapNew("1002"); + constantOrderStatus1002.updatePlatform(domainRoot); + constantOrderStatus1002.updateName("Paid"); + constantOrderStatus1002.updateCode("PAID"); + constantOrderStatus1002.updateColor("#22C55E"); + constantOrderStatus1002.updateDisplayOrder(2); + await constantOrderStatus1002.auditAs('create model constant OrderStatus(1002)').save(context); + } else { + let changed = false; + if (String((constantOrderStatus1002.platform as any)?.id ?? constantOrderStatus1002.platform) !== String(domainRoot.id)) { constantOrderStatus1002.updatePlatform(domainRoot); changed = true; } + if (constantOrderStatus1002.name !== "Paid") { constantOrderStatus1002.updateName("Paid"); changed = true; } + if (constantOrderStatus1002.code !== "PAID") { constantOrderStatus1002.updateCode("PAID"); changed = true; } + if (constantOrderStatus1002.color !== "#22C55E") { constantOrderStatus1002.updateColor("#22C55E"); changed = true; } + if (constantOrderStatus1002.displayOrder !== 2) { constantOrderStatus1002.updateDisplayOrder(2); changed = true; } + if (changed) await constantOrderStatus1002.auditAs('reconcile model constant OrderStatus(1002)').save(context); + } + let constantOrderStatus1003 = (await Q.orderStatuses().withIdIs("1003").comment('what: locate generated constant OrderStatus(1003)').purpose('why: idempotent runtime bootstrap').executeForList(context))[0]; + if (!constantOrderStatus1003) { + constantOrderStatus1003 = OrderStatus.teaqlBootstrapNew("1003"); + constantOrderStatus1003.updatePlatform(domainRoot); + constantOrderStatus1003.updateName("Cancelled"); + constantOrderStatus1003.updateCode("CANCELLED"); + constantOrderStatus1003.updateColor("#EF4444"); + constantOrderStatus1003.updateDisplayOrder(3); + await constantOrderStatus1003.auditAs('create model constant OrderStatus(1003)').save(context); + } else { + let changed = false; + if (String((constantOrderStatus1003.platform as any)?.id ?? constantOrderStatus1003.platform) !== String(domainRoot.id)) { constantOrderStatus1003.updatePlatform(domainRoot); changed = true; } + if (constantOrderStatus1003.name !== "Cancelled") { constantOrderStatus1003.updateName("Cancelled"); changed = true; } + if (constantOrderStatus1003.code !== "CANCELLED") { constantOrderStatus1003.updateCode("CANCELLED"); changed = true; } + if (constantOrderStatus1003.color !== "#EF4444") { constantOrderStatus1003.updateColor("#EF4444"); changed = true; } + if (constantOrderStatus1003.displayOrder !== 3) { constantOrderStatus1003.updateDisplayOrder(3); changed = true; } + if (changed) await constantOrderStatus1003.auditAs('reconcile model constant OrderStatus(1003)').save(context); + } +} diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated-search-models.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated-search-models.ts new file mode 100644 index 0000000000000000000000000000000000000000..2ed841d2ddb74e211dc1257a6448ae63984e3ed7 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated-search-models.ts @@ -0,0 +1,124 @@ +import type { GeneratedSearchModel } from "teaql-ts"; + +/** Generated trusted naming/type metadata. No query execution or authorization lives here. */ +export const GENERATED_SEARCH_MODELS: Readonly> = Object.freeze({ + "Platform": Object.freeze({ + fields: Object.freeze({ + "id": "integer" as const, + "name": "string" as const, + "version": "integer" as const, + }), + queryFields: Object.freeze({ + "id": "id", + "name": "name", + "version": "version", + }), + relations: Object.freeze({ + "orderStatusList": "OrderStatus", + "customerList": "Customer", + }), + }), + "OrderStatus": Object.freeze({ + fields: Object.freeze({ + "platform": "integer" as const, + "id": "integer" as const, + "name": "string" as const, + "code": "string" as const, + "color": "string" as const, + "display_order": "integer" as const, + "displayOrder": "integer" as const, + "version": "integer" as const, + }), + queryFields: Object.freeze({ + "platform": "platform", + "id": "id", + "name": "name", + "code": "code", + "color": "color", + "display_order": "displayOrder", + "displayOrder": "displayOrder", + "version": "version", + }), + relations: Object.freeze({ + "platform": "Platform", + "customerOrderList": "CustomerOrder", + }), + }), + "Customer": Object.freeze({ + fields: Object.freeze({ + "id": "integer" as const, + "platform": "integer" as const, + "name": "string" as const, + "version": "integer" as const, + }), + queryFields: Object.freeze({ + "id": "id", + "platform": "platform", + "name": "name", + "version": "version", + }), + relations: Object.freeze({ + "platform": "Platform", + "customerOrderList": "CustomerOrder", + }), + }), + "CustomerOrder": Object.freeze({ + fields: Object.freeze({ + "id": "integer" as const, + "customer": "integer" as const, + "status": "integer" as const, + "order_number": "string" as const, + "orderNumber": "string" as const, + "order_date": "date" as const, + "orderDate": "date" as const, + "total_amount": "decimal" as const, + "totalAmount": "decimal" as const, + "version": "integer" as const, + }), + queryFields: Object.freeze({ + "id": "id", + "customer": "customer", + "status": "status", + "order_number": "orderNumber", + "orderNumber": "orderNumber", + "order_date": "orderDate", + "orderDate": "orderDate", + "total_amount": "totalAmount", + "totalAmount": "totalAmount", + "version": "version", + }), + relations: Object.freeze({ + "customer": "Customer", + "status": "OrderStatus", + "orderItemList": "OrderItem", + }), + }), + "OrderItem": Object.freeze({ + fields: Object.freeze({ + "id": "integer" as const, + "customer_order": "integer" as const, + "customerOrder": "integer" as const, + "product_name": "string" as const, + "productName": "string" as const, + "quantity": "integer" as const, + "unit_price": "decimal" as const, + "unitPrice": "decimal" as const, + "version": "integer" as const, + }), + queryFields: Object.freeze({ + "id": "id", + "customer_order": "customerOrder", + "customerOrder": "customerOrder", + "product_name": "productName", + "productName": "productName", + "quantity": "quantity", + "unit_price": "unitPrice", + "unitPrice": "unitPrice", + "version": "version", + }), + relations: Object.freeze({ + "customer_order": "CustomerOrder", + "customerOrder": "CustomerOrder", + }), + }), +}); \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/E.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/E.ts new file mode 100644 index 0000000000000000000000000000000000000000..375cf0e5ba2f8fa528154e5468cadc283cab40cf --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/E.ts @@ -0,0 +1,869 @@ +import { Platform } from './models/Platform'; +import { OrderStatus } from './models/OrderStatus'; +import { Customer } from './models/Customer'; +import { CustomerOrder } from './models/CustomerOrder'; +import { OrderItem } from './models/OrderItem'; + +export class TeaQLNotLoadedError extends Error { + readonly details: Record; + + constructor( + readonly root: string, + readonly accessPath: string, + readonly breakPoint: string, + ) { + const suggestedFix = `select${breakPoint.charAt(0).toUpperCase()}${breakPoint.slice(1)}(...)`; + const details = { + error: 'TeaQLNotLoadedError', + root, + accessPath: accessPath.split('.'), + breakPoint, + missingPreload: [breakPoint], + suggestedFix, + severity: 'error', + humanMessage: `访问 ${root}.${accessPath} 时缺少预加载。请在查询中加入 ${suggestedFix}`, + }; + super(JSON.stringify(details)); + this.name = 'TeaQLNotLoadedError'; + this.details = details; + } +} + +function expressionPath(prefix: string, field: string): string { + return prefix ? `${prefix}.${field}` : field; +} + +export class ValueExpression { + constructor( + private readonly value: T | null | undefined, + private readonly present = true, + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + static missing(): ValueExpression { + return new ValueExpression(undefined, false); + } + + static notLoaded(error: TeaQLNotLoadedError): ValueExpression { + return new ValueExpression(undefined, false, error); + } + + eval(): T | null | undefined { + if (this.notLoaded) throw this.notLoaded; + return this.present ? this.value : undefined; + } + + isPresent(): boolean { + if (this.notLoaded) throw this.notLoaded; + return this.present; + } + + orElse(fallback: T): T { + const value = this.eval(); + return this.present && value != null ? value : fallback; + } +} + +export class PlatformExpression { + constructor( + private readonly value: Platform | null | undefined, + private readonly root = 'Platform(null)', + private readonly path = '', + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + eval(): Platform | null | undefined { + if (this.notLoaded) throw this.notLoaded; + return this.value; + } + + id(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'id'); + if (!this.value.isLoaded('id')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'id'), + ); + } + return new ValueExpression(this.value.id); + } + + name(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'name'); + if (!this.value.isLoaded('name')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'name'), + ); + } + return new ValueExpression(this.value.name); + } + + version(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'version'); + if (!this.value.isLoaded('version')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'version'), + ); + } + return new ValueExpression(this.value.version); + } + + + + orderStatusList(): OrderStatusListExpression { + const path = expressionPath(this.path, 'orderStatusList'); + if (this.notLoaded) { + return new OrderStatusListExpression([], this.root, path, false, this.notLoaded); + } + if (!this.value) return OrderStatusListExpression.missing(this.root, path); + if (!this.value.isLoaded('orderStatusList')) { + return new OrderStatusListExpression([], this.root, path, false, + new TeaQLNotLoadedError(this.root, path, 'orderStatusList')); + } + return new OrderStatusListExpression( + this.value.orderStatusList(), this.root, path, + ); + } + + customerList(): CustomerListExpression { + const path = expressionPath(this.path, 'customerList'); + if (this.notLoaded) { + return new CustomerListExpression([], this.root, path, false, this.notLoaded); + } + if (!this.value) return CustomerListExpression.missing(this.root, path); + if (!this.value.isLoaded('customerList')) { + return new CustomerListExpression([], this.root, path, false, + new TeaQLNotLoadedError(this.root, path, 'customerList')); + } + return new CustomerListExpression( + this.value.customerList(), this.root, path, + ); + } +} + +export class OrderStatusExpression { + constructor( + private readonly value: OrderStatus | null | undefined, + private readonly root = 'OrderStatus(null)', + private readonly path = '', + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + eval(): OrderStatus | null | undefined { + if (this.notLoaded) throw this.notLoaded; + return this.value; + } + + id(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'id'); + if (!this.value.isLoaded('id')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'id'), + ); + } + return new ValueExpression(this.value.id); + } + + name(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'name'); + if (!this.value.isLoaded('name')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'name'), + ); + } + return new ValueExpression(this.value.name); + } + + code(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'code'); + if (!this.value.isLoaded('code')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'code'), + ); + } + return new ValueExpression(this.value.code); + } + + color(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'color'); + if (!this.value.isLoaded('color')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'color'), + ); + } + return new ValueExpression(this.value.color); + } + + displayOrder(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'displayOrder'); + if (!this.value.isLoaded('displayOrder')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'displayOrder'), + ); + } + return new ValueExpression(this.value.displayOrder); + } + + version(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'version'); + if (!this.value.isLoaded('version')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'version'), + ); + } + return new ValueExpression(this.value.version); + } + + platformId(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'platform'); + if (!this.value.isLoaded('platform')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'platform'), + ); + } + const reference = this.value.platform; + return new ValueExpression( + reference instanceof Platform + ? reference.id : reference as string | number | undefined, + ); + } + + platform(): PlatformExpression { + const path = expressionPath(this.path, 'platform'); + if (this.notLoaded) { + return new PlatformExpression(undefined, this.root, path, this.notLoaded); + } + if (!this.value) return new PlatformExpression(undefined, this.root, path); + if (!this.value.isLoaded('platform')) { + return new PlatformExpression(undefined, this.root, path, + new TeaQLNotLoadedError(this.root, path, 'platform')); + } + const relation = this.value.platform; + const target = relation == null + ? undefined + : relation instanceof Platform + ? relation + : Platform.fromRecord({ id: relation }); + return new PlatformExpression(target, this.root, path); + } + + customerOrderList(): CustomerOrderListExpression { + const path = expressionPath(this.path, 'customerOrderList'); + if (this.notLoaded) { + return new CustomerOrderListExpression([], this.root, path, false, this.notLoaded); + } + if (!this.value) return CustomerOrderListExpression.missing(this.root, path); + if (!this.value.isLoaded('customerOrderList')) { + return new CustomerOrderListExpression([], this.root, path, false, + new TeaQLNotLoadedError(this.root, path, 'customerOrderList')); + } + return new CustomerOrderListExpression( + this.value.customerOrderList(), this.root, path, + ); + } +} + +export class CustomerExpression { + constructor( + private readonly value: Customer | null | undefined, + private readonly root = 'Customer(null)', + private readonly path = '', + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + eval(): Customer | null | undefined { + if (this.notLoaded) throw this.notLoaded; + return this.value; + } + + id(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'id'); + if (!this.value.isLoaded('id')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'id'), + ); + } + return new ValueExpression(this.value.id); + } + + name(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'name'); + if (!this.value.isLoaded('name')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'name'), + ); + } + return new ValueExpression(this.value.name); + } + + version(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'version'); + if (!this.value.isLoaded('version')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'version'), + ); + } + return new ValueExpression(this.value.version); + } + + platformId(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'platform'); + if (!this.value.isLoaded('platform')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'platform'), + ); + } + const reference = this.value.platform; + return new ValueExpression( + reference instanceof Platform + ? reference.id : reference as string | number | undefined, + ); + } + + platform(): PlatformExpression { + const path = expressionPath(this.path, 'platform'); + if (this.notLoaded) { + return new PlatformExpression(undefined, this.root, path, this.notLoaded); + } + if (!this.value) return new PlatformExpression(undefined, this.root, path); + if (!this.value.isLoaded('platform')) { + return new PlatformExpression(undefined, this.root, path, + new TeaQLNotLoadedError(this.root, path, 'platform')); + } + const relation = this.value.platform; + const target = relation == null + ? undefined + : relation instanceof Platform + ? relation + : Platform.fromRecord({ id: relation }); + return new PlatformExpression(target, this.root, path); + } + + customerOrderList(): CustomerOrderListExpression { + const path = expressionPath(this.path, 'customerOrderList'); + if (this.notLoaded) { + return new CustomerOrderListExpression([], this.root, path, false, this.notLoaded); + } + if (!this.value) return CustomerOrderListExpression.missing(this.root, path); + if (!this.value.isLoaded('customerOrderList')) { + return new CustomerOrderListExpression([], this.root, path, false, + new TeaQLNotLoadedError(this.root, path, 'customerOrderList')); + } + return new CustomerOrderListExpression( + this.value.customerOrderList(), this.root, path, + ); + } +} + +export class CustomerOrderExpression { + constructor( + private readonly value: CustomerOrder | null | undefined, + private readonly root = 'CustomerOrder(null)', + private readonly path = '', + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + eval(): CustomerOrder | null | undefined { + if (this.notLoaded) throw this.notLoaded; + return this.value; + } + + id(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'id'); + if (!this.value.isLoaded('id')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'id'), + ); + } + return new ValueExpression(this.value.id); + } + + orderNumber(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'orderNumber'); + if (!this.value.isLoaded('orderNumber')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'orderNumber'), + ); + } + return new ValueExpression(this.value.orderNumber); + } + + orderDate(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'orderDate'); + if (!this.value.isLoaded('orderDate')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'orderDate'), + ); + } + return new ValueExpression(this.value.orderDate); + } + + totalAmount(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'totalAmount'); + if (!this.value.isLoaded('totalAmount')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'totalAmount'), + ); + } + return new ValueExpression(this.value.totalAmount); + } + + version(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'version'); + if (!this.value.isLoaded('version')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'version'), + ); + } + return new ValueExpression(this.value.version); + } + + customerId(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'customer'); + if (!this.value.isLoaded('customer')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'customer'), + ); + } + const reference = this.value.customer; + return new ValueExpression( + reference instanceof Customer + ? reference.id : reference as string | number | undefined, + ); + } + + statusId(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'status'); + if (!this.value.isLoaded('status')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'status'), + ); + } + const reference = this.value.status; + return new ValueExpression( + reference instanceof OrderStatus + ? reference.id : reference as string | number | undefined, + ); + } + + customer(): CustomerExpression { + const path = expressionPath(this.path, 'customer'); + if (this.notLoaded) { + return new CustomerExpression(undefined, this.root, path, this.notLoaded); + } + if (!this.value) return new CustomerExpression(undefined, this.root, path); + if (!this.value.isLoaded('customer')) { + return new CustomerExpression(undefined, this.root, path, + new TeaQLNotLoadedError(this.root, path, 'customer')); + } + const relation = this.value.customer; + const target = relation == null + ? undefined + : relation instanceof Customer + ? relation + : Customer.fromRecord({ id: relation }); + return new CustomerExpression(target, this.root, path); + } + + status(): OrderStatusExpression { + const path = expressionPath(this.path, 'status'); + if (this.notLoaded) { + return new OrderStatusExpression(undefined, this.root, path, this.notLoaded); + } + if (!this.value) return new OrderStatusExpression(undefined, this.root, path); + if (!this.value.isLoaded('status')) { + return new OrderStatusExpression(undefined, this.root, path, + new TeaQLNotLoadedError(this.root, path, 'status')); + } + const relation = this.value.status; + const target = relation == null + ? undefined + : relation instanceof OrderStatus + ? relation + : OrderStatus.fromRecord({ id: relation }); + return new OrderStatusExpression(target, this.root, path); + } + + orderItemList(): OrderItemListExpression { + const path = expressionPath(this.path, 'orderItemList'); + if (this.notLoaded) { + return new OrderItemListExpression([], this.root, path, false, this.notLoaded); + } + if (!this.value) return OrderItemListExpression.missing(this.root, path); + if (!this.value.isLoaded('orderItemList')) { + return new OrderItemListExpression([], this.root, path, false, + new TeaQLNotLoadedError(this.root, path, 'orderItemList')); + } + return new OrderItemListExpression( + this.value.orderItemList(), this.root, path, + ); + } +} + +export class OrderItemExpression { + constructor( + private readonly value: OrderItem | null | undefined, + private readonly root = 'OrderItem(null)', + private readonly path = '', + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + eval(): OrderItem | null | undefined { + if (this.notLoaded) throw this.notLoaded; + return this.value; + } + + id(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'id'); + if (!this.value.isLoaded('id')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'id'), + ); + } + return new ValueExpression(this.value.id); + } + + productName(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'productName'); + if (!this.value.isLoaded('productName')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'productName'), + ); + } + return new ValueExpression(this.value.productName); + } + + quantity(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'quantity'); + if (!this.value.isLoaded('quantity')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'quantity'), + ); + } + return new ValueExpression(this.value.quantity); + } + + unitPrice(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'unitPrice'); + if (!this.value.isLoaded('unitPrice')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'unitPrice'), + ); + } + return new ValueExpression(this.value.unitPrice); + } + + version(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'version'); + if (!this.value.isLoaded('version')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'version'), + ); + } + return new ValueExpression(this.value.version); + } + + customerOrderId(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + if (!this.value) return ValueExpression.missing(); + const path = expressionPath(this.path, 'customerOrder'); + if (!this.value.isLoaded('customerOrder')) { + return ValueExpression.notLoaded( + new TeaQLNotLoadedError(this.root, path, 'customerOrder'), + ); + } + const reference = this.value.customerOrder; + return new ValueExpression( + reference instanceof CustomerOrder + ? reference.id : reference as string | number | undefined, + ); + } + + customerOrder(): CustomerOrderExpression { + const path = expressionPath(this.path, 'customerOrder'); + if (this.notLoaded) { + return new CustomerOrderExpression(undefined, this.root, path, this.notLoaded); + } + if (!this.value) return new CustomerOrderExpression(undefined, this.root, path); + if (!this.value.isLoaded('customerOrder')) { + return new CustomerOrderExpression(undefined, this.root, path, + new TeaQLNotLoadedError(this.root, path, 'customerOrder')); + } + const relation = this.value.customerOrder; + const target = relation == null + ? undefined + : relation instanceof CustomerOrder + ? relation + : CustomerOrder.fromRecord({ id: relation }); + return new CustomerOrderExpression(target, this.root, path); + } + +} + +export class PlatformListExpression { + constructor( + private readonly items: readonly Platform[], + private readonly root = 'Platform(null)', + private readonly path = '', + private readonly present = true, + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + static missing(root?: string, path = ''): PlatformListExpression { + return new PlatformListExpression([], root, path, false); + } + + size(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + return this.present + ? new ValueExpression(this.items.length) + : ValueExpression.missing(); + } + + first(): PlatformExpression { + return this.get(0); + } + + get(index: number): PlatformExpression { + const itemPath = expressionPath(this.path, `get(${index})`); + if (this.notLoaded) { + return new PlatformExpression(undefined, this.root, itemPath, this.notLoaded); + } + return !this.present || index < 0 || index >= this.items.length + ? new PlatformExpression(undefined, this.root, itemPath) + : new PlatformExpression(this.items[index], this.root, itemPath); + } +} + +export class OrderStatusListExpression { + constructor( + private readonly items: readonly OrderStatus[], + private readonly root = 'OrderStatus(null)', + private readonly path = '', + private readonly present = true, + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + static missing(root?: string, path = ''): OrderStatusListExpression { + return new OrderStatusListExpression([], root, path, false); + } + + size(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + return this.present + ? new ValueExpression(this.items.length) + : ValueExpression.missing(); + } + + first(): OrderStatusExpression { + return this.get(0); + } + + get(index: number): OrderStatusExpression { + const itemPath = expressionPath(this.path, `get(${index})`); + if (this.notLoaded) { + return new OrderStatusExpression(undefined, this.root, itemPath, this.notLoaded); + } + return !this.present || index < 0 || index >= this.items.length + ? new OrderStatusExpression(undefined, this.root, itemPath) + : new OrderStatusExpression(this.items[index], this.root, itemPath); + } +} + +export class CustomerListExpression { + constructor( + private readonly items: readonly Customer[], + private readonly root = 'Customer(null)', + private readonly path = '', + private readonly present = true, + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + static missing(root?: string, path = ''): CustomerListExpression { + return new CustomerListExpression([], root, path, false); + } + + size(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + return this.present + ? new ValueExpression(this.items.length) + : ValueExpression.missing(); + } + + first(): CustomerExpression { + return this.get(0); + } + + get(index: number): CustomerExpression { + const itemPath = expressionPath(this.path, `get(${index})`); + if (this.notLoaded) { + return new CustomerExpression(undefined, this.root, itemPath, this.notLoaded); + } + return !this.present || index < 0 || index >= this.items.length + ? new CustomerExpression(undefined, this.root, itemPath) + : new CustomerExpression(this.items[index], this.root, itemPath); + } +} + +export class CustomerOrderListExpression { + constructor( + private readonly items: readonly CustomerOrder[], + private readonly root = 'CustomerOrder(null)', + private readonly path = '', + private readonly present = true, + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + static missing(root?: string, path = ''): CustomerOrderListExpression { + return new CustomerOrderListExpression([], root, path, false); + } + + size(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + return this.present + ? new ValueExpression(this.items.length) + : ValueExpression.missing(); + } + + first(): CustomerOrderExpression { + return this.get(0); + } + + get(index: number): CustomerOrderExpression { + const itemPath = expressionPath(this.path, `get(${index})`); + if (this.notLoaded) { + return new CustomerOrderExpression(undefined, this.root, itemPath, this.notLoaded); + } + return !this.present || index < 0 || index >= this.items.length + ? new CustomerOrderExpression(undefined, this.root, itemPath) + : new CustomerOrderExpression(this.items[index], this.root, itemPath); + } +} + +export class OrderItemListExpression { + constructor( + private readonly items: readonly OrderItem[], + private readonly root = 'OrderItem(null)', + private readonly path = '', + private readonly present = true, + private readonly notLoaded?: TeaQLNotLoadedError, + ) {} + + static missing(root?: string, path = ''): OrderItemListExpression { + return new OrderItemListExpression([], root, path, false); + } + + size(): ValueExpression { + if (this.notLoaded) return ValueExpression.notLoaded(this.notLoaded); + return this.present + ? new ValueExpression(this.items.length) + : ValueExpression.missing(); + } + + first(): OrderItemExpression { + return this.get(0); + } + + get(index: number): OrderItemExpression { + const itemPath = expressionPath(this.path, `get(${index})`); + if (this.notLoaded) { + return new OrderItemExpression(undefined, this.root, itemPath, this.notLoaded); + } + return !this.present || index < 0 || index >= this.items.length + ? new OrderItemExpression(undefined, this.root, itemPath) + : new OrderItemExpression(this.items[index], this.root, itemPath); + } +} + +export class E { + static platform( + value: Platform | null | undefined, + ): PlatformExpression { + return new PlatformExpression( + value, `Platform(id=${value?.id ?? 'null'})`, + ); + } + + static orderStatus( + value: OrderStatus | null | undefined, + ): OrderStatusExpression { + return new OrderStatusExpression( + value, `OrderStatus(id=${value?.id ?? 'null'})`, + ); + } + + static customer( + value: Customer | null | undefined, + ): CustomerExpression { + return new CustomerExpression( + value, `Customer(id=${value?.id ?? 'null'})`, + ); + } + + static customerOrder( + value: CustomerOrder | null | undefined, + ): CustomerOrderExpression { + return new CustomerOrderExpression( + value, `CustomerOrder(id=${value?.id ?? 'null'})`, + ); + } + + static orderItem( + value: OrderItem | null | undefined, + ): OrderItemExpression { + return new OrderItemExpression( + value, `OrderItem(id=${value?.id ?? 'null'})`, + ); + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/Q.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/Q.ts new file mode 100644 index 0000000000000000000000000000000000000000..89574ca4242c30c0aa10ea4e7993ef3df1f529aa --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/Q.ts @@ -0,0 +1,44 @@ +import { TeaQLClient } from '../teaql-ts'; +import { PlatformRequest } from './requests/PlatformRequest'; +import { OrderStatusRequest } from './requests/OrderStatusRequest'; +import { CustomerRequest } from './requests/CustomerRequest'; +import { CustomerOrderRequest } from './requests/CustomerOrderRequest'; +import { OrderItemRequest } from './requests/OrderItemRequest'; + +export class Q { + static platforms(): PlatformRequest { + return new PlatformRequest(false); + } + + static platformsWithMinimalFields(): PlatformRequest { + return new PlatformRequest(true); + } + static orderStatuses(): OrderStatusRequest { + return new OrderStatusRequest(false); + } + + static orderStatusesWithMinimalFields(): OrderStatusRequest { + return new OrderStatusRequest(true); + } + static customers(): CustomerRequest { + return new CustomerRequest(false); + } + + static customersWithMinimalFields(): CustomerRequest { + return new CustomerRequest(true); + } + static customerOrders(): CustomerOrderRequest { + return new CustomerOrderRequest(false); + } + + static customerOrdersWithMinimalFields(): CustomerOrderRequest { + return new CustomerOrderRequest(true); + } + static orderItems(): OrderItemRequest { + return new OrderItemRequest(false); + } + + static orderItemsWithMinimalFields(): OrderItemRequest { + return new OrderItemRequest(true); + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/Customer.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/Customer.ts new file mode 100644 index 0000000000000000000000000000000000000000..41f197c51bf0120adcbd6f3377f3a984c5327c10 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/Customer.ts @@ -0,0 +1,278 @@ +import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, SmartList, TeaQLDataService, UserContext } from '../../teaql-ts'; +import { Platform } from './Platform'; +import { CustomerOrder } from './CustomerOrder'; + +export class Customer { + private static teaqlTemporaryId = 0; + id?: string; + platform?: Platform | string; + name?: string; + version?: number; + + constructor(init?: Partial) { + Object.defineProperty(this, "_action", { value: init && init.id ? "Update" : "Create", writable: true, enumerable: false }); + Object.defineProperty(this, "_comment", { value: undefined, writable: true, enumerable: false }); + Object.defineProperty(this, "_fullyLoaded", { value: !init || !init.id, writable: true, enumerable: false }); + Object.defineProperty(this, "_loadedFields", { value: new Set(Object.keys(init || {})), writable: true, enumerable: false }); + Object.defineProperty(this, "_root", { value: new EntityRoot(), writable: true, enumerable: false }); + Object.defineProperty(this, "_ledgerId", { value: init?.id ?? --Customer.teaqlTemporaryId, writable: true, enumerable: false }); + Object.defineProperty(this, "_customerOrderList", { value: init?.id ? SmartList.empty() : new SmartList(), writable: true, enumerable: false }); + if (init) { + const fields: Record = { ...(init as Record) }; + delete fields["customerOrderList"]; + Object.assign(this, fields); + if ((init as any).platform && typeof (init as any).platform === "object") { + this.platform = (init as any).platform instanceof Platform + ? (init as any).platform + : Platform.fromRecord((init as any).platform); + this.markLoaded("platform"); + } + if (Array.isArray((init as any).customerOrderList)) { + const selected = (init as any).customerOrderList; + (this as any)._customerOrderList = new SmartList(selected.map( + (child: unknown) => child instanceof CustomerOrder + ? child + : CustomerOrder.fromRecord(child as Record), + ), { totalCount: selected.totalCount, aggregations: selected.aggregations, + summary: selected.summary, facets: selected.facets, isLoaded: selected.isLoaded ?? true }); + this.markLoaded("customerOrderList"); + } + } + const key = this.teaqlEntityKey(); + if ((this as any)._action === "Create") (this as any)._root.markAsNew(key); + else if ((this as any).version !== undefined) (this as any)._root.setOriginalVersion(key, Number((this as any).version)); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + } + + private teaqlEntityKey(): EntityKey { return { entity: "Customer", id: (this as any)._ledgerId }; } + private teaqlAttachRoot(root: EntityRoot): this { + if ((this as any)._root !== root) { + root.mergeEntityFrom((this as any)._root, this.teaqlEntityKey()); + (this as any)._root = root; + } + for (const child of (this as any)._customerOrderList) child.teaqlAttachRoot(root); + return this; + } + + static fromRecord(record: Record, root?: EntityRoot): Customer { + const entity = new Customer(record as Partial); + return root ? entity.teaqlAttachRoot(root) : entity; + } + + isLoaded(field: string): boolean { + return (this as any)._fullyLoaded || (this as any)._loadedFields.has(field); + } + + markLoaded(...fields: string[]): this { + for (const field of fields) (this as any)._loadedFields.add(field); + return this; + } + + markLoadedOnly(...fields: string[]): this { + (this as any)._fullyLoaded = false; + (this as any)._loadedFields = new Set(fields); + return this; + } + + static refer(id: string | number): Customer { + return new Customer({ id: String(id) } as Partial); + } + + /** @internal Generated Runtime Module fixed-ID construction capability. */ + static teaqlBootstrapNew(id: string | number): Customer { + return new Customer().updateId(String(id)); + } + + markForDeletion(): this { + (this as any)._action = "Delete"; + (this as any)._root.markAsDeleted(this.teaqlEntityKey()); + return this; + } + + auditAs(comment: string): this { + new MutationIntent(comment); + (this as any)._comment = comment; + return this; + } + + async save(context: UserContext): Promise { + const service = context.requireResource("dataService"); + return service.executeGraphSave(new MutationIntent((this as any)._comment), async (graph) => { + this.teaqlPreflightGraph(context, service, graph); + return this.teaqlSaveWithinGraph(context, service, graph); + }); + } + + /** @internal Validates and fixes the complete graph before its first mutation. */ + teaqlPreflightGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): void { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const pending = action !== "Update" || (this as any)._root.hasPending(this.teaqlEntityKey()); + if (action === "Update" && pending) { + const notLoaded = [{ member: "id", canonical: "id" }, { member: "platform", canonical: "platform" }, { member: "name", canonical: "name" }, { member: "version", canonical: "version" }] + .find(field => !this.isLoaded(field.member)); + if (notLoaded) { + throw new CheckException([{ + ruleId: "invalid_type", + location: ObjectLocation.property(notLoaded.canonical), + message: "Mutation requires a fully loaded entity", + }]); + } + } + const request = graph.request({ + entity: "Customer", action, + payload: action === "Update" + ? (this as any)._root.change(this.teaqlEntityKey()) + : this.teaqlMutationPayload(), + id: (this as any).id, version: (this as any).version, + comment: (this as any)._comment, + ledgerKey: this.teaqlEntityKey(), ledgerRoot: (this as any)._root, + }, parent, (this as any)._comment).withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (pending) service.preflightMutation(request); + const scope = request.scopeFor(this.teaqlEntityKey()); + for (const [index, child] of (this as any)._customerOrderList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.customer; + if (this.id === undefined || !child.isLoaded("customer") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateCustomer(this); + try { child.teaqlPreflightGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_order_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + } + + /** @internal Used by generated relation cascades inside the root graph transaction. */ + async teaqlSaveWithinGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): Promise { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const ledgerPayload = (this as any)._root.change(this.teaqlEntityKey()); + const mutation = { + entity: "Customer", + action: (this as any)._action, + payload: action === "Update" ? ledgerPayload : this.teaqlMutationPayload(), + id: (this as any).id, + version: (this as any).version, + comment: (this as any)._comment + ,ledgerKey: this.teaqlEntityKey() + ,ledgerRoot: (this as any)._root + }; + const request = graph.request(mutation, parent, (this as any)._comment) + .withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (action === "Update" && !(this as any)._root.hasPending(this.teaqlEntityKey())) { + const scope = request.scopeFor(this.teaqlEntityKey()); + for (const [index, child] of (this as any)._customerOrderList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.customer; + if (this.id === undefined || !child.isLoaded("customer") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateCustomer(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_order_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + return this; + } + const result = await service.executeMutation(request); + for (const [field, value] of Object.entries(mutation.payload as Record)) { + if (field !== "id" && field !== "version") (this as any)._root.set(this.teaqlEntityKey(), field, value); + } + if (!result.persistedRecord) { + throw new Error("Mutation did not return the authoritative persisted record"); + } + const rollbackState = { + payload: this.teaqlMutationPayload(), + ledgerId: (this as any)._ledgerId, + action: (this as any)._action, + loadedFields: new Set((this as any)._loadedFields), + fullyLoaded: (this as any)._fullyLoaded, + loadedSnapshot: LoadedScalarSnapshot.forEntity(this), + }; + const oldKey = this.teaqlEntityKey(); + Object.assign(this, result.persistedRecord); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + (this as any)._ledgerId = (this as any).id ?? (this as any)._ledgerId; + const newKey = this.teaqlEntityKey(); + (this as any)._root.rekey(oldKey, newKey); + service.afterGraphRollback(() => { + Object.assign(this, rollbackState.payload); + (this as any)._ledgerId = rollbackState.ledgerId; + (this as any)._action = rollbackState.action; + (this as any)._loadedFields = rollbackState.loadedFields; + (this as any)._fullyLoaded = rollbackState.fullyLoaded; + LoadedScalarSnapshot.restoreFor(this, rollbackState.loadedSnapshot); + (this as any)._root.rekey(newKey, oldKey); + }); + (this as any)._loadedFields = new Set(Object.keys(result.persistedRecord)); + (this as any)._fullyLoaded = false; + if (mutation.action !== "Delete") (this as any)._action = "Update"; + const scope = request.scopeFor(newKey); + for (const [index, child] of (this as any)._customerOrderList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.customer; + if (this.id === undefined || !child.isLoaded("customer") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateCustomer(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_order_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + service.afterGraphCommit(() => { + (this as any)._root.clearEntity(newKey); + if ((this as any).version !== undefined) (this as any)._root.acceptCommittedVersion(newKey, Number((this as any).version)); + }); + return this; + } + + private teaqlMutationPayload(): Record { + return { + "id": this.id, + "platform": this.platform, + "name": this.name, + "version": this.version + }; + } + + updateId(value: string): this { + this.id = value; + this.markLoaded("id"); + (this as any)._root.set(this.teaqlEntityKey(), "id", value); + return this; + } + + updateName(value: string): this { + this.name = value; + this.markLoaded("name"); + (this as any)._root.set(this.teaqlEntityKey(), "name", value); + return this; + } + + updateVersion(value: number): this { + this.version = value; + this.markLoaded("version"); + (this as any)._root.set(this.teaqlEntityKey(), "version", value); + return this; + } + updatePlatform(value: any): this { + this.platform = value?.id ?? value; + this.markLoaded("platform"); + (this as any)._root.set(this.teaqlEntityKey(), "platform", this.platform); + return this; + } + + customerOrderList(): SmartList { + return (this as any)._customerOrderList; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/CustomerOrder.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/CustomerOrder.ts new file mode 100644 index 0000000000000000000000000000000000000000..65bd4518b1c3caf3961f44efac213d470c1c9c5f --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/CustomerOrder.ts @@ -0,0 +1,331 @@ +import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, SmartList, TeaQLDataService, UserContext } from '../../teaql-ts'; +import { Customer } from './Customer'; +import { OrderStatus } from './OrderStatus'; +import { OrderItem } from './OrderItem'; + +export class CustomerOrder { + private static teaqlTemporaryId = 0; + id?: string; + customer?: Customer | string; + status?: OrderStatus | string; + orderNumber?: string; + orderDate?: string; + totalAmount?: number; + version?: number; + + constructor(init?: Partial) { + Object.defineProperty(this, "_action", { value: init && init.id ? "Update" : "Create", writable: true, enumerable: false }); + Object.defineProperty(this, "_comment", { value: undefined, writable: true, enumerable: false }); + Object.defineProperty(this, "_fullyLoaded", { value: !init || !init.id, writable: true, enumerable: false }); + Object.defineProperty(this, "_loadedFields", { value: new Set(Object.keys(init || {})), writable: true, enumerable: false }); + Object.defineProperty(this, "_root", { value: new EntityRoot(), writable: true, enumerable: false }); + Object.defineProperty(this, "_ledgerId", { value: init?.id ?? --CustomerOrder.teaqlTemporaryId, writable: true, enumerable: false }); + Object.defineProperty(this, "_orderItemList", { value: init?.id ? SmartList.empty() : new SmartList(), writable: true, enumerable: false }); + if (init) { + const fields: Record = { ...(init as Record) }; + delete fields["orderItemList"]; + Object.assign(this, fields); + if ((init as any).customer && typeof (init as any).customer === "object") { + this.customer = (init as any).customer instanceof Customer + ? (init as any).customer + : Customer.fromRecord((init as any).customer); + this.markLoaded("customer"); + } + if ((init as any).status && typeof (init as any).status === "object") { + this.status = (init as any).status instanceof OrderStatus + ? (init as any).status + : OrderStatus.fromRecord((init as any).status); + this.markLoaded("status"); + } + if (Array.isArray((init as any).orderItemList)) { + const selected = (init as any).orderItemList; + (this as any)._orderItemList = new SmartList(selected.map( + (child: unknown) => child instanceof OrderItem + ? child + : OrderItem.fromRecord(child as Record), + ), { totalCount: selected.totalCount, aggregations: selected.aggregations, + summary: selected.summary, facets: selected.facets, isLoaded: selected.isLoaded ?? true }); + this.markLoaded("orderItemList"); + } + } + const key = this.teaqlEntityKey(); + if ((this as any)._action === "Create") (this as any)._root.markAsNew(key); + else if ((this as any).version !== undefined) (this as any)._root.setOriginalVersion(key, Number((this as any).version)); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + } + + private teaqlEntityKey(): EntityKey { return { entity: "CustomerOrder", id: (this as any)._ledgerId }; } + private teaqlAttachRoot(root: EntityRoot): this { + if ((this as any)._root !== root) { + root.mergeEntityFrom((this as any)._root, this.teaqlEntityKey()); + (this as any)._root = root; + } + for (const child of (this as any)._orderItemList) child.teaqlAttachRoot(root); + return this; + } + + static fromRecord(record: Record, root?: EntityRoot): CustomerOrder { + const entity = new CustomerOrder(record as Partial); + return root ? entity.teaqlAttachRoot(root) : entity; + } + + isLoaded(field: string): boolean { + return (this as any)._fullyLoaded || (this as any)._loadedFields.has(field); + } + + markLoaded(...fields: string[]): this { + for (const field of fields) (this as any)._loadedFields.add(field); + return this; + } + + markLoadedOnly(...fields: string[]): this { + (this as any)._fullyLoaded = false; + (this as any)._loadedFields = new Set(fields); + return this; + } + + static refer(id: string | number): CustomerOrder { + return new CustomerOrder({ id: String(id) } as Partial); + } + + /** @internal Generated Runtime Module fixed-ID construction capability. */ + static teaqlBootstrapNew(id: string | number): CustomerOrder { + return new CustomerOrder().updateId(String(id)); + } + + markForDeletion(): this { + (this as any)._action = "Delete"; + (this as any)._root.markAsDeleted(this.teaqlEntityKey()); + return this; + } + + auditAs(comment: string): this { + new MutationIntent(comment); + (this as any)._comment = comment; + return this; + } + + async save(context: UserContext): Promise { + const service = context.requireResource("dataService"); + return service.executeGraphSave(new MutationIntent((this as any)._comment), async (graph) => { + this.teaqlPreflightGraph(context, service, graph); + return this.teaqlSaveWithinGraph(context, service, graph); + }); + } + + /** @internal Validates and fixes the complete graph before its first mutation. */ + teaqlPreflightGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): void { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const pending = action !== "Update" || (this as any)._root.hasPending(this.teaqlEntityKey()); + if (action === "Update" && pending) { + const notLoaded = [{ member: "id", canonical: "id" }, { member: "customer", canonical: "customer" }, { member: "status", canonical: "status" }, { member: "orderNumber", canonical: "order_number" }, { member: "orderDate", canonical: "order_date" }, { member: "totalAmount", canonical: "total_amount" }, { member: "version", canonical: "version" }] + .find(field => !this.isLoaded(field.member)); + if (notLoaded) { + throw new CheckException([{ + ruleId: "invalid_type", + location: ObjectLocation.property(notLoaded.canonical), + message: "Mutation requires a fully loaded entity", + }]); + } + } + const request = graph.request({ + entity: "CustomerOrder", action, + payload: action === "Update" + ? (this as any)._root.change(this.teaqlEntityKey()) + : this.teaqlMutationPayload(), + id: (this as any).id, version: (this as any).version, + comment: (this as any)._comment, + ledgerKey: this.teaqlEntityKey(), ledgerRoot: (this as any)._root, + }, parent, (this as any)._comment).withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (pending) service.preflightMutation(request); + const scope = request.scopeFor(this.teaqlEntityKey()); + for (const [index, child] of (this as any)._orderItemList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.customerOrder; + if (this.id === undefined || !child.isLoaded("customerOrder") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateCustomerOrder(this); + try { child.teaqlPreflightGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("order_item_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + } + + /** @internal Used by generated relation cascades inside the root graph transaction. */ + async teaqlSaveWithinGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): Promise { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const ledgerPayload = (this as any)._root.change(this.teaqlEntityKey()); + const mutation = { + entity: "CustomerOrder", + action: (this as any)._action, + payload: action === "Update" ? ledgerPayload : this.teaqlMutationPayload(), + id: (this as any).id, + version: (this as any).version, + comment: (this as any)._comment + ,ledgerKey: this.teaqlEntityKey() + ,ledgerRoot: (this as any)._root + }; + const request = graph.request(mutation, parent, (this as any)._comment) + .withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (action === "Update" && !(this as any)._root.hasPending(this.teaqlEntityKey())) { + const scope = request.scopeFor(this.teaqlEntityKey()); + for (const [index, child] of (this as any)._orderItemList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.customerOrder; + if (this.id === undefined || !child.isLoaded("customerOrder") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateCustomerOrder(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("order_item_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + return this; + } + const result = await service.executeMutation(request); + for (const [field, value] of Object.entries(mutation.payload as Record)) { + if (field !== "id" && field !== "version") (this as any)._root.set(this.teaqlEntityKey(), field, value); + } + if (!result.persistedRecord) { + throw new Error("Mutation did not return the authoritative persisted record"); + } + const rollbackState = { + payload: this.teaqlMutationPayload(), + ledgerId: (this as any)._ledgerId, + action: (this as any)._action, + loadedFields: new Set((this as any)._loadedFields), + fullyLoaded: (this as any)._fullyLoaded, + loadedSnapshot: LoadedScalarSnapshot.forEntity(this), + }; + const oldKey = this.teaqlEntityKey(); + Object.assign(this, result.persistedRecord); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + (this as any)._ledgerId = (this as any).id ?? (this as any)._ledgerId; + const newKey = this.teaqlEntityKey(); + (this as any)._root.rekey(oldKey, newKey); + service.afterGraphRollback(() => { + Object.assign(this, rollbackState.payload); + (this as any)._ledgerId = rollbackState.ledgerId; + (this as any)._action = rollbackState.action; + (this as any)._loadedFields = rollbackState.loadedFields; + (this as any)._fullyLoaded = rollbackState.fullyLoaded; + LoadedScalarSnapshot.restoreFor(this, rollbackState.loadedSnapshot); + (this as any)._root.rekey(newKey, oldKey); + }); + (this as any)._loadedFields = new Set(Object.keys(result.persistedRecord)); + (this as any)._fullyLoaded = false; + if (mutation.action !== "Delete") (this as any)._action = "Update"; + const scope = request.scopeFor(newKey); + for (const [index, child] of (this as any)._orderItemList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.customerOrder; + if (this.id === undefined || !child.isLoaded("customerOrder") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateCustomerOrder(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("order_item_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + service.afterGraphCommit(() => { + (this as any)._root.clearEntity(newKey); + if ((this as any).version !== undefined) (this as any)._root.acceptCommittedVersion(newKey, Number((this as any).version)); + }); + return this; + } + + private teaqlMutationPayload(): Record { + return { + "id": this.id, + "customer": this.customer, + "status": this.status, + "order_number": this.orderNumber, + "order_date": this.orderDate, + "total_amount": this.totalAmount, + "version": this.version + }; + } + + updateId(value: string): this { + this.id = value; + this.markLoaded("id"); + (this as any)._root.set(this.teaqlEntityKey(), "id", value); + return this; + } + + updateOrderNumber(value: string): this { + this.orderNumber = value; + this.markLoaded("orderNumber"); + (this as any)._root.set(this.teaqlEntityKey(), "order_number", value); + return this; + } + + updateOrderDate(value: string): this { + this.orderDate = value; + this.markLoaded("orderDate"); + (this as any)._root.set(this.teaqlEntityKey(), "order_date", value); + return this; + } + + updateTotalAmount(value: number): this { + this.totalAmount = value; + this.markLoaded("totalAmount"); + (this as any)._root.set(this.teaqlEntityKey(), "total_amount", value); + return this; + } + + updateVersion(value: number): this { + this.version = value; + this.markLoaded("version"); + (this as any)._root.set(this.teaqlEntityKey(), "version", value); + return this; + } + updateCustomer(value: any): this { + this.customer = value?.id ?? value; + this.markLoaded("customer"); + (this as any)._root.set(this.teaqlEntityKey(), "customer", this.customer); + return this; + } + + + updateStatus(value: any): this { + this.status = value?.id ?? value; + this.markLoaded("status"); + (this as any)._root.set(this.teaqlEntityKey(), "status", this.status); + return this; + } + public updateStatusToNew(): CustomerOrder { + this.status = "1001"; + this.markLoaded("status"); + (this as any)._root.set(this.teaqlEntityKey(), "status", this.status); + return this; + } + public updateStatusToPaid(): CustomerOrder { + this.status = "1002"; + this.markLoaded("status"); + (this as any)._root.set(this.teaqlEntityKey(), "status", this.status); + return this; + } + public updateStatusToCancelled(): CustomerOrder { + this.status = "1003"; + this.markLoaded("status"); + (this as any)._root.set(this.teaqlEntityKey(), "status", this.status); + return this; + } + + orderItemList(): SmartList { + return (this as any)._orderItemList; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/OrderItem.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/OrderItem.ts new file mode 100644 index 0000000000000000000000000000000000000000..901988e62f05d076f079539423513df14036e512 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/OrderItem.ts @@ -0,0 +1,237 @@ +import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, SmartList, TeaQLDataService, UserContext } from '../../teaql-ts'; +import { CustomerOrder } from './CustomerOrder'; + +export class OrderItem { + private static teaqlTemporaryId = 0; + id?: string; + customerOrder?: CustomerOrder | string; + productName?: string; + quantity?: number; + unitPrice?: number; + version?: number; + + constructor(init?: Partial) { + Object.defineProperty(this, "_action", { value: init && init.id ? "Update" : "Create", writable: true, enumerable: false }); + Object.defineProperty(this, "_comment", { value: undefined, writable: true, enumerable: false }); + Object.defineProperty(this, "_fullyLoaded", { value: !init || !init.id, writable: true, enumerable: false }); + Object.defineProperty(this, "_loadedFields", { value: new Set(Object.keys(init || {})), writable: true, enumerable: false }); + Object.defineProperty(this, "_root", { value: new EntityRoot(), writable: true, enumerable: false }); + Object.defineProperty(this, "_ledgerId", { value: init?.id ?? --OrderItem.teaqlTemporaryId, writable: true, enumerable: false }); + if (init) { + const fields: Record = { ...(init as Record) }; + Object.assign(this, fields); + if ((init as any).customerOrder && typeof (init as any).customerOrder === "object") { + this.customerOrder = (init as any).customerOrder instanceof CustomerOrder + ? (init as any).customerOrder + : CustomerOrder.fromRecord((init as any).customerOrder); + this.markLoaded("customerOrder"); + } + } + const key = this.teaqlEntityKey(); + if ((this as any)._action === "Create") (this as any)._root.markAsNew(key); + else if ((this as any).version !== undefined) (this as any)._root.setOriginalVersion(key, Number((this as any).version)); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + } + + private teaqlEntityKey(): EntityKey { return { entity: "OrderItem", id: (this as any)._ledgerId }; } + private teaqlAttachRoot(root: EntityRoot): this { + if ((this as any)._root !== root) { + root.mergeEntityFrom((this as any)._root, this.teaqlEntityKey()); + (this as any)._root = root; + } + return this; + } + + static fromRecord(record: Record, root?: EntityRoot): OrderItem { + const entity = new OrderItem(record as Partial); + return root ? entity.teaqlAttachRoot(root) : entity; + } + + isLoaded(field: string): boolean { + return (this as any)._fullyLoaded || (this as any)._loadedFields.has(field); + } + + markLoaded(...fields: string[]): this { + for (const field of fields) (this as any)._loadedFields.add(field); + return this; + } + + markLoadedOnly(...fields: string[]): this { + (this as any)._fullyLoaded = false; + (this as any)._loadedFields = new Set(fields); + return this; + } + + static refer(id: string | number): OrderItem { + return new OrderItem({ id: String(id) } as Partial); + } + + /** @internal Generated Runtime Module fixed-ID construction capability. */ + static teaqlBootstrapNew(id: string | number): OrderItem { + return new OrderItem().updateId(String(id)); + } + + markForDeletion(): this { + (this as any)._action = "Delete"; + (this as any)._root.markAsDeleted(this.teaqlEntityKey()); + return this; + } + + auditAs(comment: string): this { + new MutationIntent(comment); + (this as any)._comment = comment; + return this; + } + + async save(context: UserContext): Promise { + const service = context.requireResource("dataService"); + return service.executeGraphSave(new MutationIntent((this as any)._comment), async (graph) => { + this.teaqlPreflightGraph(context, service, graph); + return this.teaqlSaveWithinGraph(context, service, graph); + }); + } + + /** @internal Validates and fixes the complete graph before its first mutation. */ + teaqlPreflightGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): void { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const pending = action !== "Update" || (this as any)._root.hasPending(this.teaqlEntityKey()); + if (action === "Update" && pending) { + const notLoaded = [{ member: "id", canonical: "id" }, { member: "customerOrder", canonical: "customer_order" }, { member: "productName", canonical: "product_name" }, { member: "quantity", canonical: "quantity" }, { member: "unitPrice", canonical: "unit_price" }, { member: "version", canonical: "version" }] + .find(field => !this.isLoaded(field.member)); + if (notLoaded) { + throw new CheckException([{ + ruleId: "invalid_type", + location: ObjectLocation.property(notLoaded.canonical), + message: "Mutation requires a fully loaded entity", + }]); + } + } + const request = graph.request({ + entity: "OrderItem", action, + payload: action === "Update" + ? (this as any)._root.change(this.teaqlEntityKey()) + : this.teaqlMutationPayload(), + id: (this as any).id, version: (this as any).version, + comment: (this as any)._comment, + ledgerKey: this.teaqlEntityKey(), ledgerRoot: (this as any)._root, + }, parent, (this as any)._comment).withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (pending) service.preflightMutation(request); + const scope = request.scopeFor(this.teaqlEntityKey()); + } + + /** @internal Used by generated relation cascades inside the root graph transaction. */ + async teaqlSaveWithinGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): Promise { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const ledgerPayload = (this as any)._root.change(this.teaqlEntityKey()); + const mutation = { + entity: "OrderItem", + action: (this as any)._action, + payload: action === "Update" ? ledgerPayload : this.teaqlMutationPayload(), + id: (this as any).id, + version: (this as any).version, + comment: (this as any)._comment + ,ledgerKey: this.teaqlEntityKey() + ,ledgerRoot: (this as any)._root + }; + const request = graph.request(mutation, parent, (this as any)._comment) + .withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (action === "Update" && !(this as any)._root.hasPending(this.teaqlEntityKey())) { + const scope = request.scopeFor(this.teaqlEntityKey()); + return this; + } + const result = await service.executeMutation(request); + for (const [field, value] of Object.entries(mutation.payload as Record)) { + if (field !== "id" && field !== "version") (this as any)._root.set(this.teaqlEntityKey(), field, value); + } + if (!result.persistedRecord) { + throw new Error("Mutation did not return the authoritative persisted record"); + } + const rollbackState = { + payload: this.teaqlMutationPayload(), + ledgerId: (this as any)._ledgerId, + action: (this as any)._action, + loadedFields: new Set((this as any)._loadedFields), + fullyLoaded: (this as any)._fullyLoaded, + loadedSnapshot: LoadedScalarSnapshot.forEntity(this), + }; + const oldKey = this.teaqlEntityKey(); + Object.assign(this, result.persistedRecord); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + (this as any)._ledgerId = (this as any).id ?? (this as any)._ledgerId; + const newKey = this.teaqlEntityKey(); + (this as any)._root.rekey(oldKey, newKey); + service.afterGraphRollback(() => { + Object.assign(this, rollbackState.payload); + (this as any)._ledgerId = rollbackState.ledgerId; + (this as any)._action = rollbackState.action; + (this as any)._loadedFields = rollbackState.loadedFields; + (this as any)._fullyLoaded = rollbackState.fullyLoaded; + LoadedScalarSnapshot.restoreFor(this, rollbackState.loadedSnapshot); + (this as any)._root.rekey(newKey, oldKey); + }); + (this as any)._loadedFields = new Set(Object.keys(result.persistedRecord)); + (this as any)._fullyLoaded = false; + if (mutation.action !== "Delete") (this as any)._action = "Update"; + const scope = request.scopeFor(newKey); + service.afterGraphCommit(() => { + (this as any)._root.clearEntity(newKey); + if ((this as any).version !== undefined) (this as any)._root.acceptCommittedVersion(newKey, Number((this as any).version)); + }); + return this; + } + + private teaqlMutationPayload(): Record { + return { + "id": this.id, + "customer_order": this.customerOrder, + "product_name": this.productName, + "quantity": this.quantity, + "unit_price": this.unitPrice, + "version": this.version + }; + } + + updateId(value: string): this { + this.id = value; + this.markLoaded("id"); + (this as any)._root.set(this.teaqlEntityKey(), "id", value); + return this; + } + + updateProductName(value: string): this { + this.productName = value; + this.markLoaded("productName"); + (this as any)._root.set(this.teaqlEntityKey(), "product_name", value); + return this; + } + + updateQuantity(value: number): this { + this.quantity = value; + this.markLoaded("quantity"); + (this as any)._root.set(this.teaqlEntityKey(), "quantity", value); + return this; + } + + updateUnitPrice(value: number): this { + this.unitPrice = value; + this.markLoaded("unitPrice"); + (this as any)._root.set(this.teaqlEntityKey(), "unit_price", value); + return this; + } + + updateVersion(value: number): this { + this.version = value; + this.markLoaded("version"); + (this as any)._root.set(this.teaqlEntityKey(), "version", value); + return this; + } + updateCustomerOrder(value: any): this { + this.customerOrder = value?.id ?? value; + this.markLoaded("customerOrder"); + (this as any)._root.set(this.teaqlEntityKey(), "customer_order", this.customerOrder); + return this; + } + +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/OrderStatus.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/OrderStatus.ts new file mode 100644 index 0000000000000000000000000000000000000000..e590f39c38b8ff37ff59724b3f99592813b7dd48 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/OrderStatus.ts @@ -0,0 +1,305 @@ +import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, SmartList, TeaQLDataService, UserContext } from '../../teaql-ts'; +import { Platform } from './Platform'; +import { CustomerOrder } from './CustomerOrder'; + +export class OrderStatus { + private static teaqlTemporaryId = 0; + platform?: Platform | string; + id?: string; + name?: string; + code?: string; + color?: string; + displayOrder?: number; + version?: number; + + constructor(init?: Partial) { + Object.defineProperty(this, "_action", { value: init && init.id ? "Update" : "Create", writable: true, enumerable: false }); + Object.defineProperty(this, "_comment", { value: undefined, writable: true, enumerable: false }); + Object.defineProperty(this, "_fullyLoaded", { value: !init || !init.id, writable: true, enumerable: false }); + Object.defineProperty(this, "_loadedFields", { value: new Set(Object.keys(init || {})), writable: true, enumerable: false }); + Object.defineProperty(this, "_root", { value: new EntityRoot(), writable: true, enumerable: false }); + Object.defineProperty(this, "_ledgerId", { value: init?.id ?? --OrderStatus.teaqlTemporaryId, writable: true, enumerable: false }); + Object.defineProperty(this, "_customerOrderList", { value: init?.id ? SmartList.empty() : new SmartList(), writable: true, enumerable: false }); + if (init) { + const fields: Record = { ...(init as Record) }; + delete fields["customerOrderList"]; + Object.assign(this, fields); + if ((init as any).platform && typeof (init as any).platform === "object") { + this.platform = (init as any).platform instanceof Platform + ? (init as any).platform + : Platform.fromRecord((init as any).platform); + this.markLoaded("platform"); + } + if (Array.isArray((init as any).customerOrderList)) { + const selected = (init as any).customerOrderList; + (this as any)._customerOrderList = new SmartList(selected.map( + (child: unknown) => child instanceof CustomerOrder + ? child + : CustomerOrder.fromRecord(child as Record), + ), { totalCount: selected.totalCount, aggregations: selected.aggregations, + summary: selected.summary, facets: selected.facets, isLoaded: selected.isLoaded ?? true }); + this.markLoaded("customerOrderList"); + } + } + const key = this.teaqlEntityKey(); + if ((this as any)._action === "Create") (this as any)._root.markAsNew(key); + else if ((this as any).version !== undefined) (this as any)._root.setOriginalVersion(key, Number((this as any).version)); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + } + + private teaqlEntityKey(): EntityKey { return { entity: "OrderStatus", id: (this as any)._ledgerId }; } + private teaqlAttachRoot(root: EntityRoot): this { + if ((this as any)._root !== root) { + root.mergeEntityFrom((this as any)._root, this.teaqlEntityKey()); + (this as any)._root = root; + } + for (const child of (this as any)._customerOrderList) child.teaqlAttachRoot(root); + return this; + } + + static fromRecord(record: Record, root?: EntityRoot): OrderStatus { + const entity = new OrderStatus(record as Partial); + return root ? entity.teaqlAttachRoot(root) : entity; + } + + isLoaded(field: string): boolean { + return (this as any)._fullyLoaded || (this as any)._loadedFields.has(field); + } + + markLoaded(...fields: string[]): this { + for (const field of fields) (this as any)._loadedFields.add(field); + return this; + } + + markLoadedOnly(...fields: string[]): this { + (this as any)._fullyLoaded = false; + (this as any)._loadedFields = new Set(fields); + return this; + } + + static refer(id: string | number): OrderStatus { + return new OrderStatus({ id: String(id) } as Partial); + } + + /** @internal Generated Runtime Module fixed-ID construction capability. */ + static teaqlBootstrapNew(id: string | number): OrderStatus { + return new OrderStatus().updateId(String(id)); + } + + markForDeletion(): this { + (this as any)._action = "Delete"; + (this as any)._root.markAsDeleted(this.teaqlEntityKey()); + return this; + } + + auditAs(comment: string): this { + new MutationIntent(comment); + (this as any)._comment = comment; + return this; + } + + async save(context: UserContext): Promise { + const service = context.requireResource("dataService"); + return service.executeGraphSave(new MutationIntent((this as any)._comment), async (graph) => { + this.teaqlPreflightGraph(context, service, graph); + return this.teaqlSaveWithinGraph(context, service, graph); + }); + } + + /** @internal Validates and fixes the complete graph before its first mutation. */ + teaqlPreflightGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): void { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const pending = action !== "Update" || (this as any)._root.hasPending(this.teaqlEntityKey()); + if (action === "Update" && pending) { + const notLoaded = [{ member: "platform", canonical: "platform" }, { member: "id", canonical: "id" }, { member: "name", canonical: "name" }, { member: "code", canonical: "code" }, { member: "color", canonical: "color" }, { member: "displayOrder", canonical: "display_order" }, { member: "version", canonical: "version" }] + .find(field => !this.isLoaded(field.member)); + if (notLoaded) { + throw new CheckException([{ + ruleId: "invalid_type", + location: ObjectLocation.property(notLoaded.canonical), + message: "Mutation requires a fully loaded entity", + }]); + } + } + const request = graph.request({ + entity: "OrderStatus", action, + payload: action === "Update" + ? (this as any)._root.change(this.teaqlEntityKey()) + : this.teaqlMutationPayload(), + id: (this as any).id, version: (this as any).version, + comment: (this as any)._comment, + ledgerKey: this.teaqlEntityKey(), ledgerRoot: (this as any)._root, + }, parent, (this as any)._comment).withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (pending) service.preflightMutation(request); + const scope = request.scopeFor(this.teaqlEntityKey()); + for (const [index, child] of (this as any)._customerOrderList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.status; + if (this.id === undefined || !child.isLoaded("status") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateStatus(this); + try { child.teaqlPreflightGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_order_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + } + + /** @internal Used by generated relation cascades inside the root graph transaction. */ + async teaqlSaveWithinGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): Promise { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const ledgerPayload = (this as any)._root.change(this.teaqlEntityKey()); + const mutation = { + entity: "OrderStatus", + action: (this as any)._action, + payload: action === "Update" ? ledgerPayload : this.teaqlMutationPayload(), + id: (this as any).id, + version: (this as any).version, + comment: (this as any)._comment + ,ledgerKey: this.teaqlEntityKey() + ,ledgerRoot: (this as any)._root + }; + const request = graph.request(mutation, parent, (this as any)._comment) + .withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (action === "Update" && !(this as any)._root.hasPending(this.teaqlEntityKey())) { + const scope = request.scopeFor(this.teaqlEntityKey()); + for (const [index, child] of (this as any)._customerOrderList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.status; + if (this.id === undefined || !child.isLoaded("status") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateStatus(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_order_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + return this; + } + const result = await service.executeMutation(request); + for (const [field, value] of Object.entries(mutation.payload as Record)) { + if (field !== "id" && field !== "version") (this as any)._root.set(this.teaqlEntityKey(), field, value); + } + if (!result.persistedRecord) { + throw new Error("Mutation did not return the authoritative persisted record"); + } + const rollbackState = { + payload: this.teaqlMutationPayload(), + ledgerId: (this as any)._ledgerId, + action: (this as any)._action, + loadedFields: new Set((this as any)._loadedFields), + fullyLoaded: (this as any)._fullyLoaded, + loadedSnapshot: LoadedScalarSnapshot.forEntity(this), + }; + const oldKey = this.teaqlEntityKey(); + Object.assign(this, result.persistedRecord); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + (this as any)._ledgerId = (this as any).id ?? (this as any)._ledgerId; + const newKey = this.teaqlEntityKey(); + (this as any)._root.rekey(oldKey, newKey); + service.afterGraphRollback(() => { + Object.assign(this, rollbackState.payload); + (this as any)._ledgerId = rollbackState.ledgerId; + (this as any)._action = rollbackState.action; + (this as any)._loadedFields = rollbackState.loadedFields; + (this as any)._fullyLoaded = rollbackState.fullyLoaded; + LoadedScalarSnapshot.restoreFor(this, rollbackState.loadedSnapshot); + (this as any)._root.rekey(newKey, oldKey); + }); + (this as any)._loadedFields = new Set(Object.keys(result.persistedRecord)); + (this as any)._fullyLoaded = false; + if (mutation.action !== "Delete") (this as any)._action = "Update"; + const scope = request.scopeFor(newKey); + for (const [index, child] of (this as any)._customerOrderList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.status; + if (this.id === undefined || !child.isLoaded("status") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updateStatus(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_order_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + service.afterGraphCommit(() => { + (this as any)._root.clearEntity(newKey); + if ((this as any).version !== undefined) (this as any)._root.acceptCommittedVersion(newKey, Number((this as any).version)); + }); + return this; + } + + private teaqlMutationPayload(): Record { + return { + "platform": this.platform, + "id": this.id, + "name": this.name, + "code": this.code, + "color": this.color, + "display_order": this.displayOrder, + "version": this.version + }; + } + + updateId(value: string): this { + this.id = value; + this.markLoaded("id"); + (this as any)._root.set(this.teaqlEntityKey(), "id", value); + return this; + } + + updateName(value: string): this { + this.name = value; + this.markLoaded("name"); + (this as any)._root.set(this.teaqlEntityKey(), "name", value); + return this; + } + + updateCode(value: string): this { + this.code = value; + this.markLoaded("code"); + (this as any)._root.set(this.teaqlEntityKey(), "code", value); + return this; + } + + updateColor(value: string): this { + this.color = value; + this.markLoaded("color"); + (this as any)._root.set(this.teaqlEntityKey(), "color", value); + return this; + } + + updateDisplayOrder(value: number): this { + this.displayOrder = value; + this.markLoaded("displayOrder"); + (this as any)._root.set(this.teaqlEntityKey(), "display_order", value); + return this; + } + + updateVersion(value: number): this { + this.version = value; + this.markLoaded("version"); + (this as any)._root.set(this.teaqlEntityKey(), "version", value); + return this; + } + updatePlatform(value: any): this { + this.platform = value?.id ?? value; + this.markLoaded("platform"); + (this as any)._root.set(this.teaqlEntityKey(), "platform", this.platform); + return this; + } + + customerOrderList(): SmartList { + return (this as any)._customerOrderList; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/Platform.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/Platform.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca2f0c835dfe23f9073d70150d528933d134a01f --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/models/Platform.ts @@ -0,0 +1,322 @@ +import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, SmartList, TeaQLDataService, UserContext } from '../../teaql-ts'; +import { OrderStatus } from './OrderStatus'; +import { Customer } from './Customer'; + +export class Platform { + private static teaqlTemporaryId = 0; + id?: string; + name?: string; + version?: number; + + constructor(init?: Partial) { + Object.defineProperty(this, "_action", { value: init && init.id ? "Update" : "Create", writable: true, enumerable: false }); + Object.defineProperty(this, "_comment", { value: undefined, writable: true, enumerable: false }); + Object.defineProperty(this, "_fullyLoaded", { value: !init || !init.id, writable: true, enumerable: false }); + Object.defineProperty(this, "_loadedFields", { value: new Set(Object.keys(init || {})), writable: true, enumerable: false }); + Object.defineProperty(this, "_root", { value: new EntityRoot(), writable: true, enumerable: false }); + Object.defineProperty(this, "_ledgerId", { value: init?.id ?? --Platform.teaqlTemporaryId, writable: true, enumerable: false }); + Object.defineProperty(this, "_orderStatusList", { value: init?.id ? SmartList.empty() : new SmartList(), writable: true, enumerable: false }); + Object.defineProperty(this, "_customerList", { value: init?.id ? SmartList.empty() : new SmartList(), writable: true, enumerable: false }); + if (init) { + const fields: Record = { ...(init as Record) }; + delete fields["orderStatusList"]; + delete fields["customerList"]; + Object.assign(this, fields); + if (Array.isArray((init as any).orderStatusList)) { + const selected = (init as any).orderStatusList; + (this as any)._orderStatusList = new SmartList(selected.map( + (child: unknown) => child instanceof OrderStatus + ? child + : OrderStatus.fromRecord(child as Record), + ), { totalCount: selected.totalCount, aggregations: selected.aggregations, + summary: selected.summary, facets: selected.facets, isLoaded: selected.isLoaded ?? true }); + this.markLoaded("orderStatusList"); + } + if (Array.isArray((init as any).customerList)) { + const selected = (init as any).customerList; + (this as any)._customerList = new SmartList(selected.map( + (child: unknown) => child instanceof Customer + ? child + : Customer.fromRecord(child as Record), + ), { totalCount: selected.totalCount, aggregations: selected.aggregations, + summary: selected.summary, facets: selected.facets, isLoaded: selected.isLoaded ?? true }); + this.markLoaded("customerList"); + } + } + const key = this.teaqlEntityKey(); + if ((this as any)._action === "Create") (this as any)._root.markAsNew(key); + else if ((this as any).version !== undefined) (this as any)._root.setOriginalVersion(key, Number((this as any).version)); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + } + + private teaqlEntityKey(): EntityKey { return { entity: "Platform", id: (this as any)._ledgerId }; } + private teaqlAttachRoot(root: EntityRoot): this { + if ((this as any)._root !== root) { + root.mergeEntityFrom((this as any)._root, this.teaqlEntityKey()); + (this as any)._root = root; + } + for (const child of (this as any)._orderStatusList) child.teaqlAttachRoot(root); + for (const child of (this as any)._customerList) child.teaqlAttachRoot(root); + return this; + } + + static fromRecord(record: Record, root?: EntityRoot): Platform { + const entity = new Platform(record as Partial); + return root ? entity.teaqlAttachRoot(root) : entity; + } + + isLoaded(field: string): boolean { + return (this as any)._fullyLoaded || (this as any)._loadedFields.has(field); + } + + markLoaded(...fields: string[]): this { + for (const field of fields) (this as any)._loadedFields.add(field); + return this; + } + + markLoadedOnly(...fields: string[]): this { + (this as any)._fullyLoaded = false; + (this as any)._loadedFields = new Set(fields); + return this; + } + + static refer(id: string | number): Platform { + return new Platform({ id: String(id) } as Partial); + } + + /** @internal Generated Runtime Module fixed-ID construction capability. */ + static teaqlBootstrapNew(id: string | number): Platform { + return new Platform().updateId(String(id)); + } + + markForDeletion(): this { + (this as any)._action = "Delete"; + (this as any)._root.markAsDeleted(this.teaqlEntityKey()); + return this; + } + + auditAs(comment: string): this { + new MutationIntent(comment); + (this as any)._comment = comment; + return this; + } + + async save(context: UserContext): Promise { + const service = context.requireResource("dataService"); + return service.executeGraphSave(new MutationIntent((this as any)._comment), async (graph) => { + this.teaqlPreflightGraph(context, service, graph); + return this.teaqlSaveWithinGraph(context, service, graph); + }); + } + + /** @internal Validates and fixes the complete graph before its first mutation. */ + teaqlPreflightGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): void { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const pending = action !== "Update" || (this as any)._root.hasPending(this.teaqlEntityKey()); + if (action === "Update" && pending) { + const notLoaded = [{ member: "id", canonical: "id" }, { member: "name", canonical: "name" }, { member: "version", canonical: "version" }] + .find(field => !this.isLoaded(field.member)); + if (notLoaded) { + throw new CheckException([{ + ruleId: "invalid_type", + location: ObjectLocation.property(notLoaded.canonical), + message: "Mutation requires a fully loaded entity", + }]); + } + } + const request = graph.request({ + entity: "Platform", action, + payload: action === "Update" + ? (this as any)._root.change(this.teaqlEntityKey()) + : this.teaqlMutationPayload(), + id: (this as any).id, version: (this as any).version, + comment: (this as any)._comment, + ledgerKey: this.teaqlEntityKey(), ledgerRoot: (this as any)._root, + }, parent, (this as any)._comment).withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (pending) service.preflightMutation(request); + const scope = request.scopeFor(this.teaqlEntityKey()); + for (const [index, child] of (this as any)._orderStatusList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.platform; + if (this.id === undefined || !child.isLoaded("platform") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updatePlatform(this); + try { child.teaqlPreflightGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("order_status_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + for (const [index, child] of (this as any)._customerList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.platform; + if (this.id === undefined || !child.isLoaded("platform") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updatePlatform(this); + try { child.teaqlPreflightGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + } + + /** @internal Used by generated relation cascades inside the root graph transaction. */ + async teaqlSaveWithinGraph(context: UserContext, service: TeaQLDataService, graph: GraphMutationSession, parent?: MutationTraceScope): Promise { + if (!parent) new MutationIntent((this as any)._comment); + const action = (this as any)._action; + const ledgerPayload = (this as any)._root.change(this.teaqlEntityKey()); + const mutation = { + entity: "Platform", + action: (this as any)._action, + payload: action === "Update" ? ledgerPayload : this.teaqlMutationPayload(), + id: (this as any).id, + version: (this as any).version, + comment: (this as any)._comment + ,ledgerKey: this.teaqlEntityKey() + ,ledgerRoot: (this as any)._root + }; + const request = graph.request(mutation, parent, (this as any)._comment) + .withLoadedSnapshot(LoadedScalarSnapshot.forEntity(this) ?? new LoadedScalarSnapshot()); + if (action === "Update" && !(this as any)._root.hasPending(this.teaqlEntityKey())) { + const scope = request.scopeFor(this.teaqlEntityKey()); + for (const [index, child] of (this as any)._orderStatusList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.platform; + if (this.id === undefined || !child.isLoaded("platform") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updatePlatform(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("order_status_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + for (const [index, child] of (this as any)._customerList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.platform; + if (this.id === undefined || !child.isLoaded("platform") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updatePlatform(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + return this; + } + const result = await service.executeMutation(request); + for (const [field, value] of Object.entries(mutation.payload as Record)) { + if (field !== "id" && field !== "version") (this as any)._root.set(this.teaqlEntityKey(), field, value); + } + if (!result.persistedRecord) { + throw new Error("Mutation did not return the authoritative persisted record"); + } + const rollbackState = { + payload: this.teaqlMutationPayload(), + ledgerId: (this as any)._ledgerId, + action: (this as any)._action, + loadedFields: new Set((this as any)._loadedFields), + fullyLoaded: (this as any)._fullyLoaded, + loadedSnapshot: LoadedScalarSnapshot.forEntity(this), + }; + const oldKey = this.teaqlEntityKey(); + Object.assign(this, result.persistedRecord); + LoadedScalarSnapshot.captureFor(this, this.teaqlMutationPayload()); + (this as any)._ledgerId = (this as any).id ?? (this as any)._ledgerId; + const newKey = this.teaqlEntityKey(); + (this as any)._root.rekey(oldKey, newKey); + service.afterGraphRollback(() => { + Object.assign(this, rollbackState.payload); + (this as any)._ledgerId = rollbackState.ledgerId; + (this as any)._action = rollbackState.action; + (this as any)._loadedFields = rollbackState.loadedFields; + (this as any)._fullyLoaded = rollbackState.fullyLoaded; + LoadedScalarSnapshot.restoreFor(this, rollbackState.loadedSnapshot); + (this as any)._root.rekey(newKey, oldKey); + }); + (this as any)._loadedFields = new Set(Object.keys(result.persistedRecord)); + (this as any)._fullyLoaded = false; + if (mutation.action !== "Delete") (this as any)._action = "Update"; + const scope = request.scopeFor(newKey); + for (const [index, child] of (this as any)._orderStatusList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.platform; + if (this.id === undefined || !child.isLoaded("platform") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updatePlatform(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("order_status_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + for (const [index, child] of (this as any)._customerList.entries()) { + child.teaqlAttachRoot((this as any)._root); + const currentParent = child.platform; + if (this.id === undefined || !child.isLoaded("platform") || (typeof currentParent === "object" && currentParent !== null + ? currentParent.id : currentParent) !== this.id) child.updatePlatform(this); + try { await child.teaqlSaveWithinGraph(context, service, graph, scope); } + catch (error) { + if (!(error instanceof CheckException)) throw error; + const prefix = ObjectLocation.property("customer_list").index(index); + throw new CheckException(error.violations.map(violation => ({ + ...violation, location: violation.location.prefixedBy(prefix), + }))); + } + } + service.afterGraphCommit(() => { + (this as any)._root.clearEntity(newKey); + if ((this as any).version !== undefined) (this as any)._root.acceptCommittedVersion(newKey, Number((this as any).version)); + }); + return this; + } + + private teaqlMutationPayload(): Record { + return { + "id": this.id, + "name": this.name, + "version": this.version + }; + } + + updateId(value: string): this { + this.id = value; + this.markLoaded("id"); + (this as any)._root.set(this.teaqlEntityKey(), "id", value); + return this; + } + + updateName(value: string): this { + this.name = value; + this.markLoaded("name"); + (this as any)._root.set(this.teaqlEntityKey(), "name", value); + return this; + } + + updateVersion(value: number): this { + this.version = value; + this.markLoaded("version"); + (this as any)._root.set(this.teaqlEntityKey(), "version", value); + return this; + } + orderStatusList(): SmartList { + return (this as any)._orderStatusList; + } + + customerList(): SmartList { + return (this as any)._customerList; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/CustomerOrderRequest.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/CustomerOrderRequest.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc34d5b0fb8cd552f7899440dc9dd8e4557d1b2f --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/CustomerOrderRequest.ts @@ -0,0 +1,1194 @@ +import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, UserContext, executeRelationFacets } from '../../teaql-ts'; +import { CustomerOrder } from '../models/CustomerOrder'; +import { mergeGeneratedScalarSearch, DynamicSearchWarning, QueryIntent } from 'teaql-ts'; +import { GENERATED_SEARCH_MODELS } from '../../generated-search-models'; + + + +export class CustomerOrderRequest { + private query: SelectQuery; + private filters: any[] = []; + private _purpose: string | undefined; + private _comment: string | undefined; + private _pageCountAlias: string | undefined; + private _pageCountMethod: "count" | "countAs" | undefined; + private _dynamicSearchWarnings: DynamicSearchWarning[] = []; + + constructor(minimal = false) { + this.query = new SelectQuery("CustomerOrder"); + this.filters.push({ version: { "$gte": 1 } }); + if (minimal) { + this.selectId(); + this.selectVersion(); + } + else this.selectSelfFields(); + } + + comment(c: string): this { + this.query.comment(c); + this._comment = c; + return this; + } + + filterByJson(source: unknown, warn?: (warning: DynamicSearchWarning) => void): this { + const base = this.query.clone(); + if (this.filters.length > 0) base.filter({ "$and": this.filters }); + const merged = mergeGeneratedScalarSearch(base, source, GENERATED_SEARCH_MODELS, warn); + this.query = merged.query as SelectQuery; + this.filters = this.query.filterCondition ? [this.query.filterCondition] : []; + this._dynamicSearchWarnings.push(...merged.warnings); + return this; + } + + get dynamicSearchWarnings(): readonly DynamicSearchWarning[] { + return this._dynamicSearchWarnings.map(warning => ({ ...warning })); + } + + purpose(p: string): ExecutableCustomerOrderRequest { + this.query.purpose(p); + this._purpose = p; + return new ExecutableCustomerOrderRequest( + (context) => context.withQueryRequest(this.query, () => this.executeForListInternal(context)), + (context) => context.withQueryRequest(this.query, () => this.executeForRowsInternal(context)), + (context, chunkSize) => this.executeForStreamInternal(context, chunkSize), + () => this.limit(1), + (c) => this.comment(c), + () => this.ensureIntent()); + } + + optimizeForContinuousPageFetch(): this { + this.query.optimizeForContinuousPageFetch(); + return this; + } + + optimizeForContinuousPageFetchWith(namespace: string, ttlSeconds: number): this { + this.query.optimizeForContinuousPageFetchWith(namespace, ttlSeconds); + return this; + } + + optimizePaginationWithIdSet(): this { + this.query.optimizePaginationWithIdSet(); + return this; + } + + optimizePaginationWithIdSetConfig(namespace: string, ttlSeconds: number, maxIds: number): this { + this.query.optimizePaginationWithIdSetConfig(namespace, ttlSeconds, maxIds); + return this; + } + + topNProbeParentThreshold(threshold: number): this { + this.query.topNProbeParentThreshold(threshold); + return this; + } + + limit(n: number): this { + this.query.limit(n); + return this; + } + + offset(n: number): this { + this.query.offset(n); + return this; + } + + toQuery(): SelectQuery { + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + return this.query; + } + + withDeletedRows(): this { + this.filters = this.filters.filter(filter => !("version" in filter)); + return this; + } + + deletedRowsOnly(): this { + this.withDeletedRows(); + this.filters.push({ version: { "$lte": -1 } }); + return this; + } + + selectSelfFields(): this { + this.query.select(["id", "customer", "status", "orderNumber", "orderDate", "totalAmount", "version"]); + return this; + } + + selectId(): this { + this.query.select(["id"]); + return this; + } + + + + selectOrderNumber(): this { + this.query.select(["orderNumber"]); + return this; + } + + selectOrderDate(): this { + this.query.select(["orderDate"]); + return this; + } + + selectTotalAmount(): this { + this.query.select(["totalAmount"]); + return this; + } + + selectVersion(): this { + this.query.select(["version"]); + return this; + } + + + selectCustomerWith(request: { toQuery(): SelectQuery }): this { + this.query.select(["customer"]); + this.query.relationQuery( + "customer", request.toQuery(), "customer", "id", false, + { kind: "relation-select", method: "selectCustomerWith", relation: "customer" }); + return this; + } + selectStatusWith(request: { toQuery(): SelectQuery }): this { + this.query.select(["status"]); + this.query.relationQuery( + "status", request.toQuery(), "status", "id", false, + { kind: "relation-select", method: "selectStatusWith", relation: "status" }); + return this; + } + + withCustomerMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "customer": { + "$inSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + withoutCustomerMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "customer": { + "$notInSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + withStatusMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "status": { + "$inSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + withoutStatusMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "status": { + "$notInSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + selectOrderItemListWith(request: { toQuery(): SelectQuery }): this { + this.query.relationQuery( + "orderItemList", request.toQuery(), "id", "customerOrder", true, + { kind: "relation-select", method: "selectOrderItemListWith", relation: "orderItemList" }); + return this; + } + + haveOrderItems(): this { + return this.withOrderItemListMatching({ + toQuery: () => new SelectQuery("OrderItem"), + }); + } + + haveNoOrderItems(): this { + return this.withoutOrderItemListMatching({ + toQuery: () => new SelectQuery("OrderItem"), + }); + } + + withOrderItemListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$inSubquery": { + query: request.toQuery(), field: "customerOrder", + }, + }, + }); + return this; + } + + withoutOrderItemListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$notInSubquery": { + query: request.toQuery(), field: "customerOrder", + }, + }, + }); + return this; + } + + countOrderItems(): this { + return this.countOrderItemsAs("countOrderItems"); + } + + countOrderItemsAs(alias: string): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + this.countOrderItemsWith(alias, { toQuery: () => query }); + this.query.relationAggregates[this.query.relationAggregates.length - 1].operation = { + kind: "relation-count", method: "countOrderItemsAs", relation: "orderItemList", alias }; + return this; + } + + countOrderItemsWith(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("Count", "id", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "relation-count", method: "countOrderItemsWith", relation: "orderItemList", alias }); + return this; + } + + minQuantityOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.minQuantityOfOrderItemsAs( + "minOfQuantityOfOrderItems", { toQuery: () => query }); + } + + minQuantityOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("min", "quantity", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "minQuantityOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + maxQuantityOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.maxQuantityOfOrderItemsAs( + "maxOfQuantityOfOrderItems", { toQuery: () => query }); + } + + maxQuantityOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("max", "quantity", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "maxQuantityOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + sumQuantityOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.sumQuantityOfOrderItemsAs( + "sumOfQuantityOfOrderItems", { toQuery: () => query }); + } + + sumQuantityOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("sum", "quantity", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "sumQuantityOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + avgQuantityOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.avgQuantityOfOrderItemsAs( + "avgOfQuantityOfOrderItems", { toQuery: () => query }); + } + + avgQuantityOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("avg", "quantity", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "avgQuantityOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + standardDeviationQuantityOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.standardDeviationQuantityOfOrderItemsAs( + "standardDeviationOfQuantityOfOrderItems", { toQuery: () => query }); + } + + standardDeviationQuantityOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev", "quantity", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "standardDeviationQuantityOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + squareRootOfPopulationStandardDeviationQuantityOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs( + "squareRootOfPopulationStandardDeviationOfQuantityOfOrderItems", { toQuery: () => query }); + } + + squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev_pop", "quantity", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "squareRootOfPopulationStandardDeviationQuantityOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + sampleVarianceQuantityOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.sampleVarianceQuantityOfOrderItemsAs( + "sampleVarianceOfQuantityOfOrderItems", { toQuery: () => query }); + } + + sampleVarianceQuantityOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_samp", "quantity", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "sampleVarianceQuantityOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + samplePopulationVarianceQuantityOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.samplePopulationVarianceQuantityOfOrderItemsAs( + "samplePopulationVarianceOfQuantityOfOrderItems", { toQuery: () => query }); + } + + samplePopulationVarianceQuantityOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_pop", "quantity", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "samplePopulationVarianceQuantityOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + minUnitPriceOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.minUnitPriceOfOrderItemsAs( + "minOfUnitPriceOfOrderItems", { toQuery: () => query }); + } + + minUnitPriceOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("min", "unitPrice", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "minUnitPriceOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + maxUnitPriceOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.maxUnitPriceOfOrderItemsAs( + "maxOfUnitPriceOfOrderItems", { toQuery: () => query }); + } + + maxUnitPriceOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("max", "unitPrice", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "maxUnitPriceOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + sumUnitPriceOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.sumUnitPriceOfOrderItemsAs( + "sumOfUnitPriceOfOrderItems", { toQuery: () => query }); + } + + sumUnitPriceOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("sum", "unitPrice", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "sumUnitPriceOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + avgUnitPriceOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.avgUnitPriceOfOrderItemsAs( + "avgOfUnitPriceOfOrderItems", { toQuery: () => query }); + } + + avgUnitPriceOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("avg", "unitPrice", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "avgUnitPriceOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + standardDeviationUnitPriceOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.standardDeviationUnitPriceOfOrderItemsAs( + "standardDeviationOfUnitPriceOfOrderItems", { toQuery: () => query }); + } + + standardDeviationUnitPriceOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev", "unitPrice", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "standardDeviationUnitPriceOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + squareRootOfPopulationStandardDeviationUnitPriceOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs( + "squareRootOfPopulationStandardDeviationOfUnitPriceOfOrderItems", { toQuery: () => query }); + } + + squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev_pop", "unitPrice", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "squareRootOfPopulationStandardDeviationUnitPriceOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + sampleVarianceUnitPriceOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.sampleVarianceUnitPriceOfOrderItemsAs( + "sampleVarianceOfUnitPriceOfOrderItems", { toQuery: () => query }); + } + + sampleVarianceUnitPriceOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_samp", "unitPrice", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "sampleVarianceUnitPriceOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + samplePopulationVarianceUnitPriceOfOrderItems(): this { + const query = new SelectQuery("OrderItem").filter({ version: { "$gte": 1 } }); + return this.samplePopulationVarianceUnitPriceOfOrderItemsAs( + "samplePopulationVarianceOfUnitPriceOfOrderItems", { toQuery: () => query }); + } + + samplePopulationVarianceUnitPriceOfOrderItemsAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_pop", "unitPrice", alias); + this.query.relationAggregate("orderItemList", alias, query, true, + { kind: "aggregate", method: "samplePopulationVarianceUnitPriceOfOrderItemsAs", relation: "orderItemList", alias }); + return this; + } + + withIdIs(val: any): this { + this.filters.push({ "id": { "$eq": val } }); + return this; + } + + withIdIsNot(val: any): this { + this.filters.push({ "id": { "$ne": val } }); + return this; + } + + withIdIn(...vals: any[]): this { + this.filters.push({ "id": { "$in": vals } }); + return this; + } + + withIdNotIn(...vals: any[]): this { + this.filters.push({ "id": { "$notIn": vals } }); + return this; + } + + withIdGreaterThan(val: any): this { + this.filters.push({ "id": { "$gt": val } }); + return this; + } + + withIdGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$gte": val } }); + return this; + } + + withIdLessThan(val: any): this { + this.filters.push({ "id": { "$lt": val } }); + return this; + } + + withIdLessThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$lte": val } }); + return this; + } + + withIdBetween(lower: any, upper: any): this { + this.filters.push({ "id": { "$between": [lower, upper] } }); + return this; + } + + withIdIsKnown(): this { + this.filters.push({ "id": { "$isNull": false } }); + return this; + } + + withIdIsUnknown(): this { + this.filters.push({ "id": { "$isNull": true } }); + return this; + } + + filterByCustomer(val: any): this { + this.filters.push({ "customer": { "$eq": val } }); + return this; + } + + filterByCustomerIn(...vals: any[]): this { + this.filters.push({ "customer": { "$in": vals } }); + return this; + } + + withCustomerIsKnown(): this { + this.filters.push({ "customer": { "$isNull": false } }); + return this; + } + + withCustomerIsUnknown(): this { + this.filters.push({ "customer": { "$isNull": true } }); + return this; + } + + filterByStatus(val: any): this { + this.filters.push({ "status": { "$eq": val } }); + return this; + } + + filterByStatusIn(...vals: any[]): this { + this.filters.push({ "status": { "$in": vals } }); + return this; + } + + withStatusIsKnown(): this { + this.filters.push({ "status": { "$isNull": false } }); + return this; + } + + withStatusIsUnknown(): this { + this.filters.push({ "status": { "$isNull": true } }); + return this; + } + withStatusIsNew(): this { + this.filters.push({ "status": { "$eq": "1001" } }); + return this; + } + withStatusIsPaid(): this { + this.filters.push({ "status": { "$eq": "1002" } }); + return this; + } + withStatusIsCancelled(): this { + this.filters.push({ "status": { "$eq": "1003" } }); + return this; + } + + withOrderNumberContaining(val: string): this { + this.filters.push({ "orderNumber": { "$contains": val } }); + return this; + } + + withOrderNumberIs(val: string): this { + this.filters.push({ "orderNumber": { "$eq": val } }); + return this; + } + + withOrderNumberIsNot(val: any): this { + this.filters.push({ "orderNumber": { "$ne": val } }); + return this; + } + + withOrderNumberIn(...vals: any[]): this { + this.filters.push({ "orderNumber": { "$in": vals } }); + return this; + } + + withOrderNumberNotIn(...vals: any[]): this { + this.filters.push({ "orderNumber": { "$notIn": vals } }); + return this; + } + + withOrderNumberGreaterThan(val: any): this { + this.filters.push({ "orderNumber": { "$gt": val } }); + return this; + } + + withOrderNumberGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "orderNumber": { "$gte": val } }); + return this; + } + + withOrderNumberLessThan(val: any): this { + this.filters.push({ "orderNumber": { "$lt": val } }); + return this; + } + + withOrderNumberLessThanOrEqualTo(val: any): this { + this.filters.push({ "orderNumber": { "$lte": val } }); + return this; + } + + withOrderNumberBetween(lower: any, upper: any): this { + this.filters.push({ "orderNumber": { "$between": [lower, upper] } }); + return this; + } + + withOrderNumberIsKnown(): this { + this.filters.push({ "orderNumber": { "$isNull": false } }); + return this; + } + + withOrderNumberIsUnknown(): this { + this.filters.push({ "orderNumber": { "$isNull": true } }); + return this; + } + withOrderNumberNotContaining(val: string): this { + this.filters.push({ "orderNumber": { "$notContains": val } }); + return this; + } + + withOrderNumberStartingWith(val: string): this { + this.filters.push({ "orderNumber": { "$startsWith": val } }); + return this; + } + + withOrderNumberNotStartingWith(val: string): this { + this.filters.push({ "orderNumber": { "$notStartsWith": val } }); + return this; + } + + withOrderNumberEndingWith(val: string): this { + this.filters.push({ "orderNumber": { "$endsWith": val } }); + return this; + } + + withOrderNumberNotEndingWith(val: string): this { + this.filters.push({ "orderNumber": { "$notEndsWith": val } }); + return this; + } + + withOrderNumberSoundingLike(val: string): this { + this.filters.push({ "orderNumber": { "$soundLike": val } }); + return this; + } + + withOrderDateIs(val: any): this { + this.filters.push({ "orderDate": { "$eq": val } }); + return this; + } + + withOrderDateIsNot(val: any): this { + this.filters.push({ "orderDate": { "$ne": val } }); + return this; + } + + withOrderDateIn(...vals: any[]): this { + this.filters.push({ "orderDate": { "$in": vals } }); + return this; + } + + withOrderDateNotIn(...vals: any[]): this { + this.filters.push({ "orderDate": { "$notIn": vals } }); + return this; + } + + withOrderDateGreaterThan(val: any): this { + this.filters.push({ "orderDate": { "$gt": val } }); + return this; + } + + withOrderDateGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "orderDate": { "$gte": val } }); + return this; + } + + withOrderDateLessThan(val: any): this { + this.filters.push({ "orderDate": { "$lt": val } }); + return this; + } + + withOrderDateLessThanOrEqualTo(val: any): this { + this.filters.push({ "orderDate": { "$lte": val } }); + return this; + } + + withOrderDateBetween(lower: any, upper: any): this { + this.filters.push({ "orderDate": { "$between": [lower, upper] } }); + return this; + } + + withOrderDateIsKnown(): this { + this.filters.push({ "orderDate": { "$isNull": false } }); + return this; + } + + withOrderDateIsUnknown(): this { + this.filters.push({ "orderDate": { "$isNull": true } }); + return this; + } + + withTotalAmountIs(val: any): this { + this.filters.push({ "totalAmount": { "$eq": val } }); + return this; + } + + withTotalAmountIsNot(val: any): this { + this.filters.push({ "totalAmount": { "$ne": val } }); + return this; + } + + withTotalAmountIn(...vals: any[]): this { + this.filters.push({ "totalAmount": { "$in": vals } }); + return this; + } + + withTotalAmountNotIn(...vals: any[]): this { + this.filters.push({ "totalAmount": { "$notIn": vals } }); + return this; + } + + withTotalAmountGreaterThan(val: any): this { + this.filters.push({ "totalAmount": { "$gt": val } }); + return this; + } + + withTotalAmountGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "totalAmount": { "$gte": val } }); + return this; + } + + withTotalAmountLessThan(val: any): this { + this.filters.push({ "totalAmount": { "$lt": val } }); + return this; + } + + withTotalAmountLessThanOrEqualTo(val: any): this { + this.filters.push({ "totalAmount": { "$lte": val } }); + return this; + } + + withTotalAmountBetween(lower: any, upper: any): this { + this.filters.push({ "totalAmount": { "$between": [lower, upper] } }); + return this; + } + + withTotalAmountIsKnown(): this { + this.filters.push({ "totalAmount": { "$isNull": false } }); + return this; + } + + withTotalAmountIsUnknown(): this { + this.filters.push({ "totalAmount": { "$isNull": true } }); + return this; + } + + withVersionIs(val: any): this { + this.filters.push({ "version": { "$eq": val } }); + return this; + } + + withVersionIsNot(val: any): this { + this.filters.push({ "version": { "$ne": val } }); + return this; + } + + withVersionIn(...vals: any[]): this { + this.filters.push({ "version": { "$in": vals } }); + return this; + } + + withVersionNotIn(...vals: any[]): this { + this.filters.push({ "version": { "$notIn": vals } }); + return this; + } + + withVersionGreaterThan(val: any): this { + this.filters.push({ "version": { "$gt": val } }); + return this; + } + + withVersionGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$gte": val } }); + return this; + } + + withVersionLessThan(val: any): this { + this.filters.push({ "version": { "$lt": val } }); + return this; + } + + withVersionLessThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$lte": val } }); + return this; + } + + withVersionBetween(lower: any, upper: any): this { + this.filters.push({ "version": { "$between": [lower, upper] } }); + return this; + } + + withVersionIsKnown(): this { + this.filters.push({ "version": { "$isNull": false } }); + return this; + } + + withVersionIsUnknown(): this { + this.filters.push({ "version": { "$isNull": true } }); + return this; + } + + orderByIdAscending(): this { + this.query.orderBy("id", "asc"); + return this; + } + + orderByIdDescending(): this { + this.query.orderBy("id", "desc"); + return this; + } + + + + orderByOrderNumberAscending(): this { + this.query.orderBy("orderNumber", "asc"); + return this; + } + + orderByOrderNumberDescending(): this { + this.query.orderBy("orderNumber", "desc"); + return this; + } + + orderByOrderDateAscending(): this { + this.query.orderBy("orderDate", "asc"); + return this; + } + + orderByOrderDateDescending(): this { + this.query.orderBy("orderDate", "desc"); + return this; + } + + orderByTotalAmountAscending(): this { + this.query.orderBy("totalAmount", "asc"); + return this; + } + + orderByTotalAmountDescending(): this { + this.query.orderBy("totalAmount", "desc"); + return this; + } + + orderByVersionAscending(): this { + this.query.orderBy("version", "asc"); + return this; + } + + orderByVersionDescending(): this { + this.query.orderBy("version", "desc"); + return this; + } + + + // --- Aggregations --- + count(): this { + this.query.aggregate("Count", "id", "count"); + this._pageCountAlias = "count"; + this._pageCountMethod = "count"; + return this; + } + + countAs(retName: string): this { + this.query.aggregate("Count", "id", retName); + this._pageCountAlias = retName; + this._pageCountMethod = "countAs"; + return this; + } + + minTotalAmount(): this { + return this.minTotalAmountAs("minOfTotalAmount"); + } + + minTotalAmountAs(retName: string): this { + this.query.aggregate("min", "totalAmount", retName); + return this; + } + maxTotalAmount(): this { + return this.maxTotalAmountAs("maxOfTotalAmount"); + } + + maxTotalAmountAs(retName: string): this { + this.query.aggregate("max", "totalAmount", retName); + return this; + } + sumTotalAmount(): this { + return this.sumTotalAmountAs("sumOfTotalAmount"); + } + + sumTotalAmountAs(retName: string): this { + this.query.aggregate("sum", "totalAmount", retName); + return this; + } + avgTotalAmount(): this { + return this.avgTotalAmountAs("avgOfTotalAmount"); + } + + avgTotalAmountAs(retName: string): this { + this.query.aggregate("avg", "totalAmount", retName); + return this; + } + standardDeviationTotalAmount(): this { + return this.standardDeviationTotalAmountAs("standardDeviationOfTotalAmount"); + } + + standardDeviationTotalAmountAs(retName: string): this { + this.query.aggregate("stddev", "totalAmount", retName); + return this; + } + squareRootOfPopulationStandardDeviationTotalAmount(): this { + return this.squareRootOfPopulationStandardDeviationTotalAmountAs("squareRootOfPopulationStandardDeviationOfTotalAmount"); + } + + squareRootOfPopulationStandardDeviationTotalAmountAs(retName: string): this { + this.query.aggregate("stddev_pop", "totalAmount", retName); + return this; + } + sampleVarianceTotalAmount(): this { + return this.sampleVarianceTotalAmountAs("sampleVarianceOfTotalAmount"); + } + + sampleVarianceTotalAmountAs(retName: string): this { + this.query.aggregate("var_samp", "totalAmount", retName); + return this; + } + samplePopulationVarianceTotalAmount(): this { + return this.samplePopulationVarianceTotalAmountAs("samplePopulationVarianceOfTotalAmount"); + } + + samplePopulationVarianceTotalAmountAs(retName: string): this { + this.query.aggregate("var_pop", "totalAmount", retName); + return this; + } + + // --- Group By --- + groupById(): this { + this.query.groupBy("id"); + return this; + } + + groupByIdAs(retName: string): this { + this.query.groupBy("id"); // In TS we don't alias group by yet natively + return this; + } + groupByCustomer(): this { + this.query.groupBy("customer"); + return this; + } + + groupByCustomerAs(retName: string): this { + this.query.groupBy("customer"); // In TS we don't alias group by yet natively + return this; + } + groupByStatus(): this { + this.query.groupBy("status"); + return this; + } + + groupByStatusAs(retName: string): this { + this.query.groupBy("status"); // In TS we don't alias group by yet natively + return this; + } + groupByOrderNumber(): this { + this.query.groupBy("orderNumber"); + return this; + } + + groupByOrderNumberAs(retName: string): this { + this.query.groupBy("orderNumber"); // In TS we don't alias group by yet natively + return this; + } + groupByOrderDate(): this { + this.query.groupBy("orderDate"); + return this; + } + + groupByOrderDateAs(retName: string): this { + this.query.groupBy("orderDate"); // In TS we don't alias group by yet natively + return this; + } + groupByTotalAmount(): this { + this.query.groupBy("totalAmount"); + return this; + } + + groupByTotalAmountAs(retName: string): this { + this.query.groupBy("totalAmount"); // In TS we don't alias group by yet natively + return this; + } + groupByVersion(): this { + this.query.groupBy("version"); + return this; + } + + groupByVersionAs(retName: string): this { + this.query.groupBy("version"); // In TS we don't alias group by yet natively + return this; + } + + // --- Facets --- + facetByCustomerAs( + facetName: string, + request: { toQuery(): SelectQuery }, + includeAllFacets = true, + ): this { + this.query.facetBy(facetName, "customer", request, includeAllFacets, + { kind: "facet", method: "facetByCustomerAs", relation: "customer", alias: facetName }); + return this; + } + + facetByStatusAs( + facetName: string, + request: { toQuery(): SelectQuery }, + includeAllFacets = true, + ): this { + this.query.facetBy(facetName, "status", request, includeAllFacets, + { kind: "facet", method: "facetByStatusAs", relation: "status", alias: facetName }); + return this; + } + + + private async executeForListInternal(context: UserContext): Promise> { + this.ensureIntent(); + if (this._pageCountAlias !== undefined) return this.executeCountedListInternal(context); + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + + const service = context.requireResource("dataService"); + const rows = await service.executeQuery(context.prepareQuery(this.query)); + const aggregateOnly = this.query.aggregateItems.length > 0 && this.query.groupByItems.length === 0; + const data = aggregateOnly ? [] : rows.map((row: unknown) => + row instanceof CustomerOrder + ? row + : CustomerOrder.fromRecord(row as Record, new EntityRoot())); + const result = new SmartList(data); + if (aggregateOnly && rows[0]) Object.assign(result.aggregations, rows[0]); + + if (this.query.facets.length > 0) { + result.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), this.query, this.query.facets); + } + + return result; + } + + private async executeForRowsInternal(context: UserContext): Promise>> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + return new SmartList>( + await service.executeQuery(context.prepareQuery(this.query)) as Record[]); + } + + private async executeCountedListInternal( + context: UserContext, + ): Promise> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + const useIdSet = preparedQuery.localIdSetPaginationOptions() !== undefined; + const countOperation = { kind: "named-count" as const, + method: this._pageCountMethod ?? "count", + ...(this._pageCountMethod === "countAs" ? { alias: this._pageCountAlias } : {}) }; + const totalCountBeforeRows = useIdSet ? undefined : await service.executeCount( + preparedQuery, this._pageCountAlias, countOperation); + const pageQuery = preparedQuery.clone(); + // A page count describes the full filtered set, not an aggregate-only page row. + pageQuery.aggregateItems = pageQuery.aggregateItems.filter(item => + !(String(item.function).toLowerCase() === "count" && item.alias === this._pageCountAlias)); + const rows = await service.executeQuery(pageQuery); + const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" + ? context.idSetPaginationCount! + : (totalCountBeforeRows ?? await service.executeCount(preparedQuery, this._pageCountAlias, countOperation)); + const data = new SmartList(rows.map((row: unknown) => + row instanceof CustomerOrder + ? row + : CustomerOrder.fromRecord(row as Record, new EntityRoot()))); + data.totalCount = totalCount; + if (this._pageCountAlias !== undefined) data.aggregations[this._pageCountAlias] = totalCount; + if (this.query.facets.length > 0) { + data.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), preparedQuery, preparedQuery.facets); + } + return data; + } + + private executeForStreamInternal(context: UserContext, chunkSize: number): AsyncIterable { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + // Prepare Context and capture the runtime request before returning a lazy iterator. + const chunks = service.executeForStream(preparedQuery, chunkSize); + return (async function* () { + for await (const chunk of chunks) { + for (const entity of chunk) { + yield entity instanceof CustomerOrder + ? entity + : CustomerOrder.fromRecord(entity as Record, new EntityRoot()); + } + } + })(); + } + + private ensureIntent(): void { + // Runtime owns validation, Unicode whitespace rules and typed diagnostics. + new QueryIntent(this._comment, this._purpose); + } + +} + +export class ExecutableCustomerOrderRequest { + constructor( + private readonly execute: (context: UserContext) => Promise>, + private readonly executeRows: (context: UserContext) => Promise>>, + private readonly stream: (context: UserContext, chunkSize: number) => AsyncIterable, + private readonly limitOne: () => void, + private readonly addComment: (comment: string) => void, + private readonly ensureIntent: () => void, + ) {} + + comment(c: string): this { + this.addComment(c); + return this; + } + + newEntity(context: UserContext): CustomerOrder { + this.ensureIntent(); + return new CustomerOrder(); + } + + executeForList(context: UserContext): Promise> { + this.ensureIntent(); + return this.execute(context); + } + + executeForRows(context: UserContext): Promise>> { + this.ensureIntent(); + return this.executeRows(context); + } + + executeForStream(context: UserContext, chunkSize = 1000): AsyncIterable { + this.ensureIntent(); + return this.stream(context, chunkSize); + } + + async executeForOne(context: UserContext): Promise { + this.limitOne(); + return (await this.executeForList(context))[0]; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/CustomerRequest.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/CustomerRequest.ts new file mode 100644 index 0000000000000000000000000000000000000000..2a51eebba8d63abb2cf26fe0c5e4810032a6faa1 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/CustomerRequest.ts @@ -0,0 +1,783 @@ +import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, UserContext, executeRelationFacets } from '../../teaql-ts'; +import { Customer } from '../models/Customer'; +import { mergeGeneratedScalarSearch, DynamicSearchWarning, QueryIntent } from 'teaql-ts'; +import { GENERATED_SEARCH_MODELS } from '../../generated-search-models'; + + + +export class CustomerRequest { + private query: SelectQuery; + private filters: any[] = []; + private _purpose: string | undefined; + private _comment: string | undefined; + private _pageCountAlias: string | undefined; + private _pageCountMethod: "count" | "countAs" | undefined; + private _dynamicSearchWarnings: DynamicSearchWarning[] = []; + + constructor(minimal = false) { + this.query = new SelectQuery("Customer"); + this.filters.push({ version: { "$gte": 1 } }); + if (minimal) { + this.selectId(); + this.selectVersion(); + } + else this.selectSelfFields(); + } + + comment(c: string): this { + this.query.comment(c); + this._comment = c; + return this; + } + + filterByJson(source: unknown, warn?: (warning: DynamicSearchWarning) => void): this { + const base = this.query.clone(); + if (this.filters.length > 0) base.filter({ "$and": this.filters }); + const merged = mergeGeneratedScalarSearch(base, source, GENERATED_SEARCH_MODELS, warn); + this.query = merged.query as SelectQuery; + this.filters = this.query.filterCondition ? [this.query.filterCondition] : []; + this._dynamicSearchWarnings.push(...merged.warnings); + return this; + } + + get dynamicSearchWarnings(): readonly DynamicSearchWarning[] { + return this._dynamicSearchWarnings.map(warning => ({ ...warning })); + } + + purpose(p: string): ExecutableCustomerRequest { + this.query.purpose(p); + this._purpose = p; + return new ExecutableCustomerRequest( + (context) => context.withQueryRequest(this.query, () => this.executeForListInternal(context)), + (context) => context.withQueryRequest(this.query, () => this.executeForRowsInternal(context)), + (context, chunkSize) => this.executeForStreamInternal(context, chunkSize), + () => this.limit(1), + (c) => this.comment(c), + () => this.ensureIntent()); + } + + optimizeForContinuousPageFetch(): this { + this.query.optimizeForContinuousPageFetch(); + return this; + } + + optimizeForContinuousPageFetchWith(namespace: string, ttlSeconds: number): this { + this.query.optimizeForContinuousPageFetchWith(namespace, ttlSeconds); + return this; + } + + optimizePaginationWithIdSet(): this { + this.query.optimizePaginationWithIdSet(); + return this; + } + + optimizePaginationWithIdSetConfig(namespace: string, ttlSeconds: number, maxIds: number): this { + this.query.optimizePaginationWithIdSetConfig(namespace, ttlSeconds, maxIds); + return this; + } + + topNProbeParentThreshold(threshold: number): this { + this.query.topNProbeParentThreshold(threshold); + return this; + } + + limit(n: number): this { + this.query.limit(n); + return this; + } + + offset(n: number): this { + this.query.offset(n); + return this; + } + + toQuery(): SelectQuery { + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + return this.query; + } + + withDeletedRows(): this { + this.filters = this.filters.filter(filter => !("version" in filter)); + return this; + } + + deletedRowsOnly(): this { + this.withDeletedRows(); + this.filters.push({ version: { "$lte": -1 } }); + return this; + } + + selectSelfFields(): this { + this.query.select(["id", "platform", "name", "version"]); + return this; + } + + selectId(): this { + this.query.select(["id"]); + return this; + } + + + selectName(): this { + this.query.select(["name"]); + return this; + } + + selectVersion(): this { + this.query.select(["version"]); + return this; + } + + + selectPlatformWith(request: { toQuery(): SelectQuery }): this { + this.query.select(["platform"]); + this.query.relationQuery( + "platform", request.toQuery(), "platform", "id", false, + { kind: "relation-select", method: "selectPlatformWith", relation: "platform" }); + return this; + } + + withPlatformMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "platform": { + "$inSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + withoutPlatformMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "platform": { + "$notInSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + selectCustomerOrderListWith(request: { toQuery(): SelectQuery }): this { + this.query.relationQuery( + "customerOrderList", request.toQuery(), "id", "customer", true, + { kind: "relation-select", method: "selectCustomerOrderListWith", relation: "customerOrderList" }); + return this; + } + + haveCustomerOrders(): this { + return this.withCustomerOrderListMatching({ + toQuery: () => new SelectQuery("CustomerOrder"), + }); + } + + haveNoCustomerOrders(): this { + return this.withoutCustomerOrderListMatching({ + toQuery: () => new SelectQuery("CustomerOrder"), + }); + } + + withCustomerOrderListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$inSubquery": { + query: request.toQuery(), field: "customer", + }, + }, + }); + return this; + } + + withoutCustomerOrderListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$notInSubquery": { + query: request.toQuery(), field: "customer", + }, + }, + }); + return this; + } + + countCustomerOrders(): this { + return this.countCustomerOrdersAs("countCustomerOrders"); + } + + countCustomerOrdersAs(alias: string): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + this.countCustomerOrdersWith(alias, { toQuery: () => query }); + this.query.relationAggregates[this.query.relationAggregates.length - 1].operation = { + kind: "relation-count", method: "countCustomerOrdersAs", relation: "customerOrderList", alias }; + return this; + } + + countCustomerOrdersWith(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("Count", "id", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "relation-count", method: "countCustomerOrdersWith", relation: "customerOrderList", alias }); + return this; + } + + minTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.minTotalAmountOfCustomerOrdersAs( + "minOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + minTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("min", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "minTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + maxTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.maxTotalAmountOfCustomerOrdersAs( + "maxOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + maxTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("max", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "maxTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + sumTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.sumTotalAmountOfCustomerOrdersAs( + "sumOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + sumTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("sum", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "sumTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + avgTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.avgTotalAmountOfCustomerOrdersAs( + "avgOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + avgTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("avg", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "avgTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + standardDeviationTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.standardDeviationTotalAmountOfCustomerOrdersAs( + "standardDeviationOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + standardDeviationTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "standardDeviationTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs( + "squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev_pop", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + sampleVarianceTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.sampleVarianceTotalAmountOfCustomerOrdersAs( + "sampleVarianceOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + sampleVarianceTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_samp", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "sampleVarianceTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + samplePopulationVarianceTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs( + "samplePopulationVarianceOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + samplePopulationVarianceTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_pop", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "samplePopulationVarianceTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + + withIdIs(val: any): this { + this.filters.push({ "id": { "$eq": val } }); + return this; + } + + withIdIsNot(val: any): this { + this.filters.push({ "id": { "$ne": val } }); + return this; + } + + withIdIn(...vals: any[]): this { + this.filters.push({ "id": { "$in": vals } }); + return this; + } + + withIdNotIn(...vals: any[]): this { + this.filters.push({ "id": { "$notIn": vals } }); + return this; + } + + withIdGreaterThan(val: any): this { + this.filters.push({ "id": { "$gt": val } }); + return this; + } + + withIdGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$gte": val } }); + return this; + } + + withIdLessThan(val: any): this { + this.filters.push({ "id": { "$lt": val } }); + return this; + } + + withIdLessThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$lte": val } }); + return this; + } + + withIdBetween(lower: any, upper: any): this { + this.filters.push({ "id": { "$between": [lower, upper] } }); + return this; + } + + withIdIsKnown(): this { + this.filters.push({ "id": { "$isNull": false } }); + return this; + } + + withIdIsUnknown(): this { + this.filters.push({ "id": { "$isNull": true } }); + return this; + } + + filterByPlatform(val: any): this { + this.filters.push({ "platform": { "$eq": val } }); + return this; + } + + filterByPlatformIn(...vals: any[]): this { + this.filters.push({ "platform": { "$in": vals } }); + return this; + } + + withPlatformIsKnown(): this { + this.filters.push({ "platform": { "$isNull": false } }); + return this; + } + + withPlatformIsUnknown(): this { + this.filters.push({ "platform": { "$isNull": true } }); + return this; + } + + withNameContaining(val: string): this { + this.filters.push({ "name": { "$contains": val } }); + return this; + } + + withNameIs(val: string): this { + this.filters.push({ "name": { "$eq": val } }); + return this; + } + + withNameIsNot(val: any): this { + this.filters.push({ "name": { "$ne": val } }); + return this; + } + + withNameIn(...vals: any[]): this { + this.filters.push({ "name": { "$in": vals } }); + return this; + } + + withNameNotIn(...vals: any[]): this { + this.filters.push({ "name": { "$notIn": vals } }); + return this; + } + + withNameGreaterThan(val: any): this { + this.filters.push({ "name": { "$gt": val } }); + return this; + } + + withNameGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "name": { "$gte": val } }); + return this; + } + + withNameLessThan(val: any): this { + this.filters.push({ "name": { "$lt": val } }); + return this; + } + + withNameLessThanOrEqualTo(val: any): this { + this.filters.push({ "name": { "$lte": val } }); + return this; + } + + withNameBetween(lower: any, upper: any): this { + this.filters.push({ "name": { "$between": [lower, upper] } }); + return this; + } + + withNameIsKnown(): this { + this.filters.push({ "name": { "$isNull": false } }); + return this; + } + + withNameIsUnknown(): this { + this.filters.push({ "name": { "$isNull": true } }); + return this; + } + withNameNotContaining(val: string): this { + this.filters.push({ "name": { "$notContains": val } }); + return this; + } + + withNameStartingWith(val: string): this { + this.filters.push({ "name": { "$startsWith": val } }); + return this; + } + + withNameNotStartingWith(val: string): this { + this.filters.push({ "name": { "$notStartsWith": val } }); + return this; + } + + withNameEndingWith(val: string): this { + this.filters.push({ "name": { "$endsWith": val } }); + return this; + } + + withNameNotEndingWith(val: string): this { + this.filters.push({ "name": { "$notEndsWith": val } }); + return this; + } + + withNameSoundingLike(val: string): this { + this.filters.push({ "name": { "$soundLike": val } }); + return this; + } + + withVersionIs(val: any): this { + this.filters.push({ "version": { "$eq": val } }); + return this; + } + + withVersionIsNot(val: any): this { + this.filters.push({ "version": { "$ne": val } }); + return this; + } + + withVersionIn(...vals: any[]): this { + this.filters.push({ "version": { "$in": vals } }); + return this; + } + + withVersionNotIn(...vals: any[]): this { + this.filters.push({ "version": { "$notIn": vals } }); + return this; + } + + withVersionGreaterThan(val: any): this { + this.filters.push({ "version": { "$gt": val } }); + return this; + } + + withVersionGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$gte": val } }); + return this; + } + + withVersionLessThan(val: any): this { + this.filters.push({ "version": { "$lt": val } }); + return this; + } + + withVersionLessThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$lte": val } }); + return this; + } + + withVersionBetween(lower: any, upper: any): this { + this.filters.push({ "version": { "$between": [lower, upper] } }); + return this; + } + + withVersionIsKnown(): this { + this.filters.push({ "version": { "$isNull": false } }); + return this; + } + + withVersionIsUnknown(): this { + this.filters.push({ "version": { "$isNull": true } }); + return this; + } + + orderByIdAscending(): this { + this.query.orderBy("id", "asc"); + return this; + } + + orderByIdDescending(): this { + this.query.orderBy("id", "desc"); + return this; + } + + + orderByNameAscending(): this { + this.query.orderBy("name", "asc"); + return this; + } + + orderByNameDescending(): this { + this.query.orderBy("name", "desc"); + return this; + } + + orderByVersionAscending(): this { + this.query.orderBy("version", "asc"); + return this; + } + + orderByVersionDescending(): this { + this.query.orderBy("version", "desc"); + return this; + } + + + // --- Aggregations --- + count(): this { + this.query.aggregate("Count", "id", "count"); + this._pageCountAlias = "count"; + this._pageCountMethod = "count"; + return this; + } + + countAs(retName: string): this { + this.query.aggregate("Count", "id", retName); + this._pageCountAlias = retName; + this._pageCountMethod = "countAs"; + return this; + } + + + // --- Group By --- + groupById(): this { + this.query.groupBy("id"); + return this; + } + + groupByIdAs(retName: string): this { + this.query.groupBy("id"); // In TS we don't alias group by yet natively + return this; + } + groupByPlatform(): this { + this.query.groupBy("platform"); + return this; + } + + groupByPlatformAs(retName: string): this { + this.query.groupBy("platform"); // In TS we don't alias group by yet natively + return this; + } + groupByName(): this { + this.query.groupBy("name"); + return this; + } + + groupByNameAs(retName: string): this { + this.query.groupBy("name"); // In TS we don't alias group by yet natively + return this; + } + groupByVersion(): this { + this.query.groupBy("version"); + return this; + } + + groupByVersionAs(retName: string): this { + this.query.groupBy("version"); // In TS we don't alias group by yet natively + return this; + } + + // --- Facets --- + facetByPlatformAs( + facetName: string, + request: { toQuery(): SelectQuery }, + includeAllFacets = true, + ): this { + this.query.facetBy(facetName, "platform", request, includeAllFacets, + { kind: "facet", method: "facetByPlatformAs", relation: "platform", alias: facetName }); + return this; + } + + + private async executeForListInternal(context: UserContext): Promise> { + this.ensureIntent(); + if (this._pageCountAlias !== undefined) return this.executeCountedListInternal(context); + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + + const service = context.requireResource("dataService"); + const rows = await service.executeQuery(context.prepareQuery(this.query)); + const aggregateOnly = this.query.aggregateItems.length > 0 && this.query.groupByItems.length === 0; + const data = aggregateOnly ? [] : rows.map((row: unknown) => + row instanceof Customer + ? row + : Customer.fromRecord(row as Record, new EntityRoot())); + const result = new SmartList(data); + if (aggregateOnly && rows[0]) Object.assign(result.aggregations, rows[0]); + + if (this.query.facets.length > 0) { + result.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), this.query, this.query.facets); + } + + return result; + } + + private async executeForRowsInternal(context: UserContext): Promise>> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + return new SmartList>( + await service.executeQuery(context.prepareQuery(this.query)) as Record[]); + } + + private async executeCountedListInternal( + context: UserContext, + ): Promise> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + const useIdSet = preparedQuery.localIdSetPaginationOptions() !== undefined; + const countOperation = { kind: "named-count" as const, + method: this._pageCountMethod ?? "count", + ...(this._pageCountMethod === "countAs" ? { alias: this._pageCountAlias } : {}) }; + const totalCountBeforeRows = useIdSet ? undefined : await service.executeCount( + preparedQuery, this._pageCountAlias, countOperation); + const pageQuery = preparedQuery.clone(); + // A page count describes the full filtered set, not an aggregate-only page row. + pageQuery.aggregateItems = pageQuery.aggregateItems.filter(item => + !(String(item.function).toLowerCase() === "count" && item.alias === this._pageCountAlias)); + const rows = await service.executeQuery(pageQuery); + const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" + ? context.idSetPaginationCount! + : (totalCountBeforeRows ?? await service.executeCount(preparedQuery, this._pageCountAlias, countOperation)); + const data = new SmartList(rows.map((row: unknown) => + row instanceof Customer + ? row + : Customer.fromRecord(row as Record, new EntityRoot()))); + data.totalCount = totalCount; + if (this._pageCountAlias !== undefined) data.aggregations[this._pageCountAlias] = totalCount; + if (this.query.facets.length > 0) { + data.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), preparedQuery, preparedQuery.facets); + } + return data; + } + + private executeForStreamInternal(context: UserContext, chunkSize: number): AsyncIterable { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + // Prepare Context and capture the runtime request before returning a lazy iterator. + const chunks = service.executeForStream(preparedQuery, chunkSize); + return (async function* () { + for await (const chunk of chunks) { + for (const entity of chunk) { + yield entity instanceof Customer + ? entity + : Customer.fromRecord(entity as Record, new EntityRoot()); + } + } + })(); + } + + private ensureIntent(): void { + // Runtime owns validation, Unicode whitespace rules and typed diagnostics. + new QueryIntent(this._comment, this._purpose); + } + +} + +export class ExecutableCustomerRequest { + constructor( + private readonly execute: (context: UserContext) => Promise>, + private readonly executeRows: (context: UserContext) => Promise>>, + private readonly stream: (context: UserContext, chunkSize: number) => AsyncIterable, + private readonly limitOne: () => void, + private readonly addComment: (comment: string) => void, + private readonly ensureIntent: () => void, + ) {} + + comment(c: string): this { + this.addComment(c); + return this; + } + + newEntity(context: UserContext): Customer { + this.ensureIntent(); + return new Customer(); + } + + executeForList(context: UserContext): Promise> { + this.ensureIntent(); + return this.execute(context); + } + + executeForRows(context: UserContext): Promise>> { + this.ensureIntent(); + return this.executeRows(context); + } + + executeForStream(context: UserContext, chunkSize = 1000): AsyncIterable { + this.ensureIntent(); + return this.stream(context, chunkSize); + } + + async executeForOne(context: UserContext): Promise { + this.limitOne(); + return (await this.executeForList(context))[0]; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/OrderItemRequest.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/OrderItemRequest.ts new file mode 100644 index 0000000000000000000000000000000000000000..25e555f713a8ef73ad488af4170b407e821824a3 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/OrderItemRequest.ts @@ -0,0 +1,897 @@ +import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, UserContext, executeRelationFacets } from '../../teaql-ts'; +import { OrderItem } from '../models/OrderItem'; +import { mergeGeneratedScalarSearch, DynamicSearchWarning, QueryIntent } from 'teaql-ts'; +import { GENERATED_SEARCH_MODELS } from '../../generated-search-models'; + + + +export class OrderItemRequest { + private query: SelectQuery; + private filters: any[] = []; + private _purpose: string | undefined; + private _comment: string | undefined; + private _pageCountAlias: string | undefined; + private _pageCountMethod: "count" | "countAs" | undefined; + private _dynamicSearchWarnings: DynamicSearchWarning[] = []; + + constructor(minimal = false) { + this.query = new SelectQuery("OrderItem"); + this.filters.push({ version: { "$gte": 1 } }); + if (minimal) { + this.selectId(); + this.selectVersion(); + } + else this.selectSelfFields(); + } + + comment(c: string): this { + this.query.comment(c); + this._comment = c; + return this; + } + + filterByJson(source: unknown, warn?: (warning: DynamicSearchWarning) => void): this { + const base = this.query.clone(); + if (this.filters.length > 0) base.filter({ "$and": this.filters }); + const merged = mergeGeneratedScalarSearch(base, source, GENERATED_SEARCH_MODELS, warn); + this.query = merged.query as SelectQuery; + this.filters = this.query.filterCondition ? [this.query.filterCondition] : []; + this._dynamicSearchWarnings.push(...merged.warnings); + return this; + } + + get dynamicSearchWarnings(): readonly DynamicSearchWarning[] { + return this._dynamicSearchWarnings.map(warning => ({ ...warning })); + } + + purpose(p: string): ExecutableOrderItemRequest { + this.query.purpose(p); + this._purpose = p; + return new ExecutableOrderItemRequest( + (context) => context.withQueryRequest(this.query, () => this.executeForListInternal(context)), + (context) => context.withQueryRequest(this.query, () => this.executeForRowsInternal(context)), + (context, chunkSize) => this.executeForStreamInternal(context, chunkSize), + () => this.limit(1), + (c) => this.comment(c), + () => this.ensureIntent()); + } + + optimizeForContinuousPageFetch(): this { + this.query.optimizeForContinuousPageFetch(); + return this; + } + + optimizeForContinuousPageFetchWith(namespace: string, ttlSeconds: number): this { + this.query.optimizeForContinuousPageFetchWith(namespace, ttlSeconds); + return this; + } + + optimizePaginationWithIdSet(): this { + this.query.optimizePaginationWithIdSet(); + return this; + } + + optimizePaginationWithIdSetConfig(namespace: string, ttlSeconds: number, maxIds: number): this { + this.query.optimizePaginationWithIdSetConfig(namespace, ttlSeconds, maxIds); + return this; + } + + topNProbeParentThreshold(threshold: number): this { + this.query.topNProbeParentThreshold(threshold); + return this; + } + + limit(n: number): this { + this.query.limit(n); + return this; + } + + offset(n: number): this { + this.query.offset(n); + return this; + } + + toQuery(): SelectQuery { + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + return this.query; + } + + withDeletedRows(): this { + this.filters = this.filters.filter(filter => !("version" in filter)); + return this; + } + + deletedRowsOnly(): this { + this.withDeletedRows(); + this.filters.push({ version: { "$lte": -1 } }); + return this; + } + + selectSelfFields(): this { + this.query.select(["id", "customerOrder", "productName", "quantity", "unitPrice", "version"]); + return this; + } + + selectId(): this { + this.query.select(["id"]); + return this; + } + + + selectProductName(): this { + this.query.select(["productName"]); + return this; + } + + selectQuantity(): this { + this.query.select(["quantity"]); + return this; + } + + selectUnitPrice(): this { + this.query.select(["unitPrice"]); + return this; + } + + selectVersion(): this { + this.query.select(["version"]); + return this; + } + + + selectCustomerOrderWith(request: { toQuery(): SelectQuery }): this { + this.query.select(["customerOrder"]); + this.query.relationQuery( + "customerOrder", request.toQuery(), "customerOrder", "id", false, + { kind: "relation-select", method: "selectCustomerOrderWith", relation: "customerOrder" }); + return this; + } + + withCustomerOrderMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "customerOrder": { + "$inSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + withoutCustomerOrderMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "customerOrder": { + "$notInSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + + + + withIdIs(val: any): this { + this.filters.push({ "id": { "$eq": val } }); + return this; + } + + withIdIsNot(val: any): this { + this.filters.push({ "id": { "$ne": val } }); + return this; + } + + withIdIn(...vals: any[]): this { + this.filters.push({ "id": { "$in": vals } }); + return this; + } + + withIdNotIn(...vals: any[]): this { + this.filters.push({ "id": { "$notIn": vals } }); + return this; + } + + withIdGreaterThan(val: any): this { + this.filters.push({ "id": { "$gt": val } }); + return this; + } + + withIdGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$gte": val } }); + return this; + } + + withIdLessThan(val: any): this { + this.filters.push({ "id": { "$lt": val } }); + return this; + } + + withIdLessThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$lte": val } }); + return this; + } + + withIdBetween(lower: any, upper: any): this { + this.filters.push({ "id": { "$between": [lower, upper] } }); + return this; + } + + withIdIsKnown(): this { + this.filters.push({ "id": { "$isNull": false } }); + return this; + } + + withIdIsUnknown(): this { + this.filters.push({ "id": { "$isNull": true } }); + return this; + } + + filterByCustomerOrder(val: any): this { + this.filters.push({ "customerOrder": { "$eq": val } }); + return this; + } + + filterByCustomerOrderIn(...vals: any[]): this { + this.filters.push({ "customerOrder": { "$in": vals } }); + return this; + } + + withCustomerOrderIsKnown(): this { + this.filters.push({ "customerOrder": { "$isNull": false } }); + return this; + } + + withCustomerOrderIsUnknown(): this { + this.filters.push({ "customerOrder": { "$isNull": true } }); + return this; + } + + withProductNameContaining(val: string): this { + this.filters.push({ "productName": { "$contains": val } }); + return this; + } + + withProductNameIs(val: string): this { + this.filters.push({ "productName": { "$eq": val } }); + return this; + } + + withProductNameIsNot(val: any): this { + this.filters.push({ "productName": { "$ne": val } }); + return this; + } + + withProductNameIn(...vals: any[]): this { + this.filters.push({ "productName": { "$in": vals } }); + return this; + } + + withProductNameNotIn(...vals: any[]): this { + this.filters.push({ "productName": { "$notIn": vals } }); + return this; + } + + withProductNameGreaterThan(val: any): this { + this.filters.push({ "productName": { "$gt": val } }); + return this; + } + + withProductNameGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "productName": { "$gte": val } }); + return this; + } + + withProductNameLessThan(val: any): this { + this.filters.push({ "productName": { "$lt": val } }); + return this; + } + + withProductNameLessThanOrEqualTo(val: any): this { + this.filters.push({ "productName": { "$lte": val } }); + return this; + } + + withProductNameBetween(lower: any, upper: any): this { + this.filters.push({ "productName": { "$between": [lower, upper] } }); + return this; + } + + withProductNameIsKnown(): this { + this.filters.push({ "productName": { "$isNull": false } }); + return this; + } + + withProductNameIsUnknown(): this { + this.filters.push({ "productName": { "$isNull": true } }); + return this; + } + withProductNameNotContaining(val: string): this { + this.filters.push({ "productName": { "$notContains": val } }); + return this; + } + + withProductNameStartingWith(val: string): this { + this.filters.push({ "productName": { "$startsWith": val } }); + return this; + } + + withProductNameNotStartingWith(val: string): this { + this.filters.push({ "productName": { "$notStartsWith": val } }); + return this; + } + + withProductNameEndingWith(val: string): this { + this.filters.push({ "productName": { "$endsWith": val } }); + return this; + } + + withProductNameNotEndingWith(val: string): this { + this.filters.push({ "productName": { "$notEndsWith": val } }); + return this; + } + + withProductNameSoundingLike(val: string): this { + this.filters.push({ "productName": { "$soundLike": val } }); + return this; + } + + withQuantityIs(val: any): this { + this.filters.push({ "quantity": { "$eq": val } }); + return this; + } + + withQuantityIsNot(val: any): this { + this.filters.push({ "quantity": { "$ne": val } }); + return this; + } + + withQuantityIn(...vals: any[]): this { + this.filters.push({ "quantity": { "$in": vals } }); + return this; + } + + withQuantityNotIn(...vals: any[]): this { + this.filters.push({ "quantity": { "$notIn": vals } }); + return this; + } + + withQuantityGreaterThan(val: any): this { + this.filters.push({ "quantity": { "$gt": val } }); + return this; + } + + withQuantityGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "quantity": { "$gte": val } }); + return this; + } + + withQuantityLessThan(val: any): this { + this.filters.push({ "quantity": { "$lt": val } }); + return this; + } + + withQuantityLessThanOrEqualTo(val: any): this { + this.filters.push({ "quantity": { "$lte": val } }); + return this; + } + + withQuantityBetween(lower: any, upper: any): this { + this.filters.push({ "quantity": { "$between": [lower, upper] } }); + return this; + } + + withQuantityIsKnown(): this { + this.filters.push({ "quantity": { "$isNull": false } }); + return this; + } + + withQuantityIsUnknown(): this { + this.filters.push({ "quantity": { "$isNull": true } }); + return this; + } + + withUnitPriceIs(val: any): this { + this.filters.push({ "unitPrice": { "$eq": val } }); + return this; + } + + withUnitPriceIsNot(val: any): this { + this.filters.push({ "unitPrice": { "$ne": val } }); + return this; + } + + withUnitPriceIn(...vals: any[]): this { + this.filters.push({ "unitPrice": { "$in": vals } }); + return this; + } + + withUnitPriceNotIn(...vals: any[]): this { + this.filters.push({ "unitPrice": { "$notIn": vals } }); + return this; + } + + withUnitPriceGreaterThan(val: any): this { + this.filters.push({ "unitPrice": { "$gt": val } }); + return this; + } + + withUnitPriceGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "unitPrice": { "$gte": val } }); + return this; + } + + withUnitPriceLessThan(val: any): this { + this.filters.push({ "unitPrice": { "$lt": val } }); + return this; + } + + withUnitPriceLessThanOrEqualTo(val: any): this { + this.filters.push({ "unitPrice": { "$lte": val } }); + return this; + } + + withUnitPriceBetween(lower: any, upper: any): this { + this.filters.push({ "unitPrice": { "$between": [lower, upper] } }); + return this; + } + + withUnitPriceIsKnown(): this { + this.filters.push({ "unitPrice": { "$isNull": false } }); + return this; + } + + withUnitPriceIsUnknown(): this { + this.filters.push({ "unitPrice": { "$isNull": true } }); + return this; + } + + withVersionIs(val: any): this { + this.filters.push({ "version": { "$eq": val } }); + return this; + } + + withVersionIsNot(val: any): this { + this.filters.push({ "version": { "$ne": val } }); + return this; + } + + withVersionIn(...vals: any[]): this { + this.filters.push({ "version": { "$in": vals } }); + return this; + } + + withVersionNotIn(...vals: any[]): this { + this.filters.push({ "version": { "$notIn": vals } }); + return this; + } + + withVersionGreaterThan(val: any): this { + this.filters.push({ "version": { "$gt": val } }); + return this; + } + + withVersionGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$gte": val } }); + return this; + } + + withVersionLessThan(val: any): this { + this.filters.push({ "version": { "$lt": val } }); + return this; + } + + withVersionLessThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$lte": val } }); + return this; + } + + withVersionBetween(lower: any, upper: any): this { + this.filters.push({ "version": { "$between": [lower, upper] } }); + return this; + } + + withVersionIsKnown(): this { + this.filters.push({ "version": { "$isNull": false } }); + return this; + } + + withVersionIsUnknown(): this { + this.filters.push({ "version": { "$isNull": true } }); + return this; + } + + orderByIdAscending(): this { + this.query.orderBy("id", "asc"); + return this; + } + + orderByIdDescending(): this { + this.query.orderBy("id", "desc"); + return this; + } + + + orderByProductNameAscending(): this { + this.query.orderBy("productName", "asc"); + return this; + } + + orderByProductNameDescending(): this { + this.query.orderBy("productName", "desc"); + return this; + } + + orderByQuantityAscending(): this { + this.query.orderBy("quantity", "asc"); + return this; + } + + orderByQuantityDescending(): this { + this.query.orderBy("quantity", "desc"); + return this; + } + + orderByUnitPriceAscending(): this { + this.query.orderBy("unitPrice", "asc"); + return this; + } + + orderByUnitPriceDescending(): this { + this.query.orderBy("unitPrice", "desc"); + return this; + } + + orderByVersionAscending(): this { + this.query.orderBy("version", "asc"); + return this; + } + + orderByVersionDescending(): this { + this.query.orderBy("version", "desc"); + return this; + } + + + // --- Aggregations --- + count(): this { + this.query.aggregate("Count", "id", "count"); + this._pageCountAlias = "count"; + this._pageCountMethod = "count"; + return this; + } + + countAs(retName: string): this { + this.query.aggregate("Count", "id", retName); + this._pageCountAlias = retName; + this._pageCountMethod = "countAs"; + return this; + } + + minQuantity(): this { + return this.minQuantityAs("minOfQuantity"); + } + + minQuantityAs(retName: string): this { + this.query.aggregate("min", "quantity", retName); + return this; + } + maxQuantity(): this { + return this.maxQuantityAs("maxOfQuantity"); + } + + maxQuantityAs(retName: string): this { + this.query.aggregate("max", "quantity", retName); + return this; + } + sumQuantity(): this { + return this.sumQuantityAs("sumOfQuantity"); + } + + sumQuantityAs(retName: string): this { + this.query.aggregate("sum", "quantity", retName); + return this; + } + avgQuantity(): this { + return this.avgQuantityAs("avgOfQuantity"); + } + + avgQuantityAs(retName: string): this { + this.query.aggregate("avg", "quantity", retName); + return this; + } + standardDeviationQuantity(): this { + return this.standardDeviationQuantityAs("standardDeviationOfQuantity"); + } + + standardDeviationQuantityAs(retName: string): this { + this.query.aggregate("stddev", "quantity", retName); + return this; + } + squareRootOfPopulationStandardDeviationQuantity(): this { + return this.squareRootOfPopulationStandardDeviationQuantityAs("squareRootOfPopulationStandardDeviationOfQuantity"); + } + + squareRootOfPopulationStandardDeviationQuantityAs(retName: string): this { + this.query.aggregate("stddev_pop", "quantity", retName); + return this; + } + sampleVarianceQuantity(): this { + return this.sampleVarianceQuantityAs("sampleVarianceOfQuantity"); + } + + sampleVarianceQuantityAs(retName: string): this { + this.query.aggregate("var_samp", "quantity", retName); + return this; + } + samplePopulationVarianceQuantity(): this { + return this.samplePopulationVarianceQuantityAs("samplePopulationVarianceOfQuantity"); + } + + samplePopulationVarianceQuantityAs(retName: string): this { + this.query.aggregate("var_pop", "quantity", retName); + return this; + } + minUnitPrice(): this { + return this.minUnitPriceAs("minOfUnitPrice"); + } + + minUnitPriceAs(retName: string): this { + this.query.aggregate("min", "unitPrice", retName); + return this; + } + maxUnitPrice(): this { + return this.maxUnitPriceAs("maxOfUnitPrice"); + } + + maxUnitPriceAs(retName: string): this { + this.query.aggregate("max", "unitPrice", retName); + return this; + } + sumUnitPrice(): this { + return this.sumUnitPriceAs("sumOfUnitPrice"); + } + + sumUnitPriceAs(retName: string): this { + this.query.aggregate("sum", "unitPrice", retName); + return this; + } + avgUnitPrice(): this { + return this.avgUnitPriceAs("avgOfUnitPrice"); + } + + avgUnitPriceAs(retName: string): this { + this.query.aggregate("avg", "unitPrice", retName); + return this; + } + standardDeviationUnitPrice(): this { + return this.standardDeviationUnitPriceAs("standardDeviationOfUnitPrice"); + } + + standardDeviationUnitPriceAs(retName: string): this { + this.query.aggregate("stddev", "unitPrice", retName); + return this; + } + squareRootOfPopulationStandardDeviationUnitPrice(): this { + return this.squareRootOfPopulationStandardDeviationUnitPriceAs("squareRootOfPopulationStandardDeviationOfUnitPrice"); + } + + squareRootOfPopulationStandardDeviationUnitPriceAs(retName: string): this { + this.query.aggregate("stddev_pop", "unitPrice", retName); + return this; + } + sampleVarianceUnitPrice(): this { + return this.sampleVarianceUnitPriceAs("sampleVarianceOfUnitPrice"); + } + + sampleVarianceUnitPriceAs(retName: string): this { + this.query.aggregate("var_samp", "unitPrice", retName); + return this; + } + samplePopulationVarianceUnitPrice(): this { + return this.samplePopulationVarianceUnitPriceAs("samplePopulationVarianceOfUnitPrice"); + } + + samplePopulationVarianceUnitPriceAs(retName: string): this { + this.query.aggregate("var_pop", "unitPrice", retName); + return this; + } + + // --- Group By --- + groupById(): this { + this.query.groupBy("id"); + return this; + } + + groupByIdAs(retName: string): this { + this.query.groupBy("id"); // In TS we don't alias group by yet natively + return this; + } + groupByCustomerOrder(): this { + this.query.groupBy("customerOrder"); + return this; + } + + groupByCustomerOrderAs(retName: string): this { + this.query.groupBy("customerOrder"); // In TS we don't alias group by yet natively + return this; + } + groupByProductName(): this { + this.query.groupBy("productName"); + return this; + } + + groupByProductNameAs(retName: string): this { + this.query.groupBy("productName"); // In TS we don't alias group by yet natively + return this; + } + groupByQuantity(): this { + this.query.groupBy("quantity"); + return this; + } + + groupByQuantityAs(retName: string): this { + this.query.groupBy("quantity"); // In TS we don't alias group by yet natively + return this; + } + groupByUnitPrice(): this { + this.query.groupBy("unitPrice"); + return this; + } + + groupByUnitPriceAs(retName: string): this { + this.query.groupBy("unitPrice"); // In TS we don't alias group by yet natively + return this; + } + groupByVersion(): this { + this.query.groupBy("version"); + return this; + } + + groupByVersionAs(retName: string): this { + this.query.groupBy("version"); // In TS we don't alias group by yet natively + return this; + } + + // --- Facets --- + facetByCustomerOrderAs( + facetName: string, + request: { toQuery(): SelectQuery }, + includeAllFacets = true, + ): this { + this.query.facetBy(facetName, "customerOrder", request, includeAllFacets, + { kind: "facet", method: "facetByCustomerOrderAs", relation: "customerOrder", alias: facetName }); + return this; + } + + + private async executeForListInternal(context: UserContext): Promise> { + this.ensureIntent(); + if (this._pageCountAlias !== undefined) return this.executeCountedListInternal(context); + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + + const service = context.requireResource("dataService"); + const rows = await service.executeQuery(context.prepareQuery(this.query)); + const aggregateOnly = this.query.aggregateItems.length > 0 && this.query.groupByItems.length === 0; + const data = aggregateOnly ? [] : rows.map((row: unknown) => + row instanceof OrderItem + ? row + : OrderItem.fromRecord(row as Record, new EntityRoot())); + const result = new SmartList(data); + if (aggregateOnly && rows[0]) Object.assign(result.aggregations, rows[0]); + + if (this.query.facets.length > 0) { + result.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), this.query, this.query.facets); + } + + return result; + } + + private async executeForRowsInternal(context: UserContext): Promise>> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + return new SmartList>( + await service.executeQuery(context.prepareQuery(this.query)) as Record[]); + } + + private async executeCountedListInternal( + context: UserContext, + ): Promise> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + const useIdSet = preparedQuery.localIdSetPaginationOptions() !== undefined; + const countOperation = { kind: "named-count" as const, + method: this._pageCountMethod ?? "count", + ...(this._pageCountMethod === "countAs" ? { alias: this._pageCountAlias } : {}) }; + const totalCountBeforeRows = useIdSet ? undefined : await service.executeCount( + preparedQuery, this._pageCountAlias, countOperation); + const pageQuery = preparedQuery.clone(); + // A page count describes the full filtered set, not an aggregate-only page row. + pageQuery.aggregateItems = pageQuery.aggregateItems.filter(item => + !(String(item.function).toLowerCase() === "count" && item.alias === this._pageCountAlias)); + const rows = await service.executeQuery(pageQuery); + const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" + ? context.idSetPaginationCount! + : (totalCountBeforeRows ?? await service.executeCount(preparedQuery, this._pageCountAlias, countOperation)); + const data = new SmartList(rows.map((row: unknown) => + row instanceof OrderItem + ? row + : OrderItem.fromRecord(row as Record, new EntityRoot()))); + data.totalCount = totalCount; + if (this._pageCountAlias !== undefined) data.aggregations[this._pageCountAlias] = totalCount; + if (this.query.facets.length > 0) { + data.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), preparedQuery, preparedQuery.facets); + } + return data; + } + + private executeForStreamInternal(context: UserContext, chunkSize: number): AsyncIterable { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + // Prepare Context and capture the runtime request before returning a lazy iterator. + const chunks = service.executeForStream(preparedQuery, chunkSize); + return (async function* () { + for await (const chunk of chunks) { + for (const entity of chunk) { + yield entity instanceof OrderItem + ? entity + : OrderItem.fromRecord(entity as Record, new EntityRoot()); + } + } + })(); + } + + private ensureIntent(): void { + // Runtime owns validation, Unicode whitespace rules and typed diagnostics. + new QueryIntent(this._comment, this._purpose); + } + +} + +export class ExecutableOrderItemRequest { + constructor( + private readonly execute: (context: UserContext) => Promise>, + private readonly executeRows: (context: UserContext) => Promise>>, + private readonly stream: (context: UserContext, chunkSize: number) => AsyncIterable, + private readonly limitOne: () => void, + private readonly addComment: (comment: string) => void, + private readonly ensureIntent: () => void, + ) {} + + comment(c: string): this { + this.addComment(c); + return this; + } + + newEntity(context: UserContext): OrderItem { + this.ensureIntent(); + return new OrderItem(); + } + + executeForList(context: UserContext): Promise> { + this.ensureIntent(); + return this.execute(context); + } + + executeForRows(context: UserContext): Promise>> { + this.ensureIntent(); + return this.executeRows(context); + } + + executeForStream(context: UserContext, chunkSize = 1000): AsyncIterable { + this.ensureIntent(); + return this.stream(context, chunkSize); + } + + async executeForOne(context: UserContext): Promise { + this.limitOne(); + return (await this.executeForList(context))[0]; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/OrderStatusRequest.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/OrderStatusRequest.ts new file mode 100644 index 0000000000000000000000000000000000000000..26fa6973bc60c899419a62f0c971f92bffe7027a --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/OrderStatusRequest.ts @@ -0,0 +1,1150 @@ +import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, UserContext, executeRelationFacets } from '../../teaql-ts'; +import { OrderStatus } from '../models/OrderStatus'; +import { mergeGeneratedScalarSearch, DynamicSearchWarning, QueryIntent } from 'teaql-ts'; +import { GENERATED_SEARCH_MODELS } from '../../generated-search-models'; + + + +export class OrderStatusRequest { + private query: SelectQuery; + private filters: any[] = []; + private _purpose: string | undefined; + private _comment: string | undefined; + private _pageCountAlias: string | undefined; + private _pageCountMethod: "count" | "countAs" | undefined; + private _dynamicSearchWarnings: DynamicSearchWarning[] = []; + + constructor(minimal = false) { + this.query = new SelectQuery("OrderStatus"); + this.filters.push({ version: { "$gte": 1 } }); + if (minimal) { + this.selectId(); + this.selectVersion(); + } + else this.selectSelfFields(); + } + + comment(c: string): this { + this.query.comment(c); + this._comment = c; + return this; + } + + filterByJson(source: unknown, warn?: (warning: DynamicSearchWarning) => void): this { + const base = this.query.clone(); + if (this.filters.length > 0) base.filter({ "$and": this.filters }); + const merged = mergeGeneratedScalarSearch(base, source, GENERATED_SEARCH_MODELS, warn); + this.query = merged.query as SelectQuery; + this.filters = this.query.filterCondition ? [this.query.filterCondition] : []; + this._dynamicSearchWarnings.push(...merged.warnings); + return this; + } + + get dynamicSearchWarnings(): readonly DynamicSearchWarning[] { + return this._dynamicSearchWarnings.map(warning => ({ ...warning })); + } + + purpose(p: string): ExecutableOrderStatusRequest { + this.query.purpose(p); + this._purpose = p; + return new ExecutableOrderStatusRequest( + (context) => context.withQueryRequest(this.query, () => this.executeForListInternal(context)), + (context) => context.withQueryRequest(this.query, () => this.executeForRowsInternal(context)), + (context, chunkSize) => this.executeForStreamInternal(context, chunkSize), + () => this.limit(1), + (c) => this.comment(c), + () => this.ensureIntent()); + } + + optimizeForContinuousPageFetch(): this { + this.query.optimizeForContinuousPageFetch(); + return this; + } + + optimizeForContinuousPageFetchWith(namespace: string, ttlSeconds: number): this { + this.query.optimizeForContinuousPageFetchWith(namespace, ttlSeconds); + return this; + } + + optimizePaginationWithIdSet(): this { + this.query.optimizePaginationWithIdSet(); + return this; + } + + optimizePaginationWithIdSetConfig(namespace: string, ttlSeconds: number, maxIds: number): this { + this.query.optimizePaginationWithIdSetConfig(namespace, ttlSeconds, maxIds); + return this; + } + + topNProbeParentThreshold(threshold: number): this { + this.query.topNProbeParentThreshold(threshold); + return this; + } + + limit(n: number): this { + this.query.limit(n); + return this; + } + + offset(n: number): this { + this.query.offset(n); + return this; + } + + toQuery(): SelectQuery { + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + return this.query; + } + + withDeletedRows(): this { + this.filters = this.filters.filter(filter => !("version" in filter)); + return this; + } + + deletedRowsOnly(): this { + this.withDeletedRows(); + this.filters.push({ version: { "$lte": -1 } }); + return this; + } + + selectSelfFields(): this { + this.query.select(["platform", "id", "name", "code", "color", "displayOrder", "version"]); + return this; + } + + selectId(): this { + this.query.select(["id"]); + return this; + } + + selectName(): this { + this.query.select(["name"]); + return this; + } + + selectCode(): this { + this.query.select(["code"]); + return this; + } + + selectColor(): this { + this.query.select(["color"]); + return this; + } + + selectDisplayOrder(): this { + this.query.select(["displayOrder"]); + return this; + } + + selectVersion(): this { + this.query.select(["version"]); + return this; + } + + + selectPlatformWith(request: { toQuery(): SelectQuery }): this { + this.query.select(["platform"]); + this.query.relationQuery( + "platform", request.toQuery(), "platform", "id", false, + { kind: "relation-select", method: "selectPlatformWith", relation: "platform" }); + return this; + } + + withPlatformMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "platform": { + "$inSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + withoutPlatformMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "platform": { + "$notInSubquery": { query: request.toQuery(), field: "id" }, + }, + }); + return this; + } + + selectCustomerOrderListWith(request: { toQuery(): SelectQuery }): this { + this.query.relationQuery( + "customerOrderList", request.toQuery(), "id", "status", true, + { kind: "relation-select", method: "selectCustomerOrderListWith", relation: "customerOrderList" }); + return this; + } + + haveCustomerOrders(): this { + return this.withCustomerOrderListMatching({ + toQuery: () => new SelectQuery("CustomerOrder"), + }); + } + + haveNoCustomerOrders(): this { + return this.withoutCustomerOrderListMatching({ + toQuery: () => new SelectQuery("CustomerOrder"), + }); + } + + withCustomerOrderListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$inSubquery": { + query: request.toQuery(), field: "status", + }, + }, + }); + return this; + } + + withoutCustomerOrderListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$notInSubquery": { + query: request.toQuery(), field: "status", + }, + }, + }); + return this; + } + + countCustomerOrders(): this { + return this.countCustomerOrdersAs("countCustomerOrders"); + } + + countCustomerOrdersAs(alias: string): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + this.countCustomerOrdersWith(alias, { toQuery: () => query }); + this.query.relationAggregates[this.query.relationAggregates.length - 1].operation = { + kind: "relation-count", method: "countCustomerOrdersAs", relation: "customerOrderList", alias }; + return this; + } + + countCustomerOrdersWith(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("Count", "id", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "relation-count", method: "countCustomerOrdersWith", relation: "customerOrderList", alias }); + return this; + } + + minTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.minTotalAmountOfCustomerOrdersAs( + "minOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + minTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("min", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "minTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + maxTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.maxTotalAmountOfCustomerOrdersAs( + "maxOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + maxTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("max", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "maxTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + sumTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.sumTotalAmountOfCustomerOrdersAs( + "sumOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + sumTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("sum", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "sumTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + avgTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.avgTotalAmountOfCustomerOrdersAs( + "avgOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + avgTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("avg", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "avgTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + standardDeviationTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.standardDeviationTotalAmountOfCustomerOrdersAs( + "standardDeviationOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + standardDeviationTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "standardDeviationTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs( + "squareRootOfPopulationStandardDeviationOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev_pop", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "squareRootOfPopulationStandardDeviationTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + sampleVarianceTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.sampleVarianceTotalAmountOfCustomerOrdersAs( + "sampleVarianceOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + sampleVarianceTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_samp", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "sampleVarianceTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + samplePopulationVarianceTotalAmountOfCustomerOrders(): this { + const query = new SelectQuery("CustomerOrder").filter({ version: { "$gte": 1 } }); + return this.samplePopulationVarianceTotalAmountOfCustomerOrdersAs( + "samplePopulationVarianceOfTotalAmountOfCustomerOrders", { toQuery: () => query }); + } + + samplePopulationVarianceTotalAmountOfCustomerOrdersAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_pop", "totalAmount", alias); + this.query.relationAggregate("customerOrderList", alias, query, true, + { kind: "aggregate", method: "samplePopulationVarianceTotalAmountOfCustomerOrdersAs", relation: "customerOrderList", alias }); + return this; + } + + filterByPlatform(val: any): this { + this.filters.push({ "platform": { "$eq": val } }); + return this; + } + + filterByPlatformIn(...vals: any[]): this { + this.filters.push({ "platform": { "$in": vals } }); + return this; + } + + withPlatformIsKnown(): this { + this.filters.push({ "platform": { "$isNull": false } }); + return this; + } + + withPlatformIsUnknown(): this { + this.filters.push({ "platform": { "$isNull": true } }); + return this; + } + + withIdIs(val: any): this { + this.filters.push({ "id": { "$eq": val } }); + return this; + } + + withIdIsNot(val: any): this { + this.filters.push({ "id": { "$ne": val } }); + return this; + } + + withIdIn(...vals: any[]): this { + this.filters.push({ "id": { "$in": vals } }); + return this; + } + + withIdNotIn(...vals: any[]): this { + this.filters.push({ "id": { "$notIn": vals } }); + return this; + } + + withIdGreaterThan(val: any): this { + this.filters.push({ "id": { "$gt": val } }); + return this; + } + + withIdGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$gte": val } }); + return this; + } + + withIdLessThan(val: any): this { + this.filters.push({ "id": { "$lt": val } }); + return this; + } + + withIdLessThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$lte": val } }); + return this; + } + + withIdBetween(lower: any, upper: any): this { + this.filters.push({ "id": { "$between": [lower, upper] } }); + return this; + } + + withIdIsKnown(): this { + this.filters.push({ "id": { "$isNull": false } }); + return this; + } + + withIdIsUnknown(): this { + this.filters.push({ "id": { "$isNull": true } }); + return this; + } + + withNameContaining(val: string): this { + this.filters.push({ "name": { "$contains": val } }); + return this; + } + + withNameIs(val: string): this { + this.filters.push({ "name": { "$eq": val } }); + return this; + } + + withNameIsNot(val: any): this { + this.filters.push({ "name": { "$ne": val } }); + return this; + } + + withNameIn(...vals: any[]): this { + this.filters.push({ "name": { "$in": vals } }); + return this; + } + + withNameNotIn(...vals: any[]): this { + this.filters.push({ "name": { "$notIn": vals } }); + return this; + } + + withNameGreaterThan(val: any): this { + this.filters.push({ "name": { "$gt": val } }); + return this; + } + + withNameGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "name": { "$gte": val } }); + return this; + } + + withNameLessThan(val: any): this { + this.filters.push({ "name": { "$lt": val } }); + return this; + } + + withNameLessThanOrEqualTo(val: any): this { + this.filters.push({ "name": { "$lte": val } }); + return this; + } + + withNameBetween(lower: any, upper: any): this { + this.filters.push({ "name": { "$between": [lower, upper] } }); + return this; + } + + withNameIsKnown(): this { + this.filters.push({ "name": { "$isNull": false } }); + return this; + } + + withNameIsUnknown(): this { + this.filters.push({ "name": { "$isNull": true } }); + return this; + } + withNameNotContaining(val: string): this { + this.filters.push({ "name": { "$notContains": val } }); + return this; + } + + withNameStartingWith(val: string): this { + this.filters.push({ "name": { "$startsWith": val } }); + return this; + } + + withNameNotStartingWith(val: string): this { + this.filters.push({ "name": { "$notStartsWith": val } }); + return this; + } + + withNameEndingWith(val: string): this { + this.filters.push({ "name": { "$endsWith": val } }); + return this; + } + + withNameNotEndingWith(val: string): this { + this.filters.push({ "name": { "$notEndsWith": val } }); + return this; + } + + withNameSoundingLike(val: string): this { + this.filters.push({ "name": { "$soundLike": val } }); + return this; + } + + withCodeContaining(val: string): this { + this.filters.push({ "code": { "$contains": val } }); + return this; + } + + withCodeIs(val: string): this { + this.filters.push({ "code": { "$eq": val } }); + return this; + } + + withCodeIsNot(val: any): this { + this.filters.push({ "code": { "$ne": val } }); + return this; + } + + withCodeIn(...vals: any[]): this { + this.filters.push({ "code": { "$in": vals } }); + return this; + } + + withCodeNotIn(...vals: any[]): this { + this.filters.push({ "code": { "$notIn": vals } }); + return this; + } + + withCodeGreaterThan(val: any): this { + this.filters.push({ "code": { "$gt": val } }); + return this; + } + + withCodeGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "code": { "$gte": val } }); + return this; + } + + withCodeLessThan(val: any): this { + this.filters.push({ "code": { "$lt": val } }); + return this; + } + + withCodeLessThanOrEqualTo(val: any): this { + this.filters.push({ "code": { "$lte": val } }); + return this; + } + + withCodeBetween(lower: any, upper: any): this { + this.filters.push({ "code": { "$between": [lower, upper] } }); + return this; + } + + withCodeIsKnown(): this { + this.filters.push({ "code": { "$isNull": false } }); + return this; + } + + withCodeIsUnknown(): this { + this.filters.push({ "code": { "$isNull": true } }); + return this; + } + withCodeNotContaining(val: string): this { + this.filters.push({ "code": { "$notContains": val } }); + return this; + } + + withCodeStartingWith(val: string): this { + this.filters.push({ "code": { "$startsWith": val } }); + return this; + } + + withCodeNotStartingWith(val: string): this { + this.filters.push({ "code": { "$notStartsWith": val } }); + return this; + } + + withCodeEndingWith(val: string): this { + this.filters.push({ "code": { "$endsWith": val } }); + return this; + } + + withCodeNotEndingWith(val: string): this { + this.filters.push({ "code": { "$notEndsWith": val } }); + return this; + } + + withCodeSoundingLike(val: string): this { + this.filters.push({ "code": { "$soundLike": val } }); + return this; + } + + withColorContaining(val: string): this { + this.filters.push({ "color": { "$contains": val } }); + return this; + } + + withColorIs(val: string): this { + this.filters.push({ "color": { "$eq": val } }); + return this; + } + + withColorIsNot(val: any): this { + this.filters.push({ "color": { "$ne": val } }); + return this; + } + + withColorIn(...vals: any[]): this { + this.filters.push({ "color": { "$in": vals } }); + return this; + } + + withColorNotIn(...vals: any[]): this { + this.filters.push({ "color": { "$notIn": vals } }); + return this; + } + + withColorGreaterThan(val: any): this { + this.filters.push({ "color": { "$gt": val } }); + return this; + } + + withColorGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "color": { "$gte": val } }); + return this; + } + + withColorLessThan(val: any): this { + this.filters.push({ "color": { "$lt": val } }); + return this; + } + + withColorLessThanOrEqualTo(val: any): this { + this.filters.push({ "color": { "$lte": val } }); + return this; + } + + withColorBetween(lower: any, upper: any): this { + this.filters.push({ "color": { "$between": [lower, upper] } }); + return this; + } + + withColorIsKnown(): this { + this.filters.push({ "color": { "$isNull": false } }); + return this; + } + + withColorIsUnknown(): this { + this.filters.push({ "color": { "$isNull": true } }); + return this; + } + withColorNotContaining(val: string): this { + this.filters.push({ "color": { "$notContains": val } }); + return this; + } + + withColorStartingWith(val: string): this { + this.filters.push({ "color": { "$startsWith": val } }); + return this; + } + + withColorNotStartingWith(val: string): this { + this.filters.push({ "color": { "$notStartsWith": val } }); + return this; + } + + withColorEndingWith(val: string): this { + this.filters.push({ "color": { "$endsWith": val } }); + return this; + } + + withColorNotEndingWith(val: string): this { + this.filters.push({ "color": { "$notEndsWith": val } }); + return this; + } + + withColorSoundingLike(val: string): this { + this.filters.push({ "color": { "$soundLike": val } }); + return this; + } + + withDisplayOrderIs(val: any): this { + this.filters.push({ "displayOrder": { "$eq": val } }); + return this; + } + + withDisplayOrderIsNot(val: any): this { + this.filters.push({ "displayOrder": { "$ne": val } }); + return this; + } + + withDisplayOrderIn(...vals: any[]): this { + this.filters.push({ "displayOrder": { "$in": vals } }); + return this; + } + + withDisplayOrderNotIn(...vals: any[]): this { + this.filters.push({ "displayOrder": { "$notIn": vals } }); + return this; + } + + withDisplayOrderGreaterThan(val: any): this { + this.filters.push({ "displayOrder": { "$gt": val } }); + return this; + } + + withDisplayOrderGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "displayOrder": { "$gte": val } }); + return this; + } + + withDisplayOrderLessThan(val: any): this { + this.filters.push({ "displayOrder": { "$lt": val } }); + return this; + } + + withDisplayOrderLessThanOrEqualTo(val: any): this { + this.filters.push({ "displayOrder": { "$lte": val } }); + return this; + } + + withDisplayOrderBetween(lower: any, upper: any): this { + this.filters.push({ "displayOrder": { "$between": [lower, upper] } }); + return this; + } + + withDisplayOrderIsKnown(): this { + this.filters.push({ "displayOrder": { "$isNull": false } }); + return this; + } + + withDisplayOrderIsUnknown(): this { + this.filters.push({ "displayOrder": { "$isNull": true } }); + return this; + } + + withVersionIs(val: any): this { + this.filters.push({ "version": { "$eq": val } }); + return this; + } + + withVersionIsNot(val: any): this { + this.filters.push({ "version": { "$ne": val } }); + return this; + } + + withVersionIn(...vals: any[]): this { + this.filters.push({ "version": { "$in": vals } }); + return this; + } + + withVersionNotIn(...vals: any[]): this { + this.filters.push({ "version": { "$notIn": vals } }); + return this; + } + + withVersionGreaterThan(val: any): this { + this.filters.push({ "version": { "$gt": val } }); + return this; + } + + withVersionGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$gte": val } }); + return this; + } + + withVersionLessThan(val: any): this { + this.filters.push({ "version": { "$lt": val } }); + return this; + } + + withVersionLessThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$lte": val } }); + return this; + } + + withVersionBetween(lower: any, upper: any): this { + this.filters.push({ "version": { "$between": [lower, upper] } }); + return this; + } + + withVersionIsKnown(): this { + this.filters.push({ "version": { "$isNull": false } }); + return this; + } + + withVersionIsUnknown(): this { + this.filters.push({ "version": { "$isNull": true } }); + return this; + } + + orderByIdAscending(): this { + this.query.orderBy("id", "asc"); + return this; + } + + orderByIdDescending(): this { + this.query.orderBy("id", "desc"); + return this; + } + + orderByNameAscending(): this { + this.query.orderBy("name", "asc"); + return this; + } + + orderByNameDescending(): this { + this.query.orderBy("name", "desc"); + return this; + } + + orderByCodeAscending(): this { + this.query.orderBy("code", "asc"); + return this; + } + + orderByCodeDescending(): this { + this.query.orderBy("code", "desc"); + return this; + } + + orderByColorAscending(): this { + this.query.orderBy("color", "asc"); + return this; + } + + orderByColorDescending(): this { + this.query.orderBy("color", "desc"); + return this; + } + + orderByDisplayOrderAscending(): this { + this.query.orderBy("displayOrder", "asc"); + return this; + } + + orderByDisplayOrderDescending(): this { + this.query.orderBy("displayOrder", "desc"); + return this; + } + + orderByVersionAscending(): this { + this.query.orderBy("version", "asc"); + return this; + } + + orderByVersionDescending(): this { + this.query.orderBy("version", "desc"); + return this; + } + + + // --- Aggregations --- + count(): this { + this.query.aggregate("Count", "id", "count"); + this._pageCountAlias = "count"; + this._pageCountMethod = "count"; + return this; + } + + countAs(retName: string): this { + this.query.aggregate("Count", "id", retName); + this._pageCountAlias = retName; + this._pageCountMethod = "countAs"; + return this; + } + + minDisplayOrder(): this { + return this.minDisplayOrderAs("minOfDisplayOrder"); + } + + minDisplayOrderAs(retName: string): this { + this.query.aggregate("min", "displayOrder", retName); + return this; + } + maxDisplayOrder(): this { + return this.maxDisplayOrderAs("maxOfDisplayOrder"); + } + + maxDisplayOrderAs(retName: string): this { + this.query.aggregate("max", "displayOrder", retName); + return this; + } + sumDisplayOrder(): this { + return this.sumDisplayOrderAs("sumOfDisplayOrder"); + } + + sumDisplayOrderAs(retName: string): this { + this.query.aggregate("sum", "displayOrder", retName); + return this; + } + avgDisplayOrder(): this { + return this.avgDisplayOrderAs("avgOfDisplayOrder"); + } + + avgDisplayOrderAs(retName: string): this { + this.query.aggregate("avg", "displayOrder", retName); + return this; + } + standardDeviationDisplayOrder(): this { + return this.standardDeviationDisplayOrderAs("standardDeviationOfDisplayOrder"); + } + + standardDeviationDisplayOrderAs(retName: string): this { + this.query.aggregate("stddev", "displayOrder", retName); + return this; + } + squareRootOfPopulationStandardDeviationDisplayOrder(): this { + return this.squareRootOfPopulationStandardDeviationDisplayOrderAs("squareRootOfPopulationStandardDeviationOfDisplayOrder"); + } + + squareRootOfPopulationStandardDeviationDisplayOrderAs(retName: string): this { + this.query.aggregate("stddev_pop", "displayOrder", retName); + return this; + } + sampleVarianceDisplayOrder(): this { + return this.sampleVarianceDisplayOrderAs("sampleVarianceOfDisplayOrder"); + } + + sampleVarianceDisplayOrderAs(retName: string): this { + this.query.aggregate("var_samp", "displayOrder", retName); + return this; + } + samplePopulationVarianceDisplayOrder(): this { + return this.samplePopulationVarianceDisplayOrderAs("samplePopulationVarianceOfDisplayOrder"); + } + + samplePopulationVarianceDisplayOrderAs(retName: string): this { + this.query.aggregate("var_pop", "displayOrder", retName); + return this; + } + + // --- Group By --- + groupByPlatform(): this { + this.query.groupBy("platform"); + return this; + } + + groupByPlatformAs(retName: string): this { + this.query.groupBy("platform"); // In TS we don't alias group by yet natively + return this; + } + groupById(): this { + this.query.groupBy("id"); + return this; + } + + groupByIdAs(retName: string): this { + this.query.groupBy("id"); // In TS we don't alias group by yet natively + return this; + } + groupByName(): this { + this.query.groupBy("name"); + return this; + } + + groupByNameAs(retName: string): this { + this.query.groupBy("name"); // In TS we don't alias group by yet natively + return this; + } + groupByCode(): this { + this.query.groupBy("code"); + return this; + } + + groupByCodeAs(retName: string): this { + this.query.groupBy("code"); // In TS we don't alias group by yet natively + return this; + } + groupByColor(): this { + this.query.groupBy("color"); + return this; + } + + groupByColorAs(retName: string): this { + this.query.groupBy("color"); // In TS we don't alias group by yet natively + return this; + } + groupByDisplayOrder(): this { + this.query.groupBy("displayOrder"); + return this; + } + + groupByDisplayOrderAs(retName: string): this { + this.query.groupBy("displayOrder"); // In TS we don't alias group by yet natively + return this; + } + groupByVersion(): this { + this.query.groupBy("version"); + return this; + } + + groupByVersionAs(retName: string): this { + this.query.groupBy("version"); // In TS we don't alias group by yet natively + return this; + } + + // --- Facets --- + facetByPlatformAs( + facetName: string, + request: { toQuery(): SelectQuery }, + includeAllFacets = true, + ): this { + this.query.facetBy(facetName, "platform", request, includeAllFacets, + { kind: "facet", method: "facetByPlatformAs", relation: "platform", alias: facetName }); + return this; + } + + + private async executeForListInternal(context: UserContext): Promise> { + this.ensureIntent(); + if (this._pageCountAlias !== undefined) return this.executeCountedListInternal(context); + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + + const service = context.requireResource("dataService"); + const rows = await service.executeQuery(context.prepareQuery(this.query)); + const aggregateOnly = this.query.aggregateItems.length > 0 && this.query.groupByItems.length === 0; + const data = aggregateOnly ? [] : rows.map((row: unknown) => + row instanceof OrderStatus + ? row + : OrderStatus.fromRecord(row as Record, new EntityRoot())); + const result = new SmartList(data); + if (aggregateOnly && rows[0]) Object.assign(result.aggregations, rows[0]); + + if (this.query.facets.length > 0) { + result.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), this.query, this.query.facets); + } + + return result; + } + + private async executeForRowsInternal(context: UserContext): Promise>> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + return new SmartList>( + await service.executeQuery(context.prepareQuery(this.query)) as Record[]); + } + + private async executeCountedListInternal( + context: UserContext, + ): Promise> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + const useIdSet = preparedQuery.localIdSetPaginationOptions() !== undefined; + const countOperation = { kind: "named-count" as const, + method: this._pageCountMethod ?? "count", + ...(this._pageCountMethod === "countAs" ? { alias: this._pageCountAlias } : {}) }; + const totalCountBeforeRows = useIdSet ? undefined : await service.executeCount( + preparedQuery, this._pageCountAlias, countOperation); + const pageQuery = preparedQuery.clone(); + // A page count describes the full filtered set, not an aggregate-only page row. + pageQuery.aggregateItems = pageQuery.aggregateItems.filter(item => + !(String(item.function).toLowerCase() === "count" && item.alias === this._pageCountAlias)); + const rows = await service.executeQuery(pageQuery); + const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" + ? context.idSetPaginationCount! + : (totalCountBeforeRows ?? await service.executeCount(preparedQuery, this._pageCountAlias, countOperation)); + const data = new SmartList(rows.map((row: unknown) => + row instanceof OrderStatus + ? row + : OrderStatus.fromRecord(row as Record, new EntityRoot()))); + data.totalCount = totalCount; + if (this._pageCountAlias !== undefined) data.aggregations[this._pageCountAlias] = totalCount; + if (this.query.facets.length > 0) { + data.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), preparedQuery, preparedQuery.facets); + } + return data; + } + + private executeForStreamInternal(context: UserContext, chunkSize: number): AsyncIterable { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + // Prepare Context and capture the runtime request before returning a lazy iterator. + const chunks = service.executeForStream(preparedQuery, chunkSize); + return (async function* () { + for await (const chunk of chunks) { + for (const entity of chunk) { + yield entity instanceof OrderStatus + ? entity + : OrderStatus.fromRecord(entity as Record, new EntityRoot()); + } + } + })(); + } + + private ensureIntent(): void { + // Runtime owns validation, Unicode whitespace rules and typed diagnostics. + new QueryIntent(this._comment, this._purpose); + } + +} + +export class ExecutableOrderStatusRequest { + constructor( + private readonly execute: (context: UserContext) => Promise>, + private readonly executeRows: (context: UserContext) => Promise>>, + private readonly stream: (context: UserContext, chunkSize: number) => AsyncIterable, + private readonly limitOne: () => void, + private readonly addComment: (comment: string) => void, + private readonly ensureIntent: () => void, + ) {} + + comment(c: string): this { + this.addComment(c); + return this; + } + + newEntity(context: UserContext): OrderStatus { + this.ensureIntent(); + return new OrderStatus(); + } + + executeForList(context: UserContext): Promise> { + this.ensureIntent(); + return this.execute(context); + } + + executeForRows(context: UserContext): Promise>> { + this.ensureIntent(); + return this.executeRows(context); + } + + executeForStream(context: UserContext, chunkSize = 1000): AsyncIterable { + this.ensureIntent(); + return this.stream(context, chunkSize); + } + + async executeForOne(context: UserContext): Promise { + this.limitOne(); + return (await this.executeForList(context))[0]; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/PlatformRequest.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/PlatformRequest.ts new file mode 100644 index 0000000000000000000000000000000000000000..6f44548cc3788a1325f0307b6a8e2bc0d8d1a58a --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/generated/requests/PlatformRequest.ts @@ -0,0 +1,779 @@ +import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, UserContext, executeRelationFacets } from '../../teaql-ts'; +import { Platform } from '../models/Platform'; +import { mergeGeneratedScalarSearch, DynamicSearchWarning, QueryIntent } from 'teaql-ts'; +import { GENERATED_SEARCH_MODELS } from '../../generated-search-models'; + + + +export class PlatformRequest { + private query: SelectQuery; + private filters: any[] = []; + private _purpose: string | undefined; + private _comment: string | undefined; + private _pageCountAlias: string | undefined; + private _pageCountMethod: "count" | "countAs" | undefined; + private _dynamicSearchWarnings: DynamicSearchWarning[] = []; + + constructor(minimal = false) { + this.query = new SelectQuery("Platform"); + this.filters.push({ version: { "$gte": 1 } }); + if (minimal) { + this.selectId(); + this.selectVersion(); + } + else this.selectSelfFields(); + } + + comment(c: string): this { + this.query.comment(c); + this._comment = c; + return this; + } + + filterByJson(source: unknown, warn?: (warning: DynamicSearchWarning) => void): this { + const base = this.query.clone(); + if (this.filters.length > 0) base.filter({ "$and": this.filters }); + const merged = mergeGeneratedScalarSearch(base, source, GENERATED_SEARCH_MODELS, warn); + this.query = merged.query as SelectQuery; + this.filters = this.query.filterCondition ? [this.query.filterCondition] : []; + this._dynamicSearchWarnings.push(...merged.warnings); + return this; + } + + get dynamicSearchWarnings(): readonly DynamicSearchWarning[] { + return this._dynamicSearchWarnings.map(warning => ({ ...warning })); + } + + purpose(p: string): ExecutablePlatformRequest { + this.query.purpose(p); + this._purpose = p; + return new ExecutablePlatformRequest( + (context) => context.withQueryRequest(this.query, () => this.executeForListInternal(context)), + (context) => context.withQueryRequest(this.query, () => this.executeForRowsInternal(context)), + (context, chunkSize) => this.executeForStreamInternal(context, chunkSize), + () => this.limit(1), + (c) => this.comment(c), + () => this.ensureIntent()); + } + + optimizeForContinuousPageFetch(): this { + this.query.optimizeForContinuousPageFetch(); + return this; + } + + optimizeForContinuousPageFetchWith(namespace: string, ttlSeconds: number): this { + this.query.optimizeForContinuousPageFetchWith(namespace, ttlSeconds); + return this; + } + + optimizePaginationWithIdSet(): this { + this.query.optimizePaginationWithIdSet(); + return this; + } + + optimizePaginationWithIdSetConfig(namespace: string, ttlSeconds: number, maxIds: number): this { + this.query.optimizePaginationWithIdSetConfig(namespace, ttlSeconds, maxIds); + return this; + } + + topNProbeParentThreshold(threshold: number): this { + this.query.topNProbeParentThreshold(threshold); + return this; + } + + limit(n: number): this { + this.query.limit(n); + return this; + } + + offset(n: number): this { + this.query.offset(n); + return this; + } + + toQuery(): SelectQuery { + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + return this.query; + } + + withDeletedRows(): this { + this.filters = this.filters.filter(filter => !("version" in filter)); + return this; + } + + deletedRowsOnly(): this { + this.withDeletedRows(); + this.filters.push({ version: { "$lte": -1 } }); + return this; + } + + selectSelfFields(): this { + this.query.select(["id", "name", "version"]); + return this; + } + + selectId(): this { + this.query.select(["id"]); + return this; + } + + selectName(): this { + this.query.select(["name"]); + return this; + } + + selectVersion(): this { + this.query.select(["version"]); + return this; + } + + + + + selectOrderStatusListWith(request: { toQuery(): SelectQuery }): this { + this.query.relationQuery( + "orderStatusList", request.toQuery(), "id", "platform", true, + { kind: "relation-select", method: "selectOrderStatusListWith", relation: "orderStatusList" }); + return this; + } + selectCustomerListWith(request: { toQuery(): SelectQuery }): this { + this.query.relationQuery( + "customerList", request.toQuery(), "id", "platform", true, + { kind: "relation-select", method: "selectCustomerListWith", relation: "customerList" }); + return this; + } + + haveOrderStatuses(): this { + return this.withOrderStatusListMatching({ + toQuery: () => new SelectQuery("OrderStatus"), + }); + } + + haveNoOrderStatuses(): this { + return this.withoutOrderStatusListMatching({ + toQuery: () => new SelectQuery("OrderStatus"), + }); + } + + withOrderStatusListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$inSubquery": { + query: request.toQuery(), field: "platform", + }, + }, + }); + return this; + } + + withoutOrderStatusListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$notInSubquery": { + query: request.toQuery(), field: "platform", + }, + }, + }); + return this; + } + haveCustomers(): this { + return this.withCustomerListMatching({ + toQuery: () => new SelectQuery("Customer"), + }); + } + + haveNoCustomers(): this { + return this.withoutCustomerListMatching({ + toQuery: () => new SelectQuery("Customer"), + }); + } + + withCustomerListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$inSubquery": { + query: request.toQuery(), field: "platform", + }, + }, + }); + return this; + } + + withoutCustomerListMatching(request: { toQuery(): SelectQuery }): this { + this.filters.push({ + "id": { + "$notInSubquery": { + query: request.toQuery(), field: "platform", + }, + }, + }); + return this; + } + + countOrderStatuses(): this { + return this.countOrderStatusesAs("countOrderStatuses"); + } + + countOrderStatusesAs(alias: string): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + this.countOrderStatusesWith(alias, { toQuery: () => query }); + this.query.relationAggregates[this.query.relationAggregates.length - 1].operation = { + kind: "relation-count", method: "countOrderStatusesAs", relation: "orderStatusList", alias }; + return this; + } + + countOrderStatusesWith(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("Count", "id", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "relation-count", method: "countOrderStatusesWith", relation: "orderStatusList", alias }); + return this; + } + + minDisplayOrderOfOrderStatuses(): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + return this.minDisplayOrderOfOrderStatusesAs( + "minOfDisplayOrderOfOrderStatuses", { toQuery: () => query }); + } + + minDisplayOrderOfOrderStatusesAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("min", "displayOrder", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "aggregate", method: "minDisplayOrderOfOrderStatusesAs", relation: "orderStatusList", alias }); + return this; + } + maxDisplayOrderOfOrderStatuses(): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + return this.maxDisplayOrderOfOrderStatusesAs( + "maxOfDisplayOrderOfOrderStatuses", { toQuery: () => query }); + } + + maxDisplayOrderOfOrderStatusesAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("max", "displayOrder", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "aggregate", method: "maxDisplayOrderOfOrderStatusesAs", relation: "orderStatusList", alias }); + return this; + } + sumDisplayOrderOfOrderStatuses(): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + return this.sumDisplayOrderOfOrderStatusesAs( + "sumOfDisplayOrderOfOrderStatuses", { toQuery: () => query }); + } + + sumDisplayOrderOfOrderStatusesAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("sum", "displayOrder", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "aggregate", method: "sumDisplayOrderOfOrderStatusesAs", relation: "orderStatusList", alias }); + return this; + } + avgDisplayOrderOfOrderStatuses(): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + return this.avgDisplayOrderOfOrderStatusesAs( + "avgOfDisplayOrderOfOrderStatuses", { toQuery: () => query }); + } + + avgDisplayOrderOfOrderStatusesAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("avg", "displayOrder", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "aggregate", method: "avgDisplayOrderOfOrderStatusesAs", relation: "orderStatusList", alias }); + return this; + } + standardDeviationDisplayOrderOfOrderStatuses(): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + return this.standardDeviationDisplayOrderOfOrderStatusesAs( + "standardDeviationOfDisplayOrderOfOrderStatuses", { toQuery: () => query }); + } + + standardDeviationDisplayOrderOfOrderStatusesAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev", "displayOrder", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "aggregate", method: "standardDeviationDisplayOrderOfOrderStatusesAs", relation: "orderStatusList", alias }); + return this; + } + squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatuses(): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + return this.squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs( + "squareRootOfPopulationStandardDeviationOfDisplayOrderOfOrderStatuses", { toQuery: () => query }); + } + + squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("stddev_pop", "displayOrder", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "aggregate", method: "squareRootOfPopulationStandardDeviationDisplayOrderOfOrderStatusesAs", relation: "orderStatusList", alias }); + return this; + } + sampleVarianceDisplayOrderOfOrderStatuses(): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + return this.sampleVarianceDisplayOrderOfOrderStatusesAs( + "sampleVarianceOfDisplayOrderOfOrderStatuses", { toQuery: () => query }); + } + + sampleVarianceDisplayOrderOfOrderStatusesAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_samp", "displayOrder", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "aggregate", method: "sampleVarianceDisplayOrderOfOrderStatusesAs", relation: "orderStatusList", alias }); + return this; + } + samplePopulationVarianceDisplayOrderOfOrderStatuses(): this { + const query = new SelectQuery("OrderStatus").filter({ version: { "$gte": 1 } }); + return this.samplePopulationVarianceDisplayOrderOfOrderStatusesAs( + "samplePopulationVarianceOfDisplayOrderOfOrderStatuses", { toQuery: () => query }); + } + + samplePopulationVarianceDisplayOrderOfOrderStatusesAs(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("var_pop", "displayOrder", alias); + this.query.relationAggregate("orderStatusList", alias, query, true, + { kind: "aggregate", method: "samplePopulationVarianceDisplayOrderOfOrderStatusesAs", relation: "orderStatusList", alias }); + return this; + } + countCustomers(): this { + return this.countCustomersAs("countCustomers"); + } + + countCustomersAs(alias: string): this { + const query = new SelectQuery("Customer").filter({ version: { "$gte": 1 } }); + this.countCustomersWith(alias, { toQuery: () => query }); + this.query.relationAggregates[this.query.relationAggregates.length - 1].operation = { + kind: "relation-count", method: "countCustomersAs", relation: "customerList", alias }; + return this; + } + + countCustomersWith(alias: string, child: { toQuery(): SelectQuery }): this { + const query = child.toQuery().clone(); + query.aggregateItems = []; + query.aggregate("Count", "id", alias); + this.query.relationAggregate("customerList", alias, query, true, + { kind: "relation-count", method: "countCustomersWith", relation: "customerList", alias }); + return this; + } + + + + withIdIs(val: any): this { + this.filters.push({ "id": { "$eq": val } }); + return this; + } + + withIdIsNot(val: any): this { + this.filters.push({ "id": { "$ne": val } }); + return this; + } + + withIdIn(...vals: any[]): this { + this.filters.push({ "id": { "$in": vals } }); + return this; + } + + withIdNotIn(...vals: any[]): this { + this.filters.push({ "id": { "$notIn": vals } }); + return this; + } + + withIdGreaterThan(val: any): this { + this.filters.push({ "id": { "$gt": val } }); + return this; + } + + withIdGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$gte": val } }); + return this; + } + + withIdLessThan(val: any): this { + this.filters.push({ "id": { "$lt": val } }); + return this; + } + + withIdLessThanOrEqualTo(val: any): this { + this.filters.push({ "id": { "$lte": val } }); + return this; + } + + withIdBetween(lower: any, upper: any): this { + this.filters.push({ "id": { "$between": [lower, upper] } }); + return this; + } + + withIdIsKnown(): this { + this.filters.push({ "id": { "$isNull": false } }); + return this; + } + + withIdIsUnknown(): this { + this.filters.push({ "id": { "$isNull": true } }); + return this; + } + + withNameContaining(val: string): this { + this.filters.push({ "name": { "$contains": val } }); + return this; + } + + withNameIs(val: string): this { + this.filters.push({ "name": { "$eq": val } }); + return this; + } + + withNameIsNot(val: any): this { + this.filters.push({ "name": { "$ne": val } }); + return this; + } + + withNameIn(...vals: any[]): this { + this.filters.push({ "name": { "$in": vals } }); + return this; + } + + withNameNotIn(...vals: any[]): this { + this.filters.push({ "name": { "$notIn": vals } }); + return this; + } + + withNameGreaterThan(val: any): this { + this.filters.push({ "name": { "$gt": val } }); + return this; + } + + withNameGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "name": { "$gte": val } }); + return this; + } + + withNameLessThan(val: any): this { + this.filters.push({ "name": { "$lt": val } }); + return this; + } + + withNameLessThanOrEqualTo(val: any): this { + this.filters.push({ "name": { "$lte": val } }); + return this; + } + + withNameBetween(lower: any, upper: any): this { + this.filters.push({ "name": { "$between": [lower, upper] } }); + return this; + } + + withNameIsKnown(): this { + this.filters.push({ "name": { "$isNull": false } }); + return this; + } + + withNameIsUnknown(): this { + this.filters.push({ "name": { "$isNull": true } }); + return this; + } + withNameNotContaining(val: string): this { + this.filters.push({ "name": { "$notContains": val } }); + return this; + } + + withNameStartingWith(val: string): this { + this.filters.push({ "name": { "$startsWith": val } }); + return this; + } + + withNameNotStartingWith(val: string): this { + this.filters.push({ "name": { "$notStartsWith": val } }); + return this; + } + + withNameEndingWith(val: string): this { + this.filters.push({ "name": { "$endsWith": val } }); + return this; + } + + withNameNotEndingWith(val: string): this { + this.filters.push({ "name": { "$notEndsWith": val } }); + return this; + } + + withNameSoundingLike(val: string): this { + this.filters.push({ "name": { "$soundLike": val } }); + return this; + } + + withVersionIs(val: any): this { + this.filters.push({ "version": { "$eq": val } }); + return this; + } + + withVersionIsNot(val: any): this { + this.filters.push({ "version": { "$ne": val } }); + return this; + } + + withVersionIn(...vals: any[]): this { + this.filters.push({ "version": { "$in": vals } }); + return this; + } + + withVersionNotIn(...vals: any[]): this { + this.filters.push({ "version": { "$notIn": vals } }); + return this; + } + + withVersionGreaterThan(val: any): this { + this.filters.push({ "version": { "$gt": val } }); + return this; + } + + withVersionGreaterThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$gte": val } }); + return this; + } + + withVersionLessThan(val: any): this { + this.filters.push({ "version": { "$lt": val } }); + return this; + } + + withVersionLessThanOrEqualTo(val: any): this { + this.filters.push({ "version": { "$lte": val } }); + return this; + } + + withVersionBetween(lower: any, upper: any): this { + this.filters.push({ "version": { "$between": [lower, upper] } }); + return this; + } + + withVersionIsKnown(): this { + this.filters.push({ "version": { "$isNull": false } }); + return this; + } + + withVersionIsUnknown(): this { + this.filters.push({ "version": { "$isNull": true } }); + return this; + } + + orderByIdAscending(): this { + this.query.orderBy("id", "asc"); + return this; + } + + orderByIdDescending(): this { + this.query.orderBy("id", "desc"); + return this; + } + + orderByNameAscending(): this { + this.query.orderBy("name", "asc"); + return this; + } + + orderByNameDescending(): this { + this.query.orderBy("name", "desc"); + return this; + } + + orderByVersionAscending(): this { + this.query.orderBy("version", "asc"); + return this; + } + + orderByVersionDescending(): this { + this.query.orderBy("version", "desc"); + return this; + } + + + // --- Aggregations --- + count(): this { + this.query.aggregate("Count", "id", "count"); + this._pageCountAlias = "count"; + this._pageCountMethod = "count"; + return this; + } + + countAs(retName: string): this { + this.query.aggregate("Count", "id", retName); + this._pageCountAlias = retName; + this._pageCountMethod = "countAs"; + return this; + } + + + // --- Group By --- + groupById(): this { + this.query.groupBy("id"); + return this; + } + + groupByIdAs(retName: string): this { + this.query.groupBy("id"); // In TS we don't alias group by yet natively + return this; + } + groupByName(): this { + this.query.groupBy("name"); + return this; + } + + groupByNameAs(retName: string): this { + this.query.groupBy("name"); // In TS we don't alias group by yet natively + return this; + } + groupByVersion(): this { + this.query.groupBy("version"); + return this; + } + + groupByVersionAs(retName: string): this { + this.query.groupBy("version"); // In TS we don't alias group by yet natively + return this; + } + + // --- Facets --- + + private async executeForListInternal(context: UserContext): Promise> { + this.ensureIntent(); + if (this._pageCountAlias !== undefined) return this.executeCountedListInternal(context); + if (this.filters.length > 0) { + this.query.filter({ "$and": this.filters }); + } + + const service = context.requireResource("dataService"); + const rows = await service.executeQuery(context.prepareQuery(this.query)); + const aggregateOnly = this.query.aggregateItems.length > 0 && this.query.groupByItems.length === 0; + const data = aggregateOnly ? [] : rows.map((row: unknown) => + row instanceof Platform + ? row + : Platform.fromRecord(row as Record, new EntityRoot())); + const result = new SmartList(data); + if (aggregateOnly && rows[0]) Object.assign(result.aggregations, rows[0]); + + if (this.query.facets.length > 0) { + result.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), this.query, this.query.facets); + } + + return result; + } + + private async executeForRowsInternal(context: UserContext): Promise>> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + return new SmartList>( + await service.executeQuery(context.prepareQuery(this.query)) as Record[]); + } + + private async executeCountedListInternal( + context: UserContext, + ): Promise> { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + const useIdSet = preparedQuery.localIdSetPaginationOptions() !== undefined; + const countOperation = { kind: "named-count" as const, + method: this._pageCountMethod ?? "count", + ...(this._pageCountMethod === "countAs" ? { alias: this._pageCountAlias } : {}) }; + const totalCountBeforeRows = useIdSet ? undefined : await service.executeCount( + preparedQuery, this._pageCountAlias, countOperation); + const pageQuery = preparedQuery.clone(); + // A page count describes the full filtered set, not an aggregate-only page row. + pageQuery.aggregateItems = pageQuery.aggregateItems.filter(item => + !(String(item.function).toLowerCase() === "count" && item.alias === this._pageCountAlias)); + const rows = await service.executeQuery(pageQuery); + const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" + ? context.idSetPaginationCount! + : (totalCountBeforeRows ?? await service.executeCount(preparedQuery, this._pageCountAlias, countOperation)); + const data = new SmartList(rows.map((row: unknown) => + row instanceof Platform + ? row + : Platform.fromRecord(row as Record, new EntityRoot()))); + data.totalCount = totalCount; + if (this._pageCountAlias !== undefined) data.aggregations[this._pageCountAlias] = totalCount; + if (this.query.facets.length > 0) { + data.facets = await executeRelationFacets( + service, (query: any) => context.prepareQuery(query), preparedQuery, preparedQuery.facets); + } + return data; + } + + private executeForStreamInternal(context: UserContext, chunkSize: number): AsyncIterable { + this.ensureIntent(); + if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); + const service = context.requireResource("dataService"); + const preparedQuery = context.prepareQuery(this.query); + // Prepare Context and capture the runtime request before returning a lazy iterator. + const chunks = service.executeForStream(preparedQuery, chunkSize); + return (async function* () { + for await (const chunk of chunks) { + for (const entity of chunk) { + yield entity instanceof Platform + ? entity + : Platform.fromRecord(entity as Record, new EntityRoot()); + } + } + })(); + } + + private ensureIntent(): void { + // Runtime owns validation, Unicode whitespace rules and typed diagnostics. + new QueryIntent(this._comment, this._purpose); + } + +} + +export class ExecutablePlatformRequest { + constructor( + private readonly execute: (context: UserContext) => Promise>, + private readonly executeRows: (context: UserContext) => Promise>>, + private readonly stream: (context: UserContext, chunkSize: number) => AsyncIterable, + private readonly limitOne: () => void, + private readonly addComment: (comment: string) => void, + private readonly ensureIntent: () => void, + ) {} + + comment(c: string): this { + this.addComment(c); + return this; + } + + newEntity(context: UserContext): Platform { + this.ensureIntent(); + return new Platform(); + } + + executeForList(context: UserContext): Promise> { + this.ensureIntent(); + return this.execute(context); + } + + executeForRows(context: UserContext): Promise>> { + this.ensureIntent(); + return this.executeRows(context); + } + + executeForStream(context: UserContext, chunkSize = 1000): AsyncIterable { + this.ensureIntent(); + return this.stream(context, chunkSize); + } + + async executeForOne(context: UserContext): Promise { + this.limitOne(); + return (await this.executeForList(context))[0]; + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/runtime-module.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/runtime-module.ts new file mode 100644 index 0000000000000000000000000000000000000000..6acd8901738de1cf9c62144bac04a2da46fec691 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/runtime-module.ts @@ -0,0 +1,150 @@ +import { ObjectLocation, RuntimeModule } from "teaql-ts"; +import { ENTITY_SCHEMAS } from "./teaql-schemas"; +import { ensureGeneratedBootstrap } from "./generated-bootstrap"; + +/** Generated canonical KSML to selected-wire mapping. Never infer this from TS members. */ +export const GENERATED_WIRE_MODEL_METADATA = Object.freeze({ + profile: "camelCase" as const, + entities: Object.freeze({ + "Platform": Object.freeze({ + entityType: "Platform", + profile: "camelCase" as const, + fields: Object.freeze({ + "id": Object.freeze({ canonicalName: "id", wireName: "id", aliases: Object.freeze([] as string[]) }), + "name": Object.freeze({ canonicalName: "name", wireName: "name", aliases: Object.freeze([] as string[]) }), + "version": Object.freeze({ canonicalName: "version", wireName: "version", aliases: Object.freeze([] as string[]) }) + }), + }), + "OrderStatus": Object.freeze({ + entityType: "OrderStatus", + profile: "camelCase" as const, + fields: Object.freeze({ + "platform": Object.freeze({ canonicalName: "platform", wireName: "platform", aliases: Object.freeze([] as string[]) }), + "id": Object.freeze({ canonicalName: "id", wireName: "id", aliases: Object.freeze([] as string[]) }), + "name": Object.freeze({ canonicalName: "name", wireName: "name", aliases: Object.freeze([] as string[]) }), + "code": Object.freeze({ canonicalName: "code", wireName: "code", aliases: Object.freeze([] as string[]) }), + "color": Object.freeze({ canonicalName: "color", wireName: "color", aliases: Object.freeze([] as string[]) }), + "display_order": Object.freeze({ canonicalName: "display_order", wireName: "displayOrder", aliases: Object.freeze([] as string[]) }), + "version": Object.freeze({ canonicalName: "version", wireName: "version", aliases: Object.freeze([] as string[]) }) + }), + }), + "Customer": Object.freeze({ + entityType: "Customer", + profile: "camelCase" as const, + fields: Object.freeze({ + "id": Object.freeze({ canonicalName: "id", wireName: "id", aliases: Object.freeze([] as string[]) }), + "platform": Object.freeze({ canonicalName: "platform", wireName: "platform", aliases: Object.freeze([] as string[]) }), + "name": Object.freeze({ canonicalName: "name", wireName: "name", aliases: Object.freeze([] as string[]) }), + "version": Object.freeze({ canonicalName: "version", wireName: "version", aliases: Object.freeze([] as string[]) }) + }), + }), + "CustomerOrder": Object.freeze({ + entityType: "CustomerOrder", + profile: "camelCase" as const, + fields: Object.freeze({ + "id": Object.freeze({ canonicalName: "id", wireName: "id", aliases: Object.freeze([] as string[]) }), + "customer": Object.freeze({ canonicalName: "customer", wireName: "customer", aliases: Object.freeze([] as string[]) }), + "status": Object.freeze({ canonicalName: "status", wireName: "status", aliases: Object.freeze([] as string[]) }), + "order_number": Object.freeze({ canonicalName: "order_number", wireName: "orderNumber", aliases: Object.freeze([] as string[]) }), + "order_date": Object.freeze({ canonicalName: "order_date", wireName: "orderDate", aliases: Object.freeze([] as string[]) }), + "total_amount": Object.freeze({ canonicalName: "total_amount", wireName: "totalAmount", aliases: Object.freeze([] as string[]) }), + "version": Object.freeze({ canonicalName: "version", wireName: "version", aliases: Object.freeze([] as string[]) }) + }), + }), + "OrderItem": Object.freeze({ + entityType: "OrderItem", + profile: "camelCase" as const, + fields: Object.freeze({ + "id": Object.freeze({ canonicalName: "id", wireName: "id", aliases: Object.freeze([] as string[]) }), + "customer_order": Object.freeze({ canonicalName: "customer_order", wireName: "customerOrder", aliases: Object.freeze([] as string[]) }), + "product_name": Object.freeze({ canonicalName: "product_name", wireName: "productName", aliases: Object.freeze([] as string[]) }), + "quantity": Object.freeze({ canonicalName: "quantity", wireName: "quantity", aliases: Object.freeze([] as string[]) }), + "unit_price": Object.freeze({ canonicalName: "unit_price", wireName: "unitPrice", aliases: Object.freeze([] as string[]) }), + "version": Object.freeze({ canonicalName: "version", wireName: "version", aliases: Object.freeze([] as string[]) }) + }), + }) + }), +}); + +/** Passive generated metadata manifest. It never modifies the database schema. */ +export const GENERATED_RUNTIME_MODULE = new RuntimeModule(ENTITY_SCHEMAS, { + "Platform": { + checkAndFix(context, mutation, results) { + const now = context.getResource("fixTime"); + if ((mutation.action === "Create" && mutation.payload["name"] === undefined) || mutation.payload["name"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("name") }); + if (mutation.payload["name"] != null && [...String(mutation.payload["name"])].length > 100) results.push({ ruleId: "max_length", location: ObjectLocation.property("name"), inputValue: mutation.payload["name"], systemValue: 100 }); + + + }, + }, + "OrderStatus": { + checkAndFix(context, mutation, results) { + const now = context.getResource("fixTime"); + if ((mutation.action === "Create" && mutation.payload["platform"] === undefined) || mutation.payload["platform"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("platform") }); + + + if ((mutation.action === "Create" && mutation.payload["name"] === undefined) || mutation.payload["name"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("name") }); + if (mutation.payload["name"] != null && [...String(mutation.payload["name"])].length > 100) results.push({ ruleId: "max_length", location: ObjectLocation.property("name"), inputValue: mutation.payload["name"], systemValue: 100 }); + + if ((mutation.action === "Create" && mutation.payload["code"] === undefined) || mutation.payload["code"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("code") }); + if (mutation.payload["code"] != null && [...String(mutation.payload["code"])].length > 100) results.push({ ruleId: "max_length", location: ObjectLocation.property("code"), inputValue: mutation.payload["code"], systemValue: 100 }); + + if ((mutation.action === "Create" && mutation.payload["color"] === undefined) || mutation.payload["color"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("color") }); + if (mutation.payload["color"] != null && [...String(mutation.payload["color"])].length > 100) results.push({ ruleId: "max_length", location: ObjectLocation.property("color"), inputValue: mutation.payload["color"], systemValue: 100 }); + + if ((mutation.action === "Create" && mutation.payload["display_order"] === undefined) || mutation.payload["display_order"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("display_order") }); + + + }, + }, + "Customer": { + checkAndFix(context, mutation, results) { + const now = context.getResource("fixTime"); + if ((mutation.action === "Create" && mutation.payload["platform"] === undefined) || mutation.payload["platform"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("platform") }); + + if ((mutation.action === "Create" && mutation.payload["name"] === undefined) || mutation.payload["name"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("name") }); + if (mutation.payload["name"] != null && [...String(mutation.payload["name"])].length > 100) results.push({ ruleId: "max_length", location: ObjectLocation.property("name"), inputValue: mutation.payload["name"], systemValue: 100 }); + + + }, + }, + "CustomerOrder": { + checkAndFix(context, mutation, results) { + const now = context.getResource("fixTime"); + if ((mutation.action === "Create" && mutation.payload["customer"] === undefined) || mutation.payload["customer"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("customer") }); + + if ((mutation.action === "Create" && mutation.payload["status"] === undefined) || mutation.payload["status"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("status") }); + + if ((mutation.action === "Create" && mutation.payload["order_number"] === undefined) || mutation.payload["order_number"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("order_number") }); + if (mutation.payload["order_number"] != null && [...String(mutation.payload["order_number"])].length > 100) results.push({ ruleId: "max_length", location: ObjectLocation.property("order_number"), inputValue: mutation.payload["order_number"], systemValue: 100 }); + + if ((mutation.action === "Create" && mutation.payload["order_date"] === undefined) || mutation.payload["order_date"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("order_date") }); + + if ((mutation.action === "Create" && mutation.payload["total_amount"] === undefined) || mutation.payload["total_amount"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("total_amount") }); + + + }, + }, + "OrderItem": { + checkAndFix(context, mutation, results) { + const now = context.getResource("fixTime"); + if ((mutation.action === "Create" && mutation.payload["customer_order"] === undefined) || mutation.payload["customer_order"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("customer_order") }); + + if ((mutation.action === "Create" && mutation.payload["product_name"] === undefined) || mutation.payload["product_name"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("product_name") }); + if (mutation.payload["product_name"] != null && [...String(mutation.payload["product_name"])].length > 100) results.push({ ruleId: "max_length", location: ObjectLocation.property("product_name"), inputValue: mutation.payload["product_name"], systemValue: 100 }); + + if ((mutation.action === "Create" && mutation.payload["quantity"] === undefined) || mutation.payload["quantity"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("quantity") }); + + if ((mutation.action === "Create" && mutation.payload["unit_price"] === undefined) || mutation.payload["unit_price"] === null) results.push({ ruleId: "required", location: ObjectLocation.property("unit_price") }); + + + }, + } +}, { ...{ + defaultDomainRoot: { entity: "Platform", id: "1", values: { "name": "Commerce Test Platform" } }, + constants: [ + { entity: "OrderStatus", id: "1001", values: { "platform": "1", "name": "New", "code": "NEW", "color": "#94A3B8", "displayOrder": 1 } }, + { entity: "OrderStatus", id: "1002", values: { "platform": "1", "name": "Paid", "code": "PAID", "color": "#22C55E", "displayOrder": 2 } }, + { entity: "OrderStatus", id: "1003", values: { "platform": "1", "name": "Cancelled", "code": "CANCELLED", "color": "#EF4444", "displayOrder": 3 } } + ] +}, ensure: ensureGeneratedBootstrap }); \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/teaql-schemas.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/teaql-schemas.ts new file mode 100644 index 0000000000000000000000000000000000000000..879ae338448bc5e7d73d2e91a1cdc034d3a97213 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/teaql-schemas.ts @@ -0,0 +1,34 @@ +import { EntitySchema } from "teaql-ts/sql/core"; + +export const ENTITY_SCHEMAS: Record = { +"Platform": { + table: "platform_data", + auditMaskFields: [], + columns: {"id": { columnName: "id", modelName: "id", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "name": { columnName: "name", modelName: "name", logPolicy: "plain", logicalType: "text", decode: "native", nullable: false }, "version": { columnName: "version", modelName: "version", logPolicy: "plain", logicalType: "integer", decode: "number", nullable: false }}, + relations: {"orderStatusList": { targetEntity: "OrderStatus", localKey: "id", foreignKey: "platform", many: true }, "customerList": { targetEntity: "Customer", localKey: "id", foreignKey: "platform", many: true }} +}, +"OrderStatus": { + table: "order_status_data", + auditMaskFields: [], + columns: {"platform": { columnName: "platform", modelName: "platform", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "id": { columnName: "id", modelName: "id", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "name": { columnName: "name", modelName: "name", logPolicy: "plain", logicalType: "text", decode: "native", nullable: false }, "code": { columnName: "code", modelName: "code", logPolicy: "plain", logicalType: "text", decode: "native", nullable: false }, "color": { columnName: "color", modelName: "color", logPolicy: "plain", logicalType: "text", decode: "native", nullable: false }, "displayOrder": { columnName: "display_order", modelName: "display_order", logPolicy: "plain", logicalType: "integer", decode: "number", nullable: false }, "version": { columnName: "version", modelName: "version", logPolicy: "plain", logicalType: "integer", decode: "number", nullable: false }}, + relations: {"platform": { targetEntity: "Platform", localKey: "platform", foreignKey: "id", many: false }, "customerOrderList": { targetEntity: "CustomerOrder", localKey: "id", foreignKey: "status", many: true }} +}, +"Customer": { + table: "customer_data", + auditMaskFields: [], + columns: {"id": { columnName: "id", modelName: "id", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "platform": { columnName: "platform", modelName: "platform", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "name": { columnName: "name", modelName: "name", logPolicy: "plain", logicalType: "text", decode: "native", nullable: false }, "version": { columnName: "version", modelName: "version", logPolicy: "plain", logicalType: "integer", decode: "number", nullable: false }}, + relations: {"platform": { targetEntity: "Platform", localKey: "platform", foreignKey: "id", many: false }, "customerOrderList": { targetEntity: "CustomerOrder", localKey: "id", foreignKey: "customer", many: true }} +}, +"CustomerOrder": { + table: "customer_order_data", + auditMaskFields: [], + columns: {"id": { columnName: "id", modelName: "id", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "customer": { columnName: "customer", modelName: "customer", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "status": { columnName: "status", modelName: "status", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "orderNumber": { columnName: "order_number", modelName: "order_number", logPolicy: "plain", logicalType: "text", decode: "native", nullable: false }, "orderDate": { columnName: "order_date", modelName: "order_date", logPolicy: "plain", logicalType: "date", decode: "date", nullable: false }, "totalAmount": { columnName: "total_amount", modelName: "total_amount", logPolicy: "plain", logicalType: "decimal", decode: "number", nullable: false }, "version": { columnName: "version", modelName: "version", logPolicy: "plain", logicalType: "integer", decode: "number", nullable: false }}, + relations: {"customer": { targetEntity: "Customer", localKey: "customer", foreignKey: "id", many: false }, "status": { targetEntity: "OrderStatus", localKey: "status", foreignKey: "id", many: false }, "orderItemList": { targetEntity: "OrderItem", localKey: "id", foreignKey: "customerOrder", many: true }} +}, +"OrderItem": { + table: "order_item_data", + auditMaskFields: [], + columns: {"id": { columnName: "id", modelName: "id", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "customerOrder": { columnName: "customer_order", modelName: "customer_order", logPolicy: "plain", logicalType: "integer", decode: "string", nullable: false }, "productName": { columnName: "product_name", modelName: "product_name", logPolicy: "plain", logicalType: "text", decode: "native", nullable: false }, "quantity": { columnName: "quantity", modelName: "quantity", logPolicy: "plain", logicalType: "integer", decode: "number", nullable: false }, "unitPrice": { columnName: "unit_price", modelName: "unit_price", logPolicy: "plain", logicalType: "decimal", decode: "number", nullable: false }, "version": { columnName: "version", modelName: "version", logPolicy: "plain", logicalType: "integer", decode: "number", nullable: false }}, + relations: {"customerOrder": { targetEntity: "CustomerOrder", localKey: "customerOrder", foreignKey: "id", many: false }} +} +}; \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/src/teaql-ts.ts b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/teaql-ts.ts new file mode 100644 index 0000000000000000000000000000000000000000..b54a29ac3c12fb072cf4c292e22bb2e644b56319 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/src/teaql-ts.ts @@ -0,0 +1,308 @@ +import { + CheckException, EntityChecker, RuntimeModule, + SelectQuery as RuntimeSelectQuery, UserContext, + executeRelationFacets, QueryRequest, MutationIntent, MutationRequest, GraphMutationSession, +} from "teaql-ts"; + +export { CheckException, EntityRoot, ObjectLocation, SmartList, UserContext, executeRelationFacets, MutationIntent } from "teaql-ts"; +export { GraphMutationSession, LoadedScalarSnapshot, MutationTraceScope } from "teaql-ts"; +export type { EntityKey } from "teaql-ts"; +export type { TeaQLPage } from "teaql-ts"; +import type { QueryOperation } from "teaql-ts"; + +function soundex(input: unknown): string { + const text = String(input ?? "").toUpperCase().replace(/[^A-Z]/g, ""); + if (!text) return ""; + const code = (char: string): string => "BFPV".includes(char) ? "1" + : "CGJKQSXZ".includes(char) ? "2" : "DT".includes(char) ? "3" + : char === "L" ? "4" : "MN".includes(char) ? "5" : char === "R" ? "6" : ""; + let result = text[0], previous = code(text[0]); + for (const char of text.slice(1)) { + const current = code(char); + if (current && current !== previous) result += current; + previous = current; + if (result.length === 4) break; + } + return (result + "000").slice(0, 4); +} + +/** Generated naming adapter; query policy and execution remain in the formal runtime. */ +export class SelectQuery extends RuntimeSelectQuery { + orderBy(field: string, direction: string): this { + return this.order({ field, expr: null, direction: direction === "desc" ? "Desc" : "Asc" } as any); + } + + relationQuery( + name: string, query: RuntimeSelectQuery, localKey = "id", foreignKey = "id", many = true, + operation?: QueryOperation, + ): this { + return super.relationQuery(name, query, localKey, foreignKey, many, operation); + } +} + +export interface TeaQLDataService { + executeGraphSave(intent: MutationIntent, work: (graph: GraphMutationSession) => Promise): Promise; + preflightMutation(mutation: any): any; + afterGraphCommit(work: () => void): void; + afterGraphRollback(work: () => void): void; + executeMutation(mutation: any): Promise; + executeQuery(query: any): Promise; + executeCount(query: any, alias?: string, operation?: QueryOperation): Promise; + executeForStream(query: any, chunkSize?: number): AsyncIterable; + close?(): Promise; +} + +export class TeaQLClient implements TeaQLDataService { + private data: Record> = {}; + private nextIds: Record = {}; + private readonly checkers: Record = {}; + private userContext = new UserContext(); + private graphSaveActive = false; + private graphCommitActions: Array<() => void> = []; + private graphRollbackActions: Array<() => void> = []; + private graphSaveTail: Promise = Promise.resolve(); + private readonly mutationGovernanceEvents: any[] = []; + + constructor(private storagePath?: string) { + if (storagePath) { + const fs = require("fs"); + if (fs.existsSync(storagePath)) { + const state = JSON.parse(fs.readFileSync(storagePath, "utf8")); + this.data = state.data || {}; + this.nextIds = state.nextIds || {}; + } + } + } + + /** Installs passive generated metadata. It never mutates storage. */ + install(module: RuntimeModule): this { + Object.assign(this.checkers, module.checkers); + return this; + } + + setUserContext(context: UserContext): this { + this.userContext = context; + return this; + } + + get mutationGovernanceTrace(): readonly any[] { + return [...this.mutationGovernanceEvents]; + } + + private persist() { + if (!this.storagePath) return; + const fs = require("fs"); + const path = require("path"); + fs.mkdirSync(path.dirname(path.resolve(this.storagePath)), { recursive: true }); + const temporaryPath = `${this.storagePath}.tmp`; + fs.writeFileSync(temporaryPath, JSON.stringify({ data: this.data, nextIds: this.nextIds })); + fs.renameSync(temporaryPath, this.storagePath); + } + + async executeGraphSave(intent: MutationIntent, work: (graph: GraphMutationSession) => Promise): Promise { + const graph = new GraphMutationSession(intent); + const predecessor = this.graphSaveTail; + let release!: () => void; + this.graphSaveTail = new Promise(resolve => { release = resolve; }); + await predecessor; + const dataSnapshot = JSON.parse(JSON.stringify(this.data)); + const nextIdsSnapshot = { ...this.nextIds }; + let fixEvidenceStarted = false; + let mutationPolicyGraphStarted = false; + try { + this.graphSaveActive = true; + this.graphCommitActions = []; + this.graphRollbackActions = []; + this.userContext.insertResource("fixTime", new Date()); + this.userContext.beginFixEvidence(); + fixEvidenceStarted = true; + this.userContext.beginMutationPolicyGraph(); + mutationPolicyGraphStarted = true; + const result = await work(graph); + this.userContext.ensureMutationPolicyGraphComplete(); + this.persist(); + for (const action of this.graphCommitActions) action(); + return result; + } catch (error) { + this.data = dataSnapshot; + this.nextIds = nextIdsSnapshot; + for (const action of [...this.graphRollbackActions].reverse()) action(); + throw error; + } finally { + this.graphSaveActive = false; + this.graphCommitActions = []; + this.graphRollbackActions = []; + if (mutationPolicyGraphStarted) this.userContext.endMutationPolicyGraph(); + this.userContext.removeResource("fixTime"); + if (fixEvidenceStarted) this.userContext.finishFixEvidence(); + release(); + } + } + + afterGraphCommit(work: () => void): void { + if (!this.graphSaveActive) throw new Error("No graph save is active"); + this.graphCommitActions.push(work); + } + + afterGraphRollback(work: () => void): void { + if (!this.graphSaveActive) throw new Error("No graph save is active"); + this.graphRollbackActions.push(work); + } + + preflightMutation(mutation: any): any { + mutation = this.checkAndFixMutation(mutation); + this.userContext.recordMutationPolicyPreflight(mutation); + return mutation; + } + + private checkAndFixMutation(mutation: any): any { + if (mutation instanceof MutationRequest) mutation = mutation.mutation; + if (!String(mutation?.comment || "").trim()) throw new Error("Security audit failure: audit reason is required before mutation"); + mutation = { ...mutation, payload: { ...(mutation?.payload || {}) } }; + const checker = this.checkers[String(mutation.entity)]; + if (!checker) return mutation; + const results: any[] = []; + const ownsFixTime = this.userContext.getResource("fixTime") === undefined; + if (ownsFixTime) this.userContext.insertResource("fixTime", new Date()).beginFixEvidence(); + try { + checker.checkAndFix(this.userContext, mutation, results); + if (mutation.ledgerKey && mutation.ledgerRoot) for (const [field, value] of Object.entries(mutation.payload)) mutation.ledgerRoot.set(mutation.ledgerKey, field, value); + this.userContext.translateCheckResults(results); + if (results.length) throw new CheckException(results); + return mutation; + } finally { if (ownsFixTime) this.userContext.removeResource("fixTime").finishFixEvidence(); } + } + + async executeMutation(mutation: any): Promise { + mutation = this.checkAndFixMutation(mutation); + const mutationGovernance = this.userContext.enterMutationPolicy(mutation); + this.mutationGovernanceEvents.push(mutationGovernance); + const table = this.data[mutation.entity] ||= {}; + if (mutation.action === "Create") { + const id = mutation.id ?? String(this.nextIds[mutation.entity] || 1); + this.nextIds[mutation.entity] = Number(id) + 1; + const record = { ...mutation.payload, id: String(id), version: Number(mutation.version || 0) + 1 }; + table[String(id)] = record; + if (!this.graphSaveActive) this.persist(); + return { success: true, id: String(id), version: record.version, persistedRecord: { ...record } }; + } + if (mutation.action === "Update") { + const id = String(mutation.id); + if (!table[id]) throw new Error(`${mutation.entity}(${id}) does not exist`); + const expectedVersion = Number(mutation.version); + const currentVersion = Number(table[id].version || 0); + if (!Number.isFinite(expectedVersion) || expectedVersion !== currentVersion) { + throw new Error( + `Optimistic lock conflict for ${mutation.entity}(${id}): expected ${expectedVersion}, current ${currentVersion}`); + } + table[id] = { ...table[id], ...mutation.payload, id, version: Number(table[id].version || 0) + 1 }; + if (!this.graphSaveActive) this.persist(); + return { success: true, id, version: table[id].version, persistedRecord: { ...table[id] } }; + } + if (mutation.action === "Delete") { + const id = String(mutation.id); + if (!table[id]) throw new Error(`${mutation.entity}(${id}) does not exist`); + const expectedVersion = Number(mutation.version); + const currentVersion = Number(table[id].version || 0); + if (!Number.isFinite(expectedVersion) || expectedVersion !== currentVersion) { + throw new Error( + `Optimistic lock conflict for ${mutation.entity}(${id}): expected ${expectedVersion}, current ${currentVersion}`); + } + table[id] = { ...table[id], id, version: -(currentVersion + 1) }; + if (!this.graphSaveActive) this.persist(); + return { success: true, id, version: table[id].version, deleted: true, persistedRecord: { ...table[id] } }; + } + throw new Error(`Unsupported mutation action: ${mutation.action}`); + } + async query(context: any, req: any): Promise { + return { rows: [] }; + } + async executeQuery(query: any): Promise { + if (!(query instanceof RuntimeSelectQuery)) { + throw new Error("TeaQL list execution requires the formal runtime SelectQuery"); + } + query.prepareForList(); + let rows = Object.values(this.data[query.entity] || {}).map((row: any) => ({ ...row })); + const matches = (row: any, expression: any): boolean => { + if (expression?.$and) return expression.$and.every((item: any) => matches(row, item)); + return Object.entries(expression || {}).every(([field, predicate]: [string, any]) => { + if (predicate?.$eq !== undefined) return row[field] === (predicate.$eq?.id ?? predicate.$eq); + if (predicate?.$ne !== undefined) return row[field] !== (predicate.$ne?.id ?? predicate.$ne); + if (predicate?.$contains !== undefined) return String(row[field] ?? "").includes(String(predicate.$contains)); + if (predicate?.$notContains !== undefined) return !String(row[field] ?? "").includes(String(predicate.$notContains)); + if (predicate?.$startsWith !== undefined) return String(row[field] ?? "").startsWith(String(predicate.$startsWith)); + if (predicate?.$notStartsWith !== undefined) return !String(row[field] ?? "").startsWith(String(predicate.$notStartsWith)); + if (predicate?.$endsWith !== undefined) return String(row[field] ?? "").endsWith(String(predicate.$endsWith)); + if (predicate?.$notEndsWith !== undefined) return !String(row[field] ?? "").endsWith(String(predicate.$notEndsWith)); + if (predicate?.$soundLike !== undefined) return soundex(row[field]) === soundex(predicate.$soundLike); + if (predicate?.$in !== undefined) return predicate.$in.some((value: any) => row[field] === (value?.id ?? value)); + if (predicate?.$notIn !== undefined) return !predicate.$notIn.some((value: any) => row[field] === (value?.id ?? value)); + if (predicate?.$between !== undefined) return row[field] >= predicate.$between[0] && row[field] <= predicate.$between[1]; + if (predicate?.$isNull === true) return row[field] === null || row[field] === undefined; + if (predicate?.$isNull === false) return row[field] !== null && row[field] !== undefined; + if (predicate?.$gt !== undefined) return row[field] > predicate.$gt; + if (predicate?.$gte !== undefined) return row[field] >= predicate.$gte; + if (predicate?.$lt !== undefined) return row[field] < predicate.$lt; + if (predicate?.$lte !== undefined) return row[field] <= predicate.$lte; + return true; + }); + }; + if (query.filterCondition) rows = rows.filter(row => matches(row, query.filterCondition)); + if (query.aggregateItems?.length) { + return [Object.fromEntries(query.aggregateItems.map((aggregate: any) => { + if (String(aggregate.function).toLowerCase() !== "count") { + throw new Error(`Unsupported local aggregate: ${aggregate.function}`); + } + return [aggregate.alias, rows.length]; + }))]; + } + for (const order of [...query.orderItems].reverse()) { + rows.sort((a, b) => (a[order.field] === b[order.field] ? 0 : a[order.field] > b[order.field] ? 1 : -1) * (String(order.direction).toLowerCase() === "desc" ? -1 : 1)); + } + const start = query.offsetValue || 0; + rows = rows.slice(start, start + query.limitValue); + for (const relation of (query.relations || []) as any[]) { + const localValues = new Set(rows.map((row: any) => row[relation.localKey || "id"])); + const relatedRows = (await this.executeQuery(relation.query)).filter( + (row: any) => localValues.has(row[relation.foreignKey || "id"])); + for (const row of rows) { + const matches = relatedRows.filter( + (related: any) => related[relation.foreignKey || "id"] === row[relation.localKey || "id"]); + row[relation.name] = relation.many === false ? matches[0] : matches; + } + } + if (query.selectItems.length > 0) { + const selections = new Set(query.selectItems); + for (const relation of (query.relations || []) as any[]) selections.add(relation.name); + rows = rows.map((row: any) => Object.fromEntries( + Object.entries(row).filter(([field]) => selections.has(field)))); + } + return rows; + } + async executeCount(query: any, countAlias?: string, operation?: QueryOperation): Promise { + if (typeof query?.forExactCount !== "function") { + throw new Error("TeaQL exact count requires the formal runtime SelectQuery"); + } + const alias = countAlias ?? "__teaql_total"; + const request = new QueryRequest(query).deriveOperation(query.forExactCount(alias), operation ?? { + kind: "named-count", ...(countAlias === undefined ? {} : { alias: countAlias }) }); + const rows = await this.executeQuery(request.query); + const value = rows[0]?.[alias]; + if (typeof value !== "number" || !Number.isFinite(value)) { + throw new Error(`TeaQL provider did not return exact count alias ${alias}`); + } + return value; + } + async *executeForStream(query: any, chunkSize = 1000): AsyncIterable { + if (!Number.isInteger(chunkSize) || chunkSize <= 0) throw new Error("stream chunk size must be a positive integer"); + const rows = await this.executeQuery(query); + for (let offset = 0; offset < rows.length; offset += chunkSize) { + yield rows.slice(offset, offset + chunkSize); + } + } +} + +declare const require: any; + +export function eq(a: any, b: any) { return {type: 'eq', field: a, value: b}; } +export function contain(a: any, b: any) { return {type: 'contain', field: a, value: b}; } \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/teaql-i18n.json b/source/teaql-ts/examples/browser-sqlite/orders-lib/teaql-i18n.json new file mode 100644 index 0000000000000000000000000000000000000000..c69942a7adf7c471b956b29df700f8472446e43a --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/teaql-i18n.json @@ -0,0 +1,128 @@ +{ + "schema": "teaql.i18n/v1", + "defaultLocale": "en", + "locales": { + "de": { + "vocabulary": { + }, + "messages": { + } + }, + "ko": { + "vocabulary": { + }, + "messages": { + } + }, + "pt": { + "vocabulary": { + }, + "messages": { + } + }, + "zh-TW": { + "vocabulary": { + }, + "messages": { + } + }, + "fil": { + "vocabulary": { + }, + "messages": { + } + }, + "en": { + "vocabulary": { + "property.platform.name": "Name", + "property.customerOrder.orderNumber": "Order Number", + "property.orderItem.id": "Id", + "entity.orderItem": "Order Item", + "property.orderItem.customerOrder": "Customer Order", + "property.orderStatus.version": "Version", + "property.orderItem.unitPrice": "Unit Price", + "property.orderItem.productName": "Product Name", + "property.orderStatus.code": "Code", + "property.customerOrder.orderDate": "Order Date", + "entity.customerOrder": "Customer Order", + "property.orderStatus.displayOrder": "Display Order", + "entity.customer": "Customer", + "property.customerOrder.id": "Id", + "property.orderStatus.color": "Color", + "property.customerOrder.totalAmount": "Total Amount", + "property.customerOrder.version": "Version", + "entity.platform": "Platform", + "property.platform.id": "Id", + "property.customer.version": "Version", + "property.orderStatus.id": "Id", + "property.customer.id": "Id", + "property.customer.platform": "Platform", + "entity.orderStatus": "Order Status", + "property.customerOrder.customer": "Customer", + "property.customer.name": "Name", + "property.orderItem.version": "Version", + "property.orderStatus.platform": "Platform", + "property.orderStatus.name": "Name", + "property.platform.version": "Version", + "property.customerOrder.status": "Status", + "property.orderItem.quantity": "Quantity" + }, + "messages": { + } + }, + "fr": { + "vocabulary": { + }, + "messages": { + } + }, + "zh-CN": { + "vocabulary": { + }, + "messages": { + } + }, + "es": { + "vocabulary": { + }, + "messages": { + } + }, + "ar": { + "vocabulary": { + }, + "messages": { + } + }, + "vi": { + "vocabulary": { + }, + "messages": { + } + }, + "th": { + "vocabulary": { + }, + "messages": { + } + }, + "uk": { + "vocabulary": { + }, + "messages": { + } + }, + "ja": { + "vocabulary": { + }, + "messages": { + } + }, + "id": { + "vocabulary": { + }, + "messages": { + } + } + } +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders-lib/tsconfig.json b/source/teaql-ts/examples/browser-sqlite/orders-lib/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..18139f743ca48c921f9a21e51be3b1485651513c --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders-lib/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true + }, + "include": ["src/**/*", "*.d.ts"] +} \ No newline at end of file diff --git a/source/teaql-ts/examples/browser-sqlite/orders.html b/source/teaql-ts/examples/browser-sqlite/orders.html new file mode 100644 index 0000000000000000000000000000000000000000..62924d0c945ccf829dac77c84ca0aac53d97c077 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/orders.html @@ -0,0 +1,40 @@ + + + + + + + TeaQL browser order TraceChain + + +
+

GENERATED Q + E · SQLITE/WASM · NO BACKEND

+

Order query evidence

+

One filtered page, named total, status facets and bounded item previews.

+

WorkItem demo · Runtime source

+
+ + + +
+ + + + +

Starting SQLite/WASM…

+

Response data and metadata

+

+    

SQL execution evidence

+

Time is the recorded execution duration. Identity is the request entity from tracePath, not a user or object ID.

+
+ + + +
TimeIdentityTrace chainSQL
+
+
Business TraceChain as text
+
Runtime metadata and physical tracePath
+
+ + + diff --git a/source/teaql-ts/examples/browser-sqlite/package-lock.json b/source/teaql-ts/examples/browser-sqlite/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..bf06ad3a555e96b2e4d468f0aa9b76bf2f23967c --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/package-lock.json @@ -0,0 +1,1611 @@ +{ + "name": "teaql-browser-sqlite-example", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "teaql-browser-sqlite-example", + "version": "1.0.0", + "dependencies": { + "@sqlite.org/sqlite-wasm": "3.53.0-build1", + "teaql-ts": "file:../.." + }, + "devDependencies": { + "puppeteer-core": "25.10.0", + "typescript": "5.9.2", + "vite": "^7.3.6" + } + }, + "../..": { + "name": "@teaql/teaql", + "version": "0.3.0", + "license": "Apache-2.0", + "dependencies": { + "node-fetch": "^2.7.0" + }, + "devDependencies": { + "@opentelemetry/api-logs": "^0.221.0", + "@opentelemetry/context-async-hooks": "^2.10.0", + "@opentelemetry/core": "^2.10.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.221.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.221.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.221.0", + "@opentelemetry/resources": "^2.10.0", + "@opentelemetry/sdk-logs": "^0.221.0", + "@opentelemetry/sdk-metrics": "^2.10.0", + "@opentelemetry/sdk-trace-base": "^2.10.0", + "@sqlite.org/sqlite-wasm": "3.53.0-build1", + "@types/better-sqlite3": "^7.6.12", + "@types/jest": "^29.5.0", + "@types/node-fetch": "^2.6.13", + "@types/pg": "^8.11.0", + "better-sqlite3": "^12.10.0", + "esbuild": "^0.28.2", + "jest": "^29.5.0", + "jest-util": "^29.7.0", + "mysql2": "^3.11.0", + "peggy": "^5.1.0", + "pg": "^8.12.0", + "pg-query-stream": "^4.7.0", + "ts-jest": "^29.1.0", + "typescript": "5.4.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.1", + "@opentelemetry/api-logs": "^0.221.0", + "@sqlite.org/sqlite-wasm": "3.53.0-build1", + "better-sqlite3": "^12.10.0", + "expo-sqlite": "*", + "mysql2": "^3.11.0", + "pg": "^8.12.0", + "pg-query-stream": "^4.7.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/api-logs": { + "optional": true + }, + "@sqlite.org/sqlite-wasm": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "expo-sqlite": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-query-stream": { + "optional": true + } + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.2.2.tgz", + "integrity": "sha512-q2BU4YfO9h/Wt7IcWPcggpOOqLk2Tbs1hDwolvKZrweRjy751OJBKMN9zO5bfD0pzU7X/tvKw/exQds4pM/LOg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "modern-tar": "^0.8.4", + "yargs": "^18.0.0" + }, + "bin": { + "browsers": "lib/main-cli.js" + }, + "engines": { + "node": ">=22.12.0" + }, + "peerDependencies": { + "proxy-agent": ">=8.0.1", + "yauzl": "^2.10.0 || ^3.4.0" + }, + "peerDependenciesMeta": { + "proxy-agent": { + "optional": true + }, + "yauzl": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.1.tgz", + "integrity": "sha512-UZ8sUxPTiHWYX9QNdJedb1kDZSpS1t/VPWBWGSgqHNi9w3Cu6IXvu2mzbhiTiPvtrqgTQJ+zqiAq2iPIPilpaQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.1.tgz", + "integrity": "sha512-cQ4nFQABN5cDvDpbvJ7bMStCpnaVxynZrRMfUJYgxcIk9Sh54FIO1vtfkg0B69REjER77ioZ/ov+eAApx/KmLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.1.tgz", + "integrity": "sha512-FQNqd1lRy/0QhDk3xeRIkSBiCpXCiDnZO3YLVdcDKN1UBiKToNftCzcXYNLshmPDUMlu2TdeS8tGcsU6f3YF1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.1.tgz", + "integrity": "sha512-pvD16V939D3CloK0+qikpGaxiPrDUXTe7Y5cWOMkMSy7m1cawa8EGy/kXYi/G/cKAC4HDAbSnzCIk1WmsoOKXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.1.tgz", + "integrity": "sha512-pcFGeL2345VwdTnJhA6zLbew+YgWB0qBG2+dMtXjCicf6+rm6kO6cOoh5VnTe0ZMrMRgRyuHmCJxZWrIdzYuOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.1.tgz", + "integrity": "sha512-mRJlqSRulVzcKq/LKA6ICSIc3K/l4fzlVn/gePn2nXIHy8seRi5z/eeRE0d/XMBxcMldiXtQTSpRj0tkkC3g8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.1.tgz", + "integrity": "sha512-YDUNvVM85TI3g/1OpnqKP1h4NeW/j64DfWMf+G3M809xNk1bJSnpFp4sh83NpmVE5DXnkh8ULor4LTVZKoYLHw==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.1.tgz", + "integrity": "sha512-7Mcn71p9ZuQFAj+h+dhQXy/yeLePRS2yKRnmW1DijA9thKO5qap0GNOIQK4yQ6iP3SU0Mrb/yWo8h8vgRba8lw==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.1.tgz", + "integrity": "sha512-4YiLQTX6U4CSl0L9cluep9A9W6UmTfqBDc2/CH6wlu54pl4E7Jn3cOD8oxzvBDEGk/JMKgJ47C8g+radF7mwvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.1.tgz", + "integrity": "sha512-2ra8F7w8OquwZN9z2/fKFnli69wa8PLwaVzRMIPGb13ByMJwC28Fbp8YcVGoUhlYMTt7j5j9bNgpysrN2UM+vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.1.tgz", + "integrity": "sha512-Sy20ncyhjmBP0Ml+UvQbimjlk6VFgjW5uNP+qqwHB00mTE8Bl2C1TuHTlRwK2YoXeZbee5lP2XevBWVkAQAtSQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.1.tgz", + "integrity": "sha512-noITLp8oNjYliPnGWmLyelIHwULGqbHloQHGw1rtxbWhTuWooRpnZarZQJ1y9EUC4szuCusCc+HEpUtxpIwYvA==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.1.tgz", + "integrity": "sha512-hlxxXd+F1mWiAcaFR7Sv9ZQT6m6UfI8+Vy/kFJzztq2pDMU/0wZ9sish0iszNZvsQDo8Gc0i5yuFEOz5dDf6fA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.1.tgz", + "integrity": "sha512-EF7OpqQTQ/BvGqLzUi4rEHuagCV9MugAUXSHemwPW5vxZ75RR+jxO/2j95Ph2dalMpFHSVECjRoioHZgA9zOYA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.1.tgz", + "integrity": "sha512-wQO3JesW9PRkwlabQ27y7sPfVOOTLRG73I4F2UYHG5PXun3J9U3y+b7ezVKSYbsvSKGQ1k1cq8Qlun4C9kLt3w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.1.tgz", + "integrity": "sha512-ouAGwhO6wHRXdnOVCOsB0tRFkA7nhNB2Nwax6oECXN0YiN8EYUTBAOudADOB1PI+yDL61TeNx/u7MVCzksNbkQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.1.tgz", + "integrity": "sha512-q2R38Sn+1J8RxhfJ+T54wSWmyKXWec+9jgDfqO2AtArEqHO5R2aeayp5H5OYLr5UYDVGsVaZPEFUooMhYCdz5A==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.1.tgz", + "integrity": "sha512-gfI5T24WLLuFfSKw7Go/zDXjAAV0fny0swTaDv+WjK7vqcw4cRhFfdsyKL1n+ukI+ooBxn3bVQnyrn06WpI50w==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.1.tgz", + "integrity": "sha512-4h6XqthmB4Hspji84wvgk+ElodTsGj+dbZqHJHHtKxj4mYq0ANSEEPX9ys3moJueqsRjwpaJYH7874Itwnj2ow==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.1.tgz", + "integrity": "sha512-dlfCOa87o1VAYegLQ9EKilx2JCeRofiyPGhTCmqnuXZ6bMPiycO1rq1+sKoulAp7pGLIsTIw+1x5R+zgh5LhhA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.1.tgz", + "integrity": "sha512-cjkLbOlfcm3QGhMM1J5zaZjsw1GggbN6rw9UTSSRrPrR1KkcXnN7Uq9rPw34xImQ9VOY9GN+6u2Zj80B9ptkcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.1.tgz", + "integrity": "sha512-Li1KdUnWGE4N3e1F/B4RTB1ms+nG4WBgjByO46pkeBVX/2UBsY53xf5vK9WygVmnH3RwncIST7lkSdLSY6P9lg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.1.tgz", + "integrity": "sha512-t4ZYOSoLTgwhuFMrmTMLx/+i1DQVK7HYqMc6kY46EApwi8X0nIVphzdNoThU3xt6n+N5urG1/gxBdCaKDLavfg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.1.tgz", + "integrity": "sha512-RgroPfMmKlD1RzSDxvwgcPiy2HNQKoYV7OmwIXDsk73uKW5t6B/V8KIy27SMv/FNXFo/oSBtWc9J0X7t91ezZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.1.tgz", + "integrity": "sha512-at8QVep6S3h5Y6gSbdGU06bRY5WJkf6WUduM9YtvYMbYhB1MOFfUgc6kehitQXzOtMSaT70q7f9ydPhpqu821w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sqlite.org/sqlite-wasm": { + "version": "3.53.0-build1", + "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.53.0-build1.tgz", + "integrity": "sha512-PfWPWN2n+/37doa8oh2/oUXk4OOsRYZsxc1W1sDXIGb/Pu5Yrb+f2eyYpgQMGITVX7HVgxhs9P18Rc6I97ym/g==", + "license": "Apache-2.0", + "workspaces": [ + "demos/*" + ], + "engines": { + "node": ">=22" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chromium-bidi": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-17.0.2.tgz", + "integrity": "sha512-5v9GQFhTktFvotn/OFNJBmKLKRAb6n9r0bVCwf7sHgWc3/JryK0bj1nn93L3pHFrfgcsu6Be6EWsDi+1XHTGDg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "mitt": "^3.0.1", + "zod": "^3.24.1" + }, + "engines": { + "node": ">=20.19.0 <22.0.0 || >=22.12.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1666840", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1666840.tgz", + "integrity": "sha512-gCcO42XCHKEs7Ag0S7aGYsnJ7hlgrO3qderYqeiY0Eqk+0GFfuvT13IA0hHreJTa2KCdDVyGMeOhdMNmrrTjVg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, + "node_modules/modern-tar": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.8.4.tgz", + "integrity": "sha512-gN54ddmyzEg10orwZ2u4OOv+bjpMWdIl5jIkodK97bMq8QBSL5c0D7YX0lT1Ooz+99S7+PvFbnxzdjgHo1r41g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/puppeteer-core": { + "version": "25.10.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.10.0.tgz", + "integrity": "sha512-Hy5eMQshOEMil4JUUx03h5pw1HYkYCso1RG/gcpPlFSd4cYPOcopxcXEAxpLPOkOPJb9LIJtwxuj66bSdvknFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "3.2.2", + "chromium-bidi": "17.0.2", + "devtools-protocol": "0.0.1666840", + "typed-query-selector": "^2.12.2", + "webdriver-bidi-protocol": "0.4.3", + "ws": "^8.21.3" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/rollup": { + "version": "4.63.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.1.tgz", + "integrity": "sha512-3Df9jsstwhccuEfmAMi9l8XUh/GOkVObmFTU7CCVBysEbcOZLl84jCtaAZMcPiMz2EGKsATzQcU+Xr3n/wU6cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.63.1", + "@rollup/rollup-android-arm64": "4.63.1", + "@rollup/rollup-darwin-arm64": "4.63.1", + "@rollup/rollup-darwin-x64": "4.63.1", + "@rollup/rollup-freebsd-arm64": "4.63.1", + "@rollup/rollup-freebsd-x64": "4.63.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.63.1", + "@rollup/rollup-linux-arm-musleabihf": "4.63.1", + "@rollup/rollup-linux-arm64-gnu": "4.63.1", + "@rollup/rollup-linux-arm64-musl": "4.63.1", + "@rollup/rollup-linux-loong64-gnu": "4.63.1", + "@rollup/rollup-linux-loong64-musl": "4.63.1", + "@rollup/rollup-linux-ppc64-gnu": "4.63.1", + "@rollup/rollup-linux-ppc64-musl": "4.63.1", + "@rollup/rollup-linux-riscv64-gnu": "4.63.1", + "@rollup/rollup-linux-riscv64-musl": "4.63.1", + "@rollup/rollup-linux-s390x-gnu": "4.63.1", + "@rollup/rollup-linux-x64-gnu": "4.63.1", + "@rollup/rollup-linux-x64-musl": "4.63.1", + "@rollup/rollup-openbsd-x64": "4.63.1", + "@rollup/rollup-openharmony-arm64": "4.63.1", + "@rollup/rollup-win32-arm64-msvc": "4.63.1", + "@rollup/rollup-win32-ia32-msvc": "4.63.1", + "@rollup/rollup-win32-x64-gnu": "4.63.1", + "@rollup/rollup-win32-x64-msvc": "4.63.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/teaql-ts": { + "resolved": "../..", + "link": true + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/typed-query-selector": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz", + "integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/webdriver-bidi-protocol": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.3.tgz", + "integrity": "sha512-uuN0goWfxP22B7J/uAgBpOYNPttC+XVseYE+rSY5+rQ+YBeVz/VORw8WbmLVcqW78zNg5A4qnjNXYUWR3il2ig==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ws": { + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz", + "integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^8.2.1", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/source/teaql-ts/examples/browser-sqlite/package.json b/source/teaql-ts/examples/browser-sqlite/package.json new file mode 100644 index 0000000000000000000000000000000000000000..33409c71a9218e79b13648e86d7e01cc15f1d391 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/package.json @@ -0,0 +1,21 @@ +{ + "name": "teaql-browser-sqlite-example", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc --noEmit && vite build", + "smoke": "node scripts/smoke.mjs", + "smoke:orders": "node scripts/orders-smoke.mjs" + }, + "dependencies": { + "@sqlite.org/sqlite-wasm": "3.53.0-build1", + "teaql-ts": "file:../.." + }, + "devDependencies": { + "puppeteer-core": "25.10.0", + "typescript": "5.9.2", + "vite": "^7.3.6" + } +} diff --git a/source/teaql-ts/examples/browser-sqlite/scripts/orders-smoke.mjs b/source/teaql-ts/examples/browser-sqlite/scripts/orders-smoke.mjs new file mode 100644 index 0000000000000000000000000000000000000000..3997d91a2915a2cd56c97b2dc2ed7666d65d9ef2 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/scripts/orders-smoke.mjs @@ -0,0 +1,114 @@ +import {spawn} from 'node:child_process'; +import {readFileSync, writeFileSync} from 'node:fs'; +import {createHash} from 'node:crypto'; +import {join} from 'node:path'; +import assert from 'node:assert/strict'; +import puppeteer from 'puppeteer-core'; + +const generated = JSON.parse(readFileSync('generated-order-hashes.json', 'utf8')); +function checkLibrary() { + for (const [file, expected] of Object.entries(generated)) + assert.equal(createHash('sha256').update(readFileSync(join('orders-lib', file))).digest('hex'), expected, `generated file changed: ${file}`); +} +checkLibrary(); +const server = spawn(process.execPath, ['node_modules/vite/bin/vite.js', 'preview', '--host', '127.0.0.1', '--port', '4175', '--strictPort'], + {stdio: ['ignore', 'pipe', 'pipe']}); +let serverOutput = ''; +server.stdout.on('data', value => { serverOutput += value; }); server.stderr.on('data', value => { serverOutput += value; }); +let browser; +const receipts = []; +try { + let ready = false; + for (let attempt = 0; attempt < 100; attempt++) { + try { ready = (await fetch('http://127.0.0.1:4175/orders.html')).ok; } catch { /* starting */ } + if (ready) break; + await new Promise(resolve => setTimeout(resolve, 100)); + } + assert.ok(ready, serverOutput); + browser = await puppeteer.launch({executablePath: process.env.CHROME_BIN || (process.platform === 'darwin' + ? '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' + : '/usr/bin/google-chrome'), + args: ['--no-sandbox', '--disable-dev-shm-usage'], headless: true}); + const page = await browser.newPage(), errors = []; + page.on('pageerror', error => errors.push(error.message)); + page.on('console', event => { if (event.type() === 'error') errors.push(event.text()); }); + page.on('response', response => { if (response.status() >= 400) errors.push(`${response.status()} ${response.url()}`); }); + page.on('requestfailed', request => errors.push(`${request.failure()?.errorText} ${request.url()}`)); + async function waitReady(storage) { + try { + await page.waitForFunction(value => { + const text = document.querySelector('#status')?.textContent || ''; + return text.startsWith(value) && text.includes('ready'); + }, {timeout: 20_000}, storage); + } catch (error) { + throw new Error(`${error.message}; status=${await page.$eval('#status', element => element.textContent)}; browserErrors=${errors.join('\n')}`); + } + } + async function inspect(label, diagnostics) { + const response = JSON.parse(await page.$eval('#result', element => element.textContent)); + assert.equal(response.metadata.totalCount, 3); assert.equal(response.metadata.aggregations.totalOrders, 3); + assert.equal(response.metadata.pageOffset, 1); assert.equal(response.metadata.pageSize, 1); + assert.deepEqual(response.metadata.searchWarnings, []); + assert.equal(response.data.length, 1); const order = response.data[0]; + assert.equal(order.orderNumber, 'KEEP-002'); assert.equal(order.orderDate.slice(0, 10), '2026-10-02'); + assert.equal(order.version, 1); assert.equal(order.status.name, 'Paid'); assert.equal(order.status.color, '#22C55E'); + assert.deepEqual(order.items.map(item => [item.productName, item.quantity]), [['Box 1', 1], ['Box 2', 2], ['Box 3', 3]]); + assert.equal(order.itemCount, 5); + assert.deepEqual(response.facets.statusCounts.map(row => [String(row.id), row.orderCount, row.orderTotalAmount]), + [['1001', 1, 100], ['1002', 2, 500], ['1003', 0, null]]); + const evidence = JSON.parse(await page.$eval('#sql', element => element.textContent)); + assert.equal(evidence.length, 8); + const comments = evidence.map(entry => entry.traceChain.filter(node => node.kind === 'comment').map(node => node.detail)); + const expected = [ + ['load order list', "countAs('totalOrders')"], ['load order list'], + ['load order list', 'selectStatusWith(...)', 'load status'], + ['load order list', 'selectOrderItemListWith(...)', 'load item previews'], + ['load order list', "countOrderItemsAs('itemCount')"], + ['load order list', "facetByStatusAs('statusCounts')", 'aggregate status'], + ['load order list', "facetByStatusAs('statusCounts')", 'load status facets'], + ['load order list', "facetByStatusAs('statusCounts')", 'aggregate status'], + ]; + assert.deepEqual(comments.map(JSON.stringify).sort(), expected.map(JSON.stringify).sort()); + for (const entry of evidence) { + assert.equal(entry.purpose, 'render order list page'); + assert.ok(entry.tracePath.some(node => node.kind === 'provider')); + assert.equal(entry.traceChain.filter(node => node.kind === 'purpose').length, 1); + } + const text = await page.$eval('#status', element => element.textContent); + assert.ok(text.includes(`${diagnostics} diagnostics`), text); + assert.equal(await page.$eval('#trace', element => element.textContent), evidence.map(entry => `${entry.purpose}: ${entry.traceChain + .filter(node => node.kind === 'comment').map(node => node.detail).join(' → ')}`).join('\n')); + assert.deepEqual(await page.$$eval('.evidence-table th', cells => cells.map(cell => cell.textContent)), + ['Time', 'Identity', 'Trace chain', 'SQL']); + const renderedEvidence = await page.$$eval('#evidence-rows tr', rows => rows.map(row => + [...row.querySelectorAll('td')].map(cell => cell.textContent))); + assert.deepEqual(renderedEvidence, evidence.map(entry => [ + `${entry.elapsedMicros} µs`, entry.tracePath.find(node => node.kind === 'request')?.name ?? '—', + `${entry.traceChain.find(node => node.kind === 'purpose').detail}: ${entry.traceChain + .filter(node => node.kind === 'comment').map(node => node.detail).join(' → ')}`, entry.debugSQL, + ])); + receipts.push({label, response, evidence, diagnostics, renderedEvidence}); + return response; + } + await page.goto('http://127.0.0.1:4175/orders.html', {waitUntil: 'networkidle0'}); + await waitReady('MEMORY'); const baseline = await inspect('memory-first', 8); + await page.reload({waitUntil: 'networkidle0'}); await waitReady('MEMORY'); + assert.deepEqual(await inspect('memory-refresh', 8), baseline); + await page.click('#logging'); + await page.waitForFunction(() => document.querySelector('#status')?.textContent?.includes('0 diagnostics')); + assert.deepEqual(await inspect('memory-logging-off', 0), baseline); + await page.click('#reset'); + await page.waitForFunction(() => !document.querySelector('#reset')?.hasAttribute('disabled')); + assert.deepEqual(await inspect('memory-reset', 0), baseline); + await page.click('#persist'); await waitReady('OPFS'); + assert.deepEqual(await inspect('opfs-first', 0), baseline); + await page.reload({waitUntil: 'networkidle0'}); await waitReady('OPFS'); + assert.deepEqual(await inspect('opfs-refresh', 8), baseline); + await page.click('#reset'); + await page.waitForFunction(() => !document.querySelector('#reset')?.hasAttribute('disabled')); + assert.deepEqual(await inspect('opfs-reset', 8), baseline); + assert.deepEqual(errors, []); checkLibrary(); + if (process.env.TEAQL_BROWSER_ORDER_EVIDENCE) writeFileSync(process.env.TEAQL_BROWSER_ORDER_EVIDENCE, + JSON.stringify({receipts, generatedLibraryUnchanged: true, browserErrors: errors}, null, 2) + '\n', {flag: 'wx'}); + console.log('PASS browser generated order TraceChain: memory/OPFS, refresh/reset, logging on/off, exact facets/counts/previews, actual SQL=8, unchanged generated library'); +} finally { await browser?.close(); server.kill('SIGTERM'); } diff --git a/source/teaql-ts/examples/browser-sqlite/scripts/smoke.mjs b/source/teaql-ts/examples/browser-sqlite/scripts/smoke.mjs new file mode 100644 index 0000000000000000000000000000000000000000..2dcce59961fb89e6906eea87f8539cb0b2a5c9d8 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/scripts/smoke.mjs @@ -0,0 +1,393 @@ +import { spawn } from 'node:child_process'; +import puppeteer from 'puppeteer-core'; + +const port = 4174; +const server = spawn(process.execPath, [ + // Verify the built deployment, not Vite's first-load dependency optimizer. + 'node_modules/vite/bin/vite.js', 'preview', '--host', '127.0.0.1', '--port', String(port), '--strictPort', +], { + stdio: ['ignore', 'pipe', 'pipe'], +}); + +let output = ''; +server.stdout.on('data', chunk => { output += chunk; }); +server.stderr.on('data', chunk => { output += chunk; }); + +async function waitForServer() { + for (let attempt = 0; attempt < 100; attempt += 1) { + try { + const response = await fetch(`http://127.0.0.1:${port}/`); + if (response.ok) return; + } catch { /* server is still starting */ } + await new Promise(resolve => setTimeout(resolve, 100)); + } + throw new Error(`Vite did not start:\n${output}`); +} + +let browser; +try { + await waitForServer(); + browser = await puppeteer.launch({ + executablePath: process.env.CHROME_BIN || (process.platform === 'darwin' + ? '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' + : '/usr/bin/google-chrome'), + args: ['--no-sandbox', '--disable-dev-shm-usage'], + headless: true, + }); + const page = await browser.newPage(); + const browserErrors = []; + page.on('console', message => { + if (message.type() === 'error') browserErrors.push(message.text()); + }); + page.on('pageerror', error => browserErrors.push(error.message)); + page.on('response', response => { + if (response.status() >= 400) browserErrors.push(`${response.status()} ${response.url()}`); + }); + page.on('requestfailed', request => browserErrors.push( + `${request.failure()?.errorText || 'request failed'} ${request.url()}`, + )); + await page.goto(`http://127.0.0.1:${port}/`, { waitUntil: 'networkidle0' }); + try { + await page.waitForFunction(() => document.querySelector('#status')?.textContent?.includes('ready'), { + timeout: 20_000, + }); + } catch (error) { + const currentStatus = await page.$eval('#status', element => element.textContent || ''); + throw new Error(`${error.message}\nstatus: ${currentStatus}\nconsole: ${browserErrors.join('\n')}`); + } + const first = await page.$eval('#result', element => element.textContent || ''); + const firstStatus = await page.$eval('#status', element => element.textContent || ''); + const defaultLocale = await page.evaluate(() => ({ + lang: document.documentElement.lang, + title: document.querySelector('#query-browser-title')?.textContent || '', + englishActive: document.querySelector('[data-locale="en"]')?.classList.contains('active'), + })); + if (defaultLocale.lang !== 'en' || defaultLocale.title !== 'Choose a query' || !defaultLocale.englishActive) { + throw new Error(`English was not the default locale: ${JSON.stringify(defaultLocale)}`); + } + if (!firstStatus.includes('policy installed')) { + throw new Error(`Browser runtime did not install Mutation Policy: ${firstStatus}`); + } + const defaultLanding = await page.evaluate(() => ({ + hash: window.location.hash, + activeQuery: document.querySelector('[data-query-id].active')?.dataset.queryId || '', + resultTitle: document.querySelector('#result-title')?.textContent || '', + hasOrderCenter: !!document.querySelector('#result .order-center'), + tableViewActive: document.querySelector('#view-table')?.classList.contains('active'), + })); + if (!firstStatus.includes('7 entities') + || defaultLanding.hash !== '#order-center' + || defaultLanding.activeQuery !== 'order-center' + || defaultLanding.resultTitle !== 'Comprehensive: Order management center' + || !defaultLanding.hasOrderCenter + || !defaultLanding.tableViewActive + || !first.includes('Order Management Center') + || !first.includes('TQL-2026-1008') + || !first.includes('Shipped')) { + throw new Error(`Order center was not the default business page: ${JSON.stringify(defaultLanding)}\n${first}`); + } + const catalog = await page.$$eval('#query-catalog .query-group', groups => groups.map(group => ({ + title: group.querySelector('h2')?.textContent, + links: group.querySelectorAll('a').length, + }))); + if (catalog.length !== 4 || catalog.some(group => group.links < 3)) { + throw new Error(`Expected four query groups with at least three links: ${JSON.stringify(catalog)}`); + } + const rawResult = await page.$('#result pre'); + if (rawResult) throw new Error('Result regressed to a raw preformatted JSON block'); + const defaultSql = await page.$eval('#sql-output', element => element.textContent || ''); + if (!defaultSql.includes('SELECT') || !defaultSql.includes('customer_order_data') + || !defaultSql.includes('render order list page: load order list')) { + throw new Error(`Default order center did not render its business-to-SQL evidence:\n${defaultSql}`); + } + + const dashboard = await page.$eval('#result', element => element.textContent || ''); + const metricCount = await page.$$('#result .metric-card'); + const dashboardRows = await page.$$('#result .order-row:not(.order-row-head)'); + const dashboardColumns = await page.$$('#result .order-row-head > span'); + const productTitles = await page.$$eval('#result .product-thumb', elements => + elements.map(element => element.getAttribute('title') || '')); + const selectedColors = await page.$$eval('#result .metric-card:not(.metric-total)', elements => + elements.map(element => element.style.getPropertyValue('--metric-color'))); + const facetCards = await page.$$eval('#result .metric-card:not(.metric-total)', elements => + elements.map(element => ({ + name: element.querySelector('span')?.textContent || '', + count: element.querySelector('strong')?.textContent || '', + total: element.querySelector('small')?.textContent || '', + color: element.style.getPropertyValue('--metric-color'), + }))); + const cancelledMetric = await page.$eval('#result .metric-cancelled', element => ({ + text: element.textContent || '', + color: element.style.getPropertyValue('--metric-color'), + })); + const badgeColors = await page.$$eval('#result .status-badge', elements => + elements.map(element => element.style.color)); + if (!dashboard.includes('Order Management Center') || metricCount.length !== 6 + || dashboardRows.length !== 4 || dashboardColumns.length !== 4 + || !productTitles.some(title => title.includes('TeaQL Portable Keyboard')) + || !cancelledMetric.text.includes('Cancelled') || !cancelledMetric.text.includes('1') + || cancelledMetric.color !== '#9F1239' + || JSON.stringify(facetCards) !== JSON.stringify([ + { name: 'Pending payment', count: '1', total: 'Total 79.90', color: '#D97706' }, + { name: 'Paid', count: '2', total: 'Total 968.80', color: '#2563EB' }, + { name: 'Shipped', count: '2', total: 'Total 1,567.00', color: '#16A34A' }, + { name: 'Delivered', count: '2', total: 'Total 718.00', color: '#047857' }, + { name: 'Cancelled', count: '1', total: 'Total 159.00', color: '#9F1239' }, + ]) + || selectedColors.some(color => !color) || badgeColors.some(color => !color)) { + throw new Error('Comprehensive order center did not render metrics and the first paginated page'); + } + const dashboardSqlCount = await page.$$('#sql-output .evidence-row'); + if (dashboardSqlCount.length < 5) { + throw new Error(`Order center should expose every executed SQL statement, found ${dashboardSqlCount.length}`); + } + const evidenceRows = await page.$$eval('#sql-output .evidence-row', rows => rows.map(row => ({ + cells: row.querySelectorAll('td').length, + time: row.querySelector('.evidence-time')?.textContent || '', + identity: row.querySelector('td:nth-child(2)')?.textContent || '', + trace: row.querySelector('.evidence-trace')?.textContent || '', + sql: row.querySelector('.evidence-sql')?.textContent || '', + whiteSpace: getComputedStyle(row.querySelector('td')).whiteSpace, + }))); + const traceRoot = 'render order list page: load order list'; + if (evidenceRows.some(row => row.cells !== 4 || row.whiteSpace !== 'nowrap') + || evidenceRows.some(row => !row.time.includes('T') || !row.time.endsWith(' ms')) + || evidenceRows.some(row => !row.identity.startsWith('order-center · #')) + || evidenceRows.some(row => !row.trace.startsWith(traceRoot)) + || !evidenceRows.some(row => row.trace.endsWith("→ countAs('totalOrders')")) + || !evidenceRows.some(row => row.trace.endsWith('→ count items')) + || !evidenceRows.some(row => row.trace.endsWith('→ load status')) + || !evidenceRows.some(row => row.trace.endsWith('→ load item previews')) + || !evidenceRows.some(row => row.trace === `${traceRoot} → facetByStatusAs('statusCounts') → aggregate status`) + || !evidenceRows.some(row => row.trace === `${traceRoot} → facetByStatusAs('statusCounts') → load status facets`) + || evidenceRows.some(row => !row.sql.includes('SELECT') || !row.sql.includes(' · bindings: ')) + || evidenceRows.some(row => /[{}\[\]"]/.test(row.trace))) { + throw new Error(`Execution evidence was not rendered as plain one-line log text: ${JSON.stringify(evidenceRows)}`); + } + const reviewLayout = await page.$eval('#result-grid', grid => ({ + order: [...grid.children].map(child => child.className), + columns: getComputedStyle(grid).gridTemplateColumns.split(' ').length, + gridWidth: grid.getBoundingClientRect().width, + queryWidth: grid.querySelector('.query-card')?.getBoundingClientRect().width ?? 0, + evidenceColumns: [...grid.querySelectorAll('.execution-evidence th')].map(cell => cell.textContent || ''), + })); + if (reviewLayout.order.join('|') !== 'tree-card|query-card|sql-card' + || reviewLayout.columns !== 1 + || Math.abs(reviewLayout.gridWidth - reviewLayout.queryWidth) > 1 + || reviewLayout.evidenceColumns.join('|') !== 'Time|Identity|Trace chain|SQL') { + throw new Error(`Review layout or execution identity is incomplete: ${JSON.stringify(reviewLayout)}`); + } + const dashboardQuery = await page.$eval('#query-code', element => element.textContent || ''); + if (!dashboardQuery.includes('Q.customerOrdersWithMinimalFields()') + || !dashboardQuery.includes('Q.orderStatuses()') + || !dashboardQuery.includes('.selectColor()') + || !dashboardQuery.includes(".sumOrderTotalAmountAs('orderTotalAmount')") + || !dashboardQuery.includes(".facetByStatusAs('statusCounts'") + || !dashboardQuery.includes('.filterByJson(searchParams)') + || !dashboardQuery.includes('.executeForPage(ctx, pageOffset, pageSize)') + || dashboardQuery.includes('new SelectQuery') + || dashboardQuery.includes('.selectCode()') + || dashboardQuery.includes('Q.orderStatuses()\n') + || dashboardQuery.includes('Q.orderItems()\n') + || dashboardQuery.includes('selectPlatformWith') + || dashboardQuery.includes('selectCustomerWith')) { + throw new Error(`Order center must execute one generated Q expression:\n${dashboardQuery}`); + } + for (const implementationField of [ + '.selectId()', '.selectOrderId()', '.selectDisplayOrder()', '.selectSku()', + ]) { + if (dashboardQuery.includes(implementationField)) { + throw new Error(`Order center leaked runtime-only field ${implementationField}:\n${dashboardQuery}`); + } + } + const visualQueryOrder = [ + '.filterByJson(searchParams)', + ".countAs('totalOrders')", + ".facetByStatusAs('statusCounts'", + '.selectOrderNumber()', + '.selectOrderDate()', + '.selectStatusWith(', + '.selectItemListWith(', + '.executeForPage(ctx, pageOffset, pageSize)', + ].map(fragment => dashboardQuery.indexOf(fragment)); + if (visualQueryOrder.some(index => index < 0) + || visualQueryOrder.some((index, position) => position > 0 && index <= visualQueryOrder[position - 1])) { + throw new Error(`Q expression no longer follows the visual order:\n${dashboardQuery}`); + } + const dashboardSql = evidenceRows.map(row => row.sql).join('\n'); + if (!dashboardSql.includes('COUNT("id") AS "totalOrders"')) { + throw new Error(`countAs('totalOrders') did not reach the executed SQL:\n${dashboardSql}`); + } + if (!dashboardSql.includes('COUNT("id") AS "orderCount"') + || !dashboardSql.includes('SUM("total_amount") AS "orderTotalAmount"') + || !dashboardSql.includes('GROUP BY "status_id"')) { + throw new Error(`Status facet did not execute count and total amount in one grouped SQL query:\n${dashboardSql}`); + } + if (dashboardSql.includes('platform_data') || dashboardSql.includes('customer_data')) { + throw new Error(`Order center executed unused Platform/Customer queries:\n${dashboardSql}`); + } + if (!dashboardSql.includes('"color"') || dashboardSql.includes('"code"')) { + throw new Error(`Order status projection should select color, not code:\n${dashboardSql}`); + } + if (!dashboardSql.includes('order_item_data') || !dashboardSql.includes('order_id') + || !dashboardSql.includes('product_name') || dashboardSql.includes('"sku"')) { + throw new Error(`Order item projection was not derived from the public Q selection:\n${dashboardSql}`); + } + await page.click('#view-tree'); + await page.waitForFunction(() => document.querySelector('#result-view-label')?.textContent === 'Result tree' + && !!document.querySelector('#result details')); + const dashboardTree = await page.$eval('#result', element => element.textContent || ''); + if (!dashboardTree.includes('statusFacets') || !dashboardTree.includes('itemList')) { + throw new Error(`Dashboard Result Tree is incomplete:\n${dashboardTree}`); + } + await page.click('#view-table'); + await page.waitForFunction(() => document.querySelector('#result-view-label')?.textContent === 'Result table' + && !!document.querySelector('#result .order-center')); + await page.$$eval('#result .pagination button', buttons => + buttons.find(button => button.textContent === '2')?.click()); + await page.waitForFunction(() => !document.querySelector('#result')?.hasAttribute('aria-busy') + && document.querySelector('#result')?.textContent?.includes('Showing 5–8')); + const pageQuery = await page.$eval('#query-code', element => element.textContent || ''); + const pageParams = await page.$eval('#query-params-code', element => element.textContent || ''); + if (pageQuery !== dashboardQuery || !pageParams.includes('"pageOffset": 4')) { + throw new Error(`Pagination changed the Q expression instead of only its parameters:\n${pageParams}`); + } + await page.$$eval('#result .pagination button', buttons => + buttons.find(button => button.textContent === '1')?.click()); + await page.waitForFunction(() => !document.querySelector('#result')?.hasAttribute('aria-busy') + && document.querySelector('#result')?.textContent?.includes('Showing 1–4')); + await page.type('#result .order-search input', 'Keyboard'); + await page.click('#result .order-search button'); + await page.waitForFunction(() => !document.querySelector('#result')?.hasAttribute('aria-busy') + && document.querySelector('#result-meta')?.textContent?.includes('2 matching orders')); + const searchedDashboard = await page.$eval('#result', element => element.textContent || ''); + if (!searchedDashboard.includes('TQL-2026-1008') || !searchedDashboard.includes('TQL-2026-1001')) { + throw new Error(`Product subquery search did not return both keyboard orders:\n${searchedDashboard}`); + } + const searchedQuery = await page.$eval('#query-code', element => element.textContent || ''); + const searchedParams = await page.$eval('#query-params-code', element => element.textContent || ''); + if (searchedQuery !== dashboardQuery + || !searchedParams.includes('itemList.productName') + || !searchedParams.includes('Keyboard')) { + throw new Error(`Search changed the Q expression instead of only its parameters:\n${searchedQuery}\n${searchedParams}`); + } + const statusSql = await page.$$eval('#sql-output .evidence-sql', cells => cells + .map(cell => cell.textContent || '') + .join('\n')); + if (!statusSql.includes('order_status_data')) { + throw new Error(`OrderStatus relation/facet SQL was not executed:\n${statusSql}`); + } + await page.click('#result .metric-pending_payment'); + await page.waitForFunction(() => !document.querySelector('#result')?.hasAttribute('aria-busy') + && document.querySelector('#result-meta')?.textContent?.includes('1 matching order')); + const statusQuery = await page.$eval('#query-code', element => element.textContent || ''); + const statusParams = await page.$eval('#query-params-code', element => element.textContent || ''); + if (statusQuery !== dashboardQuery || !statusParams.includes('status.code') + || !statusParams.includes('PENDING_PAYMENT')) { + throw new Error(`Status selection changed the Q expression instead of only its parameters:\n${statusParams}`); + } + + await page.click('[data-query-id="order-detail"]'); + await page.waitForFunction(() => document.querySelector('#result-title')?.textContent === 'Complete order details' + && !document.querySelector('#result')?.hasAttribute('aria-busy')); + await page.click('#view-tree'); + await page.waitForSelector('#result details'); + await page.click('#expand-all'); + const detail = await page.$eval('#result', element => element.textContent || ''); + for (const value of ['TQL-2026-1003', 'White Porcelain Travel Tea Set', 'ALI-260906-11', 'SF2609061003']) { + if (!detail.includes(value)) throw new Error(`Complete order graph is missing ${value}`); + } + + await page.click('[data-query-id="orders-by-status"]'); + await page.waitForFunction(() => document.querySelector('#result-title')?.textContent === 'Orders by status' + && !document.querySelector('#result')?.hasAttribute('aria-busy')); + const summary = await page.$eval('#result', element => element.textContent || ''); + if (!summary.includes('grossAmount') || !summary.includes('averageOrderValue')) { + throw new Error(`Aggregation result is incomplete:\n${summary}`); + } + + await page.click('[data-query-id="dynamic-safe-fields"]'); + await page.waitForFunction(() => document.querySelector('#result-title')?.textContent === 'Dynamic: field allowlist' + && !document.querySelector('#result')?.hasAttribute('aria-busy')); + const dynamic = await page.$eval('#result', element => element.textContent || ''); + if (!dynamic.includes('DYNAMIC_SEARCH_UNKNOWN_FIELD') || !dynamic.includes('TQL-2026-1001')) { + throw new Error(`Dynamic search did not report an unknown field and execute valid clauses:\n${dynamic}`); + } + + const beforeLocaleSwitch = await page.evaluate(() => ({ + executionId: document.querySelector('.evidence-time')?.dataset.executedAt || '', + rows: [...document.querySelectorAll('#sql-output .evidence-row')].map(element => element.textContent || ''), + })); + await page.click('[data-locale="zh"]'); + await page.waitForFunction(() => document.documentElement.lang === 'zh-CN' + && document.querySelector('#result-title')?.textContent === '动态:字段白名单'); + const chineseLocale = await page.evaluate(() => ({ + title: document.querySelector('#query-browser-title')?.textContent || '', + evidenceTitle: document.querySelector('.sql-card-heading .query-card-label')?.textContent || '', + evidenceColumns: [...document.querySelectorAll('.execution-evidence th')].map(element => element.textContent || ''), + executionId: document.querySelector('.evidence-time')?.dataset.executedAt || '', + rows: [...document.querySelectorAll('#sql-output .evidence-row')].map(element => element.textContent || ''), + })); + if (chineseLocale.title !== '选择一个查询' + || chineseLocale.evidenceTitle !== '执行证据' + || chineseLocale.evidenceColumns.join('|') !== '时间|身份|追踪链|SQL' + || chineseLocale.executionId !== beforeLocaleSwitch.executionId + || JSON.stringify(chineseLocale.rows) !== JSON.stringify(beforeLocaleSwitch.rows)) { + throw new Error(`Chinese locale did not rerender safely: ${JSON.stringify(chineseLocale)}`); + } + await page.click('[data-locale="en"]'); + await page.waitForFunction(() => document.documentElement.lang === 'en' + && document.querySelector('#result-title')?.textContent === 'Dynamic: field allowlist'); + + const queryIds = await page.$$eval('[data-query-id]', links => links.map(link => link.dataset.queryId)); + for (const queryId of queryIds) { + await page.click(`[data-query-id="${queryId}"]`); + await page.waitForFunction(id => document.querySelector(`[data-query-id="${id}"]`)?.classList.contains('active') + && !document.querySelector('#result')?.hasAttribute('aria-busy'), {}, queryId); + const queryState = await page.evaluate(() => ({ + status: document.querySelector('#status')?.textContent || '', + meta: document.querySelector('#result-meta')?.textContent || '', + })); + if (!queryState.status.includes('ready') || queryState.meta.includes('失败') || queryState.meta.includes('failed')) { + throw new Error(`Query ${queryId} failed: ${JSON.stringify(queryState)}`); + } + const unexpectedChinese = await page.$eval('body', body => { + const copy = body.cloneNode(true); + copy.querySelector('[data-locale="zh"]')?.remove(); + return copy.textContent?.match(/[\u4e00-\u9fff]+/g) ?? []; + }); + if (unexpectedChinese.length) { + throw new Error(`English query ${queryId} still renders Chinese: ${unexpectedChinese.join(', ')}`); + } + } + + const beforeReset = await page.$eval('#result', element => element.textContent || ''); + await page.click('#reset'); + await page.waitForFunction(() => !document.querySelector('#reset')?.hasAttribute('disabled')); + const reset = await page.$eval('#result', element => element.textContent || ''); + if (reset !== beforeReset) throw new Error('Reset did not restore deterministic order data'); + + await page.click('#persist'); + await page.waitForFunction(() => { + const text = document.querySelector('#status')?.textContent || ''; + return text.startsWith('OPFS') && text.includes('ready'); + }, { timeout: 20_000 }); + const persisted = await page.$eval('#result', element => element.textContent || ''); + if (persisted !== beforeReset) throw new Error('OPFS did not receive deterministic order data'); + + await page.reload({ waitUntil: 'networkidle0' }); + await page.waitForFunction(() => { + const text = document.querySelector('#status')?.textContent || ''; + return text.startsWith('OPFS') && text.includes('ready'); + }, { timeout: 20_000 }); + const preference = await page.$eval('#persist', element => element.checked); + const afterReload = await page.$eval('#result', element => element.textContent || ''); + if (!preference || afterReload !== persisted) { + throw new Error('OPFS preference or data did not survive a browser reload'); + } + if (browserErrors.length) throw new Error(`Browser console errors:\n${browserErrors.join('\n')}`); + console.log('PASS generated Q queries, order center, executed SQL, result tree, all queries, OPFS, and reset'); +} finally { + await browser?.close(); + server.kill('SIGTERM'); +} diff --git a/source/teaql-ts/examples/browser-sqlite/src/generated/Q.ts b/source/teaql-ts/examples/browser-sqlite/src/generated/Q.ts new file mode 100644 index 0000000000000000000000000000000000000000..d7208fef9c851483a0fb906753200bfc391f4e63 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/src/generated/Q.ts @@ -0,0 +1,427 @@ +import { + mergeDynamicSearch, + OrderBy, + SelectQuery, + SmartList, + UserContext, + executeRelationFacets, + type QueryOperation, + type TeaQLPage, +} from 'teaql-ts'; +import { ORDER_STATUS } from '../order-model'; + +type Row = Record; +type DataService = { + executeQuery(query: SelectQuery): Promise; + executeCount(query: SelectQuery, alias?: string, operation?: QueryOperation): Promise; +}; + +const qString = (value: string): string => + `'${value.replaceAll('\\', '\\\\').replaceAll("'", "\\'").replaceAll('\n', '\\n')}'`; +const nestedQ = (request: GeneratedRequest): string => + request.toQExpression().replace(/\s*\n\s*/g, ''); + +const orderSearchModel = { + CustomerOrder: { + fields: { + id: 'integer', orderNumber: 'string', orderDate: 'date', status: 'integer', + totalAmount: 'decimal', currency: 'string', customerId: 'integer', platformId: 'integer', + }, + relations: { status: 'OrderStatus', itemList: 'OrderItem' }, + }, + OrderStatus: { + fields: { id: 'integer', name: 'string', code: 'string', color: 'string', displayOrder: 'integer' }, + relations: {}, + }, + OrderItem: { + fields: { id: 'integer', orderId: 'integer', productName: 'string', sku: 'string' }, + relations: {}, + }, +} as const; + +function normalizeOrderSearch(input: unknown): unknown { + if (!input || typeof input !== 'object' || Array.isArray(input)) return input; + const normalized = structuredClone(input as Record); + const candidate = normalized.filter; + if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate) || !('status' in candidate)) return normalized; + const filter = candidate as Record; + const status = filter.status; + const idFor = (code: unknown) => { + const id = ORDER_STATUS[String(code) as keyof typeof ORDER_STATUS]; + return id === undefined ? code : Number(id); + }; + if (status && typeof status === 'object' && !Array.isArray(status) && '$in' in status) { + filter.status = { $in: Array.isArray(status.$in) ? status.$in.map(idFor) : status.$in }; + } else { + filter.status = idFor(status); + } + return normalized; +} + +/** Generated domain request base. Application code should enter through Q, not SelectQuery. */ +abstract class GeneratedRequest { + protected readonly query: SelectQuery; + protected readonly filters: unknown[] = []; + private readonly qRoot: string; + private readonly qSteps: string[] = []; + private auditComment = ''; + private queryPurpose = ''; + private pageTotalAlias?: string; + + protected constructor(entity: string, qRoot: string) { + this.query = new SelectQuery(entity); + this.qRoot = qRoot; + } + + comment(value: string): this { + this.auditComment = value; + this.query.comment(value); + this.record(`comment(${qString(value)})`); + return this; + } + + purpose(value: string): this { + this.queryPurpose = value; + this.query.purpose(value); + this.record(`purpose(${qString(value)})`); + return this; + } + + limit(value: number): this { this.query.limit(value); this.record(`limit(${value})`); return this; } + offset(value: number): this { this.query.offset(value); this.record(`offset(${value})`); return this; } + + /** The expression is recorded by this exact request while it is being built. */ + toQExpression(terminal?: string): string { + const steps = terminal ? [...this.qSteps, terminal] : this.qSteps; + return [this.qRoot, ...steps.map(step => ` .${step}`)].join('\n'); + } + + toQuery(): SelectQuery { + const query = this.query.clone(); + if (this.filters.length) query.filter({ $and: [...this.filters] }); + return query; + } + + async executeForList(context: UserContext): Promise> { + this.ensureIntent(); + const service = this.service(context); + const query = this.toQuery(); + const rows = await service.executeQuery(context.prepareQuery(query)); + const data = new SmartList(rows); + if (query.facets.length) { + data.facets = await executeRelationFacets( + service, nested => context.prepareQuery(nested), query, query.facets, + ); + } + return data; + } + + async executeForRows(context: UserContext): Promise> { + return this.executeForList(context); + } + + async executeForPage(context: UserContext, offset: number, limit: number): Promise> { + this.ensureIntent(); + const service = this.service(context); + const countQuery = this.toQuery(); + // The runtime derives the count child request and its comment from this + // alias. Generated requests do not manufacture TraceChain text. + const totalCount = await service.executeCount( + countQuery, + this.pageTotalAlias, + this.pageTotalAlias + ? { kind: 'named-count', method: 'countAs', alias: this.pageTotalAlias } + : undefined, + ); + const pageQuery = this.toQuery().offset(offset).limit(limit); + const data = new SmartList( + await service.executeQuery(context.prepareQuery(pageQuery)), + { totalCount }, + ); + if (this.pageTotalAlias) data.aggregations[this.pageTotalAlias] = totalCount; + if (countQuery.facets.length) { + data.facets = await executeRelationFacets( + service, nested => context.prepareQuery(nested), countQuery, countQuery.facets, + ); + } + return { data, totalCount, offset, limit }; + } + protected addFilter(filter: unknown): this { this.filters.push(filter); return this; } + protected select(...fields: string[]): this { this.query.select(fields); return this; } + protected order(field: string, direction: 'asc' | 'desc'): this { + this.query.order(direction === 'asc' ? OrderBy.asc(field) : OrderBy.desc(field)); + return this; + } + protected group(field: string): this { this.query.groupBy(field); return this; } + protected aggregate(fn: string, field: string, alias: string): this { + this.query.aggregate(fn, field, alias); + return this; + } + protected record(step: string): this { this.qSteps.push(step); return this; } + protected includePageTotalAs(alias: string): this { + this.pageTotalAlias = alias; + return this; + } + + private service(context: UserContext): DataService { + return context.requireResource('dataService'); + } + + private ensureIntent(): void { + if (!this.auditComment.trim() || !this.queryPurpose.trim()) { + throw new Error('Generated Q requests require comment() and purpose() before execution'); + } + } +} + +export class PlatformRequest extends GeneratedRequest { + constructor() { super('Platform', 'Q.platforms()'); } + selectId(): this { return this.select('id'); } + selectName(): this { return this.select('name'); } + selectCode(): this { return this.select('code'); } + withIdIs(value: string): this { return this.addFilter({ id: { $eq: value } }); } +} + +export class CustomerRequest extends GeneratedRequest { + constructor() { super('Customer', 'Q.customers()'); } + selectId(): this { return this.select('id'); } + selectName(): this { return this.select('name'); } + selectCity(): this { return this.select('city'); } + selectTier(): this { return this.select('tier'); } + selectPlatformWith(request: PlatformRequest): this { + this.query.relationQuery('platform', request.toQuery(), 'platformId', 'id', false); + return this; + } + countOrderListAs(alias: string): this { + this.query.relationAggregate('orderList', alias, + new SelectQuery('CustomerOrder').aggregate('Count', 'id', alias)); + return this; + } + orderByNameAscending(): this { return this.order('name', 'asc'); } +} + +export class OrderItemRequest extends GeneratedRequest { + constructor() { super('OrderItem', 'Q.orderItems()'); } + selectId(): this { this.select('id'); return this.record('selectId()'); } + selectOrderId(): this { this.select('orderId'); return this.record('selectOrderId()'); } + selectProductName(): this { this.select('productName'); return this.record('selectProductName()'); } + selectSku(): this { this.select('sku'); return this.record('selectSku()'); } + selectQuantity(): this { this.select('quantity'); return this.record('selectQuantity()'); } + withProductNameContaining(value: string): this { + return this.addFilter({ productName: { $contains: value } }); + } + orderByIdAscending(): this { this.order('id', 'asc'); return this.record('orderByIdAscending()'); } + groupByProductName(): this { return this.group('productName'); } + sumQuantityAs(alias: string): this { return this.aggregate('Sum', 'quantity', alias); } + sumLineAmountAs(alias: string): this { return this.aggregate('Sum', 'lineAmount', alias); } + countAs(alias: string): this { return this.aggregate('Count', 'id', alias); } +} + +export class OrderStatusRequest extends GeneratedRequest { + constructor() { super('OrderStatus', 'Q.orderStatuses()'); } + selectId(): this { this.select('id'); return this.record('selectId()'); } + selectName(): this { this.select('name'); return this.record('selectName()'); } + selectCode(): this { this.select('code'); return this.record('selectCode()'); } + selectColor(): this { this.select('color'); return this.record('selectColor()'); } + selectDisplayOrder(): this { this.select('displayOrder'); return this.record('selectDisplayOrder()'); } + withCodeIs(value: string): this { return this.addFilter({ code: { $eq: value } }); } + countAs(alias: string): this { + this.aggregate('Count', 'id', alias); + return this.record(`countAs(${qString(alias)})`); + } + sumOrderTotalAmountAs(alias: string): this { + this.aggregate('Sum', 'totalAmount', alias); + return this.record(`sumOrderTotalAmountAs(${qString(alias)})`); + } + orderByDisplayOrderAscending(): this { + this.order('displayOrder', 'asc'); + return this.record('orderByDisplayOrderAscending()'); + } +} + +export class PaymentRequest extends GeneratedRequest { + constructor() { super('Payment', 'Q.payments()'); } + groupByCurrency(): this { return this.group('currency'); } + groupByProvider(): this { return this.group('provider'); } + groupByStatus(): this { return this.group('status'); } + countAs(alias: string): this { return this.aggregate('Count', 'id', alias); } + sumAmountAs(alias: string): this { return this.aggregate('Sum', 'amount', alias); } + orderByCurrencyAscending(): this { return this.order('currency', 'asc'); } + orderByProviderAscending(): this { return this.order('provider', 'asc'); } + orderByIdAscending(): this { return this.order('id', 'asc'); } +} + +export class ShipmentRequest extends GeneratedRequest { + constructor() { super('Shipment', 'Q.shipments()'); } + withStatusIn(...values: string[]): this { return this.addFilter({ status: { $in: values } }); } + selectOrderWith(request: CustomerOrderRequest): this { + this.query.relationQuery('order', request.toQuery(), 'orderId', 'id', false); + return this; + } + orderByStatusAscending(): this { return this.order('status', 'asc'); } + orderByIdAscending(): this { return this.order('id', 'asc'); } +} + +export class CustomerOrderRequest extends GeneratedRequest { + private dynamicWarnings: unknown[] = []; + private countAlias?: string; + private rowCountApplied = false; + + constructor(minimal = false) { + super('CustomerOrder', minimal ? 'Q.customerOrdersWithMinimalFields()' : 'Q.customerOrders()'); + if (minimal) this.query.select(['id', 'version']); + else { + this.query.select([ + 'id', 'orderNumber', 'orderDate', 'status', 'totalAmount', 'currency', + 'customerId', 'platformId', 'version', + ]); + } + } + selectId(): this { return this.select('id'); } + selectOrderNumber(): this { this.select('orderNumber'); return this.record('selectOrderNumber()'); } + selectOrderDate(): this { this.select('orderDate'); return this.record('selectOrderDate()'); } + selectStatus(): this { return this.select('status'); } + selectTotalAmount(): this { return this.select('totalAmount'); } + selectCurrency(): this { return this.select('currency'); } + withOrderNumberIs(value: string): this { return this.addFilter({ orderNumber: { $eq: value } }); } + withOrderNumberContaining(value: string): this { return this.addFilter({ orderNumber: { $contains: value } }); } + withStatusMatching(request: OrderStatusRequest): this { + return this.addFilter({ status: { $inSubquery: { query: request.toQuery(), field: 'id' } } }); + } + withStatusIsPendingPayment(): this { return this.addFilter({ status: { $eq: ORDER_STATUS.PENDING_PAYMENT } }); } + withStatusIsPaid(): this { return this.addFilter({ status: { $eq: ORDER_STATUS.PAID } }); } + withStatusIsShipped(): this { return this.addFilter({ status: { $eq: ORDER_STATUS.SHIPPED } }); } + withStatusIsDelivered(): this { return this.addFilter({ status: { $eq: ORDER_STATUS.DELIVERED } }); } + withStatusIsCancelled(): this { return this.addFilter({ status: { $eq: ORDER_STATUS.CANCELLED } }); } + withCurrencyIs(value: string): this { return this.addFilter({ currency: { $eq: value } }); } + withTotalAmountGreaterThanOrEqualTo(value: number): this { + return this.addFilter({ totalAmount: { $gte: value } }); + } + withOrderDateGreaterThanOrEqualTo(value: string): this { + return this.addFilter({ orderDate: { $gte: value } }); + } + withPlatformIdIs(value: string): this { return this.addFilter({ platformId: { $eq: value } }); } + withItemListMatching(request: OrderItemRequest): this { + return this.addFilter({ id: { $inSubquery: { query: request.toQuery(), field: 'orderId' } } }); + } + filterByJson(input: unknown): this { + const { query, warnings } = mergeDynamicSearch(this.toQuery(), normalizeOrderSearch(input), orderSearchModel, { + filter: (path, predicate) => { + if (path === 'status.code') { + return { status: { $inSubquery: { + query: new SelectQuery('OrderStatus').filter({ code: predicate }), field: 'id', + } } }; + } + if (path === 'itemList.productName') { + return { id: { $inSubquery: { + query: new SelectQuery('OrderItem').filter({ productName: predicate }), field: 'orderId', + } } }; + } + return { [path]: predicate }; + }, + order: (path, direction) => direction === 'asc' ? OrderBy.asc(path) : OrderBy.desc(path), + }); + this.dynamicWarnings = warnings; + this.query.filterCondition = query.filterCondition; + this.query.orderItems = [...query.orderItems]; + this.record('filterByJson(searchParams)'); + return this; + } + warnings(): readonly unknown[] { return this.dynamicWarnings; } + selectPlatformWith(request: PlatformRequest): this { + this.query.relationQuery('platform', request.toQuery(), 'platformId', 'id', false); + return this; + } + selectCustomerWith(request: CustomerRequest): this { + this.query.relationQuery('customer', request.toQuery(), 'customerId', 'id', false); + return this; + } + selectStatusWith(request: OrderStatusRequest): this { + this.query.select(['status']); + this.query.relationQuery('status', request.toQuery(), 'status', 'id', false, { + kind: 'relation-select', method: 'selectStatusWith', relation: 'status', + }); + return this.record(`selectStatusWith(${nestedQ(request)})`); + } + selectItemListWith(request: OrderItemRequest): this { + this.query.relationQuery('itemList', request.toQuery(), 'id', 'orderId', true, { + kind: 'relation-select', method: 'selectItemListWith', relation: 'itemList', + }); + return this.record(`selectItemListWith(${nestedQ(request)})`); + } + selectPaymentListWith(request: PaymentRequest): this { + this.query.relationQuery('paymentList', request.toQuery(), 'id', 'orderId', true); + return this; + } + selectShipmentListWith(request: ShipmentRequest): this { + this.query.relationQuery('shipmentList', request.toQuery(), 'id', 'orderId', true); + return this; + } + countItemListAs(alias: string): this { + this.query.relationAggregate('itemList', alias, + new SelectQuery('OrderItem').aggregate('Count', 'id', alias) + .comment('count items'), true, { + kind: 'relation-count', method: 'countItemListAs', relation: 'itemList', alias, + }); + return this.record(`countItemListAs(${qString(alias)})`); + } + facetByStatusAs(name: string, request: OrderStatusRequest, includeAllFacets = true): this { + const facet = request.toQuery(); + if (!facet.commentText) facet.comment('load status facets'); + this.query.facetBy(name, 'status', { toQuery: () => facet }, includeAllFacets, { + kind: 'facet', method: 'facetByStatusAs', relation: 'status', alias: name, + }); + return this.record(`facetByStatusAs(${qString(name)}, ${nestedQ(request)})`); + } + orderByOrderDateDescending(): this { + this.order('orderDate', 'desc'); + return this.record('orderByOrderDateDescending()'); + } + orderByOrderDateAscending(): this { return this.order('orderDate', 'asc'); } + orderByIdDescending(): this { this.order('id', 'desc'); return this.record('orderByIdDescending()'); } + orderByTotalAmountDescending(): this { return this.order('totalAmount', 'desc'); } + groupByCurrency(): this { return this.group('currency'); } + groupByStatus(): this { return this.group('status'); } + countAs(alias: string): this { + this.countAlias = alias; + return this.record(`countAs(${qString(alias)})`); + } + sumTotalAmountAs(alias: string): this { return this.aggregate('Sum', 'totalAmount', alias); } + averageTotalAmountAs(alias: string): this { return this.aggregate('Avg', 'totalAmount', alias); } + + override executeForList(context: UserContext): Promise> { + this.applyRowCount(); + return super.executeForList(context); + } + + override executeForRows(context: UserContext): Promise> { + this.applyRowCount(); + return super.executeForList(context); + } + + override executeForPage( + context: UserContext, + offset: number, + limit: number, + ): Promise> { + if (this.countAlias) this.includePageTotalAs(this.countAlias); + return super.executeForPage(context, offset, limit); + } + + private applyRowCount(): void { + if (!this.countAlias || this.rowCountApplied) return; + this.query.aggregate('Count', 'id', this.countAlias); + this.rowCountApplied = true; + } +} + +export class Q { + static platforms(): PlatformRequest { return new PlatformRequest(); } + static customers(): CustomerRequest { return new CustomerRequest(); } + static customerOrders(): CustomerOrderRequest { return new CustomerOrderRequest(); } + static customerOrdersWithMinimalFields(): CustomerOrderRequest { return new CustomerOrderRequest(true); } + static orderItems(): OrderItemRequest { return new OrderItemRequest(); } + static orderStatuses(): OrderStatusRequest { return new OrderStatusRequest(); } + static payments(): PaymentRequest { return new PaymentRequest(); } + static shipments(): ShipmentRequest { return new ShipmentRequest(); } +} diff --git a/source/teaql-ts/examples/browser-sqlite/src/main.ts b/source/teaql-ts/examples/browser-sqlite/src/main.ts new file mode 100644 index 0000000000000000000000000000000000000000..2bd68ea67295da25f04d27c10e917a7c48038f9e --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/src/main.ts @@ -0,0 +1,1220 @@ +import { + BrowserSQLiteStorage, + BrowserSQLiteTeaQLClient, +} from 'teaql-ts/sql/browser-sqlite'; +import { + SQLExecutionEvidenceStore, + SQLExecutionMetadata, +} from 'teaql-ts/sql/core'; +import { + DelegatingMutationPolicyApprovalProvider, + DelegatingMutationPolicyRegistry, + MutationIntent, + RuntimeModule, + UserContext, +} from 'teaql-ts'; +import { ORDER_SCHEMAS, ORDER_SEED, ORDER_STATUS, ORDER_STATUS_CONSTANTS } from './order-model'; +import { Q } from './generated/Q'; +import './style.css'; + +const status = document.querySelector('#status')!; +const persist = document.querySelector('#persist')!; +const reset = document.querySelector('#reset')!; +const queryCatalog = document.querySelector('#query-catalog')!; +const result = document.querySelector('#result')!; +const resultTitle = document.querySelector('#result-title')!; +const resultDescription = document.querySelector('#result-description')!; +const resultMeta = document.querySelector('#result-meta')!; +const queryCode = document.querySelector('#query-code')!; +const queryParamsBlock = document.querySelector('#query-params-block')!; +const queryParamsCode = document.querySelector('#query-params-code')!; +const resultGrid = document.querySelector('#result-grid')!; +const resultViewLabel = document.querySelector('#result-view-label')!; +const sqlCount = document.querySelector('#sql-count')!; +const sqlOutput = document.querySelector('#sql-output')!; +const expandAll = document.querySelector('#expand-all')!; +const collapseAll = document.querySelector('#collapse-all')!; +const viewTable = document.querySelector('#view-table')!; +const viewTree = document.querySelector('#view-tree')!; +const languageButtons = Array.from(document.querySelectorAll('[data-locale]')); + +type Runtime = { + client: BrowserSQLiteTeaQLClient; + context: UserContext; + evidence: SQLExecutionEvidenceStore; +}; +type QueryView = 'tree' | 'dashboard'; +type ResultView = 'table' | 'tree'; +type QueryExample = Readonly<{ + id: string; + title: string; + description: string; + code: string; + view?: QueryView; + run(active: Runtime): Promise; +}>; +type QueryGroup = Readonly<{ + label: string; + description: string; + queries: readonly QueryExample[]; +}>; + +type Locale = 'en' | 'zh'; +type LocalizedCopy = Readonly<{ en: string; zh: string }>; + +const UI_COPY: Readonly> = { + heroTitle: { en: 'Understand TeaQL queries through a familiar order model.', zh: '用一个熟悉的订单模型,看懂 TeaQL 查询。' }, + heroIntro: { en: 'Platform, customer, order, item, payment, and shipment data all run in the browser. Order status is backed by a constant model. Choose a query below to inspect real SQLite/WASM results.', zh: '平台、用户、订单、明细、支付和物流数据都在浏览器中运行;订单状态由常数模型提供。选择下面的查询,查看真实的 SQLite/WASM 结果。' }, + platform: { en: 'Platform', zh: '平台' }, customer: { en: 'Customer', zh: '用户' }, + order: { en: 'Order', zh: '订单' }, item: { en: 'Item', zh: '明细' }, + payment: { en: 'Payment', zh: '支付' }, shipment: { en: 'Shipment', zh: '物流' }, + constantModel: { en: 'Constant model', zh: '常数模型' }, + persist: { en: 'Persist locally with OPFS', zh: '使用 OPFS 保存在本地' }, + reset: { en: 'Reset demo data', zh: '重置演示数据' }, + chooseQuery: { en: 'Choose a query', zh: '选择一个查询' }, + queryIntro: { en: 'Queries are grouped by purpose and share the same order dataset.', zh: '查询按用途分组,并共用同一份订单数据。' }, + table: { en: 'Table', zh: '表格' }, resultTree: { en: 'Result Tree', zh: '结果树' }, + expandAll: { en: 'Expand all', zh: '全部展开' }, + collapseAll: { en: 'Collapse all', zh: '全部折叠' }, waiting: { en: 'Waiting for query…', zh: '等待查询…' }, + queryNote: { en: 'The Q expression stays fixed; search, status cards, and pagination only update dynamic parameters. The underlying SelectQuery remains inside the generated request implementation.', zh: 'Q 表达式保持不变;搜索、状态卡片和分页只更新动态参数。底层 SelectQuery 仍封装在生成的请求实现中。' }, + executionEvidence: { en: 'EXECUTION EVIDENCE', zh: '执行证据' }, + evidenceTime: { en: 'Time', zh: '时间' }, identity: { en: 'Identity', zh: '身份' }, + traceChain: { en: 'Trace chain', zh: '追踪链' }, + sqlNote: { en: 'One plain-text line per statement: time, identity, trace chain, and the SQL SQLite executed.', zh: '每条语句使用一行纯文本:时间、身份、追踪链,以及 SQLite 实际执行的 SQL。' }, + localData: { en: 'Data stays in this browser', zh: '数据只保留在当前浏览器中' }, +}; + +const EN_TEXT: Readonly> = { + '基本查询': 'Basic queries', + '从订单、用户和关联对象开始': 'Start with orders, customers, and related objects', + '汇总查询': 'Aggregations', + '分组、计数、求和与平均值': 'Grouping, counts, sums, and averages', + '过滤查询': 'Filtered queries', + '精确、范围与组合条件': 'Exact, range, and combined predicates', + '动态查询': 'Dynamic queries', + '由页面条件安全生成,不使用 eval': 'Safely generated from page criteria without eval', + '综合:订单管理中心': 'Comprehensive: Order management center', + '一个真实的综合查询页面:状态指标、搜索、商品预览和分页都由 TeaQL 查询驱动。': 'A real composite query page: status metrics, search, product previews, and pagination are all driven by TeaQL.', + '最近订单': 'Recent orders', + '按下单日期倒序浏览全部订单,并带出所属平台与用户。': 'Browse all orders by date descending, including their platform and customer.', + '完整订单详情': 'Complete order details', + '查看一个订单及其用户、商品明细、支付和物流,体现完整对象图。': 'Inspect one order with its customer, items, payments, and shipments as a complete object graph.', + '用户与订单数': 'Customers with order counts', + '列出用户,并通过关联汇总显示每位用户的订单数量。': 'List customers and show each customer’s order count through a relation aggregate.', + '订单状态汇总': 'Orders by status', + '按币种与订单状态统计订单数、总额和平均客单价。': 'Aggregate order count, gross amount, and average order value by currency and status.', + '商品销售汇总': 'Product sales summary', + '按商品汇总销量与销售额,找出最受欢迎的订单明细。': 'Aggregate units and revenue by product to identify the most popular order items.', + '支付渠道对账': 'Payment reconciliation', + '按币种、支付渠道和状态汇总笔数与金额。': 'Aggregate transaction count and amount by currency, payment provider, and status.', + '待支付订单': 'Orders awaiting payment', + '筛选尚未完成付款的订单,并带出对应支付记录。': 'Find orders that have not completed payment and include their payment records.', + '国内大额订单': 'High-value domestic orders', + '组合平台与金额条件,找出 TeaQL 商城中金额不低于 500 元的订单。': 'Combine platform and amount filters to find TeaQL Store orders worth at least CNY 500.', + '运输中的包裹': 'Active shipments', + '筛选待揽收和运输中的物流单,并关联订单信息。': 'Find shipments that are ready or in transit and include their order information.', + '动态:已付款国内订单': 'Dynamic: paid domestic orders', + '从动态条件对象生成查询:人民币、金额至少 250,且状态为已付款或已发货。': 'Build a query from dynamic criteria: CNY, at least 250, and status PAID or SHIPPED.', + '动态:九月新订单': 'Dynamic: new September orders', + '运行时传入日期范围与排序方式,查询 9 月 15 日之后的订单。': 'Pass a date range and sort order at runtime to find orders after September 15.', + '动态:字段白名单': 'Dynamic: field allowlist', + '未知字段会被报告并忽略;合法条件仍可安全执行。': 'Unknown fields are reported and ignored while valid predicates still execute safely.', +}; + +let locale: Locale = localStorage.getItem('teaql-browser-locale') === 'zh' ? 'zh' : 'en'; + +function copy(key: string): string { + return UI_COPY[key]?.[locale] ?? key; +} + +function localize(value: string): string { + return locale === 'en' ? EN_TEXT[value] ?? value : value; +} + +let runtime: Runtime | undefined; +let activeQueryId = window.location.hash.slice(1) || 'order-center'; +if (!window.location.hash) history.replaceState(null, '', '#order-center'); +let activeResultView: ResultView = 'tree'; +let currentResult: { data: unknown; query: QueryExample; active: Runtime } | undefined; +let lastElapsed = 0; +let lastExecutedAt: Date | undefined; +const dashboardState = { search: '', page: 0, pageSize: 4 }; +const storagePreference = localStorage.getItem('teaql-browser-storage') === 'opfs' ? 'opfs' : 'memory'; +persist.checked = storagePreference === 'opfs'; + +async function dynamicOrderQuery( + active: Runtime, + input: unknown, +): Promise<{ request: unknown; warnings: readonly unknown[]; data: unknown[] }> { + const request = Q.customerOrders() + .filterByJson(input) + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery'); + const data = await request.executeForList(active.context); + return { request: input, warnings: request.warnings(), data }; +} + +type DashboardData = Readonly<{ + orders: ReadonlyArray>; + totalOrders: number; + filteredOrders: number; + statusFacets: ReadonlyArray>; + search: string; + page: number; + pageSize: number; + queryExpression: string; +}>; + +const statusCodeById = Object.fromEntries( + Object.entries(ORDER_STATUS).map(([code, id]) => [id, code]), +) as Readonly>; + +function statusCodeFor(status: Record): string { + const selectedCode = String(status.code ?? ''); + if (selectedCode && selectedCode in ORDER_STATUS) return selectedCode; + if (!('color' in status)) return ''; + return statusCodeById[String(status.id ?? '')] ?? ''; +} + +function orderCenterSearchParams(search: string): Record { + const value = search.trim(); + if (!value) return { filter: {} }; + const upper = value.toUpperCase(); + const status = ['PENDING_PAYMENT', 'PAID', 'SHIPPED', 'DELIVERED', 'CANCELLED'] + .find(candidate => candidate.includes(upper)); + if (status) return { filter: { 'status.code': status } }; + if (/^(TQL-|\d)/i.test(value)) return { filter: { orderNumber: { $contains: upper } } }; + return { filter: { 'itemList.productName': { $contains: value } } }; +} + +async function runOrderCenter(active: Runtime): Promise { + const searchParams = orderCenterSearchParams(dashboardState.search); + const request = Q.customerOrdersWithMinimalFields() + .filterByJson(searchParams) + .countAs('totalOrders') + .facetByStatusAs('statusCounts', Q.orderStatuses().selectName().selectColor().countAs('orderCount').sumOrderTotalAmountAs('orderTotalAmount').orderByDisplayOrderAscending().comment('load status facets')) + .selectOrderNumber() + .selectOrderDate() + .selectStatusWith(Q.orderStatuses().selectName().selectColor().comment('load status')) + .selectItemListWith(Q.orderItems().selectProductName().selectQuantity().orderByIdAscending().limit(3).comment('load item previews')) + .countItemListAs('itemCount') + .orderByOrderDateDescending() + .orderByIdDescending() + .comment('load order list') + .purpose('render order list page'); + const page = await request.executeForPage( + active.context, + dashboardState.page * dashboardState.pageSize, + dashboardState.pageSize, + ); + const statusRows = page.data.facet('statusCounts') ?? []; + return { + orders: page.data, + totalOrders: Number(page.data.aggregations.totalOrders ?? page.totalCount), + filteredOrders: page.totalCount, + statusFacets: statusRows.map(row => ({ + code: statusCodeFor(row), + name: String(row.name ?? ''), + color: String(row.color ?? ''), + orderCount: Number(row.orderCount ?? 0), + orderTotalAmount: Number(row.orderTotalAmount ?? 0), + })).filter(status => status.code && status.name), + search: dashboardState.search, + page: dashboardState.page, + pageSize: dashboardState.pageSize, + queryExpression: request.toQExpression('executeForPage(ctx, pageOffset, pageSize);'), + }; +} + +const QUERY_GROUPS: readonly QueryGroup[] = [ + { + label: '基本查询', + description: '从订单、用户和关联对象开始', + queries: [ + { + id: 'order-center', + title: '综合:订单管理中心', + description: '一个真实的综合查询页面:状态指标、搜索、商品预览和分页都由 TeaQL 查询驱动。', + code: '', + view: 'dashboard', + run: runOrderCenter, + }, + { + id: 'recent-orders', + title: '最近订单', + description: '按下单日期倒序浏览全部订单,并带出所属平台与用户。', + code: `await Q.customerOrders() + .selectPlatformWith(Q.platforms().selectName()) + .selectCustomerWith(Q.customers().selectName().selectCity().selectTier()) + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .orderByOrderDateDescending() + .orderByIdDescending() + .limit(8) + .comment('what: list recent commerce orders') + .purpose('why: provide the default order overview') + .executeForList(ctx)`, + run: active => Q.customerOrders() + .selectPlatformWith(Q.platforms().selectName()) + .selectCustomerWith(Q.customers().selectName().selectCity().selectTier()) + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .orderByOrderDateDescending() + .orderByIdDescending() + .limit(8) + .comment('what: list recent commerce orders') + .purpose('why: provide the default order overview') + .executeForList(active.context), + }, + { + id: 'order-detail', + title: '完整订单详情', + description: '查看一个订单及其用户、商品明细、支付和物流,体现完整对象图。', + code: `await Q.customerOrders() + .withOrderNumberIs('TQL-2026-1003') + .selectPlatformWith(Q.platforms()) + .selectCustomerWith(Q.customers()) + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectItemListWith(Q.orderItems().orderByIdAscending()) + .selectPaymentListWith(Q.payments().orderByIdAscending()) + .selectShipmentListWith(Q.shipments().orderByIdAscending()) + .limit(1) + .comment('what: load one complete order graph') + .purpose('why: inspect items, payment and fulfillment together') + .executeForList(ctx)`, + run: active => Q.customerOrders() + .withOrderNumberIs('TQL-2026-1003') + .selectPlatformWith(Q.platforms()) + .selectCustomerWith(Q.customers()) + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectItemListWith(Q.orderItems().orderByIdAscending()) + .selectPaymentListWith(Q.payments().orderByIdAscending()) + .selectShipmentListWith(Q.shipments().orderByIdAscending()) + .limit(1) + .comment('what: load one complete order graph') + .purpose('why: inspect items, payment and fulfillment together') + .executeForList(active.context), + }, + { + id: 'customers-with-order-count', + title: '用户与订单数', + description: '列出用户,并通过关联汇总显示每位用户的订单数量。', + code: `await Q.customers() + .selectPlatformWith(Q.platforms().selectName()) + .countOrderListAs('orderCount') + .orderByNameAscending() + .comment('what: list customers with related order counts') + .purpose('why: compare customer activity at a glance') + .executeForList(ctx)`, + run: active => Q.customers() + .selectPlatformWith(Q.platforms().selectName()) + .countOrderListAs('orderCount') + .orderByNameAscending() + .comment('what: list customers with related order counts') + .purpose('why: compare customer activity at a glance') + .executeForList(active.context), + }, + ], + }, + { + label: '汇总查询', + description: '分组、计数、求和与平均值', + queries: [ + { + id: 'orders-by-status', + title: '订单状态汇总', + description: '按币种与订单状态统计订单数、总额和平均客单价。', + code: `await Q.customerOrders() + .groupByCurrency().groupByStatus() + .countAs('orderCount') + .sumTotalAmountAs('grossAmount') + .averageTotalAmountAs('averageOrderValue') + .comment('what: aggregate orders by currency and status') + .purpose('why: show the current order funnel') + .executeForRows(ctx)`, + run: active => Q.customerOrders() + .groupByCurrency().groupByStatus() + .countAs('orderCount') + .sumTotalAmountAs('grossAmount') + .averageTotalAmountAs('averageOrderValue') + .comment('what: aggregate orders by currency and status') + .purpose('why: show the current order funnel') + .executeForRows(active.context), + }, + { + id: 'product-sales', + title: '商品销售汇总', + description: '按商品汇总销量与销售额,找出最受欢迎的订单明细。', + code: `await Q.orderItems() + .groupByProductName() + .sumQuantityAs('units') + .sumLineAmountAs('revenue') + .comment('what: aggregate sold units and line revenue') + .purpose('why: identify the strongest products in the demo data') + .executeForRows(ctx)`, + run: active => Q.orderItems() + .groupByProductName() + .sumQuantityAs('units') + .sumLineAmountAs('revenue') + .comment('what: aggregate sold units and line revenue') + .purpose('why: identify the strongest products in the demo data') + .executeForRows(active.context), + }, + { + id: 'payment-reconciliation', + title: '支付渠道对账', + description: '按币种、支付渠道和状态汇总笔数与金额。', + code: `await Q.payments() + .groupByCurrency().groupByProvider().groupByStatus() + .countAs('paymentCount').sumAmountAs('paymentAmount') + .orderByCurrencyAscending().orderByProviderAscending() + .comment('what: reconcile payment totals by provider') + .purpose('why: compare captured, pending and refunded money') + .executeForRows(ctx)`, + run: active => Q.payments() + .groupByCurrency().groupByProvider().groupByStatus() + .countAs('paymentCount').sumAmountAs('paymentAmount') + .orderByCurrencyAscending().orderByProviderAscending() + .comment('what: reconcile payment totals by provider') + .purpose('why: compare captured, pending and refunded money') + .executeForRows(active.context), + }, + ], + }, + { + label: '过滤查询', + description: '精确、范围与组合条件', + queries: [ + { + id: 'pending-payment', + title: '待支付订单', + description: '筛选尚未完成付款的订单,并带出对应支付记录。', + code: `await Q.customerOrders() + .withStatusIsPendingPayment() + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectCustomerWith(Q.customers().selectName()) + .selectPaymentListWith(Q.payments()) + .comment('what: find orders awaiting payment') + .purpose('why: support payment follow-up') + .executeForList(ctx)`, + run: active => Q.customerOrders() + .withStatusIsPendingPayment() + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectCustomerWith(Q.customers().selectName()) + .selectPaymentListWith(Q.payments()) + .comment('what: find orders awaiting payment') + .purpose('why: support payment follow-up') + .executeForList(active.context), + }, + { + id: 'large-cn-orders', + title: '国内大额订单', + description: '组合平台与金额条件,找出 TeaQL 商城中金额不低于 500 元的订单。', + code: `await Q.customerOrders() + .withPlatformIdIs('1') + .withTotalAmountGreaterThanOrEqualTo(500) + .selectCustomerWith(Q.customers().selectName().selectCity()) + .orderByTotalAmountDescending() + .comment('what: find high-value domestic orders') + .purpose('why: prioritize valuable fulfillment work') + .executeForList(ctx)`, + run: active => Q.customerOrders() + .withPlatformIdIs('1') + .withTotalAmountGreaterThanOrEqualTo(500) + .selectCustomerWith(Q.customers().selectName().selectCity()) + .orderByTotalAmountDescending() + .comment('what: find high-value domestic orders') + .purpose('why: prioritize valuable fulfillment work') + .executeForList(active.context), + }, + { + id: 'open-shipments', + title: '运输中的包裹', + description: '筛选待揽收和运输中的物流单,并关联订单信息。', + code: `await Q.shipments() + .withStatusIn('READY', 'IN_TRANSIT') + .selectOrderWith(Q.customerOrders().selectOrderNumber().selectOrderDate().selectStatusWith(Q.orderStatuses().selectName().selectColor()).selectTotalAmount().selectCurrency()) + .orderByStatusAscending().orderByIdAscending() + .comment('what: find shipments that are not delivered') + .purpose('why: monitor active fulfillment') + .executeForList(ctx)`, + run: active => Q.shipments() + .withStatusIn('READY', 'IN_TRANSIT') + .selectOrderWith(Q.customerOrders() + .selectOrderNumber().selectOrderDate() + .selectStatusWith(Q.orderStatuses().selectName().selectColor()) + .selectTotalAmount().selectCurrency()) + .orderByStatusAscending().orderByIdAscending() + .comment('what: find shipments that are not delivered') + .purpose('why: monitor active fulfillment') + .executeForList(active.context), + }, + ], + }, + { + label: '动态查询', + description: '由页面条件安全生成,不使用 eval', + queries: [ + { + id: 'dynamic-paid-cn', + title: '动态:已付款国内订单', + description: '从动态条件对象生成查询:人民币、金额至少 250,且状态为已付款或已发货。', + code: `const input = { + "filter": { + "currency": "CNY", + "totalAmount": { "$gte": 250 }, + "status": { "$in": ["PAID", "SHIPPED"] } + }, + "orderBy": [{ "field": "totalAmount", "direction": "desc" }] +}; +const data = await Q.customerOrders() + .filterByJson(input) + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx);`, + run: active => dynamicOrderQuery(active, { + filter: { + currency: 'CNY', + totalAmount: { $gte: 250 }, + status: { $in: ['PAID', 'SHIPPED'] }, + }, + orderBy: [{ field: 'totalAmount', direction: 'desc' }], + }), + }, + { + id: 'dynamic-date-range', + title: '动态:九月新订单', + description: '运行时传入日期范围与排序方式,查询 9 月 15 日之后的订单。', + code: `const input = { + "filter": { "orderDate": { "$gte": "2026-09-15" } }, + "orderBy": [{ "field": "orderDate", "direction": "asc" }] +}; +const data = await Q.customerOrders() + .filterByJson(input) + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx);`, + run: active => dynamicOrderQuery(active, { + filter: { orderDate: { $gte: '2026-09-15' } }, + orderBy: [{ field: 'orderDate', direction: 'asc' }], + }), + }, + { + id: 'dynamic-safe-fields', + title: '动态:字段白名单', + description: '未知字段会被报告并忽略;合法条件仍可安全执行。', + code: `const input = { + "filter": { + "status": "DELIVERED", + "internalNote": { "$contains": "not queryable" } + } +}; +const request = Q.customerOrders().filterByJson(input); +const data = await request + .limit(20) + .comment('what: execute a validated browser search') + .purpose('why: demonstrate safe dynamic order discovery') + .executeForList(ctx); +const warnings = request.warnings();`, + run: active => dynamicOrderQuery(active, { + filter: { + status: 'DELIVERED', + internalNote: { $contains: 'not queryable' }, + }, + }), + }, + ], + }, +] as const; + +const allQueries = QUERY_GROUPS.flatMap(group => group.queries); + +async function openRuntime(storage: BrowserSQLiteStorage): Promise { + const worker = new Worker(new URL('./sqlite.worker.ts', import.meta.url), { type: 'module' }); + const client = await BrowserSQLiteTeaQLClient.open(worker, { ...ORDER_SCHEMAS }, { + storage, + databaseName: 'teaql-order-playground-v3.sqlite3', + }); + const evidence = new SQLExecutionEvidenceStore().enableSelect(); + client.install(new RuntimeModule(ORDER_SCHEMAS, {}, { + constants: ORDER_STATUS_CONSTANTS, + })); + client.setRuntimeTelemetrySink(evidence).setDiagnosticSQLLogSink(undefined); + const policyIdentity = Object.freeze({ + policyId: 'browser-order-demo-seed', + version: '1', + fingerprint: 'sha256:browser-order-demo-seed-v1', + }); + const context = new UserContext() + .insertResource('dataService', client) + .withMutationPolicyRegistry(new DelegatingMutationPolicyRegistry(() => ({ + identity: policyIdentity, + review: (_context, plan) => plan.operations.length > 0 + ? { verdict: 'allow' } + : { verdict: 'deny', code: 'EMPTY_GRAPH', message: 'empty mutation graph' }, + }))) + .withMutationPolicyApprovalProvider(new DelegatingMutationPolicyApprovalProvider( + identity => ({ policy: identity, approvedBy: 'browser-demo-owner', approvedAt: new Date() }), + )); + client.setUserContext(context); + await context.ensureSchema(); + return { client, context, evidence }; +} + +async function seedDemoData(active: Runtime): Promise { + const existing = await Q.customerOrders() + .selectId() + .limit(1) + .comment('what: detect existing order playground data') + .purpose('why: keep deterministic browser bootstrap idempotent') + .executeForList(active.context); + if (existing.length) return; + const intent = new MutationIntent('Seed deterministic order playground data'); + await active.client.executeGraphSave(intent, async graph => { + const requests = ORDER_SEED.map(record => graph.request({ + entity: record.entity, + action: 'Create', + id: record.id, + payload: record.payload, + })); + for (const request of requests) active.client.preflightMutation(request); + for (const request of requests) await active.client.executeMutation(request); + }); +} + +function renderQueryCatalog(): void { + queryCatalog.replaceChildren(); + for (const group of QUERY_GROUPS) { + const section = document.createElement('section'); + section.className = 'query-group'; + const heading = document.createElement('div'); + heading.className = 'query-group-heading'; + const title = document.createElement('h2'); + title.textContent = localize(group.label); + const description = document.createElement('p'); + description.textContent = localize(group.description); + heading.append(title, description); + const links = document.createElement('div'); + links.className = 'query-links'; + for (const query of group.queries) { + const link = document.createElement('a'); + link.href = `#${query.id}`; + link.dataset.queryId = query.id; + link.textContent = localize(query.title); + link.addEventListener('click', event => { + event.preventDefault(); + activeQueryId = query.id; + history.replaceState(null, '', `#${query.id}`); + updateActiveLink(); + if (runtime) runQuery(query, runtime).catch(showError); + }); + links.append(link); + } + section.append(heading, links); + queryCatalog.append(section); + } + updateActiveLink(); +} + +function updateActiveLink(): void { + queryCatalog.querySelectorAll('a[data-query-id]').forEach(link => { + const active = link.dataset.queryId === activeQueryId; + link.classList.toggle('active', active); + if (active) link.setAttribute('aria-current', 'page'); + else link.removeAttribute('aria-current'); + }); +} + +async function runQuery(query: QueryExample, active: Runtime): Promise { + const startedAt = performance.now(); + const executedAt = new Date(); + active.evidence.enableSelect(); + result.classList.add('loading'); + result.setAttribute('aria-busy', 'true'); + resultTitle.textContent = localize(query.title); + resultDescription.textContent = localize(query.description); + queryCode.textContent = query.code; + queryParamsBlock.classList.toggle('hidden', query.view !== 'dashboard'); + queryParamsCode.textContent = query.view === 'dashboard' + ? JSON.stringify({ + searchParams: orderCenterSearchParams(dashboardState.search), + pageOffset: dashboardState.page * dashboardState.pageSize, + pageSize: dashboardState.pageSize, + }, null, 2) + : ''; + resultGrid.classList.toggle('dashboard-mode', query.view === 'dashboard'); + result.classList.toggle('dashboard-result', query.view === 'dashboard'); + expandAll.closest('.tree-actions')?.classList.toggle('hidden', query.view === 'dashboard'); + resultViewLabel.textContent = query.view === 'dashboard' + ? (locale === 'en' ? 'Order management center' : '订单管理中心') + : (locale === 'en' ? 'Result tree' : '结果树'); + resultMeta.textContent = locale === 'en' ? 'Running query…' : '查询中…'; + try { + const data = await query.run(active); + if (query.view === 'dashboard') { + queryCode.textContent = (data as DashboardData).queryExpression; + } + currentResult = { data, query, active }; + activeResultView = query.view === 'dashboard' || isTabularResult(data) ? 'table' : 'tree'; + renderCurrentResult(); + const elapsed = Math.max(1, Math.round(performance.now() - startedAt)); + lastElapsed = elapsed; + lastExecutedAt = executedAt; + const statements = active.evidence.snapshot(); + renderSql(statements, executedAt); + updateResultMeta(data, query, elapsed); + } finally { + result.classList.remove('loading'); + result.removeAttribute('aria-busy'); + } +} + +function renderSql(statements: readonly SQLExecutionMetadata[], executedAt = lastExecutedAt): void { + sqlOutput.replaceChildren(); + sqlCount.textContent = locale === 'en' + ? `${statements.length} statement${statements.length === 1 ? '' : 's'}` + : `${statements.length} 条语句`; + statements.forEach((statement, index) => { + const row = document.createElement('tr'); + row.className = 'evidence-row'; + const traceIdentity = [...statement.tracePath].reverse() + .find(frame => frame.kind === 'relation' || frame.kind === 'request' || frame.kind === 'entity'); + const timeCell = document.createElement('td'); + timeCell.className = 'evidence-time'; + timeCell.dataset.executedAt = executedAt?.toISOString() ?? ''; + timeCell.textContent = `${executedAt?.toISOString() ?? '—'} · ${Math.max(0.01, statement.elapsedMicros / 1000).toFixed(2)} ms`; + const identityCell = document.createElement('td'); + identityCell.textContent = `${currentResult?.query.id ?? 'query'} · #${index + 1} · ${traceIdentity?.name ?? 'query'}`; + const traceCell = document.createElement('td'); + traceCell.className = 'evidence-trace'; + if (statement.traceChain?.length) { + const purpose = statement.traceChain.find(node => node.kind === 'purpose'); + const comments = statement.traceChain + .filter(node => node.kind === 'comment') + .map(node => node.detail || node.name); + traceCell.textContent = `${purpose?.detail || purpose?.name || ''}: ${comments.join(' → ')}`; + } else { + traceCell.textContent = statement.tracePath.map(frame => frame.detail || frame.name).join(' → '); + } + const sqlCell = document.createElement('td'); + sqlCell.className = 'evidence-sql'; + const bindings = statement.parameters.length + ? statement.parameters.map(value => String(value)).join(', ') + : 'none'; + sqlCell.textContent = `${statement.parameterizedSQL} · bindings: ${bindings}`; + row.append(timeCell, identityCell, traceCell, sqlCell); + sqlOutput.append(row); + }); +} + +function isTabularResult(value: unknown): value is ReadonlyArray> { + return Array.isArray(value) && value.every(row => row !== null && typeof row === 'object' && !Array.isArray(row)); +} + +function renderCurrentResult(): void { + if (!currentResult) return; + const { data, query, active } = currentResult; + const tableAvailable = query.view === 'dashboard' || isTabularResult(data); + if (!tableAvailable) activeResultView = 'tree'; + viewTable.disabled = !tableAvailable; + viewTable.classList.toggle('active', activeResultView === 'table'); + viewTree.classList.toggle('active', activeResultView === 'tree'); + viewTable.setAttribute('aria-pressed', String(activeResultView === 'table')); + viewTree.setAttribute('aria-pressed', String(activeResultView === 'tree')); + expandAll.closest('.tree-actions')?.classList.toggle('hidden', activeResultView !== 'tree'); + + if (activeResultView === 'table' && query.view === 'dashboard') { + resultViewLabel.textContent = locale === 'en' ? 'Result table' : '结果表格'; + renderDashboard(data as DashboardData, active, query); + return; + } + if (activeResultView === 'table' && isTabularResult(data)) { + resultViewLabel.textContent = locale === 'en' ? 'Result table' : '结果表格'; + renderTable(data); + return; + } + resultViewLabel.textContent = locale === 'en' ? 'Result tree' : '结果树'; + renderTree(query.view === 'dashboard' ? dashboardTreeData(data as DashboardData) : data); +} + +function dashboardTreeData(data: DashboardData): Record { + return { + orders: data.orders, + totalOrders: data.totalOrders, + filteredOrders: data.filteredOrders, + statusFacets: data.statusFacets, + search: data.search, + page: data.page, + pageSize: data.pageSize, + }; +} + +function renderTable(rows: ReadonlyArray>): void { + const shell = document.createElement('div'); + shell.className = 'result-table-shell'; + if (!rows.length) { + const empty = document.createElement('p'); + empty.className = 'result-table-empty'; + empty.textContent = locale === 'en' ? 'The query returned no records.' : '查询没有返回记录。'; + shell.append(empty); + result.replaceChildren(shell); + return; + } + const columns = [...new Set(rows.flatMap(row => Object.keys(row)))]; + const table = document.createElement('table'); + table.className = 'result-table'; + const head = document.createElement('thead'); + const headRow = document.createElement('tr'); + for (const column of columns) { + const cell = document.createElement('th'); + cell.scope = 'col'; + cell.textContent = column; + headRow.append(cell); + } + head.append(headRow); + const body = document.createElement('tbody'); + for (const row of rows) { + const tableRow = document.createElement('tr'); + for (const column of columns) { + const cell = document.createElement('td'); + cell.textContent = tableCellText(row[column]); + tableRow.append(cell); + } + body.append(tableRow); + } + table.append(head, body); + shell.append(table); + result.replaceChildren(shell); +} + +function tableCellText(value: unknown): string { + if (value === null || value === undefined) return '—'; + if (Array.isArray(value)) return locale === 'en' ? `${value.length} items` : `${value.length} 项`; + if (value instanceof Date) return value.toISOString(); + if (typeof value === 'object') { + const record = value as Record; + const code = statusCodeFor(record); + if (code) return statusLabel(code); + const identity = record.name ?? record.orderNumber ?? record.code ?? record.id; + return identity === undefined + ? (locale === 'en' ? `${Object.keys(record).length} fields` : `${Object.keys(record).length} 个字段`) + : String(identity); + } + return String(value); +} + +function renderDashboard(data: DashboardData, active: Runtime, query: QueryExample): void { + const center = document.createElement('div'); + center.className = 'order-center'; + + const toolbar = document.createElement('div'); + toolbar.className = 'order-center-toolbar'; + const heading = document.createElement('div'); + const title = document.createElement('h3'); + title.textContent = locale === 'en' ? 'Order Management Center' : '订单管理中心'; + const subtitle = document.createElement('p'); + subtitle.textContent = locale === 'en' + ? 'One generated Q expression describes the entire page' + : '一个生成式 Q 表达式描述整个页面'; + heading.append(title, subtitle); + const searchForm = document.createElement('form'); + searchForm.className = 'order-search'; + const searchInput = document.createElement('input'); + searchInput.type = 'search'; + searchInput.placeholder = locale === 'en' + ? 'Order number, status, or product…' + : '订单号、状态或商品名称…'; + searchInput.value = data.search; + searchInput.setAttribute('aria-label', locale === 'en' ? 'Search orders' : '搜索订单'); + const searchButton = document.createElement('button'); + searchButton.type = 'submit'; + searchButton.className = 'order-search-submit'; + searchButton.setAttribute('aria-label', locale === 'en' ? 'Run order query' : '执行订单查询'); + searchButton.title = locale === 'en' ? 'Search' : '查询'; + const searchIcon = document.createElement('span'); + searchIcon.className = 'search-icon'; + searchIcon.setAttribute('aria-hidden', 'true'); + searchButton.append(searchIcon); + searchForm.append(searchInput, searchButton); + searchForm.addEventListener('submit', event => { + event.preventDefault(); + dashboardState.search = searchInput.value.trim(); + dashboardState.page = 0; + runQuery(query, active).catch(showError); + }); + toolbar.append(heading, searchForm); + + const metrics = document.createElement('div'); + metrics.className = 'order-metrics'; + metrics.append(metricCard(locale === 'en' ? 'All orders' : '全部订单', data.totalOrders, 'total', '#2B66D9', !data.search, () => { + dashboardState.search = ''; + dashboardState.page = 0; + runQuery(query, active).catch(showError); + })); + for (const status of data.statusFacets) { + metrics.append(metricCard( + status.name, + status.orderCount, + status.code.toLowerCase(), + status.color, + data.search.toUpperCase() === status.code, () => { + dashboardState.search = status.code; + dashboardState.page = 0; + runQuery(query, active).catch(showError); + }, + `${locale === 'en' ? 'Total' : '总额'} ${formatFacetAmount(status.orderTotalAmount)}`, + )); + } + + const table = document.createElement('div'); + table.className = 'order-table'; + const tableHeader = document.createElement('div'); + tableHeader.className = 'order-row order-row-head'; + const columnLabels = locale === 'en' + ? ['Order number', 'Order date', 'Status', 'Product details'] + : ['订单号', '订单日期', '状态', '商品明细']; + for (const label of columnLabels) { + const cell = document.createElement('span'); + cell.textContent = label; + tableHeader.append(cell); + } + table.append(tableHeader); + if (!data.orders.length) { + const empty = document.createElement('div'); + empty.className = 'order-empty'; + empty.textContent = locale === 'en' + ? 'No matching orders. Try an order number, status code, or product name.' + : '没有匹配的订单,请尝试订单号、状态英文或商品名称。'; + table.append(empty); + } + for (const order of data.orders) table.append(renderOrderRow(order)); + + const footer = document.createElement('div'); + footer.className = 'order-center-footer'; + const pageInfo = document.createElement('p'); + const first = data.filteredOrders ? data.page * data.pageSize + 1 : 0; + const last = Math.min(data.filteredOrders, (data.page + 1) * data.pageSize); + pageInfo.textContent = locale === 'en' + ? `Showing ${first}–${last} of ${data.filteredOrders} orders` + : `显示 ${first}–${last},共 ${data.filteredOrders} 条订单`; + const pagination = document.createElement('div'); + pagination.className = 'pagination'; + const pageCount = Math.max(1, Math.ceil(data.filteredOrders / data.pageSize)); + pagination.append(pageButton('‹', data.page - 1, data.page === 0, active, query)); + for (let page = 0; page < pageCount; page += 1) { + const button = pageButton(String(page + 1), page, false, active, query); + button.classList.toggle('active', page === data.page); + pagination.append(button); + } + pagination.append(pageButton('›', data.page + 1, data.page >= pageCount - 1, active, query)); + footer.append(pageInfo, pagination); + + center.append(toolbar, metrics, table, footer); + result.replaceChildren(center); +} + +function metricCard( + label: string, + count: number, + tone: string, + color: string, + active: boolean, + select: () => void, + detail?: string, +): HTMLButtonElement { + const button = document.createElement('button'); + button.type = 'button'; + button.className = `metric-card metric-${tone}`; + if (color) button.style.setProperty('--metric-color', color); + button.classList.toggle('active', active); + const name = document.createElement('span'); + name.textContent = label; + const value = document.createElement('strong'); + value.textContent = String(count); + button.append(name, value); + if (detail) { + const secondary = document.createElement('small'); + secondary.textContent = detail; + button.append(secondary); + } + button.addEventListener('click', select); + return button; +} + +function formatFacetAmount(value: number): string { + return new Intl.NumberFormat(locale === 'en' ? 'en-US' : 'zh-CN', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }).format(value); +} + +function renderOrderRow(order: Record): HTMLElement { + const row = document.createElement('div'); + row.className = 'order-row'; + const status = (order.status ?? {}) as Record; + const items = Array.isArray(order.itemList) ? order.itemList as Array> : []; + const values = [ + String(order.orderNumber ?? ''), + String(order.orderDate ?? ''), + ]; + values.forEach(value => { + const cell = document.createElement('span'); + cell.className = 'order-primary'; + cell.textContent = value; + row.append(cell); + }); + const statusCell = document.createElement('span'); + const badge = document.createElement('span'); + const statusCode = statusCodeFor(status); + badge.className = `status-badge status-${statusCode.toLowerCase()}`; + badge.textContent = statusLabel(statusCode) || String(status.name ?? statusCode); + const statusColor = String(status.color ?? ''); + if (statusColor) { + badge.style.color = statusColor; + badge.style.backgroundColor = `${statusColor}18`; + } + statusCell.append(badge); + row.append(statusCell); + + const products = document.createElement('span'); + products.className = 'product-preview'; + items.forEach((item, index) => { + const thumb = document.createElement('span'); + thumb.className = `product-thumb product-tone-${index % 3}`; + thumb.textContent = String(item.productName ?? '?').slice(0, 1); + thumb.title = `${String(item.productName ?? '')} × ${String(item.quantity ?? 1)}`; + products.append(thumb); + }); + const remaining = Number(order.itemCount ?? items.length) - items.length; + if (remaining > 0) { + const more = document.createElement('small'); + more.textContent = `+${remaining}`; + products.append(more); + } + row.append(products); + return row; +} + +function pageButton( + label: string, + page: number, + disabled: boolean, + active: Runtime, + query: QueryExample, +): HTMLButtonElement { + const button = document.createElement('button'); + button.type = 'button'; + button.textContent = label; + button.disabled = disabled; + button.addEventListener('click', () => { + dashboardState.page = page; + runQuery(query, active).catch(showError); + }); + return button; +} + +function statusLabel(value: string): string { + const labels = locale === 'en' + ? { PENDING_PAYMENT: 'Pending payment', PAID: 'Paid', SHIPPED: 'Shipped', DELIVERED: 'Delivered', CANCELLED: 'Cancelled' } + : { PENDING_PAYMENT: '待支付', PAID: '已支付', SHIPPED: '运输中', DELIVERED: '已完成', CANCELLED: '已取消' }; + return (labels as Record)[value] ?? value; +} + +function renderTree(value: unknown): void { + result.replaceChildren(createTreeNode(value, 'result', 0)); +} + +function createTreeNode(value: unknown, key: string, depth: number): HTMLElement { + if (value !== null && typeof value === 'object') { + const entries = Array.isArray(value) + ? value.map((item, index) => [String(index), item] as const) + : Object.entries(value as Record); + const details = document.createElement('details'); + details.className = 'tree-branch'; + details.open = depth === 0; + const summary = document.createElement('summary'); + const keyLabel = document.createElement('span'); + keyLabel.className = 'tree-key'; + keyLabel.textContent = key; + const preview = document.createElement('span'); + preview.className = 'tree-preview'; + preview.textContent = objectPreview(value, entries.length); + summary.append(keyLabel, preview); + details.append(summary); + const children = document.createElement('div'); + children.className = 'tree-children'; + for (const [childKey, childValue] of entries) { + children.append(createTreeNode(childValue, Array.isArray(value) ? `#${Number(childKey) + 1}` : childKey, depth + 1)); + } + details.append(children); + return details; + } + + const leaf = document.createElement('div'); + leaf.className = 'tree-leaf'; + const keyLabel = document.createElement('span'); + keyLabel.className = 'tree-key'; + keyLabel.textContent = key; + const scalar = document.createElement('span'); + scalar.className = `tree-value tree-${value === null ? 'null' : typeof value}`; + scalar.textContent = value === null ? 'null' : typeof value === 'string' ? `“${value}”` : String(value); + leaf.append(keyLabel, scalar); + return leaf; +} + +function objectPreview(value: object, size: number): string { + if (Array.isArray(value)) return locale === 'en' ? `${size} items` : `${size} 项`; + const record = value as Record; + const identity = record.orderNumber ?? record.name ?? record.productName + ?? record.transactionId ?? record.trackingNumber; + return identity ? String(identity) : (locale === 'en' ? `${size} fields` : `${size} 个字段`); +} + +function formatExecutedAt(value: Date): string { + return new Intl.DateTimeFormat(locale === 'en' ? 'en-US' : 'zh-CN', { + year: 'numeric', month: '2-digit', day: '2-digit', + hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, + }).format(value); +} + +function resultRowCount(data: unknown): number { + if (Array.isArray(data)) return data.length; + return Array.isArray((data as { data?: unknown[] })?.data) + ? (data as { data: unknown[] }).data.length + : 1; +} + +function updateResultMeta(data: unknown, query: QueryExample, elapsed: number): void { + const count = query.view === 'dashboard' + ? (data as DashboardData).filteredOrders + : resultRowCount(data); + const rows = locale === 'en' + ? `${count} ${query.view === 'dashboard' ? `matching order${count === 1 ? '' : 's'}` : `result${count === 1 ? '' : 's'}`}` + : `${count} 条${query.view === 'dashboard' ? '匹配订单' : '结果'}`; + resultMeta.textContent = `${rows} · ${elapsed} ms · ${locale === 'en' ? 'in-browser SQLite' : '浏览器内 SQLite'}`; +} + +function updateRuntimeStatus(storage: BrowserSQLiteStorage): void { + const orders = ORDER_SEED.filter(record => record.entity === 'CustomerOrder').length; + status.textContent = locale === 'en' + ? `${storage.toUpperCase()} · ${orders} orders · 7 entities · policy installed · ready` + : `${storage.toUpperCase()} · ${orders} 个订单 · 7 个实体 · 已安装策略 · 就绪`; +} + +function applyLocale(): void { + document.documentElement.lang = locale === 'en' ? 'en' : 'zh-CN'; + document.title = locale === 'en' ? 'TeaQL Order Query Playground' : 'TeaQL 订单查询演练场'; + const description = document.querySelector('meta[name="description"]'); + if (description) description.content = locale === 'en' + ? 'A TeaQL order-query playground running entirely in the browser' + : '完全运行在浏览器中的 TeaQL 订单查询演练场'; + document.querySelectorAll('[data-i18n]').forEach(element => { + const key = element.dataset.i18n; + if (key) element.textContent = copy(key); + }); + languageButtons.forEach(button => { + const active = button.dataset.locale === locale; + button.classList.toggle('active', active); + button.setAttribute('aria-pressed', String(active)); + }); + document.querySelector('.language-switch')?.setAttribute('aria-label', locale === 'en' ? 'Language' : '语言'); + document.querySelector('.brand')?.setAttribute('aria-label', locale === 'en' ? 'TeaQL Playground home' : 'TeaQL 演练场首页'); + document.querySelector('.model-map')?.setAttribute('aria-label', locale === 'en' ? 'Order domain model' : '订单领域模型'); + document.querySelector('.runtime-bar')?.setAttribute('aria-label', locale === 'en' ? 'Runtime settings' : '运行时设置'); + queryCatalog.setAttribute('aria-label', locale === 'en' ? 'Example queries' : '示例查询'); + document.querySelector('.result-view-switch')?.setAttribute('aria-label', locale === 'en' ? 'Result views' : '结果视图'); + document.querySelector('.tree-actions')?.setAttribute('aria-label', locale === 'en' ? 'Result tree actions' : '结果树操作'); + renderQueryCatalog(); + if (currentResult) { + const { data, query, active } = currentResult; + resultTitle.textContent = localize(query.title); + resultDescription.textContent = localize(query.description); + renderCurrentResult(); + renderSql(active.evidence.snapshot(), lastExecutedAt); + updateResultMeta(data, query, lastElapsed); + updateRuntimeStatus(persist.checked ? 'opfs' : 'memory'); + } else { + status.textContent = locale === 'en' ? 'Starting SQLite/WASM…' : '正在启动 SQLite/WASM…'; + } +} + +function selectedQuery(): QueryExample { + return allQueries.find(query => query.id === activeQueryId) ?? allQueries[0]; +} + +async function replaceRuntime(storage: BrowserSQLiteStorage): Promise { + status.textContent = locale === 'en' + ? `Opening ${storage.toUpperCase()} SQLite/WASM…` + : `正在打开 ${storage.toUpperCase()} SQLite/WASM…`; + const previous = runtime; + runtime = undefined; + await previous?.client.close(); + const next = await openRuntime(storage); + runtime = next; + await seedDemoData(next); + await runQuery(selectedQuery(), next); + updateRuntimeStatus(storage); +} + +persist.addEventListener('change', () => { + const storage = persist.checked ? 'opfs' : 'memory'; + localStorage.setItem('teaql-browser-storage', storage); + replaceRuntime(storage).catch(showError); +}); + +reset.addEventListener('click', async () => { + if (!runtime) return; + reset.disabled = true; + try { + await runtime.client.reset(runtime.context); + await seedDemoData(runtime); + await runQuery(selectedQuery(), runtime); + } catch (error) { showError(error); } + finally { reset.disabled = false; } +}); + +expandAll.addEventListener('click', () => { + result.querySelectorAll('details').forEach(branch => { branch.open = true; }); +}); + +viewTable.addEventListener('click', () => { + if (viewTable.disabled) return; + activeResultView = 'table'; + renderCurrentResult(); +}); + +viewTree.addEventListener('click', () => { + activeResultView = 'tree'; + renderCurrentResult(); +}); + +collapseAll.addEventListener('click', () => { + result.querySelectorAll('details').forEach((branch, index) => { branch.open = index === 0; }); +}); + +languageButtons.forEach(button => { + button.addEventListener('click', () => { + locale = button.dataset.locale === 'zh' ? 'zh' : 'en'; + localStorage.setItem('teaql-browser-locale', locale); + applyLocale(); + }); +}); + +function showError(value: unknown): void { + const error = value instanceof Error ? value : new Error(String(value)); + status.textContent = `${error.name}: ${error.message}`; + resultMeta.textContent = locale === 'en' ? 'Query failed' : '查询失败'; + renderTree({ error: error.name, message: error.message }); +} + +applyLocale(); +activeQueryId = selectedQuery().id; +updateActiveLink(); +replaceRuntime(storagePreference).catch(showError); diff --git a/source/teaql-ts/examples/browser-sqlite/src/order-model.ts b/source/teaql-ts/examples/browser-sqlite/src/order-model.ts new file mode 100644 index 0000000000000000000000000000000000000000..76b787b155d2a0601c8b7e961d8276024d49753d --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/src/order-model.ts @@ -0,0 +1,227 @@ +import type { EntitySchema } from 'teaql-ts/sql/core'; + +const id = (columnName: string) => ({ + columnName, + modelName: columnName, + logicalType: 'integer' as const, + decode: 'string' as const, +}); + +const text = (columnName: string) => ({ + columnName, + modelName: columnName, + logicalType: 'text' as const, + decode: 'native' as const, +}); + +const date = (columnName: string) => ({ + columnName, + modelName: columnName, + logicalType: 'date' as const, + decode: 'date' as const, +}); + +const dateTime = (columnName: string) => ({ + columnName, + modelName: columnName, + logicalType: 'datetime' as const, + decode: 'date' as const, +}); + +const number = (columnName: string, logicalType: 'integer' | 'decimal' = 'decimal') => ({ + columnName, + modelName: columnName, + logicalType, + decode: 'number' as const, +}); + +export const ORDER_STATUS = Object.freeze({ + PENDING_PAYMENT: '1001', + PAID: '1002', + SHIPPED: '1003', + DELIVERED: '1004', + CANCELLED: '1005', +} as const); + +export const ORDER_STATUS_CONSTANTS = [ + { entity: 'OrderStatus', id: ORDER_STATUS.PENDING_PAYMENT, values: { name: 'Pending payment', code: 'PENDING_PAYMENT', color: '#D97706', displayOrder: 10 } }, + { entity: 'OrderStatus', id: ORDER_STATUS.PAID, values: { name: 'Paid', code: 'PAID', color: '#2563EB', displayOrder: 20 } }, + { entity: 'OrderStatus', id: ORDER_STATUS.SHIPPED, values: { name: 'Shipped', code: 'SHIPPED', color: '#16A34A', displayOrder: 30 } }, + { entity: 'OrderStatus', id: ORDER_STATUS.DELIVERED, values: { name: 'Delivered', code: 'DELIVERED', color: '#047857', displayOrder: 40 } }, + { entity: 'OrderStatus', id: ORDER_STATUS.CANCELLED, values: { name: 'Cancelled', code: 'CANCELLED', color: '#9F1239', displayOrder: 50 } }, +] as const; + +/** A familiar commerce model with OrderStatus represented as constant objects. */ +export const ORDER_SCHEMAS: Record = { + Platform: { + table: 'platform_data', + columns: { + id: id('id'), + name: text('name'), + code: text('code'), + region: text('region'), + currency: text('currency'), + version: number('version', 'integer'), + }, + relations: { + customerList: { targetEntity: 'Customer', localKey: 'id', foreignKey: 'platformId', many: true }, + orderList: { targetEntity: 'CustomerOrder', localKey: 'id', foreignKey: 'platformId', many: true }, + }, + }, + Customer: { + table: 'customer_data', + columns: { + id: id('id'), + name: text('name'), + email: text('email'), + city: text('city'), + tier: text('tier'), + platformId: id('platform_id'), + version: number('version', 'integer'), + }, + relations: { + platform: { targetEntity: 'Platform', localKey: 'platformId', foreignKey: 'id', many: false }, + orderList: { targetEntity: 'CustomerOrder', localKey: 'id', foreignKey: 'customerId', many: true }, + }, + }, + CustomerOrder: { + table: 'customer_order_data', + columns: { + id: id('id'), + orderNumber: text('order_number'), + orderDate: date('order_date'), + status: id('status_id'), + totalAmount: number('total_amount'), + currency: text('currency'), + customerId: id('customer_id'), + platformId: id('platform_id'), + version: number('version', 'integer'), + }, + relations: { + platform: { targetEntity: 'Platform', localKey: 'platformId', foreignKey: 'id', many: false }, + customer: { targetEntity: 'Customer', localKey: 'customerId', foreignKey: 'id', many: false }, + status: { targetEntity: 'OrderStatus', localKey: 'status', foreignKey: 'id', many: false }, + itemList: { targetEntity: 'OrderItem', localKey: 'id', foreignKey: 'orderId', many: true }, + paymentList: { targetEntity: 'Payment', localKey: 'id', foreignKey: 'orderId', many: true }, + shipmentList: { targetEntity: 'Shipment', localKey: 'id', foreignKey: 'orderId', many: true }, + }, + }, + OrderStatus: { + table: 'order_status_data', + columns: { + id: id('id'), + name: text('name'), + code: text('code'), + color: text('color'), + displayOrder: number('display_order', 'integer'), + version: number('version', 'integer'), + }, + relations: { + orderList: { targetEntity: 'CustomerOrder', localKey: 'id', foreignKey: 'status', many: true }, + }, + }, + OrderItem: { + table: 'order_item_data', + columns: { + id: id('id'), + orderId: id('order_id'), + productName: text('product_name'), + sku: text('sku'), + quantity: number('quantity', 'integer'), + unitPrice: number('unit_price'), + lineAmount: number('line_amount'), + version: number('version', 'integer'), + }, + relations: { + order: { targetEntity: 'CustomerOrder', localKey: 'orderId', foreignKey: 'id', many: false }, + }, + }, + Payment: { + table: 'payment_data', + columns: { + id: id('id'), + orderId: id('order_id'), + provider: text('provider'), + status: text('status'), + amount: number('amount'), + currency: text('currency'), + transactionId: text('transaction_id'), + paidAt: dateTime('paid_at'), + version: number('version', 'integer'), + }, + relations: { + order: { targetEntity: 'CustomerOrder', localKey: 'orderId', foreignKey: 'id', many: false }, + }, + }, + Shipment: { + table: 'shipment_data', + columns: { + id: id('id'), + orderId: id('order_id'), + carrier: text('carrier'), + status: text('status'), + trackingNumber: text('tracking_number'), + shipToCity: text('ship_to_city'), + shippedAt: dateTime('shipped_at'), + deliveredAt: dateTime('delivered_at'), + version: number('version', 'integer'), + }, + relations: { + order: { targetEntity: 'CustomerOrder', localKey: 'orderId', foreignKey: 'id', many: false }, + }, + }, +}; + +export type SeedRecord = Readonly<{ + entity: keyof typeof ORDER_SCHEMAS; + id: string; + payload: Readonly>; +}>; + +export const ORDER_SEED: readonly SeedRecord[] = [ + { entity: 'Platform', id: '1', payload: { name: 'TeaQL Store', code: 'TEAQL-CN', region: 'China', currency: 'CNY' } }, + { entity: 'Platform', id: '2', payload: { name: 'TeaQL Global', code: 'TEAQL-GLOBAL', region: 'Global', currency: 'USD' } }, + + { entity: 'Customer', id: '101', payload: { name: 'Lin Xiao', email: 'lin.xiao@example.com', city: 'Shanghai', tier: 'GOLD', platformId: '1' } }, + { entity: 'Customer', id: '102', payload: { name: 'Zhou Ran', email: 'zhou.ran@example.com', city: 'Hangzhou', tier: 'SILVER', platformId: '1' } }, + { entity: 'Customer', id: '103', payload: { name: 'Maya Patel', email: 'maya.patel@example.com', city: 'Singapore', tier: 'GOLD', platformId: '2' } }, + { entity: 'Customer', id: '104', payload: { name: 'Lucas Martin', email: 'lucas.martin@example.com', city: 'Paris', tier: 'SILVER', platformId: '2' } }, + { entity: 'Customer', id: '105', payload: { name: 'Wang Ning', email: 'wang.ning@example.com', city: 'Chengdu', tier: 'BRONZE', platformId: '1' } }, + + { entity: 'CustomerOrder', id: '1001', payload: { orderNumber: 'TQL-2026-1001', orderDate: '2026-08-28', status: ORDER_STATUS.DELIVERED, totalAmount: 499, currency: 'CNY', customerId: '101', platformId: '1' } }, + { entity: 'CustomerOrder', id: '1002', payload: { orderNumber: 'TQL-2026-1002', orderDate: '2026-09-02', status: ORDER_STATUS.SHIPPED, totalAmount: 1299, currency: 'CNY', customerId: '102', platformId: '1' } }, + { entity: 'CustomerOrder', id: '1003', payload: { orderNumber: 'TQL-2026-1003', orderDate: '2026-09-06', status: ORDER_STATUS.PAID, totalAmount: 328.8, currency: 'CNY', customerId: '101', platformId: '1' } }, + { entity: 'CustomerOrder', id: '1004', payload: { orderNumber: 'TQL-2026-1004', orderDate: '2026-09-11', status: ORDER_STATUS.PENDING_PAYMENT, totalAmount: 79.9, currency: 'CNY', customerId: '105', platformId: '1' } }, + { entity: 'CustomerOrder', id: '1005', payload: { orderNumber: 'TQL-2026-1005', orderDate: '2026-09-14', status: ORDER_STATUS.DELIVERED, totalAmount: 219, currency: 'USD', customerId: '103', platformId: '2' } }, + { entity: 'CustomerOrder', id: '1006', payload: { orderNumber: 'TQL-2026-1006', orderDate: '2026-09-18', status: ORDER_STATUS.PAID, totalAmount: 640, currency: 'USD', customerId: '104', platformId: '2' } }, + { entity: 'CustomerOrder', id: '1007', payload: { orderNumber: 'TQL-2026-1007', orderDate: '2026-09-21', status: ORDER_STATUS.CANCELLED, totalAmount: 159, currency: 'CNY', customerId: '102', platformId: '1' } }, + { entity: 'CustomerOrder', id: '1008', payload: { orderNumber: 'TQL-2026-1008', orderDate: '2026-09-25', status: ORDER_STATUS.SHIPPED, totalAmount: 268, currency: 'CNY', customerId: '105', platformId: '1' } }, + + { entity: 'OrderItem', id: '2001', payload: { orderId: '1001', productName: 'TeaQL Mechanical Keyboard', sku: 'KB-TQL-87', quantity: 1, unitPrice: 299, lineAmount: 299 } }, + { entity: 'OrderItem', id: '2002', payload: { orderId: '1001', productName: 'Silent Wireless Mouse', sku: 'MS-SILENT', quantity: 2, unitPrice: 100, lineAmount: 200 } }, + { entity: 'OrderItem', id: '2003', payload: { orderId: '1002', productName: '27-inch Developer Monitor', sku: 'MON-27-4K', quantity: 1, unitPrice: 1299, lineAmount: 1299 } }, + { entity: 'OrderItem', id: '2004', payload: { orderId: '1003', productName: 'White Porcelain Travel Tea Set', sku: 'TEA-TRAVEL', quantity: 1, unitPrice: 168.8, lineAmount: 168.8 } }, + { entity: 'OrderItem', id: '2005', payload: { orderId: '1003', productName: 'Pre-Qingming Longjing Tea', sku: 'TEA-LJ-100', quantity: 2, unitPrice: 80, lineAmount: 160 } }, + { entity: 'OrderItem', id: '2006', payload: { orderId: '1004', productName: 'Double-wall Glass Tumbler', sku: 'CUP-GLASS', quantity: 1, unitPrice: 79.9, lineAmount: 79.9 } }, + { entity: 'OrderItem', id: '2007', payload: { orderId: '1005', productName: 'Travel Brew Kit', sku: 'BREW-KIT', quantity: 1, unitPrice: 219, lineAmount: 219 } }, + { entity: 'OrderItem', id: '2008', payload: { orderId: '1006', productName: 'Desktop Studio Speaker', sku: 'SPK-STUDIO', quantity: 2, unitPrice: 260, lineAmount: 520 } }, + { entity: 'OrderItem', id: '2009', payload: { orderId: '1006', productName: 'Speaker Stand', sku: 'SPK-STAND', quantity: 1, unitPrice: 120, lineAmount: 120 } }, + { entity: 'OrderItem', id: '2010', payload: { orderId: '1007', productName: 'Desktop Reading Lamp', sku: 'LAMP-DESK', quantity: 1, unitPrice: 159, lineAmount: 159 } }, + { entity: 'OrderItem', id: '2011', payload: { orderId: '1008', productName: 'TeaQL Portable Keyboard', sku: 'KB-TQL-68', quantity: 1, unitPrice: 268, lineAmount: 268 } }, + + { entity: 'Payment', id: '3001', payload: { orderId: '1001', provider: 'Alipay', status: 'CAPTURED', amount: 499, currency: 'CNY', transactionId: 'ALI-260828-01', paidAt: '2026-08-28T10:14:00Z' } }, + { entity: 'Payment', id: '3002', payload: { orderId: '1002', provider: 'WeChat Pay', status: 'CAPTURED', amount: 1299, currency: 'CNY', transactionId: 'WX-260902-08', paidAt: '2026-09-02T03:20:00Z' } }, + { entity: 'Payment', id: '3003', payload: { orderId: '1003', provider: 'Alipay', status: 'CAPTURED', amount: 328.8, currency: 'CNY', transactionId: 'ALI-260906-11', paidAt: '2026-09-06T11:42:00Z' } }, + { entity: 'Payment', id: '3004', payload: { orderId: '1004', provider: 'WeChat Pay', status: 'PENDING', amount: 79.9, currency: 'CNY', transactionId: 'WX-260911-02', paidAt: null } }, + { entity: 'Payment', id: '3005', payload: { orderId: '1005', provider: 'Stripe', status: 'CAPTURED', amount: 219, currency: 'USD', transactionId: 'PI-260914-05', paidAt: '2026-09-14T06:10:00Z' } }, + { entity: 'Payment', id: '3006', payload: { orderId: '1006', provider: 'Stripe', status: 'CAPTURED', amount: 640, currency: 'USD', transactionId: 'PI-260918-03', paidAt: '2026-09-18T15:08:00Z' } }, + { entity: 'Payment', id: '3007', payload: { orderId: '1007', provider: 'Alipay', status: 'REFUNDED', amount: 159, currency: 'CNY', transactionId: 'ALI-260921-07', paidAt: '2026-09-21T02:55:00Z' } }, + { entity: 'Payment', id: '3008', payload: { orderId: '1008', provider: 'WeChat Pay', status: 'CAPTURED', amount: 268, currency: 'CNY', transactionId: 'WX-260925-06', paidAt: '2026-09-25T08:31:00Z' } }, + + { entity: 'Shipment', id: '4001', payload: { orderId: '1001', carrier: 'SF Express', status: 'DELIVERED', trackingNumber: 'SF2608281001', shipToCity: 'Shanghai', shippedAt: '2026-08-29T02:00:00Z', deliveredAt: '2026-08-30T07:26:00Z' } }, + { entity: 'Shipment', id: '4002', payload: { orderId: '1002', carrier: 'JD Logistics', status: 'IN_TRANSIT', trackingNumber: 'JD2609021002', shipToCity: 'Hangzhou', shippedAt: '2026-09-03T04:12:00Z', deliveredAt: null } }, + { entity: 'Shipment', id: '4003', payload: { orderId: '1003', carrier: 'SF Express', status: 'READY', trackingNumber: 'SF2609061003', shipToCity: 'Shanghai', shippedAt: null, deliveredAt: null } }, + { entity: 'Shipment', id: '4004', payload: { orderId: '1005', carrier: 'DHL', status: 'DELIVERED', trackingNumber: 'DHL2609141005', shipToCity: 'Singapore', shippedAt: '2026-09-15T01:10:00Z', deliveredAt: '2026-09-17T09:22:00Z' } }, + { entity: 'Shipment', id: '4005', payload: { orderId: '1006', carrier: 'DHL', status: 'READY', trackingNumber: 'DHL2609181006', shipToCity: 'Paris', shippedAt: null, deliveredAt: null } }, + { entity: 'Shipment', id: '4006', payload: { orderId: '1008', carrier: 'SF Express', status: 'IN_TRANSIT', trackingNumber: 'SF2609251008', shipToCity: 'Chengdu', shippedAt: '2026-09-26T03:18:00Z', deliveredAt: null } }, +] as const; diff --git a/source/teaql-ts/examples/browser-sqlite/src/orders.ts b/source/teaql-ts/examples/browser-sqlite/src/orders.ts new file mode 100644 index 0000000000000000000000000000000000000000..604aa4f49559e4e0e803d9281a9f669eccebb871 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/src/orders.ts @@ -0,0 +1,156 @@ +import { BrowserSQLiteTeaQLClient, type BrowserSQLiteStorage } from 'teaql-ts/sql/browser-sqlite'; +import { DelegatingMutationPolicyApprovalProvider, DelegatingMutationPolicyRegistry, UserContext } from 'teaql-ts'; +import { SQLExecutionEvidenceStore, type SQLExecutionMetadata } from 'teaql-ts/sql/core'; +import { Q } from '../orders-lib/src/generated/Q'; +import { E } from '../orders-lib/src/generated/E'; +import { OrderStatus } from '../orders-lib/src/generated/models/OrderStatus'; +import { GENERATED_RUNTIME_MODULE } from '../orders-lib/src/runtime-module'; +import { ENTITY_SCHEMAS } from '../orders-lib/src/teaql-schemas'; +import './style.css'; + +const status = document.querySelector('#status')!; +const output = document.querySelector('#result')!; +const trace = document.querySelector('#trace')!; +const sql = document.querySelector('#sql')!; +const evidenceRows = document.querySelector('#evidence-rows')!; +const persist = document.querySelector('#persist')!; +const logging = document.querySelector('#logging')!; +const reset = document.querySelector('#reset')!; +const run = document.querySelector('#query')!; +const search = document.querySelector('#search')!; +const preset = {filter: {orderNumber: {$contains: 'KEEP'}}}; +type Runtime = {client: BrowserSQLiteTeaQLClient; context: UserContext; evidence: SQLExecutionEvidenceStore; diagnostics: SQLExecutionMetadata[]}; +let active: Runtime | undefined; +persist.checked = localStorage.getItem('teaql-browser-order-storage') === 'opfs'; + +async function open(storage: BrowserSQLiteStorage): Promise { + const worker = new Worker(new URL('./sqlite.worker.ts', import.meta.url), {type: 'module'}); + const client = await BrowserSQLiteTeaQLClient.open(worker, {...ENTITY_SCHEMAS}, { + storage, databaseName: 'teaql-browser-orders.sqlite3', + }); + client.install(GENERATED_RUNTIME_MODULE); + client.setDiagnosticSQLLogSink(undefined).setMutationLoggingEnabled(false); + const identity = Object.freeze({policyId: 'browser-order-seed', version: '1', fingerprint: 'sha256:browser-order-seed-v1'}); + const context = new UserContext().insertResource('dataService', client) + .withMutationPolicyRegistry(new DelegatingMutationPolicyRegistry(() => ({identity, + review: (_context, plan) => plan.operations.length > 0 ? {verdict: 'allow'} + : {verdict: 'deny', code: 'EMPTY_GRAPH', message: 'empty mutation graph'}, + }))) + .withMutationPolicyApprovalProvider(new DelegatingMutationPolicyApprovalProvider( + policy => ({policy, approvedBy: 'browser-demo-owner', approvedAt: new Date()}), + )); + client.setUserContext(context); + await context.ensureSchema(); + await context.ensureSchema(); + return {client, context, evidence: new SQLExecutionEvidenceStore(), diagnostics: []}; +} + +async function seed({context}: Runtime): Promise { + const existing = await Q.customerOrdersWithMinimalFields().limit(1) + .comment('detect existing order demo').purpose('keep mutation seeding idempotent').executeForList(context); + if (existing.length) return; + const platform = (await Q.platforms().limit(2).comment('load bootstrap platform').purpose('prepare order demo').executeForList(context))[0]; + const customer = Q.customers().comment('initialize demo customer').purpose('prepare order demo').newEntity(context); + customer.updateName('North Star Retail').updatePlatform(platform.id); + await customer.auditAs('seed browser order customer').save(context); + for (let index = 1; index <= 4; index++) { + const order = Q.customerOrders().comment('initialize demo order').purpose('prepare order demo').newEntity(context); + order.updateCustomer(customer.id).updateOrderNumber(index < 4 ? `KEEP-00${index}` : 'DROP-004') + .updateOrderDate(`2026-10-0${index}`).updateTotalAmount(index < 4 ? index * 100 : 900); + if (index === 1) order.updateStatusToNew(); else order.updateStatusToPaid(); + await order.auditAs('seed browser order').save(context); + for (let item = 1; item <= 5; item++) { + const line = Q.orderItems().comment('initialize demo item').purpose('prepare item previews').newEntity(context); + line.updateCustomerOrder(order.id).updateProductName(`Box ${item}`).updateQuantity(item).updateUnitPrice(20); + await line.auditAs('seed browser order item').save(context); + } + } +} + +async function show(runtime: Runtime): Promise { + const searchParams: unknown = JSON.parse(search.value); + const request = Q.customerOrdersWithMinimalFields().filterByJson(searchParams); + runtime.evidence.enableAll(); runtime.diagnostics.length = 0; + runtime.client.setRuntimeTelemetrySink(runtime.evidence).setQueryLoggingEnabled(logging.checked) + .setDiagnosticSQLLogSink({write: entry => runtime.diagnostics.push(entry)}); + const page = await request.countAs('totalOrders') + .facetByStatusAs('statusCounts', Q.orderStatusesWithMinimalFields().selectName().selectColor() + .countAs('orderCount').sumTotalAmountOfCustomerOrdersAs('orderTotalAmount', Q.customerOrdersWithMinimalFields()) + .orderByDisplayOrderAscending().comment('load status facets')) + .selectOrderNumber().selectOrderDate() + .selectStatusWith(Q.orderStatusesWithMinimalFields().selectName().selectColor().comment('load status')) + .selectOrderItemListWith(Q.orderItemsWithMinimalFields().selectProductName().selectQuantity() + .orderByIdAscending().limit(3).comment('load item previews')) + .countOrderItemsAs('itemCount').orderByOrderDateDescending().orderByIdDescending() + .offset(1).limit(1).comment('load order list').purpose('render order list page').executeForList(runtime.context); + const response = { + data: page.data.map(row => { + const expression = E.customerOrder(row); + const previewSize = expression.orderItemList().size().eval(); + if (previewSize == null) throw new Error('Selected item list unexpectedly has a null size'); + return {id: row.id, version: row.version, orderNumber: expression.orderNumber().eval(), orderDate: expression.orderDate().eval(), + status: {name: expression.status().name().eval(), color: expression.status().color().eval()}, + items: Array.from({length: previewSize}, (_, index) => ({ + productName: expression.orderItemList().get(index).productName().eval(), quantity: expression.orderItemList().get(index).quantity().eval(), + })), itemCount: (row as unknown as Record).itemCount}; + }), + metadata: {totalCount: page.totalCount, pageOffset: 1, pageSize: 1, aggregations: page.data.aggregations, searchWarnings: request.dynamicSearchWarnings}, + facets: {statusCounts: page.data.facets.statusCounts.map(value => ({ + id: value.id, name: E.orderStatus(OrderStatus.fromRecord(value)).name().eval(), + color: E.orderStatus(OrderStatus.fromRecord(value)).color().eval(), orderCount: value.orderCount, orderTotalAmount: value.orderTotalAmount, + }))}, + }; + output.textContent = JSON.stringify(response, null, 2); + const statements = runtime.evidence.snapshot(); + // Rendering only: ownership and comments come from the actual runtime metadata. + const rows = statements.map(entry => { + const chain = entry.traceChain ?? []; + const purposes = chain.filter(node => node.kind === 'purpose'); + const businessTrace = purposes.length === 1 + ? `${purposes[0].detail}: ${chain.filter(node => node.kind === 'comment').map(node => node.detail).join(' → ')}` + : 'TraceChain unavailable'; + const row = document.createElement('tr'); + for (const value of [`${entry.elapsedMicros} µs`, + entry.tracePath.find(node => node.kind === 'request')?.name ?? '—', businessTrace, entry.debugSQL]) { + const cell = document.createElement('td'); + cell.textContent = value; + row.append(cell); + } + return {row, businessTrace}; + }); + evidenceRows.replaceChildren(...rows.map(value => value.row)); + trace.textContent = rows.map(value => value.businessTrace).join('\n'); + sql.textContent = JSON.stringify(statements, null, 2); + status.textContent = `${runtime.client.storage!.toUpperCase()} · ${page.totalCount} matches · ${statements.length} SQL statements · ${runtime.diagnostics.length} diagnostics · policy installed · ready`; +} + +async function replace(storage: BrowserSQLiteStorage): Promise { + status.textContent = `Opening ${storage.toUpperCase()} SQLite/WASM…`; + const previous = active; active = undefined; + await previous?.client.close(); + const next = await open(storage); active = next; + await seed(next); await show(next); +} +function fail(value: unknown): void { + status.textContent = value instanceof Error ? `${value.name}: ${value.message}` : String(value); +} +run.addEventListener('click', async () => { + if (!active) return; + run.disabled = true; + try { await show(active); } catch (error) { fail(error); } finally { run.disabled = false; } +}); +document.querySelector('#preset')!.addEventListener('click', () => { + search.value = JSON.stringify(preset, null, 2); run.click(); +}); +logging.addEventListener('change', () => { if (active) show(active).catch(fail); }); +persist.addEventListener('change', () => { + const storage = persist.checked ? 'opfs' : 'memory'; + localStorage.setItem('teaql-browser-order-storage', storage); replace(storage).catch(fail); +}); +reset.addEventListener('click', async () => { + if (!active) return; + reset.disabled = true; + try { await active.client.reset(active.context); await seed(active); await show(active); } + catch (error) { fail(error); } finally { reset.disabled = false; } +}); +replace(persist.checked ? 'opfs' : 'memory').catch(fail); diff --git a/source/teaql-ts/examples/browser-sqlite/src/sqlite.worker.ts b/source/teaql-ts/examples/browser-sqlite/src/sqlite.worker.ts new file mode 100644 index 0000000000000000000000000000000000000000..02811edbc65c86fdd90ce1b6df7a34616e08bd35 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/src/sqlite.worker.ts @@ -0,0 +1,4 @@ +import { startBrowserSQLiteWorker } from 'teaql-ts/sql/browser-sqlite-worker'; +import sqliteWasmUrl from '@sqlite.org/sqlite-wasm/sqlite3.wasm?url'; + +startBrowserSQLiteWorker({ wasmUrl: sqliteWasmUrl }); diff --git a/source/teaql-ts/examples/browser-sqlite/src/style.css b/source/teaql-ts/examples/browser-sqlite/src/style.css new file mode 100644 index 0000000000000000000000000000000000000000..3d54aecaba2c5b23cc0fa2f7947281db8b961112 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/src/style.css @@ -0,0 +1,441 @@ +:root { + font: 16px/1.5 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + color: #17231b; + background: #f5f4ed; + font-synthesis: none; + --ink: #17231b; + --muted: #677067; + --paper: #fffef8; + --line: #d8ddd3; + --green: #145b37; + --green-deep: #0e4329; + --lime: #dff45c; + --orange: #ef8354; + --blue: #2b66d9; +} + +* { box-sizing: border-box; } +html { scroll-behavior: smooth; } +body { margin: 0; min-width: 320px; background: #f5f4ed; } +button, input { font: inherit; } +button, a { -webkit-tap-highlight-color: transparent; } + +.page-shell { width: min(1440px, 100%); margin: 0 auto; padding: 0 42px; } +.site-header { + height: 76px; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid var(--line); +} +.brand, .docs-link { color: var(--ink); text-decoration: none; font-weight: 750; } +.brand { display: inline-flex; align-items: center; gap: 11px; letter-spacing: -.02em; } +.brand-mark { + width: 30px; + height: 30px; + display: grid; + place-items: center; + border-radius: 50%; + color: var(--lime); + background: var(--green-deep); + font-family: Georgia, serif; + font-style: italic; +} +.docs-link { color: var(--green); font-size: 14px; } +.header-actions { display: flex; align-items: center; gap: 18px; } +.language-switch { display: flex; gap: 3px; padding: 3px; border: 1px solid var(--line); border-radius: 8px; } +.language-switch button { padding: 3px 7px; border: 0; border-radius: 5px; color: var(--muted); background: transparent; font-size: 11px; cursor: pointer; } +.language-switch button.active { color: white; background: var(--green); } + +.hero { + min-height: 460px; + display: grid; + grid-template-columns: minmax(0, 1.1fr) minmax(440px, .9fr); + align-items: center; + gap: 72px; + padding: 76px 0 66px; +} +.eyebrow, .section-index, .query-card-label { + margin: 0 0 14px; + color: var(--green); + font-size: 11px; + font-weight: 850; + letter-spacing: .18em; +} +h1 { + margin: 0; + max-width: 820px; + font-family: Georgia, "Noto Serif SC", serif; + font-size: clamp(42px, 5.6vw, 78px); + font-weight: 500; + line-height: 1.08; + letter-spacing: -.055em; +} +.hero-intro { max-width: 680px; margin: 26px 0 0; color: var(--muted); font-size: 18px; } + +.model-map { + position: relative; + min-height: 310px; + padding: 38px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 12px; + border: 1px solid #bfc8bb; + border-radius: 28px; + background: linear-gradient(145deg, #fdfdf8, #e9eee5); + box-shadow: 0 18px 48px rgba(33, 60, 40, .06); + overflow: hidden; +} +.model-map::before { + content: "DOMAIN MODEL"; + position: absolute; + top: 18px; + left: 22px; + color: #708073; + font-size: 10px; + font-weight: 800; + letter-spacing: .16em; +} +.model-flow { width: 100%; display: grid; grid-template-columns: 1fr auto 1fr auto 1fr; align-items: center; gap: 10px; } +.model-flow > span:not(.model-arrow), .model-leaves span { + min-width: 0; + padding: 15px 17px; + border: 1px solid #b8c2b7; + border-radius: 12px; + background: rgba(255, 255, 250, .86); + font: 750 14px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; + box-shadow: 0 8px 22px rgba(30, 58, 38, .05); +} +.model-map small { display: block; margin-top: 7px; color: var(--muted); font: 12px/1.2 Inter, sans-serif; } +.model-flow > span.model-root { color: white; border-color: var(--green); background: var(--green); } +.model-map .model-root small { color: #cce4d4; } +.model-arrow { color: #809087; font-size: 22px; text-align: center; } +.model-arrow-split { height: 22px; line-height: 18px; } +.model-leaves { width: 100%; display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; } + +.runtime-bar { + min-height: 72px; + padding: 14px 18px 14px 22px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + border-radius: 14px; + color: #e7f1e9; + background: var(--green-deep); +} +#status { margin: 0; color: #c8d9ce; font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; } +.controls { display: flex; align-items: center; gap: 18px; } +.toggle { display: inline-flex; align-items: center; gap: 9px; font-size: 13px; cursor: pointer; } +.toggle input { position: absolute; opacity: 0; pointer-events: none; } +.toggle span { + position: relative; + width: 38px; + height: 22px; + border-radius: 999px; + background: #55705f; + transition: background .2s ease; +} +.toggle span::after { + content: ""; + position: absolute; + top: 3px; + left: 3px; + width: 16px; + height: 16px; + border-radius: 50%; + background: white; + transition: transform .2s ease; +} +.toggle input:checked + span { background: var(--lime); } +.toggle input:checked + span::after { transform: translateX(16px); background: var(--green-deep); } +.secondary-button, .tree-actions button { + border: 1px solid currentColor; + border-radius: 8px; + background: transparent; + cursor: pointer; +} +.secondary-button { padding: 8px 12px; color: white; font-size: 12px; } +.secondary-button:disabled { opacity: .45; cursor: wait; } + +.query-browser { padding: 96px 0 82px; } +.section-heading, .result-heading { + display: flex; + align-items: end; + justify-content: space-between; + gap: 36px; + margin-bottom: 40px; +} +.section-heading h2, .result-heading h2 { + margin: 0; + font-family: Georgia, "Noto Serif SC", serif; + font-size: clamp(34px, 4vw, 52px); + font-weight: 500; + letter-spacing: -.045em; +} +.section-heading > p { max-width: 420px; margin: 0; color: var(--muted); } +.query-group { + display: grid; + grid-template-columns: 230px 1fr; + gap: 36px; + padding: 24px 0; + border-top: 1px solid var(--line); +} +.query-group:last-child { border-bottom: 1px solid var(--line); } +.query-group-heading h2 { margin: 0 0 4px; font-size: 16px; } +.query-group-heading p { margin: 0; color: var(--muted); font-size: 12px; } +.query-links { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 24px; } +.query-links a { + position: relative; + padding: 5px 0; + color: #34443a; + text-decoration-color: #a6b1a8; + text-underline-offset: 5px; + font-weight: 650; + transition: color .16s ease; +} +.query-links a::after { content: " ↗"; color: #9aa49b; font-weight: 400; } +.query-links a:hover { color: var(--green); } +.query-links a.active { color: var(--green); text-decoration-color: var(--orange); text-decoration-thickness: 2px; } + +.result-panel { + margin: 0 -42px; + padding: 82px 42px 92px; + color: #eef5f0; + background: #111a15; +} +.result-heading { align-items: center; } +.result-heading .section-index { color: var(--lime); } +.result-heading h2 { color: white; } +#result-description { max-width: 620px; margin: 10px 0 0; color: #9fb0a4; } +.result-actions { display: flex; align-items: center; gap: 10px; } +.result-view-switch, .tree-actions { display: flex; gap: 6px; } +.result-view-switch button, .tree-actions button { padding: 8px 11px; border: 1px solid #536159; border-radius: 8px; color: #aebdb3; background: transparent; font-size: 12px; cursor: pointer; } +.result-view-switch button.active { color: #17231b; border-color: var(--lime); background: var(--lime); } +.result-view-switch button:disabled { opacity: .35; cursor: default; } +.tree-actions button:hover { color: var(--lime); } +.result-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; align-items: start; } +.tree-card, .query-card, .sql-card { border: 1px solid #2f3d34; border-radius: 14px; background: #17231b; } +.tree-card { min-height: 520px; overflow: hidden; } +.tree-card-bar { + min-height: 48px; + padding: 0 18px; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid #2f3d34; + color: #b8c9bd; + font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; + text-transform: uppercase; + letter-spacing: .08em; +} +#result-meta { margin: 0; color: #829188; text-transform: none; letter-spacing: 0; } +.json-tree { min-height: 470px; max-height: 680px; padding: 18px 20px 28px; overflow: auto; font: 13px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; } +.json-tree.loading { opacity: .55; } +.tree-actions.hidden { display: none; } +.result-table-shell { width: 100%; min-height: 470px; overflow: auto; } +.result-table { width: 100%; border-collapse: collapse; white-space: nowrap; } +.result-table th, .result-table td { padding: 11px 14px; border-bottom: 1px solid #2f3d34; text-align: left; vertical-align: top; } +.result-table th { position: sticky; top: 0; z-index: 1; color: #8ea095; background: #131d17; font: 700 10px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; } +.result-table td { color: #d9e5dc; font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; } +.result-table tbody tr:hover { background: rgba(255, 255, 255, .025); } +.result-table-empty { margin: 0; padding: 48px 20px; color: #7f9185; text-align: center; } +.tree-branch { margin: 2px 0; } +.tree-branch > summary { + min-height: 29px; + display: flex; + align-items: center; + gap: 9px; + list-style: none; + cursor: pointer; + border-radius: 5px; +} +.tree-branch > summary::-webkit-details-marker { display: none; } +.tree-branch > summary::before { + content: "›"; + width: 15px; + color: #73887a; + font-size: 18px; + line-height: 1; + transform-origin: center; + transition: transform .12s ease; +} +.tree-branch[open] > summary::before { transform: rotate(90deg); } +.tree-branch > summary:hover { background: rgba(255, 255, 255, .035); } +.tree-children { margin-left: 8px; padding-left: 20px; border-left: 1px solid #314238; } +.tree-leaf { min-height: 28px; display: grid; grid-template-columns: minmax(110px, 180px) 1fr; align-items: baseline; gap: 12px; padding-left: 23px; } +.tree-key { color: #bdd0c2; font-weight: 700; } +.tree-preview { overflow: hidden; color: #718079; font-size: 11px; text-overflow: ellipsis; white-space: nowrap; } +.tree-value { overflow-wrap: anywhere; } +.tree-string { color: #dff45c; } +.tree-number { color: #82b4ff; } +.tree-boolean { color: #f2a27f; } +.tree-null { color: #78847c; font-style: italic; } + +.query-card, .sql-card { min-width: 0; padding: 22px; } +.query-card-label { color: var(--lime); } +.query-card pre { + max-height: 430px; + margin: 0; + padding: 0; + overflow: auto; + color: #d5e2d8; + background: transparent; + font: 12px/1.72 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + white-space: pre-wrap; +} +.query-params { margin-top: 24px; padding-top: 18px; border-top: 1px solid #2f3d34; } +.query-params.hidden { display: none; } +.query-params .query-card-label { margin-bottom: 10px; color: #82b4ff; } +.query-params pre { max-height: 220px; color: #b9caee; } +.query-note { margin: 28px 0 0; padding-top: 18px; border-top: 1px solid #2f3d34; color: #829188; font-size: 12px; } +.sql-card-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; } +.sql-card-heading .query-card-label { margin-bottom: 0; } +#sql-count { color: #7f9185; font: 10px/1.3 ui-monospace, SFMono-Regular, Menlo, monospace; } +.execution-evidence-wrap { margin-top: 18px; overflow-x: auto; border: 1px solid #34433a; border-radius: 8px; } +.execution-evidence { min-width: 1500px; width: 100%; border-collapse: collapse; color: #c7d5cb; } +.execution-evidence th, .execution-evidence td { + padding: 10px 12px; + border-right: 1px solid #34433a; + border-bottom: 1px solid #34433a; + text-align: left; + vertical-align: top; + white-space: nowrap; +} +.execution-evidence th:last-child, .execution-evidence td:last-child { border-right: 0; } +.execution-evidence tbody tr:last-child td { border-bottom: 0; } +.execution-evidence th { color: #7f9185; background: #131d17; font: 700 10px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; } +.execution-evidence td { color: #cbd8ce; background: #101813; font: 10px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; } +.execution-evidence tbody tr:hover td { background: #141f18; } +.execution-evidence .evidence-trace { color: #b9caee; } +.execution-evidence .evidence-sql { color: #dff45c; } + +.dashboard-result { max-height: none; padding: 0; color: var(--ink); background: #f7f8f5; font: 14px/1.45 Inter, system-ui, sans-serif; } +.order-center { min-width: 880px; padding: 24px; } +.order-center-toolbar { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin-bottom: 20px; } +.order-center-toolbar h3 { margin: 0; color: #111d16; font: 750 22px/1.2 Inter, system-ui, sans-serif; letter-spacing: -.025em; } +.order-center-toolbar p { margin: 5px 0 0; color: #778078; font-size: 12px; } +.order-search { width: min(390px, 45%); display: flex; align-items: center; gap: 6px; } +.order-search input { + min-width: 0; + height: 32px; + flex: 1; + padding: 6px 10px; + border: 1px solid #cfd5ce; + border-radius: 7px; + outline: 0; + background: white; + font-size: 12px; +} +.order-search input:focus { border-color: #8e9990; } +.order-search-submit { + width: 30px; + height: 30px; + flex: 0 0 30px; + display: grid; + place-items: center; + padding: 0; + border: 1px solid #cfd5ce; + border-radius: 7px; + color: #536057; + background: white; + cursor: pointer; +} +.order-search-submit:hover, .order-search-submit:focus-visible { + color: var(--green); + border-color: #93a097; + outline: none; +} +.search-icon { + position: relative; + width: 13px; + height: 13px; + display: block; + border: 1.5px solid currentColor; + border-radius: 50%; +} +.search-icon::after { + content: ""; + position: absolute; + right: -3px; + bottom: -2px; + width: 5px; + height: 1.5px; + border-radius: 1px; + background: currentColor; + transform: rotate(45deg); + transform-origin: left center; +} +.order-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; margin-bottom: 18px; } +.metric-card { padding: 14px; display: grid; gap: 8px; text-align: left; border: 1px solid #dbe0da; border-radius: 9px; color: #58625b; background: white; cursor: pointer; } +.metric-card strong { color: #16231a; font-size: 23px; line-height: 1; } +.metric-card small { color: #727b74; font-size: 10px; font-variant-numeric: tabular-nums; } +.metric-card.active { border-color: var(--metric-color, var(--blue)); box-shadow: inset 3px 0 0 var(--metric-color, var(--blue)); } +.order-table { overflow: hidden; border: 1px solid #e0e4df; border-radius: 10px; background: white; } +.order-row { min-width: 720px; display: grid; grid-template-columns: 1.05fr .85fr .75fr 2fr; align-items: center; gap: 14px; min-height: 68px; padding: 10px 14px; border-top: 1px solid #edf0ec; } +.order-row:first-child { border-top: 0; } +.order-row-head { min-height: 40px; color: #69736b; background: #f2f4f1; font-size: 11px; font-weight: 750; } +.order-primary { color: #26322a; font: 650 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; } +.status-badge { display: inline-block; padding: 4px 8px; border-radius: 999px; color: #2b5e39; background: #e3f4e8; font-size: 10px; white-space: nowrap; } +.status-pending_payment { color: #92580a; background: #fff0d8; } +.status-paid { color: #215b9d; background: #e2efff; } +.status-shipped { color: #1d6e38; background: #ddf5e4; } +.status-cancelled { color: #7b4650; background: #f6e6e9; } +.product-preview { display: flex; align-items: center; gap: 5px; } +.product-thumb { width: 32px; height: 28px; display: grid; place-items: center; border: 1px solid #cad4ca; border-radius: 6px; color: #315139; background: linear-gradient(135deg, #e5eddf, #bdceb8); font: 800 11px/1 Inter, sans-serif; } +.product-tone-1 { color: #725333; background: linear-gradient(135deg, #f1e5d4, #d3b58d); } +.product-tone-2 { color: #3d526b; background: linear-gradient(135deg, #e1e9ef, #adbecd); } +.product-preview small { color: #68736a; font-size: 10px; } +.order-empty { padding: 48px 20px; color: #7a847c; text-align: center; } +.order-center-footer { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding-top: 16px; } +.order-center-footer p { margin: 0; color: #7a847c; font-size: 11px; } +.pagination { display: flex; gap: 5px; } +.pagination button { min-width: 31px; height: 31px; border: 1px solid #d8ddd7; border-radius: 6px; color: #465149; background: white; cursor: pointer; } +.pagination button.active { color: white; border-color: var(--blue); background: var(--blue); } +.pagination button:disabled { opacity: .4; cursor: default; } + +footer { + min-height: 86px; + display: flex; + align-items: center; + justify-content: space-between; + color: var(--muted); + font-size: 12px; +} + +@media (max-width: 980px) { + .page-shell { padding: 0 24px; } + .hero { grid-template-columns: 1fr; gap: 46px; padding-top: 58px; } + .model-map { min-height: 260px; } + .result-panel { margin: 0 -24px; padding-left: 24px; padding-right: 24px; } + .result-grid { grid-template-columns: 1fr; } +} + +@media (max-width: 680px) { + .page-shell { padding: 0 16px; } + .site-header { height: 64px; } + .header-actions { gap: 9px; } + .docs-link { display: none; } + h1 { font-size: 43px; } + .hero { min-height: auto; padding: 48px 0; } + .hero-intro { font-size: 16px; } + .model-map { gap: 9px; padding: 52px 22px 22px; } + .model-flow { grid-template-columns: 1fr; } + .model-flow > span:not(.model-arrow), .model-leaves span { width: 100%; } + .model-flow .model-arrow { transform: rotate(90deg); } + .model-leaves { grid-template-columns: 1fr; } + .runtime-bar, .section-heading, .result-heading { align-items: flex-start; flex-direction: column; } + .runtime-bar { padding: 18px; } + .controls { width: 100%; justify-content: space-between; } + .query-browser { padding: 70px 0 64px; } + .query-group { grid-template-columns: 1fr; gap: 14px; } + .query-links { gap: 8px 18px; } + .result-panel { margin: 0 -16px; padding: 64px 16px; } + .result-actions { width: 100%; align-items: stretch; flex-direction: column; } + .result-view-switch, .tree-actions { width: 100%; } + .result-view-switch button, .tree-actions button { flex: 1; } + .tree-leaf { grid-template-columns: minmax(90px, 120px) 1fr; padding-left: 15px; } + .json-tree { padding-left: 12px; padding-right: 12px; } +} diff --git a/source/teaql-ts/examples/browser-sqlite/src/work-items.css b/source/teaql-ts/examples/browser-sqlite/src/work-items.css new file mode 100644 index 0000000000000000000000000000000000000000..c682cbfeb264b1fef5593361f2d503c869f851ae --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/src/work-items.css @@ -0,0 +1,10 @@ +:root { font: 16px/1.5 Inter, system-ui, sans-serif; color: #e8edf5; background: #090b10; } +body { margin: 0; } +main { width: min(760px, calc(100% - 40px)); margin: 10vh auto; } +.eyebrow { color: #d9ff52; font-size: 12px; font-weight: 800; letter-spacing: .16em; } +h1 { margin: 8px 0; font-size: clamp(36px, 7vw, 68px); letter-spacing: -.05em; } +a { color: #d9ff52; } +.controls { display: flex; gap: 18px; align-items: center; margin: 32px 0; } +button { border: 0; border-radius: 5px; padding: 10px 14px; background: #d9ff52; font-weight: 800; } +#status { color: #aab4c4; } +pre { min-height: 260px; padding: 22px; overflow: auto; border: 1px solid #2b323e; border-radius: 8px; background: #11151c; color: #c6d1df; } diff --git a/source/teaql-ts/examples/browser-sqlite/src/work-items.ts b/source/teaql-ts/examples/browser-sqlite/src/work-items.ts new file mode 100644 index 0000000000000000000000000000000000000000..880284ff79723227e8c53c2b9acc85c7f823e393 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/src/work-items.ts @@ -0,0 +1,114 @@ +import { + BrowserSQLiteStorage, + BrowserSQLiteTeaQLClient, +} from 'teaql-ts/sql/browser-sqlite'; +import { + DelegatingMutationPolicyApprovalProvider, + DelegatingMutationPolicyRegistry, + UserContext, +} from 'teaql-ts'; +import { Q } from '../../conformance/src/generated/Q'; +import { WorkItem } from '../../conformance/src/generated/models/WorkItem'; +import { GENERATED_RUNTIME_MODULE } from '../../conformance/src/runtime-module'; +import { ENTITY_SCHEMAS } from '../../conformance/src/teaql-node-sql'; +import './work-items.css'; + +const status = document.querySelector('#status')!; +const result = document.querySelector('#result')!; +const persist = document.querySelector('#persist')!; +const reset = document.querySelector('#reset')!; + +type Runtime = { client: BrowserSQLiteTeaQLClient; context: UserContext }; +let runtime: Runtime | undefined; +const storagePreference = localStorage.getItem('teaql-browser-storage') === 'opfs' ? 'opfs' : 'memory'; +persist.checked = storagePreference === 'opfs'; + +async function openRuntime(storage: BrowserSQLiteStorage): Promise { + const worker = new Worker(new URL('./sqlite.worker.ts', import.meta.url), { type: 'module' }); + const client = await BrowserSQLiteTeaQLClient.open(worker, { ...ENTITY_SCHEMAS }, { + storage, + databaseName: 'teaql-browser-example.sqlite3', + }); + client.install(GENERATED_RUNTIME_MODULE); + const policyIdentity = Object.freeze({ + policyId: 'browser-demo-seed', + version: '1', + fingerprint: 'sha256:browser-demo-seed-v1', + }); + const context = new UserContext() + .insertResource('dataService', client) + .withMutationPolicyRegistry(new DelegatingMutationPolicyRegistry(() => ({ + identity: policyIdentity, + review: (_context, plan) => plan.operations.length > 0 + ? { verdict: 'allow' } + : { verdict: 'deny', code: 'EMPTY_GRAPH', message: 'empty mutation graph' }, + }))) + .withMutationPolicyApprovalProvider(new DelegatingMutationPolicyApprovalProvider( + identity => ({ policy: identity, approvedBy: 'browser-demo-owner', approvedAt: new Date() }), + )); + client.setUserContext(context); + await context.ensureSchema(); + return { client, context }; +} + +async function seedDemoData({ context }: Runtime): Promise { + const existing = await Q.workItemsWithMinimalFields() + .comment('what: detect existing browser demo records') + .purpose('why: keep generated mutation bootstrap idempotent') + .executeForList(context); + if (existing.length) return; + for (const title of ['Evaluate semantic model', 'Generate typed library', 'Verify browser runtime']) { + await new WorkItem() + .updateTitle(title) + .updatePlatform('1') + .auditAs('seed deterministic browser demo data') + .save(context); + } +} + +async function showData(active: Runtime): Promise { + const rows = await Q.workItems() + .selectTitle() + .orderByIdAscending() + .limit(20) + .comment('what: load browser-local work items') + .purpose('why: prove the generated Q API runs without a backend') + .executeForList(active.context); + result.textContent = JSON.stringify(rows, null, 2); + status.textContent = `${active.client.storage!.toUpperCase()} · ${rows.length} rows · policy installed · ready`; +} + +async function replaceRuntime(storage: BrowserSQLiteStorage): Promise { + status.textContent = `Opening ${storage.toUpperCase()} SQLite/WASM…`; + const previous = runtime; + runtime = undefined; + await previous?.client.close(); + const next = await openRuntime(storage); + runtime = next; + await seedDemoData(next); + await showData(next); +} + +persist.addEventListener('change', () => { + const storage = persist.checked ? 'opfs' : 'memory'; + localStorage.setItem('teaql-browser-storage', storage); + replaceRuntime(storage).catch(showError); +}); + +reset.addEventListener('click', async () => { + if (!runtime) return; + reset.disabled = true; + try { + await runtime.client.reset(runtime.context); + await seedDemoData(runtime); + await showData(runtime); + } catch (error) { showError(error); } + finally { reset.disabled = false; } +}); + +function showError(value: unknown): void { + const error = value instanceof Error ? value : new Error(String(value)); + status.textContent = `${error.name}: ${error.message}`; +} + +replaceRuntime(storagePreference).catch(showError); diff --git a/source/teaql-ts/examples/browser-sqlite/tsconfig.json b/source/teaql-ts/examples/browser-sqlite/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..1fa3ba02c8c5a64f4e5efad96abb10fdaaaf0fa3 --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "baseUrl": ".", + "paths": { + "teaql-ts": ["../../src/index.ts"], + "teaql-ts/sql/core": ["../../src/sql/core.ts"], + "teaql-ts/sql/browser-sqlite": ["../../src/sql/browser-sqlite.ts"], + "teaql-ts/sql/browser-sqlite-worker": ["../../src/sql/browser-sqlite-worker.ts"], + "@sqlite.org/sqlite-wasm": ["node_modules/@sqlite.org/sqlite-wasm/dist/index.d.mts"] + }, + "strict": true, + "skipLibCheck": true, + "types": ["vite/client", "node"], + "lib": ["ES2022", "DOM", "WebWorker"] + }, + "include": ["src"] +} diff --git a/source/teaql-ts/examples/browser-sqlite/vite.config.ts b/source/teaql-ts/examples/browser-sqlite/vite.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..092c6b9001f2b1053db246490988190371619c2b --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/vite.config.ts @@ -0,0 +1,31 @@ +import { defineConfig } from 'vite'; +import { fileURLToPath, URL } from 'node:url'; + +export default defineConfig({ + build: { rollupOptions: { input: { + main: 'index.html', workItems: 'work-items.html', orders: 'orders.html', + } } }, + resolve: { + preserveSymlinks: true, + alias: [ + { find: /^teaql-ts$/, replacement: fileURLToPath(new URL('../../src/index.ts', import.meta.url)) }, + { find: /^teaql-ts\/sql\/core$/, replacement: fileURLToPath(new URL('../../src/sql/core.ts', import.meta.url)) }, + { find: /^teaql-ts\/sql\/browser-sqlite$/, replacement: fileURLToPath(new URL('../../src/sql/browser-sqlite.ts', import.meta.url)) }, + { find: /^teaql-ts\/sql\/browser-sqlite-worker$/, replacement: fileURLToPath(new URL('../../src/sql/browser-sqlite-worker.ts', import.meta.url)) }, + { find: /^@sqlite\.org\/sqlite-wasm$/, replacement: fileURLToPath(new URL('./node_modules/@sqlite.org/sqlite-wasm/dist/index.mjs', import.meta.url)) }, + ], + }, + optimizeDeps: { exclude: ['@sqlite.org/sqlite-wasm'] }, + server: { + headers: { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp', + }, + }, + preview: { + headers: { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp', + }, + }, +}); diff --git a/source/teaql-ts/examples/browser-sqlite/work-items.html b/source/teaql-ts/examples/browser-sqlite/work-items.html new file mode 100644 index 0000000000000000000000000000000000000000..62802104e6eb740be67901902ff0b1d5f2aff08b --- /dev/null +++ b/source/teaql-ts/examples/browser-sqlite/work-items.html @@ -0,0 +1,25 @@ + + + + + + + TeaQL Browser SQLite WorkItems + + +
+

TEAQL TYPESCRIPT RUNTIME

+

Browser-local Data Service

+

Generated Q APIs and audited mutations, backed by SQLite/WASM.

+

Open the order management center

+

Open the generated order TraceChain page

+
+ + +
+

Starting SQLite/WASM…

+

+    
+ + + diff --git a/source/teaql-ts/jest.config.cjs b/source/teaql-ts/jest.config.cjs new file mode 100644 index 0000000000000000000000000000000000000000..e63ddf2547f02951055566442a7055c9a245f135 --- /dev/null +++ b/source/teaql-ts/jest.config.cjs @@ -0,0 +1,5 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/tests/**/*.test.ts'], +}; diff --git a/source/teaql-ts/package-lock.json b/source/teaql-ts/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..b6ae55c641fbd9cc6ad7754b83cf3ab818915f00 --- /dev/null +++ b/source/teaql-ts/package-lock.json @@ -0,0 +1,12426 @@ +{ + "name": "@teaql/teaql", + "version": "0.3.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@teaql/teaql", + "version": "0.3.1", + "license": "Apache-2.0", + "dependencies": { + "node-fetch": "^2.7.0" + }, + "devDependencies": { + "@opentelemetry/api-logs": "^0.221.0", + "@opentelemetry/context-async-hooks": "^2.10.0", + "@opentelemetry/core": "^2.10.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.221.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.221.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/resources": "^2.10.0", + "@opentelemetry/sdk-logs": "^0.221.0", + "@opentelemetry/sdk-metrics": "^2.10.0", + "@opentelemetry/sdk-trace-base": "^2.10.0", + "@sqlite.org/sqlite-wasm": "3.53.0-build1", + "@types/better-sqlite3": "^7.6.12", + "@types/jest": "^29.5.0", + "@types/node-fetch": "^2.6.13", + "@types/pg": "^8.11.0", + "better-sqlite3": "^12.10.0", + "esbuild": "^0.28.2", + "jest": "^29.5.0", + "jest-util": "^29.7.0", + "mysql2": "^3.11.0", + "peggy": "^5.1.0", + "pg": "^8.12.0", + "pg-query-stream": "^4.7.0", + "ts-jest": "^29.1.0", + "typescript": "5.4.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.1", + "@opentelemetry/api-logs": "^0.221.0", + "@opentelemetry/context-async-hooks": "^2.10.0", + "@opentelemetry/core": "^2.10.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.221.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.221.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/resources": "^2.10.0", + "@opentelemetry/sdk-logs": "^0.221.0", + "@opentelemetry/sdk-metrics": "^2.10.0", + "@opentelemetry/sdk-trace-base": "^2.10.0", + "@sqlite.org/sqlite-wasm": "3.53.0-build1", + "better-sqlite3": "^12.10.0", + "expo-sqlite": "*", + "mysql2": "^3.11.0", + "pg": "^8.12.0", + "pg-query-stream": "^4.7.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/api-logs": { + "optional": true + }, + "@opentelemetry/context-async-hooks": { + "optional": true + }, + "@opentelemetry/core": { + "optional": true + }, + "@opentelemetry/exporter-logs-otlp-http": { + "optional": true + }, + "@opentelemetry/exporter-metrics-otlp-http": { + "optional": true + }, + "@opentelemetry/exporter-trace-otlp-http": { + "optional": true + }, + "@opentelemetry/otlp-transformer": { + "optional": true + }, + "@opentelemetry/resources": { + "optional": true + }, + "@opentelemetry/sdk-logs": { + "optional": true + }, + "@opentelemetry/sdk-metrics": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "@sqlite.org/sqlite-wasm": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "expo-sqlite": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-query-stream": { + "optional": true + } + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/@jest/core/node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/@jest/core/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/environment/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/environment/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/@jest/reporters/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/@jest/test-sequencer/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.221.0.tgz", + "integrity": "sha512-OlanaW1vv7ufTqQ3/fPLI4arGt5ZoM+P8abOMki6uEYnpRazepSWDwDnnw+la7kE26SHVC18//SMccrDvLKOXQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.10.0.tgz", + "integrity": "sha512-bvyMcgLEkozzSzpEEEo1OMoeQ97bxj6Qs2uN3mPrSdDvObMI1myffD/BPqcLlzZO9//d1SqQA/WPw7Cz2AiqhA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.10.0.tgz", + "integrity": "sha512-/wNZ8twnEQQA4HoHu22+vcsdru6pWPWxW+7w+FlxT6Id7PE/WIbZmVKkte+PF72e0F2dnImFeHD2syyE1Mw6MQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.221.0.tgz", + "integrity": "sha512-nKXkr4Tomi6fjYVOf+ytcW3dZAVr4v4Bv5gsT6dr2gvpUPJpKgHB4XbMufMsPotRE3g0XH2GwVVCkN2w6SON+Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-logs": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.221.0.tgz", + "integrity": "sha512-sRfCKbOzgy8xZQV2as0RzIZlnCmCseCKZGLfRcrpo2CBngJDr+rPtX0zkG0+oUCV5kfQPUoW3W3C96Ag3Y/Clg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-metrics": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.221.0.tgz", + "integrity": "sha512-AySXiKoC+meiWm6zdVj5T2LnPDZuatveBby1cMOeQteIWsYXAUxs8Sru13G2pVSPrUXz6vF+og7QVBX6GdC/oQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-trace": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.221.0.tgz", + "integrity": "sha512-UFPIq80OH3Ns/oPFHRj14d4DTOxUo+MUFU8hUiCq5jTqFhdeJnfVSANHT+xp92409cA+oxzvlZCe6NM1wvCuBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/otlp-transformer": "0.221.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.221.0.tgz", + "integrity": "sha512-lg6lkOU08Az23jVcn/0Els9HP+V8PnR4Km6p0KgpTggS0n/WuhnmY64rSh83Of9iR9nD+dpWr6adlcX8KzAwjg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-logs": "0.221.0", + "@opentelemetry/sdk-metrics": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.10.0.tgz", + "integrity": "sha512-q6MMm2zhggzsHVNbabYwut+a6nbuQQe3URUoxaojM/8K1IBfwwPzvxIjNi2/lI1TFe+fMHMW9MWhrtDLEXEnkA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.221.0.tgz", + "integrity": "sha512-FaDcazjyMp7TZZZAsqbo4IkovP0UegoCu0EBkiNt+qCqvUf7FPAsfcrZ3+ZEkKgXZ/jHafop+JoGPDk3A0SmLg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.10.0.tgz", + "integrity": "sha512-t6r1VSvXNtSDnPXU1FbZeetJb7yyovHmgu0wRSoftxtE0g2rSNhQZQUy69sRUCL+iioJpX8SN/S6wq6ZtvLySQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.10.0.tgz", + "integrity": "sha512-MfQGq3GRmTh5fM/y+OjaO0vj6+luCB1XO2gfXCalKCfgKw0eHL++sm75DNweC6ohlp+aFvACqeE0fYayqdRaoQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.10.0.tgz", + "integrity": "sha512-GuYQQT7QD2EeO8lcZLRQzcbOyhqAzL+6WWTKTU9mSUBYBazkEDl+VrQcXQhbB08OWM9anD1aHleVadzulpOaUQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", + "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@peggyjs/from-mem": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@peggyjs/from-mem/-/from-mem-3.1.3.tgz", + "integrity": "sha512-LLlgtfXIaeYXoOYovOI0spLM8ZXaqkAlmcRRrLzHJzLMqkU6Sw0R4KMoCoHx1PjaP815pSCBlS+BN6aD8t1Jgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "7.7.4" + }, + "engines": { + "node": ">=20.8" + } + }, + "node_modules/@peggyjs/from-mem/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@sqlite.org/sqlite-wasm": { + "version": "3.53.0-build1", + "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.53.0-build1.tgz", + "integrity": "sha512-PfWPWN2n+/37doa8oh2/oUXk4OOsRYZsxc1W1sDXIGb/Pu5Yrb+f2eyYpgQMGITVX7HVgxhs9P18Rc6I97ym/g==", + "dev": true, + "license": "Apache-2.0", + "workspaces": [ + "demos/*" + ], + "engines": { + "node": ">=22" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/better-sqlite3": { + "version": "7.6.13", + "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz", + "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/node": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz", + "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==", + "dev": true, + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, + "node_modules/@types/pg": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.21.0.tgz", + "integrity": "sha512-AYdtudzabjLZgVgRZmAnU8bAnVUXzuJX2IYHeSIiIHm68olD+LgQYCGWdtcNYnP0uq9c4S4NibVG3Ni7VbKW7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.13", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz", + "integrity": "sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==", + "dev": true, + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/better-sqlite3": { + "version": "12.11.1", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.11.1.tgz", + "integrity": "sha512-dq9AtApgg5PGFtBzPFSBl3HZQjHok5gaQCM6zh2Yk0aSmDCs1CbnVI8/HgASQkNKsWFpseIO9beg5xxpYhbIfA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + }, + "engines": { + "node": "20.x || 22.x || 23.x || 24.x || 25.x || 26.x" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC" + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.403", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.403.tgz", + "integrity": "sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-config/node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/jest-config/node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/jest-config/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-config/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-resolve/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-runner/node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-runner/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jest-snapshot/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-snapshot/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/jest/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", + "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lru.min": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.4.tgz", + "integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==", + "dev": true, + "license": "MIT", + "engines": { + "bun": ">=1.0.0", + "deno": ">=1.30.0", + "node": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mysql2": { + "version": "3.23.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.23.3.tgz", + "integrity": "sha512-ehp9HEKr4wVJaBOUVxNFa+CNrsCCCZ6363/jbGhb7WpEmSRNIXjHBjFs5K2s2cXn7j/RhDieejsQJ6nfUwD6vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aws-ssl-profiles": "^1.1.2", + "generate-function": "^2.3.1", + "iconv-lite": "^0.7.3", + "long": "^5.3.2", + "lru.min": "^1.1.4", + "named-placeholders": "^1.1.6", + "sql-escaper": "^1.5.1" + }, + "engines": { + "node": ">= 8.0" + }, + "peerDependencies": { + "@types/node": ">= 8" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.6.tgz", + "integrity": "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "lru.min": "^1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-abi": { + "version": "3.94.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.94.0.tgz", + "integrity": "sha512-W5ZNO5KRPB5TkYmGVD9F6YqhsglXJzE6etpbmT+f6EQElhiX/UTG551cnsRGvLG3fyZEg9HwaDmNmj5nwJ4z9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/peggy": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/peggy/-/peggy-5.1.0.tgz", + "integrity": "sha512-IEo5aYRZ2kXH4Qby06cjtL114PZnwLoTiA41vUmg2vPZgANn+c87m5BUurhuDr5/cu758ZlpgsAfBVx+hhO5+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peggyjs/from-mem": "3.1.3", + "commander": "^14.0.3", + "source-map-generator": "2.0.6" + }, + "bin": { + "peggy": "bin/peggy.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/pg": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.23.0.tgz", + "integrity": "sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.14.0", + "pg-pool": "^3.14.0", + "pg-protocol": "^1.16.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.4.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz", + "integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz", + "integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pg-cursor": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.22.0.tgz", + "integrity": "sha512-knzXLKqarTjOvb3qDSW0JiGsazmxwEKXrqHfWRte7XUsOYccQRafn3BLnQobWwInkzFJSyOej8y8cQRh2z3kGw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "pg": "^8" + } + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz", + "integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.0.tgz", + "integrity": "sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pg-query-stream": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/pg-query-stream/-/pg-query-stream-4.17.0.tgz", + "integrity": "sha512-69bug2CH/AJi1BN8r08eZ8tAGdbZZVp9kB0FG9OC2VkJPHIyj7d3Nk9V8tmporO60wqeWvhn7qtQ5oNimwlFug==", + "dev": true, + "license": "MIT", + "dependencies": { + "pg-cursor": "^2.22.0" + }, + "peerDependencies": { + "pg": "^8" + } + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-generator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-2.0.6.tgz", + "integrity": "sha512-IlassDs1Ve8nV6uyQZXF9kdkJpVKnMte2JZQXu13M0A5zwc+vu6+LNHfmxsHBMDtoZE21RHiKI0/xvpecZRCNg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sql-escaper": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/sql-escaper/-/sql-escaper-1.5.1.tgz", + "integrity": "sha512-4toX5E1fQbBrpfXidaHnF0669nkAdETeIPTs2SUjxxD7RRIs9ICG4gtpmfc68JCEKehsdwLFqBu9VlQqZ1P1gg==", + "dev": true, + "license": "MIT", + "engines": { + "bun": ">=1.0.0", + "deno": ">=2.0.0", + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/mysqljs/sql-escaper?sponsor=1" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar-fs": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz", + "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-jest": { + "version": "29.4.12", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz", + "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==", + "dev": true, + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.9", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.8.5", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <7" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz", + "integrity": "sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + } + }, + "@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true + }, + "@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + } + }, + "@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "requires": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true + }, + "@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "requires": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true + }, + "@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "requires": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + } + }, + "@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "dev": true, + "requires": { + "@babel/types": "^7.29.8" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.29.7" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.29.7" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.29.7" + } + }, + "@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + } + }, + "@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + } + }, + "@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "dev": true, + "optional": true + }, + "@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "dev": true, + "optional": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true + }, + "@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "requires": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + } + } + }, + "@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "requires": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + } + }, + "@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "requires": { + "jest-get-type": "^29.6.3" + } + }, + "@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "dependencies": { + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + } + } + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + } + } + }, + "@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "requires": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "requires": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@opentelemetry/api": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", + "devOptional": true + }, + "@opentelemetry/api-logs": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.221.0.tgz", + "integrity": "sha512-OlanaW1vv7ufTqQ3/fPLI4arGt5ZoM+P8abOMki6uEYnpRazepSWDwDnnw+la7kE26SHVC18//SMccrDvLKOXQ==", + "dev": true, + "requires": { + "@opentelemetry/api": "^1.3.0" + } + }, + "@opentelemetry/context-async-hooks": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.10.0.tgz", + "integrity": "sha512-bvyMcgLEkozzSzpEEEo1OMoeQ97bxj6Qs2uN3mPrSdDvObMI1myffD/BPqcLlzZO9//d1SqQA/WPw7Cz2AiqhA==", + "dev": true, + "requires": {} + }, + "@opentelemetry/core": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.10.0.tgz", + "integrity": "sha512-/wNZ8twnEQQA4HoHu22+vcsdru6pWPWxW+7w+FlxT6Id7PE/WIbZmVKkte+PF72e0F2dnImFeHD2syyE1Mw6MQ==", + "dev": true, + "requires": { + "@opentelemetry/semantic-conventions": "^1.29.0" + } + }, + "@opentelemetry/exporter-logs-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.221.0.tgz", + "integrity": "sha512-nKXkr4Tomi6fjYVOf+ytcW3dZAVr4v4Bv5gsT6dr2gvpUPJpKgHB4XbMufMsPotRE3g0XH2GwVVCkN2w6SON+Q==", + "dev": true, + "requires": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-logs": "0.221.0" + } + }, + "@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.221.0.tgz", + "integrity": "sha512-sRfCKbOzgy8xZQV2as0RzIZlnCmCseCKZGLfRcrpo2CBngJDr+rPtX0zkG0+oUCV5kfQPUoW3W3C96Ag3Y/Clg==", + "dev": true, + "requires": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-metrics": "2.10.0" + } + }, + "@opentelemetry/exporter-trace-otlp-http": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.221.0.tgz", + "integrity": "sha512-AySXiKoC+meiWm6zdVj5T2LnPDZuatveBby1cMOeQteIWsYXAUxs8Sru13G2pVSPrUXz6vF+og7QVBX6GdC/oQ==", + "dev": true, + "requires": { + "@opentelemetry/otlp-exporter-base": "0.221.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-trace": "2.10.0" + } + }, + "@opentelemetry/otlp-exporter-base": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.221.0.tgz", + "integrity": "sha512-UFPIq80OH3Ns/oPFHRj14d4DTOxUo+MUFU8hUiCq5jTqFhdeJnfVSANHT+xp92409cA+oxzvlZCe6NM1wvCuBA==", + "dev": true, + "requires": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/otlp-transformer": "0.221.0" + } + }, + "@opentelemetry/otlp-transformer": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.221.0.tgz", + "integrity": "sha512-lg6lkOU08Az23jVcn/0Els9HP+V8PnR4Km6p0KgpTggS0n/WuhnmY64rSh83Of9iR9nD+dpWr6adlcX8KzAwjg==", + "dev": true, + "requires": { + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-logs": "0.221.0", + "@opentelemetry/sdk-metrics": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0" + } + }, + "@opentelemetry/resources": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.10.0.tgz", + "integrity": "sha512-q6MMm2zhggzsHVNbabYwut+a6nbuQQe3URUoxaojM/8K1IBfwwPzvxIjNi2/lI1TFe+fMHMW9MWhrtDLEXEnkA==", + "dev": true, + "requires": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + } + }, + "@opentelemetry/sdk-logs": { + "version": "0.221.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.221.0.tgz", + "integrity": "sha512-FaDcazjyMp7TZZZAsqbo4IkovP0UegoCu0EBkiNt+qCqvUf7FPAsfcrZ3+ZEkKgXZ/jHafop+JoGPDk3A0SmLg==", + "dev": true, + "requires": { + "@opentelemetry/api-logs": "0.221.0", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + } + }, + "@opentelemetry/sdk-metrics": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.10.0.tgz", + "integrity": "sha512-t6r1VSvXNtSDnPXU1FbZeetJb7yyovHmgu0wRSoftxtE0g2rSNhQZQUy69sRUCL+iioJpX8SN/S6wq6ZtvLySQ==", + "dev": true, + "requires": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0" + } + }, + "@opentelemetry/sdk-trace": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.10.0.tgz", + "integrity": "sha512-MfQGq3GRmTh5fM/y+OjaO0vj6+luCB1XO2gfXCalKCfgKw0eHL++sm75DNweC6ohlp+aFvACqeE0fYayqdRaoQ==", + "dev": true, + "requires": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + } + }, + "@opentelemetry/sdk-trace-base": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.10.0.tgz", + "integrity": "sha512-GuYQQT7QD2EeO8lcZLRQzcbOyhqAzL+6WWTKTU9mSUBYBazkEDl+VrQcXQhbB08OWM9anD1aHleVadzulpOaUQ==", + "dev": true, + "requires": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + } + }, + "@opentelemetry/semantic-conventions": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", + "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", + "dev": true + }, + "@peggyjs/from-mem": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@peggyjs/from-mem/-/from-mem-3.1.3.tgz", + "integrity": "sha512-LLlgtfXIaeYXoOYovOI0spLM8ZXaqkAlmcRRrLzHJzLMqkU6Sw0R4KMoCoHx1PjaP815pSCBlS+BN6aD8t1Jgg==", + "dev": true, + "requires": { + "semver": "7.7.4" + }, + "dependencies": { + "semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true + } + } + }, + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + } + }, + "@sqlite.org/sqlite-wasm": { + "version": "3.53.0-build1", + "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.53.0-build1.tgz", + "integrity": "sha512-PfWPWN2n+/37doa8oh2/oUXk4OOsRYZsxc1W1sDXIGb/Pu5Yrb+f2eyYpgQMGITVX7HVgxhs9P18Rc6I97ym/g==", + "dev": true + }, + "@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "requires": { + "@babel/types": "^7.28.2" + } + }, + "@types/better-sqlite3": { + "version": "7.6.13", + "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz", + "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "dev": true, + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "@types/node": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz", + "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==", + "dev": true, + "requires": { + "undici-types": "~8.3.0" + } + }, + "@types/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "dev": true, + "requires": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, + "@types/pg": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.21.0.tgz", + "integrity": "sha512-AYdtudzabjLZgVgRZmAnU8bAnVUXzuJX2IYHeSIiIHm68olD+LgQYCGWdtcNYnP0uq9c4S4NibVG3Ni7VbKW7Q==", + "dev": true, + "requires": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "dependencies": { + "picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "dev": true + }, + "babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "baseline-browser-mapping": { + "version": "2.11.13", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz", + "integrity": "sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==", + "dev": true + }, + "better-sqlite3": { + "version": "12.11.1", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.11.1.tgz", + "integrity": "sha512-dq9AtApgg5PGFtBzPFSBl3HZQjHok5gaQCM6zh2Yk0aSmDCs1CbnVI8/HgASQkNKsWFpseIO9beg5xxpYhbIfA==", + "dev": true, + "requires": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "requires": { + "fill-range": "^7.1.1" + } + }, + "browserslist": { + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", + "dev": true, + "requires": { + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + } + }, + "dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "requires": {} + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, + "detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true + }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, + "electron-to-chromium": { + "version": "1.5.403", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.403.tgz", + "integrity": "sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA==", + "dev": true + }, + "emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + } + }, + "esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + } + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true + }, + "expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "requires": { + "is-property": "^1.0.2" + } + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "requires": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "requires": { + "hasown": "^2.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "requires": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "dependencies": { + "semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "requires": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "requires": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "requires": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "requires": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + } + } + }, + "jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + } + }, + "jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "requires": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true + }, + "jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "requires": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + } + }, + "jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + } + }, + "jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "requires": {} + }, + "jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "requires": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "dependencies": { + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + } + } + }, + "jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "requires": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + } + } + }, + "jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + } + } + }, + "jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, + "jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + } + } + }, + "jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true + } + } + }, + "jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "requires": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "requires": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", + "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "lru.min": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.4.tgz", + "integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==", + "dev": true + }, + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "requires": { + "semver": "^7.5.3" + }, + "dependencies": { + "semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "requires": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "dependencies": { + "picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true + } + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "mysql2": { + "version": "3.23.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.23.3.tgz", + "integrity": "sha512-ehp9HEKr4wVJaBOUVxNFa+CNrsCCCZ6363/jbGhb7WpEmSRNIXjHBjFs5K2s2cXn7j/RhDieejsQJ6nfUwD6vQ==", + "dev": true, + "requires": { + "aws-ssl-profiles": "^1.1.2", + "generate-function": "^2.3.1", + "iconv-lite": "^0.7.3", + "long": "^5.3.2", + "lru.min": "^1.1.4", + "named-placeholders": "^1.1.6", + "sql-escaper": "^1.5.1" + } + }, + "named-placeholders": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.6.tgz", + "integrity": "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==", + "dev": true, + "requires": { + "lru.min": "^1.1.0" + } + }, + "napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-abi": { + "version": "3.94.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.94.0.tgz", + "integrity": "sha512-W5ZNO5KRPB5TkYmGVD9F6YqhsglXJzE6etpbmT+f6EQElhiX/UTG551cnsRGvLG3fyZEg9HwaDmNmj5nwJ4z9g==", + "dev": true, + "requires": { + "semver": "^7.3.5" + }, + "dependencies": { + "semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true + } + } + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node-releases": { + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "peggy": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/peggy/-/peggy-5.1.0.tgz", + "integrity": "sha512-IEo5aYRZ2kXH4Qby06cjtL114PZnwLoTiA41vUmg2vPZgANn+c87m5BUurhuDr5/cu758ZlpgsAfBVx+hhO5+w==", + "dev": true, + "requires": { + "@peggyjs/from-mem": "3.1.3", + "commander": "^14.0.3", + "source-map-generator": "2.0.6" + } + }, + "pg": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.23.0.tgz", + "integrity": "sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==", + "dev": true, + "requires": { + "pg-cloudflare": "^1.4.0", + "pg-connection-string": "^2.14.0", + "pg-pool": "^3.14.0", + "pg-protocol": "^1.16.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + } + }, + "pg-cloudflare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz", + "integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==", + "dev": true, + "optional": true + }, + "pg-connection-string": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz", + "integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==", + "dev": true + }, + "pg-cursor": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.22.0.tgz", + "integrity": "sha512-knzXLKqarTjOvb3qDSW0JiGsazmxwEKXrqHfWRte7XUsOYccQRafn3BLnQobWwInkzFJSyOej8y8cQRh2z3kGw==", + "dev": true, + "requires": {} + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "dev": true + }, + "pg-pool": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz", + "integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==", + "dev": true, + "requires": {} + }, + "pg-protocol": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.0.tgz", + "integrity": "sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==", + "dev": true + }, + "pg-query-stream": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/pg-query-stream/-/pg-query-stream-4.17.0.tgz", + "integrity": "sha512-69bug2CH/AJi1BN8r08eZ8tAGdbZZVp9kB0FG9OC2VkJPHIyj7d3Nk9V8tmporO60wqeWvhn7qtQ5oNimwlFug==", + "dev": true, + "requires": { + "pg-cursor": "^2.22.0" + } + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dev": true, + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dev": true, + "requires": { + "split2": "^4.1.0" + } + }, + "picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "dev": true + }, + "postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "dev": true + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "dev": true + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dev": true, + "requires": { + "xtend": "^4.0.0" + } + }, + "prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "dev": true, + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "dev": true + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + } + } + }, + "react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map-generator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-2.0.6.tgz", + "integrity": "sha512-IlassDs1Ve8nV6uyQZXF9kdkJpVKnMte2JZQXu13M0A5zwc+vu6+LNHfmxsHBMDtoZE21RHiKI0/xvpecZRCNg==", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "sql-escaper": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/sql-escaper/-/sql-escaper-1.5.1.tgz", + "integrity": "sha512-4toX5E1fQbBrpfXidaHnF0669nkAdETeIPTs2SUjxxD7RRIs9ICG4gtpmfc68JCEKehsdwLFqBu9VlQqZ1P1gg==", + "dev": true + }, + "stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tar-fs": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz", + "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "ts-jest": { + "version": "29.4.12", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz", + "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==", + "dev": true, + "requires": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.9", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.8.5", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true + }, + "type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true + }, + "uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "optional": true + }, + "undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz", + "integrity": "sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==", + "dev": true, + "requires": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/source/teaql-ts/package.json b/source/teaql-ts/package.json new file mode 100644 index 0000000000000000000000000000000000000000..320d043cd9395b32877bc6389fc7f76d1e62d638 --- /dev/null +++ b/source/teaql-ts/package.json @@ -0,0 +1,218 @@ +{ + "name": "@teaql/teaql", + "version": "0.3.1", + "description": "TeaQL runtime and SQL data services for TypeScript", + "files": [ + "dist", + "!dist/.sql-root-owned-backup-*" + ], + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/esm/index.js", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "./sql/core": { + "types": "./dist/sql/core.d.ts", + "import": "./dist/esm/sql/core.js", + "require": "./dist/sql/core.js", + "default": "./dist/sql/core.js" + }, + "./sql/postgres": { + "types": "./dist/sql/postgres.d.ts", + "import": "./dist/esm/sql/postgres.js", + "require": "./dist/sql/postgres.js", + "default": "./dist/sql/postgres.js" + }, + "./sql/mysql": { + "types": "./dist/sql/mysql.d.ts", + "import": "./dist/esm/sql/mysql.js", + "require": "./dist/sql/mysql.js", + "default": "./dist/sql/mysql.js" + }, + "./sql/sqlite": { + "types": "./dist/sql/sqlite.d.ts", + "import": "./dist/esm/sql/sqlite.js", + "require": "./dist/sql/sqlite.js", + "default": "./dist/sql/sqlite.js" + }, + "./sql/expo-sqlite": { + "types": "./dist/sql/expo-sqlite.d.ts", + "import": "./dist/esm/sql/expo-sqlite.js", + "require": "./dist/sql/expo-sqlite.js", + "default": "./dist/sql/expo-sqlite.js" + }, + "./sql/browser-sqlite": { + "types": "./dist/sql/browser-sqlite.d.ts", + "import": "./dist/esm/sql/browser-sqlite.js", + "require": "./dist/sql/browser-sqlite.js", + "default": "./dist/sql/browser-sqlite.js" + }, + "./sql/browser-sqlite-worker": { + "types": "./dist/sql/browser-sqlite-worker.d.ts", + "import": "./dist/esm/sql/browser-sqlite-worker.js", + "require": "./dist/sql/browser-sqlite-worker.js", + "default": "./dist/sql/browser-sqlite-worker.js" + }, + "./telemetry/standard-node": { + "types": "./dist/telemetry/standard-node.d.ts", + "import": "./dist/esm/telemetry/standard-node.js", + "require": "./dist/telemetry/standard-node.js", + "default": "./dist/telemetry/standard-node.js" + }, + "./telemetry/opentelemetry": { + "types": "./dist/telemetry/opentelemetry.d.ts", + "import": "./dist/esm/telemetry/opentelemetry.js", + "require": "./dist/telemetry/opentelemetry.js", + "default": "./dist/telemetry/opentelemetry.js" + } + }, + "typesVersions": { + "*": { + "sql/core": [ + "dist/sql/core.d.ts" + ], + "sql/postgres": [ + "dist/sql/postgres.d.ts" + ], + "sql/mysql": [ + "dist/sql/mysql.d.ts" + ], + "sql/sqlite": [ + "dist/sql/sqlite.d.ts" + ], + "sql/expo-sqlite": [ + "dist/sql/expo-sqlite.d.ts" + ], + "sql/browser-sqlite": [ + "dist/sql/browser-sqlite.d.ts" + ], + "sql/browser-sqlite-worker": [ + "dist/sql/browser-sqlite-worker.d.ts" + ], + "telemetry/standard-node": [ + "dist/telemetry/standard-node.d.ts" + ] + } + }, + "scripts": { + "generate:query-parser": "node scripts/generate-query-parser.mjs", + "build": "npm run generate:query-parser && tsc && node scripts/build-esm.mjs", + "test": "jest", + "prepack": "npm run build" + }, + "keywords": [ + "teaql", + "query", + "database" + ], + "author": "TeaQL", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/teaql/teaql-ts.git" + }, + "bugs": { + "url": "https://github.com/teaql/teaql-ts/issues" + }, + "homepage": "https://teaql.io", + "sideEffects": false, + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "@opentelemetry/api-logs": "^0.221.0", + "@opentelemetry/context-async-hooks": "^2.10.0", + "@opentelemetry/core": "^2.10.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.221.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.221.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.221.0", + "@opentelemetry/resources": "^2.10.0", + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/sdk-logs": "^0.221.0", + "@opentelemetry/sdk-metrics": "^2.10.0", + "@opentelemetry/sdk-trace-base": "^2.10.0", + "@sqlite.org/sqlite-wasm": "3.53.0-build1", + "@types/better-sqlite3": "^7.6.12", + "@types/jest": "^29.5.0", + "@types/node-fetch": "^2.6.13", + "@types/pg": "^8.11.0", + "better-sqlite3": "^12.10.0", + "esbuild": "^0.28.2", + "jest": "^29.5.0", + "jest-util": "^29.7.0", + "mysql2": "^3.11.0", + "peggy": "^5.1.0", + "pg": "^8.12.0", + "pg-query-stream": "^4.7.0", + "ts-jest": "^29.1.0", + "typescript": "5.4.5" + }, + "dependencies": { + "node-fetch": "^2.7.0" + }, + "peerDependencies": { + "@opentelemetry/otlp-transformer": "0.221.0", + "@opentelemetry/core": "^2.10.0", + "@opentelemetry/context-async-hooks": "^2.10.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.221.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.221.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.221.0", + "@opentelemetry/resources": "^2.10.0", + "@opentelemetry/sdk-logs": "^0.221.0", + "@opentelemetry/sdk-metrics": "^2.10.0", + "@opentelemetry/sdk-trace-base": "^2.10.0", + "@opentelemetry/api": "^1.9.1", + "@opentelemetry/api-logs": "^0.221.0", + "@sqlite.org/sqlite-wasm": "3.53.0-build1", + "better-sqlite3": "^12.10.0", + "expo-sqlite": "*", + "mysql2": "^3.11.0", + "pg": "^8.12.0", + "pg-query-stream": "^4.7.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/otlp-transformer": { "optional": true }, + "@opentelemetry/core": { "optional": true }, + "@opentelemetry/context-async-hooks": { "optional": true }, + "@opentelemetry/exporter-logs-otlp-http": { "optional": true }, + "@opentelemetry/exporter-metrics-otlp-http": { "optional": true }, + "@opentelemetry/exporter-trace-otlp-http": { "optional": true }, + "@opentelemetry/resources": { "optional": true }, + "@opentelemetry/sdk-logs": { "optional": true }, + "@opentelemetry/sdk-metrics": { "optional": true }, + "@opentelemetry/sdk-trace-base": { "optional": true }, + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/api-logs": { + "optional": true + }, + "@sqlite.org/sqlite-wasm": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-query-stream": { + "optional": true + }, + "expo-sqlite": { + "optional": true + } + }, + "directories": { + "example": "examples", + "test": "tests" + }, + "type": "commonjs" +} diff --git a/source/teaql-ts/scripts/build-esm.mjs b/source/teaql-ts/scripts/build-esm.mjs new file mode 100644 index 0000000000000000000000000000000000000000..6c917e105f2aec5815638eea1a827bd1a401df4b --- /dev/null +++ b/source/teaql-ts/scripts/build-esm.mjs @@ -0,0 +1,29 @@ +import {rm, writeFile} from 'node:fs/promises'; +import {build} from 'esbuild'; + +const output = new URL('../dist/esm/', import.meta.url); +await rm(output, {recursive: true, force: true}); +await build({ + entryPoints: { + index: 'src/index.ts', + 'sql/core': 'src/sql/core.ts', + 'sql/postgres': 'src/sql/postgres.ts', + 'sql/mysql': 'src/sql/mysql.ts', + 'sql/sqlite': 'src/sql/sqlite.ts', + 'sql/expo-sqlite': 'src/sql/expo-sqlite.ts', + 'sql/browser-sqlite': 'src/sql/browser-sqlite.ts', + 'sql/browser-sqlite-worker': 'src/sql/browser-sqlite-worker.ts', + 'telemetry/opentelemetry': 'src/telemetry/opentelemetry.ts', + 'telemetry/standard-node': 'src/telemetry/standard-node.ts', + }, + outdir: 'dist/esm', + bundle: true, + splitting: true, + chunkNames: 'chunks/[name]-[hash]', + packages: 'external', + platform: 'neutral', + format: 'esm', + target: 'es2020', + sourcemap: true, +}); +await writeFile(new URL('package.json', output), '{"type":"module"}\n'); diff --git a/source/teaql-ts/scripts/fixtures/checker-overlap-command.sh b/source/teaql-ts/scripts/fixtures/checker-overlap-command.sh new file mode 100644 index 0000000000000000000000000000000000000000..e9f4915fe1e62e13353406b57a81a086a22a58fd --- /dev/null +++ b/source/teaql-ts/scripts/fixtures/checker-overlap-command.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Test-only npm stand-in; never invoked by a real consumer verification. +marker='PASS TypeScript generated Checker overlap: 4 scenarios; real Required rejection, no rejected commands/business SQL/audit; transactions serialized' +case "${TEAQL_CHECKER_GUARD_CONTROL:?test mode required}" in + timeout) printf '%s\n' "$marker"; exec sleep 30 ;; + nonzero) printf '%s\n' "$marker"; exit 7 ;; + missing) echo 'process exited successfully without completing Checker assertions' ;; + partial) printf 'prefix %s suffix\n' "$marker" ;; + success) printf '%s\n' "$marker" ;; + *) exit 2 ;; +esac diff --git a/source/teaql-ts/scripts/generate-query-parser.mjs b/source/teaql-ts/scripts/generate-query-parser.mjs new file mode 100644 index 0000000000000000000000000000000000000000..66e0676bc045ffb95d9f618e07d0ab38e3f353a8 --- /dev/null +++ b/source/teaql-ts/scripts/generate-query-parser.mjs @@ -0,0 +1,9 @@ +import {readFile, writeFile} from 'node:fs/promises'; +import peggy from 'peggy'; + +const grammar = await readFile(new URL('../src/parser/query.pegjs', import.meta.url), 'utf8'); +const source = peggy.generate(grammar, {format: 'es', output: 'source'}); +await writeFile( + new URL('../src/parser/query-parser.generated.ts', import.meta.url), + `// @ts-nocheck -- generated by scripts/generate-query-parser.mjs\n${source}\n`, +); diff --git a/source/teaql-ts/scripts/run-checker-overlap.sh b/source/teaql-ts/scripts/run-checker-overlap.sh new file mode 100644 index 0000000000000000000000000000000000000000..81fca8768aaabe4c0c6563088dad01fef02b9043 --- /dev/null +++ b/source/teaql-ts/scripts/run-checker-overlap.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Requires GNU coreutils timeout (including --kill-after). Guard only this +# Checker consumer; compilation and unrelated examples retain their own flows. +repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +log="${1:?usage: run-checker-overlap.sh LOG_FILE}" +seconds="${TEAQL_TRACE_CHAIN_CHECKER_TIMEOUT_SECONDS:-60}" +if [[ ! "$seconds" =~ ^[1-9][0-9]*$ ]]; then + echo 'FAIL: Checker timeout must be a positive integer number of seconds' >&2 + exit 2 +fi +marker='PASS TypeScript generated Checker overlap: 4 scenarios; real Required rejection, no rejected commands/business SQL/audit; transactions serialized' + +if ( + cd "$repo/examples/trace-chain" + timeout --kill-after=5s "${seconds}s" env -u TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS \ + npm run test:checker-overlap +) > "$log" 2>&1; then + : +else + status=$? + tail -n 20 "$log" >&2 + printf 'FAIL: Checker consumer exit %s; evidence %s\n' "$status" "$log" >&2 + exit "$status" +fi +if ! grep -Fxq -- "$marker" "$log"; then + tail -n 20 "$log" >&2 + printf 'FAIL: Checker consumer omitted its exact PASS marker; evidence %s\n' "$log" >&2 + exit 1 +fi +tail -n 2 "$log" diff --git a/source/teaql-ts/scripts/test-checker-overlap-guard.sh b/source/teaql-ts/scripts/test-checker-overlap-guard.sh new file mode 100644 index 0000000000000000000000000000000000000000..935ae36a21d2881ab97ee3aeef46ee1fb49d1a73 --- /dev/null +++ b/source/teaql-ts/scripts/test-checker-overlap-guard.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +evidence="${1:-$(mktemp -d /tmp/teaql-ts-checker-guard-controls.XXXXXX)}" +mkdir -p "$evidence/bin" +evidence="$(cd "$evidence" && pwd)" +ln -s "$repo/scripts/fixtures/checker-overlap-command.sh" "$evidence/bin/npm" + +for control in timeout nonzero missing partial success; do + case "$control" in + timeout) expected=124 ;; + nonzero) expected=7 ;; + missing|partial) expected=1 ;; + success) expected=0 ;; + esac + if PATH="$evidence/bin:$PATH" TEAQL_CHECKER_GUARD_CONTROL="$control" \ + TEAQL_TRACE_CHAIN_CHECKER_TIMEOUT_SECONDS=1 \ + bash "$repo/scripts/run-checker-overlap.sh" "$evidence/$control-consumer.log" \ + > "$evidence/$control-guard.log" 2>&1; then + actual=0 + else + actual=$? + fi + if [[ "$actual" != "$expected" ]]; then + printf 'FAIL: guard control %s expected %s got %s; evidence %s\n' \ + "$control" "$expected" "$actual" "$evidence" >&2 + exit 1 + fi + printf 'GUARD_CONTROL %s exit=%s expected=%s\n' "$control" "$actual" "$expected" +done +printf 'PASS: Checker verifier guard controls; evidence %s\n' "$evidence" diff --git a/source/teaql-ts/scripts/verify-checker-overlap.sh b/source/teaql-ts/scripts/verify-checker-overlap.sh new file mode 100644 index 0000000000000000000000000000000000000000..f6f449f9a6fd530a9a9c2f1bc6a534c26e7ccc96 --- /dev/null +++ b/source/teaql-ts/scripts/verify-checker-overlap.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +evidence="${TEAQL_TRACE_CHAIN_CHECKER_EVIDENCE:-$(mktemp -d /tmp/teaql-ts-checker-overlap.XXXXXX)}" +mkdir -p "$evidence" +evidence="$(cd "$evidence" && pwd)" +database="${TEAQL_TRACE_CHAIN_CHECKER_DB:-$evidence/checker.sqlite}" +export TEAQL_TRACE_CHAIN_CHECKER_EVIDENCE="$evidence" +export TEAQL_TRACE_CHAIN_CHECKER_DB="$database" + +# file: dependencies execute dist. Rebuild without installing packages or +# resetting data, then replay both modes/orderings against one retained DB. +(cd "$repo" && npm run build) > "$evidence/runtime-build.log" 2>&1 +(cd "$repo/examples/trace-chain" && npm run build) > "$evidence/app-build.log" 2>&1 +for attempt in 1 2; do + TEAQL_TRACE_CHAIN_CHECKER_RUN="attempt-$attempt" \ + bash "$repo/scripts/run-checker-overlap.sh" "$evidence/attempt-$attempt.log" +done +printf 'PASS: retained Checker overlap evidence %s\n' "$evidence" diff --git a/source/teaql-ts/scripts/verify-current-aggregate.sh b/source/teaql-ts/scripts/verify-current-aggregate.sh new file mode 100644 index 0000000000000000000000000000000000000000..4470cf46e4665d3c53cbc365031ecad6dad539c8 --- /dev/null +++ b/source/teaql-ts/scripts/verify-current-aggregate.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail +repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +evidence="${TEAQL_TS_AGGREGATE_EVIDENCE:-$(mktemp -d -t teaql-ts-aggregate-gate.XXXXXXXX)}" +mkdir -p "$evidence" +database="${TEAQL_TRACE_CHAIN_MEMBERSHIP_DB:-$evidence/membership.sqlite}" +unset TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS +(cd "$repo" && npm run build) > "$evidence/runtime-build.log" 2>&1 +(cd "$repo/examples/trace-chain" && npm run build) > "$evidence/app-build.log" 2>&1 +(cd "$repo/examples/trace-chain/lib" && rg --files --hidden --no-ignore -0 | sort -z | xargs -0 sha256sum) > "$evidence/library-before.sha256" +for round in 1 2; do + (cd "$repo" && timeout --kill-after=5s 120s npm test -- --runInBand \ + tests/numeric-partition-trace.test.ts tests/sql-relation-membership.test.ts) > "$evidence/native-$round.log" 2>&1 + (cd "$repo/examples/trace-chain" && TEAQL_TRACE_CHAIN_MEMBERSHIP_DB="$database" \ + timeout --kill-after=5s 90s node node_modules/ts-node/dist/bin.js aggregate-membership.ts) > "$evidence/run-$round.log" 2>&1 + rg -Fxq 'PASS TypeScript generated aggregate membership: 24 scenarios; actual SQL, complete safe ancestry, FK and independent filtered views' "$evidence/run-$round.log" + [[ "$(rg -c '^TS_AGGREGATE_MEMBERSHIP ' "$evidence/run-$round.log")" == 24 ]] +done +(cd "$repo/examples/trace-chain/lib" && rg --files --hidden --no-ignore -0 | sort -z | xargs -0 sha256sum) > "$evidence/library-after.sha256" +cmp "$evidence/library-before.sha256" "$evidence/library-after.sha256" +echo "PASS TypeScript current aggregate gate: native and generated twice; retained database=$database; evidence=$evidence" diff --git a/source/teaql-ts/scripts/verify-examples.sh b/source/teaql-ts/scripts/verify-examples.sh new file mode 100644 index 0000000000000000000000000000000000000000..460849de084edc98aff022b906c0f1a2fa16e594 --- /dev/null +++ b/source/teaql-ts/scripts/verify-examples.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +# file: dependencies resolve the package's dist entry points, not TypeScript source. +# Rebuild here so examples can never silently validate stale checked-in output. +(cd "$repo" && npm run build) +(cd "$repo" && npm test -- --runInBand tests/sql-relation-membership.test.ts) +mkdir -p "$repo/.local" +expected=(browser-sqlite conformance ensure-schema-bootstrap facet-trace order-management school-management task-board trace-chain) +mapfile -t actual < <(find "$repo/examples" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort) +if [[ "${actual[*]}" != "${expected[*]}" ]]; then + echo "example inventory changed; update scripts/verify-examples.sh: ${actual[*]}" >&2 + exit 1 +fi +if rg -n --glob '*.ts' --glob '!**/node_modules/**' --glob '!**/dist/**' \ + '\b(executeForPage|ExecuteForPage|execute_for_page)\b' "$repo/examples"; then + echo 'FAIL: an example still exposes or calls a retired page terminal; regenerate its library' >&2 + exit 1 +fi + +for example in conformance ensure-schema-bootstrap school-management; do + ( + cd "$repo/examples/$example" + npm install + npm run build + if [[ "$example" == school-management ]]; then + npx ts-node app.ts + else + npm start + fi + ) +done +(cd "$repo/examples/order-management" && npm install && npm run build && npm start) +(cd "$repo/examples/task-board" && npm install && npm run build) +(cd "$repo/examples/browser-sqlite" && npm install && npm run build && npm run smoke && npm run smoke:orders) +( + cd "$repo/examples/trace-chain" + npm install + npm run build + for attempt in 1 2; do + graph_log="$(mktemp -t teaql-ts-graph.XXXXXX.log)" + npm start | tee "$graph_log" + rg -Fxq 'PASS TypeScript graph identity controls: duplicate, missing and equal-ID type collapse rejected' "$graph_log" + rg -Fq 'GRAPH IDENTITY EVIDENCE ' "$graph_log" + rg -Fxq 'PASS TypeScript generated trace-chain example: 7 checks' "$graph_log" + [[ "$(rg -c '^PRIVATE_LINEAGE_OBSERVED ' "$graph_log")" == 8 ]] + [[ "$(rg -c '^PASS TypeScript complete private lineage:' "$graph_log")" == 8 ]] + done + env -u TEAQL_TELEMETRY_ENABLED -u TEAQL_TELEMETRY_SERVICE_NAME -u TEAQL_TELEMETRY_OTLP_ENDPOINT npm run test:standard-telemetry + env -u TEAQL_TELEMETRY_ENABLED -u TEAQL_TELEMETRY_SERVICE_NAME -u TEAQL_TELEMETRY_OTLP_ENDPOINT npm run test:standard-telemetry + env -u TEAQL_TELEMETRY_ENABLED -u TEAQL_TELEMETRY_SERVICE_NAME -u TEAQL_TELEMETRY_OTLP_ENDPOINT npm run test:standard-telemetry-graph + env -u TEAQL_TELEMETRY_ENABLED -u TEAQL_TELEMETRY_SERVICE_NAME -u TEAQL_TELEMETRY_OTLP_ENDPOINT npm run test:standard-telemetry-graph + response_directory="$(mktemp -d -t teaql-ts-response-example.XXXXXXXX)" + for attempt in 1 2; do + response_log="$response_directory/round-$attempt.log" + env -u TEAQL_TELEMETRY_ENABLED -u TEAQL_TELEMETRY_SERVICE_NAME -u TEAQL_TELEMETRY_OTLP_ENDPOINT \ + TEAQL_STANDARD_RESPONSE_DB="$response_directory/graphs.sqlite" \ + node node_modules/ts-node/dist/bin.js standard-export-responses.ts | tee "$response_log" + rg -Fxq 'PASS TypeScript standard response graph: create, rollback, retry, update, delete, Q/E, committed audit' "$response_log" + rg -Fq "\"firstSeedAudits\":$((2-attempt)),\"repeatSeedAudits\":0" "$response_log" + done + env -u TEAQL_TRACE_CHAIN_SCENARIO npm run test:shared-reference + env -u TEAQL_TRACE_CHAIN_SCENARIO npm run test:shared-reference + npm run test:page + npm run test:page + npm run test:stream-capture + npm run test:stream-capture +) +for attempt in 1 2; do + aggregate_log="$(mktemp -t teaql-ts-aggregate.XXXXXX.log)" + (cd "$repo/examples/trace-chain" && npm run test:relation-aggregate) | tee "$aggregate_log" + rg -Fq 'FORWARD_NOTLOADED_OBSERVED {"logging":true' "$aggregate_log" + rg -Fq 'FORWARD_NOTLOADED_OBSERVED {"logging":false' "$aggregate_log" +done +bash "$repo/scripts/verify-current-aggregate.sh" +for attempt in 1 2; do + checker_log="$(mktemp -t teaql-ts-checker.XXXXXX.log)" + TEAQL_TRACE_CHAIN_CHECKER_RUN="verify-examples-$attempt" \ + bash "$repo/scripts/run-checker-overlap.sh" "$checker_log" +done +for attempt in 1 2; do + plan_log="$(mktemp -t teaql-ts-plan-items.XXXXXX.log)" + (cd "$repo/examples/trace-chain" && timeout --kill-after=5s 90s npm run test:plan-item-lineage) | tee "$plan_log" + rg -Fxq 'PASS TypeScript generated plan item lineage: 4 scenarios; one plan, ordered same-type items, sibling privacy, independent next request' "$plan_log" +done +bash "$repo/examples/facet-trace/verify.sh" +bootstrap_directory="$(mktemp -d -t teaql-ts-bootstrap.XXXXXXXX)" +for attempt in 1 2; do + bootstrap_log="$bootstrap_directory/round-$attempt.log" + (cd "$repo/examples/trace-chain" && TEAQL_TRACE_CHAIN_BOOTSTRAP_DB="$bootstrap_directory/bootstrap.sqlite" \ + timeout --kill-after=5s 90s npm run test:bootstrap-intent) | tee "$bootstrap_log" + rg -Fxq 'PASS TypeScript generated bootstrap intent: logging off/on, committed audit, repeat no writes, unchanged generated library' "$bootstrap_log" + for logging in false true; do + rg -Fq "\"path\":\"generated default bootstrap\",\"logging\":$logging,\"firstWrites\":$((2-attempt)),\"repeatWrites\":0" "$bootstrap_log" + done +done +echo "PASS: all TypeScript examples" diff --git a/source/teaql-ts/scripts/verify-standard-telemetry.sh b/source/teaql-ts/scripts/verify-standard-telemetry.sh new file mode 100644 index 0000000000000000000000000000000000000000..42943bed6844bea7dfa35212e9f2ca6c8af5c973 --- /dev/null +++ b/source/teaql-ts/scripts/verify-standard-telemetry.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +(cd "$repo" && npm run build) +(cd "$repo" && npm test -- --runInBand --silent \ + tests/telemetry-startup.test.ts tests/standard-telemetry-module.test.ts \ + tests/sql-telemetry-correlation.test.ts tests/runtime-telemetry.test.ts \ + tests/opentelemetry.test.ts tests/log-privacy.test.ts tests/sql-stream.test.ts) +(cd "$repo/examples/trace-chain" && npm run build) +for attempt in 1 2; do + (cd "$repo/examples/trace-chain" && env -u TEAQL_TELEMETRY_ENABLED \ + -u TEAQL_TELEMETRY_SERVICE_NAME -u TEAQL_TELEMETRY_OTLP_ENDPOINT npm run test:standard-telemetry) + (cd "$repo/examples/trace-chain" && env -u TEAQL_TELEMETRY_ENABLED \ + -u TEAQL_TELEMETRY_SERVICE_NAME -u TEAQL_TELEMETRY_OTLP_ENDPOINT npm run test:standard-telemetry-graph) +done +if [[ "${TEAQL_TELEMETRY_ENABLED:-}" == true ]]; then + for attempt in 1 2; do + (cd "$repo/examples/trace-chain" && npm run test:standard-telemetry) + (cd "$repo/examples/trace-chain" && npm run test:standard-telemetry-graph) + done +fi +echo 'PASS TypeScript standard telemetry local example verification' diff --git a/source/teaql-ts/src/core/ast.ts b/source/teaql-ts/src/core/ast.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a241f3f891c5e5eebc4f007032404900f376bdd --- /dev/null +++ b/source/teaql-ts/src/core/ast.ts @@ -0,0 +1,326 @@ +import { Value } from './value'; +import { SmartList } from './smart-list'; +import { retainQueryDiagnosticOrigin, snapshotQuery } from './query-snapshot'; +import type { QueryOperation } from './request-intent'; + +export enum SortDirection { + Asc = 'Asc', + Desc = 'Desc' +} + +export class OrderBy { + constructor( + public field: string, + public expr: any | null, + public direction: SortDirection + ) {} + + static new(field: string, direction: SortDirection): OrderBy { + return new OrderBy(field, null, direction); + } + + static expr(expr: any, direction: SortDirection): OrderBy { + return new OrderBy('', expr, direction); + } + + static asc(field: string): OrderBy { return OrderBy.new(field, SortDirection.Asc); } + static desc(field: string): OrderBy { return OrderBy.new(field, SortDirection.Desc); } +} + +export class AggregationCacheOptions { + constructor( + public enabledValue: boolean, + public cacheExpiredMillis: number, + public propagateValue: boolean, + public propagateCacheExpiredMillis: number + ) {} + + static enabled(cacheExpiredMillis: number): AggregationCacheOptions { + return new AggregationCacheOptions(true, cacheExpiredMillis, false, 0); + } + + propagate(cacheExpiredMillis: number): AggregationCacheOptions { + this.propagateValue = true; + this.propagateCacheExpiredMillis = cacheExpiredMillis; + return this; + } +} + +export interface TeaQLPage { + data: SmartList; + totalCount: number; + offset: number; + limit: number; +} + +export interface QuerySelection { + toQuery(): SelectQuery; +} + +export interface FacetRequest { + facetName: string; + relationName: string; + query: SelectQuery; + includeAllFacets: boolean; + operation?: QueryOperation; +} + +export interface RelationAggregate { + relationName: string; + alias: string; + query: SelectQuery; + singleResult: boolean; + operation?: QueryOperation; +} + +export class SelectQuery { + private hardLimitValue: number = 10_000; + private continuousPageFetchOptions?: { namespace: string; ttlSeconds: number }; + private continuousPageRuntimeContext?: any; + private idSetPaginationOptions?: { namespace: string; ttlSeconds: number; maxIds: number }; + private idSetPaginationRuntimeContext?: any; + private topNProbeThreshold?: number; + public entity: string; + public filterCondition: any | null = null; + public limitValue: number = 0; + public offsetValue: number = 0; + public orderItems: OrderBy[] = []; + public selectItems: string[] = []; + public properties: string[] = []; + public joins: any[] = []; + public groupByItems: string[] = []; + public aggregateItems: any[] = []; + public aggregationCache?: AggregationCacheOptions; + public facets: FacetRequest[] = []; + public relations: Array<{ + name: string; + query?: SelectQuery; + localKey?: string; + foreignKey?: string; + many?: boolean; + operation?: QueryOperation; + }> = []; + public relationAggregates: RelationAggregate[] = []; + public commentText?: string; + public purposeText?: string; + + constructor(entity: string) { + this.entity = entity; + // Local runtime policy must never cross the federation JSON boundary. + Object.defineProperty(this, 'hardLimitValue', { enumerable: false, writable: true, value: 10_000 }); + Object.defineProperty(this, 'continuousPageFetchOptions', { enumerable: false, writable: true, value: undefined }); + Object.defineProperty(this, 'continuousPageRuntimeContext', { enumerable: false, writable: true, value: undefined }); + Object.defineProperty(this, 'idSetPaginationOptions', { enumerable: false, writable: true, value: undefined }); + Object.defineProperty(this, 'idSetPaginationRuntimeContext', { enumerable: false, writable: true, value: undefined }); + Object.defineProperty(this, 'topNProbeThreshold', { enumerable: false, writable: true, value: undefined }); + } + + comment(text: string): this { + this.commentText = text; + return this; + } + + purpose(text: string): this { + this.purposeText = text; + return this; + } + + facetBy( + facetName: string, + relationName: string, + request: QuerySelection, + includeAllFacets = true, + operation?: QueryOperation, + ): this { + this.facets.push({ + facetName, + relationName, + query: request.toQuery(), + includeAllFacets, + operation, + }); + return this; + } + + clone(): SelectQuery { + const copy = snapshotQuery(this); + // Cloning an execution snapshot produces a mutable builder. The request + // envelope still owns immutable intent and reapplies it on derivation. + for (const field of ['commentText', 'purposeText', '_comment', '_purpose']) { + const descriptor = Object.getOwnPropertyDescriptor(copy, field); + if (descriptor && 'value' in descriptor && descriptor.configurable) { + Object.defineProperty(copy, field, { ...descriptor, writable: true }); + } + } + return copy; + } + + filter(condition: any): this { + this.filterCondition = condition; + return this; + } + + limit(limit: number): this { + if (!Number.isSafeInteger(limit) || limit < 1) { + throw new Error('QUERY_INVALID_LIMIT: limit must be a positive safe integer'); + } + this.limitValue = limit; + return this; + } + + optimizeForContinuousPageFetch(): this { + return this.optimizeForContinuousPageFetchWith('default', 600); + } + + optimizeForContinuousPageFetchWith(namespace: string, ttlSeconds: number): this { + if (!namespace?.trim()) throw new Error('continuous page namespace must not be empty'); + if (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0) throw new Error('continuous page ttlSeconds must be a positive integer'); + this.continuousPageFetchOptions = { namespace, ttlSeconds }; + return this; + } + + bindContinuousPageRuntime(runtime: any): this { this.continuousPageRuntimeContext = runtime; return this; } + localContinuousPageOptions(): { namespace: string; ttlSeconds: number } | undefined { return this.continuousPageFetchOptions; } + localContinuousPageRuntime(): any { return this.continuousPageRuntimeContext; } + clearContinuousPageRuntime(): this { this.continuousPageRuntimeContext = undefined; return this; } + + optimizePaginationWithIdSet(): this { + return this.optimizePaginationWithIdSetConfig('default', 600, 3_000_000); + } + + optimizePaginationWithIdSetConfig(namespace: string, ttlSeconds: number, maxIds: number): this { + if (!namespace?.trim()) throw new Error('ID set namespace must not be empty'); + if (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0) throw new Error('ID set ttlSeconds must be a positive integer'); + if (!Number.isSafeInteger(maxIds) || maxIds <= 0) throw new Error('ID set maxIds must be a positive integer'); + this.idSetPaginationOptions = { namespace, ttlSeconds, maxIds }; + return this; + } + + bindIdSetPaginationRuntime(runtime: any): this { this.idSetPaginationRuntimeContext = runtime; return this; } + localIdSetPaginationOptions(): { namespace: string; ttlSeconds: number; maxIds: number } | undefined { return this.idSetPaginationOptions; } + localIdSetPaginationRuntime(): any { return this.idSetPaginationRuntimeContext; } + clearIdSetPaginationRuntime(): this { this.idSetPaginationRuntimeContext = undefined; return this; } + + topNProbeParentThreshold(threshold: number): this { + if (!Number.isSafeInteger(threshold) || threshold < 0) { + throw new Error('topNProbeParentThreshold must be a non-negative safe integer'); + } + this.topNProbeThreshold = threshold; + return this; + } + + localTopNProbeParentThreshold(): number | undefined { + return this.topNProbeThreshold; + } + + prepareForList(): this { + if (!Number.isSafeInteger(this.offsetValue) || this.offsetValue < 0) { + throw new Error('QUERY_INVALID_OFFSET: offset must be a non-negative safe integer'); + } + if (this.limitValue && (!Number.isSafeInteger(this.limitValue) || this.limitValue < 1)) { + throw new Error('QUERY_INVALID_LIMIT: limit must be a positive safe integer'); + } + this.applyListLimit(this.hardLimitValue); + return this; + } + + forExactCount(alias = '__teaql_total'): SelectQuery { + const count = new SelectQuery(this.entity); + count.filterCondition = snapshotQuery(this.filterCondition); + count.commentText = this.commentText; + count.purposeText = this.purposeText; + count.aggregate('Count', 'id', alias); + retainQueryDiagnosticOrigin(this, count); + return count; + } + + private applyListLimit(ceiling: number): void { + if (!this.limitValue) this.limitValue = ceiling; + if (this.limitValue > ceiling) { + throw new Error(`QUERY_HARD_LIMIT_EXCEEDED: requested limit ${this.limitValue} exceeds hard limit ${ceiling}`); + } + for (const relation of this.relations) { + relation.query?.applyListLimit(10_000); + } + } + + offset(offset: number): this { + if (!Number.isSafeInteger(offset) || offset < 0) { + throw new Error('QUERY_INVALID_OFFSET: offset must be a non-negative safe integer'); + } + this.offsetValue = offset; + return this; + } + + relation(name: string): this { + this.relations.push({ name }); + return this; + } + + relationQuery( + name: string, + query: SelectQuery, + localKey = 'id', + foreignKey = 'id', + many = true, + operation?: QueryOperation, + ): this { + this.relations.push({ name, query, localKey, foreignKey, many, operation }); + return this; + } + + relationAggregate( + relationName: string, + alias: string, + query: SelectQuery, + singleResult = true, + operation?: QueryOperation, + ): this { + this.relationAggregates.push({ relationName, alias, query, singleResult, operation }); + return this; + } + + order(orderBy: OrderBy): this { + this.orderItems.push(orderBy); + return this; + } + + select(items: string[]): this { + this.selectItems.push(...items); + return this; + } + + enableAggregationCacheFor(cacheExpiredMillis: number): this { + this.aggregationCache = AggregationCacheOptions.enabled(cacheExpiredMillis); + return this; + } + + propagateAggregationCache(cacheExpiredMillis: number): this { + if (!this.aggregationCache) { + this.aggregationCache = AggregationCacheOptions.enabled(0); + } + this.aggregationCache.propagate(cacheExpiredMillis); + return this; + } + + aggregate(functionName: string, field: string, alias: string): this { + this.aggregateItems.push({ function: functionName, field, alias }); + return this; + } + + groupBy(item: string): this { + this.groupByItems.push(item); + return this; + } +} + +export class MutationQuery { + constructor( + public entity: string, + public action: "Create" | "Update" | "Delete", + public payload: any, + public id?: any, + public comment?: string, + public expectedVersion?: number, + ) {} +} diff --git a/source/teaql-ts/src/core/builtin-messages-v1.json b/source/teaql-ts/src/core/builtin-messages-v1.json new file mode 100644 index 0000000000000000000000000000000000000000..f51e5343fa2883f262dede1ce9c4eda8dd952767 --- /dev/null +++ b/source/teaql-ts/src/core/builtin-messages-v1.json @@ -0,0 +1,156 @@ +{ + "schema": "teaql.i18n/v1", + "defaultLocale": "en", + "locales": { + "en": { + "messages": { + "checker.required": "The {location} is required", + "checker.min": "The {location} should be equal or greater than {system}, but input is {input}", + "checker.max": "The {location} should be equal or less than {system}, but input is {input}", + "checker.minLength": "The length of {location} should be equal or greater than {system}, but the length of {input} is {input_len}", + "checker.maxLength": "The length of {location} should be equal or less than {system}, but the length of {input} is {input_len}" + }, + "vocabulary": {} + }, + "zh-CN": { + "messages": { + "checker.required": "{location} 是必填项", + "checker.min": "{location} 应该大于等于 {system},但输入值为 {input}", + "checker.max": "{location} 应该小于等于 {system},但输入值为 {input}", + "checker.minLength": "{location} 的长度应大于等于 {system},但实际长度为 {input_len}", + "checker.maxLength": "{location} 的长度应小于等于 {system},但实际长度为 {input_len}" + }, + "vocabulary": {} + }, + "zh-TW": { + "messages": { + "checker.required": "{location} 是必填的", + "checker.min": "{location} 應該等於或大於 {system},但輸入為 {input}", + "checker.max": "{location} 應該等於或小於 {system},但輸入為 {input}", + "checker.minLength": "{location} 的長度應該等於或大於 {system},但 {input} 的長度是 {input_len}", + "checker.maxLength": "{location} 的長度應該等於或小於 {system},但 {input} 的長度是 {input_len}" + }, + "vocabulary": {} + }, + "ja": { + "messages": { + "checker.required": "{location} は必須です", + "checker.min": "{location} は {system} 以上である必要があります。入力値は {input} です", + "checker.max": "{location} は {system} 以下である必要があります。入力値は {input} です", + "checker.minLength": "{location} の長さは {system} 以上である必要があります。実際の長さは {input_len} です", + "checker.maxLength": "{location} の長さは {system} 以下である必要があります。実際の長さは {input_len} です" + }, + "vocabulary": {} + }, + "ko": { + "messages": { + "checker.required": "{location}은(는) 필수입니다", + "checker.min": "{location}은(는) {system} 이상이어야 하지만 입력값은 {input}입니다", + "checker.max": "{location}은(는) {system} 이하여야 하지만 입력값은 {input}입니다", + "checker.minLength": "{location}의 길이는 {system} 이상이어야 하지만 실제 길이는 {input_len}입니다", + "checker.maxLength": "{location}의 길이는 {system} 이하여야 하지만 실제 길이는 {input_len}입니다" + }, + "vocabulary": {} + }, + "de": { + "messages": { + "checker.required": "{location} ist erforderlich", + "checker.min": "{location} muss mindestens {system} sein, aber die Eingabe ist {input}", + "checker.max": "{location} darf höchstens {system} sein, aber die Eingabe ist {input}", + "checker.minLength": "Die Länge von {location} muss mindestens {system} sein, ist aber {input_len}", + "checker.maxLength": "Die Länge von {location} darf höchstens {system} sein, ist aber {input_len}" + }, + "vocabulary": {} + }, + "fr": { + "messages": { + "checker.required": "{location} est obligatoire", + "checker.min": "{location} doit être supérieur ou égal à {system}, mais la valeur saisie est {input}", + "checker.max": "{location} doit être inférieur ou égal à {system}, mais la valeur saisie est {input}", + "checker.minLength": "La longueur de {location} doit être supérieure ou égale à {system}, mais elle est {input_len}", + "checker.maxLength": "La longueur de {location} doit être inférieure ou égale à {system}, mais elle est {input_len}" + }, + "vocabulary": {} + }, + "es": { + "messages": { + "checker.required": "{location} es requerido/a", + "checker.min": "{location} debe ser mayor o igual que {system}, pero el valor ingresado es {input}", + "checker.max": "{location} debe ser menor o igual que {system}, pero el valor ingresado es {input}", + "checker.minLength": "La longitud de {location} debe ser mayor o igual que {system}, pero es {input_len}", + "checker.maxLength": "La longitud de {location} debe ser menor o igual que {system}, pero es {input_len}" + }, + "vocabulary": {} + }, + "pt": { + "messages": { + "checker.required": "{location} é obrigatório", + "checker.min": "{location} deve ser maior ou igual a {system}, mas a entrada é {input}", + "checker.max": "{location} deve ser menor ou igual a {system}, mas a entrada é {input}", + "checker.minLength": "O comprimento de {location} deve ser maior ou igual a {system}, mas é {input_len}", + "checker.maxLength": "O comprimento de {location} deve ser menor ou igual a {system}, mas é {input_len}" + }, + "vocabulary": {} + }, + "ar": { + "messages": { + "checker.required": "{location} مطلوب", + "checker.min": "يجب أن يكون {location} مساويًا أو أكبر من {system}، لكن المُدخل هو {input}", + "checker.max": "يجب أن يكون {location} مساويًا أو أصغر من {system}، لكن المُدخل هو {input}", + "checker.minLength": "يجب أن يكون طول {location} مساويًا أو أكبر من {system}، لكن الطول هو {input_len}", + "checker.maxLength": "يجب أن يكون طول {location} مساويًا أو أصغر من {system}، لكن الطول هو {input_len}" + }, + "vocabulary": {} + }, + "th": { + "messages": { + "checker.required": "{location} เป็นสิ่งจำเป็น", + "checker.min": "{location} ควรจะเท่ากับหรือมากกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}", + "checker.max": "{location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ข้อมูลที่ป้อนคือ {input}", + "checker.minLength": "ความยาวของ {location} ควรจะเท่ากับหรือมากกว่า {system} แต่ความยาวคือ {input_len}", + "checker.maxLength": "ความยาวของ {location} ควรจะเท่ากับหรือน้อยกว่า {system} แต่ความยาวคือ {input_len}" + }, + "vocabulary": {} + }, + "id": { + "messages": { + "checker.required": "{location} wajib diisi", + "checker.min": "{location} harus sama dengan atau lebih besar dari {system}, tetapi input adalah {input}", + "checker.max": "{location} harus sama dengan atau lebih kecil dari {system}, tetapi input adalah {input}", + "checker.minLength": "Panjang {location} harus sama dengan atau lebih besar dari {system}, tetapi panjangnya {input_len}", + "checker.maxLength": "Panjang {location} harus sama dengan atau lebih kecil dari {system}, tetapi panjangnya {input_len}" + }, + "vocabulary": {} + }, + "fil": { + "messages": { + "checker.required": "Ang {location} ay kinakailangan", + "checker.min": "Ang {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang input ay {input}", + "checker.max": "Ang {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang input ay {input}", + "checker.minLength": "Ang haba ng {location} ay dapat katumbas o mas malaki kaysa {system}, ngunit ang haba ay {input_len}", + "checker.maxLength": "Ang haba ng {location} ay dapat katumbas o mas maliit kaysa {system}, ngunit ang haba ay {input_len}" + }, + "vocabulary": {} + }, + "uk": { + "messages": { + "checker.required": "{location} є обов'язковим", + "checker.min": "{location} повинен бути рівним або більшим за {system}, але ввідне значення {input}", + "checker.max": "{location} повинен бути рівним або меншим за {system}, але ввідне значення {input}", + "checker.minLength": "Довжина {location} повинна бути рівною або більшою за {system}, але довжина становить {input_len}", + "checker.maxLength": "Довжина {location} повинна бути рівною або меншою за {system}, але довжина становить {input_len}" + }, + "vocabulary": {} + }, + "vi": { + "messages": { + "checker.required": "{location} là bắt buộc", + "checker.min": "{location} phải lớn hơn hoặc bằng {system}, nhưng giá trị nhập là {input}", + "checker.max": "{location} phải nhỏ hơn hoặc bằng {system}, nhưng giá trị nhập là {input}", + "checker.minLength": "Độ dài của {location} phải lớn hơn hoặc bằng {system}, nhưng độ dài là {input_len}", + "checker.maxLength": "Độ dài của {location} phải nhỏ hơn hoặc bằng {system}, nhưng độ dài là {input_len}" + }, + "vocabulary": {} + } + } +} diff --git a/source/teaql-ts/src/core/checker.ts b/source/teaql-ts/src/core/checker.ts new file mode 100644 index 0000000000000000000000000000000000000000..7240d416d01d747f0ad3b4ebac59058cc4d3eaaf --- /dev/null +++ b/source/teaql-ts/src/core/checker.ts @@ -0,0 +1,13 @@ +import { UserContext } from './context'; +import { CheckResult } from './i18n'; + +export interface EntityChecker { + checkAndFix(context: UserContext, mutation: any, results: CheckResult[]): void; +} + +export class CheckException extends Error { + constructor(public readonly violations: readonly CheckResult[]) { + super(`Check failed: ${violations.map(v => v.message ?? `${v.ruleId}:${v.location}`).join('; ')}`); + this.name = 'CheckException'; + } +} diff --git a/source/teaql-ts/src/core/context.ts b/source/teaql-ts/src/core/context.ts new file mode 100644 index 0000000000000000000000000000000000000000..15ac9e7354957df97face00a8723b9860f79fdbf --- /dev/null +++ b/source/teaql-ts/src/core/context.ts @@ -0,0 +1,295 @@ +import { SelectQuery } from './ast'; +import { CheckResult, I18nCatalog, Locale, parseLocale } from './i18n'; +import { + contextSchemaCapability, + InternalContextSchemaExecutor, +} from './schema-capability'; +import { + MutationGovernanceSink, + MutationGovernanceSnapshot, + MutationPlan, + MutationPolicyApprovalProvider, + MutationPolicyRegistry, + MutationPolicyRuntimeState, +} from './mutation-policy'; + +type Cursor = { cursorId: string; boundary: any; expiresAt: number }; +export type RetainedIdSet = { ids: BigUint64Array; expiresAt: number }; +export interface IdSetPaginationStore { + get(key: string): RetainedIdSet | undefined; + put(key: string, value: RetainedIdSet): void; + invalidate?(key: string): void; +} +const resourceIdentities = new WeakMap(); +let nextResourceIdentity = 1; + +function resourceIdentity(value: unknown): string { + if (!value || (typeof value !== 'object' && typeof value !== 'function')) return String(value); + const object = value as object; + let identity = resourceIdentities.get(object); + if (!identity) { identity = nextResourceIdentity++; resourceIdentities.set(object, identity); } + return String(identity); +} + +export type ContextEntityRef = Readonly<{ entity: string; id: string | number | bigint }>; +export type FixEvidence = Readonly<{ + entityType: string; + modelPath: string; + source: 'clock' | 'context'; + sourceLabel: string; +}>; + +export class ContextRootError extends Error { + constructor( + public readonly reason: 'missing' | 'type_mismatch', + public readonly expectedType: string, + public readonly activeRoot?: ContextEntityRef, + ) { + super(`context root ${reason}: expected ${expectedType}`); + this.name = 'ContextRootError'; + } +} + +export class UserContext { + /** Runtime-owned outer boundary used by generated Q execution, never SDK code. */ + async withQueryRequest(query: SelectQuery, work: () => Promise): Promise { + const service = this.requireResource<{ + withQueryRequest?(query: SelectQuery, work: () => Promise): Promise; + }>('dataService'); + return service.withQueryRequest ? service.withQueryRequest(query, work) : work(); + } + + private readonly mutationPolicy = new MutationPolicyRuntimeState(); + private readonly resources = new Map(); + private readonly continuousPageCursors = new Map(); + private readonly retainedIdSets = new Map(); + private readonly idSetBuilds = new Map>(); + private readonly continuousPageRuntime = { + owner: '', + get: (key: string, offset: number) => this.getContinuousPageCursor(key, offset), + put: (key: string, offset: number, cursor: Cursor) => this.putContinuousPageCursor(key, offset, cursor), + observe: (plan: string, cursorId?: string) => { this.continuousPagePlan = plan; this.continuousPageCursorId = cursorId; }, + }; + private readonly idSetPaginationRuntime = { + owner: '', + scope: '', + get: (key: string) => this.idSetStore().get(key), + put: (key: string, value: RetainedIdSet) => this.idSetStore().put(key, value), + build: (key: string, builder: () => Promise) => + this.singleFlightIdSetBuild(key, builder), + observe: (plan: string, count?: number) => { + this.idSetPaginationPlan = plan; + this.idSetPaginationCount = count; + this.idSetPaginationCountAccuracy = plan === 'ID_SET_BUILD' || plan === 'ID_SET_HIT' + ? 'EXACT' + : plan === 'ID_SET_FALLBACK_LIMIT_EXCEEDED' ? 'LOWER_BOUND' : 'UNKNOWN'; + }, + }; + public userIdentifier = ''; + public continuousPagePlan = 'DISABLED'; + public continuousPageCursorId?: string; + public idSetPaginationPlan = 'ID_SET_DISABLED'; + public idSetPaginationCount?: number; + public idSetPaginationCountAccuracy: 'EXACT' | 'LOWER_BOUND' | 'UNKNOWN' = 'UNKNOWN'; + public locale: Locale = 'en'; + public i18nCatalog: I18nCatalog = I18nCatalog.builtin; + + setLocaleCode(code: string): this { const locale = parseLocale(code); this.locale = locale; return this; } + setLanguageCode(code: string): this { return this.setLocaleCode(code); } + installI18nCatalog(catalog: I18nCatalog): this { if(!catalog) throw new Error('catalog is required'); this.i18nCatalog=catalog; return this; } + installIdSetPaginationStore(store: IdSetPaginationStore): this { + if (!store) throw new Error('ID set pagination store is required'); + return this.insertResource('idSetPaginationStore', store); + } + translateCheckResults(results: CheckResult[]): CheckResult[] { return results.map(result=>this.i18nCatalog.translate(result,this.locale)); } + + withMutationPolicyRegistry(registry: MutationPolicyRegistry): this { + if (!registry || typeof registry.resolve !== 'function') { + throw new TypeError('mutation policy registry must expose resolve(requestKey)'); + } + this.mutationPolicy.setRegistry(registry); + return this; + } + + withMutationPolicyApprovalProvider(provider: MutationPolicyApprovalProvider): this { + if (!provider || typeof provider.findApproval !== 'function') { + throw new TypeError('mutation policy approval provider must expose findApproval(identity)'); + } + this.mutationPolicy.setApprovalProvider(provider); + return this; + } + + withMutationGovernanceSink(sink: MutationGovernanceSink): this { + if (!sink || typeof sink.onWarning !== 'function') { + throw new TypeError('mutation governance sink must expose onWarning(context, warning)'); + } + this.mutationPolicy.setWarningSink(sink); + return this; + } + + reviewMutationPlan(plan: MutationPlan): MutationGovernanceSnapshot { + return this.mutationPolicy.review(this, plan); + } + + /** @internal Used by governed data-service graph orchestration. */ + beginMutationPolicyGraph(): void { this.mutationPolicy.beginGraph(); } + /** @internal Used by generated preflight after Checker/Fix. */ + recordMutationPolicyPreflight(mutation: unknown): void { + this.mutationPolicy.recordPreflight(mutation); + } + /** @internal Called at the provider mutation boundary. */ + enterMutationPolicy(mutation: unknown): MutationGovernanceSnapshot { + return this.mutationPolicy.enterMutation(this, mutation).snapshot; + } + /** @internal Must run before the surrounding graph transaction commits. */ + ensureMutationPolicyGraphComplete(): void { this.mutationPolicy.ensureGraphComplete(); } + /** @internal Always runs when the graph operation leaves its transaction. */ + endMutationPolicyGraph(): void { this.mutationPolicy.endGraph(); } + + beginFixEvidence(): this { return this.insertResource('fixEvidenceCurrent', [] as FixEvidence[]); } + recordFixEvidence(evidence: FixEvidence): this { + const label = String(evidence.sourceLabel || ''); + const normalized = label.toLowerCase(); + if (!evidence.entityType || !evidence.modelPath || !label + || normalized.includes('authorization') || normalized.includes('cookie') || normalized.includes('token=')) { + throw new TypeError('Fix evidence must contain only safe framework provenance labels'); + } + const current = this.getResource('fixEvidenceCurrent') ?? []; + if (!this.getResource('fixEvidenceCurrent')) this.insertResource('fixEvidenceCurrent', current); + current.push(Object.freeze({ ...evidence })); + return this; + } + finishFixEvidence(): this { + const current = this.getResource('fixEvidenceCurrent') ?? []; + this.insertResource('fixEvidenceLast', Object.freeze([...current])); + return this.removeResource('fixEvidenceCurrent'); + } + lastFixEvidence(): readonly FixEvidence[] { + return this.getResource('fixEvidenceLast') ?? []; + } + + insertResource(name: string, resource: T): this { + this.resources.set(name, resource); + return this; + } + + getResource(name: string): T | undefined { + return this.resources.get(name) as T | undefined; + } + + removeResource(name: string): this { this.resources.delete(name); return this; } + + requireResource(name: string): T { + const resource = this.getResource(name); + if (resource === undefined) { + throw new Error(`Required UserContext resource is missing: ${name}`); + } + return resource; + } + + /** + * Explicitly reconcile the installed Runtime Module with this context's data service. + * Installing a module never performs schema changes. + */ + ensureSchema(): Promise { + const service = this.requireResource>('dataService'); + const ensure = service[contextSchemaCapability]; + if (!ensure) { + throw new Error('Configured dataService is not a schema-aware TeaQL provider'); + } + return ensure.call(service, this); + } + + withActiveRoot(root: ContextEntityRef): this { + if (!root || !root.entity || root.id === undefined || root.id === null) { + throw new TypeError('active root must be a typed entity reference'); + } + return this.insertResource('activeRoot', Object.freeze({ ...root })); + } + + requireActiveRoot(expectedType: string): ContextEntityRef { + const root = this.getResource('activeRoot'); + if (!root) throw new ContextRootError('missing', expectedType); + if (root.entity !== expectedType) throw new ContextRootError('type_mismatch', expectedType, root); + return root; + } + + /** + * Bind local optimization state without copying trusted runtime resources + * into the query or federation JSON payload. + */ + prepareQuery(query: SelectQuery): SelectQuery { + this.continuousPageRuntime.owner = this.userIdentifier; + this.idSetPaginationRuntime.owner = this.userIdentifier; + const activeRoot = this.getResource('activeRoot'); + this.idSetPaginationRuntime.scope = [ + this.userIdentifier, + activeRoot ? `${activeRoot.entity}:${String(activeRoot.id)}` : '-', + resourceIdentity(this.getResource('dataService')), + ].join('|'); + return query + .bindContinuousPageRuntime(this.continuousPageRuntime) + .bindIdSetPaginationRuntime(this.idSetPaginationRuntime); + } + + private getContinuousPageCursor(key: string, offset: number): Cursor | undefined { + const storeKey = `${key}:${offset}`; + const cursor = this.continuousPageCursors.get(storeKey); + if (cursor && cursor.expiresAt <= Date.now()) { this.continuousPageCursors.delete(storeKey); return undefined; } + return cursor; + } + + private putContinuousPageCursor(key: string, offset: number, cursor: Cursor): void { + if (this.continuousPageCursors.size >= 4096) { + const oldest = [...this.continuousPageCursors.entries()].sort((a, b) => a[1].expiresAt - b[1].expiresAt)[0]; + if (oldest) this.continuousPageCursors.delete(oldest[0]); + } + this.continuousPageCursors.set(`${key}:${offset}`, cursor); + } + + private getRetainedIdSet(key: string): RetainedIdSet | undefined { + const value = this.retainedIdSets.get(key); + if (value && value.expiresAt <= Date.now()) { + this.retainedIdSets.delete(key); + return undefined; + } + return value; + } + + private idSetStore(): IdSetPaginationStore { + return this.getResource('idSetPaginationStore') ?? { + get: key => this.getRetainedIdSet(key), + put: (key, value) => this.putRetainedIdSet(key, value), + invalidate: key => { this.retainedIdSets.delete(key); }, + }; + } + + private putRetainedIdSet(key: string, value: RetainedIdSet): void { + const memoryCeiling = 256 * 1024 * 1024; + if (value.ids.byteLength > memoryCeiling) { + throw new Error('ID set exceeds the process-local store memory ceiling'); + } + const retainedBytes = () => [...this.retainedIdSets.values()] + .reduce((sum, retained) => sum + retained.ids.byteLength, 0); + while (this.retainedIdSets.size >= 64 + || retainedBytes() + value.ids.byteLength > memoryCeiling) { + const oldest = [...this.retainedIdSets.entries()] + .sort((a, b) => a[1].expiresAt - b[1].expiresAt)[0]; + if (!oldest) break; + this.retainedIdSets.delete(oldest[0]); + } + this.retainedIdSets.set(key, value); + } + + private async singleFlightIdSetBuild( + key: string, + builder: () => Promise, + ): Promise<{ value: RetainedIdSet | undefined; built: boolean }> { + const existing = this.idSetBuilds.get(key); + if (existing) return { value: await existing, built: false }; + const pending = builder(); + this.idSetBuilds.set(key, pending); + try { return { value: await pending, built: true }; } + finally { this.idSetBuilds.delete(key); } + } +} diff --git a/source/teaql-ts/src/core/dynamic-search.ts b/source/teaql-ts/src/core/dynamic-search.ts new file mode 100644 index 0000000000000000000000000000000000000000..ece2d671658f1b77e62441ac998c1825035d2934 --- /dev/null +++ b/source/teaql-ts/src/core/dynamic-search.ts @@ -0,0 +1,183 @@ +/** Local UI-search normalization. This is deliberately not a federation decoder. */ +import { OrderBy, SelectQuery } from './ast'; +export type SearchValueType = 'string' | 'number' | 'integer' | 'boolean' | 'date' | 'timestamp' | 'decimal' | 'unsupported'; +export interface SearchModel { + fields: Readonly>; + relations: Readonly>; +} + +/** Model-derived scalar bindings. Native query keys are trusted, not input JSON. */ +export interface GeneratedSearchModel extends SearchModel { + queryFields: Readonly>; +} + +/** + * Default generated binding for scalar fields. Known relation paths require a + * trusted application binding via mergeDynamicSearch, which owns authorization. + * No relation predicate is guessed or silently dropped. + */ +export function mergeGeneratedScalarSearch( + base: SelectQuery, + source: unknown, + models: Readonly>, + warn?: (warning: DynamicSearchWarning) => void, +): { query: SelectQuery; warnings: DynamicSearchWarning[] } { + const field = (path: string): string => { + if (path.includes('.')) throw new Error('Dynamic search requires a trusted relation binding'); + const fields = models[base.entity]?.queryFields; + if (!fields || !Object.prototype.hasOwnProperty.call(fields, path)) { + throw new Error('Missing generated scalar search binding'); + } + return fields[path]; + }; + return mergeDynamicSearch(base, source, models, { + filter: (path, predicate) => { + const [operator, value] = Object.entries(predicate as Record)[0]; + if (value === null && operator !== '$eq' && operator !== '$ne') { + throw new Error('Null supports only equality predicates'); + } + return { [field(path)]: predicate }; + }, + order: (path, direction) => direction === 'asc' ? OrderBy.asc(field(path)) : OrderBy.desc(field(path)), + }, warn); +} +export interface DynamicSearchWarning { + code: 'DYNAMIC_SEARCH_UNKNOWN_FIELD'; + entity: string; + clause: 'FILTER' | 'ORDER_BY'; + fieldPath: string; +} +export interface DynamicSearchInput { + filter?: Record; + orderBy?: Array<{ field: string; direction: 'asc' | 'desc' }>; +} + +/** Trusted application adapters compile canonical model paths using native query APIs. */ +export interface DynamicSearchBindings { + filter(path: string, predicate: unknown): unknown; + order(path: string, direction: 'asc' | 'desc'): OrderBy; +} + +/** Add validated search clauses to an existing scoped query; never replace its policies. */ +export function mergeDynamicSearch( + base: SelectQuery, + source: unknown, + models: Readonly>, + bindings: DynamicSearchBindings, + warn: (warning: DynamicSearchWarning) => void = warning => console.warn({ ...warning, fieldPath: '' }), +): { query: SelectQuery; warnings: DynamicSearchWarning[] } { + const normalized = normalizeDynamicSearch(source, base.entity, models, () => {}); + const filters = Object.entries(normalized.search.filter ?? {}) + .map(([path, predicate]) => bindings.filter(path, predicate)); + const orders = (normalized.search.orderBy ?? []).map(order => bindings.order(order.field, order.direction)); + if (filters.some(filter => !object(filter))) throw new Error('Invalid trusted search filter binding'); + if (orders.some(order => !(order instanceof OrderBy))) throw new Error('Invalid trusted search order binding'); + const query = base.clone(); + // Native providers also accept legacy generated _filters; retain those constraints explicitly. + const legacy = (base as SelectQuery & { _filters?: unknown[] })._filters ?? []; + const existing = [...legacy, ...(base.filterCondition ? [base.filterCondition] : [])]; + if (filters.length || legacy.length) query.filter({ $and: [...existing, ...filters] }); + // Append rather than replace stable default ordering. The application owns primary sort policy. + query.orderItems.push(...orders); + normalized.warnings.forEach(warning => warn({ ...warning })); + return { query, warnings: normalized.warnings }; +} +const own = (object: object, key: string) => Object.prototype.hasOwnProperty.call(object, key); +const object = (value: unknown): value is Record => + typeof value === 'object' && value !== null && !Array.isArray(value); +const forbidden = new Set(['__proto__', 'prototype', 'constructor']); +const operators = new Set(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$notIn', '$contains']); + +/** + * Metadata, resource limits and warning sink must come from trusted application setup. + * No caller-supplied context, limits, SQL, subqueries or arbitrary AST are accepted. + * Returned clauses still require the normal query authorization/execution pipeline. + */ +export function normalizeDynamicSearch( + source: string | unknown, + entity: string, + models: Readonly>, + warn: (warning: DynamicSearchWarning) => void = warning => console.warn({ ...warning, fieldPath: '' }), + maxClauses = 100, +): { search: DynamicSearchInput; warnings: DynamicSearchWarning[] } { + if (!Number.isSafeInteger(maxClauses) || maxClauses < 1) throw new Error('Invalid search limit'); + if (!own(models, entity)) throw new Error('Unknown search entity'); + let input: unknown; + try { input = typeof source === 'string' ? JSON.parse(source) : source; } + catch { throw new Error('Dynamic search requires valid JSON'); } + if (!object(input) || Object.keys(input).some(key => !['filter', 'orderBy'].includes(key))) { + throw new Error('Unsupported dynamic search input or control'); + } + if (input.filter !== undefined && !object(input.filter)) throw new Error('Invalid search filter'); + if (input.orderBy !== undefined && !Array.isArray(input.orderBy)) throw new Error('Invalid search ordering'); + const filters = Object.entries((input.filter ?? {}) as Record); + const orders = (input.orderBy ?? []) as unknown[]; + if (filters.length + orders.length > maxClauses) throw new Error('Dynamic search exceeds clause limit'); + const warnings: DynamicSearchWarning[] = []; + const search: DynamicSearchInput = { filter: Object.create(null), orderBy: [] }; + + function fieldType(path: string): SearchValueType | undefined { + const segments = path.split('.'); + if (segments.length > 16 || segments.some(s => !s || s.startsWith('$') || forbidden.has(s))) { + throw new Error('Invalid dynamic search field path'); + } + let model = models[entity]; + for (const segment of segments.slice(0, -1)) { + if (!own(model.relations, segment)) return undefined; + const target = model.relations[segment]; + if (!own(models, target)) throw new Error('Invalid trusted search relation metadata'); + model = models[target]; + } + const field = segments[segments.length - 1]; + return own(model.fields, field) ? model.fields[field] : undefined; + } + function missing(path: string, clause: DynamicSearchWarning['clause']) { + warnings.push({ code: 'DYNAMIC_SEARCH_UNKNOWN_FIELD', entity, clause, fieldPath: path }); + } + function scalar(value: unknown, type: SearchValueType) { + if (value === null) return; + const valid = type === 'date' + ? typeof value === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(value) && !value.startsWith('0000-') + && Number.isFinite(Date.parse(value + 'T00:00:00Z')) + && new Date(value + 'T00:00:00Z').toISOString().slice(0, 10) === value + : type === 'decimal' + ? (typeof value === 'string' && /^[+-]?\d+(?:\.\d+)?$/.test(value)) + || (typeof value === 'number' && Number.isFinite(value)) + : type === 'integer' || type === 'timestamp' ? typeof value === 'number' && Number.isSafeInteger(value) + : type === 'number' ? typeof value === 'number' && Number.isFinite(value) + : typeof value === type; + if (!valid) throw new Error('Invalid value for known search field'); + } + for (const [path, predicate] of filters) { + const entries = object(predicate) ? Object.entries(predicate) : [['$eq', predicate]]; + if (entries.length !== 1 || !operators.has(entries[0][0] as string)) { + throw new Error('Unsupported or malformed dynamic search operator'); + } + const [operator, value] = entries[0]; + if ((operator === '$in' || operator === '$notIn') && (!Array.isArray(value) || value.length > 1000)) { + throw new Error('Invalid or oversized search value list'); + } + const type = fieldType(path); + if (type === undefined) { missing(path, 'FILTER'); continue; } + if (type === 'unsupported') throw new Error('Known search field has no supported scalar binding'); + if (operator === '$contains' && type !== 'string') throw new Error('String operator requires a string field'); + if (Array.isArray(value)) { + if (operator !== '$in' && operator !== '$notIn') throw new Error('Unexpected search value list'); + value.forEach(item => scalar(item, type)); + } else scalar(value, type); + search.filter![path] = { [operator as string]: Array.isArray(value) ? [...value] : value }; + } + for (const order of orders) { + if (!object(order) || Object.keys(order).some(key => !['field', 'direction'].includes(key)) + || typeof order.field !== 'string' || !['asc', 'desc'].includes(order.direction as string)) { + throw new Error('Invalid dynamic search ordering'); + } + const type = fieldType(order.field); + if (type === undefined) { missing(order.field, 'ORDER_BY'); continue; } + if (type === 'unsupported') throw new Error('Known search field has no supported scalar binding'); + search.orderBy!.push({ field: order.field, direction: order.direction as 'asc' | 'desc' }); + } + // Publish diagnostics only after all fatal validation completes; never log source values. + warnings.forEach(warning => warn({ ...warning })); + return { search, warnings }; +} diff --git a/source/teaql-ts/src/core/entity-root.ts b/source/teaql-ts/src/core/entity-root.ts new file mode 100644 index 0000000000000000000000000000000000000000..f9119ad50830b583e82567bf2be901e3d4ae464c --- /dev/null +++ b/source/teaql-ts/src/core/entity-root.ts @@ -0,0 +1,117 @@ +export type EntityId = string | number | bigint; + +export type EntityKey = Readonly<{ entity: string; id: EntityId }>; +export type EntityChange = Readonly<{ key: EntityKey; values: Readonly> }>; + +const identity = (key: EntityKey): string => `${key.entity}\u0000${typeof key.id}:${String(key.id)}`; + +/** Pending mutation ledger shared by one generated object graph. */ +export class EntityRoot { + private readonly changes = new Map }>(); + private readonly originalVersions = new Map(); + private readonly newKeys = new Map(); + private readonly deletedKeys = new Map(); + private readonly traces = new Map(); + + /** A complete per-entity lineage replaces, rather than extends, graph fallback. */ + setTraceChain(key: EntityKey, nodes: readonly TraceNode[]): void { + this.traces.set(identity(key), { key: Object.freeze({ ...key }), nodes: cloneTraceNodes(nodes) }); + } + traceChain(key: EntityKey): readonly TraceNode[] | undefined { return this.traces.get(identity(key))?.nodes; } + + set(key: EntityKey, field: string, value: unknown): void { + if (!field.trim()) throw new TypeError('field is required'); + const id = identity(key); + const entry = this.changes.get(id) ?? { key: Object.freeze({ ...key }), values: {} }; + entry.values[field] = value; + this.changes.set(id, entry); + } + + snapshot(): EntityChange[] { + return [...this.changes.values()].map(entry => ({ + key: Object.freeze({ ...entry.key }), + values: Object.freeze({ ...entry.values }), + })); + } + + change(key: EntityKey): Readonly> { + return Object.freeze({ ...(this.changes.get(identity(key))?.values ?? {}) }); + } + + mergeFrom(other: EntityRoot): void { + if (other === this) return; + // Validate the whole explicit merge before copying any pending state. + for (const entry of other.snapshotVersions()) this.requireMatchingVersion(entry.key, entry.version); + for (const entry of other.snapshot()) for (const [field, value] of Object.entries(entry.values)) this.set(entry.key, field, value); + for (const key of other.newKeys.values()) this.markAsNew(key); + for (const key of other.deletedKeys.values()) this.markAsDeleted(key); + for (const entry of other.snapshotVersions()) this.setOriginalVersion(entry.key, entry.version); + for (const entry of other.traces.values()) this.setTraceChain(entry.key, entry.nodes); + } + + /** Import one explicitly reached entity, never its foreign graph or ownership. */ + mergeEntityFrom(other: EntityRoot, key: EntityKey): void { + if (other === this) return; + const version = other.originalVersion(key); + if (version !== undefined) this.requireMatchingVersion(key, version); + for (const [field, value] of Object.entries(other.change(key))) this.set(key, field, value); + if (other.isNew(key)) this.markAsNew(key); + if (other.isDeleted(key)) this.markAsDeleted(key); + if (version !== undefined) this.setOriginalVersion(key, version); + const trace = other.traceChain(key); + if (trace) this.setTraceChain(key, trace); + } + + hasPending(key: EntityKey): boolean { + const id = identity(key); + return this.newKeys.has(id) || this.deletedKeys.has(id) + || Object.keys(this.changes.get(id)?.values ?? {}).length > 0; + } + + private snapshotVersions(): Array<{ key: EntityKey; version: number }> { return [...this.originalVersions.values()]; } + + rekey(oldKey: EntityKey, newKey: EntityKey): void { + const oldId = identity(oldKey); const newId = identity(newKey); if (oldId === newId) return; + const loadedVersion = this.originalVersion(oldKey); + if (loadedVersion !== undefined) this.requireMatchingVersion(newKey, loadedVersion); + const entry = this.changes.get(oldId); if (entry) { this.changes.delete(oldId); for (const [field, value] of Object.entries(entry.values)) this.set(newKey, field, value); } + const version = this.originalVersions.get(oldId); if (version !== undefined) { this.originalVersions.delete(oldId); this.originalVersions.set(newId, { key: Object.freeze({ ...newKey }), version: version.version }); } + if (this.newKeys.delete(oldId)) this.newKeys.set(newId, Object.freeze({ ...newKey })); + if (this.deletedKeys.delete(oldId)) this.deletedKeys.set(newId, Object.freeze({ ...newKey })); + const trace = this.traces.get(oldId); + if (trace) { this.traces.delete(oldId); this.setTraceChain(newKey, trace.nodes); } + } + + clearEntity(key: EntityKey): void { + const id = identity(key); this.changes.delete(id); this.newKeys.delete(id); this.deletedKeys.delete(id); this.traces.delete(id); + } + + private requireMatchingVersion(key: EntityKey, version: number): void { + const original = this.originalVersion(key); + if (original !== undefined && original !== version) { + throw new Error('ENTITY_VERSION_CONFLICT: one graph cannot contain different loaded versions of the same typed entity'); + } + } + setOriginalVersion(key: EntityKey, version: number): void { + this.requireMatchingVersion(key, version); + this.originalVersions.set(identity(key), { key: Object.freeze({ ...key }), version }); + } + /** @internal Accept only the authoritative result after this key committed. */ + acceptCommittedVersion(key: EntityKey, version: number): void { + if (this.hasPending(key)) throw new Error('ENTITY_COMMIT_PENDING: clear committed changes before accepting the persisted version'); + this.originalVersions.set(identity(key), { key: Object.freeze({ ...key }), version }); + } + originalVersion(key: EntityKey): number | undefined { return this.originalVersions.get(identity(key))?.version; } + markAsNew(key: EntityKey): void { this.newKeys.set(identity(key), Object.freeze({ ...key })); } + isNew(key: EntityKey): boolean { return this.newKeys.has(identity(key)); } + markAsDeleted(key: EntityKey): void { const id = identity(key); this.changes.delete(id); this.deletedKeys.set(id, Object.freeze({ ...key })); } + isDeleted(key: EntityKey): boolean { return this.deletedKeys.has(identity(key)); } + + clearCommitted(): void { + this.changes.clear(); + this.newKeys.clear(); + this.deletedKeys.clear(); + this.traces.clear(); + } +} +import { cloneTraceNodes, TraceNode } from './trace-chain'; diff --git a/source/teaql-ts/src/core/facet.ts b/source/teaql-ts/src/core/facet.ts new file mode 100644 index 0000000000000000000000000000000000000000..1d926fdb5cf7e121eb82a637198598353199c6ea --- /dev/null +++ b/source/teaql-ts/src/core/facet.ts @@ -0,0 +1,245 @@ +import { FacetRequest, SelectQuery } from './ast'; +import { SmartList, SmartListRecord } from './smart-list'; +import { QueryRequest } from './request-intent'; +import { retainQueryDiagnosticOrigin } from './query-snapshot'; + +export interface FacetAggregate { + function: string; + field: string; + alias: string; +} + +export interface FacetQueryService { + executeQuery(query: SelectQuery): Promise; + executeFacetAggregates?( + outerQuery: SelectQuery, + relationName: string, + aggregates: readonly FacetAggregate[], + ): Promise>; + executeFacetMembership?( + outerQuery: SelectQuery, relationName: string, countAliases?: readonly string[], + ): Promise>; +} + +function snakeCase(value: string): string { + return value.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase(); +} + +function scalarId(value: unknown): unknown { + if (value && typeof value === 'object') { + const record = value as Record; + return record.id ?? record.Id; + } + return value; +} + +function relationId(row: SmartListRecord, relationName: string): unknown { + const snake = snakeCase(relationName); + for (const key of [relationName, `${relationName}Id`, snake, `${snake}_id`]) { + const value = scalarId(row[key]); + if (value !== undefined && value !== null) return value; + } + return undefined; +} + +function emptyAggregateValue(aggregate: FacetAggregate): unknown { + const fn = aggregate.function.toLowerCase(); + return fn === 'count' || fn === 'sum' ? 0 : null; +} + +function compareAggregateValues(left: unknown, right: unknown): number { + if (typeof left === 'number' && typeof right === 'number') return left - right; + if (left instanceof Date && right instanceof Date) return left.getTime() - right.getTime(); + return String(left).localeCompare(String(right)); +} + +async function executeFacetAggregatesFallback( + service: FacetQueryService, + prepareQuery: (query: SelectQuery) => SelectQuery, + request: QueryRequest, + outerQuery: SelectQuery, + relationName: string, + aggregates: readonly FacetAggregate[], +): Promise> { + const membershipQuery = outerQuery.clone(); + membershipQuery.facets = []; + membershipQuery.relations = []; + membershipQuery.relationAggregates = []; + membershipQuery.orderItems = []; + membershipQuery.aggregateItems = []; + membershipQuery.groupByItems = []; + membershipQuery.offsetValue = 0; + membershipQuery.limitValue = 0; + membershipQuery.selectItems = [...new Set([ + relationName, + ...aggregates.map(aggregate => aggregate.field), + ])]; + membershipQuery.comment(`aggregate ${relationName}`); + retainQueryDiagnosticOrigin(outerQuery, membershipQuery); + const memberships = await service.executeQuery( + request.deriveHelper(prepareQuery(membershipQuery), `aggregate ${relationName}`).query, + ); + const result = new Map(); + const averageCounts = new Map>(); + + for (const row of memberships) { + const id = relationId(row, relationName); + if (id === undefined || id === null) continue; + const key = String(id); + const values = result.get(key) ?? {}; + const counts = averageCounts.get(key) ?? {}; + for (const aggregate of aggregates) { + const fn = aggregate.function.toLowerCase(); + const raw = row[aggregate.field]; + if (fn === 'count') { + if (raw !== undefined && raw !== null) { + values[aggregate.alias] = Number(values[aggregate.alias] ?? 0) + 1; + } + } else if (fn === 'sum' || fn === 'avg') { + if (raw !== undefined && raw !== null) { + const numeric = Number(raw); + if (!Number.isFinite(numeric)) { + throw new Error(`Facet aggregate ${aggregate.alias} requires numeric values`); + } + values[aggregate.alias] = Number(values[aggregate.alias] ?? 0) + numeric; + if (fn === 'avg') counts[aggregate.alias] = (counts[aggregate.alias] ?? 0) + 1; + } + } else if (fn === 'min' || fn === 'max') { + if (raw !== undefined && raw !== null) { + const current = values[aggregate.alias]; + const comparison = current === undefined || current === null + ? 0 + : compareAggregateValues(raw, current); + if (current === undefined || current === null + || (fn === 'min' && comparison < 0) + || (fn === 'max' && comparison > 0)) { + values[aggregate.alias] = raw; + } + } + } else { + throw new Error(`Unsupported facet aggregate: ${aggregate.function}`); + } + } + result.set(key, values); + averageCounts.set(key, counts); + } + + for (const [key, values] of result) { + const counts = averageCounts.get(key) ?? {}; + for (const aggregate of aggregates) { + if (aggregate.function.toLowerCase() !== 'avg') continue; + const count = counts[aggregate.alias] ?? 0; + values[aggregate.alias] = count ? Number(values[aggregate.alias] ?? 0) / count : null; + } + } + return result; +} + +/** + * Execute relation facets without crossing entity boundaries with the outer + * filter. The outer query determines relation membership; the nested query + * determines which facet entities and fields are returned. + */ +export async function executeRelationFacets( + service: FacetQueryService, + prepareQuery: (query: SelectQuery) => SelectQuery, + outerQuery: SelectQuery, + facets: readonly FacetRequest[], +): Promise>> { + const request = new QueryRequest(outerQuery); + outerQuery = request.query; + const result: Record> = {}; + for (const facet of facets) { + const operation = request.deriveOperation(outerQuery, facet.operation ?? { + kind: 'facet', relation: facet.relationName, alias: facet.facetName, + }); + const nestedRequest = operation.deriveChild(facet.query.clone(), facet.relationName); + const nestedQuery = nestedRequest.query; + const nestedFacets = nestedQuery.facets; + nestedQuery.facets = []; + const requestedAggregates: FacetAggregate[] = nestedQuery.aggregateItems.map(item => ({ + function: String(item.function), + field: String(item.field), + alias: String(item.alias), + })); + const executedAggregates = requestedAggregates.length + ? requestedAggregates + : [{ function: 'Count', field: 'id', alias: '__teaql_facet_membership_count' }]; + let aggregateValues: Map; + if (service.executeFacetAggregates) { + aggregateValues = await service.executeFacetAggregates( + operation.deriveHelper( + prepareQuery(outerQuery.clone()), `aggregate ${facet.relationName}`, + ).query, + facet.relationName, + executedAggregates, + ); + } else if (service.executeFacetMembership + && executedAggregates.every(item => item.function.toLowerCase() === 'count')) { + const counts = await service.executeFacetMembership( + operation.deriveHelper( + prepareQuery(outerQuery.clone()), `aggregate ${facet.relationName}`, + ).query, + facet.relationName, + ); + aggregateValues = new Map([...counts].map(([key, count]) => [ + key, + Object.fromEntries(executedAggregates.map(item => [item.alias, count])), + ])); + } else { + aggregateValues = await executeFacetAggregatesFallback( + service, prepareQuery, operation, outerQuery, facet.relationName, executedAggregates, + ); + } + nestedQuery.aggregateItems = []; + nestedQuery.groupByItems = []; + for (const aggregate of nestedQuery.relationAggregates) { + if (aggregate.query.entity !== outerQuery.entity) continue; + // Reverse facet sums share the complete source membership, not the + // returned page or all source rows pointing at the same facet value. + const membership = outerQuery.clone(); + membership.selectItems = ['id']; + membership.properties = []; + membership.relations = []; + membership.relationAggregates = []; + membership.facets = []; + membership.aggregateItems = []; + membership.groupByItems = []; + membership.orderItems = []; + membership.offsetValue = 0; + membership.limitValue = 0; + const filter = { id: { $inSubquery: { query: membership, field: 'id' } } }; + aggregate.query.filterCondition = aggregate.query.filterCondition + ? { $and: [aggregate.query.filterCondition, filter] } : filter; + retainQueryDiagnosticOrigin(outerQuery, aggregate.query); + } + // Restrict before pagination and before evaluating child facets. Filtering + // only the returned rows makes child counts include unrelated entities. + if (!facet.includeAllFacets) { + const membership = { id: { $in: [...aggregateValues.keys()] } }; + nestedQuery.filterCondition = nestedQuery.filterCondition + ? { $and: [nestedQuery.filterCondition, membership] } : membership; + } + retainQueryDiagnosticOrigin(outerQuery, nestedQuery); + const rows = await service.executeQuery(nestedRequest.withQuery(prepareQuery(nestedQuery)).query); + const decorated = rows + .map(row => { + const key = String(scalarId(row.id ?? row.Id)); + const values = aggregateValues.get(key); + const copy = { ...row }; + for (const aggregate of requestedAggregates) { + copy[aggregate.alias] = values?.[aggregate.alias] ?? emptyAggregateValue(aggregate); + } + return copy; + }) + .filter(row => facet.includeAllFacets + || aggregateValues.has(String(scalarId(row.id ?? row.Id)))); + const list = new SmartList(decorated); + if (nestedFacets.length) { + list.facets = await executeRelationFacets(service, prepareQuery, + nestedRequest.withQuery(nestedQuery).query, nestedFacets); + } + result[facet.facetName] = list; + } + return result; +} diff --git a/source/teaql-ts/src/core/i18n.ts b/source/teaql-ts/src/core/i18n.ts new file mode 100644 index 0000000000000000000000000000000000000000..24d5e6445a0dc147b628a4c6e89f08ce9c65b1d8 --- /dev/null +++ b/source/teaql-ts/src/core/i18n.ts @@ -0,0 +1,19 @@ +import builtinJson from './builtin-messages-v1.json'; +import { JsonFieldNamingProfile, ObjectLocation, ObjectLocationSegment } from './object-location'; + +export const locales = ['en','zh-CN','zh-TW','ja','ko','de','fr','es','pt','ar','th','id','fil','uk','vi'] as const; +export type Locale = typeof locales[number]; +export class UnsupportedLocaleError extends Error { constructor(public readonly localeCode: unknown){super(`Unsupported locale: ${localeCode}`);} } +const aliases:Record={'en-us':'en','en-gb':'en','zh':'zh-CN','zh-hans':'zh-CN','zh-sg':'zh-CN','cn':'zh-CN','zh-hant':'zh-TW','zh-hk':'zh-TW','zh-mo':'zh-TW','tw':'zh-TW','ja-jp':'ja','ko-kr':'ko','de-de':'de','fr-fr':'fr','es-mx':'es','pt-br':'pt','pt-pt':'pt','ar-sa':'ar','th-th':'th','id-id':'id','tl':'fil','fil-ph':'fil','uk-ua':'uk','vi-vn':'vi'}; +export function parseLocale(code:unknown):Locale{if(typeof code!=='string'||!code.trim())throw new UnsupportedLocaleError(code);const normalized=code.trim().replace(/_/g,'-').toLowerCase();const canonical=locales.find(v=>v.toLowerCase()===normalized);if(canonical)return canonical;const alias=aliases[normalized];if(!alias)throw new UnsupportedLocaleError(code);return alias;} +type LocaleData={messages:Record;vocabulary:Record}; +export type CatalogData={schema:string;defaultLocale:string;locales:Record}; +export interface CheckResult{ruleId:string;entityType?:string;location:ObjectLocation;sourceInstancePath?:string;inputValue?:unknown;systemValue?:unknown;message?:string} +export interface WireCheckResult{ruleId:string;entityType?:string;location:readonly ObjectLocationSegment[];instancePath:string;sourceInstancePath?:string;inputValue?:unknown;systemValue?:unknown;message?:string} +export function checkResultToWire(result:CheckResult,profile:JsonFieldNamingProfile='camelCase'):WireCheckResult{return {ruleId:result.ruleId,entityType:result.entityType,location:result.location.segments,instancePath:result.location.instancePath(profile),sourceInstancePath:result.sourceInstancePath,inputValue:result.inputValue,systemValue:result.systemValue,message:result.message};} +export class I18nCatalog{ + static readonly builtin=new I18nCatalog(builtinJson as CatalogData); + constructor(private readonly data:CatalogData,private readonly fallback?:I18nCatalog){if(data.schema!=='teaql.i18n/v1')throw new Error('Unsupported i18n schema');Object.keys(data.locales).forEach(parseLocale);} + message(locale:Locale,key:string):string{return this.data.locales[locale]?.messages[key]??this.fallback?.data.locales[locale]?.messages[key]??this.data.locales.en?.messages[key]??this.fallback?.data.locales.en?.messages[key]??key;} + translate(result:CheckResult,locale:Locale):CheckResult{const keys:Record={required:'checker.required',min:'checker.min',max:'checker.max',min_str_len:'checker.minLength',min_length:'checker.minLength',max_str_len:'checker.maxLength',max_length:'checker.maxLength'};const key=keys[result.ruleId.toLowerCase()]??`checker.${result.ruleId.toLowerCase()}`;const input=String(result.inputValue);const length=typeof result.inputValue==='string'?[...result.inputValue].length:0;result.message=this.message(locale,key).split('{location}').join(result.location.nativePath()).split('{system}').join(String(result.systemValue)).split('{input}').join(input).split('{input_len}').join(String(length));return result;} +} diff --git a/source/teaql-ts/src/core/loaded-scalar-snapshot.ts b/source/teaql-ts/src/core/loaded-scalar-snapshot.ts new file mode 100644 index 0000000000000000000000000000000000000000..7cd4da3351aa06125e9b97c3ba1ca445f8159f4b --- /dev/null +++ b/source/teaql-ts/src/core/loaded-scalar-snapshot.ts @@ -0,0 +1,32 @@ +import { snapshotQuery } from './query-snapshot'; + +const loadedSnapshots = new WeakMap(); + +/** @internal Loaded scalar provenance. No relations, ownership, SQL or Context. */ +export class LoadedScalarSnapshot { + readonly #values: Readonly>; + + constructor(values: Record = {}) { + this.#values = snapshotQuery(values); + Object.freeze(this); + } + + /** Copies prevent callers or mutable JSON/date fields from rewriting history. */ + values(): Readonly> { return snapshotQuery(this.#values); } + + /** @internal Generated hydration stores provenance outside entity/JSON state. */ + static captureFor(entity: object, values: Record): LoadedScalarSnapshot { + const snapshot = new LoadedScalarSnapshot(values); + loadedSnapshots.set(entity, snapshot); + return snapshot; + } + + /** @internal Mutation uses the loaded values, not already-edited properties. */ + static forEntity(entity: object): LoadedScalarSnapshot | undefined { return loadedSnapshots.get(entity); } + + /** @internal Rollback restores provenance together with authoritative entity state. */ + static restoreFor(entity: object, snapshot: LoadedScalarSnapshot | undefined): void { + if (snapshot) loadedSnapshots.set(entity, snapshot); + else loadedSnapshots.delete(entity); + } +} diff --git a/source/teaql-ts/src/core/local-cache.ts b/source/teaql-ts/src/core/local-cache.ts new file mode 100644 index 0000000000000000000000000000000000000000..f21a309351b39ac08739b81e97cec243d7607171 --- /dev/null +++ b/source/teaql-ts/src/core/local-cache.ts @@ -0,0 +1,36 @@ +type LocalCacheEntry = { + value: unknown; + expiresAt?: number; +}; + +/** Process-local cache with optional TTL in seconds. */ +export class LocalCache { + private readonly entries = new Map(); + + put(key: string, value: unknown, timeToLiveInSeconds?: number): void { + const expiresAt = timeToLiveInSeconds !== undefined && timeToLiveInSeconds > 0 + ? Date.now() + timeToLiveInSeconds * 1000 + : undefined; + this.entries.set(key, { value, expiresAt }); + } + + get(key: string): T | undefined { + const entry = this.entries.get(key); + if (entry === undefined) return undefined; + if (entry.expiresAt !== undefined && Date.now() >= entry.expiresAt) { + this.entries.delete(key); + return undefined; + } + return entry.value as T; + } + + remove(key: string): void { + this.entries.delete(key); + } + + clear(): void { + this.entries.clear(); + } +} + +export const localCache = new LocalCache(); diff --git a/source/teaql-ts/src/core/log-privacy.ts b/source/teaql-ts/src/core/log-privacy.ts new file mode 100644 index 0000000000000000000000000000000000000000..f74b4cbdcc0c566886f45f91a5bc48c9744d0efd --- /dev/null +++ b/source/teaql-ts/src/core/log-privacy.ts @@ -0,0 +1,246 @@ +import type { SQLExecutionMetadata } from '../sql/core'; +import { renderSQL, sqlLiteral, SQLParameterLogPolicy } from '../sql/log-rendering'; + +export const PLAINTEXT_LOG_ENV = 'TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS'; +export const PLAINTEXT_LOG_ACK = 'I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK'; +const redacted = '[REDACTED]'; +const redactedSQL = '[REDACTED SQL; NOT REPLAYABLE]'; +const debugLabel = '-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN\n'; +let warned = false; + +/** Business-field masking; credentials always need complete redaction instead. */ +export function maskAuditValue(value: string): string { + const scalars = Array.from(value); + if (scalars.length < 8 || /^[0-9]+$/.test(value)) return '*'.repeat(scalars.length); + return scalars.slice(0, 2).join('') + '*'.repeat(scalars.length - 4) + scalars.slice(-2).join(''); +} + +export function plaintextLogsEnabled(): boolean { + // Browsers have no trusted process environment: remain redacted there. + const environment = (globalThis as typeof globalThis & { + process?: { env?: Record }; + }).process?.env; + const enabled = environment?.[PLAINTEXT_LOG_ENV] === PLAINTEXT_LOG_ACK; + if (enabled && !warned) { + warned = true; + console.warn('TeaQL: sensitive plaintext logging enabled; application data may be written to disk. Authentication secrets remain redacted.'); + } + return enabled; +} + +export function credentialName(name: string): boolean { + const normalized = name.toLowerCase().replace(/[^a-z0-9]/g, ''); + return ['password', 'passwd', 'passphrase', 'privatekey', 'secret', 'accesstoken', + 'refreshtoken', 'idtoken', 'apikey', 'authorization', 'credential', 'sessiontoken', + 'magiclinktoken'].some(word => normalized.includes(word)); +} + +export function hasCredentials(value: unknown): boolean { + if (Array.isArray(value)) return value.some(hasCredentials); + if (value && typeof value === 'object') { + return Object.entries(value).some(([key, child]) => credentialName(key) || hasCredentials(child)); + } + return false; +} + +export function logValueStrings(value: unknown): string[] { + if (value === undefined || value === null || value === '') return []; + if (Array.isArray(value)) return value.flatMap(logValueStrings); + if (value instanceof Date) return [value.toISOString()]; + if (typeof value === 'object') return Object.values(value).flatMap(logValueStrings); + return [String(value)]; +} + +export function scrubLogText(text: string | undefined, values: readonly string[]): string | undefined { + return [...new Set(values)].sort((a,b) => b.length - a.length) + .reduce((result, value) => result?.split(value).join(redacted), text); +} + +const projections = new WeakMap(); +// A debug record can later reach a sink after debug is disabled. Keep only its +// already-safe alternative, never raw source parameters/provenance on a record. +const safeAlternatives = new WeakMap(); +const rawProvenance = new WeakMap(); + +/** @internal Keep result reprojection safe without serializing raw provenance. */ +export function retainSQLLogProvenance(metadata: SQLExecutionMetadata, bindings?: SQLLogBindingSource, + intentValues: readonly unknown[] = []): void { + rawProvenance.set(metadata, { bindings: bindings ? inheritSQLLogBindings(bindings) : undefined, + intentValues: Object.freeze(intentValues.map(copyLogValue)) }); +} + +/** Internal SQL compiler/runtime plumbing, never a request or wire option. */ +export type SQLLogBindingSource = Pick; + +function bindingPolicies(metadata: SQLLogBindingSource): SQLParameterLogPolicy[] { + const supplied = metadata.parameterLogPolicies; + const valid = !!supplied && supplied.length === metadata.parameters.length; + const credentialStatement = credentialName(metadata.parameterizedSQL) + && (metadata.sqlOrigin !== 'generated' || !valid); + return metadata.parameters.map((value, index) => { + if (credentialStatement || hasCredentials(value)) return 'credential'; + const policy = valid ? supplied[index] : undefined; + return policy === 'plain' || policy === 'masked' || policy === 'credential' ? policy : 'unknown'; + }); +} + +function bindingIsMasked(policy: SQLParameterLogPolicy, allow: boolean): boolean { + return policy === 'credential' || policy === 'unknown' || (!allow && policy !== 'plain'); +} + +/** Audit is always safe-mode; explicitly public loaded scalars are not secrets. */ +export function privateLogValueStrings(source?: SQLLogBindingSource): string[] { + if (!source) return []; + const policies = bindingPolicies(source); + return source.parameters.flatMap((value, index) => + bindingIsMasked(policies[index], false) ? logValueStrings(value) : []); +} + +function copyLogValue(value: unknown): unknown { + if (value instanceof Date) return new Date(value.getTime()); + if (value instanceof Uint8Array) return new Uint8Array(value); + if (Array.isArray(value)) return Object.freeze(value.map(copyLogValue)); + if (value && typeof value === 'object') return Object.freeze(Object.fromEntries( + Object.entries(value).map(([key, child]) => [key, copyLogValue(child)]))); + return value; +} + +/** Internal compiler plumbing: snapshot and flatten ancestor binding policies. + * Never attach this raw provenance to a query payload or projected log record. */ +export function inheritSQLLogBindings(source: SQLLogBindingSource, inherited?: SQLLogBindingSource): SQLLogBindingSource { + const sources = inherited ? [inherited, source] : [source]; + return Object.freeze({ + parameterizedSQL: '', sqlOrigin: 'generated' as const, + parameters: Object.freeze(sources.flatMap(item => item.parameters.map(copyLogValue))), + parameterLogPolicies: Object.freeze(sources.flatMap(bindingPolicies)), + }); +} + +function businessMask(value: unknown): unknown { + if (value === null || value === undefined) return null; + if (Array.isArray(value)) return value.map(businessMask); + if (value && typeof value === 'object' && 'type' in value) { + return businessMask((value as { value?: unknown }).value); + } + if (typeof value === 'object' && !(value instanceof Date)) return redacted; + return maskAuditValue(value instanceof Date ? value.toISOString() : String(value)); +} + +export function projectSQLLog(metadata: SQLExecutionMetadata, inherited?: SQLLogBindingSource, + intentValues: readonly unknown[] = []): SQLExecutionMetadata { + const allow = plaintextLogsEnabled() && metadata.logMode !== 'masked'; + const prior = projections.get(metadata); + // Safe projections cannot recover raw values. If debug gets disabled, reproject. + if (prior !== undefined && (!prior || allow)) return metadata; + const safe = safeAlternatives.get(metadata); + if (!allow && safe) return safe; + const projected = projectWithPolicy(metadata, allow, inherited, intentValues); + projections.set(projected, allow); + if (allow) { + const alternative = projectWithPolicy(metadata, false, inherited, intentValues); + projections.set(alternative, false); + safeAlternatives.set(projected, alternative); + } + return projected; +} + +/** Telemetry always uses safe mode even when local plaintext debugging is enabled. */ +export function projectSafeSQLLog(metadata: SQLExecutionMetadata): SQLExecutionMetadata { + const safe = safeAlternatives.get(metadata); + if (safe) return safe; + if (projections.get(metadata) === false) return metadata; + const projected = projectWithPolicy(metadata, false); + projections.set(projected, false); + return projected; +} + +function projectWithPolicy(metadata: SQLExecutionMetadata, allow: boolean, inherited?: SQLLogBindingSource, + intentValues: readonly unknown[] = []): SQLExecutionMetadata { + const retained = rawProvenance.get(metadata); + if (retained?.bindings) inherited = inheritSQLLogBindings(retained.bindings, inherited); + if (retained) intentValues = [...intentValues, ...retained.intentValues]; + const supplied = metadata.parameterLogPolicies; + const policiesValid = !supplied || supplied.length === metadata.parameters.length; + // Compiler-owned bindings identify credentials individually. Selecting a + // credential column must not override unrelated ordinary/masked policies. + const credentialStatement = credentialName(metadata.parameterizedSQL) + && (metadata.sqlOrigin !== 'generated' || !supplied || !policiesValid); + const policies = bindingPolicies(metadata); + const masked = policies.map(policy => bindingIsMasked(policy, allow)); + const secrets = metadata.parameters.flatMap((value, index) => masked[index] ? logValueStrings(value) : []); + if (inherited) { + const inheritedPolicies = bindingPolicies(inherited); + secrets.push(...inherited.parameters.flatMap((value, index) => + bindingIsMasked(inheritedPolicies[index], allow) ? logValueStrings(value) : [])); + } + const intentSecrets = [...secrets, ...intentValues.flatMap(logValueStrings)]; + // Copies/serialization discard the private safe alternative. Their old debug + // intent has unknown provenance, so fail closed when returning to safe mode. + const unknownDebugIntent = !allow && metadata.logMode === 'debug-plaintext' && !inherited; + const intentText = (value: string | undefined): string | undefined => + unknownDebugIntent && value ? redacted : scrubLogText(value, intentSecrets); + const safeValues = metadata.parameters.map((value, index) => { + if (!masked[index]) return copyLogValue(value); + return policies[index] === 'masked' ? businessMask(value) : redacted; + }); + const bareTemplate = metadata.parameterizedSQL.replace(/\$[0-9]+|@p[0-9]+/gi, '?'); + // Unclassified literal SQL needs a real parser/provenance before it is safe to log. + // Compiled runtime SQL has trusted identifiers and fixed literals, not injected values. + const unsafeSQL = (!allow || credentialStatement) && metadata.sqlOrigin !== 'generated' + && /['"`$]|--|\/\*|\b\d+\b|:[A-Za-z_]/.test(bareTemplate); + const kind = metadata.databaseKind ?? 'sqlite'; + let rendered = redactedSQL; + let omissionReason: SQLExecutionMetadata['omissionReason'] = unsafeSQL + ? 'untrusted-literal-sql' : !policiesValid ? 'policy-count-mismatch' : undefined; + if (!unsafeSQL && policiesValid) { + try { + rendered = renderSQL(metadata.parameterizedSQL, safeValues, kind, index => + sqlLiteral(safeValues[index], kind) + (masked[index] ? ' /* masked */' : '')); + rendered = (allow + ? (masked.some(Boolean) ? '-- TeaQL DEBUG PLAINTEXT; EXPLICIT OPT-IN; PARTIALLY MASKED; NOT REPLAYABLE\n' : debugLabel) + : '-- TeaQL MASKED; NOT REPLAYABLE\n') + rendered; + } catch { + // Do not include driver exceptions or source SQL in this diagnostic failure. + rendered = redactedSQL; + omissionReason = 'unsupported-or-mismatched-bindings'; + } + } + const projected = Object.freeze({ + ...metadata, + ...(metadata.statements ? { statements: Object.freeze(metadata.statements.map(statement => + projectWithPolicy(statement, allow, inheritSQLLogBindings(metadata, inherited), intentValues))) } : {}), + parameterizedSQL: unsafeSQL ? redactedSQL : metadata.sqlOrigin === 'generated' + ? metadata.parameterizedSQL : scrubLogText(metadata.parameterizedSQL, secrets)!, + parameters: Object.freeze(safeValues), + parameterLogPolicies: Object.freeze(policies), + maskedParameters: Object.freeze(masked), + logMode: allow ? 'debug-plaintext' as const : 'masked' as const, + omissionReason, + debugSQL: rendered, + comment: intentText(metadata.comment), + purpose: intentText(metadata.purpose), + auditReason: intentText(metadata.auditReason), + ...(metadata.traceChain ? { traceChain: Object.freeze(metadata.traceChain.map(node => + Object.freeze(Object.fromEntries(Object.entries(node).map(([key, value]) => + [key, key !== 'entityId' && typeof value === 'string' ? intentText(value) : value]))))) as SQLExecutionMetadata['traceChain'] } : {}), + // Counts are operational metadata, not a copy of a masked numeric binding. + resultSummary: metadata.resultCount !== undefined ? `${metadata.resultCount} rows returned` + : metadata.affectedRows !== undefined ? `${metadata.affectedRows} rows affected` + : scrubLogText(metadata.resultSummary, secrets)!, + tracePath: Object.freeze(metadata.tracePath.map(frame => Object.freeze( + Object.fromEntries(Object.entries(frame).map(([key,value]) => + [key, key !== 'entityId' && typeof value === 'string' ? intentText(value) : value])), + ))) as SQLExecutionMetadata['tracePath'], + ...(metadata.traceChain ? { traceChain: Object.freeze(metadata.traceChain.map(node => + Object.freeze(Object.fromEntries(Object.entries(node).map(([key, value]) => + [key, key !== 'entityId' && typeof value === 'string' ? intentText(value) : value]))))) as SQLExecutionMetadata['traceChain'] } : {}), + // Typed identity is structural (as in the audit event's id), not prose. + ...(metadata.mutationLineage ? { mutationLineage: Object.freeze(metadata.mutationLineage.map(node => + Object.freeze(Object.fromEntries(Object.entries(node).map(([key, value]) => + [key, key !== 'entityId' && typeof value === 'string' ? intentText(value) : value]))))) as SQLExecutionMetadata['mutationLineage'] } : {}), + }); + return projected; +} diff --git a/source/teaql-ts/src/core/mutation-policy.ts b/source/teaql-ts/src/core/mutation-policy.ts new file mode 100644 index 0000000000000000000000000000000000000000..d7eb41e0ae9e23609a9a9bb24e74ea72e7c0513b --- /dev/null +++ b/source/teaql-ts/src/core/mutation-policy.ts @@ -0,0 +1,467 @@ +/** Governed application policy for complete mutation graphs. */ +import { MutationIntent } from './request-intent'; + +export const MISSING_MUTATION_POLICY = 'MUTATION-POLICY-001'; +export const MISSING_MUTATION_POLICY_APPROVAL = 'MUTATION-POLICY-002'; + +export type MutationOperationKind = 'create' | 'update' | 'delete' | 'recover'; + +export type MutationPolicyIdentity = Readonly<{ + policyId: string; + version: string; + fingerprint: string; +}>; + +export type MutationOperation = Readonly<{ + kind: MutationOperationKind; + entity: string; + entityId?: unknown; + originalVersion?: number; + changedValues: Readonly>; +}>; + +export type MutationPlan = Readonly<{ + executionId: string; + requestKey: string; + rootEntityType: string; + auditReason: string; + operations: readonly MutationOperation[]; +}>; + +export type MutationDecision = Readonly<{ + verdict: 'allow' | 'deny'; + code?: string; + message?: string; + fieldPaths?: readonly string[]; +}>; + +export interface MutationPolicy { + readonly identity: MutationPolicyIdentity; + review(context: unknown, plan: MutationPlan): MutationDecision; +} + +export interface MutationPolicyRegistry { + resolve(requestKey: string): MutationPolicy | undefined; +} + +export type MutationPolicyApproval = Readonly<{ + policy: MutationPolicyIdentity; + approvedBy: string; + approvedAt: Date; +}>; + +export interface MutationPolicyApprovalProvider { + findApproval(identity: MutationPolicyIdentity): MutationPolicyApproval | undefined; +} + +export type MutationPolicySource = 'generated_default' | 'customer'; +export type MutationPolicyApprovalStatus = 'not_applicable' | 'missing' | 'approved'; + +export type MutationOperationSummary = Readonly<{ + kind: MutationOperationKind; + entity: string; + entityId?: unknown; + changedFields: readonly string[]; +}>; + +export type MutationGovernanceSnapshot = Readonly<{ + executionId: string; + requestKey: string; + source: MutationPolicySource; + policy?: MutationPolicyIdentity; + approvalStatus: MutationPolicyApprovalStatus; + warningCodes: readonly string[]; + operations: readonly MutationOperationSummary[]; +}>; + +export type MutationGovernanceWarning = Readonly<{ + snapshot: MutationGovernanceSnapshot; + warningCode: string; + firstOccurrence: boolean; +}>; + +export interface MutationGovernanceSink { + onWarning(context: unknown, warning: MutationGovernanceWarning): void; +} + +export class MutationPolicyError extends Error { + constructor(message: string) { + super(message); + this.name = 'MutationPolicyError'; + } +} + +export class DelegatingMutationPolicyRegistry implements MutationPolicyRegistry { + constructor(private readonly resolver: (requestKey: string) => MutationPolicy | undefined) {} + resolve(requestKey: string): MutationPolicy | undefined { return this.resolver(requestKey); } +} + +export class DelegatingMutationPolicyApprovalProvider +implements MutationPolicyApprovalProvider { + constructor(private readonly finder: + (identity: MutationPolicyIdentity) => MutationPolicyApproval | undefined) {} + findApproval(identity: MutationPolicyIdentity): MutationPolicyApproval | undefined { + return this.finder(identity); + } +} + +export class DelegatingMutationGovernanceSink implements MutationGovernanceSink { + constructor(private readonly consumer: + (context: unknown, warning: MutationGovernanceWarning) => void) {} + onWarning(context: unknown, warning: MutationGovernanceWarning): void { + this.consumer(context, warning); + } +} + +class ConsoleMutationGovernanceSink implements MutationGovernanceSink { + onWarning(_context: unknown, warning: MutationGovernanceWarning): void { + if (!warning.firstOccurrence || typeof console === 'undefined') return; + console.warn( + `TeaQL mutation policy warning code=${warning.warningCode} ` + + `requestKey=${warning.snapshot.requestKey} source=${warning.snapshot.source} ` + + `approval=${warning.snapshot.approvalStatus}`, + ); + } +} + +type MutableMutationPolicyProfile = { + registry?: MutationPolicyRegistry; + approvalProvider?: MutationPolicyApprovalProvider; + warningSink: MutationGovernanceSink; +}; + +type MutationExecution = Readonly<{ + snapshot: MutationGovernanceSnapshot; +}>; + +let executionSequence = 0; + +/** @internal Runtime state owned by one UserContext. */ +export class MutationPolicyRuntimeState { + private readonly profile: MutableMutationPolicyProfile = { + warningSink: new ConsoleMutationGovernanceSink(), + }; + private readonly emittedWarnings = new Set(); + private graphActive = false; + private graphReviewed = false; + private preflight: MutationOperation[] = []; + private preflightKeys: string[] = []; + private rootEntity?: string; + private auditReason?: string; + private remaining = new Map(); + private graphSnapshot?: MutationGovernanceSnapshot; + + setRegistry(registry: MutationPolicyRegistry): void { this.profile.registry = registry; } + setApprovalProvider(provider: MutationPolicyApprovalProvider): void { + this.profile.approvalProvider = provider; + } + setWarningSink(sink: MutationGovernanceSink): void { this.profile.warningSink = sink; } + + beginGraph(): void { + if (this.graphActive) throw new MutationPolicyError('mutation policy graph is already active'); + this.graphActive = true; + this.graphReviewed = false; + this.preflight = []; + this.preflightKeys = []; + this.rootEntity = undefined; + this.auditReason = undefined; + this.remaining.clear(); + this.graphSnapshot = undefined; + } + + endGraph(): void { + this.graphActive = false; + this.graphReviewed = false; + this.preflight = []; + this.preflightKeys = []; + this.rootEntity = undefined; + this.auditReason = undefined; + this.remaining.clear(); + this.graphSnapshot = undefined; + } + + recordPreflight(mutation: unknown): void { + if (!this.graphActive) return; + if (this.graphReviewed) { + throw new MutationPolicyError('mutation preflight cannot change after policy review'); + } + const operation = operationFromMutation(mutation); + this.rootEntity ??= operation.entity; + this.auditReason ??= mutationComment(mutation); + this.preflight.push(operation); + this.preflightKeys.push(operationMatchKey(mutation, operation)); + } + + enterMutation(context: unknown, mutation: unknown): MutationExecution { + const operation = operationFromMutation(mutation); + if (!this.graphActive) { + return { snapshot: this.review(context, this.plan(operation.entity, + mutationComment(mutation), [operation])) }; + } + + if (!this.graphReviewed) { + if (this.profile.registry && this.preflight.length === 0) { + throw new MutationPolicyError( + 'customer mutation policy requires complete graph preflight before provider mutation', + ); + } + // Legacy/manual graph callers without a customer policy remain usable. + // Generated graphs provide the complete preflight and therefore share + // one reviewed plan; the generated-default fallback reviews each legacy + // operation independently and emits the stable missing-policy warning. + if (!this.profile.registry && this.preflight.length === 0) { + return { snapshot: this.review(context, this.plan( + operation.entity, mutationComment(mutation), [operation], + )) }; + } + const operations = this.preflight.length ? this.preflight : [operation]; + this.graphSnapshot = this.review(context, this.plan( + this.rootEntity ?? operations[0].entity, + this.auditReason ?? mutationComment(mutation), + operations, + )); + this.remaining.clear(); + const plannedKeys = this.preflight.length + ? this.preflightKeys : operations.map(operationSignature); + for (const signature of plannedKeys) { + this.remaining.set(signature, (this.remaining.get(signature) ?? 0) + 1); + } + this.graphReviewed = true; + } + this.consume(operationMatchKey(mutation, operation)); + return { snapshot: this.graphSnapshot! }; + } + + ensureGraphComplete(): void { + if (this.graphReviewed && this.remaining.size) { + throw new MutationPolicyError( + 'reviewed mutation plan contains operations that were not executed', + ); + } + } + + review(context: unknown, input: MutationPlan): MutationGovernanceSnapshot { + validatePlan(input); + const plan = freezePlan(input); + const policy = this.profile.registry?.resolve(plan.requestKey); + let source: MutationPolicySource; + let identity: MutationPolicyIdentity | undefined; + let approvalStatus: MutationPolicyApprovalStatus; + let warningCodes: readonly string[]; + + if (!policy) { + source = 'generated_default'; + approvalStatus = 'not_applicable'; + warningCodes = [MISSING_MUTATION_POLICY]; + } else { + identity = freezeIdentity(policy.identity); + const decision = policy.review(context, plan); + if (!decision || (decision.verdict !== 'allow' && decision.verdict !== 'deny')) { + throw new MutationPolicyError('customer mutation policy returned an invalid decision'); + } + if (decision.verdict === 'deny') { + throw new MutationPolicyError( + `[MUTATION POLICY DENIED] ${decision.code || 'MUTATION-POLICY-DENIED'}: ` + + `${decision.message || 'mutation rejected'}`, + ); + } + source = 'customer'; + const approval = this.profile.approvalProvider?.findApproval(identity); + approvalStatus = validApproval(approval, identity) ? 'approved' : 'missing'; + warningCodes = approvalStatus === 'approved' + ? [] : [MISSING_MUTATION_POLICY_APPROVAL]; + } + + const snapshot: MutationGovernanceSnapshot = Object.freeze({ + executionId: plan.executionId, + requestKey: plan.requestKey, + source, + policy: identity, + approvalStatus, + warningCodes: Object.freeze([...warningCodes]), + operations: Object.freeze(plan.operations.map(operation => Object.freeze({ + kind: operation.kind, + entity: operation.entity, + entityId: cloneAndFreeze(operation.entityId), + changedFields: Object.freeze(Object.keys(operation.changedValues).sort()), + }))), + }); + for (const code of warningCodes) this.emitWarning(context, snapshot, code); + return snapshot; + } + + private plan(root: string, reason: string | undefined, + operations: readonly MutationOperation[]): MutationPlan { + executionSequence += 1; + return freezePlan({ + executionId: `teaql-mutation-${executionSequence}`, + requestKey: `${root}.saveGraph`, + rootEntityType: root, + auditReason: new MutationIntent(reason).comment, + operations, + }); + } + + private consume(signature: string): void { + const count = this.remaining.get(signature) ?? 0; + if (count < 1) { + throw new MutationPolicyError( + 'provider mutation is not present in the reviewed graph plan', + ); + } + if (count === 1) this.remaining.delete(signature); + else this.remaining.set(signature, count - 1); + } + + private emitWarning(context: unknown, snapshot: MutationGovernanceSnapshot, + warningCode: string): void { + const policy = snapshot.policy + ? `${snapshot.policy.policyId}:${snapshot.policy.version}:${snapshot.policy.fingerprint}` + : 'none'; + const key = `${snapshot.requestKey}|${policy}|${warningCode}`; + const firstOccurrence = !this.emittedWarnings.has(key); + this.emittedWarnings.add(key); + try { + this.profile.warningSink.onWarning(context, Object.freeze({ + snapshot, warningCode, firstOccurrence, + })); + } catch { + // Warning delivery must not change persistence semantics. + } + } +} + +function operationFromMutation(value: any): MutationOperation { + const entity = String(value?.entity ?? '').trim(); + const action = String(value?.action ?? '').toLowerCase(); + const kinds: Record = { + create: 'create', update: 'update', delete: 'delete', recover: 'recover', + }; + if (!entity || !kinds[action]) { + throw new MutationPolicyError('mutation must contain a supported entity operation'); + } + const payload = value?.payload && typeof value.payload === 'object' + ? value.payload as Record : {}; + return Object.freeze({ + kind: kinds[action], + entity, + entityId: cloneAndFreeze(value?.id ?? payload.id), + originalVersion: value?.version ?? value?.expectedVersion, + changedValues: cloneRecord(payload), + }); +} + +function mutationComment(value: any): string { + return new MutationIntent(value?.comment).comment; +} + +function validatePlan(plan: MutationPlan): void { + new MutationIntent(plan?.auditReason); + if (!plan.executionId?.trim()) throw new MutationPolicyError('execution id is required'); + if (!plan.requestKey?.trim()) throw new MutationPolicyError('request key is required'); + if (!plan.rootEntityType?.trim()) throw new MutationPolicyError('root entity type is required'); + if (!plan.operations.length) throw new MutationPolicyError('mutation plan is empty'); +} + +function freezeIdentity(identity: MutationPolicyIdentity): MutationPolicyIdentity { + if (!identity || !identity.policyId?.trim() || !identity.version?.trim() + || !identity.fingerprint?.trim()) { + throw new MutationPolicyError('customer mutation policy identity is invalid'); + } + return Object.freeze({ + policyId: identity.policyId.trim(), version: identity.version.trim(), + fingerprint: identity.fingerprint.trim(), + }); +} + +function validApproval(approval: MutationPolicyApproval | undefined, + identity: MutationPolicyIdentity): boolean { + return !!approval && sameIdentity(approval.policy, identity) + && !!approval.approvedBy?.trim() && approval.approvedAt instanceof Date + && Number.isFinite(approval.approvedAt.getTime()) && approval.approvedAt.getTime() !== 0; +} + +function sameIdentity(left: MutationPolicyIdentity, right: MutationPolicyIdentity): boolean { + return left.policyId === right.policyId && left.version === right.version + && left.fingerprint === right.fingerprint; +} + +function freezePlan(plan: MutationPlan): MutationPlan { + return Object.freeze({ + executionId: plan.executionId, + requestKey: plan.requestKey, + rootEntityType: plan.rootEntityType, + auditReason: plan.auditReason, + operations: Object.freeze(plan.operations.map(operation => Object.freeze({ + kind: operation.kind, + entity: operation.entity, + entityId: cloneAndFreeze(operation.entityId), + originalVersion: operation.originalVersion, + changedValues: cloneRecord(operation.changedValues), + }))), + }); +} + +function cloneAndFreeze(value: unknown, ancestors = new WeakSet()): unknown { + if (value === null || value === undefined || typeof value === 'string' + || typeof value === 'number' || typeof value === 'boolean' + || typeof value === 'bigint') return value; + if (value instanceof Date) return value.toISOString(); + if (typeof value === 'object') { + if (ancestors.has(value)) { + throw new MutationPolicyError('mutation policy values must not contain cycles'); + } + ancestors.add(value); + try { + if (Array.isArray(value)) { + return Object.freeze(value.map(item => cloneAndFreeze(item, ancestors))); + } + const record = value as Record; + if ('id' in record && Object.keys(record).some(key => key !== 'id')) { + return cloneAndFreeze(record.id, ancestors); + } + return Object.freeze(Object.fromEntries( + Object.entries(record).map(([key, item]) => [key, cloneAndFreeze(item, ancestors)]), + )); + } finally { + ancestors.delete(value); + } + } + return String(value); +} + +function cloneRecord(value: Readonly>): Readonly> { + return Object.freeze(Object.fromEntries( + Object.entries(value).map(([key, item]) => [key, cloneAndFreeze(item)]), + )); +} + +function operationSignature(operation: MutationOperation): string { + return canonicalJSON({ + kind: operation.kind, + entity: operation.entity, + entityId: operation.entityId, + originalVersion: operation.originalVersion, + changedValues: operation.changedValues, + }); +} + +function operationMatchKey(mutation: any, operation: MutationOperation): string { + const ledgerKey = mutation?.ledgerKey; + if (ledgerKey && typeof ledgerKey === 'object' + && String(ledgerKey.entity ?? '').trim() + && ledgerKey.id !== undefined && ledgerKey.id !== null) { + return `ledger:${String(ledgerKey.entity).trim()}:${canonicalJSON(ledgerKey.id)}`; + } + return `operation:${operationSignature(operation)}`; +} + +function canonicalJSON(value: unknown): string { + if (typeof value === 'bigint') return JSON.stringify(`${value.toString()}n`); + if (value === undefined) return '""'; + if (value === null || typeof value !== 'object') return JSON.stringify(value); + if (Array.isArray(value)) return `[${value.map(canonicalJSON).join(',')}]`; + return `{${Object.entries(value as Record) + .sort(([left], [right]) => left.localeCompare(right)) + .map(([key, item]) => `${JSON.stringify(key)}:${canonicalJSON(item)}`).join(',')}}`; +} diff --git a/source/teaql-ts/src/core/object-location.ts b/source/teaql-ts/src/core/object-location.ts new file mode 100644 index 0000000000000000000000000000000000000000..1212deb49099f71f07fd243568870022e82e30f3 --- /dev/null +++ b/source/teaql-ts/src/core/object-location.ts @@ -0,0 +1,66 @@ +export type ObjectLocationSegment = + | { readonly kind: 'property'; readonly name: string } + | { readonly kind: 'index'; readonly index: number }; + +export type JsonFieldNamingProfile = 'camelCase' | 'snake_case' | 'PascalCase'; + +function lowerCamel(name: string): string { + const parts = name.split('_'); + return parts[0] + parts.slice(1).map(part => part ? part[0].toUpperCase() + part.slice(1) : '').join(''); +} + +export function renderJsonFieldName(name: string, profile: JsonFieldNamingProfile): string { + if (profile === 'snake_case') return name; + const camel = lowerCamel(name); + if (profile === 'camelCase' || !camel) return camel; + return camel[0].toUpperCase() + camel.slice(1); +} + +function escapeJsonPointer(value: string): string { + return value.replace(/~/g, '~0').replace(/\//g, '~1'); +} + +/** A casing-neutral location expressed with canonical KSML property names. */ +export class ObjectLocation { + private constructor(public readonly segments: readonly ObjectLocationSegment[]) {} + + static root(): ObjectLocation { return new ObjectLocation([]); } + static property(name: string): ObjectLocation { return ObjectLocation.root().property(name); } + + property(name: string): ObjectLocation { + return new ObjectLocation([...this.segments, { kind: 'property', name }]); + } + + index(index: number): ObjectLocation { + return new ObjectLocation([...this.segments, { kind: 'index', index }]); + } + + prefixedBy(prefix: ObjectLocation): ObjectLocation { + return new ObjectLocation([...prefix.segments, ...this.segments]); + } + + modelPath(): string { + return this.render(name => name); + } + + nativePath(): string { + return this.render(lowerCamel); + } + + instancePath(profile: JsonFieldNamingProfile = 'camelCase'): string { + return this.segments.map(segment => segment.kind === 'index' + ? String(segment.index) + : escapeJsonPointer(renderJsonFieldName(segment.name, profile))).map(value => `/${value}`).join(''); + } + + toString(): string { return this.nativePath(); } + + private render(propertyName: (name: string) => string): string { + let result = ''; + for (const segment of this.segments) { + if (segment.kind === 'index') result += `[${segment.index}]`; + else result += `${result ? '.' : ''}${propertyName(segment.name)}`; + } + return result; + } +} diff --git a/source/teaql-ts/src/core/query-snapshot.ts b/source/teaql-ts/src/core/query-snapshot.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a123282d5360b15b534b14bcf5d57be522ab589 --- /dev/null +++ b/source/teaql-ts/src/core/query-snapshot.ts @@ -0,0 +1,36 @@ +// Internal execution plumbing. Never export provenance from the public facade +// or store it as a JSON/symbol property on a builder, entity or Context. +const origins = new WeakMap(); +const requestOwners = new WeakMap(); + +/** Internal capability: never a field on query JSON, entities or Context. */ +export function queryExecutionOwner(query: object): object | undefined { return requestOwners.get(query); } +export function retainQueryExecutionOwner(query: object, owner: object): void { requestOwners.set(query, owner); } + +export function queryDiagnosticOrigin(query: object): object | undefined { return origins.get(query); } + +export function retainQueryDiagnosticOrigin(source: object, target: object): void { + origins.set(target, origins.get(source) ?? snapshotQuery(source)); +} + +/** Capture request-owned AST values while retaining opaque local capabilities. + * Date/binary values keep their native types. Non-enumerable runtime policy and + * Context handles are intentionally not traversed or serialized. */ +export function snapshotQuery(value: T, seen = new Map()): T { + if (!value || typeof value !== 'object') return value; + if (seen.has(value)) return seen.get(value) as T; + if (value instanceof Date) return new Date(value.getTime()) as T; + if (value instanceof Uint8Array) return new Uint8Array(value) as T; + const copy = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value)); + seen.set(value, copy); + for (const key of Reflect.ownKeys(value)) { + const descriptor = Object.getOwnPropertyDescriptor(value, key)!; + if ('value' in descriptor && descriptor.enumerable) descriptor.value = snapshotQuery(descriptor.value, seen); + Object.defineProperty(copy, key, descriptor); + } + const origin = origins.get(value); + if (origin) origins.set(copy, origin); + const owner = requestOwners.get(value); + if (owner) requestOwners.set(copy, owner); + return copy; +} diff --git a/source/teaql-ts/src/core/request-intent.ts b/source/teaql-ts/src/core/request-intent.ts new file mode 100644 index 0000000000000000000000000000000000000000..533f8b1ad91cc7802cfe47608e51a1759a40af38 --- /dev/null +++ b/source/teaql-ts/src/core/request-intent.ts @@ -0,0 +1,343 @@ +import type { MutationQuery, SelectQuery } from './ast'; +import { cloneTraceNodes, queryTraceSource, TraceNode, MutationTraceScope, mutationScopeForEntity } from './trace-chain'; +import type { EntityKey, EntityRoot } from './entity-root'; +import { inheritSQLLogBindings, logValueStrings, privateLogValueStrings, scrubLogText } from './log-privacy'; +import type { SQLLogBindingSource } from './log-privacy'; +import { snapshotQuery, queryExecutionOwner, retainQueryExecutionOwner } from './query-snapshot'; +import { LoadedScalarSnapshot } from './loaded-scalar-snapshot'; + +const mutationSnapshots = new WeakMap(); + +// Only runtime-created snapshots carry provenance. No property supplied by a +// JSON/builder caller can forge it, and no mutable trace stack lives on Context. +const querySources = new WeakMap(); +const graphRequests = new WeakMap(); +const scopeOwners = new WeakMap(); + +export type QueryOperation = Readonly<{ + kind: 'named-count' | 'facet' | 'relation-count' | 'relation-select' | 'aggregate' | 'pagination'; + /** Exact generator-supplied native method; absent for a low-level runtime operation. */ + method?: string; + alias?: string; + relation?: string; +}>; + +function operationSnapshot(operation: QueryOperation): QueryOperation { + if (!['named-count', 'facet', 'relation-count', 'relation-select', 'aggregate', 'pagination'].includes(operation.kind) + || (operation.method !== undefined && !/^[A-Za-z_][A-Za-z0-9_]*$/.test(operation.method)) + || (operation.alias !== undefined && typeof operation.alias !== 'string') + || (operation.relation !== undefined && typeof operation.relation !== 'string')) { + throw new Error('QUERY_OPERATION_INVALID: invalid generated operation descriptor'); + } + return Object.freeze({ kind: operation.kind, method: operation.method, + alias: operation.alias, relation: operation.relation }); +} + +/** One native literal renderer for all count/facet aliases. Never parse SQL. */ +export function queryOperationComment(operation: QueryOperation): string { + const captured = operationSnapshot(operation); + const literal = (value: string) => "'" + value.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r') + .replace(/\t/g, '\\t').replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029') + "'"; + if (!captured.method) return 'framework: ' + captured.kind + + (captured.relation ? ' ' + captured.relation : '') + + (captured.alias !== undefined ? ' ' + literal(captured.alias) : ''); + return captured.method + '(' + (captured.alias !== undefined ? literal(captured.alias) + : captured.kind === 'relation-select' ? '...' : '') + ')'; +} + +const requestBindingToken = Symbol('runtime request binding'); +type QueryBinding = { + [requestBindingToken]: true; + parent?: QueryRequest; + comment: string; + name: string; + operation?: QueryOperation; + source: readonly TraceNode[]; + invocation?: object; +}; + +export type RequestKind = 'query' | 'mutation'; + +/** Stable, value-free request-boundary diagnostics. */ +export class RequestIntentError extends Error { + constructor( + public readonly code: 'REQUEST_COMMENT_REQUIRED' | 'QUERY_PURPOSE_REQUIRED', + public readonly field: 'comment' | 'purpose', + public readonly requestKind: RequestKind, + ) { + super(`${code}: ${requestKind} request requires a non-blank ${field}; supply it at the request entry point`); + this.name = 'RequestIntentError'; + } +} + +// Match Rust str::trim (Unicode White_Space), not JavaScript trim: NEL is +// whitespace, while BOM is not. Validate but never trim the supplied text. +function requireText(value: unknown, field: 'comment' | 'purpose', kind: RequestKind): string { + if (typeof value !== 'string' || /^\p{White_Space}*$/u.test(value)) { + throw new RequestIntentError( + field === 'comment' ? 'REQUEST_COMMENT_REQUIRED' : 'QUERY_PURPOSE_REQUIRED', field, kind, + ); + } + return value; +} + +export class QueryIntent { + readonly #comment: string; + readonly #purpose: string; + + constructor(comment: unknown, purpose: unknown) { + this.#comment = requireText(comment, 'comment', 'query'); + this.#purpose = requireText(purpose, 'purpose', 'query'); + Object.freeze(this); + } + + get comment(): string { return this.#comment; } + get purpose(): string { return this.#purpose; } +} + +export class MutationIntent { + readonly #comment: string; + + constructor(comment: unknown) { + this.#comment = requireText(comment, 'comment', 'mutation'); + Object.freeze(this); + } + + get comment(): string { return this.#comment; } + get auditReason(): string { return this.#comment; } + readbackIntent(): QueryIntent { + return new QueryIntent(this.#comment, 'verify persisted mutation result'); + } +} + +/** + * Request intent is owned separately from the mutable query builder. A snapshot + * retains local, non-enumerable pagination capabilities without serializing them. + */ +export class QueryRequest { + readonly #intent: QueryIntent; + readonly #query: T; + readonly #parent?: QueryRequest; + readonly #comment: string; + readonly #name: string; + readonly #operation?: QueryOperation; + readonly #invocation: object; + + constructor(query: T, intent?: QueryIntent, binding?: QueryBinding) { + const source = query as any; + const previous = queryExecutionOwner(query); + const previousOwner = previous instanceof QueryRequest ? previous : undefined; + this.#intent = intent === undefined + ? previousOwner?.intent + ?? new QueryIntent(source?._comment ?? source?.commentText, source?._purpose ?? source?.purposeText) + : new QueryIntent(intent?.comment, intent?.purpose); + if (binding && binding[requestBindingToken] !== true) + throw new Error('QUERY_REQUEST_OWNERSHIP_INVALID: request binding is runtime-owned'); + const owner = previousOwner + && previousOwner.intent.comment === this.#intent.comment + && previousOwner.purpose === this.#intent.purpose ? previousOwner : undefined; + this.#invocation = binding?.invocation ?? (binding?.parent ? binding.parent.#invocation : undefined) + ?? (owner ? owner.#invocation : undefined) ?? Object.freeze({}); + this.#parent = binding ? binding.parent : owner?.parentRequest; + this.#comment = requireText(binding?.comment ?? owner?.comment ?? this.#intent.comment, 'comment', 'query'); + this.#name = binding?.name ?? owner?.requestName ?? String(source.entity ?? 'query'); + this.#operation = binding?.operation ?? owner?.operation; + this.#query = snapshotQuery(query); + const captured = this.#query as any; + // Every request owns its local comment. Purpose is resolved from the root + // request through parent ownership and is copied only onto the private SQL + // execution snapshot for boundary validation. + for (const [field, value] of [ + ['commentText', this.comment], ['purposeText', this.purpose], + ['_comment', this.comment], ['_purpose', this.purpose], + ] as const) { + Object.defineProperty(captured, field, { value, enumerable: !field.startsWith('_'), + configurable: true, writable: false }); + } + querySources.set(captured, cloneTraceNodes(binding?.source ?? owner?.traceSource ?? querySources.get(query) + ?? queryTraceSource(String(source.entity), this.intent.comment, this.purpose))); + retainQueryExecutionOwner(captured, this); + Object.freeze(this); + } + + get intent(): QueryIntent { return this.#intent; } + get query(): T { return this.#query; } + get comment(): string { return this.#comment; } + get purpose(): string { return this.#intent.purpose; } + get traceSource(): readonly TraceNode[] { return querySources.get(this.#query)!; } + get parentRequest(): QueryRequest | undefined { return this.#parent; } + get rootRequest(): QueryRequest { + let root: QueryRequest = this; + while (root.parentRequest) root = root.parentRequest; + return root; + } + get requestName(): string { return this.#name; } + get operation(): QueryOperation | undefined { return this.#operation; } + get traceChain(): readonly TraceNode[] { + const comments: TraceNode[] = []; + for (let node: QueryRequest | undefined = this; node; node = node.parentRequest) + comments.push({ kind: 'comment', name: node.requestName, detail: node.comment }); + return cloneTraceNodes([{ kind: 'purpose', name: this.rootRequest.requestName, detail: this.purpose }, + ...comments.reverse()]); + } + + /** Runtime derivation preserves this invocation's source across builder clones. */ + withQuery(query: Q): QueryRequest { + const previous = queryExecutionOwner(query); + if (previous instanceof QueryRequest && previous.#invocation !== this.#invocation) { + throw new Error('QUERY_SCOPE_OWNER_MISMATCH: replacement belongs to another query invocation'); + } + return new QueryRequest(query, this.intent, { [requestBindingToken]: true, + parent: this.parentRequest, comment: this.comment, name: this.requestName, + operation: this.operation, source: this.traceSource, invocation: this.#invocation }); + } + + /** A real operation child need not execute SQL itself; descendants retain it. */ + deriveOperation(query: Q, operation: QueryOperation): QueryRequest { + const captured = operationSnapshot(operation); + return new QueryRequest(query, this.intent, { [requestBindingToken]: true, + parent: this, comment: queryOperationComment(captured), name: String((query as any).entity ?? this.requestName), + operation: captured, source: this.traceSource }); + } + + /** Local description for work created by the framework, never a root authorization. */ + deriveHelper(query: Q, comment: string): QueryRequest { + return new QueryRequest(query, this.intent, { [requestBindingToken]: true, + parent: this, comment: requireText(comment, 'comment', 'query'), + name: String((query as any).entity ?? this.requestName), source: this.traceSource }); + } + + /** Preserve the Q-operation parent and the actual nested request's own comment. */ + derive(query: Q, relation: string, operation?: QueryOperation): QueryRequest { + if (operation) return this.deriveOperation(this.query, operation).deriveChild(query, relation); + const owner = `${String((this.query as any).entity)}.${relation}`; + return this.deriveChild(query, relation, undefined, owner); + } + + /** Aggregates execute their operation; an anonymous template is not a value load. */ + deriveAggregate(query: Q, relation: string, operation: QueryOperation): QueryRequest { + const facet = this.parentRequest?.operation?.kind === 'facet' ? this.parentRequest : undefined; + const branch = facet + ? facet.deriveHelper(query, 'aggregate ' + facet.operation!.relation) + : this.deriveOperation(query, operation); + const physical = [...this.traceSource, { kind: 'relation' as const, name: relation, + detail: `${String((this.query as any).entity)}.${relation}` }]; + const scoped = new QueryRequest(query, this.intent, { [requestBindingToken]: true, + parent: branch.parentRequest, comment: branch.comment, name: branch.requestName, + operation: branch.operation, source: physical }); + const comment = (query as any)._comment ?? (query as any).commentText; + return comment === undefined ? scoped : scoped.deriveChild(query); + } + + /** Bind a framework helper or value query below an existing operation parent. */ + deriveChild( + query: Q, + relation?: string, + defaultComment?: string, + requestName?: string, + ): QueryRequest { + const source = query as any; + const comment = source._comment ?? source.commentText; + return new QueryRequest(query, this.intent, { [requestBindingToken]: true, + parent: this, comment: comment === undefined + ? (defaultComment ?? `load ${String(source.entity)}`) + : requireText(comment, 'comment', 'query'), + name: requestName ?? String(source.entity), source: relation === undefined ? this.traceSource : [...this.traceSource, { + kind: 'relation', name: relation, detail: `${String((this.query as any).entity)}.${relation}`, + }] }); + } +} + +/** A batch also needs this root envelope; child comments are not a fallback. */ +export class MutationRequest { + readonly #intent: MutationIntent; + readonly #mutation: T; + + constructor(mutation: T, intent?: MutationIntent) { + this.#intent = new MutationIntent(intent === undefined ? (mutation as any)?.comment : intent?.comment); + this.#mutation = { ...mutation }; + Object.defineProperty(this.#mutation, 'comment', { + value: this.#intent.comment, enumerable: true, writable: false, configurable: false, + }); + Object.freeze(this); + } + + get intent(): MutationIntent { return this.#intent; } + get mutation(): T { return this.#mutation; } + get comment(): string { return this.#intent.comment; } + + /** @internal Generated hydration/commit provenance, never a wire field. */ + withLoadedSnapshot(snapshot: LoadedScalarSnapshot): this { + mutationSnapshots.set(this, new LoadedScalarSnapshot(snapshot.values())); + return this; + } + /** @internal Does not become part of the write payload or policy input. */ + loadedValues(): Readonly> { return mutationSnapshots.get(this)?.values() ?? {}; } + + /** Runtime-owned execution capability; raw mutation fields cannot forge it. */ + get graphSession(): GraphMutationSession | undefined { return graphRequests.get(this)?.session; } + + scopeFor(key: EntityKey): MutationTraceScope { + const graph = graphRequests.get(this); + const scope = mutationScopeForEntity(graph?.parent, key.entity, key.id, this.comment, graph?.localComment); + if (graph) scopeOwners.set(scope, graph.session); + return scope; + } + + traceFor(key: EntityKey): readonly TraceNode[] { + const mutation = this.#mutation as T & { ledgerRoot?: EntityRoot; ledgerKey?: EntityKey }; + const specific = mutation.ledgerRoot?.traceChain(mutation.ledgerKey ?? key); + return specific?.length ? cloneTraceNodes(specific) : this.scopeFor(key).recover(); + } + + /** Safe event projection; internal policy intent is never mutated. */ + auditProjection(key: EntityKey, payload: unknown, bindings?: SQLLogBindingSource): Readonly<{ + reason: string; mutationLineage: readonly TraceNode[]; + }> { + const secrets = [...logValueStrings(payload), ...logValueStrings((this.#mutation as any).id), + ...(bindings ? privateLogValueStrings(bindings) : logValueStrings(this.loadedValues())), + ...privateLogValueStrings(this.graphSession?.logBindings)]; + return Object.freeze({ reason: scrubLogText(this.comment, secrets)!, + mutationLineage: cloneTraceNodes(this.traceFor(key).map(node => ({ ...node, + detail: scrubLogText(node.detail, secrets) }))) }); + } +} + +/** One explicit graph invocation, never a Context-owned trace stack. */ +export class GraphMutationSession { + readonly #intent: MutationIntent; + #bindings?: SQLLogBindingSource; + + constructor(intent: MutationIntent) { + this.#intent = new MutationIntent(intent?.comment); + Object.freeze(this); + } + get intent(): MutationIntent { return this.#intent; } + + request(mutation: T, parent?: MutationTraceScope, + localComment?: string): MutationRequest { + if (parent && scopeOwners.get(parent) !== this) + throw new Error('GRAPH_TRACE_SCOPE_MISMATCH: parent scope belongs to another graph invocation'); + const request = new MutationRequest(mutation, this.#intent); + graphRequests.set(request, { session: this, parent, localComment }); + return request; + } + + /** @internal Preflight snapshots bind provenance for all siblings before SQL. */ + captureLogBindings(source: SQLLogBindingSource): void { + this.#bindings = inheritSQLLogBindings(source, this.#bindings); + } + /** @internal Never put this raw provenance on a wire or log record. */ + get logBindings(): SQLLogBindingSource | undefined { return this.#bindings; } +} + +/** Database committed; retrying this operation as a rolled-back write is unsafe. */ +export class GraphCommittedError extends Error { + readonly committed = true; + constructor(public readonly cause: unknown) { + super('GRAPH_ALREADY_COMMITTED: post-commit processing failed; do not retry as an uncommitted mutation'); + this.name = 'GraphCommittedError'; + } +} diff --git a/source/teaql-ts/src/core/runtime-module.ts b/source/teaql-ts/src/core/runtime-module.ts new file mode 100644 index 0000000000000000000000000000000000000000..fdd507c94af00e8e6381a39b192a878ef69e003e --- /dev/null +++ b/source/teaql-ts/src/core/runtime-module.ts @@ -0,0 +1,72 @@ +import type { EntitySchema } from '../sql/core'; +import type { EntityChecker } from './checker'; +import type { UserContext } from './context'; + +export type BootstrapEntity = Readonly<{ + entity: string; + id: string; + values?: Readonly>; +}>; + +export type RuntimeBootstrap = Readonly<{ + defaultDomainRoot?: BootstrapEntity; + constants?: readonly BootstrapEntity[]; + /** Generated typed Mutation program. Application workspaces cannot replace it. */ + ensure?: (context: UserContext) => Promise; +}>; + +export function mergeRuntimeBootstrap( + left: RuntimeBootstrap, + right: RuntimeBootstrap, +): RuntimeBootstrap { + const leftRoot = left.defaultDomainRoot; + const rightRoot = right.defaultDomainRoot; + if (leftRoot && rightRoot && + (leftRoot.entity !== rightRoot.entity || leftRoot.id !== rightRoot.id)) { + throw new Error('Cannot compose Runtime Modules with different Default Domain Roots'); + } + const constants = new Map(); + for (const value of [...(left.constants ?? []), ...(right.constants ?? [])]) { + constants.set(`${value.entity}:${value.id}`, value); + } + return { + defaultDomainRoot: rightRoot ?? leftRoot, + constants: [...constants.values()], + ensure: left.ensure && right.ensure + ? async context => { await left.ensure!(context); await right.ensure!(context); } + : right.ensure ?? left.ensure, + }; +} + +export interface RuntimeModuleTarget { + install(module: RuntimeModule): RuntimeModuleTarget; +} + +/** Passive, immutable metadata manifest. It never creates or alters database tables. */ +export class RuntimeModule { + readonly schemas: Readonly>; + readonly checkers: Readonly>; + readonly bootstrap: RuntimeBootstrap; + + constructor( + schemas: Record = {}, + checkers: Record = {}, + bootstrap: RuntimeBootstrap = {}, + ) { + this.schemas = Object.freeze({ ...schemas }); + this.checkers = Object.freeze({ ...checkers }); + this.bootstrap = Object.freeze({ + defaultDomainRoot: bootstrap.defaultDomainRoot, + constants: Object.freeze([...(bootstrap.constants ?? [])]), + ensure: bootstrap.ensure, + }); + } + + and(other: RuntimeModule): RuntimeModule { + return new RuntimeModule( + { ...this.schemas, ...other.schemas }, + { ...this.checkers, ...other.checkers }, + mergeRuntimeBootstrap(this.bootstrap, other.bootstrap), + ); + } +} diff --git a/source/teaql-ts/src/core/schema-capability.ts b/source/teaql-ts/src/core/schema-capability.ts new file mode 100644 index 0000000000000000000000000000000000000000..830b7e00de26d60dc0c1b874b296cc05045f243f --- /dev/null +++ b/source/teaql-ts/src/core/schema-capability.ts @@ -0,0 +1,8 @@ +import type { UserContext } from './context'; + +/** Package-internal capability. This module is intentionally absent from package exports. */ +export const contextSchemaCapability: unique symbol = Symbol('teaql.context.schema-capability'); + +export interface InternalContextSchemaExecutor { + [contextSchemaCapability](context: UserContext): Promise; +} diff --git a/source/teaql-ts/src/core/smart-list.ts b/source/teaql-ts/src/core/smart-list.ts new file mode 100644 index 0000000000000000000000000000000000000000..5784ddba3a3fd518cca2762a37c362853e83cd10 --- /dev/null +++ b/source/teaql-ts/src/core/smart-list.ts @@ -0,0 +1,63 @@ +export type SmartListRecord = Record; + +/** + * TeaQL's typed list boundary. Besides array ergonomics it preserves query + * metadata so adding facets, summaries, or totals does not require an API change. + */ +export class SmartList extends Array { + static get [Symbol.species](): ArrayConstructor { + return Array; + } + + totalCount?: number; + aggregations: SmartListRecord; + summary: SmartListRecord; + facets: Record>; + isLoaded: boolean; + + constructor( + data: Iterable | number = [], + options: { + totalCount?: number; + aggregations?: SmartListRecord; + summary?: SmartListRecord; + facets?: Record>; + isLoaded?: boolean; + } = {}, + ) { + if (typeof data === 'number') super(data); + else super(...data); + Object.setPrototypeOf(this, SmartList.prototype); + this.totalCount = options.totalCount; + this.aggregations = options.aggregations ?? {}; + this.summary = options.summary ?? {}; + this.facets = options.facets ?? {}; + this.isLoaded = options.isLoaded ?? true; + } + + static empty(): SmartList { + return new SmartList([], { isLoaded: false }); + } + + get data(): SmartList { + return this; + } + + withTotalCount(totalCount: number): this { + this.totalCount = totalCount; + return this; + } + + withFacet(name: string, facet: SmartList): this { + this.facets[name] = facet; + return this; + } + + facet(name: string): SmartList | undefined { + return this.facets[name]; + } + + totalCountOrLength(): number { + return this.totalCount ?? this.length; + } +} diff --git a/source/teaql-ts/src/core/sql-diagnostic-event.ts b/source/teaql-ts/src/core/sql-diagnostic-event.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b15e966c94dfaaa284e9b939144d56ff860456f --- /dev/null +++ b/source/teaql-ts/src/core/sql-diagnostic-event.ts @@ -0,0 +1,25 @@ +import type { RuntimeDiagnosticEvent, RuntimeExecutionCorrelation } from './telemetry'; +import type { SQLExecutionMetadata } from '../sql/core'; + +/** Does not spread metadata, parameters, rows, audit payloads or entity IDs. */ +export function sqlDiagnosticEvent(metadata: SQLExecutionMetadata, + correlation?: RuntimeExecutionCorrelation): RuntimeDiagnosticEvent { + if (metadata.logMode !== 'masked') throw new Error('Telemetry requires safe SQL projection'); + const nodes = (frames: readonly { kind: string; name: string; detail?: string }[] = []) => + JSON.stringify(frames.map(frame => ({ kind: frame.kind, name: frame.name, detail: frame.detail ?? '' }))); + return Object.freeze({ body: 'TeaQL SQL execution', correlation, + attributes: Object.freeze({ + 'teaql.trace_chain': nodes(metadata.traceChain), + 'teaql.trace_path': nodes(metadata.tracePath), + 'teaql.mutation_lineage': nodes(metadata.mutationLineage), + 'teaql.intent.comment': metadata.comment ?? metadata.auditReason ?? '', + 'teaql.intent.purpose': metadata.purpose ?? '', + 'teaql.sql.debug': metadata.debugSQL, + 'teaql.sql.log_mode': metadata.logMode, + 'teaql.sql.operation': metadata.operation, + 'teaql.sql.outcome': metadata.executionOutcome ?? 'unknown', + 'teaql.sql.elapsed_us': metadata.elapsedMicros, + ...(metadata.resultCount === undefined ? {} : { 'teaql.sql.result_count': metadata.resultCount }), + ...(metadata.affectedRows === undefined ? {} : { 'teaql.sql.affected_rows': metadata.affectedRows }), + }) }); +} diff --git a/source/teaql-ts/src/core/telemetry-startup.ts b/source/teaql-ts/src/core/telemetry-startup.ts new file mode 100644 index 0000000000000000000000000000000000000000..88fc3521cacb04de7946240a5f59d3979c9d7c20 --- /dev/null +++ b/source/teaql-ts/src/core/telemetry-startup.ts @@ -0,0 +1,47 @@ +/** Environment activation is process configuration, never request input. */ +export const TELEMETRY_ENVIRONMENT = Object.freeze({ + enabled: 'TEAQL_TELEMETRY_ENABLED', + service: 'TEAQL_TELEMETRY_SERVICE_NAME', + endpoint: 'TEAQL_TELEMETRY_OTLP_ENDPOINT', +}); + +export function telemetryNotice(message: string, warning = false): void { + try { if (warning) console.warn(message); else console.info(message); } + catch { /* diagnostic output must not change application startup or business work */ } +} + +export type TelemetryStartupConfiguration = Readonly<{ + enabled: boolean; + serviceName?: string; + endpoint?: string; + error?: 'invalid-enable' | 'invalid-service' | 'invalid-endpoint'; +}>; + +export function readTelemetryStartupConfiguration( + environment: Readonly>, +): TelemetryStartupConfiguration { + const flag = environment[TELEMETRY_ENVIRONMENT.enabled]?.trim().toLowerCase(); + if (!flag || flag === 'false') return Object.freeze({ enabled: false }); + if (flag !== 'true') return Object.freeze({ enabled: false, error: 'invalid-enable' }); + const serviceName = environment[TELEMETRY_ENVIRONMENT.service]?.trim(); + if (!serviceName || !/^[a-zA-Z0-9_.-]{1,120}$/.test(serviceName)) { + return Object.freeze({ enabled: false, error: 'invalid-service' }); + } + try { + const endpoint = new URL(environment[TELEMETRY_ENVIRONMENT.endpoint] || ''); + if (!['http:', 'https:'].includes(endpoint.protocol) || endpoint.username || endpoint.password + || endpoint.search || endpoint.hash) throw new Error('invalid endpoint'); + return Object.freeze({ enabled: true, serviceName, endpoint: endpoint.href.replace(/\/$/, '') }); + } catch { return Object.freeze({ enabled: false, error: 'invalid-endpoint' }); } +} + +export function telemetryStartupMessage(configuration: TelemetryStartupConfiguration): string { + const variables = `${TELEMETRY_ENVIRONMENT.enabled}=true ` + + `${TELEMETRY_ENVIRONMENT.service}= ` + + `${TELEMETRY_ENVIRONMENT.endpoint}=`; + if (configuration.error) return `TeaQL telemetry: disabled; configuration=${configuration.error}. ${variables}`; + if (!configuration.enabled) return `TeaQL telemetry: supported, disabled. Enable full masked diagnostics with ${variables}`; + return `TeaQL telemetry: starting standard module; full recording, masked SQL; ` + + `${TELEMETRY_ENVIRONMENT.enabled}=true ${TELEMETRY_ENVIRONMENT.service}=${configuration.serviceName} ` + + `${TELEMETRY_ENVIRONMENT.endpoint}=${configuration.endpoint}`; +} diff --git a/source/teaql-ts/src/core/telemetry.ts b/source/teaql-ts/src/core/telemetry.ts new file mode 100644 index 0000000000000000000000000000000000000000..a9587158ff0cc49dffe0496e550fa87e4906529a --- /dev/null +++ b/source/teaql-ts/src/core/telemetry.ts @@ -0,0 +1,156 @@ +export type RuntimeOperationFamily = + | 'query' + | 'mutation' + | 'relation_load' + | 'provider' + | 'cache' + | 'tfp' + | 'audit'; + +export type RuntimeAttributeValue = string | number | boolean; + +export type RuntimeErrorCategory = + | 'validation' | 'authorization' | 'conflict' | 'timeout' + | 'transport' | 'provider' | 'internal'; + +/** Stable classification derived from a native error type, never its message. */ +export function runtimeErrorCategory(error: unknown): RuntimeErrorCategory { + const type = error instanceof Error && error.constructor?.name + ? error.constructor.name.toLowerCase() + : typeof error; + if (/timeout|deadline/.test(type)) return 'timeout'; + if (/authentication|authorization|unauthorized|forbidden|permission/.test(type)) return 'authorization'; + if (/validation|invalidargument|valueerror|parse|format/.test(type)) return 'validation'; + if (/conflict|optimistic|version|duplicate|alreadyexists/.test(type)) return 'conflict'; + if (/transport|network|connection|socket|http|ioerror/.test(type)) return 'transport'; + if (/provider|sql|database|jdbc/.test(type)) return 'provider'; + return 'internal'; +} + +export interface RuntimeOperation { + readonly family: RuntimeOperationFamily; + readonly name: string; + readonly attributes?: Readonly>; +} + +export interface RuntimeOperationCompletion { + readonly attributes?: Readonly>; +} + +export interface RuntimeExecutionCorrelation { + readonly traceId: string; + readonly spanId: string; +} + +/** Only runtime-projected, allow-listed diagnostics may enter this event. */ +export interface RuntimeDiagnosticEvent { + readonly body: 'TeaQL SQL execution'; + readonly correlation?: RuntimeExecutionCorrelation; + readonly attributes: Readonly>; +} + +export interface RuntimeTelemetryScope { + success(completion?: RuntimeOperationCompletion): void; + failure(error: unknown): void; + run?(work: () => Promise): Promise; + correlation?(): RuntimeExecutionCorrelation | undefined; +} + +/** Provider-neutral TeaQL lifecycle contract. Implementations must be fail open. */ +export interface RuntimeTelemetry { + recordsSQLDiagnostics?(): boolean; + start(operation: RuntimeOperation): RuntimeTelemetryScope; + inject?(carrier: Record): void; + flush?(): void | Promise; + shutdown?(): void | Promise; + recordDiagnostic?(event: RuntimeDiagnosticEvent): void; +} + +/** Inject the active runtime trace into transport metadata without affecting business work. */ +export function injectRuntimeContext( + telemetry: RuntimeTelemetry | undefined, + carrier: Record, +): Record { + try { telemetry?.inject?.(carrier); } catch { /* telemetry is fail open */ } + return carrier; +} + +const noopScope: RuntimeTelemetryScope = Object.freeze({ + success: () => undefined, + failure: () => undefined, +}); + +export const NOOP_RUNTIME_TELEMETRY: RuntimeTelemetry = Object.freeze({ + start: () => noopScope, +}); + +const forbiddenAttributes = new Set([ + 'teaql.entity.id', + 'teaql.user.id', + 'teaql.tenant.id', + 'teaql.query.parameters', + 'teaql.field.values', + 'teaql.audit.reason', + 'db.query.parameter_values', + 'http.request.body', + 'url.full', +]); + +export function safeRuntimeOperation(operation: RuntimeOperation): RuntimeOperation { + const attributes: Record = { + 'teaql.operation.family': operation.family, + 'teaql.operation.name': operation.name, + }; + for (const [key, value] of Object.entries(operation.attributes || {})) { + if (!forbiddenAttributes.has(key)) attributes[key] = value; + } + return Object.freeze({ ...operation, attributes: Object.freeze(attributes) }); +} + +export function startRuntimeOperation( + telemetry: RuntimeTelemetry | undefined, + operation: RuntimeOperation, +): RuntimeTelemetryScope { + if (!telemetry) return noopScope; + try { + const delegate = telemetry.start(safeRuntimeOperation(operation)); + let ended = false; + return { + correlation: () => { + try { return delegate.correlation?.(); } catch { return undefined; } + }, + run: delegate.run + ? (work: () => Promise) => delegate.run!(work) + : (work: () => Promise) => work(), + success(completion) { + if (ended) return; + ended = true; + try { delegate?.success(completion); } catch { /* telemetry is fail open */ } + }, + failure(error) { + if (ended) return; + ended = true; + try { delegate?.failure(error); } catch { /* telemetry is fail open */ } + }, + }; + } catch { + return noopScope; + } +} + +export async function observeRuntimeOperation( + telemetry: RuntimeTelemetry | undefined, + operation: RuntimeOperation, + work: () => Promise, + completion?: (result: T) => RuntimeOperationCompletion, +): Promise { + const scope = startRuntimeOperation(telemetry, operation); + try { + const result = await (scope.run ? scope.run(work) : work()); + scope.success(completion?.(result)); + return result; + } catch (error) { + scope.failure(error); + throw error; + } +} diff --git a/source/teaql-ts/src/core/tools.ts b/source/teaql-ts/src/core/tools.ts new file mode 100644 index 0000000000000000000000000000000000000000..e971761a04e95a00ec262563dcc35a2da9374496 --- /dev/null +++ b/source/teaql-ts/src/core/tools.ts @@ -0,0 +1,123 @@ +import { UserContext } from './context'; + +export type ToolRisk = 'MEMORY_ONLY' | 'EXTERNAL_RESOURCE' | 'PRIVILEGED'; + +export interface ToolToken { + readonly id: string; + readonly risk: ToolRisk; + readonly _type?: T; +} + +export interface ToolProvider { + readonly token: ToolToken; + create(context: UserContext): T; +} + +export class ToolPolicy { + constructor( + private readonly allowed: ReadonlySet, + private readonly allowMemoryOnly = true, + ) {} + + static standard(): ToolPolicy { return new ToolPolicy(new Set()); } + static denyAll(): ToolPolicy { return new ToolPolicy(new Set(), false); } + static builder(): ToolPolicyBuilder { return new ToolPolicyBuilder(); } + + allows(token: ToolToken): boolean { + return (token.risk === 'MEMORY_ONLY' && this.allowMemoryOnly) || this.allowed.has(token.id); + } +} + +export class ToolPolicyBuilder { + private readonly allowed = new Set(); + allow(token: ToolToken): this { this.allowed.add(token.id); return this; } + build(): ToolPolicy { return new ToolPolicy(new Set(this.allowed)); } +} + +export interface Tools { + has(token: ToolToken): boolean; + get(token: ToolToken): T; + descriptors(): readonly ToolToken[]; +} + +class DefaultTools implements Tools { + private readonly providers = new Map>(); + + constructor( + private readonly context: UserContext, + private readonly policy: ToolPolicy, + providers: readonly ToolProvider[], + ) { + for (const provider of providers) this.providers.set(provider.token.id, provider); + } + + has(token: ToolToken): boolean { return this.providers.has(token.id); } + + get(token: ToolToken): T { + const provider = this.providers.get(token.id); + if (!provider) throw new Error(`Tool not available: ${token.id}`); + if (!this.policy.allows(token)) throw new Error(`Tool denied by policy: ${token.id}`); + return provider.create(this.context) as T; + } + + descriptors(): readonly ToolToken[] { + return [...this.providers.values()].map((provider) => provider.token); + } +} + +export class ContextTools { + static builder(context: UserContext): ContextToolsBuilder { return new ContextToolsBuilder(context); } + static of(context: UserContext): Tools { return this.builder(context).build(); } +} + +export class ContextToolsBuilder { + private selectedPolicy = ToolPolicy.standard(); + private readonly providers: ToolProvider[] = []; + constructor(private readonly context: UserContext) {} + policy(policy: ToolPolicy): this { this.selectedPolicy = policy; return this; } + provider(provider: ToolProvider): this { + this.providers.push(provider as ToolProvider); + return this; + } + build(): Tools { return new DefaultTools(this.context, this.selectedPolicy, this.providers); } +} + +export interface ExecutableHttpTool { execute(): Promise; } +export interface HttpIntentPhase { + purpose(intent: string): ExecutableHttpTool; + auditAs(intent: string): ExecutableHttpTool; +} +export interface HttpTool { + get(url: string): HttpIntentPhase; + post(url: string, body: unknown): HttpIntentPhase; +} + +export const HTTP_TOOL: ToolToken = Object.freeze({ + id: 'http', risk: 'EXTERNAL_RESOURCE' as const, +}); + +export class FetchHttpToolProvider implements ToolProvider { + readonly token = HTTP_TOOL; + constructor(private readonly fetchImpl: typeof fetch = fetch) {} + create(_context: UserContext): HttpTool { + const stage = (method: 'GET' | 'POST', url: string, body?: unknown): HttpIntentPhase => ({ + purpose: (intent) => executable(method, url, body, intent), + auditAs: (intent) => executable(method, url, body, intent), + }); + const executable = ( + method: 'GET' | 'POST', url: string, body: unknown, intent: string, + ): ExecutableHttpTool => ({ + execute: async () => { + if (!intent.trim()) throw new Error('HTTP tool execution requires non-empty intent'); + const response = await this.fetchImpl(url, method === 'GET' ? { method } : { + method, + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + }); + if (!response.ok) throw new Error(`HTTP tool failed: ${response.status}`); + return response.text(); + }, + }); + return { get: (url) => stage('GET', url), post: (url, body) => stage('POST', url, body) }; + } +} diff --git a/source/teaql-ts/src/core/trace-chain.ts b/source/teaql-ts/src/core/trace-chain.ts new file mode 100644 index 0000000000000000000000000000000000000000..665e5c4d4894649d6495895898306dc78f341df2 --- /dev/null +++ b/source/teaql-ts/src/core/trace-chain.ts @@ -0,0 +1,86 @@ +/** Typed vocabulary shared by SQL routing and independently owned audit lineage. */ +export type TraceKind = 'operation' | 'request' | 'relation' | 'entity' | 'provider' | + 'sql' | 'comment' | 'purpose' | 'auditReason'; +export type TraceNode = Readonly<{ + kind: TraceKind; + name: string; + /** Strings/bigints preserve unsigned-64 identities beyond JavaScript's safe integer range. */ + entityId?: string | number | bigint | null; + detail?: string; +}>; +export type SQLTraceOperation = 'select' | 'insert' | 'update' | 'delete' | 'recover'; + +export function cloneTraceNodes(source: readonly TraceNode[]): readonly TraceNode[] { + return Object.freeze(source.map(node => Object.freeze({ ...node }))); +} + +/** Persistent graph-local responsibility. Creating a branch is O(1). */ +export class MutationTraceScope { + readonly #parent?: MutationTraceScope; + readonly #node: TraceNode; + + constructor(parent: MutationTraceScope | undefined, node: TraceNode) { + this.#parent = parent; + this.#node = Object.freeze({ ...node }); + Object.freeze(this); + } + + recover(): readonly TraceNode[] { + const nodes: TraceNode[] = []; + let scope: MutationTraceScope | undefined = this; + while (scope) { nodes.push(scope.#node); scope = scope.#parent; } + return cloneTraceNodes(nodes.reverse()); + } +} + +export function mutationScopeForEntity(parent: MutationTraceScope | undefined, + entity: string, id: string | number | bigint, rootComment: string, + localComment?: string): MutationTraceScope { + const reason = parent ? localComment : rootComment; + if (parent && (typeof reason !== 'string' || /^\p{White_Space}*$/u.test(reason))) return parent; + const rawId = String(id); + const entityId = /^(0|[1-9][0-9]*)$/.test(rawId) && BigInt(rawId) <= 18446744073709551615n + ? id : undefined; + return new MutationTraceScope(parent, { kind: 'auditReason', name: entity, + entityId, detail: reason }); +} + +const intentKinds = new Set(['comment', 'purpose', 'auditReason']); +const nonBlank = (value: string): boolean => !/^\p{White_Space}*$/u.test(value); + +/** Pure Rust-baseline algorithm. Request validation remains a separate mandatory gate. */ +export function canonicalSQLTracePath(source: readonly TraceNode[], backend: string, + operation: SQLTraceOperation): Readonly<{ + tracePath: readonly TraceNode[]; comment?: string; purpose?: string; auditReason?: string; + }> { + const last = (kind: TraceKind): string | undefined => { + for (let index = source.length - 1; index >= 0; index--) { + if (source[index].kind === kind) return source[index].detail ?? ''; + } + return undefined; + }; + const canonical = ['operation', 'provider', 'sql'].every(kind => source.some(node => node.kind === kind)); + let path: readonly TraceNode[]; + if (canonical) path = source.filter(node => !intentKinds.has(node.kind)); + else { + const root = source.find(node => nonBlank(node.name))?.name ?? 'unknown'; + let entity = root; + if (operation !== 'select') { + for (const node of source) if (node.kind === 'entity' && nonBlank(node.name)) entity = node.name; + } + path = [ + { kind: 'operation', name: root, detail: operation === 'select' ? 'query' : 'mutation' }, + { kind: operation === 'select' ? 'request' : 'entity', name: operation === 'select' ? root : entity, detail: '' }, + ...source.filter(node => node.kind === 'relation'), + { kind: 'provider', name: nonBlank(backend) ? backend : 'unknown', detail: '' }, + { kind: 'sql', name: operation, detail: '' }, + ]; + } + return Object.freeze({ tracePath: cloneTraceNodes(path), comment: last('comment'), + purpose: last('purpose'), auditReason: last('auditReason') }); +} + +export function queryTraceSource(entity: string, comment: string, purpose: string): readonly TraceNode[] { + return cloneTraceNodes([{ kind: 'comment', name: entity, detail: comment }, + { kind: 'purpose', name: entity, detail: purpose }]); +} diff --git a/source/teaql-ts/src/core/value.ts b/source/teaql-ts/src/core/value.ts new file mode 100644 index 0000000000000000000000000000000000000000..429ee6c89a63226d38f38face7681a574127e74a --- /dev/null +++ b/source/teaql-ts/src/core/value.ts @@ -0,0 +1,47 @@ +export type Value = + | { type: 'Null' } + | { type: 'Bool', value: boolean } + | { type: 'I64', value: number } + | { type: 'U64', value: number } + | { type: 'F64', value: number } + | { type: 'Decimal', value: number | string } + | { type: 'Text', value: string } + | { type: 'Json', value: any } + | { type: 'Date', value: string | Date } + | { type: 'Timestamp', value: number } + | { type: 'Object', value: Record } + | { type: 'List', value: Value[] } + | { type: 'TypedNull', dataType: string }; + +export const Values = { + Null: (): Value => ({ type: 'Null' }), + Bool: (value: boolean): Value => ({ type: 'Bool', value }), + I64: (value: number): Value => ({ type: 'I64', value }), + U64: (value: number): Value => ({ type: 'U64', value }), + F64: (value: number): Value => ({ type: 'F64', value }), + Decimal: (value: number | string): Value => ({ type: 'Decimal', value }), + Text: (value: string): Value => ({ type: 'Text', value }), + Json: (value: any): Value => ({ type: 'Json', value }), + Date: (value: string | Date): Value => ({ type: 'Date', value }), + Timestamp: (value: number): Value => ({ type: 'Timestamp', value }), + Object: (value: Record): Value => ({ type: 'Object', value }), + List: (value: Value[]): Value => ({ type: 'List', value }), + TypedNull: (dataType: string): Value => ({ type: 'TypedNull', dataType }), + + isEmpty(v: Value): boolean { + switch (v.type) { + case 'Null': + case 'TypedNull': return true; + case 'Text': return v.value === ''; + case 'Object': return Object.keys(v.value).length === 0; + case 'List': return v.value.length === 0; + default: return false; + } + }, + + tryI64(v: Value): number | null { + if (v.type === 'I64' || v.type === 'U64') return Number(v.value); + if (v.type === 'Decimal') return parseInt(v.value.toString(), 10); + return null; + } +}; diff --git a/source/teaql-ts/src/core/wire-fields.ts b/source/teaql-ts/src/core/wire-fields.ts new file mode 100644 index 0000000000000000000000000000000000000000..be877b3d771bf1b0061d834a2812f8f77ac854d7 --- /dev/null +++ b/source/teaql-ts/src/core/wire-fields.ts @@ -0,0 +1,146 @@ +import { + JsonFieldNamingProfile, + renderJsonFieldName, +} from './object-location'; +import type { CheckResult } from './i18n'; + +export interface WireFieldMetadata { + readonly canonicalName: string; + readonly wireName: string; + readonly aliases: readonly string[]; +} + +export interface WireEntityMetadata { + readonly entityType: string; + readonly profile: JsonFieldNamingProfile; + readonly fields: Readonly>; +} + +export interface NormalizedWireInput { + /** Values keyed only by canonical KSML property names. */ + readonly values: Readonly>; + /** Exact submitted RFC 6901 pointer, retained only for accepted aliases. */ + readonly sourceInstancePaths: Readonly>; +} + +export class WireInputError extends Error { + constructor( + public readonly code: 'WIRE_UNKNOWN_FIELD' | 'WIRE_FIELD_COLLISION', + public readonly instancePath: string, + message: string, + ) { + super(message); + this.name = 'WireInputError'; + } +} + +export function createWireEntityMetadata( + entityType: string, + canonicalFields: readonly string[], + profile: JsonFieldNamingProfile = 'camelCase', + aliases: Readonly> = {}, +): WireEntityMetadata { + const fields: Record = {}; + const spellings = new Map(); + for (const canonicalName of canonicalFields) { + const wireName = renderJsonFieldName(canonicalName, profile); + const fieldAliases = [...(aliases[canonicalName] ?? [])]; + for (const spelling of [wireName, ...fieldAliases]) { + const existing = spellings.get(spelling); + if (existing && existing !== canonicalName) { + throw new Error( + `Wire field spelling '${spelling}' maps to both '${existing}' and '${canonicalName}'`, + ); + } + spellings.set(spelling, canonicalName); + } + fields[canonicalName] = Object.freeze({ + canonicalName, + wireName, + aliases: Object.freeze(fieldAliases), + }); + } + return Object.freeze({ entityType, profile, fields: Object.freeze(fields) }); +} + +/** + * Normalize one JSON object before checker or mutation execution. + * + * No serializer naming policy is consulted. The generated field map is the + * complete authority, and two submitted spellings for one canonical field are + * always rejected, even when their values happen to be equal. + */ +export function normalizeWireInput( + input: Readonly>, + metadata: WireEntityMetadata, + parentPointer = '', +): NormalizedWireInput { + const lookup = new Map(); + for (const field of Object.values(metadata.fields)) { + lookup.set(field.wireName, field); + for (const alias of field.aliases) lookup.set(alias, field); + } + + const values: Record = {}; + const sourceInstancePaths: Record = {}; + const submitted = new Map(); + for (const [submittedName, value] of Object.entries(input)) { + const pointer = `${parentPointer}/${escapeJsonPointer(submittedName)}`; + const field = lookup.get(submittedName); + if (!field) { + throw new WireInputError( + 'WIRE_UNKNOWN_FIELD', pointer, + `Unknown ${metadata.entityType} field '${submittedName}'`, + ); + } + const previous = submitted.get(field.canonicalName); + if (previous !== undefined) { + throw new WireInputError( + 'WIRE_FIELD_COLLISION', pointer, + `Fields '${previous}' and '${submittedName}' both map to canonical field '${field.canonicalName}'`, + ); + } + submitted.set(field.canonicalName, submittedName); + values[field.canonicalName] = value; + if (submittedName !== field.wireName) { + sourceInstancePaths[field.canonicalName] = pointer; + } + } + return Object.freeze({ + values: Object.freeze(values), + sourceInstancePaths: Object.freeze(sourceInstancePaths), + }); +} + +/** Render canonical mutation values to the selected external profile. */ +export function encodeWireOutput( + values: Readonly>, + metadata: WireEntityMetadata, +): Readonly> { + const output: Record = {}; + for (const [canonicalName, value] of Object.entries(values)) { + const field = metadata.fields[canonicalName]; + if (!field) { + throw new Error(`Unknown canonical ${metadata.entityType} field '${canonicalName}'`); + } + output[field.wireName] = value; + } + return Object.freeze(output); +} + +/** Add submitted alias provenance to checker results without changing location identity. */ +export function retainSubmittedPaths( + results: readonly CheckResult[], + normalized: NormalizedWireInput, +): CheckResult[] { + return results.map(result => { + const firstProperty = result.location.segments.find(segment => segment.kind === 'property'); + if (!firstProperty || firstProperty.kind !== 'property') return { ...result }; + const sourceInstancePath = normalized.sourceInstancePaths[firstProperty.name]; + return sourceInstancePath === undefined ? { ...result } : { ...result, sourceInstancePath }; + }); +} + +function escapeJsonPointer(value: string): string { + return value.replace(/~/g, '~0').replace(/\//g, '~1'); +} diff --git a/source/teaql-ts/src/index.ts b/source/teaql-ts/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..a583d97f3307a2a3b61c3450a445cd7eab250a95 --- /dev/null +++ b/source/teaql-ts/src/index.ts @@ -0,0 +1,24 @@ +export * from './core/value'; +export * from './core/context'; +export * from './core/request-intent'; +export * from './core/trace-chain'; +export * from './core/mutation-policy'; +export * from './core/entity-root'; +export * from './core/loaded-scalar-snapshot'; +export * from './core/checker'; +export * from './core/object-location'; +export * from './core/wire-fields'; +export * from './core/dynamic-search'; +export * from './core/i18n'; +export * from './core/tools'; +export * from './core/local-cache'; +export * from './core/runtime-module'; +export * from './core/smart-list'; +export * from './core/telemetry'; +export { SelectQuery, MutationQuery, AggregationCacheOptions, OrderBy, SortDirection } from './core/ast'; +export type { TeaQLPage, QuerySelection, FacetRequest } from './core/ast'; +export { executeRelationFacets } from './core/facet'; +export type { FacetAggregate, FacetQueryService } from './core/facet'; +export * from './meta/descriptors'; +export * from './tfp/client'; +export * from './parser/dsl'; diff --git a/source/teaql-ts/src/meta/descriptors.ts b/source/teaql-ts/src/meta/descriptors.ts new file mode 100644 index 0000000000000000000000000000000000000000..3fdcc3cce845cc1a97135595d620e97c40521ba4 --- /dev/null +++ b/source/teaql-ts/src/meta/descriptors.ts @@ -0,0 +1,169 @@ +export enum DataType { + Text = 'Text', + I64 = 'I64', + U64 = 'U64', + F64 = 'F64', + Decimal = 'Decimal', + Bool = 'Bool', + Date = 'Date', + Timestamp = 'Timestamp', + Json = 'Json' +} + +export class PropertyDescriptor { + public name: string; + public dataType: DataType; + public nullable: boolean = true; + public columnNameString: string; + public isId: boolean = false; + public isVersion: boolean = false; + + constructor(name: string, dataType: DataType) { + this.name = name; + this.dataType = dataType; + this.columnNameString = name; + } + + static new(name: string, dataType: DataType): PropertyDescriptor { + return new PropertyDescriptor(name, dataType); + } + + columnName(name: string): this { + this.columnNameString = name; + return this; + } + + notNull(): this { + this.nullable = false; + return this; + } + + id(): this { + this.isId = true; + return this; + } + + version(): this { + this.isVersion = true; + return this; + } +} + +export class RelationDescriptor { + public name: string; + public targetEntity: string; + public localKeyValue: string = 'id'; + public foreignKeyValue: string = 'id'; + public isMany: boolean = false; + public isAttach: boolean = true; + public isDeleteMissing: boolean = true; + + constructor(name: string, targetEntity: string) { + this.name = name; + this.targetEntity = targetEntity; + } + + static new(name: string, targetEntity: string): RelationDescriptor { + return new RelationDescriptor(name, targetEntity); + } + + localKey(key: string): this { + this.localKeyValue = key; + return this; + } + + foreignKey(key: string): this { + this.foreignKeyValue = key; + return this; + } + + many(many: boolean = true): this { + this.isMany = many; + return this; + } + + attach(attach: boolean = true): this { + this.isAttach = attach; + return this; + } + + detached(): this { + this.isAttach = false; + return this; + } + + deleteMissing(deleteMissing: boolean = true): this { + this.isDeleteMissing = deleteMissing; + return this; + } + + keepMissing(): this { + this.isDeleteMissing = false; + return this; + } +} + +export class EntityDescriptor { + public name: string; + public tableNameValue: string; + public dataServiceName?: string; + public properties: PropertyDescriptor[] = []; + public relations: RelationDescriptor[] = []; + public auditMaskFieldList: string[] = []; + public auditValueMaxLenValue?: number; + + constructor(name: string) { + this.name = name; + this.tableNameValue = name.toLowerCase(); // Default fallback + } + + static new(name: string): EntityDescriptor { + return new EntityDescriptor(name); + } + + tableName(name: string): this { + this.tableNameValue = name; + return this; + } + + dataService(name: string): this { + this.dataServiceName = name; + return this; + } + + property(prop: PropertyDescriptor): this { + this.properties.push(prop); + return this; + } + + relation(rel: RelationDescriptor): this { + this.relations.push(rel); + return this; + } + + auditMaskFields(fields: string[]): this { + this.auditMaskFieldList = fields; + return this; + } + + auditValueMaxLen(len: number): this { + this.auditValueMaxLenValue = len; + return this; + } + + propertyByName(name: string): PropertyDescriptor | undefined { + return this.properties.find(p => p.name === name); + } + + relationByName(name: string): RelationDescriptor | undefined { + return this.relations.find(r => r.name === name); + } + + idProperty(): PropertyDescriptor | undefined { + return this.properties.find(p => p.isId); + } + + versionProperty(): PropertyDescriptor | undefined { + return this.properties.find(p => p.isVersion); + } +} diff --git a/source/teaql-ts/src/parser/dsl.ts b/source/teaql-ts/src/parser/dsl.ts new file mode 100644 index 0000000000000000000000000000000000000000..5062340d4cb6cbd6ae7c0c8e919f0bfe5c67c44a --- /dev/null +++ b/source/teaql-ts/src/parser/dsl.ts @@ -0,0 +1,52 @@ +import * as parser from './query-parser.generated'; + +type CallNode = { + type: 'Call'; + method: string; + arguments: ValueNode[]; +}; + +type CallChainNode = { + type: 'CallChain'; + target: string; + calls: CallNode[]; +}; + +type ValueNode = CallChainNode | string | number | boolean | null | ValueNode[]; + +const FORBIDDEN_PROPERTY_NAMES = new Set(['__proto__', 'prototype', 'constructor']); + +function executeCallChain(node: CallChainNode, entryPoint: object): unknown { + if (node.target !== 'Q') { + throw new Error(`Unsupported query entry point ${node.target}; expected Q`); + } + let receiver: unknown = entryPoint; + for (const call of node.calls) { + if (FORBIDDEN_PROPERTY_NAMES.has(call.method)) { + throw new Error(`Method ${call.method} is not allowed in a query expression`); + } + if ((typeof receiver !== 'object' && typeof receiver !== 'function') || receiver === null) { + throw new Error(`Cannot call ${call.method} on a non-query value`); + } + const method = (receiver as Record)[call.method]; + if (typeof method !== 'function') { + throw new Error(`Method ${call.method} is not available on the generated query API`); + } + const args = call.arguments.map(argument => + typeof argument === 'object' && argument !== null && !Array.isArray(argument) + ? executeCallChain(argument as CallChainNode, entryPoint) + : argument, + ); + receiver = method.apply(receiver, args); + } + return receiver; +} + +export class QueryParser { + // The concrete return type is supplied by the generated entry point at runtime. + // Keep `any` for source compatibility with existing generated Q facades. + static parse(querySource: string, entryPoint: object): any { + const ast = parser.parse(querySource, undefined) as CallChainNode; + return executeCallChain(ast, entryPoint); + } +} diff --git a/source/teaql-ts/src/parser/query-parser.generated.ts b/source/teaql-ts/src/parser/query-parser.generated.ts new file mode 100644 index 0000000000000000000000000000000000000000..ba02cd51ad8cd783e4b833ecef7a9eebfac4648e --- /dev/null +++ b/source/teaql-ts/src/parser/query-parser.generated.ts @@ -0,0 +1,1334 @@ +// @ts-nocheck -- generated by scripts/generate-query-parser.mjs +// @generated by Peggy 5.1.0. +// +// https://peggyjs.org/ + + +class peg$SyntaxError extends SyntaxError { + constructor(message, expected, found, location) { + super(message); + this.expected = expected; + this.found = found; + this.location = location; + this.name = "SyntaxError"; + } + + format(sources) { + let str = "Error: " + this.message; + if (this.location) { + let src = null; + const st = sources.find(s => s.source === this.location.source); + if (st) { + src = st.text.split(/\r\n|\n|\r/g); + } + const s = this.location.start; + const offset_s = (this.location.source && (typeof this.location.source.offset === "function")) + ? this.location.source.offset(s) + : s; + const loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; + if (src) { + const e = this.location.end; + const filler = "".padEnd(offset_s.line.toString().length, " "); + const line = src[s.line - 1]; + const last = s.line === e.line ? e.column : line.length + 1; + const hatLen = (last - s.column) || 1; + str += "\n --> " + loc + "\n" + + filler + " |\n" + + offset_s.line + " | " + line + "\n" + + filler + " | " + "".padEnd(s.column - 1, " ") + + "".padEnd(hatLen, "^"); + } else { + str += "\n at " + loc; + } + } + return str; + } + + static buildMessage(expected, found) { + function hex(ch) { + return ch.codePointAt(0).toString(16).toUpperCase(); + } + + const nonPrintable = Object.prototype.hasOwnProperty.call(RegExp.prototype, "unicode") + ? new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]", "gu") + : null; + function unicodeEscape(s) { + if (nonPrintable) { + return s.replace(nonPrintable, ch => "\\u{" + hex(ch) + "}"); + } + return s; + } + + function literalEscape(s) { + return unicodeEscape(s + .replace(/\\/g, "\\\\") + .replace(/"/g, "\\\"") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) + .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); + } + + function classEscape(s) { + return unicodeEscape(s + .replace(/\\/g, "\\\\") + .replace(/\]/g, "\\]") + .replace(/\^/g, "\\^") + .replace(/-/g, "\\-") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch)) + .replace(/[\x10-\x1F\x7F-\x9F]/g, ch => "\\x" + hex(ch))); + } + + const DESCRIBE_EXPECTATION_FNS = { + literal(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + class(expectation) { + const escapedParts = expectation.parts.map( + part => (Array.isArray(part) + ? classEscape(part[0]) + "-" + classEscape(part[1]) + : classEscape(part)) + ); + + return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]" + (expectation.unicode ? "u" : ""); + }, + + any() { + return "any character"; + }, + + end() { + return "end of input"; + }, + + other(expectation) { + return expectation.description; + }, + }; + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + const descriptions = expected.map(describeExpectation); + descriptions.sort(); + + if (descriptions.length > 0) { + let j = 1; + for (let i = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; + } +} + +function peg$parse(input, options) { + options = options !== undefined ? options : {}; + + const peg$FAILED = {}; + const peg$source = options.grammarSource; + + const peg$startRuleFunctions = { + Start: peg$parseStart, + }; + let peg$startRuleFunction = peg$parseStart; + + const peg$c0 = ";"; + const peg$c1 = "."; + const peg$c2 = "("; + const peg$c3 = ")"; + const peg$c4 = ","; + const peg$c5 = "["; + const peg$c6 = "]"; + const peg$c7 = "\""; + const peg$c8 = "\\"; + const peg$c9 = "'"; + const peg$c10 = "-"; + const peg$c11 = "true"; + const peg$c12 = "false"; + const peg$c13 = "null"; + + const peg$r0 = /^[^"\\]/; + const peg$r1 = /^[^'\\]/; + const peg$r2 = /^[0-9]/; + const peg$r3 = /^[eE]/; + const peg$r4 = /^[+\-]/; + const peg$r5 = /^[A-Za-z_$]/; + const peg$r6 = /^[A-Za-z0-9_$]/; + const peg$r7 = /^[ \t\r\n]/; + + const peg$e0 = peg$literalExpectation(";", false); + const peg$e1 = peg$literalExpectation(".", false); + const peg$e2 = peg$literalExpectation("(", false); + const peg$e3 = peg$literalExpectation(")", false); + const peg$e4 = peg$literalExpectation(",", false); + const peg$e5 = peg$literalExpectation("[", false); + const peg$e6 = peg$literalExpectation("]", false); + const peg$e7 = peg$literalExpectation("\"", false); + const peg$e8 = peg$literalExpectation("\\", false); + const peg$e9 = peg$anyExpectation(); + const peg$e10 = peg$classExpectation(["\"", "\\"], true, false, false); + const peg$e11 = peg$literalExpectation("'", false); + const peg$e12 = peg$classExpectation(["'", "\\"], true, false, false); + const peg$e13 = peg$literalExpectation("-", false); + const peg$e14 = peg$classExpectation([["0", "9"]], false, false, false); + const peg$e15 = peg$classExpectation(["e", "E"], false, false, false); + const peg$e16 = peg$classExpectation(["+", "-"], false, false, false); + const peg$e17 = peg$literalExpectation("true", false); + const peg$e18 = peg$literalExpectation("false", false); + const peg$e19 = peg$literalExpectation("null", false); + const peg$e20 = peg$classExpectation([["A", "Z"], ["a", "z"], "_", "$"], false, false, false); + const peg$e21 = peg$classExpectation([["A", "Z"], ["a", "z"], ["0", "9"], "_", "$"], false, false, false); + const peg$e22 = peg$classExpectation([" ", "\t", "\r", "\n"], false, false, false); + + function peg$f0(value) { return value; } + function peg$f1(target, calls) { return expression(target, calls); } + function peg$f2(method, args) { + return { type: "Call", method, arguments: args || [] }; + } + function peg$f3(head, tail) { return [head, ...tail.map(item => item[3])]; } + function peg$f4(values) { return values || []; } + function peg$f5(value) { return JSON.parse(value); } + function peg$f6(escaped) { return escaped; } + function peg$f7(chars) { return chars.join(""); } + function peg$f8(value) { return Number(value); } + function peg$f9() { return true; } + function peg$f10() { return false; } + function peg$f11() { return null; } + function peg$f12(value) { return value; } + let peg$currPos = options.peg$currPos | 0; + let peg$savedPos = peg$currPos; + const peg$posDetailsCache = [{ line: 1, column: 1 }]; + let peg$maxFailPos = peg$currPos; + let peg$maxFailExpected = options.peg$maxFailExpected || []; + let peg$silentFails = options.peg$silentFails | 0; + + let peg$result; + + if (options.startRule) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$savedPos, peg$currPos); + } + + function offset() { + return peg$savedPos; + } + + function range() { + return { + source: peg$source, + start: peg$savedPos, + end: peg$currPos, + }; + } + + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); + } + + function expected(description, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildStructuredError( + [peg$otherExpectation(description)], + input.substring(peg$savedPos, peg$currPos), + location + ); + } + + function error(message, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildSimpleError(message, location); + } + + function peg$getUnicode(pos = peg$currPos) { + const cp = input.codePointAt(pos); + if (cp === undefined) { + return ""; + } + return String.fromCodePoint(cp); + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text, ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase, unicode) { + return { type: "class", parts, inverted, ignoreCase, unicode }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$otherExpectation(description) { + return { type: "other", description }; + } + + function peg$computePosDetails(pos) { + let details = peg$posDetailsCache[pos]; + let p; + + if (details) { + return details; + } else { + if (pos >= peg$posDetailsCache.length) { + p = peg$posDetailsCache.length - 1; + } else { + p = pos; + while (!peg$posDetailsCache[--p]) {} + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column, + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + + return details; + } + } + + function peg$computeLocation(startPos, endPos, offset) { + const startPosDetails = peg$computePosDetails(startPos); + const endPosDetails = peg$computePosDetails(endPos); + + const res = { + source: peg$source, + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column, + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column, + }, + }; + if (offset && peg$source && (typeof peg$source.offset === "function")) { + res.start = peg$source.offset(res.start); + res.end = peg$source.offset(res.end); + } + return res; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildSimpleError(message, location) { + return new peg$SyntaxError(message, null, null, location); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError( + peg$SyntaxError.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parseStart() { + let s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parse_(); + s2 = peg$parseExpression(); + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (input.charCodeAt(peg$currPos) === 59) { + s4 = peg$c0; + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s4 === peg$FAILED) { + s4 = null; + } + s5 = peg$parse_(); + peg$savedPos = s0; + s0 = peg$f0(s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseExpression() { + let s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parseIdentifier(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c1; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + s7 = peg$parseCall(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c1; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + s7 = peg$parseCall(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f1(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseCall() { + let s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parseIdentifier(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (input.charCodeAt(peg$currPos) === 40) { + s3 = peg$c2; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e2); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + s5 = peg$parseArguments(); + if (s5 === peg$FAILED) { + s5 = null; + } + s6 = peg$parse_(); + if (input.charCodeAt(peg$currPos) === 41) { + s7 = peg$c3; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + if (s7 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f2(s1, s5); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseArguments() { + let s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parseValue(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c4; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + s7 = peg$parseValue(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c4; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + s7 = peg$parseValue(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + peg$savedPos = s0; + s0 = peg$f3(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseValue() { + let s0; + + s0 = peg$parseExpression(); + if (s0 === peg$FAILED) { + s0 = peg$parseArray(); + if (s0 === peg$FAILED) { + s0 = peg$parseDoubleQuotedString(); + if (s0 === peg$FAILED) { + s0 = peg$parseSingleQuotedString(); + if (s0 === peg$FAILED) { + s0 = peg$parseNumber(); + if (s0 === peg$FAILED) { + s0 = peg$parseBoolean(); + if (s0 === peg$FAILED) { + s0 = peg$parseNull(); + } + } + } + } + } + } + + return s0; + } + + function peg$parseArray() { + let s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + s3 = peg$parseArguments(); + if (s3 === peg$FAILED) { + s3 = null; + } + s4 = peg$parse_(); + if (input.charCodeAt(peg$currPos) === 93) { + s5 = peg$c6; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e6); } + } + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f4(s3); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseDoubleQuotedString() { + let s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c7; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e7); } + } + if (s3 !== peg$FAILED) { + s4 = []; + s5 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s6 = peg$c8; + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + if (s6 !== peg$FAILED) { + if (input.length > peg$currPos) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s7 !== peg$FAILED) { + s6 = [s6, s7]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + if (s5 === peg$FAILED) { + s5 = input.charAt(peg$currPos); + if (peg$r0.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s6 = peg$c8; + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + if (s6 !== peg$FAILED) { + if (input.length > peg$currPos) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s7 !== peg$FAILED) { + s6 = [s6, s7]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + if (s5 === peg$FAILED) { + s5 = input.charAt(peg$currPos); + if (peg$r0.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + } + } + if (input.charCodeAt(peg$currPos) === 34) { + s5 = peg$c7; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e7); } + } + if (s5 !== peg$FAILED) { + s3 = [s3, s4, s5]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f5(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseSingleQuotedString() { + let s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c9; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e11); } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s4 = peg$c8; + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + if (s4 !== peg$FAILED) { + if (input.length > peg$currPos) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s5 !== peg$FAILED) { + peg$savedPos = s3; + s3 = peg$f6(s5); + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = input.charAt(peg$currPos); + if (peg$r1.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e12); } + } + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s4 = peg$c8; + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + if (s4 !== peg$FAILED) { + if (input.length > peg$currPos) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s5 !== peg$FAILED) { + peg$savedPos = s3; + s3 = peg$f6(s5); + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = input.charAt(peg$currPos); + if (peg$r1.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e12); } + } + } + } + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c9; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e11); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f7(s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseNumber() { + let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s3 = peg$c10; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e13); } + } + if (s3 === peg$FAILED) { + s3 = null; + } + s4 = peg$currPos; + s5 = []; + s6 = input.charAt(peg$currPos); + if (peg$r2.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + if (s6 !== peg$FAILED) { + while (s6 !== peg$FAILED) { + s5.push(s6); + s6 = input.charAt(peg$currPos); + if (peg$r2.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + } + } else { + s5 = peg$FAILED; + } + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s6 = peg$c1; + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + if (s6 !== peg$FAILED) { + s7 = []; + s8 = input.charAt(peg$currPos); + if (peg$r2.test(s8)) { + peg$currPos++; + } else { + s8 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + if (s8 !== peg$FAILED) { + while (s8 !== peg$FAILED) { + s7.push(s8); + s8 = input.charAt(peg$currPos); + if (peg$r2.test(s8)) { + peg$currPos++; + } else { + s8 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + } + } else { + s7 = peg$FAILED; + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = []; + s5 = input.charAt(peg$currPos); + if (peg$r2.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = input.charAt(peg$currPos); + if (peg$r2.test(s5)) { + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + } + } else { + s4 = peg$FAILED; + } + } + if (s4 !== peg$FAILED) { + s5 = peg$currPos; + s6 = input.charAt(peg$currPos); + if (peg$r3.test(s6)) { + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e15); } + } + if (s6 !== peg$FAILED) { + s7 = input.charAt(peg$currPos); + if (peg$r4.test(s7)) { + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e16); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + s8 = []; + s9 = input.charAt(peg$currPos); + if (peg$r2.test(s9)) { + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + if (s9 !== peg$FAILED) { + while (s9 !== peg$FAILED) { + s8.push(s9); + s9 = input.charAt(peg$currPos); + if (peg$r2.test(s9)) { + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + } + } else { + s8 = peg$FAILED; + } + if (s8 !== peg$FAILED) { + s6 = [s6, s7, s8]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + if (s5 === peg$FAILED) { + s5 = null; + } + s3 = [s3, s4, s5]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f8(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseBoolean() { + let s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c11) { + s1 = peg$c11; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e17); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseIdentifierPart(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = undefined; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f9(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 5) === peg$c12) { + s1 = peg$c12; + peg$currPos += 5; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseIdentifierPart(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = undefined; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f10(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + return s0; + } + + function peg$parseNull() { + let s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c13) { + s1 = peg$c13; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e19); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseIdentifierPart(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = undefined; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f11(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseIdentifier() { + let s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + s3 = input.charAt(peg$currPos); + if (peg$r5.test(s3)) { + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e20); } + } + if (s3 !== peg$FAILED) { + s4 = []; + s5 = peg$parseIdentifierPart(); + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$parseIdentifierPart(); + } + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f12(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseIdentifierPart() { + let s0; + + s0 = input.charAt(peg$currPos); + if (peg$r6.test(s0)) { + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e21); } + } + + return s0; + } + + function peg$parse_() { + let s0, s1; + + s0 = []; + s1 = input.charAt(peg$currPos); + if (peg$r7.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e22); } + } + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = input.charAt(peg$currPos); + if (peg$r7.test(s1)) { + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e22); } + } + } + + return s0; + } + + + function expression(target, calls) { + return { type: "CallChain", target, calls: calls.map(item => item[3]) }; + } + + peg$result = peg$startRuleFunction(); + + const peg$success = (peg$result !== peg$FAILED && peg$currPos === input.length); + function peg$throw() { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? peg$getUnicode(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } + if (options.peg$library) { + return /** @type {any} */ ({ + peg$result, + peg$currPos, + peg$FAILED, + peg$maxFailExpected, + peg$maxFailPos, + peg$success, + peg$throw: peg$success ? undefined : peg$throw, + }); + } + if (peg$success) { + return peg$result; + } else { + peg$throw(); + } +} + +const peg$allowedStartRules = [ + "Start" +]; + +export { + peg$allowedStartRules as StartRules, + peg$SyntaxError as SyntaxError, + peg$parse as parse +}; + diff --git a/source/teaql-ts/src/parser/query.pegjs b/source/teaql-ts/src/parser/query.pegjs new file mode 100644 index 0000000000000000000000000000000000000000..41d146e124e1c5b7c9f596797aaf1fdfd2ec5c2b --- /dev/null +++ b/source/teaql-ts/src/parser/query.pegjs @@ -0,0 +1,55 @@ +{ + function expression(target, calls) { + return { type: "CallChain", target, calls: calls.map(item => item[3]) }; + } +} + +Start + = _ value:Expression _ ";"? _ { return value; } + +Expression + = target:Identifier calls:(_ "." _ Call)+ { return expression(target, calls); } + +Call + = method:Identifier _ "(" _ args:Arguments? _ ")" { + return { type: "Call", method, arguments: args || [] }; + } + +Arguments + = head:Value tail:(_ "," _ Value)* { return [head, ...tail.map(item => item[3])]; } + +Value + = Expression + / Array + / DoubleQuotedString + / SingleQuotedString + / Number + / Boolean + / Null + +Array + = "[" _ values:Arguments? _ "]" { return values || []; } + +DoubleQuotedString + = value:$('"' ("\\" . / [^"\\])* '"') { return JSON.parse(value); } + +SingleQuotedString + = "'" chars:("\\" escaped:. { return escaped; } / [^'\\])* "'" { return chars.join(""); } + +Number + = value:$('-'? ([0-9]+ "." [0-9]+ / [0-9]+) ([eE] [+-]? [0-9]+)?) { return Number(value); } + +Boolean + = "true" !IdentifierPart { return true; } + / "false" !IdentifierPart { return false; } + +Null + = "null" !IdentifierPart { return null; } + +Identifier + = value:$([A-Za-z_$] IdentifierPart*) { return value; } + +IdentifierPart + = [A-Za-z0-9_$] + +_ = [ \t\r\n]* diff --git a/source/teaql-ts/src/sql/browser-sqlite-protocol.ts b/source/teaql-ts/src/sql/browser-sqlite-protocol.ts new file mode 100644 index 0000000000000000000000000000000000000000..1bc43481e3059d54c31c7b1497e2aafaab2e8808 --- /dev/null +++ b/source/teaql-ts/src/sql/browser-sqlite-protocol.ts @@ -0,0 +1,29 @@ +export type BrowserSQLiteStorage = 'memory' | 'opfs'; + +export type BrowserSQLiteOpenOptions = Readonly<{ + storage?: BrowserSQLiteStorage; + databaseName?: string; +}>; + +export type BrowserSQLiteRequest = Readonly<{ + type: 'teaql-browser-sqlite-request'; + requestId: number; + operation: 'open' | 'query' | 'reset' | 'close'; + payload?: Record; +}>; + +export type BrowserSQLiteResponse = Readonly<{ + type: 'teaql-browser-sqlite-response'; + requestId: number; + result?: unknown; + error?: Readonly<{ name: string; message: string; code?: string }>; +}>; + +export interface BrowserSQLiteWorkerLike { + postMessage(message: BrowserSQLiteRequest): void; + addEventListener(type: 'message', listener: (event: MessageEvent) => void): void; + addEventListener(type: 'error', listener: (event: ErrorEvent) => void): void; + removeEventListener(type: 'message', listener: (event: MessageEvent) => void): void; + removeEventListener(type: 'error', listener: (event: ErrorEvent) => void): void; + terminate?(): void; +} diff --git a/source/teaql-ts/src/sql/browser-sqlite-worker.ts b/source/teaql-ts/src/sql/browser-sqlite-worker.ts new file mode 100644 index 0000000000000000000000000000000000000000..f2155facbe264afdec74a258bb51503bd01915a8 --- /dev/null +++ b/source/teaql-ts/src/sql/browser-sqlite-worker.ts @@ -0,0 +1,140 @@ +import sqlite3InitModule from '@sqlite.org/sqlite-wasm'; +import { + BrowserSQLiteOpenOptions, + BrowserSQLiteRequest, + BrowserSQLiteResponse, +} from './browser-sqlite-protocol'; + +type WorkerScope = { + postMessage(message: BrowserSQLiteResponse): void; + addEventListener(type: 'message', listener: (event: MessageEvent) => void): void; +}; + +export type BrowserSQLiteWorkerOptions = Readonly<{ + scope?: WorkerScope; + /** Bundler-resolved URL for @sqlite.org/sqlite-wasm/sqlite3.wasm. */ + wasmUrl?: string; +}>; + +type SQLiteDatabase = { + exec(options: Record): unknown; + exec(sql: string): unknown; + changes(total?: boolean): number; + close(): void; +}; + +type SQLiteModule = { + oo1: { + DB: new (filename?: string, flags?: string) => SQLiteDatabase; + OpfsDb?: new (filename: string, flags?: string) => SQLiteDatabase; + }; +}; + +/** + * Installs the TeaQL SQLite/WASM RPC loop in the current dedicated worker. + * Call this once from an application-owned worker entry point. + */ +export function startBrowserSQLiteWorker(options: BrowserSQLiteWorkerOptions = {}): void { + const scope = options.scope ?? globalThis as unknown as WorkerScope; + let sqlitePromise: Promise | undefined; + let database: SQLiteDatabase | undefined; + let openOptions: Required | undefined; + let tail: Promise = Promise.resolve(); + + const sqlite = (): Promise => { + if (!sqlitePromise) { + const initialize = sqlite3InitModule as unknown as ( + config?: { locateFile(file: string): string }, + ) => Promise; + sqlitePromise = initialize(options.wasmUrl + ? { locateFile: (file: string) => file.endsWith('.wasm') ? options.wasmUrl! : file } + : undefined); + } + return sqlitePromise; + }; + + const open = async (options: BrowserSQLiteOpenOptions = {}): Promise => { + database?.close(); + const storage = options.storage ?? 'memory'; + const databaseName = options.databaseName ?? 'teaql-browser.sqlite3'; + const module = await sqlite(); + if (storage === 'opfs') { + if (!module.oo1.OpfsDb) { + const error = new Error( + 'OPFS SQLite is unavailable. Serve COOP/COEP headers and use a compatible browser.', + ); + error.name = 'BrowserSQLiteStorageUnavailableError'; + throw error; + } + database = new module.oo1.OpfsDb(`/${databaseName}`, 'c'); + } else { + database = new module.oo1.DB(':memory:', 'ct'); + } + openOptions = { storage, databaseName }; + database.exec('PRAGMA foreign_keys = ON'); + }; + + const requireDatabase = (): SQLiteDatabase => { + if (!database) throw new Error('Browser SQLite database is not open'); + return database; + }; + + const query = (sql: string, values: unknown[] = []): unknown => { + if (typeof sql !== 'string' || !sql.trim()) throw new TypeError('SQL is required'); + if (!Array.isArray(values)) throw new TypeError('SQL bind values must be an array'); + const db = requireDatabase(); + const rows = db.exec({ + sql, + bind: values, + rowMode: 'object', + returnValue: 'resultRows', + }) as unknown[]; + const mutation = /^\s*(?:insert|update|delete|replace)\b/i.test(sql); + return { rows, rowCount: rows.length || (mutation ? Number(db.changes()) : 0) }; + }; + + const reset = async (): Promise => { + const db = requireDatabase(); + db.exec('PRAGMA foreign_keys = OFF'); + const rows = db.exec({ + sql: "SELECT name FROM sqlite_schema WHERE type = 'table' AND name NOT LIKE 'sqlite_%'", + rowMode: 'object', + returnValue: 'resultRows', + }) as Array<{ name: unknown }>; + for (const row of rows) { + const name = String(row.name).replace(/"/g, '""'); + db.exec(`DROP TABLE IF EXISTS "${name}"`); + } + db.exec('PRAGMA foreign_keys = ON'); + if (!openOptions) throw new Error('Browser SQLite database is not open'); + }; + + scope.addEventListener('message', event => { + const request = event.data; + if (!request || request.type !== 'teaql-browser-sqlite-request') return; + tail = tail.then(async () => { + try { + let result: unknown; + if (request.operation === 'open') result = await open(request.payload as BrowserSQLiteOpenOptions); + else if (request.operation === 'query') { + result = query(String(request.payload?.sql ?? ''), (request.payload?.values ?? []) as unknown[]); + } else if (request.operation === 'reset') result = await reset(); + else if (request.operation === 'close') { database?.close(); database = undefined; } + else throw new Error(`Unsupported Browser SQLite operation: ${String(request.operation)}`); + scope.postMessage({ + type: 'teaql-browser-sqlite-response', requestId: request.requestId, result, + }); + } catch (value) { + const error = value instanceof Error ? value : new Error(String(value)); + scope.postMessage({ + type: 'teaql-browser-sqlite-response', requestId: request.requestId, + error: { + name: error.name, + message: error.message, + code: (error as Error & { code?: string }).code, + }, + }); + } + }); + }); +} diff --git a/source/teaql-ts/src/sql/browser-sqlite.ts b/source/teaql-ts/src/sql/browser-sqlite.ts new file mode 100644 index 0000000000000000000000000000000000000000..18b1333ebb55f9ec73d5f7e19a7e835da71df6e1 --- /dev/null +++ b/source/teaql-ts/src/sql/browser-sqlite.ts @@ -0,0 +1,296 @@ +import { UserContext } from '../core/context'; +import { + AbstractSQLTeaQLClient, + assertSafeIdentifier, + canonicalRelationIndexes, + ColumnSchema, + ensureOptimisticIdFloor, + EntitySchema, + LogicalColumnType, + SqlQueryResult, + SqlSession, + standardAggregateFunction, + TeaQLSqlDriver, +} from './core'; +import { + BrowserSQLiteOpenOptions, + BrowserSQLiteRequest, + BrowserSQLiteResponse, + BrowserSQLiteStorage, + BrowserSQLiteWorkerLike, +} from './browser-sqlite-protocol'; + +type PendingRequest = { + resolve(value: unknown): void; + reject(error: Error): void; +}; + +class BrowserSQLiteTransport { + private nextRequestId = 1; + private readonly pending = new Map(); + private closed = false; + + private readonly onMessage = (event: MessageEvent): void => { + const message = event.data; + if (!message || message.type !== 'teaql-browser-sqlite-response') return; + const pending = this.pending.get(message.requestId); + if (!pending) return; + this.pending.delete(message.requestId); + if (message.error) { + const error = new Error(message.error.message); + error.name = message.error.name; + if (message.error.code) (error as Error & { code?: string }).code = message.error.code; + pending.reject(error); + } else { + pending.resolve(message.result); + } + }; + + private readonly onError = (event: ErrorEvent): void => { + const error = new Error(event.message || 'Browser SQLite worker failed'); + error.name = 'BrowserSQLiteWorkerError'; + for (const pending of this.pending.values()) pending.reject(error); + this.pending.clear(); + }; + + constructor(private readonly worker: BrowserSQLiteWorkerLike) { + worker.addEventListener('message', this.onMessage); + worker.addEventListener('error', this.onError); + } + + request(operation: BrowserSQLiteRequest['operation'], payload?: Record): Promise { + if (this.closed) return Promise.reject(new Error('Browser SQLite worker is closed')); + const requestId = this.nextRequestId++; + return new Promise((resolve, reject) => { + this.pending.set(requestId, { resolve: value => resolve(value as T), reject }); + this.worker.postMessage({ + type: 'teaql-browser-sqlite-request', requestId, operation, payload, + }); + }); + } + + async close(terminateWorker: boolean): Promise { + if (this.closed) return; + try { await this.request('close'); } + finally { + this.closed = true; + this.worker.removeEventListener('message', this.onMessage); + this.worker.removeEventListener('error', this.onError); + if (terminateWorker) this.worker.terminate?.(); + const error = new Error('Browser SQLite worker is closed'); + for (const pending of this.pending.values()) pending.reject(error); + this.pending.clear(); + } + } +} + +class BrowserSQLiteSession implements SqlSession { + constructor(private readonly transport: BrowserSQLiteTransport) {} + + query(sql: string, values: any[] = []): Promise { + return this.transport.request('query', { sql, values }); + } +} + +export type BrowserSQLiteDriverOptions = BrowserSQLiteOpenOptions & Readonly<{ + terminateWorkerOnClose?: boolean; +}>; + +/** SQLite/WASM driver. SQL runs in the caller-supplied dedicated Web Worker. */ +export class BrowserSQLiteDriver implements TeaQLSqlDriver { + readonly databaseKind = 'sqlite' as const; + private accessTail: Promise = Promise.resolve(); + + private constructor( + private readonly transport: BrowserSQLiteTransport, + readonly options: Required, + ) {} + + static async open( + worker: BrowserSQLiteWorkerLike, + options: BrowserSQLiteDriverOptions = {}, + ): Promise { + const normalized: Required = { + storage: options.storage ?? 'memory', + databaseName: normalizeDatabaseName(options.databaseName ?? 'teaql-browser.sqlite3'), + terminateWorkerOnClose: options.terminateWorkerOnClose ?? true, + }; + const transport = new BrowserSQLiteTransport(worker); + await transport.request('open', normalized); + return new BrowserSQLiteDriver(transport, normalized); + } + + identifier(value: string): string { return `"${assertSafeIdentifier(value)}"`; } + placeholder(_index: number): string { return '?'; } + contains(columnSql: string, placeholder: string): string { + return `CAST(${columnSql} AS TEXT) LIKE '%' || ${placeholder} || '%'`; + } + aggregateFunction(name: string): string { return standardAggregateFunction(name); } + + encode(value: any, column?: ColumnSchema): any { + if (value === null || value === undefined) return value; + if (column?.logicalType === 'json' && typeof value !== 'string') return JSON.stringify(value); + if (column?.logicalType === 'boolean') return value ? 1 : 0; + if (value instanceof Date) return value.toISOString(); + return value; + } + + private async exclusive(work: () => Promise): Promise { + const predecessor = this.accessTail; + let release!: () => void; + this.accessTail = new Promise(resolve => { release = resolve; }); + await predecessor; + try { return await work(); } + finally { release(); } + } + + query(sql: string, values: any[] = []): Promise { + return this.exclusive(() => this.transport.request('query', { sql, values })); + } + + async *stream(sql: string, values: any[] = []): AsyncIterable { + // The first browser profile intentionally buffers. True streaming is a later capability. + const result = await this.query(sql, values); + for (const row of result.rows) yield row; + } + + transaction(work: (session: SqlSession) => Promise): Promise { + return this.exclusive(async () => { + const session = new BrowserSQLiteSession(this.transport); + await session.query('BEGIN IMMEDIATE'); + try { + const result = await work(session); + await session.query('COMMIT'); + return result; + } catch (error) { + try { await session.query('ROLLBACK'); } catch { /* preserve the business error */ } + throw error; + } + }); + } + + async ensureSchema(schemas: Record): Promise { + for (const schema of Object.values(schemas)) { + const table = this.identifier(schema.table); + await this.query( + `CREATE TABLE IF NOT EXISTS ${table} (` + + '"id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)', + ); + const columns = await this.query(`PRAGMA table_info(${table})`); + const existing = new Set(columns.rows.map(row => String(row.name))); + for (const [field, column] of Object.entries(schema.columns)) { + if (field === 'id' || field === 'version' || existing.has(column.columnName)) continue; + await this.query( + `ALTER TABLE ${table} ADD COLUMN ` + + `${this.identifier(column.columnName)} ${sqliteType(column.logicalType)}` + + `${column.nullable === false ? ' NOT NULL' : ''}`, + ); + } + } + for (const index of canonicalRelationIndexes(schemas)) { + await this.query( + `CREATE INDEX IF NOT EXISTS ${this.identifier(index.name)} ON ` + + `${this.identifier(index.table)} (` + + `${this.identifier(index.foreignColumn)}, ${this.identifier(index.idColumn)} DESC)`, + ); + } + await this.query( + 'CREATE TABLE IF NOT EXISTS teaql_id_space (' + + 'type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)', + ); + } + + async nextId(session: SqlSession, entity: string): Promise { + for (let attempt = 1; attempt <= 100; attempt += 1) { + const current = await session.query( + 'SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?', [entity], + ); + if (!current.rowCount) { + try { + const inserted = await session.query( + 'INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)', [entity], + ); + if (inserted.rowCount === 1) return '1'; + } catch (error) { + const winner = await session.query( + 'SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?', [entity], + ); + if (!winner.rowCount) throw error; + } + continue; + } + const previous = Number(current.rows[0].id); + const next = previous + 1; + const updated = await session.query( + 'UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?', + [next, entity, previous], + ); + if (updated.rowCount === 1) return String(next); + if (updated.rowCount !== 0) { + throw new Error(`ID space update for ${entity} changed ${updated.rowCount} rows`); + } + } + throw new Error(`Unable to allocate ID for ${entity} after 100 optimistic-lock attempts`); + } + + ensureIdFloor(session: SqlSession, entity: string, floor: string): Promise { + return ensureOptimisticIdFloor(session, index => this.placeholder(index), entity, floor); + } + + reset(): Promise { + return this.exclusive(() => this.transport.request('reset', this.options)); + } + + close(): Promise { + return this.exclusive(() => this.transport.close(this.options.terminateWorkerOnClose)); + } +} + +/** TeaQL SQL client for browser-local SQLite/WASM. */ +export class BrowserSQLiteTeaQLClient extends AbstractSQLTeaQLClient { + private constructor(private readonly browserDriver: BrowserSQLiteDriver, + schemas: Record) { + super(browserDriver, schemas); + } + + static async open( + worker: BrowserSQLiteWorkerLike, + schemas: Record, + options: BrowserSQLiteDriverOptions = {}, + ): Promise { + return new BrowserSQLiteTeaQLClient(await BrowserSQLiteDriver.open(worker, options), schemas); + } + + get storage(): BrowserSQLiteStorage { + return this.browserDriver.options.storage; + } + + /** Drops browser-local data, then explicitly reconciles schema and generated bootstrap data. */ + async reset(context: UserContext): Promise { + await this.browserDriver.reset(); + this.invalidateSchemaState(); + await context.ensureSchema(); + } +} + +function sqliteType(type: LogicalColumnType): string { + const types: Record = { + boolean: 'INTEGER', double: 'REAL', decimal: 'NUMERIC', date: 'TEXT', + datetime: 'TEXT', json: 'TEXT', integer: 'INTEGER', text: 'TEXT', + }; + return types[type]; +} + +function normalizeDatabaseName(value: string): string { + const normalized = value.trim(); + if (!normalized || normalized.includes('/') || normalized.includes('\\') || normalized === '.' || normalized === '..') { + throw new TypeError('Browser SQLite databaseName must be a simple file name'); + } + return normalized; +} + +export type { + BrowserSQLiteOpenOptions, + BrowserSQLiteStorage, + BrowserSQLiteWorkerLike, +} from './browser-sqlite-protocol'; diff --git a/source/teaql-ts/src/sql/core.ts b/source/teaql-ts/src/sql/core.ts new file mode 100644 index 0000000000000000000000000000000000000000..30f8b6e60282289ff5a2ebb0b2cebe1e662ed464 --- /dev/null +++ b/source/teaql-ts/src/sql/core.ts @@ -0,0 +1,2042 @@ +import { + observeRuntimeOperation, + RuntimeTelemetry, + RuntimeExecutionCorrelation, + RuntimeTelemetryScope, + startRuntimeOperation, +} from '../core/telemetry'; +import { CheckException, EntityChecker } from '../core/checker'; +import { UserContext } from '../core/context'; +import { mergeRuntimeBootstrap } from '../core/runtime-module'; +import type { BootstrapEntity, RuntimeBootstrap } from '../core/runtime-module'; +import { contextSchemaCapability } from '../core/schema-capability'; +import { OrderBy, SelectQuery } from '../core/ast'; +import { GraphCommittedError, GraphMutationSession, MutationIntent, MutationRequest, QueryIntent, QueryRequest } from '../core/request-intent'; +import type { QueryOperation } from '../core/request-intent'; +import { canonicalSQLTracePath, cloneTraceNodes, queryTraceSource, TraceNode } from '../core/trace-chain'; +import { projectSQLLog, projectSafeSQLLog, logValueStrings, scrubLogText, credentialName, inheritSQLLogBindings, retainSQLLogProvenance } from '../core/log-privacy'; +import { sqlDiagnosticEvent } from '../core/sql-diagnostic-event'; +import { telemetryNotice } from '../core/telemetry-startup'; +import type { SQLLogBindingSource } from '../core/log-privacy'; +import { SQLDatabaseKind, SQLParameterLogPolicy } from './log-rendering'; +import { queryDiagnosticOrigin, retainQueryDiagnosticOrigin } from '../core/query-snapshot'; +import { executeRelationFacets } from '../core/facet'; +import type { FacetAggregate } from '../core/facet'; +import { SmartList } from '../core/smart-list'; + +export type LogicalColumnType = + | 'boolean' + | 'double' + | 'decimal' + | 'date' + | 'datetime' + | 'json' + | 'integer' + | 'text'; + +export type ColumnSchema = { + columnName: string; + modelName?: string; + logicalType: LogicalColumnType; + decode: 'string' | 'number' | 'date' | 'native'; + nullable?: boolean; + /** Trusted model/application log policy, never taken from a query payload. */ + logPolicy?: SQLParameterLogPolicy; +}; + +export type EntitySchema = { + table: string; + columns: Record; + relations?: Record; + auditMaskFields?: readonly string[]; +}; + +export type RelationSchema = { + targetEntity: string; + localKey: string; + foreignKey: string; + many: boolean; +}; + +export type CanonicalRelationIndex = { + name: string; + table: string; + foreignColumn: string; + idColumn: string; +}; + +/** Canonical index for recent-child Top-N. Custom ordering needs an explicit model index. */ +export function canonicalRelationIndexes( + schemas: Record, +): CanonicalRelationIndex[] { + const indexes = new Map(); + for (const schema of Object.values(schemas)) { + for (const relation of Object.values(schema.relations || {})) { + if (!relation.many) continue; + const target = schemas[relation.targetEntity]; + const foreignColumn = target?.columns[relation.foreignKey]?.columnName; + const idColumn = target?.columns.id?.columnName; + if (!target || !foreignColumn || !idColumn) continue; + const raw = `idx_${target.table}_${foreignColumn}_${idColumn}`; + let hash = 2166136261; + for (let i = 0; i < raw.length; i += 1) { + hash = Math.imul(hash ^ raw.charCodeAt(i), 16777619); + } + const suffix = (hash >>> 0).toString(36); + const name = raw.length <= 30 + ? raw + : `${raw.slice(0, Math.max(1, 29 - suffix.length))}_${suffix}`; + indexes.set(name, { name, table: target.table, foreignColumn, idColumn }); + } + } + return [...indexes.values()]; +} + +export type SqlQueryResult = { + rows: any[]; + rowCount: number; +}; + +export type MutationResult = { + success: boolean; + id: string; + version?: number; + deleted?: boolean; + persistedRecord?: Record; + /** Trusted internal result; use policy projection before diagnostics. */ + metadata?: SQLExecutionMetadata; +}; + +export interface SqlSession { + query(sql: string, values?: any[]): Promise; +} + +export interface TeaQLSqlDriver extends SqlSession { + readonly databaseKind: SQLDatabaseKind; + readonly topNRelationPlanPolicy?: 'window' | 'alwaysProbe'; + stream(sql: string, values?: any[]): AsyncIterable; + identifier(value: string): string; + placeholder(index: number): string; + encode(value: any, column?: ColumnSchema): any; + contains(columnSql: string, placeholder: string): string; + aggregateFunction(name: string): string; + ensureSchema(schemas: Record): Promise; + transaction(work: (session: SqlSession) => Promise): Promise; + nextId(session: SqlSession, entity: string): Promise; + ensureIdFloor(session: SqlSession, entity: string, floor: string): Promise; + close(): Promise; +} + +export async function ensureOptimisticIdFloor( + session: SqlSession, + placeholder: (index: number) => string, + entity: string, + floor: string, +): Promise { + const numericFloor = Number(floor); + if (!Number.isSafeInteger(numericFloor) || numericFloor < 0) { + throw new Error(`Invalid ID space floor ${floor} for ${entity}`); + } + for (let attempt = 1; attempt <= 100; attempt += 1) { + const currentResult = await session.query( + `SELECT current_level AS id FROM teaql_id_space WHERE type_name = ${placeholder(1)}`, + [entity], + ); + if (!currentResult.rowCount) { + try { + const inserted = await session.query( + `INSERT INTO teaql_id_space(type_name, current_level) VALUES (${placeholder(1)}, ${placeholder(2)})`, + [entity, numericFloor], + ); + if (inserted.rowCount === 1) return; + } catch (error) { + const winner = await session.query( + `SELECT current_level FROM teaql_id_space WHERE type_name = ${placeholder(1)}`, + [entity], + ); + if (!winner.rowCount) throw error; + } + continue; + } + const current = Number(currentResult.rows[0].id); + if (current >= numericFloor) return; + const updated = await session.query( + `UPDATE teaql_id_space SET current_level = ${placeholder(1)} ` + + `WHERE type_name = ${placeholder(2)} AND current_level = ${placeholder(3)}`, + [numericFloor, entity, current], + ); + if (updated.rowCount === 1) return; + if (updated.rowCount !== 0) throw new Error( + `ID space floor update for ${entity} changed ${updated.rowCount} rows on attempt ${attempt}`); + } + throw new Error( + `Unable to synchronize ID space floor for ${entity} after 100 optimistic-lock attempts`); +} + +function sameBootstrapValue(left: unknown, right: unknown): boolean { + if (left === right) return true; + if (left instanceof Date) left = left.getTime(); + if (right instanceof Date) right = right.getTime(); + return left !== null && left !== undefined && right !== null && right !== undefined && + String(left) === String(right); +} + +export interface TeaQLDataService { + withQueryRequest?(query: SelectQuery, work: () => Promise): Promise; + executeGraphSave(intent: MutationIntent, work: (graph: GraphMutationSession) => Promise): Promise; + preflightMutation(mutation: any): any; + afterGraphCommit(work: () => void): void; + afterGraphRollback(work: () => void): void; + executeMutation(mutation: any): Promise; + executeQuery(query: any): Promise; + executeCount(query: any, alias?: string, operation?: QueryOperation): Promise; + executeForStream(query: any, chunkSize?: number): AsyncIterable; + executeFacetMembership?(outerQuery: any, relationName: string, countAliases?: readonly string[]): Promise>; + close?(): Promise; +} + +export type SQLExecutionOperation = 'select' | 'insert' | 'update' | 'delete'; +/** Statement/cursor completion, not transaction commit or business success. */ +export type SQLExecutionOutcome = 'success' | 'failure' | 'cancelled'; + +type SQLLogIntent = { comment?: string; purpose?: string; auditReason?: string; tracePath?: readonly SQLTraceFrame[]; + traceChain?: readonly TraceNode[]; + mutationLineage?: readonly TraceNode[]; + inheritedBindings?: SQLLogBindingSource; + /** Compiler-only target ID for free-text projection; never included in log metadata. */ + targetID?: unknown }; + +export type SQLTraceFrame = TraceNode & Readonly<{ + level: number; +}>; + +function sqlTraceFrames(source: readonly TraceNode[]): readonly SQLTraceFrame[] { + return Object.freeze(source.map((node, level) => Object.freeze({ ...node, level }))); +} + +function mutationLogIntent(request: MutationRequest, mutation: any, provider: string, + operation: SQLExecutionOperation, id: string, localBindings: SQLLogBindingSource): SQLLogIntent { + const lineage = request.traceFor({ entity: String(mutation.entity), id }); + const path = canonicalSQLTracePath([...lineage, { kind: 'entity', name: String(mutation.entity), + entityId: id, detail: '' }], provider, operation); + return { auditReason: request.comment, tracePath: sqlTraceFrames(path.tracePath), + mutationLineage: lineage, targetID: id, + inheritedBindings: inheritSQLLogBindings(localBindings, request.graphSession?.logBindings) }; +} + +export type SQLExecutionMetadata = Readonly<{ + /** Ordered physical children of a logical mutation result. */ + statements?: readonly SQLExecutionMetadata[]; + operation: SQLExecutionOperation; + executionOutcome?: SQLExecutionOutcome; + comment?: string; + purpose?: string; + auditReason?: string; + /** Business intent lineage: root purpose followed by each request's comment. */ + traceChain?: readonly TraceNode[]; + /** Physical execution route: operation/request/relation/provider/sql. */ + tracePath: readonly SQLTraceFrame[]; + /** Business responsibility, not the physical SQL route. */ + mutationLineage?: readonly TraceNode[]; + parameterizedSQL: string; + parameters: readonly unknown[]; + /** SQL with bind values rendered as literals, intended only for diagnostics. */ + debugSQL: string; + databaseKind?: SQLDatabaseKind; + parameterLogPolicies?: readonly SQLParameterLogPolicy[]; + /** Set by the runtime SQL compiler, not by the incoming Q/TFP request. */ + sqlOrigin?: 'generated'; + maskedParameters?: readonly boolean[]; + logMode?: 'masked' | 'debug-plaintext'; + omissionReason?: 'untrusted-literal-sql' | 'policy-count-mismatch' | 'unsupported-or-mismatched-bindings'; + elapsedMicros: number; + resultCount?: number; + affectedRows?: number; + resultSummary: string; +}>; + +export { debugSQL } from './log-rendering'; +export type { SQLDatabaseKind } from './log-rendering'; + +export interface RuntimeTelemetrySink { + record(metadata: SQLExecutionMetadata): void; +} + +/** + * Policy-projected SQL diagnostic surface. Values are redacted by default; + * selecting a custom sink does not grant plaintext access. + */ +export interface DiagnosticSQLLogSink { + write(metadata: SQLExecutionMetadata): void; +} + +export class TextDiagnosticSQLLogSink implements DiagnosticSQLLogSink { + constructor(private readonly writer: (text: string) => void = text => console.debug(text)) {} + + write(metadata: SQLExecutionMetadata): void { + metadata = projectSQLLog(metadata); + this.writer( + `[TeaQL SQL][${metadata.operation}][${metadata.elapsedMicros}us] ${metadata.resultSummary}` + + `${metadata.executionOutcome ? ` outcome=${metadata.executionOutcome}` : ''}\n` + + `comment=${metadata.comment ?? ''} purpose=${metadata.purpose ?? ''} ` + + `auditReason=${metadata.auditReason ?? ''} tracePath=${diagnosticJSON(metadata.tracePath)}` + + ` traceChain=${diagnosticJSON(metadata.traceChain ?? [])}` + + ` mutationLineage=${diagnosticJSON(metadata.mutationLineage ?? [])}\n` + + (metadata.omissionReason ? `SQL omitted: ${metadata.omissionReason}\n` : '') + + `Debug SQL: ${metadata.debugSQL}`, + ); + } +} + +function diagnosticJSON(value: unknown): string { + return JSON.stringify(value, (_key, item) => + typeof item === 'bigint' ? item.toString() : item); +} + +export class SQLExecutionEvidenceStore implements RuntimeTelemetrySink { + private mode: 'all' | 'select' | 'mutation' | 'disabled' = 'all'; + private entries: SQLExecutionMetadata[] = []; + + record(metadata: SQLExecutionMetadata): void { + const isSelect = metadata.operation === 'select'; + if (this.mode === 'disabled' || + (this.mode === 'select' && !isSelect) || + (this.mode === 'mutation' && isSelect)) return; + this.entries.push(Object.freeze({ + ...metadata, + ...(metadata.traceChain ? { traceChain: cloneTraceNodes(metadata.traceChain) } : {}), + parameters: Object.freeze([...metadata.parameters]), + })); + } + + private setMode(mode: 'all' | 'select' | 'mutation' | 'disabled'): this { + this.mode = mode; + this.entries = []; + return this; + } + + enableAll(): this { return this.setMode('all'); } + enableSelect(): this { return this.setMode('select'); } + enableMutation(): this { return this.setMode('mutation'); } + disable(): this { return this.setMode('disabled'); } + snapshot(): readonly SQLExecutionMetadata[] { return [...this.entries]; } +} + +type NormalizedAggregate = { func: string; field: string; retName: string }; +type NormalizedOrder = { field: string; direction: string }; +// Private to one relation load. Keys never enter records, wire requests, +// mutation state or UserContext; null hydration cannot erase membership. +type RelationAssembly = { field: string; keys: WeakMap }; + +export abstract class AbstractSQLTeaQLClient implements TeaQLDataService { + private schemaReady?: Promise; + private bootstrapTail: Promise = Promise.resolve(); + public readonly sqlTrace: string[] = []; + private readonly internalQueryToken = Symbol('teaql-internal-query'); + private readonly bindLogPolicies = new WeakMap(); + // Compiler-owned operands before LIKE decoration, never SQL parameters or + // serialized metadata. Lifetime follows this execution's binding array. + private readonly bindOperandSources = new WeakMap(); + private readonly derivedQueryBindings = new WeakMap(); + private readonly derivedRelationAssembly = new WeakMap(); + + private fieldLogPolicy(schema: EntitySchema, field: string): SQLParameterLogPolicy { + const column = schema.columns[field]; + const name = column?.modelName ?? column?.columnName ?? field; + if (credentialName(name) || credentialName(field)) return 'credential'; + if (!schema.auditMaskFields) return 'unknown'; + if (schema.auditMaskFields?.includes(name) || schema.auditMaskFields?.includes(field)) return 'masked'; + return column?.logPolicy ?? 'unknown'; + } + + private bindValue(values: any[], value: unknown, policy: SQLParameterLogPolicy, sourceOperand?: string): void { + const policies = this.bindLogPolicies.get(values) ?? values.map(() => 'unknown' as const); + values.push(value); + policies.push(policy); + this.bindLogPolicies.set(values, policies); + if (sourceOperand !== undefined) { + this.bindOperandSources.set(values, inheritSQLLogBindings({ + parameterizedSQL: '', parameters: [sourceOperand], parameterLogPolicies: [policy], sqlOrigin: 'generated', + }, this.bindOperandSources.get(values))); + } + } + + private queryLogBindings(sql: string, values: readonly unknown[]): SQLLogBindingSource { + return inheritSQLLogBindings({ parameterizedSQL: sql, parameters: values, + parameterLogPolicies: this.bindLogPolicies.get(values), sqlOrigin: 'generated' }, this.bindOperandSources.get(values)); + } + private readonly auditEvents: Readonly>[] = []; + private auditSink?: (event: Readonly>) => void | Promise; + private telemetrySink?: RuntimeTelemetrySink; + private diagnosticSQLLogSink?: DiagnosticSQLLogSink = new TextDiagnosticSQLLogSink(); + private queryLoggingEnabled = true; + private mutationLoggingEnabled = true; + private runtimeTelemetry?: RuntimeTelemetry; + private telemetryStartup?: Promise; + private standardTelemetryHandle?: import('../telemetry/standard-node').StandardTelemetryHandle; + private customTelemetry = false; + private readonly checkers: Record = {}; + private userContext = new UserContext(); + private bootstrap: RuntimeBootstrap = {}; + private graphMutationSession?: SqlSession; + private activeGraph?: GraphMutationSession; + private graphAuditActions: Array<() => Promise> = []; + private graphCommitActions: Array<() => void> = []; + private graphRollbackActions: Array<() => void> = []; + private graphSaveTail: Promise = Promise.resolve(); + private readonly schemas: Record; + + protected constructor( + protected readonly driver: TeaQLSqlDriver, + schemas: Record, + ) { this.schemas = { ...schemas }; } + + /** Installs metadata only. Call context.ensureSchema() explicitly when schema changes are intended. */ + install(module: import('../core/runtime-module').RuntimeModule): this { + Object.assign(this.schemas, module.schemas); + Object.assign(this.checkers, module.checkers); + this.bootstrap = mergeRuntimeBootstrap(this.bootstrap, module.bootstrap); + return this; + } + + setUserContext(context: UserContext): this { this.userContext = context; return this; } + + private schema(entity: string): EntitySchema { + const schema = this.schemas[entity]; + if (!schema) throw new Error(`Unknown TeaQL entity: ${entity}`); + return schema; + } + + private toRuntimeMutationRecord( + schema: EntitySchema, + canonicalRecord: Record, + ): Record { + const result: Record = {}; + for (const [canonicalName, value] of Object.entries(canonicalRecord)) { + const runtimeName = schema.columns[canonicalName] + ? canonicalName + : Object.keys(schema.columns).find( + name => schema.columns[name].modelName === canonicalName || + schema.columns[name].columnName === canonicalName, + ); + if (runtimeName) result[runtimeName] = value; + } + return result; + } + + private encode(value: any, column?: ColumnSchema): any { + const normalized = value?.id ?? value; + if (normalized === undefined) return undefined; + return this.driver.encode(normalized, column); + } + + private decodeRow(entity: string, row: any, aggregateNames: string[] = []): any { + const schema = this.schema(entity); + const result = { ...row }; + for (const [field, column] of Object.entries(schema.columns)) { + const value = result[field]; + if (value === null || value === undefined) continue; + if (column.decode === 'number') result[field] = Number(value); + if (column.decode === 'string') result[field] = String(value); + if (column.decode === 'date' && value instanceof Date) { + result[field] = value.toISOString(); + } + if (column.logicalType === 'boolean') result[field] = Boolean(value); + } + for (const name of aggregateNames) { + if (result[name] !== null && result[name] !== undefined) { + result[name] = Number(result[name]); + } + } + return result; + } + + get auditTrace(): ReadonlyArray>> { + return [...this.auditEvents]; + } + + setAuditSink(sink: (event: Readonly>) => void | Promise): this { + this.auditSink = sink; + return this; + } + + setRuntimeTelemetrySink(sink: RuntimeTelemetrySink | undefined): this { + this.telemetrySink = sink; + return this; + } + + setDiagnosticSQLLogSink(sink: DiagnosticSQLLogSink | undefined): this { + this.diagnosticSQLLogSink = sink; + return this; + } + + setQueryLoggingEnabled(enabled: boolean): this { + this.queryLoggingEnabled = enabled; + return this; + } + + setMutationLoggingEnabled(enabled: boolean): this { + this.mutationLoggingEnabled = enabled; + return this; + } + + setRuntimeTelemetry(telemetry: RuntimeTelemetry | undefined): this { + this.customTelemetry = true; + this.runtimeTelemetry = telemetry; + return this; + } + + /** Node provider startup hook. Optional module initialization remains fail-open. */ + protected attachStandardTelemetryStartup( + startup: Promise, + ): void { + this.telemetryStartup = startup.then(async handle => { + if (!handle) return; + if (this.customTelemetry) { await handle.release(); return; } + this.standardTelemetryHandle = handle; + this.runtimeTelemetry = handle.telemetry; + }).catch(() => { telemetryNotice('TeaQL telemetry: initialization failed; business continues without export.', true); }); + } + + async flushTelemetry(): Promise { + await this.telemetryStartup; + try { await this.standardTelemetryHandle?.flush(); } + catch { telemetryNotice('TeaQL telemetry: export flush failed; business outcome unchanged.', true); } + } + + async withQueryRequest(query: SelectQuery, work: () => Promise): Promise { + new QueryRequest(query); // Reject invalid intent before starting execution. + await this.telemetryStartup; + return observeRuntimeOperation(this.runtimeTelemetry, { family: 'query', + name: `${String(query.entity)}.request`, attributes: { 'teaql.entity.type': String(query.entity) } }, work); + } + + private recordSQL( + operation: SQLExecutionOperation, parameterizedSQL: string, parameters: readonly unknown[], + startedAt: number, resultCount?: number, affectedRows?: number, + intent: SQLLogIntent = {}, + executionOutcome: SQLExecutionOutcome = 'success', + inherited?: SQLLogBindingSource, + correlation?: RuntimeExecutionCorrelation, + ): SQLExecutionMetadata { + const isSelect = operation === 'select'; + const logsEnabled = isSelect ? this.queryLoggingEnabled : this.mutationLoggingEnabled; + const { targetID, inheritedBindings, ...visibleIntent } = intent; + const metadata = Object.freeze({ + operation, ...visibleIntent, executionOutcome, + traceChain: cloneTraceNodes(intent.traceChain ?? []), + tracePath: sqlTraceFrames(intent.tracePath ?? []), + ...(intent.traceChain ? { traceChain: cloneTraceNodes(intent.traceChain) } : {}), + ...(intent.mutationLineage ? { mutationLineage: cloneTraceNodes(intent.mutationLineage) } : {}), + parameterizedSQL, parameters: Object.freeze([...parameters]), + // Never build a plaintext SQL copy before the log policy boundary. + debugSQL: '', databaseKind: this.driver.databaseKind, sqlOrigin: 'generated' as const, + parameterLogPolicies: Object.freeze([...(this.bindLogPolicies.get(parameters) ?? parameters.map(() => 'unknown' as const))]), + elapsedMicros: Math.max(0, (Date.now() - startedAt) * 1_000), + resultCount, affectedRows, + resultSummary: resultCount !== undefined + ? `${resultCount} rows returned` : affectedRows !== undefined ? `${affectedRows} rows affected` + : `statement ${executionOutcome}; row count unknown`, + }); + const ancestors = inheritedBindings && inherited + ? inheritSQLLogBindings(inherited, inheritedBindings) : inheritedBindings ?? inherited; + const operands = this.bindOperandSources.get(parameters); + const provenance = operands ? inheritSQLLogBindings(operands, ancestors) : ancestors; + retainSQLLogProvenance(metadata, provenance, targetID === undefined ? [] : [targetID]); + if (this.runtimeTelemetry?.recordDiagnostic) { + try { + if (this.runtimeTelemetry.recordsSQLDiagnostics?.() !== false) + this.runtimeTelemetry.recordDiagnostic(sqlDiagnosticEvent(projectSafeSQLLog(metadata), correlation)); + } + catch { telemetryNotice('TeaQL telemetry: SQL diagnostic rejected; business outcome unchanged.', true); } + } + if (!this.telemetrySink && !(logsEnabled && this.diagnosticSQLLogSink)) return metadata; + try { + const projected = projectSQLLog(metadata); + // Runtime diagnostics are fail-open and each sink is independent. A + // broken application sink must not roll back a successful SQL mutation. + try { this.telemetrySink?.record(projected); } catch { /* diagnostic sink failed */ } + if (logsEnabled) { + try { this.diagnosticSQLLogSink?.write(projected); } catch { /* diagnostic sink failed */ } + } + } catch { /* projection failure must not alter database execution */ } + return metadata; + } + + private queryLogIntent(query: any): SQLLogIntent { + const request = new QueryRequest(query); + const path = canonicalSQLTracePath(request.traceSource, this.driver.databaseKind, 'select'); + return { comment: request.intent.comment, purpose: request.purpose, + traceChain: request.traceChain, tracePath: sqlTraceFrames(path.tracePath) }; + } + + private async executeLoggedSQL( + operation: SQLExecutionOperation, sql: string, values: any[], + intent: SQLLogIntent, + execute: () => Promise, + inherited?: SQLLogBindingSource, + statements?: SQLExecutionMetadata[], + ): Promise { + await this.telemetryStartup; + const scope = startRuntimeOperation(this.runtimeTelemetry, { family: 'provider', + name: `${this.driver.databaseKind}.${operation}`, + attributes: { 'teaql.provider.kind': this.driver.databaseKind, + 'teaql.provider.operation': operation === 'select' ? 'query' : operation } }); + const correlation = scope.correlation?.(); + const startedAt = Date.now(); + let result: SqlQueryResult; + try { result = await (scope.run ? scope.run(execute) : execute()); } + catch (error) { + // No exception text/cause/driver object enters a diagnostic sink. Preserve + // the original error for the caller, even if a sink itself is broken. + try { + const metadata = this.recordSQL(operation, sql, values, startedAt, undefined, undefined, intent, 'failure', inherited, correlation); + statements?.push(metadata); + } + finally { scope.failure(error); throw error; } + } + const metadata = this.recordSQL(operation, sql, values, startedAt, + operation === 'select' ? result.rowCount : undefined, + operation === 'select' ? undefined : result.rowCount, intent, 'success', inherited, correlation); + statements?.push(metadata); + scope.success({ attributes: { 'teaql.result.cardinality': result.rowCount } }); + return result; + } + + /** Package-internal physical capability used only by UserContext.ensureSchema(). */ + async [contextSchemaCapability](context: UserContext): Promise { + await this.telemetryStartup; + if (!this.schemaReady) { + this.schemaReady = this.driver.ensureSchema(this.schemas); + } + await this.schemaReady; + const predecessor = this.bootstrapTail; + let release!: () => void; + this.bootstrapTail = new Promise(resolve => { release = resolve; }); + await predecessor; + this.userContext = context; + const previousActor = context.getResource('bootstrapActor'); + const previousCategory = context.getResource('bootstrapCategory'); + context.insertResource('bootstrapActor', 'teaql-generated-bootstrap'); + context.insertResource('bootstrapCategory', 'runtime-bootstrap'); + try { + if (this.bootstrap.ensure) { + await this.bootstrap.ensure(context); + } else { + await this.ensureBootstrapData(); + } + } finally { + if (previousActor === undefined) context.removeResource('bootstrapActor'); + else context.insertResource('bootstrapActor', previousActor); + if (previousCategory === undefined) context.removeResource('bootstrapCategory'); + else context.insertResource('bootstrapCategory', previousCategory); + release(); + } + } + + /** Allows a provider which replaces its physical store to require explicit schema reconciliation again. */ + protected invalidateSchemaState(): void { + this.schemaReady = undefined; + } + + private async ensureBootstrapData(): Promise { + const records = [ + ...(this.bootstrap.defaultDomainRoot ? [this.bootstrap.defaultDomainRoot] : []), + ...(this.bootstrap.constants ?? []), + ]; + if (!records.length) return; + await this.executeGraphSave(new MutationIntent('reconcile model bootstrap data'), async graph => { + const session = this.graphMutationSession!; + const planned: Array<{ record: BootstrapEntity; request: MutationRequest }> = []; + for (const record of records) { + const mutation = await this.planBootstrapMutation(session, record); + if (mutation) planned.push({ record, request: graph.request(mutation) }); + } + for (const { request } of planned) this.preflightMutation(request); + for (const { request } of planned) await this.executeMutation(request); + for (const record of records) await this.driver.ensureIdFloor(session, record.entity, record.id); + }); + } + + private async planBootstrapMutation(session: SqlSession, record: BootstrapEntity): Promise { + const schema = this.schema(record.entity); + const entries = Object.entries(record.values ?? {}).map(([field, value]) => { + const column = schema.columns[field]; + if (!column) throw new Error(`Unknown bootstrap field ${record.entity}.${field}`); + return { + column: column.columnName, + value: this.driver.encode(value, column), + }; + }); + const query = new SelectQuery(record.entity).filter({ id: { $eq: record.id } }).limit(1) + .comment('inspect model bootstrap record').purpose('ensure model-defined root and constants'); + query.prepareForList(); + const request = new QueryRequest(query); + // Reconciliation must see an existing tombstone too. Normal list SQL adds + // version > 0 and would attempt a duplicate INSERT for a deleted constant. + // This fixed primary-key lookup still owns validated query intent and logs. + const sql = `SELECT * FROM ${this.driver.identifier(schema.table)} WHERE ` + + `${this.driver.identifier(schema.columns.id?.columnName ?? 'id')} = ${this.driver.placeholder(1)}`; + const values = [record.id]; + this.bindLogPolicies.set(values, [this.fieldLogPolicy(schema, 'id')]); + const current = await this.executeLoggedSQL('select', sql, values, this.queryLogIntent(request.query), + () => session.query(sql, values)); + if (!current.rowCount) { + return { entity: record.entity, action: 'Create', id: record.id, version: 0, + payload: { ...record.values } }; + } + const row = current.rows[0]; + const changed = entries.filter(entry => !sameBootstrapValue(row[entry.column], entry.value)); + if (!changed.length) return undefined; + // Checker sees the fully loaded object, not a partial update projection. + return { entity: record.entity, action: 'Update', id: record.id, + version: Number(row[schema.columns.version?.columnName ?? 'version']), + payload: { ...this.decodeRowForSchema(schema, row), ...record.values } }; + } + + async executeGraphSave(intent: MutationIntent, work: (graph: GraphMutationSession) => Promise): Promise { + // Root intent is mandatory before lifecycle initialization or provider work. + const graph = new GraphMutationSession(intent); + await this.telemetryStartup; + const save = async () => { + // Generated child saves call their within-graph entry point directly. Every + // public/root save comes through here and is queued, so an unrelated async + // save cannot accidentally join another graph's transaction merely because + // this client currently has an active session. + const predecessor = this.graphSaveTail; + let release!: () => void; + this.graphSaveTail = new Promise(resolve => { release = resolve; }); + await predecessor; + let fixEvidenceStarted = false; + let mutationPolicyGraphStarted = false; + let committed = false; + try { + this.graphCommitActions = []; + this.graphRollbackActions = []; + this.graphAuditActions = []; + this.userContext.insertResource('fixTime', new Date()); + this.userContext.beginFixEvidence(); + fixEvidenceStarted = true; + this.userContext.beginMutationPolicyGraph(); + mutationPolicyGraphStarted = true; + const result = await this.driver.transaction(async session => { + this.graphMutationSession = session; + this.activeGraph = graph; + try { + const value = await work(graph); + this.userContext.ensureMutationPolicyGraphComplete(); + return value; + } + finally { this.graphMutationSession = undefined; this.activeGraph = undefined; } + }); + committed = true; + let failure: unknown; + let failed = false; + // Cleanup and other audit events must continue after one sink fails. + for (const action of [...this.graphCommitActions, ...this.graphAuditActions]) { + try { await action(); } catch (error) { if (!failed) failure = error; failed = true; } + } + if (failed) throw new GraphCommittedError(failure); + return result; + } catch (error) { + if (!committed) { + // Keep the original execution failure even if a restore callback fails. + for (const action of [...this.graphRollbackActions].reverse()) { + try { action(); } catch { /* independent rollback restorations continue */ } + } + } + throw error; + } finally { + this.graphCommitActions = []; + this.graphRollbackActions = []; + this.graphAuditActions = []; + if (mutationPolicyGraphStarted) this.userContext.endMutationPolicyGraph(); + this.userContext.removeResource('fixTime'); + if (fixEvidenceStarted) this.userContext.finishFixEvidence(); + release(); + } + }; + return observeRuntimeOperation(this.runtimeTelemetry, { family: 'mutation', name: 'graph.save', + attributes: { 'teaql.entity.type': 'graph', 'teaql.mutation.kind': 'graph' } }, save); + } + + afterGraphCommit(work: () => void): void { + if (!this.graphMutationSession) throw new Error('No graph save is active'); + this.graphCommitActions.push(work); + } + + afterGraphRollback(work: () => void): void { + if (!this.graphMutationSession) throw new Error('No graph save is active'); + this.graphRollbackActions.push(work); + } + + private requireGraphOwnership(request: MutationRequest): void { + if (request.graphSession !== this.activeGraph || + (this.graphMutationSession !== undefined && request.graphSession === undefined)) { + throw new Error('GRAPH_MUTATION_SESSION_REQUIRED: use the explicit active graph request capability'); + } + } + + private async withMutationSession(request: MutationRequest, work: (session: SqlSession) => Promise): Promise { + this.requireGraphOwnership(request); + return request.graphSession ? work(this.graphMutationSession!) : this.driver.transaction(work); + } + + preflightMutation(mutation: any): any { + const request = mutation instanceof MutationRequest ? mutation : new MutationRequest(mutation); + this.requireGraphOwnership(request); + mutation = this.checkAndFixMutation(request); + if (request.graphSession) { + const schema = this.schema(mutation.entity); + request.graphSession.captureLogBindings(this.mutationLogBindings(request, mutation, schema)); + } + this.userContext.recordMutationPolicyPreflight(mutation); + return mutation; + } + + private mutationLogBindings(request: MutationRequest, mutation: any, schema: EntitySchema): SQLLogBindingSource { + const source = (values: Record): SQLLogBindingSource => { + const record = this.toRuntimeMutationRecord(schema, values); + const fields = Object.keys(record); + return { parameterizedSQL: '', sqlOrigin: 'generated', parameters: fields.map(field => record[field]), + parameterLogPolicies: fields.map(field => this.fieldLogPolicy(schema, field)) }; + }; + return inheritSQLLogBindings(source(mutation.payload || {}), source(request.loadedValues())); + } + + private checkAndFixMutation(mutation: any): any { + const request = mutation instanceof MutationRequest ? mutation : new MutationRequest(mutation); + this.requireGraphOwnership(request); + mutation = request.mutation; + // The ledger exposes immutable snapshots. Fixers receive a mutable working + // payload and every derived value is copied back into the graph ledger. + mutation = { ...mutation, payload: { ...(mutation?.payload ?? {}) } }; + Object.defineProperty(mutation, 'comment', { value: request.comment, enumerable: true }); + const checker = this.checkers[String(mutation.entity)]; + if (!checker) return mutation; + const results: import('../core/i18n').CheckResult[] = []; + const ownsFixTime = this.userContext.getResource('fixTime') === undefined; + if (ownsFixTime) this.userContext.insertResource('fixTime', new Date()).beginFixEvidence(); + try { + checker.checkAndFix(this.userContext, mutation, results); + if (mutation.ledgerKey && mutation.ledgerRoot) { + for (const [field, value] of Object.entries(mutation.payload || {})) { + mutation.ledgerRoot.set(mutation.ledgerKey, field, value); + } + } + this.userContext.translateCheckResults(results); + if (results.length) throw new CheckException(results); + return mutation; + } finally { + if (ownsFixTime) this.userContext.removeResource('fixTime').finishFixEvidence(); + } + } + + async executeMutation(mutation: any): Promise { + await this.telemetryStartup; + // Validate before Checker, policy, telemetry and transaction/provider work. + const request = mutation instanceof MutationRequest ? mutation : new MutationRequest(mutation); + this.requireGraphOwnership(request); + mutation = request.mutation; + const scope = startRuntimeOperation(this.runtimeTelemetry, { + family: 'mutation', + name: `${String(mutation?.entity || 'unknown')}.${String(mutation?.action || 'unknown').toLowerCase()}`, + attributes: { + 'teaql.entity.type': String(mutation?.entity || 'unknown'), + 'teaql.mutation.kind': String(mutation?.action || 'unknown').toLowerCase(), + }, + }); + const work = async () => { try { + mutation = this.checkAndFixMutation(request); + const mutationGovernance = this.userContext.enterMutationPolicy(mutation); + const schema = this.schema(mutation.entity); + const mutationRecord = this.toRuntimeMutationRecord(schema, mutation.payload || {}); + const diagnosticBindings = this.mutationLogBindings(request, mutation, schema); + const table = this.driver.identifier(schema.table); + const statements: SQLExecutionMetadata[] = []; + const result = await observeRuntimeOperation(this.runtimeTelemetry, { + family: 'provider', + name: `${this.driver.databaseKind}.mutation`, + attributes: { + 'teaql.provider.kind': this.driver.databaseKind, + 'teaql.provider.operation': String(mutation.action).toLowerCase(), + }, + }, () => this.withMutationSession(request, async session => { + if (mutation.action === 'Create') { + const id = mutation.id + ? String(mutation.id) + : await this.driver.nextId(session, mutation.entity); + if (mutation.id) { + await this.driver.ensureIdFloor(session, mutation.entity, id); + } + const version = Number(mutation.version || 0) + 1; + const record: Record = { ...mutationRecord, id, version }; + const fields = Object.keys(schema.columns) + .filter(field => record[field] !== undefined); + const columns = fields.map(field => + this.driver.identifier(schema.columns[field].columnName), + ).join(', '); + const placeholders = fields.map((_, index) => + this.driver.placeholder(index + 1), + ).join(', '); + const values = fields.map(field => + this.encode(record[field], schema.columns[field]), + ); + this.bindLogPolicies.set(values, fields.map(field => this.fieldLogPolicy(schema, field))); + const sql = `INSERT INTO ${table} (${columns}) VALUES (${placeholders})`; + const intent = mutationLogIntent(request, mutation, this.driver.databaseKind, 'insert', id, diagnosticBindings); + await this.executeLoggedSQL('insert', sql, values, intent, () => session.query(sql, values), undefined, statements); + return { + success: true, + id, + version, + persistedRecord: await this.readPersistedRecord(session, schema, id, intent, sql, values, statements), + }; + } + + if (mutation.action === 'Update') { + const fields = Object.keys(schema.columns).filter(field => + field !== 'id' && field !== 'version' && + mutationRecord[field] !== undefined, + ); + const values = fields.map(field => + this.encode(mutationRecord[field], schema.columns[field]), + ); + this.bindLogPolicies.set(values, fields.map(field => this.fieldLogPolicy(schema, field))); + const assignments = fields.map((field, index) => + `${this.driver.identifier(schema.columns[field].columnName)} = ` + + this.driver.placeholder(index + 1), + ); + const versionColumn = this.driver.identifier('version'); + assignments.push(`${versionColumn} = ${versionColumn} + 1`); + this.bindValue(values, String(mutation.id), this.fieldLogPolicy(schema, 'id')); + const predicates = [ + `${this.driver.identifier('id')} = ${this.driver.placeholder(values.length)}`, + ]; + if (mutation.version !== undefined && mutation.version !== null) { + this.bindValue(values, Number(mutation.version), this.fieldLogPolicy(schema, 'version')); + predicates.push( + `${versionColumn} = ${this.driver.placeholder(values.length)}`, + ); + } + const sql = `UPDATE ${table} SET ${assignments.join(', ')} ` + + `WHERE ${predicates.join(' AND ')}`; + const intent = mutationLogIntent(request, mutation, this.driver.databaseKind, 'update', String(mutation.id), diagnosticBindings); + const result = await this.executeLoggedSQL('update', sql, values, intent, () => session.query(sql, values), undefined, statements); + if (result.rowCount !== 1) { + throw new Error( + `Optimistic lock failed or ${mutation.entity}(${mutation.id}) does not exist`, + ); + } + const persistedRecord = await this.readPersistedRecord( + session, schema, String(mutation.id), intent, sql, values, statements, + ); + return { + success: true, + id: String(mutation.id), + version: Number(persistedRecord.version), + persistedRecord, + }; + } + + if (mutation.action === 'Delete') { + const versionColumn = this.driver.identifier('version'); + const values: any[] = [String(mutation.id)]; + this.bindLogPolicies.set(values, [this.fieldLogPolicy(schema, 'id')]); + const predicates = [ + `${this.driver.identifier('id')} = ${this.driver.placeholder(1)}`, + ]; + if (mutation.version !== undefined && mutation.version !== null) { + this.bindValue(values, Number(mutation.version), this.fieldLogPolicy(schema, 'version')); + predicates.push( + `${this.driver.identifier('version')} = ` + + this.driver.placeholder(values.length), + ); + } + const sql = `UPDATE ${table} SET ${versionColumn} = -(${versionColumn} + 1) ` + + `WHERE ${predicates.join(' AND ')}`; + const intent = mutationLogIntent(request, mutation, this.driver.databaseKind, 'delete', String(mutation.id), diagnosticBindings); + const result = await this.executeLoggedSQL('delete', sql, values, intent, () => session.query(sql, values), undefined, statements); + if (result.rowCount !== 1) { + throw new Error( + `Optimistic lock failed or ${mutation.entity}(${mutation.id}) does not exist`, + ); + } + const persistedRecord = await this.readPersistedRecord( + session, schema, String(mutation.id), intent, sql, values, statements, + ); + return { + success: true, + id: String(mutation.id), + version: Number(persistedRecord.version), + deleted: true, + persistedRecord, + }; + } + + throw new Error(`Unsupported mutation action: ${mutation.action}`); + })); + const auditProjection = request.auditProjection({ entity: String(mutation.entity), id: result.id }, mutation.payload, diagnosticBindings); + const event = Object.freeze({ + entity: mutation.entity, + action: mutation.action, + id: String(result.id), + ...auditProjection, + recordedAt: new Date().toISOString(), + actor: this.userContext.getResource('bootstrapActor'), + category: this.userContext.getResource('bootstrapCategory'), + changedFields: Object.freeze(Object.keys(mutation.payload || {}).sort()), + version: result.version, + mutationGovernance, + }); + const publish = async () => { + this.auditEvents.push(event); + if (this.auditSink) await observeRuntimeOperation(this.runtimeTelemetry, { + family: 'audit', + name: `${mutation.entity}.audit`, + attributes: { + 'teaql.entity.type': String(mutation.entity), + 'teaql.mutation.kind': String(mutation.action).toLowerCase(), + 'teaql.audit.changed_field_count': Object.keys(mutation.payload || {}).length, + }, + }, async () => this.auditSink!(event)); + }; + if (request.graphSession) this.graphAuditActions.push(publish); + else { + try { await publish(); } catch (error) { throw new GraphCommittedError(error); } + } + scope.success(); + const metadata = Object.freeze({ ...statements[0], statements: Object.freeze([...statements]) }); + retainSQLLogProvenance(metadata, inheritSQLLogBindings(diagnosticBindings, request.graphSession?.logBindings), [result.id]); + return { ...result, metadata }; + } catch (error) { + scope.failure(error); + throw error; + } }; + return scope.run ? scope.run(work) : work(); + } + + private async readPersistedRecord( + session: SqlSession, schema: EntitySchema, id: string, + intent: SQLLogIntent, writeSQL: string, writeValues: any[], + statements: SQLExecutionMetadata[], + ): Promise> { + const projection = Object.entries(schema.columns).map(([field, column]) => + `${this.driver.identifier(column.columnName)} AS ${this.driver.identifier(field)}`, + ).join(', '); + const sql = `SELECT ${projection} FROM ${this.driver.identifier(schema.table)} WHERE ` + + `${this.driver.identifier('id')} = ${this.driver.placeholder(1)}`; + const values = [id]; + this.bindLogPolicies.set(values, [this.fieldLogPolicy(schema, 'id')]); + const scope = startRuntimeOperation(this.runtimeTelemetry, { family: 'provider', + name: `${this.driver.databaseKind}.readback`, attributes: { + 'teaql.provider.kind': this.driver.databaseKind, 'teaql.provider.operation': 'query' } }); + const startedAt = Date.now(); + let result: SqlQueryResult | undefined; + const inherited: SQLLogBindingSource = { parameterizedSQL: writeSQL, parameters: writeValues, + parameterLogPolicies: this.bindLogPolicies.get(writeValues), sqlOrigin: 'generated' }; + const root = intent.tracePath?.find(node => node.kind === 'operation')?.name ?? 'unknown'; + const path = canonicalSQLTracePath([ + ...queryTraceSource(root, intent.auditReason!, 'verify persisted mutation result'), + ...(intent.tracePath ?? []).filter(node => node.kind === 'relation'), + ], this.driver.databaseKind, 'select'); + const readIntent = { ...intent, tracePath: sqlTraceFrames(path.tracePath), + comment: intent.auditReason, purpose: 'verify persisted mutation result' }; + const recordReadback = (outcome: SQLExecutionOutcome) => statements.push( + this.recordSQL('select', sql, values, startedAt, result?.rowCount, undefined, readIntent, outcome, inherited, scope.correlation?.())); + let record: Record; + try { + result = await (scope.run ? scope.run(() => session.query(sql, values)) : session.query(sql, values)); + scope.success({ attributes: { 'teaql.result.cardinality': result.rowCount } }); + if (result.rowCount !== 1) throw new Error(`Persisted ${schema.table}(${id}) could not be read back`); + record = this.decodeRowForSchema(schema, result.rows[0]); + } catch (error) { + if (!result) scope.failure(error); + // Write success remains a separate statement fact. A snapshot validation + // failure means SELECT success with its real count, not a driver failure. + const outcome: SQLExecutionOutcome = result ? 'success' + : error instanceof Error && (error.name === 'AbortError' || error.name === 'TimeoutError') + ? 'cancelled' : 'failure'; + try { recordReadback(outcome); } finally { throw error; } + } + recordReadback('success'); + return record; + } + + private decodeRowForSchema(schema: EntitySchema, row: any): Record { + const result = { ...row }; + for (const [field, column] of Object.entries(schema.columns)) { + const value = result[field]; + if (value === null || value === undefined) continue; + if (column.decode === 'number') result[field] = Number(value); + if (column.decode === 'string') result[field] = String(value); + if (column.decode === 'date' && value instanceof Date) result[field] = value.toISOString(); + if (column.logicalType === 'boolean') result[field] = Boolean(value); + } + return result; + } + + private compileExpression( + expression: any, + schema: EntitySchema, + values: any[], + ): string { + if (Array.isArray(expression?.$and)) { + const parts = expression.$and.map((item: any) => + this.compileExpression(item, schema, values), + ); + return `(${parts.join(' AND ')})`; + } + const parts = Object.entries(expression || {}).map( + ([field, predicate]: [string, any]) => { + const column = schema.columns[field]; + if (!column) throw new Error(`Unknown field ${field} for SQL query`); + const quotedField = this.driver.identifier(column.columnName); + const logPolicy = this.fieldLogPolicy(schema, field); + if (predicate?.$eq !== undefined) { + const value = predicate.$eq?.id ?? predicate.$eq; + if (value === null) return `${quotedField} IS NULL`; + this.bindValue(values, this.encode(value, column), logPolicy); + return `${quotedField} = ${this.driver.placeholder(values.length)}`; + } + if (predicate?.$ne !== undefined) { + const value = predicate.$ne?.id ?? predicate.$ne; + if (value === null) return `${quotedField} IS NOT NULL`; + this.bindValue(values, this.encode(value, column), logPolicy); + return `${quotedField} <> ${this.driver.placeholder(values.length)}`; + } + if (predicate?.$soundLike !== undefined) { + this.bindValue(values, String(predicate.$soundLike), logPolicy); + return `SOUNDEX(${quotedField}) = SOUNDEX(${this.driver.placeholder(values.length)})`; + } + if (predicate?.$contains !== undefined) { + this.bindValue(values, String(predicate.$contains), logPolicy); + return this.driver.contains( + quotedField, + this.driver.placeholder(values.length), + ); + } + if (predicate?.$notContains !== undefined) { + this.bindValue(values, String(predicate.$notContains), logPolicy); + return `NOT (${this.driver.contains(quotedField, this.driver.placeholder(values.length))})`; + } + for (const [operator, prefix, suffix, negative] of [ + ['$startsWith', '', '%', false], + ['$notStartsWith', '', '%', true], + ['$endsWith', '%', '', false], + ['$notEndsWith', '%', '', true], + ] as const) { + if (predicate?.[operator] !== undefined) { + // Retain the exact original value; stripping SQL wildcard text + // would misclassify literal %, _ or escape characters in intent. + const operand = String(predicate[operator]); + this.bindValue(values, `${prefix}${operand}${suffix}`, logPolicy, operand); + const like = `${quotedField} LIKE ${this.driver.placeholder(values.length)}`; + return negative ? `NOT (${like})` : like; + } + } + if (Array.isArray(predicate?.$in)) { + if (!predicate.$in.length) return 'FALSE'; + const placeholders = predicate.$in.map((value: any) => { + this.bindValue(values, this.encode(value?.id ?? value, column), logPolicy); + return this.driver.placeholder(values.length); + }); + return `${quotedField} IN (${placeholders.join(', ')})`; + } + if (Array.isArray(predicate?.$notIn)) { + if (!predicate.$notIn.length) return 'TRUE'; + const placeholders = predicate.$notIn.map((value: any) => { + this.bindValue(values, this.encode(value?.id ?? value, column), logPolicy); + return this.driver.placeholder(values.length); + }); + return `${quotedField} NOT IN (${placeholders.join(', ')})`; + } + for (const [operator, negative] of [ + ['$inSubquery', false], + ['$notInSubquery', true], + ] as const) { + const subquery = predicate?.[operator]; + if (subquery !== undefined) { + const childQuery = subquery.query; + const childSchema = this.schema(childQuery?.entity); + const projectedField = String(subquery.field); + const projectedColumn = childSchema.columns[projectedField]; + if (!projectedColumn) { + throw new Error( + `Unknown subquery projection ${projectedField} for ${childQuery?.entity}`, + ); + } + const childPredicates = this.filters(childQuery).map(item => + this.compileExpression(item, childSchema, values), + ); + if (childSchema.columns.version) { + childPredicates.push( + `${this.driver.identifier(childSchema.columns.version.columnName)} > 0`, + ); + } + // A NULL projected by a NOT IN subquery makes the predicate + // UNKNOWN for every outer row. Orphan relations are handled by + // the explicit unknown predicate and must not poison HaveNo or + // negative relation matching. + if (negative) { + childPredicates.push( + `${this.driver.identifier(projectedColumn.columnName)} IS NOT NULL`, + ); + } + const where = childPredicates.length + ? ` WHERE ${childPredicates.join(' AND ')}` + : ''; + const sql = `SELECT ${this.driver.identifier(projectedColumn.columnName)} ` + + `FROM ${this.driver.identifier(childSchema.table)}${where}`; + return `${quotedField} ${negative ? 'NOT IN' : 'IN'} (${sql})`; + } + } + if (Array.isArray(predicate?.$between) && predicate.$between.length === 2) { + this.bindValue(values, this.encode(predicate.$between[0], column), logPolicy); + const lower = this.driver.placeholder(values.length); + this.bindValue(values, this.encode(predicate.$between[1], column), logPolicy); + const upper = this.driver.placeholder(values.length); + return `${quotedField} BETWEEN ${lower} AND ${upper}`; + } + if (predicate?.$isNull === true) return `${quotedField} IS NULL`; + if (predicate?.$isNull === false) return `${quotedField} IS NOT NULL`; + if (predicate?.$gte !== undefined) { + this.bindValue(values, this.encode(predicate.$gte, column), logPolicy); + return `${quotedField} >= ${this.driver.placeholder(values.length)}`; + } + if (predicate?.$lte !== undefined) { + this.bindValue(values, this.encode(predicate.$lte, column), logPolicy); + return `${quotedField} <= ${this.driver.placeholder(values.length)}`; + } + if (predicate?.$gt !== undefined) { + this.bindValue(values, this.encode(predicate.$gt, column), logPolicy); + return `${quotedField} > ${this.driver.placeholder(values.length)}`; + } + if (predicate?.$lt !== undefined) { + this.bindValue(values, this.encode(predicate.$lt, column), logPolicy); + return `${quotedField} < ${this.driver.placeholder(values.length)}`; + } + throw new Error(`Unsupported query predicate for ${field}: ${JSON.stringify(predicate)}`); + }, + ); + return parts.length ? `(${parts.join(' AND ')})` : 'TRUE'; + } + + private filters(query: any): any[] { + if (Array.isArray(query._filters) && query._filters.length) return query._filters; + return query.filterCondition ? [query.filterCondition] : []; + } + + private groupBy(query: any): string[] { + return query._groupBy || query.groupByItems || []; + } + + private aggregates(query: any): NormalizedAggregate[] { + if (Array.isArray(query._aggregates)) return query._aggregates; + return (query.aggregateItems || []).map((aggregate: any) => ({ + func: aggregate.function, + field: aggregate.field, + retName: aggregate.alias, + })); + } + + private orders(query: any): NormalizedOrder[] { + if (Array.isArray(query._orderBy)) { + return query._orderBy.map((order: any) => ({ + field: order.f, + direction: order.d, + })); + } + return (query.orderItems || []).map((order: any) => ({ + field: order.field, + direction: order.direction, + })); + } + + private async compileQuery(query: any, recordTrace = true, assemblyFields: readonly string[] = []): Promise<{ + sql: string; + values: any[]; + aggregateNames: string[]; + }> { + // Internal execution changes query shape/limits, never the intent contract. + new QueryIntent(query?.commentText ?? query?._comment, query?.purposeText ?? query?._purpose); + const schema = this.schema(query.entity); + const values: any[] = []; + const groupProperties = this.groupBy(query); + const groupFields = groupProperties.map(field => { + if (!schema.columns[field]) throw new Error(`Unknown group field: ${field}`); + return this.driver.identifier(schema.columns[field].columnName); + }); + const groupProjection = groupProperties.map(field => + `${this.driver.identifier(schema.columns[field].columnName)} AS ` + + this.driver.identifier(field), + ); + const aggregateNames: string[] = []; + const requestedFields = Array.isArray(query.selectItems) && query.selectItems.length + ? [...new Set(['id', 'version', ...query.selectItems])] + : Object.keys(schema.columns); + // Explicitly requested relations need their real membership keys, even + // with a minimal parent projection. Missing projection is not SQL NULL. + if (!groupProperties.length && !this.aggregates(query).length) { + for (const field of assemblyFields) if (!requestedFields.includes(field)) requestedFields.push(field); + const relationNames = [...(query.relations ?? []).map((load: any) => load.name), + ...(query.relationAggregates ?? []).map((aggregate: any) => aggregate.relationName)]; + for (const name of relationNames) { + const relation = schema.relations?.[name]; + if (!relation) throw new Error(`Missing relation ${query.entity}.${name}`); + if (!requestedFields.includes(relation.localKey)) requestedFields.push(relation.localKey); + } + } + for (const field of requestedFields) { + if (!schema.columns[field]) throw new Error(`Unknown selected field: ${field}`); + } + let projection = requestedFields.map(field => { + const column = schema.columns[field]; + return `${this.driver.identifier(column.columnName)} AS ${this.driver.identifier(field)}`; + }).join(', '); + const aggregates = this.aggregates(query); + if (aggregates.length) { + const aggregateProjection = aggregates.map(aggregate => { + if (!schema.columns[aggregate.field]) { + throw new Error(`Unknown aggregate field: ${aggregate.field}`); + } + aggregateNames.push(aggregate.retName); + return `${this.driver.aggregateFunction(aggregate.func)}(` + + `${this.driver.identifier(schema.columns[aggregate.field].columnName)}) AS ` + + this.driver.identifier(aggregate.retName); + }); + projection = [...groupProjection, ...aggregateProjection].join(', '); + } + + const partitionBy = query.__teaqlPartitionBy as string | undefined; + const orders = this.orders(query); + const orderClauses = orders.map(order => { + if (!schema.columns[order.field]) { + throw new Error(`Unknown order field: ${order.field}`); + } + const direction = String(order.direction).toLowerCase() === 'desc' + ? 'DESC' + : 'ASC'; + return `${this.driver.identifier(schema.columns[order.field].columnName)} ${direction}`; + }); + if (partitionBy) { + const partitionColumn = schema.columns[partitionBy]; + if (!partitionColumn) throw new Error(`Unknown partition field: ${partitionBy}`); + const windowOrder = orderClauses.length ? ` ORDER BY ${orderClauses.join(', ')}` : ''; + projection += `, ROW_NUMBER() OVER (PARTITION BY ` + + `${this.driver.identifier(partitionColumn.columnName)}${windowOrder}) AS ` + + this.driver.identifier('__teaql_partition_rank'); + } + + let sql = `SELECT ${projection} FROM ${this.driver.identifier(schema.table)}`; + const filters = this.filters(query); + const predicates = filters.map(expression => + this.compileExpression(expression, schema, values), + ); + if (schema.columns.version) { + predicates.push( + `${this.driver.identifier(schema.columns.version.columnName)} > 0`, + ); + } + if (predicates.length) { + sql += ` WHERE ${predicates.join(' AND ')}`; + } + if (groupFields.length) sql += ` GROUP BY ${groupFields.join(', ')}`; + const limit = query._limit !== undefined + ? Number(query._limit) + : Number(query.limitValue || 0); + const offset = query._offset !== undefined + ? Number(query._offset) + : Number(query.offsetValue || 0); + if (partitionBy) { + const rank = this.driver.identifier('__teaql_partition_rank'); + const predicates: string[] = []; + this.bindValue(values, offset, 'plain'); + predicates.push(`${rank} > ${this.driver.placeholder(values.length)}`); + if (limit > 0) { + this.bindValue(values, offset + limit, 'plain'); + predicates.push(`${rank} <= ${this.driver.placeholder(values.length)}`); + } + sql = `SELECT * FROM (${sql}) AS ${this.driver.identifier('__teaql_partitioned')} ` + + `WHERE ${predicates.join(' AND ')} ORDER BY ${rank}`; + } else if (orders.length) { + sql += ` ORDER BY ${orderClauses.join(', ')}`; + } + if (!partitionBy && limit > 0) { + this.bindValue(values, limit, 'plain'); + sql += ` LIMIT ${this.driver.placeholder(values.length)}`; + } + if (!partitionBy && offset > 0) { + this.bindValue(values, offset, 'plain'); + sql += ` OFFSET ${this.driver.placeholder(values.length)}`; + } + if (recordTrace) this.sqlTrace.push(sql); + return { sql, values, aggregateNames }; + } + + async executeQuery(query: any): Promise { + const request = query instanceof QueryRequest ? query : new QueryRequest(query); + // Keep the existing builder hard-limit normalization contract. Intent is + // already validated; the private execution snapshot is normalized again. + if (!(query instanceof QueryRequest) && query?.[this.internalQueryToken] !== true + && typeof query?.prepareForList === 'function') query.prepareForList(); + return this.executeQueryWithIntent(request.query, this.derivedQueryBindings.get(query), + this.derivedRelationAssembly.get(query)); + } + + private async executeDerivedQuery(query: object, inherited: SQLLogBindingSource | undefined, + intent: QueryIntent, assembly?: RelationAssembly): Promise { + // Only fresh execution-local child requests are registered. Keep virtual + // executeQuery dispatch for existing subclasses; no provenance on wire data. + const captured = new QueryRequest(query, intent).query; + if (inherited) this.derivedQueryBindings.set(captured, inherited); + if (assembly) this.derivedRelationAssembly.set(captured, assembly); + try { return await this.executeQuery(captured); } + finally { + this.derivedQueryBindings.delete(captured); + this.derivedRelationAssembly.delete(captured); + } + } + + private descendantBindings(query: any, sql: string, values: any[], inherited?: SQLLogBindingSource): SQLLogBindingSource | undefined { + if (!query.relations?.length && !query.relationAggregates?.length) return undefined; + return inheritSQLLogBindings(this.queryLogBindings(sql, values), inherited); + } + + private async queryTreeBindings(query: any, sql: string, values: any[], inherited?: SQLLogBindingSource): Promise { + let source = inheritSQLLogBindings(this.queryLogBindings(sql, values), inherited); + const intent = new QueryRequest(query).intent; + const stack: any[] = [query]; + const visited = new Set(); + while (stack.length) { + const current = stack.pop(); + if (!current || visited.has(current)) continue; + visited.add(current); + if (current !== query) { + // Pure compilation, not a physical query or an sqlTrace entry. + const compiled = await this.compileQuery(new QueryRequest(current, intent).query, false); + source = inheritSQLLogBindings(this.queryLogBindings(compiled.sql, compiled.values), source); + } + const origin = queryDiagnosticOrigin(current); + if (origin) stack.push(origin); + for (const child of [...(current.relations ?? []), ...(current.relationAggregates ?? [])]) { + if (child.query) stack.push(child.query); + } + for (const facet of current.facets ?? []) { + if (!facet.query) continue; + // Facet aggregates describe membership rows from the outer entity. + // The nested query only selects the facet value object itself, so its + // diagnostic compilation must mirror execution and omit those measures. + const facetValueQuery = facet.query.clone(); + facetValueQuery.aggregateItems = []; + facetValueQuery.groupByItems = []; + stack.push(facetValueQuery); + } + } + return source; + } + + private async executeQueryWithIntent(query: any, inherited?: SQLLogBindingSource, + assembly?: RelationAssembly): Promise { + await this.telemetryStartup; + const scope = startRuntimeOperation(this.runtimeTelemetry, { + family: 'query', + name: `${String(query?.entity || 'unknown')}.list`, + attributes: { 'teaql.entity.type': String(query?.entity || 'unknown') }, + }); + const work = async () => { try { + const internal = query?.[this.internalQueryToken] === true; + if (!internal) { + if (typeof query?.prepareForList !== 'function') { + throw new Error('TeaQL list execution requires the formal runtime SelectQuery'); + } + query.prepareForList(); + } + const idSetPrepared = internal ? { query, execution: undefined } : await this.prepareIdSetPage(query, inherited); + const prepared = internal ? idSetPrepared : await this.prepareContinuousPage(idSetPrepared.query); + query = new QueryRequest(query).withQuery(prepared.query).query; + const { sql, values, aggregateNames } = await this.compileQuery(query, true, assembly ? [assembly.field] : []); + inherited = await this.queryTreeBindings(query, sql, values, inherited); + const result = await this.executeLoggedSQL('select', sql, values, this.queryLogIntent(query), + () => this.driver.query(sql, values), inherited); + const rows = result.rows.map(row => + this.decodeRow(query.entity, row, aggregateNames), + ); + if (idSetPrepared.execution?.pageIds) { + const positions = new Map( + idSetPrepared.execution.pageIds.map( + (id: any, index: number): [string, number] => [String(id), index], + ), + ); + rows.sort((left: any, right: any) => + (positions.get(String(left.id)) ?? Number.MAX_SAFE_INTEGER) + - (positions.get(String(right.id)) ?? Number.MAX_SAFE_INTEGER)); + } + const descendantBindings = this.descendantBindings(query, sql, values, inherited); + if (assembly) for (const row of rows) assembly.keys.set(row, row[assembly.field]); + await this.enhanceQueryRows(rows, query, descendantBindings); + if (assembly && Array.isArray(query.selectItems) && query.selectItems.length + && !['id', 'version', ...query.selectItems, ...this.groupBy(query)].includes(assembly.field)) { + const schema = this.schema(query.entity); + const selectedRelations = [...(query.relations ?? []).map((load: any) => load.name), + ...(query.relationAggregates ?? []).map((aggregate: any) => aggregate.relationName)]; + if (!selectedRelations.some(name => schema.relations?.[name]?.localKey === assembly.field)) + for (const row of rows) delete row[assembly.field]; + } + if (!internal) await this.registerContinuousPage(query, prepared.execution, rows); + scope.success({ attributes: { 'teaql.result.cardinality': rows.length } }); + return rows as T[]; + } catch (error) { + scope.failure(error); + throw error; + } }; + return scope.run ? scope.run(work) : work(); + } + + private async prepareIdSetPage(query: any, inherited?: SQLLogBindingSource): Promise<{ query: any; execution?: any }> { + const options = query.localIdSetPaginationOptions?.(); + const runtime = query.localIdSetPaginationRuntime?.(); + if (!options || !runtime) { runtime?.observe('ID_SET_DISABLED'); return { query }; } + const limit = this.queryLimit(query); + if (!limit || query.localContinuousPageOptions?.() || this.aggregates(query).length + || this.groupBy(query).length || query.__teaqlPartitionBy) { + runtime.observe('ID_SET_FALLBACK_UNSUPPORTED_SHAPE'); + return { query }; + } + if ((query.orderItems || []).some((order: any) => order.expr != null)) { + runtime.observe('ID_SET_FALLBACK_NON_DETERMINISTIC_ORDER'); + return { query }; + } + if (!this.orders(query).some(order => order.field === 'id')) { + query = query.clone().order(OrderBy.asc('id')); + } + const normalized = query.clone(); + normalized.offsetValue = 0; + normalized.limitValue = 0; + normalized.selectItems = []; + normalized.relations = []; + normalized.commentText = undefined; + normalized.purposeText = undefined; + normalized.clearIdSetPaginationRuntime(); + normalized.clearContinuousPageRuntime(); + const rawKey = `${options.namespace}|${runtime.scope}|${JSON.stringify(normalized)}`; + let hash = 2166136261; + for (let i = 0; i < rawKey.length; i++) hash = Math.imul(hash ^ rawKey.charCodeAt(i), 16777619); + const queryKey = `teaql:id-set:v1:${(hash >>> 0).toString(16)}`; + let retained: any; + let cacheHit = false; + try { retained = runtime.get(queryKey); } + catch { runtime.observe('ID_SET_FALLBACK_STORE_UNAVAILABLE'); return { query }; } + if (!retained) { + let buildResult: any; + try { + buildResult = await runtime.build(queryKey, async () => { + const existing = runtime.get(queryKey); + if (existing) return existing; + const idQuery = query.clone(); + idQuery.selectItems = ['id']; + idQuery.relations = []; + idQuery.relationAggregates = []; + idQuery.facets = []; + idQuery.offsetValue = 0; + idQuery.limitValue = options.maxIds + 1; + idQuery.clearIdSetPaginationRuntime(); + idQuery.clearContinuousPageRuntime(); + (idQuery as any)[this.internalQueryToken] = true; + const helper = new QueryRequest(query).deriveHelper(idQuery, `collect ${query.entity} IDs for pagination`); + // Classification is pure compilation, not another SQL execution. + // The collector drops relations, but its inherited prose can still + // mention a secret bound only by one of those future requests. + const diagnostic = await this.compileQuery(query, false); + const helperBindings = await this.queryTreeBindings(query, diagnostic.sql, diagnostic.values, inherited); + const idRows = await this.executeDerivedQuery(helper.query, + helperBindings, helper.intent); + if (idRows.length > options.maxIds) return undefined; + let ids: BigUint64Array; + try { ids = BigUint64Array.from(idRows.map(row => BigInt(row.id))); } + catch { throw new Error('ID_SET_UNSUPPORTED_ID'); } + const value = { ids, expiresAt: Date.now() + options.ttlSeconds * 1000 }; + runtime.put(queryKey, value); + return value; + }); + } catch (error) { + runtime.observe(error instanceof Error && error.message === 'ID_SET_UNSUPPORTED_ID' + ? 'ID_SET_FALLBACK_UNSUPPORTED_SHAPE' + : 'ID_SET_FALLBACK_STORE_UNAVAILABLE'); + return { query }; + } + retained = buildResult.value; + if (!retained) { + runtime.observe('ID_SET_FALLBACK_LIMIT_EXCEEDED', options.maxIds + 1); + return { query }; + } + cacheHit = !buildResult.built; + runtime.observe(cacheHit ? 'ID_SET_HIT' : 'ID_SET_BUILD', retained.ids.length); + } else { + cacheHit = true; + runtime.observe('ID_SET_HIT', retained.ids.length); + } + const offset = Number(query.offsetValue || query._offset || 0); + const pageIds = Array.from(retained.ids.slice(offset, offset + limit)); + const page = query.clone(); + page.offsetValue = 0; + page.limitValue = Math.max(pageIds.length, 1); + page.filterCondition = page.filterCondition + ? { $and: [page.filterCondition, { id: { $in: pageIds } }] } + : { id: { $in: pageIds } }; + page.clearIdSetPaginationRuntime(); + runtime.observe(cacheHit ? 'ID_SET_HIT' : 'ID_SET_BUILD', retained.ids.length); + return { query: page, execution: { pageIds, totalCount: retained.ids.length } }; + } + + async executeFacetMembership( + outerQuery: SelectQuery, + relationName: string, + countAliases: readonly string[] = [], + ): Promise> { + const aggregates = await this.executeFacetAggregates(outerQuery, relationName, [{ + function: 'Count', field: 'id', alias: '__teaql_facet_count', + }]); + return new Map([...aggregates].map(([key, values]) => [ + key, Number(values.__teaql_facet_count ?? 0), + ])); + } + + async executeFacetAggregates( + outerQuery: SelectQuery, + relationName: string, + aggregates: readonly FacetAggregate[], + ): Promise>> { + const request = new QueryRequest(outerQuery); + outerQuery = request.query; + const query = request.withQuery(outerQuery.clone()).query; + retainQueryDiagnosticOrigin(outerQuery, query); + query.facets = []; + query.relations = []; + query.relationAggregates = []; + query.orderItems = []; + query.offsetValue = 0; + query.limitValue = 0; + query.selectItems = []; + query.groupByItems = [relationName]; + query.aggregateItems = aggregates.map(aggregate => ({ ...aggregate })); + (query as any)[this.internalQueryToken] = true; + const rows = await this.executeQuery>(query); + return new Map(rows.flatMap(row => { + const value = row[relationName]; + if (value === null || value === undefined) return []; + const result: Record = {}; + for (const aggregate of aggregates) result[aggregate.alias] = row[aggregate.alias]; + return [[String(value), result]]; + })); + } + + async executeCount(query: any, countAlias?: string, operation?: QueryOperation): Promise { + const request = query instanceof QueryRequest ? query : new QueryRequest(query); + query = request.query; + if (typeof query?.forExactCount !== 'function') { + throw new Error('TeaQL exact count requires the formal runtime SelectQuery'); + } + const alias = countAlias ?? '__teaql_total'; + const countRequest = request.deriveOperation(query.forExactCount(alias), operation ?? { + kind: 'named-count', ...(countAlias !== undefined ? { alias: countAlias } : {}), + }); + const rows = await this.executeQuery>(countRequest.query); + const value = rows[0]?.[alias]; + if (typeof value !== 'number' || !Number.isFinite(value)) { + throw new Error(`TeaQL provider did not return exact count alias ${alias}`); + } + return value; + } + + private async prepareContinuousPage(query: any): Promise<{ query: any; execution?: any }> { + const options = query.localContinuousPageOptions?.(); + const runtime = query.localContinuousPageRuntime?.(); + if (!options || !runtime) { runtime?.observe('DISABLED'); return { query }; } + const orders = this.orders(query); + const limit = this.queryLimit(query); + if (!limit || orders.length !== 1 || orders[0].field !== 'id' || this.aggregates(query).length || this.groupBy(query).length || query.__teaqlPartitionBy) { + runtime.observe('OFFSET_FALLBACK:UNSUPPORTED_QUERY_SHAPE'); return { query }; + } + const clone = Object.assign(Object.create(Object.getPrototypeOf(query)), query); + clone.orderItems = [...(query.orderItems || [])]; clone.relations = [...(query.relations || [])]; + Object.defineProperty(clone, 'continuousPageFetchOptions', { enumerable: false, writable: true, value: options }); + Object.defineProperty(clone, 'continuousPageRuntimeContext', { enumerable: false, writable: true, value: runtime }); + const offset = Number(query.offsetValue || query._offset || 0); + const normalized = { ...JSON.parse(JSON.stringify(clone)), offsetValue: 0, _offset: 0, commentText: undefined, purposeText: undefined }; + const rawKey = `${options.namespace}|${runtime.owner}|${JSON.stringify(normalized)}`; + let hash = 2166136261; for (let i = 0; i < rawKey.length; i++) hash = Math.imul(hash ^ rawKey.charCodeAt(i), 16777619); + const queryKey = `teaql:continuous-page:v1:${(hash >>> 0).toString(16)}`; + const execution: any = { queryKey, offset, limit, direction: String(orders[0].direction).toLowerCase(), ttlSeconds: options.ttlSeconds, runtime, optimized: false }; + if (offset === 0) { runtime.observe('OFFSET_FALLBACK:FIRST_PAGE'); return { query: clone, execution }; } + let cursor: any; try { + cursor = await observeRuntimeOperation(this.runtimeTelemetry, { + family: 'cache', + name: 'continuous_page.get', + attributes: { 'teaql.cache.operation': 'get' }, + }, () => runtime.get(queryKey, offset)); + } catch { runtime.observe('OFFSET_FALLBACK:STORE_UNAVAILABLE'); return { query: clone, execution }; } + if (!cursor) { runtime.observe('OFFSET_FALLBACK:CACHE_MISS'); return { query: clone, execution }; } + const seek = { id: { [execution.direction === 'desc' ? '$lt' : '$gt']: cursor.boundary } }; + clone.filterCondition = clone.filterCondition ? { $and: [clone.filterCondition, seek] } : seek; + clone.offsetValue = 0; if (clone._offset !== undefined) clone._offset = 0; + execution.optimized = true; execution.cursorId = cursor.cursorId; + runtime.observe('CURSOR_SEEK', cursor.cursorId); + return { query: clone, execution }; + } + + private async registerContinuousPage(_query: any, execution: any, rows: any[]): Promise { + if (!execution || rows.length !== execution.limit || !rows.length || rows[rows.length - 1].id === undefined) return; + try { + await observeRuntimeOperation(this.runtimeTelemetry, { + family: 'cache', + name: 'continuous_page.put', + attributes: { 'teaql.cache.operation': 'put' }, + }, () => execution.runtime.put(execution.queryKey, execution.offset + rows.length, { + cursorId: `cpg_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`, + boundary: rows[rows.length - 1].id, + expiresAt: Date.now() + execution.ttlSeconds * 1000, + })); + } catch { execution.runtime.observe('OFFSET_FALLBACK:STORE_UNAVAILABLE'); return; } + if (execution.optimized) execution.runtime.observe('CURSOR_SEEK', execution.cursorId); + } + + executeForStream(query: any, chunkSize = 1000): AsyncIterable { + // Capture before returning the lazy iterator. No SQL/cursor is opened here. + // Preserve the asynchronous failure contract, but never re-read a builder + // that the caller may "repair" or repurpose before the first poll. + try { + const request = query instanceof QueryRequest + ? new QueryRequest(query.query, query.intent) : new QueryRequest(query); + return this.executeCapturedStream(request.query, chunkSize); + } catch (error) { + return (async function* (): AsyncIterable { throw error; })(); + } + } + + private async *executeCapturedStream(query: any, chunkSize: number): AsyncIterable { + await this.telemetryStartup; + if (!Number.isInteger(chunkSize) || chunkSize <= 0) { + throw new Error('stream chunk size must be a positive integer'); + } + if (Array.isArray(query.facets) && query.facets.length > 0) { + throw new Error('QRY-F01_STREAM_UNSUPPORTED: execute facets with executeForList'); + } + const { sql, values, aggregateNames } = await this.compileQuery(query); + const inherited = await this.queryTreeBindings(query, sql, values); + const queryScope = startRuntimeOperation(this.runtimeTelemetry, { family: 'query', + name: `${String(query.entity)}.stream`, attributes: { 'teaql.entity.type': String(query.entity) } }); + let providerScope!: RuntimeTelemetryScope; + const startProvider = async () => { providerScope = startRuntimeOperation(this.runtimeTelemetry, { + family: 'provider', name: `${this.driver.databaseKind}.stream`, attributes: { + 'teaql.provider.kind': this.driver.databaseKind, 'teaql.provider.operation': 'query' } }); }; + await (queryScope.run ? queryScope.run(startProvider) : startProvider()); + const correlation = providerScope.correlation?.(); + const iterator = this.driver.stream(sql, values)[Symbol.asyncIterator](); + const startedAt = Date.now(); + let outcome: SQLExecutionOutcome = 'cancelled'; + let delivered = 0; + let chunk: any[] = []; + const descendantBindings = this.descendantBindings(query, sql, values, inherited); + try { + while (true) { + const next = await (providerScope.run ? providerScope.run(() => iterator.next()) : iterator.next()); + if (next.done) break; + chunk.push(this.decodeRow(query.entity, next.value, aggregateNames)); + if (chunk.length === chunkSize) { + await this.enhanceQueryRows(chunk, query, descendantBindings); + delivered += chunk.length; + yield chunk as T[]; + chunk = []; + } + } + if (chunk.length) { + await this.enhanceQueryRows(chunk, query, descendantBindings); + delivered += chunk.length; + yield chunk as T[]; + } + outcome = 'success'; + } catch (error) { + outcome = 'failure'; + providerScope.failure(error); queryScope.failure(error); + throw error; + } finally { + try { await iterator.return?.(); } + catch (error) { + if (outcome !== 'failure') { + outcome = 'failure'; + providerScope.failure(error); queryScope.failure(error); + throw error; + } + } finally { + // Generator.return()/consumer break also closes the driver's cursor. Report + // only delivered rows, not prefetched rows, and never stringify an error. + if (outcome === 'failure') { + try { this.recordSQL('select', sql, values, startedAt, delivered, undefined, + this.queryLogIntent(query), outcome, inherited, correlation); } catch { /* preserve driver failure */ } + } else { + this.recordSQL('select', sql, values, startedAt, delivered, undefined, + this.queryLogIntent(query), outcome, inherited, correlation); + providerScope.success({ attributes: { 'teaql.result.cardinality': delivered } }); + queryScope.success({ attributes: { 'teaql.result.cardinality': delivered } }); + } + } + } + } + + private async enhanceQueryRows(rows: any[], query: any, inherited?: SQLLogBindingSource): Promise { + if (!rows.length) return; + const names = [...(query.relations ?? []).map((load: any) => load.name), + ...(query.relationAggregates ?? []).map((aggregate: any) => aggregate.relationName)]; + if (!names.length) return; + const schema = this.schema(query.entity); + const keys = new Map(); + for (const name of names) { + const relation = schema.relations?.[name]; + if (!relation) throw new Error(`Missing relation ${query.entity}.${name}`); + if (!keys.has(relation.localKey)) keys.set(relation.localKey, rows.map(row => row[relation.localKey])); + } + // Lists and each streamed chunk capture before aliases or sibling loads can + // replace any scalar key. Keep existing execution order and trace sources. + await this.enhanceRelationAggregates(rows, query, keys, inherited); + await this.enhanceRelations(rows, query, keys, inherited); + } + + private async enhanceRelations(parents: any[], query: any, keys: ReadonlyMap, + inherited?: SQLLogBindingSource): Promise { + if (!parents.length || !Array.isArray(query.relations) || !query.relations.length) return; + const parentSchema = this.schema(query.entity); + const intent = new QueryRequest(query).intent; + for (const load of query.relations) { + const relation = parentSchema.relations?.[load.name]; + if (!relation) throw new Error(`Missing relation ${query.entity}.${load.name}`); + const parentKeys = keys.get(relation.localKey)!; + const parentIds = parentKeys + .filter(value => value !== undefined && value !== null); + const limit = load.query ? this.queryLimit(load.query) : undefined; + const threshold = load.query?.localTopNProbeParentThreshold?.(); + const boundedTopN = relation.many && limit !== undefined; + const requestedChildFields = Array.isArray(load.query?.selectItems) + ? load.query.selectItems + : []; + const implicitRelationKey = requestedChildFields.length > 0 + && !requestedChildFields.includes(relation.foreignKey); + const providerAlwaysProbe = this.driver.topNRelationPlanPolicy === 'alwaysProbe'; + const useProbes = boundedTopN && (threshold === undefined + ? providerAlwaysProbe + : threshold > 0 && parentIds.length <= threshold); + const selectedPlan = useProbes ? 'bounded_probes' : 'window'; + const relationScope = startRuntimeOperation(this.runtimeTelemetry, { + family: 'relation_load', + name: `${query.entity}.${String(load.name)}`, + attributes: { + 'teaql.entity.type': String(query.entity), + 'teaql.relation.name': String(load.name), + 'teaql.relation.parent_count': parentIds.length, + 'teaql.relation.per_parent_limit': limit ?? 0, + 'teaql.relation.configured_probe_threshold': threshold ?? 'provider-default', + 'teaql.relation.selected_plan': selectedPlan, + 'teaql.relation.probe_count': useProbes ? parentIds.length : 0, + }, + }); + try { + if (!parentIds.length && !(relation.many && load.query?.facets?.length)) { + for (const parent of parents) parent[load.name] = relation.many ? [] : null; + relationScope.success({ attributes: { 'teaql.result.cardinality': 0 } }); + continue; + } + const childQuery = { + ...(load.query || {}), + entity: relation.targetEntity, + // Relation assembly keys belong to the runtime protocol. Callers should + // not have to expose selectId()/selectOrderId() in their domain query. + selectItems: implicitRelationKey + ? [...requestedChildFields, relation.foreignKey] + : requestedChildFields, + _filters: [...this.filters(load.query || {})], + relations: [...(load.query?.relations || [])], + orderItems: [...(load.query?.orderItems || [])], + __teaqlPartitionBy: boundedTopN && !useProbes + ? relation.foreignKey + : undefined, + }; + if (boundedTopN) { + // Aggregate rows have group identity, not source-row identity. An + // ungrouped id is invalid on strict SQL engines and cannot break ties. + const groups = this.groupBy(childQuery); + const stableFields = groups.length || this.aggregates(childQuery).length ? groups : ['id']; + for (const field of stableFields) { + if (!childQuery.orderItems.some((order: any) => order.field === field)) { + childQuery.orderItems.push(OrderBy.asc(field)); + } + } + } + if (typeof childQuery.clearContinuousPageRuntime === 'function') childQuery.clearContinuousPageRuntime(); + childQuery[this.internalQueryToken] = true; + const children: any[] = []; + const assembly: RelationAssembly = { field: relation.foreignKey, keys: new WeakMap() }; + if (useProbes) { + for (const parentId of parentIds) { + const probeQuery = { + ...childQuery, + _filters: [...childQuery._filters, { [relation.foreignKey]: { $eq: parentId } }], + __teaqlPartitionBy: undefined, + }; + children.push(...await this.executeDerivedQuery( + new QueryRequest(query).derive(probeQuery, load.name, load.operation).query, inherited, intent, assembly)); + } + } else { + childQuery._filters.push({ [relation.foreignKey]: { $in: parentIds } }); + children.push(...await this.executeDerivedQuery( + new QueryRequest(query).derive(childQuery, load.name, load.operation).query, inherited, intent, assembly)); + } + for (const child of children) delete child.__teaql_partition_rank; + const buckets = new Map(); + for (const child of children) { + if (!assembly.keys.has(child)) throw new Error('Relation assembly lost its captured row identity'); + const key = assembly.keys.get(child); + const bucket = buckets.get(key) || []; + bucket.push(child); + buckets.set(key, bucket); + } + if (implicitRelationKey) { + for (const child of children) delete child[relation.foreignKey]; + } + for (const [index, parent] of parents.entries()) { + const related = buckets.get(parentKeys[index]) || []; + if (relation.many && load.query?.facets?.length) { + // Each loaded collection owns its own facet membership. The full + // filtered child set, not its Top-N page or other parents, is counted. + const facetQuery: SelectQuery = load.query.clone(); + facetQuery.entity = relation.targetEntity; + // A missing local key means no relationship, never orphan rows with + // a NULL foreign key. Empty IN compiles to an unsatisfiable predicate. + const key = parentKeys[index]; + const membership = { [relation.foreignKey]: key === null || key === undefined + ? { $in: [] } : { $eq: key } }; + facetQuery.filterCondition = facetQuery.filterCondition + ? { $and: [facetQuery.filterCondition, membership] } : membership; + retainQueryDiagnosticOrigin(query, facetQuery); + const derived = new QueryRequest(query).derive(facetQuery, load.name, load.operation).query; + parent[load.name] = new SmartList(related, { facets: + await executeRelationFacets(this, item => item, derived, facetQuery.facets) }); + } else { + // A failed detail selection does not erase the captured FK. Missing + // target properties remain absent (NotLoaded), never loaded-null. + const key = parentKeys[index]; + parent[load.name] = relation.many ? related : (related[0] ?? + (key === null || key === undefined ? null : { [relation.foreignKey]: key })); + } + } + relationScope.success({ attributes: { 'teaql.result.cardinality': children.length } }); + } catch (error) { + relationScope.failure(error); + throw error; + } + } + } + + private async enhanceRelationAggregates(parents: any[], query: any, keys: ReadonlyMap, + inherited?: SQLLogBindingSource): Promise { + const aggregates = query.relationAggregates; + if (!parents.length || !Array.isArray(aggregates) || !aggregates.length) return; + const parentSchema = this.schema(query.entity); + const intent = new QueryRequest(query).intent; + for (const aggregate of aggregates) { + const relation = parentSchema.relations?.[aggregate.relationName]; + if (!relation) throw new Error(`Missing relation ${query.entity}.${aggregate.relationName}`); + const parentKeys = keys.get(relation.localKey)!; + const parentIds = parentKeys + .filter(value => value !== undefined && value !== null); + if (!parentIds.length) { + for (const parent of parents) { + parent[aggregate.alias] = aggregate.singleResult + ? this.emptyAggregateValue(aggregate.query) + : {}; + } + continue; + } + const childQuery: SelectQuery = aggregate.query.clone(); + childQuery.entity = relation.targetEntity; + childQuery.selectItems = []; + childQuery.properties = []; + childQuery.orderItems = []; + childQuery.limitValue = 0; + childQuery.offsetValue = 0; + childQuery.relations = []; + childQuery.relationAggregates = []; + if (!childQuery.aggregateItems.length) { + childQuery.aggregate('Count', 'id', aggregate.alias); + } + if (!childQuery.groupByItems.includes(relation.foreignKey)) { + childQuery.groupBy(relation.foreignKey); + } + const membership = { [relation.foreignKey]: { $in: parentIds } }; + childQuery.filterCondition = childQuery.filterCondition + ? { $and: [childQuery.filterCondition, membership] } : membership; + (childQuery as any)[this.internalQueryToken] = true; + const rows = await this.executeDerivedQuery( + new QueryRequest(query).deriveAggregate(childQuery, aggregate.relationName, aggregate.operation ?? { + kind: 'relation-count', relation: aggregate.relationName, alias: aggregate.alias, + }).query, inherited, intent); + const buckets = new Map(); + for (const row of rows) buckets.set(row[relation.foreignKey], row); + for (const [index, parent] of parents.entries()) { + const row = buckets.get(parentKeys[index]); + if (!row) { + parent[aggregate.alias] = aggregate.singleResult + ? this.emptyAggregateValue(aggregate.query) + : {}; + } else if (aggregate.singleResult) { + parent[aggregate.alias] = row[childQuery.aggregateItems[0].alias] ?? null; + } else { + parent[aggregate.alias] = Object.fromEntries( + Object.entries(row).filter(([key]) => key !== relation.foreignKey), + ); + } + } + } + } + + private emptyAggregateValue(query: SelectQuery): unknown { + const aggregate = query.aggregateItems[0]; + return !aggregate || String(aggregate.function).toLowerCase() === 'count' ? 0 : null; + } + + private queryLimit(query: any): number | undefined { + if (query._limit !== undefined) return Number(query._limit); + if (query.limitValue !== undefined && Number(query.limitValue) > 0) { + return Number(query.limitValue); + } + return undefined; + } + + async close(): Promise { + try { await this.driver.close(); } + finally { + await this.telemetryStartup; + await this.standardTelemetryHandle?.release(); + this.standardTelemetryHandle = undefined; + } + } +} + +export function assertSafeIdentifier(value: string): string { + if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) { + throw new Error(`Unsafe SQL identifier: ${value}`); + } + return value; +} + +export function standardAggregateFunction(name: string): string { + const functions: Record = { + count: 'COUNT', + sum: 'SUM', + avg: 'AVG', + min: 'MIN', + max: 'MAX', + }; + const sqlFunction = functions[String(name).toLowerCase()]; + if (!sqlFunction) throw new Error(`Unsupported aggregate: ${name}`); + return sqlFunction; +} diff --git a/source/teaql-ts/src/sql/expo-sqlite.ts b/source/teaql-ts/src/sql/expo-sqlite.ts new file mode 100644 index 0000000000000000000000000000000000000000..62c852ba85b91c58714e8d2893d73ee4e0bdca2f --- /dev/null +++ b/source/teaql-ts/src/sql/expo-sqlite.ts @@ -0,0 +1,229 @@ +import { + AbstractSQLTeaQLClient, + assertSafeIdentifier, + ColumnSchema, + EntitySchema, + LogicalColumnType, + SqlQueryResult, + SqlSession, + standardAggregateFunction, + ensureOptimisticIdFloor, + TeaQLSqlDriver, + canonicalRelationIndexes, +} from './core'; + +export type ExpoSQLiteBindValue = null | number | string | Uint8Array; + +export interface ExpoSQLiteExecuteResult> + extends AsyncIterableIterator { + changes: number; + getAllAsync(): Promise; +} + +export interface ExpoSQLiteStatement { + executeAsync>( + params: ExpoSQLiteBindValue[], + ): Promise>; + finalizeAsync(): Promise; +} + +export interface ExpoSQLiteDatabaseLike { + execAsync(sql: string): Promise; + prepareAsync(sql: string): Promise; + withExclusiveTransactionAsync( + work: (transaction: ExpoSQLiteDatabaseLike) => Promise, + ): Promise; + closeAsync(): Promise; +} + +class ExpoSQLiteSession implements SqlSession { + constructor(private readonly database: ExpoSQLiteDatabaseLike) {} + + async query(sql: string, values: any[] = []): Promise { + const statement = await this.database.prepareAsync(sql); + try { + const result = await statement.executeAsync(values as ExpoSQLiteBindValue[]); + const rows = await result.getAllAsync(); + return { rows, rowCount: rows.length || Number(result.changes || 0) }; + } finally { + await statement.finalizeAsync(); + } + } +} + +/** + * TeaQL SQL driver for an opened `expo-sqlite` database. + * + * The structural database type keeps `teaql-ts` importable in Node and browser + * profiles. A React Native application opens the database with + * `expo-sqlite.openDatabaseAsync()` and injects it here through UserContext. + */ +export class ExpoSQLiteDriver implements TeaQLSqlDriver { + readonly databaseKind = 'sqlite' as const; + private initialized?: Promise; + + constructor(private readonly database: ExpoSQLiteDatabaseLike) { + if (!database) throw new Error('opened Expo SQLite database is required'); + } + + identifier(value: string): string { + return `"${assertSafeIdentifier(value)}"`; + } + + placeholder(_index: number): string { + return '?'; + } + + encode(value: any, column?: ColumnSchema): ExpoSQLiteBindValue { + if (value === null || value === undefined) return value as ExpoSQLiteBindValue; + if (column?.logicalType === 'json' && typeof value !== 'string') { + return JSON.stringify(value); + } + if (column?.logicalType === 'boolean') return value ? 1 : 0; + if (value instanceof Date) return value.toISOString(); + return value as ExpoSQLiteBindValue; + } + + contains(columnSql: string, placeholder: string): string { + return `CAST(${columnSql} AS TEXT) LIKE '%' || ${placeholder} || '%'`; + } + + aggregateFunction(name: string): string { + return standardAggregateFunction(name); + } + + private sqlType(type: LogicalColumnType): string { + const types: Record = { + boolean: 'INTEGER', + double: 'REAL', + decimal: 'NUMERIC', + date: 'TEXT', + datetime: 'TEXT', + json: 'TEXT', + integer: 'INTEGER', + text: 'TEXT', + }; + return types[type]; + } + + private initialize(): Promise { + if (!this.initialized) { + this.initialized = this.database.execAsync( + 'PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;', + ); + } + return this.initialized; + } + + async ensureSchema(schemas: Record): Promise { + await this.initialize(); + for (const schema of Object.values(schemas)) { + const table = this.identifier(schema.table); + await this.query( + `CREATE TABLE IF NOT EXISTS ${table} (` + + '"id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)', + ); + const columns = await this.query(`PRAGMA table_info(${table})`); + const existing = new Set(columns.rows.map(row => String(row.name))); + for (const [field, column] of Object.entries(schema.columns)) { + if (field === 'id' || field === 'version' || + existing.has(column.columnName)) continue; + await this.query( + `ALTER TABLE ${table} ADD COLUMN ` + + `${this.identifier(column.columnName)} ${this.sqlType(column.logicalType)}` + + `${column.nullable === false ? ' NOT NULL' : ''}`, + ); + } + } + for (const index of canonicalRelationIndexes(schemas)) { + await this.query( + `CREATE INDEX IF NOT EXISTS ${this.identifier(index.name)} ON ` + + `${this.identifier(index.table)} (` + + `${this.identifier(index.foreignColumn)}, ${this.identifier(index.idColumn)} DESC)`, + ); + } + await this.query( + 'CREATE TABLE IF NOT EXISTS teaql_id_space (' + + 'type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)', + ); + } + + async transaction(work: (session: SqlSession) => Promise): Promise { + let value: T | undefined; + await this.database.withExclusiveTransactionAsync(async transaction => { + value = await work(new ExpoSQLiteSession(transaction)); + }); + return value as T; + } + + async nextId(session: SqlSession, entity: string): Promise { + for (let attempt = 1; attempt <= 100; attempt += 1) { + const current = await session.query( + 'SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?', + [entity], + ); + if (!current.rowCount) { + try { + const inserted = await session.query( + 'INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)', + [entity], + ); + if (inserted.rowCount === 1) return '1'; + } catch (error) { + const winner = await session.query( + 'SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?', + [entity], + ); + if (!winner.rowCount) throw error; + } + continue; + } + const previous = Number(current.rows[0].id); + const next = previous + 1; + const updated = await session.query( + 'UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?', + [next, entity, previous], + ); + if (updated.rowCount === 1) return String(next); + if (updated.rowCount !== 0) { + throw new Error(`ID space update for ${entity} changed ${updated.rowCount} rows`); + } + } + throw new Error( + `Unable to allocate ID for ${entity} after 100 optimistic-lock attempts`, + ); + } + + ensureIdFloor(session: SqlSession, entity: string, floor: string): Promise { + return ensureOptimisticIdFloor(session, index => this.placeholder(index), entity, floor); + } + + async query(sql: string, values: any[] = []): Promise { + return new ExpoSQLiteSession(this.database).query(sql, values); + } + + async *stream(sql: string, values: any[] = []): AsyncIterable { + const statement = await this.database.prepareAsync(sql); + try { + const result = await statement.executeAsync( + values as ExpoSQLiteBindValue[], + ); + for await (const row of result) yield row; + } finally { + await statement.finalizeAsync(); + } + } + + async close(): Promise { + await this.database.closeAsync(); + } +} + +export class ExpoSQLiteTeaQLClient extends AbstractSQLTeaQLClient { + constructor( + database: ExpoSQLiteDatabaseLike, + schemas: Record, + ) { + super(new ExpoSQLiteDriver(database), schemas); + } +} diff --git a/source/teaql-ts/src/sql/index.ts b/source/teaql-ts/src/sql/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..c5f5b2c005bf004cb73a4f452f5884bb2334fb6a --- /dev/null +++ b/source/teaql-ts/src/sql/index.ts @@ -0,0 +1,5 @@ +export * from './core'; +export * from './postgres'; +export * from './mysql'; +export * from './sqlite'; +export * from './expo-sqlite'; diff --git a/source/teaql-ts/src/sql/log-rendering.ts b/source/teaql-ts/src/sql/log-rendering.ts new file mode 100644 index 0000000000000000000000000000000000000000..2f796cb3a38a453a5bb4e4287932bbdd485eb9da --- /dev/null +++ b/source/teaql-ts/src/sql/log-rendering.ts @@ -0,0 +1,142 @@ +/** Render provider placeholders as SQL literals so the statement can be copied into a SQL client. */ +export type SQLDatabaseKind = 'postgresql' | 'mysql' | 'sqlite'; +export type SQLParameterLogPolicy = 'plain' | 'masked' | 'credential' | 'unknown'; + +export function debugSQL( + parameterizedSQL: string, + parameters: readonly unknown[], + databaseKind: SQLDatabaseKind = 'sqlite', +): string { + return renderSQL(parameterizedSQL, parameters, databaseKind); +} + +/** Shared scanner for diagnostics. A callback enables strict bind accounting. */ +export function renderSQL( + parameterizedSQL: string, + parameters: readonly unknown[], + databaseKind: SQLDatabaseKind, + parameterLiteral?: (index: number) => string, +): string { + if (parameterLiteral && !parameterizedSQL.trim()) throw new Error('Missing SQL template'); + let positionalIndex = 0; + const used = new Set(); + const literal = (index: number): string => { + if (index < 0 || index >= parameters.length) throw new Error('SQL bind count mismatch'); + used.add(index); + return parameterLiteral ? parameterLiteral(index) : sqlLiteral(parameters[index], databaseKind); + }; + let result = ''; + let state: 'sql' | 'single' | 'double' | 'backtick' | 'line-comment' | 'block-comment' = 'sql'; + for (let index = 0; index < parameterizedSQL.length; index++) { + const char = parameterizedSQL[index]; + const next = parameterizedSQL[index + 1] ?? ''; + if (state === 'sql' && char === "'") { + result += char; + state = 'single'; + continue; + } + if (state === 'sql' && char === '"') { result += char; state = 'double'; continue; } + if (state === 'sql' && char === '`') { result += char; state = 'backtick'; continue; } + if (state === 'sql' && char === '-' && next === '-') { + result += '--'; index++; state = 'line-comment'; continue; + } + if (state === 'sql' && char === '/' && next === '*') { + result += '/*'; index++; state = 'block-comment'; continue; + } + if (state === 'single') { + result += char; + if (char === "'" && next === "'") result += parameterizedSQL[++index]; + else if (char === "'") state = 'sql'; + continue; + } + if (state === 'double') { + result += char; + if (char === '"' && next === '"') result += parameterizedSQL[++index]; + else if (char === '"') state = 'sql'; + continue; + } + if (state === 'backtick') { + result += char; + if (char === '`' && next === '`') result += parameterizedSQL[++index]; + else if (char === '`') state = 'sql'; + continue; + } + if (state === 'line-comment') { + result += char; + if (char === '\r' || char === '\n') state = 'sql'; + continue; + } + if (state === 'block-comment') { + result += char; + if (char === '*' && next === '/') { result += '/'; index++; state = 'sql'; } + continue; + } + if (char === '?') { + if (parameterLiteral || positionalIndex < parameters.length) result += literal(positionalIndex++); + else result += char; + continue; + } + if (char === '$' && /[0-9]/.test(parameterizedSQL[index + 1] ?? '')) { + let end = index + 1; + while (/[0-9]/.test(parameterizedSQL[end] ?? '')) end++; + const parameterIndex = Number(parameterizedSQL.slice(index + 1, end)) - 1; + result += parameterLiteral || (parameterIndex >= 0 && parameterIndex < parameters.length) + ? literal(parameterIndex) : parameterizedSQL.slice(index, end); + index = end - 1; + continue; + } + if (parameterizedSQL.slice(index).match(/^@p[0-9]+/i)) { + const placeholder = parameterizedSQL.slice(index).match(/^@p([0-9]+)/i)!; + const parameterIndex = Number(placeholder[1]) - 1; + result += parameterLiteral || (parameterIndex >= 0 && parameterIndex < parameters.length) + ? literal(parameterIndex) : placeholder[0]; + index += placeholder[0].length - 1; + continue; + } + result += char; + } + if (parameterLiteral && (used.size !== parameters.length || (state !== 'sql' && state !== 'line-comment'))) { + throw new Error('Incomplete SQL diagnostic rendering'); + } + return result; +} + +export function sqlLiteral(value: unknown, databaseKind: SQLDatabaseKind): string { + if (value && typeof value === 'object' && 'type' in value) { + const typed = value as { type: string; value?: unknown }; + if (typed.type === 'Null' || typed.type === 'TypedNull') return 'NULL'; + if (typed.type === 'Date') { + const date = typed.value instanceof Date + ? typed.value.toISOString().slice(0, 10) : String(typed.value); + if (databaseKind === 'postgresql') return `DATE ${quoteSQLString(date)}`; + if (databaseKind === 'mysql') return `CAST(${quoteSQLString(date)} AS DATE)`; + return quoteSQLString(date); + } + if (typed.type === 'Timestamp') { + if (databaseKind === 'sqlite') return String(typed.value); + const iso = new Date(Number(typed.value)).toISOString(); + if (databaseKind === 'postgresql') return `TIMESTAMPTZ ${quoteSQLString(iso)}`; + return `CAST(${quoteSQLString(iso.slice(0, 23).replace('T', ' '))} AS DATETIME(3))`; + } + if (typed.type === 'Bool') return typed.value ? 'TRUE' : 'FALSE'; + if (['I64', 'U64', 'F64', 'Decimal'].includes(typed.type)) return String(typed.value); + if (typed.type === 'Text') return quoteSQLString(String(typed.value)); + } + if (value === null || value === undefined) return 'NULL'; + if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE'; + if (typeof value === 'number' || typeof value === 'bigint') return String(value); + if (value instanceof Date) { + if (databaseKind === 'sqlite') return String(value.getTime()); + if (databaseKind === 'postgresql') return `TIMESTAMPTZ ${quoteSQLString(value.toISOString())}`; + return `CAST(${quoteSQLString(value.toISOString().slice(0, 23).replace('T', ' '))} AS DATETIME(3))`; + } + if (value instanceof Uint8Array) { + return `X'${Array.from(value, byte => byte.toString(16).padStart(2, '0')).join('')}'`; + } + if (typeof value === 'object') return quoteSQLString(JSON.stringify(value)); + return quoteSQLString(String(value)); +} + +function quoteSQLString(value: string): string { + return `'${value.replace(/'/g, "''")}'`; +} diff --git a/source/teaql-ts/src/sql/mysql.ts b/source/teaql-ts/src/sql/mysql.ts new file mode 100644 index 0000000000000000000000000000000000000000..6a667af2fdd45ec0f9fc60a03367f4ebd9a5a923 --- /dev/null +++ b/source/teaql-ts/src/sql/mysql.ts @@ -0,0 +1,205 @@ +import { createPool as createCallbackPool, Pool as CallbackPool } from 'mysql2'; +import { Pool, PoolConnection } from 'mysql2/promise'; +import { + AbstractSQLTeaQLClient, + assertSafeIdentifier, + ColumnSchema, + EntitySchema, + LogicalColumnType, + SqlQueryResult, + SqlSession, + standardAggregateFunction, + ensureOptimisticIdFloor, + TeaQLSqlDriver, + canonicalRelationIndexes, +} from './core'; + +class MySQLSession implements SqlSession { + constructor(private readonly client: Pool | PoolConnection) {} + + async query(sql: string, values: any[] = []): Promise { + const [raw]: any = await (this.client as any).query(sql, values); + if (Array.isArray(raw)) return { rows: raw, rowCount: raw.length }; + return { rows: [], rowCount: Number(raw?.affectedRows || 0) }; + } +} + +export class MySQLDriver implements TeaQLSqlDriver { + readonly databaseKind = 'mysql' as const; + private readonly callbackPool: CallbackPool; + private readonly pool: Pool; + + constructor(connectionString: string) { + if (!connectionString) throw new Error('connectionString is required'); + this.callbackPool = createCallbackPool({ uri: connectionString, timezone: 'Z' }); + this.pool = this.callbackPool.promise(); + } + + identifier(value: string): string { + return `\`${assertSafeIdentifier(value)}\``; + } + + placeholder(_index: number): string { + return '?'; + } + + encode(value: any, column?: ColumnSchema): any { + if (value === null || value === undefined) return value; + if (column?.logicalType === 'json' && typeof value !== 'string') { + return JSON.stringify(value); + } + if (column?.logicalType === 'boolean') return value ? 1 : 0; + return value; + } + + contains(columnSql: string, placeholder: string): string { + return `CAST(${columnSql} AS CHAR) LIKE CONCAT('%', ${placeholder}, '%')`; + } + + aggregateFunction(name: string): string { + const functions: Record = { + stddev: 'STDDEV_SAMP', + stddevpop: 'STDDEV_POP', + varsamp: 'VAR_SAMP', + varpop: 'VAR_POP', + bitand: 'BIT_AND', + bitor: 'BIT_OR', + bitxor: 'BIT_XOR', + }; + return functions[String(name).toLowerCase()] + || standardAggregateFunction(name); + } + + private sqlType(type: LogicalColumnType): string { + const types: Record = { + boolean: 'BOOLEAN', + double: 'DOUBLE', + decimal: 'DECIMAL(65, 30)', + date: 'DATE', + datetime: 'DATETIME(6)', + json: 'JSON', + integer: 'BIGINT', + text: 'TEXT', + }; + return types[type]; + } + + async ensureSchema(schemas: Record): Promise { + for (const schema of Object.values(schemas)) { + const table = this.identifier(schema.table); + await this.query( + `CREATE TABLE IF NOT EXISTS ${table} (` + + '`id` BIGINT PRIMARY KEY, `version` BIGINT NOT NULL)', + ); + for (const [field, column] of Object.entries(schema.columns)) { + if (field === 'id' || field === 'version') continue; + const existing = await this.query( + 'SELECT 1 FROM information_schema.columns ' + + 'WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?', + [schema.table, column.columnName], + ); + if (!existing.rowCount) { + await this.query( + `ALTER TABLE ${table} ADD COLUMN ` + + `${this.identifier(column.columnName)} ${this.sqlType(column.logicalType)}` + + `${column.nullable === false ? ' NOT NULL' : ''}`, + ); + } + } + } + for (const index of canonicalRelationIndexes(schemas)) { + const existing = await this.query( + 'SELECT 1 FROM information_schema.statistics ' + + 'WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?', + [index.table, index.name], + ); + if (!existing.rowCount) { + await this.query( + `CREATE INDEX ${this.identifier(index.name)} ON ` + + `${this.identifier(index.table)} (` + + `${this.identifier(index.foreignColumn)}, ${this.identifier(index.idColumn)} DESC)`, + ); + } + } + await this.query( + 'CREATE TABLE IF NOT EXISTS teaql_id_space (' + + 'type_name VARCHAR(255) PRIMARY KEY, current_level BIGINT NOT NULL)', + ); + } + + async transaction(work: (session: SqlSession) => Promise): Promise { + const connection = await this.pool.getConnection(); + try { + await connection.beginTransaction(); + const result = await work(new MySQLSession(connection)); + await connection.commit(); + return result; + } catch (error) { + await connection.rollback(); + throw error; + } finally { + connection.release(); + } + } + + async nextId(session: SqlSession, entity: string): Promise { + for (let attempt = 1; attempt <= 100; attempt += 1) { + const result = await session.query( + 'SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?', [entity]); + if (!result.rowCount) { + try { + const inserted = await session.query( + 'INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)', [entity]); + if (inserted.rowCount === 1) return '1'; + } catch (error) { + const winner = await session.query( + 'SELECT current_level FROM teaql_id_space WHERE type_name = ?', [entity]); + if (!winner.rowCount) throw error; + } + continue; + } + const previous = Number(result.rows[0].id); + const next = previous + 1; + const updated = await session.query( + 'UPDATE teaql_id_space SET current_level = ? ' + + 'WHERE type_name = ? AND current_level = ?', [next, entity, previous]); + if (updated.rowCount === 1) return String(next); + if (updated.rowCount !== 0) throw new Error( + `ID space update for ${entity} changed ${updated.rowCount} rows`); + } + throw new Error(`Unable to allocate ID for ${entity} after 100 optimistic-lock attempts`); + } + + ensureIdFloor(session: SqlSession, entity: string, floor: string): Promise { + return ensureOptimisticIdFloor(session, index => this.placeholder(index), entity, floor); + } + + query(sql: string, values: any[] = []): Promise { + return new MySQLSession(this.pool).query(sql, values); + } + + async *stream(sql: string, values: any[] = []): AsyncIterable { + const connection = await new Promise((resolve, reject) => { + this.callbackPool.getConnection((error, value) => error ? reject(error) : resolve(value)); + }); + const readable = connection.query(sql, values).stream(); + try { + for await (const row of readable) yield row; + } finally { + readable.destroy(); + connection.release(); + } + } + + async close(): Promise { + await this.callbackPool.promise().end(); + } +} + +export class MySQLTeaQLClient extends AbstractSQLTeaQLClient { + constructor(connectionString: string, schemas: Record) { + super(new MySQLDriver(connectionString), schemas); + this.attachStandardTelemetryStartup(startStandardNodeTelemetry()); + } +} +import { startStandardNodeTelemetry } from '../telemetry/standard-node'; diff --git a/source/teaql-ts/src/sql/postgres.ts b/source/teaql-ts/src/sql/postgres.ts new file mode 100644 index 0000000000000000000000000000000000000000..b9c9e66e4d8e6c530fa8e70a9fb4f9bcccdcf536 --- /dev/null +++ b/source/teaql-ts/src/sql/postgres.ts @@ -0,0 +1,192 @@ +import { Pool, PoolClient } from 'pg'; +import QueryStream from 'pg-query-stream'; +import { + AbstractSQLTeaQLClient, + assertSafeIdentifier, + ColumnSchema, + EntitySchema, + LogicalColumnType, + SqlQueryResult, + SqlSession, + standardAggregateFunction, + ensureOptimisticIdFloor, + TeaQLSqlDriver, + canonicalRelationIndexes, +} from './core'; + +class PostgreSQLSession implements SqlSession { + constructor(private readonly client: Pool | PoolClient) {} + + async query(sql: string, values: any[] = []): Promise { + const result = await this.client.query(sql, values); + return { rows: result.rows, rowCount: result.rowCount ?? result.rows.length }; + } +} + +export class PostgreSQLDriver implements TeaQLSqlDriver { + readonly databaseKind = 'postgresql' as const; + private readonly pool: Pool; + + constructor(connectionString: string) { + if (!connectionString) throw new Error('connectionString is required'); + this.pool = new Pool({ connectionString }); + } + + identifier(value: string): string { + return `"${assertSafeIdentifier(value)}"`; + } + + placeholder(index: number): string { + return `$${index}`; + } + + encode(value: any, column?: ColumnSchema): any { + if (column?.logicalType === 'json' && typeof value !== 'string') { + return JSON.stringify(value); + } + return value; + } + + contains(columnSql: string, placeholder: string): string { + return `CAST(${columnSql} AS TEXT) LIKE '%' || ${placeholder} || '%'`; + } + + aggregateFunction(name: string): string { + const functions: Record = { + stddev: 'STDDEV', + stddevpop: 'STDDEV_POP', + varsamp: 'VAR_SAMP', + varpop: 'VAR_POP', + bitand: 'BIT_AND', + bitor: 'BIT_OR', + bitxor: 'BIT_XOR', + }; + return functions[String(name).toLowerCase()] + || standardAggregateFunction(name); + } + + private sqlType(type: LogicalColumnType): string { + const types: Record = { + boolean: 'BOOLEAN', + double: 'DOUBLE PRECISION', + decimal: 'NUMERIC', + date: 'DATE', + datetime: 'TIMESTAMPTZ', + json: 'JSONB', + integer: 'BIGINT', + text: 'TEXT', + }; + return types[type]; + } + + async ensureSchema(schemas: Record): Promise { + await this.transaction(async session => { + for (const schema of Object.values(schemas)) { + const table = this.identifier(schema.table); + await session.query( + `CREATE TABLE IF NOT EXISTS ${table} (` + + '"id" BIGINT PRIMARY KEY, "version" BIGINT NOT NULL)', + ); + for (const [field, column] of Object.entries(schema.columns)) { + if (field === 'id' || field === 'version') continue; + await session.query( + `ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS ` + + `${this.identifier(column.columnName)} ${this.sqlType(column.logicalType)}` + + `${column.nullable === false ? ' NOT NULL' : ''}`, + ); + } + } + for (const index of canonicalRelationIndexes(schemas)) { + await session.query( + `CREATE INDEX IF NOT EXISTS ${this.identifier(index.name)} ON ` + + `${this.identifier(index.table)} (` + + `${this.identifier(index.foreignColumn)}, ${this.identifier(index.idColumn)} DESC)`, + ); + } + await session.query( + 'CREATE TABLE IF NOT EXISTS teaql_id_space (' + + 'type_name VARCHAR(255) PRIMARY KEY, current_level BIGINT NOT NULL)', + ); + }); + } + + async transaction(work: (session: SqlSession) => Promise): Promise { + const client = await this.pool.connect(); + try { + await client.query('BEGIN'); + const result = await work(new PostgreSQLSession(client)); + await client.query('COMMIT'); + return result; + } catch (error) { + await client.query('ROLLBACK'); + throw error; + } finally { + client.release(); + } + } + + async nextId(session: SqlSession, entity: string): Promise { + for (let attempt = 1; attempt <= 100; attempt += 1) { + const result = await session.query( + 'SELECT current_level::text AS id FROM teaql_id_space WHERE type_name = $1', + [entity], + ); + if (!result.rowCount) { + try { + const inserted = await session.query( + 'INSERT INTO teaql_id_space(type_name, current_level) VALUES ($1, 1)', + [entity], + ); + if (inserted.rowCount === 1) return '1'; + } catch (error) { + const winner = await session.query( + 'SELECT current_level FROM teaql_id_space WHERE type_name = $1', [entity]); + if (!winner.rowCount) throw error; + } + continue; + } + const previous = Number(result.rows[0].id); + const next = previous + 1; + const updated = await session.query( + 'UPDATE teaql_id_space SET current_level = $1 ' + + 'WHERE type_name = $2 AND current_level = $3', + [next, entity, previous], + ); + if (updated.rowCount === 1) return String(next); + if (updated.rowCount !== 0) throw new Error( + `ID space update for ${entity} changed ${updated.rowCount} rows`); + } + throw new Error(`Unable to allocate ID for ${entity} after 100 optimistic-lock attempts`); + } + + ensureIdFloor(session: SqlSession, entity: string, floor: string): Promise { + return ensureOptimisticIdFloor(session, index => this.placeholder(index), entity, floor); + } + + query(sql: string, values: any[] = []): Promise { + return new PostgreSQLSession(this.pool).query(sql, values); + } + + async *stream(sql: string, values: any[] = []): AsyncIterable { + const client = await this.pool.connect(); + const cursor = client.query(new QueryStream(sql, values)); + try { + for await (const row of cursor as any) yield row; + } finally { + cursor.destroy(); + client.release(); + } + } + + async close(): Promise { + await this.pool.end(); + } +} + +export class PostgreSQLTeaQLClient extends AbstractSQLTeaQLClient { + constructor(connectionString: string, schemas: Record) { + super(new PostgreSQLDriver(connectionString), schemas); + this.attachStandardTelemetryStartup(startStandardNodeTelemetry()); + } +} +import { startStandardNodeTelemetry } from '../telemetry/standard-node'; diff --git a/source/teaql-ts/src/sql/sqlite.ts b/source/teaql-ts/src/sql/sqlite.ts new file mode 100644 index 0000000000000000000000000000000000000000..b2803495381a066a8c3d7c533c60da6b5ab37453 --- /dev/null +++ b/source/teaql-ts/src/sql/sqlite.ts @@ -0,0 +1,214 @@ +import Database from 'better-sqlite3'; +import { startStandardNodeTelemetry } from '../telemetry/standard-node'; +import { + AbstractSQLTeaQLClient, + assertSafeIdentifier, + ColumnSchema, + EntitySchema, + LogicalColumnType, + SqlQueryResult, + SqlSession, + standardAggregateFunction, + ensureOptimisticIdFloor, + TeaQLSqlDriver, + canonicalRelationIndexes, +} from './core'; + +function soundex(value: unknown): string { + const letters = String(value ?? '').toUpperCase().match(/[A-Z]/g) ?? []; + if (!letters.length) return '?000'; + const groups: Record = {}; + for (const [chars, code] of [['BFPV', '1'], ['CGJKQSXZ', '2'], ['DT', '3'], ['L', '4'], ['MN', '5'], ['R', '6']]) { + for (const char of chars) groups[char] = code; + } + const first = letters[0]!; + let result: string = first; + let previous = groups[first] ?? '0'; + for (const letter of letters.slice(1)) { + const current = groups[letter] ?? '0'; + if (current !== '0' && current !== previous) result += current; + if (result.length === 4) break; + previous = current; + } + return result.padEnd(4, '0'); +} + +export class SQLiteDriver implements TeaQLSqlDriver, SqlSession { + readonly databaseKind = 'sqlite' as const; + readonly topNRelationPlanPolicy = 'alwaysProbe' as const; + private readonly database: Database.Database; + private soundexRegistered = false; + + constructor(filename: string) { + if (!filename) throw new Error('filename is required'); + this.database = new Database(filename); + this.database.pragma('journal_mode = WAL'); + this.database.pragma('foreign_keys = ON'); + } + + identifier(value: string): string { + return `"${assertSafeIdentifier(value)}"`; + } + + placeholder(_index: number): string { + return '?'; + } + + encode(value: any, column?: ColumnSchema): any { + if (value === null || value === undefined) return value; + if (column?.logicalType === 'json' && typeof value !== 'string') { + return JSON.stringify(value); + } + if (column?.logicalType === 'boolean') return value ? 1 : 0; + if (column?.logicalType === 'date') { + return value instanceof Date ? value.toISOString().slice(0, 10) : value; + } + if (column?.logicalType === 'datetime') { + if (value instanceof Date) return value.getTime(); + if (typeof value === 'string') { + const millis = Date.parse(value); + if (!Number.isNaN(millis)) return millis; + } + } + return value; + } + + contains(columnSql: string, placeholder: string): string { + return `CAST(${columnSql} AS TEXT) LIKE '%' || ${placeholder} || '%'`; + } + + aggregateFunction(name: string): string { + return standardAggregateFunction(name); + } + + private sqlType(type: LogicalColumnType): string { + const types: Record = { + boolean: 'INTEGER', + double: 'REAL', + decimal: 'NUMERIC', + date: 'TEXT', + datetime: 'INTEGER', + json: 'TEXT', + integer: 'INTEGER', + text: 'TEXT', + }; + return types[type]; + } + + async ensureSchema(schemas: Record): Promise { + if (!this.soundexRegistered) { + this.database.function('soundex', { deterministic: true }, soundex); + this.soundexRegistered = true; + } + for (const schema of Object.values(schemas)) { + const table = this.identifier(schema.table); + await this.query( + `CREATE TABLE IF NOT EXISTS ${table} (` + + '"id" INTEGER PRIMARY KEY, "version" INTEGER NOT NULL)', + ); + const columns = await this.query(`PRAGMA table_info(${table})`); + const existing = new Set(columns.rows.map(row => String(row.name))); + for (const [field, column] of Object.entries(schema.columns)) { + if (field === 'id' || field === 'version' || + existing.has(column.columnName)) continue; + await this.query( + `ALTER TABLE ${table} ADD COLUMN ` + + `${this.identifier(column.columnName)} ${this.sqlType(column.logicalType)}` + + `${column.nullable === false ? ' NOT NULL' : ''}`, + ); + } + } + for (const index of canonicalRelationIndexes(schemas)) { + await this.query( + `CREATE INDEX IF NOT EXISTS ${this.identifier(index.name)} ON ` + + `${this.identifier(index.table)} (` + + `${this.identifier(index.foreignColumn)}, ${this.identifier(index.idColumn)} DESC)`, + ); + } + await this.query( + 'CREATE TABLE IF NOT EXISTS teaql_id_space (' + + 'type_name TEXT PRIMARY KEY, current_level INTEGER NOT NULL)', + ); + } + + async transaction(work: (session: SqlSession) => Promise): Promise { + this.database.exec('BEGIN IMMEDIATE'); + try { + const result = await work(this); + this.database.exec('COMMIT'); + return result; + } catch (error) { + this.database.exec('ROLLBACK'); + throw error; + } + } + + async nextId(session: SqlSession, entity: string): Promise { + for (let attempt = 1; attempt <= 100; attempt += 1) { + const current = await session.query( + 'SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?', + [entity], + ); + if (!current.rowCount) { + try { + const inserted = await session.query( + 'INSERT INTO teaql_id_space(type_name, current_level) VALUES (?, 1)', + [entity], + ); + if (inserted.rowCount === 1) return '1'; + } catch (error) { + const winner = await session.query( + 'SELECT current_level AS id FROM teaql_id_space WHERE type_name = ?', + [entity], + ); + if (!winner.rowCount) throw error; + } + continue; + } + const previous = Number(current.rows[0].id); + const next = previous + 1; + const updated = await session.query( + 'UPDATE teaql_id_space SET current_level = ? WHERE type_name = ? AND current_level = ?', + [next, entity, previous], + ); + if (updated.rowCount === 1) return String(next); + if (updated.rowCount !== 0) { + throw new Error(`ID space update for ${entity} changed ${updated.rowCount} rows`); + } + } + throw new Error( + `Unable to allocate ID for ${entity} after 100 optimistic-lock attempts`, + ); + } + + ensureIdFloor(session: SqlSession, entity: string, floor: string): Promise { + return ensureOptimisticIdFloor(session, index => this.placeholder(index), entity, floor); + } + + async query(sql: string, values: any[] = []): Promise { + const statement = this.database.prepare(sql); + if (statement.reader) { + const rows = statement.all(...values); + return { rows, rowCount: rows.length }; + } + const result = statement.run(...values); + return { rows: [], rowCount: result.changes }; + } + + async *stream(sql: string, values: any[] = []): AsyncIterable { + const statement = this.database.prepare(sql); + if (!statement.reader) throw new Error('stream() requires a SELECT statement'); + for (const row of statement.iterate(...values)) yield row; + } + + async close(): Promise { + this.database.close(); + } +} + +export class SQLiteTeaQLClient extends AbstractSQLTeaQLClient { + constructor(filename: string, schemas: Record) { + super(new SQLiteDriver(filename), schemas); + this.attachStandardTelemetryStartup(startStandardNodeTelemetry()); + } +} diff --git a/source/teaql-ts/src/telemetry/export-health.ts b/source/teaql-ts/src/telemetry/export-health.ts new file mode 100644 index 0000000000000000000000000000000000000000..77010c762f700f0a0f032894cabd5ec874df1258 --- /dev/null +++ b/source/teaql-ts/src/telemetry/export-health.ts @@ -0,0 +1,130 @@ +import { telemetryNotice } from '../core/telemetry-startup'; + +export type TelemetrySignal = 'traces' | 'logs' | 'metrics'; +export type TelemetryLossReason = 'queue_overflow' | 'export_failure' | 'shutdown' | 'handoff_failure'; + +type Admission = {sequence?: number; state: 'queued' | 'exporting' | 'complete' | 'retired'}; +export type QueueHealth = Readonly<{offered: number; admitted: number; completed: number; outstanding: number; + exporting: number; overflow: number; postShutdown: number; handoffFailed: number; retired: number}>; + +/** Bounded admission counts in-flight records too, never only the visible SDK queue. */ +export class ExportHealth { + private readonly pending = new Set(); + private readonly records = new WeakMap(); + private readonly changed = new Set<() => void>(); + private offered = 0; + private admitted = 0; + private completed = 0; + private overflow = 0; + private postShutdown = 0; + private handoffFailed = 0; + private retired = 0; + private failures = 0; + private closed = false; + private aborted = false; + private readonly announced = new Set(); + constructor(private readonly signal: TelemetrySignal, private readonly capacity: number, + private readonly onLoss: (amount: number, signal: TelemetrySignal, reason: TelemetryLossReason) => void) { + if (!Number.isInteger(capacity) || capacity < 1) throw new Error('Invalid telemetry queue capacity'); + } + admit(amount = 1): boolean { + if (!this.reserve(amount)) return false; + for (let index = 0; index < amount; index++) this.pending.add({sequence: ++this.admitted, state: 'queued'}); + return true; + } + complete(amount: number, failed: boolean): void { + this.settle([...this.pending].slice(0, amount), failed); + } + private reserve(amount: number): boolean { + this.offered += amount; + if (this.closed) {this.postShutdown += amount; this.lost(amount, 'shutdown'); return false;} + if (this.pending.size + amount > this.capacity) { + this.overflow += amount; this.lost(amount, 'queue_overflow'); return false; + } + return true; + } + /** SDK object identity carries admission; never infer tickets from equal data or completion order. */ + handoff(record: object, submit: () => void): void { + if (!this.reserve(1)) return; + const admission: Admission = {state: 'queued'}; + this.pending.add(admission); this.records.set(record, admission); + try { + submit(); admission.sequence = ++this.admitted; + if (admission.state === 'complete') this.completed++; + } catch { + this.pending.delete(admission); this.records.delete(record); + this.handoffFailed++; this.lost(1, 'handoff_failure'); + } + this.notify(); + } + beginExport(records: readonly object[]): {complete(failed: boolean): void} | undefined { + if (this.aborted) return undefined; + const batch = records.map(record => this.records.get(record)); + if (batch.some(record => !record || record.state !== 'queued')) return undefined; + const admissions = batch as Admission[]; + for (const admission of admissions) admission.state = 'exporting'; + let completed = false; + return {complete: failed => { + if (completed) return; completed = true; this.settle(admissions, failed); + }}; + } + private settle(admissions: readonly Admission[], failed: boolean): void { + let settled = 0; + for (const admission of admissions) { + if (!this.pending.delete(admission)) continue; + admission.state = 'complete'; settled++; + if (admission.sequence !== undefined) this.completed++; + } + if (failed && settled) {this.failures += settled; this.lost(settled, 'export_failure');} + this.notify(); + } + abortQueued(): void { + if (this.aborted) return; this.aborted = true; + let retired = 0; + for (const admission of this.pending) if (admission.state === 'queued') { + this.pending.delete(admission); admission.state = 'retired'; retired++; + } + this.retired += retired; + if (retired) this.lost(retired, 'shutdown'); + this.notify(); + } + /** Captured prefix excludes later submissions and cannot be satisfied by their completion. */ + waitForPrefix(timeoutMillis = 5000): Promise { + const target = this.admitted; + return this.wait(() => ![...this.pending].some(record => record.sequence !== undefined && record.sequence <= target), timeoutMillis); + } + waitForIdle(timeoutMillis = 200): Promise {return this.wait(() => this.pending.size === 0, timeoutMillis);} + private wait(ready: () => boolean, timeoutMillis: number): Promise { + if (ready()) return Promise.resolve(); + return new Promise((resolve, reject) => { + const finish = (failed: boolean) => { + clearTimeout(timer); this.changed.delete(check); + if (failed) reject(new Error('TeaQL telemetry drain timed out')); else resolve(); + }; + const check = () => {if (ready()) finish(false);}; + const timer = setTimeout(() => finish(true), timeoutMillis); + this.changed.add(check); check(); + }); + } + private notify(): void {for (const observer of [...this.changed]) observer();} + private lost(amount: number, reason: TelemetryLossReason): void { + try { this.onLoss(amount, this.signal, reason); } catch { /* loss reporting is best effort */ } + if (this.announced.has(reason)) return; + this.announced.add(reason); + telemetryNotice(`TeaQL telemetry: records lost; signal=${this.signal} reason=${reason}. Business outcome unchanged.`, true); + } + get pendingRecords(): number { return this.pending.size; } + get failedRecords(): number { return this.failures; } + close(): void { this.closed = true; } + rejectLate(): void {this.offered++; this.postShutdown++; this.lost(1, 'shutdown');} + snapshot(): QueueHealth {return {offered: this.offered, admitted: this.admitted, completed: this.completed, + outstanding: this.pending.size, exporting: [...this.pending].filter(record => record.state === 'exporting').length, + overflow: this.overflow, postShutdown: this.postShutdown, handoffFailed: this.handoffFailed, retired: this.retired};} +} + +export function lifecycleDeadline(work: Promise, timeoutMillis = 6000): Promise { + return new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error('TeaQL telemetry lifecycle timed out')), timeoutMillis); + work.then(value => { clearTimeout(timer); resolve(value); }, error => { clearTimeout(timer); reject(error); }); + }); +} diff --git a/source/teaql-ts/src/telemetry/opentelemetry.ts b/source/teaql-ts/src/telemetry/opentelemetry.ts new file mode 100644 index 0000000000000000000000000000000000000000..de2da1ddad0524117d5502ac2b08a13e13b73b01 --- /dev/null +++ b/source/teaql-ts/src/telemetry/opentelemetry.ts @@ -0,0 +1,144 @@ +import { + Attributes, + Context, + context, + Meter, + propagation, + Span, + SpanStatusCode, + Tracer, + trace, +} from '@opentelemetry/api'; +import type { Logger } from '@opentelemetry/api-logs'; +import { + RuntimeAttributeValue, + RuntimeOperation, + RuntimeOperationCompletion, + RuntimeTelemetry, + RuntimeTelemetryScope, + RuntimeDiagnosticEvent, + runtimeErrorCategory, +} from '../core/telemetry'; + +export interface OpenTelemetryRuntimeLifecycle { + flush?: () => void | Promise; + shutdown?: () => void | Promise; +} + +export interface OpenTelemetryExecutionContext { + active(): Context; + with(active: Context, work: () => T): T; +} + +/** Bridges the provider-neutral TeaQL lifecycle to application-owned OTel providers. */ +export class OpenTelemetryRuntimeTelemetry implements RuntimeTelemetry { + private readonly duration; + private readonly operations; + + constructor( + private readonly tracer: Tracer, + meter: Meter, + private readonly lifecycle: OpenTelemetryRuntimeLifecycle = {}, + private readonly logger?: Logger, + private readonly executionContext: OpenTelemetryExecutionContext = context, + ) { + this.duration = meter.createHistogram('teaql.runtime.operation.duration', { + description: 'TeaQL runtime operation duration', + unit: 'ms', + }); + this.operations = meter.createCounter('teaql.runtime.operation.count', { + description: 'Completed TeaQL runtime operations', + unit: '{operation}', + }); + } + + start(operation: RuntimeOperation): RuntimeTelemetryScope { + const startedAt = performance.now(); + const span = this.tracer.startSpan(`teaql.${operation.family}`, { + attributes: operation.attributes as Attributes, + }, this.executionContext.active()); + const activeContext = trace.setSpan(this.executionContext.active(), span); + let ended = false; + + const finishInContext = (outcome: 'success' | 'failure', completion?: RuntimeOperationCompletion, + errorCategory?: string) => { + if (ended) return; + ended = true; + if (outcome === 'success') this.setSafeCompletionAttributes(span, completion); + span.setStatus(outcome === 'success' + ? { code: SpanStatusCode.OK } + : { code: SpanStatusCode.ERROR }); + const durationMs = Math.max(0, performance.now() - startedAt); + const metricAttributes = { + 'teaql.operation.family': operation.family, + 'teaql.operation.outcome': outcome, + }; + this.duration.record(durationMs, metricAttributes); + this.operations.add(1, metricAttributes); + this.logger?.emit({ + context: activeContext, + severityNumber: 9, + severityText: 'INFO', + body: 'TeaQL runtime operation completed', + attributes: { + ...metricAttributes, + 'teaql.operation.name': operation.name, + 'teaql.operation.duration_ms': durationMs, + ...(errorCategory ? { 'teaql.error.category': errorCategory } : {}), + }, + }); + span.end(); + }; + const finish = (outcome: 'success' | 'failure', completion?: RuntimeOperationCompletion, + errorCategory?: string) => + this.executionContext.with(activeContext, () => finishInContext(outcome, completion, errorCategory)); + + return { + correlation: () => ({ traceId: span.spanContext().traceId, spanId: span.spanContext().spanId }), + run: work => this.executionContext.with(activeContext, work), + success: completion => finish('success', completion), + failure: error => { + const category = runtimeErrorCategory(error); + span.setAttribute('teaql.error.type', this.errorType(error)); + span.setAttribute('teaql.error.category', category); + finish('failure', undefined, category); + }, + }; + } + + recordDiagnostic(event: RuntimeDiagnosticEvent): void { + const identity = event.correlation; + if (!identity || !/^[0-9a-f]{32}$/.test(identity.traceId) || !/^[0-9a-f]{16}$/.test(identity.spanId) + || /^0+$/.test(identity.traceId) || /^0+$/.test(identity.spanId)) { + throw new Error('Missing SQL execution correlation'); + } + this.logger?.emit({ severityNumber: 9, severityText: 'INFO', body: event.body, + context: trace.setSpanContext(this.executionContext.active(), { ...identity, traceFlags: 1 }), + attributes: event.attributes }); + } + + inject(carrier: Record): void { + propagation.inject(this.executionContext.active(), carrier); + } + + flush(): void | Promise { + return this.lifecycle.flush?.(); + } + + shutdown(): void | Promise { + return this.lifecycle.shutdown?.(); + } + + private setSafeCompletionAttributes(span: Span, completion?: RuntimeOperationCompletion): void { + for (const [key, value] of Object.entries(completion?.attributes || {})) { + if (key === 'teaql.result.cardinality' || key === 'teaql.cache.result') { + span.setAttribute(key, value as RuntimeAttributeValue); + } + } + } + + private errorType(error: unknown): string { + if (error instanceof Error && error.constructor?.name) return error.constructor.name; + return typeof error; + } +} diff --git a/source/teaql-ts/src/telemetry/owned-otlp-http.ts b/source/teaql-ts/src/telemetry/owned-otlp-http.ts new file mode 100644 index 0000000000000000000000000000000000000000..04dc498258defe27230b1b13a26d7fa290a2d04a --- /dev/null +++ b/source/teaql-ts/src/telemetry/owned-otlp-http.ts @@ -0,0 +1,158 @@ +import * as http from 'node:http'; +import * as https from 'node:https'; +import type { ExportResult } from '@opentelemetry/core'; +import type { ISerializer } from '@opentelemetry/otlp-transformer'; +import type { TelemetrySignal } from './export-health'; + +export type ResponseKind = 'partial_success' | 'warning' | 'invalid_response'; +export type Acknowledgement = { partialSuccess?: { + rejectedSpans?: number; rejectedLogRecords?: number; rejectedDataPoints?: number; errorMessage?: string; +} }; +const responseLimit = 4 * 1024 * 1024; +const rejectedFields = { traces: 'rejectedSpans', logs: 'rejectedLogRecords', metrics: 'rejectedDataPoints' } as const; + +/** Strict framing guard for the two-level proto3 acknowledgement, not a second OTLP codec. */ +export function validateAcknowledgementBytes(bytes: Uint8Array, partial = false): void { + if (bytes.byteLength > responseLimit) throw new Error('Invalid telemetry acknowledgement'); + let position = 0; + const varint = (): bigint => { + let result = 0n; + for (let index = 0; index < 10; index++) { + if (position === bytes.length) throw new Error('Invalid telemetry acknowledgement'); + const value = bytes[position++]; + if (index === 9 && value > 1) throw new Error('Invalid telemetry acknowledgement'); + result |= BigInt(value & 127) << BigInt(index * 7); + if (!(value & 128)) return result; + } + throw new Error('Invalid telemetry acknowledgement'); + }; + while (position < bytes.length) { + const tag = varint(); + if (tag === 0n || tag > 0xffffffffn || tag >> 3n === 0n) throw new Error('Invalid telemetry acknowledgement'); + const field = Number(tag >> 3n), wire = Number(tag & 7n); + if ((!partial && field === 1 && wire !== 2) || (partial && field === 1 && wire !== 0) + || (partial && field === 2 && wire !== 2)) throw new Error('Invalid telemetry acknowledgement'); + if (wire === 0) varint(); + else if (wire === 1) position += 8; + else if (wire === 5) position += 4; + else if (wire === 2) { + const length = varint(); + if (length > BigInt(bytes.length - position)) throw new Error('Invalid telemetry acknowledgement'); + const value = bytes.subarray(position, position + Number(length)); + if (!partial && field === 1) validateAcknowledgementBytes(value, true); + if (partial && field === 2) { + try { new TextDecoder('utf-8', {fatal: true}).decode(value); } + catch { throw new Error('Invalid telemetry acknowledgement'); } + } + position += Number(length); + } else throw new Error('Invalid telemetry acknowledgement'); // no groups in OTLP proto3 + if (position > bytes.length) throw new Error('Invalid telemetry acknowledgement'); + } +} + +export function acknowledgementResult(signal: TelemetrySignal, response: Acknowledgement, submitted: number) { + const partial = response.partialSuccess; + const rejected = partial?.[rejectedFields[signal]] ?? 0; + if (!Number.isSafeInteger(rejected) || rejected < 0 || rejected > submitted) + throw new Error('Invalid telemetry acknowledgement'); + return { rejected, kind: rejected > 0 ? 'partial_success' as const + : partial?.errorMessage ? 'warning' as const : undefined }; +} + +/** Pipeline-owned agents, no global fetch/agent/SDK interception, retries or redirects. */ +export class OwnedOTLPHTTP { + private readonly httpAgent = new http.Agent({keepAlive: true, maxSockets: 8, maxFreeSockets: 4}); + private readonly httpsAgent = new https.Agent({keepAlive: true, maxSockets: 8, maxFreeSockets: 4}); + private readonly requests = new Set(); + private closed = false; + private readonly idleWaiters = new Set<() => void>(); + + send(url: string, payload: Uint8Array): Promise<{bytes?: Uint8Array; invalid?: boolean}> { + if (this.closed) return Promise.resolve({}); + return new Promise(resolve => { + let finished = false, request: http.ClientRequest | undefined; + const finish = (value: {bytes?: Uint8Array; invalid?: boolean}) => { + if (finished) return; + finished = true; clearTimeout(timer); + if (request) this.requests.delete(request); + if (!this.requests.size) for (const waiter of [...this.idleWaiters]) waiter(); + resolve(value); + }; + const timer = setTimeout(() => { finish({}); request?.destroy(); }, 3000); + try { + const target = new URL(url), secure = target.protocol === 'https:'; + request = (secure ? https : http).request({protocol: target.protocol, hostname: target.hostname, + port: target.port, path: target.pathname, method: 'POST', + agent: secure ? this.httpsAgent : this.httpAgent, + headers: {'Content-Type': 'application/x-protobuf', 'Content-Length': String(payload.byteLength)}, + }, response => { + if (response.statusCode !== 200) { finish({}); response.destroy(); return; } + const type = String(response.headers['content-type'] || '').split(';')[0].trim().toLowerCase(); + if (type !== 'application/x-protobuf' || response.headers['content-encoding'] + || Number(response.headers['content-length'] || 0) > responseLimit) { + finish({invalid: true}); response.destroy(); return; + } + const chunks: Buffer[] = []; let length = 0; + response.on('data', (chunk: Buffer) => { + length += chunk.length; + if (length > responseLimit) { finish({invalid: true}); response.destroy(); } + else chunks.push(chunk); + }); + response.once('end', () => finish({bytes: Buffer.concat(chunks, length)})); + response.once('error', () => finish({})); + response.once('aborted', () => finish({})); + }); + this.requests.add(request); + request.once('error', () => finish({})); + request.once('close', () => finish({})); + request.end(Buffer.from(payload)); + } catch { finish({}); request?.destroy(); } + }); + } + + abort(): void { + for (const request of this.requests) request.destroy(); + } + close(): void { + this.closed = true; this.abort(); this.httpAgent.destroy(); this.httpsAgent.destroy(); + } + waitForIdle(timeoutMillis = 200): Promise { + if (!this.requests.size) return Promise.resolve(); + return new Promise(resolve => { + const finish = () => {clearTimeout(timer); this.idleWaiters.delete(finish); resolve();}; + const timer = setTimeout(finish, timeoutMillis); this.idleWaiters.add(finish); + }); + } +} + +export function ownedExporter(transport: OwnedOTLPHTTP, endpoint: string, + signal: TelemetrySignal, serializer: ISerializer, submitted: (data: T) => number, + observe: (signal: TelemetrySignal, kind: ResponseKind, rejected: number) => void) { + const active = new Set>(); + return { + export(data: T, done: (result: ExportResult) => void): void { + const work = async () => { + let failed = true; + try { + const payload = serializer.serializeRequest(data); + if (!payload) throw new Error('Telemetry serialization failed'); + const result = await transport.send(endpoint + '/v1/' + signal, payload); + if (result.invalid) observe(signal, 'invalid_response', 0); + else if (result.bytes) { + try { + validateAcknowledgementBytes(result.bytes); + const acknowledgement = acknowledgementResult(signal, serializer.deserializeResponse(result.bytes), submitted(data)); + if (acknowledgement.kind) observe(signal, acknowledgement.kind, acknowledgement.rejected); + failed = false; + } catch { observe(signal, 'invalid_response', 0); } + } + } catch { /* raw serializer, HTTP and decoder errors never enter SDK diagnostics */ } + done(failed ? {code: 1, error: new Error('TeaQL telemetry export failed')} : {code: 0}); + }; + const pending = work(); active.add(pending); + void pending.then(() => active.delete(pending), () => active.delete(pending)); + }, + async forceFlush(): Promise { await Promise.all([...active]); }, + async shutdown(): Promise { await Promise.all([...active]); }, + }; +} diff --git a/source/teaql-ts/src/telemetry/response-health.ts b/source/teaql-ts/src/telemetry/response-health.ts new file mode 100644 index 0000000000000000000000000000000000000000..6ee2e8258edf8334871f8ca2485eaae808ba1112 --- /dev/null +++ b/source/teaql-ts/src/telemetry/response-health.ts @@ -0,0 +1,28 @@ +import { telemetryNotice } from '../core/telemetry-startup'; +import type { TelemetrySignal } from './export-health'; +import type { ResponseKind } from './owned-otlp-http'; + +export class ResponseHealth { + private readonly signals = { + traces: {rejected: 0, partialSuccess: 0, warnings: 0, invalidResponses: 0}, + logs: {rejected: 0, partialSuccess: 0, warnings: 0, invalidResponses: 0}, + metrics: {rejected: 0, partialSuccess: 0, warnings: 0, invalidResponses: 0}, + }; + private readonly announced = new Set(); + constructor(private readonly record: (signal: TelemetrySignal, kind: ResponseKind, rejected: number) => void) {} + observe(signal: TelemetrySignal, kind: ResponseKind, rejected: number): void { + const current = this.signals[signal]; + current.rejected += rejected; + if (kind === 'partial_success') current.partialSuccess++; + else if (kind === 'warning') current.warnings++; + else current.invalidResponses++; + try { this.record(signal, kind, rejected); } catch { /* diagnosis cannot govern business results */ } + const key = signal + '/' + kind; + if (this.announced.has(key)) return; + this.announced.add(key); + telemetryNotice(`TeaQL telemetry: receiver response; signal=${signal} reason=${kind}. Business outcome unchanged.`, true); + } + snapshot() { + return {traces: {...this.signals.traces}, logs: {...this.signals.logs}, metrics: {...this.signals.metrics}}; + } +} diff --git a/source/teaql-ts/src/telemetry/standard-node-sdk.ts b/source/teaql-ts/src/telemetry/standard-node-sdk.ts new file mode 100644 index 0000000000000000000000000000000000000000..ebfe49a3a15ab9371e88c60591f545c062f252c5 --- /dev/null +++ b/source/teaql-ts/src/telemetry/standard-node-sdk.ts @@ -0,0 +1,170 @@ +import { context, ROOT_CONTEXT, defaultTextMapSetter } from '@opentelemetry/api'; +import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks'; +import { AlwaysOnSampler, BasicTracerProvider, BatchSpanProcessor, SpanProcessor } from '@opentelemetry/sdk-trace-base'; +import { LoggerProvider, BatchLogRecordProcessor, LogRecordProcessor } from '@opentelemetry/sdk-logs'; +import { ExportResult, W3CTraceContextPropagator } from '@opentelemetry/core'; +import { AggregationTemporality, MeterProvider, PeriodicExportingMetricReader, ResourceMetrics } from '@opentelemetry/sdk-metrics'; +import { ProtobufLogsSerializer, ProtobufMetricsSerializer, ProtobufTraceSerializer } from '@opentelemetry/otlp-transformer'; +import { resourceFromAttributes } from '@opentelemetry/resources'; +import { OpenTelemetryRuntimeTelemetry } from './opentelemetry'; +import { telemetryNotice } from '../core/telemetry-startup'; +import { ExportHealth, lifecycleDeadline } from './export-health'; +import { OwnedOTLPHTTP, ownedExporter } from './owned-otlp-http'; +import { ResponseHealth } from './response-health'; + +function reportedExporter(delegate: { export(records: T[], done: (result: ExportResult) => void): void; + shutdown(): Promise; forceFlush?(): Promise }, health: ExportHealth) { + return { + export: (records: T[], done: (result: ExportResult) => void) => { + const ticket = health.beginExport(records as object[]); + if (!ticket) {done({code: 0}); return;} + let completed = false; + const finish = (result: ExportResult) => { + if (completed) return; + completed = true; + ticket.complete(result.code !== 0); + done(result); + }; + try { delegate.export(records, finish); } + catch { finish({ code: 1 }); } + }, + shutdown: () => delegate.shutdown(), + forceFlush: () => delegate.forceFlush?.() ?? Promise.resolve(), + }; +} + +/** Isolated providers; never registers or replaces process-global OTel configuration. */ +export function createStandardNodePipeline(serviceName: string, endpoint: string) { + const resource = resourceFromAttributes({ 'service.name': serviceName, 'teaql.runtime.language': 'typescript' }); + const manager = new AsyncLocalStorageContextManager().enable(); + const transport = new OwnedOTLPHTTP(); + let lossCounter: ReturnType | undefined; + let rejectedCounter: typeof lossCounter, responseCounter: typeof lossCounter; + const responses = new ResponseHealth((signal, reason, rejected) => { + rejectedCounter?.add(rejected, {'teaql.telemetry.signal': signal}); + responseCounter?.add(1, {'teaql.telemetry.signal': signal, 'teaql.telemetry.reason': reason}); + }); + const metricPoints = (data: ResourceMetrics) => data.scopeMetrics.reduce((n, scope) => + n + scope.metrics.reduce((m, metric) => m + metric.dataPoints.length, 0), 0); + const metricExporter = ownedExporter(transport, endpoint, 'metrics', ProtobufMetricsSerializer, + metricPoints, (signal, kind, rejected) => responses.observe(signal, kind, rejected)); + let metricDataObjectsFailed = 0; + let metricFailureAnnounced = false; + const meterProvider = new MeterProvider({ resource, readers: [new PeriodicExportingMetricReader({ + exporter: { export: (data, done) => { + let completed = false; + const finish = (result: ExportResult) => { + if (completed) return; + completed = true; + if (result.code !== 0) { + const objects = data.scopeMetrics.reduce((n, scope) => n + scope.metrics.length, 0); + metricDataObjectsFailed += objects; + lossCounter?.add(objects, {'teaql.telemetry.signal': 'metrics', 'teaql.telemetry.reason': 'export_failure'}); + if (!metricFailureAnnounced) { + metricFailureAnnounced = true; + telemetryNotice('TeaQL telemetry: records lost; signal=metrics reason=export_failure. Business outcome unchanged.', true); + } + } + done(result); + }; + try { metricExporter.export(data, finish); } catch { finish({ code: 1 }); } + }, forceFlush: () => metricExporter.forceFlush(), shutdown: () => metricExporter.shutdown(), + selectAggregationTemporality: () => AggregationTemporality.CUMULATIVE }, + exportIntervalMillis: 10000, exportTimeoutMillis: 5000 })] }); + const meter = meterProvider.getMeter('io.teaql.runtime'); + lossCounter = meter.createCounter('teaql.telemetry.export.lost', { + description: 'Lost span/log records or failed metric-data objects; not metric data points', unit: '{entry}' }); + rejectedCounter = meter.createCounter('teaql.telemetry.export.rejected', { + description: 'Receiver-rejected spans, log records or metric data points', unit: '{item}' }); + responseCounter = meter.createCounter('teaql.telemetry.export.response', {unit: '{response}'}); + for (const signal of ['traces', 'logs', 'metrics']) { + rejectedCounter.add(0, {'teaql.telemetry.signal': signal}); + for (const reason of ['partial_success', 'warning', 'invalid_response']) + responseCounter.add(0, {'teaql.telemetry.signal': signal, 'teaql.telemetry.reason': reason}); + lossCounter.add(0, {'teaql.telemetry.signal': signal, 'teaql.telemetry.reason': 'export_failure'}); + } + const lost = (amount: number, signal: string, reason: string) => lossCounter!.add(amount, + {'teaql.telemetry.signal': signal, 'teaql.telemetry.reason': reason}); + const spanHealth = new ExportHealth('traces', 2048, lost); + const logHealth = new ExportHealth('logs', 2048, lost); + const spanBatch = new BatchSpanProcessor(reportedExporter(ownedExporter(transport, endpoint, 'traces', + ProtobufTraceSerializer, spans => spans.length, (signal, kind, rejected) => responses.observe(signal, kind, rejected)), spanHealth), { maxQueueSize: 2048, maxExportBatchSize: 128, + scheduledDelayMillis: 1000, exportTimeoutMillis: 5000 }); + const spanProcessor: SpanProcessor = { + onStart: (...args) => spanBatch.onStart(...args), + onEnd: span => spanHealth.handoff(span, () => spanBatch.onEnd(span)), + forceFlush: () => spanBatch.forceFlush(), shutdown: () => spanBatch.shutdown(), + }; + const logBatch = new BatchLogRecordProcessor({ + exporter: reportedExporter(ownedExporter(transport, endpoint, 'logs', ProtobufLogsSerializer, + logs => logs.length, (signal, kind, rejected) => responses.observe(signal, kind, rejected)), logHealth), + maxQueueSize: 2048, maxExportBatchSize: 128, scheduledDelayMillis: 1000, exportTimeoutMillis: 5000 }); + const logProcessor: LogRecordProcessor = { + onEmit: record => logHealth.handoff(record, () => logBatch.onEmit(record)), + forceFlush: () => logBatch.forceFlush(), shutdown: () => logBatch.shutdown(), + }; + const tracerProvider = new BasicTracerProvider({ resource, sampler: new AlwaysOnSampler(), + spanProcessors: [spanProcessor] }); + const loggerProvider = new LoggerProvider({ resource, processors: [logProcessor] }); + let closed = false; + let shutdownPromise: Promise | undefined; + const flush = async () => { + if (closed) return shutdownPromise; + const spans = spanHealth.waitForPrefix(), logs = logHealth.waitForPrefix(); + await lifecycleDeadline((async () => { + const records = await Promise.allSettled([tracerProvider.forceFlush(), loggerProvider.forceFlush(), spans, logs]); + if (closed) return; + await meterProvider.forceFlush(); // loss/rejection counters follow record completion + if (records.some(result => result.status === 'rejected')) throw new Error('TeaQL telemetry export incomplete'); + })()); }; + const shutdown = () => shutdownPromise ??= (async () => { + closed = true; + spanHealth.close(); logHealth.close(); + const started = performance.now(); + const stopped = Promise.allSettled([tracerProvider.shutdown(), loggerProvider.shutdown()]); + try { + try {await Promise.all([spanHealth.waitForPrefix(5000), logHealth.waitForPrefix(5000)]);} + catch { + spanHealth.abortQueued(); logHealth.abortQueued(); transport.abort(); + await Promise.all([spanHealth.waitForIdle(200), logHealth.waitForIdle(200)]); + } + await lifecycleDeadline(stopped, Math.max(1, 5700 - (performance.now() - started))); + await lifecycleDeadline(meterProvider.shutdown(), Math.max(1, 5800 - (performance.now() - started))); + } finally { + spanHealth.abortQueued(); logHealth.abortQueued(); transport.close(); + await lifecycleDeadline(Promise.all([transport.waitForIdle(200), metricExporter.forceFlush()]), + Math.max(1, 6000 - (performance.now() - started))).catch(() => { + telemetryNotice('TeaQL telemetry: owned cleanup deadline reached; business outcome unchanged.', true); + }); + manager.disable(); + } + })(); + const executionContext = { + active: () => manager.active() === ROOT_CONTEXT ? context.active() : manager.active(), + with: (active: import('@opentelemetry/api').Context, work: () => T): T => manager.with(active, work), + }; + const adapter = new OpenTelemetryRuntimeTelemetry(tracerProvider.getTracer('io.teaql.runtime'), + meterProvider.getMeter('io.teaql.runtime'), {}, loggerProvider.getLogger('io.teaql.runtime'), executionContext); + const telemetry: import('../core/telemetry').RuntimeTelemetry = { + start: operation => { + const delegate = closed ? undefined : adapter.start(operation); + let finished = false; + const finish = (work: () => void) => { + if (finished) return; finished = true; + if (closed) {spanHealth.rejectLate(); logHealth.rejectLate();} else work(); + }; + return {correlation: () => closed ? undefined : delegate?.correlation?.(), + run: work => !closed && delegate?.run ? delegate.run(work) : work(), + success: completion => finish(() => delegate!.success(completion)), + failure: error => finish(() => delegate!.failure(error))}; + }, + recordsSQLDiagnostics: () => !closed, + recordDiagnostic: event => {if (!closed) adapter.recordDiagnostic(event);}, + }; + const propagator = new W3CTraceContextPropagator(); + telemetry.inject = carrier => propagator.inject(executionContext.active(), carrier, defaultTextMapSetter); + telemetryNotice('TeaQL telemetry: enabled; traces, metrics, logs, complete TraceChain and masked SQL; recording=all.'); + return { telemetry, flush, shutdown, health: () => ({traceSpansFailed: spanHealth.failedRecords, + logRecordsFailed: logHealth.failedRecords, metricDataObjectsFailed, responses: responses.snapshot(), + queues: {traces: spanHealth.snapshot(), logs: logHealth.snapshot()}}) }; +} diff --git a/source/teaql-ts/src/telemetry/standard-node.ts b/source/teaql-ts/src/telemetry/standard-node.ts new file mode 100644 index 0000000000000000000000000000000000000000..261d1763dcdb48d7269b7469b4a221c86eb784e0 --- /dev/null +++ b/source/teaql-ts/src/telemetry/standard-node.ts @@ -0,0 +1,65 @@ +import { readTelemetryStartupConfiguration, telemetryStartupMessage, telemetryNotice } from '../core/telemetry-startup'; +import type { RuntimeTelemetry } from '../core/telemetry'; +import type { QueueHealth, TelemetrySignal } from './export-health'; + +export interface StandardTelemetryHealth { + readonly traceSpansFailed: number; + readonly logRecordsFailed: number; + readonly metricDataObjectsFailed: number; + readonly responses: Readonly>>; + readonly queues: Readonly>; +} + +export interface StandardTelemetryHandle { + readonly telemetry: RuntimeTelemetry; + flush(): Promise; + release(): Promise; + health?(): StandardTelemetryHealth; +} + +type Pipeline = { telemetry: RuntimeTelemetry; flush(): Promise; shutdown(): Promise; health?(): StandardTelemetryHealth }; +const pipelines = new Map }>(); +const announcements = new Set(); + +/** Node entry point; importing it does not import or initialize any OTel SDK. */ +export function startStandardNodeTelemetry(): Promise { + const configuration = readTelemetryStartupConfiguration(process.env); + const message = telemetryStartupMessage(configuration); + if (!announcements.has(message)) { + announcements.add(message); + telemetryNotice(message); + } + if (!configuration.enabled) return Promise.resolve(undefined); + const key = `${configuration.serviceName}|${configuration.endpoint}`; + let entry = pipelines.get(key); + if (!entry) { + entry = { references: 0, ready: import('./standard-node-sdk').then(module => + module.createStandardNodePipeline(configuration.serviceName!, configuration.endpoint!)) }; + pipelines.set(key, entry); + } + const ownedEntry = entry; + ownedEntry.references++; + return ownedEntry.ready.then(pipeline => { + let released = false; + return { + telemetry: pipeline.telemetry, + flush: () => pipeline.flush(), + health: pipeline.health ? () => pipeline.health!() : undefined, + release: async () => { + if (released) return; + released = true; + ownedEntry.references--; + if (ownedEntry.references !== 0) return; + if (pipelines.get(key) === ownedEntry) pipelines.delete(key); + try { await pipeline.shutdown(); } + catch { telemetryNotice('TeaQL telemetry: owned pipeline shutdown failed; business outcome unchanged.', true); } + }, + }; + }).catch(() => { + if (pipelines.get(key) === ownedEntry) pipelines.delete(key); + telemetryNotice('TeaQL telemetry: standard module unavailable; check installed SDK dependencies. Business continues without export.', true); + return undefined; + }); +} diff --git a/source/teaql-ts/src/tfp/client.ts b/source/teaql-ts/src/tfp/client.ts new file mode 100644 index 0000000000000000000000000000000000000000..7913fb52cda471af94c5f43823a1fc1cda792628 --- /dev/null +++ b/source/teaql-ts/src/tfp/client.ts @@ -0,0 +1,187 @@ +import { SelectQuery } from '../core/ast'; +import { SmartList, SmartListRecord } from '../core/smart-list'; +import { UserContext } from '../core/context'; +import { MutationGovernanceSnapshot } from '../core/mutation-policy'; +import { MutationRequest, QueryIntent, QueryRequest } from '../core/request-intent'; +import { + NOOP_RUNTIME_TELEMETRY, + injectRuntimeContext, + observeRuntimeOperation, + RuntimeTelemetry, +} from '../core/telemetry'; + +function rejectRemoteHardLimit(value: unknown, path = '$'): void { + if (Array.isArray(value)) { + value.forEach((item, index) => rejectRemoteHardLimit(item, `${path}[${index}]`)); + return; + } + if (!value || typeof value !== 'object') return; + + for (const [key, child] of Object.entries(value as Record)) { + const normalized = key.replace(/[^a-zA-Z]/g, '').toLowerCase(); + if (normalized === 'hardlimit' || normalized === 'hardlimitvalue' + || normalized.startsWith('continuouspage') || normalized.startsWith('idsetpagination') + || normalized.startsWith('paginationwithidset')) { + throw new Error(`TFP_FORBIDDEN_FIELD: ${path}.${key} is server-local policy`); + } + rejectRemoteHardLimit(child, `${path}.${key}`); + } +} + +function serializeQuery(query: SelectQuery, nestedFacet = false, + intent?: QueryIntent): Record { + const request = new QueryRequest(query, intent); + query = request.query; + if (!Number.isSafeInteger(query.offsetValue) || query.offsetValue < 0) { + throw new Error('TFP_INVALID_REQUEST: offset must be a non-negative safe integer'); + } + if (query.limitValue && (!Number.isSafeInteger(query.limitValue) || query.limitValue < 1)) { + throw new Error('TFP_INVALID_REQUEST: limit must be a positive safe integer'); + } + rejectRemoteHardLimit(JSON.parse(JSON.stringify(query))); + if (query.relations.length || query.joins.length) { + throw new Error('TFP_INVALID_REQUEST: relations and joins are not part of canonical TFP v1'); + } + if (nestedFacet && query.facets.length) { + throw new Error('TFP_INVALID_REQUEST: nested facets are not supported'); + } + return { + entity: query.entity, + filterCondition: query.filterCondition, + limitValue: query.limitValue || undefined, + offsetValue: query.offsetValue || undefined, + orderItems: query.orderItems, + selectItems: query.selectItems, + groupByItems: query.groupByItems, + aggregateItems: query.aggregateItems, + facets: query.facets.map(facet => ({ + facetName: facet.facetName, + relationName: facet.relationName, + includeAllFacets: facet.includeAllFacets, + query: serializeQuery(facet.query, true, request.intent), + })), + commentText: query.commentText, + purposeText: query.purposeText, + }; +} + +export interface TeaQLClientConfig { + baseUrl: string; + fetch?: typeof fetch; + getHeaders?: () => Record | Promise>; + runtimeTelemetry?: RuntimeTelemetry; + /** Trusted local context; never serialized into the TFP request. */ + userContext?: UserContext; +} + +export class TeaQLClient { + private config: TeaQLClientConfig; + private fetchImpl: typeof fetch; + private runtimeTelemetry: RuntimeTelemetry; + private userContext: UserContext; + private readonly mutationGovernanceEvents: MutationGovernanceSnapshot[] = []; + + constructor(config: TeaQLClientConfig) { + this.config = config; + // Fallback to global fetch if available + this.fetchImpl = config.fetch ?? (typeof window !== 'undefined' ? window.fetch.bind(window) : fetch); + this.runtimeTelemetry = config.runtimeTelemetry ?? NOOP_RUNTIME_TELEMETRY; + this.userContext = config.userContext ?? new UserContext(); + } + + setRuntimeTelemetry(telemetry: RuntimeTelemetry | undefined): this { + this.runtimeTelemetry = telemetry ?? NOOP_RUNTIME_TELEMETRY; + return this; + } + + setUserContext(context: UserContext): this { + if (!context) throw new TypeError('UserContext is required'); + this.userContext = context; + return this; + } + + get mutationGovernanceTrace(): readonly MutationGovernanceSnapshot[] { + return [...this.mutationGovernanceEvents]; + } + + private async requestHeaders(): Promise> { + const headers: Record = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + return this.config.getHeaders + ? { ...headers, ...await this.config.getHeaders() } + : headers; + } + + async executeQuery(query: SelectQuery | QueryRequest): Promise> { + const request = query instanceof QueryRequest ? query : new QueryRequest(query); + const payload = serializeQuery(request.query, false, request.intent); + const url = `${this.config.baseUrl.replace(/\/$/, '')}/query`; + + return observeRuntimeOperation( + this.runtimeTelemetry, + { family: 'tfp', name: 'client.query', attributes: { 'teaql.tfp.role': 'client' } }, + async () => { + const headers = injectRuntimeContext( + this.runtimeTelemetry, await this.requestHeaders(), + ); + const response = await this.fetchImpl(url, { + method: 'POST', headers, body: JSON.stringify(payload), + }); + if (!response.ok) { + const errText = await response.text(); + throw new Error(`TEAQL Query Error [${response.status}]: ${errText}`); + } + const responseJson = await response.json(); + const facets: Record> = {}; + for (const [name, values] of Object.entries(responseJson.facets ?? {})) { + facets[name] = new SmartList(values as SmartListRecord[]); + } + return new SmartList(responseJson.data ?? [], { facets }); + }, + result => ({ attributes: { 'teaql.result.cardinality': result.length } }), + ); + } + + async *executeForStream( + _query: SelectQuery, + _chunkSize = 1000, + ): AsyncIterable { + new QueryRequest(_query); + throw new Error( + 'TeaQL federation does not support executeForStream over the ordinary TFP request/response protocol; use a dedicated streaming protocol', + ); + } + + async executeMutation(query: any): Promise { + const request = query instanceof MutationRequest ? query : new MutationRequest(query); + query = request.mutation; + const payload = { + entity: query.entity, action: query.action, payload: query.payload, + id: query.id, expectedVersion: query.expectedVersion, comment: query.comment, + }; + rejectRemoteHardLimit(payload); + // Client policy is defense in depth for browser/Node applications. The + // receiving TeaQL server remains authoritative and evaluates its own policy. + const mutationGovernance = this.userContext.enterMutationPolicy(payload); + this.mutationGovernanceEvents.push(mutationGovernance); + return observeRuntimeOperation( + this.runtimeTelemetry, + { family: 'tfp', name: 'client.mutation', attributes: { 'teaql.tfp.role': 'client' } }, + async () => { + const headers = injectRuntimeContext( + this.runtimeTelemetry, await this.requestHeaders(), + ); + const response = await this.fetchImpl(`${this.config.baseUrl.replace(/\/$/, '')}/mutate`, { + method: 'POST', headers, body: JSON.stringify(payload), + }); + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`TeaQL Mutation failed: ${response.status} ${errorText}`); + } + return response.json(); + }, + ); + } +} diff --git a/source/teaql-ts/test-vectors/masking-v1.tsv b/source/teaql-ts/test-vectors/masking-v1.tsv new file mode 100644 index 0000000000000000000000000000000000000000..476f5a8769549238ccccb64f6392035c231d4ac3 --- /dev/null +++ b/source/teaql-ts/test-vectors/masking-v1.tsv @@ -0,0 +1,11 @@ +id input expected +empty +short Ada *** +digits 12345678 ******** +boundary ABCDEFGH AB****GH +long Riverside Ri*****de +quote O'Reilly O'****ly +emoji 😀😀1234😀😀 😀😀****😀😀 +non_ascii_digits 12345678 12****78 +combining éabcdef é****ef +cjk 甲乙丙丁戊己庚辛 甲乙****庚辛 diff --git a/source/teaql-ts/tests/ast.test.ts b/source/teaql-ts/tests/ast.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca943033000de18c1ba86b59f36e08b4f563182f --- /dev/null +++ b/source/teaql-ts/tests/ast.test.ts @@ -0,0 +1,104 @@ +import { SelectQuery, SortDirection, OrderBy, MutationQuery } from '../src/core/ast'; + +describe('AST Classes', () => { + it('keeps continuous page optimization local and validates it', () => { + const query = new SelectQuery('Order').optimizeForContinuousPageFetchWith('orders', 30); + expect(query.localContinuousPageOptions()).toEqual({ namespace: 'orders', ttlSeconds: 30 }); + expect(JSON.stringify(query)).not.toContain('continuousPage'); + expect(() => new SelectQuery('Order').optimizeForContinuousPageFetchWith(' ', 30)).toThrow('namespace'); + expect(() => new SelectQuery('Order').optimizeForContinuousPageFetchWith('orders', 0)).toThrow('ttlSeconds'); + }); + it('keeps ID set pagination local and validates it', () => { + const query = new SelectQuery('Order').optimizePaginationWithIdSetConfig('orders', 30, 1_000); + expect(query.localIdSetPaginationOptions()).toEqual({ namespace: 'orders', ttlSeconds: 30, maxIds: 1_000 }); + expect(JSON.stringify(query)).not.toContain('idSetPagination'); + expect(() => new SelectQuery('Order').optimizePaginationWithIdSetConfig(' ', 30, 1)).toThrow('namespace'); + expect(() => new SelectQuery('Order').optimizePaginationWithIdSetConfig('orders', 0, 1)).toThrow('ttlSeconds'); + expect(() => new SelectQuery('Order').optimizePaginationWithIdSetConfig('orders', 30, 0)).toThrow('maxIds'); + }); + it('enforces a local-only materialized list hard limit', () => { + expect(new SelectQuery('Order').prepareForList().limitValue).toBe(10_000); + expect(() => new SelectQuery('Order').limit(10_001).prepareForList()).toThrow('QUERY_HARD_LIMIT_EXCEEDED'); + expect(() => new SelectQuery('Order').limit(0)).toThrow('QUERY_INVALID_LIMIT'); + expect(() => new SelectQuery('Order').limit(-1)).toThrow('QUERY_INVALID_LIMIT'); + expect(() => new SelectQuery('Order').offset(-1)).toThrow('QUERY_INVALID_OFFSET'); + }); + + it('uses a fixed 10,000 ceiling for every nested relation query', () => { + const nested = new SelectQuery('OrderLine'); + const query = new SelectQuery('Order').relationQuery('lines', nested); + + query.prepareForList(); + expect(query.limitValue).toBe(10_000); + expect(nested.limitValue).toBe(10_000); + + nested.limit(10_001); + expect(() => query.prepareForList()).toThrow('QUERY_HARD_LIMIT_EXCEEDED'); + }); + + it('SelectQuery should build correctly', () => { + const query = new SelectQuery("Task") + .filter({ "status": { "$eq": 1001 } }) + .order(OrderBy.desc("id")) + .limit(5) + .offset(10); + + expect(query.entity).toBe("Task"); + expect(query.filterCondition.status.$eq).toBe(1001); + expect(query.limitValue).toBe(5); + expect(query.offsetValue).toBe(10); + expect(query.orderItems.length).toBe(1); + expect(query.orderItems[0].field).toBe("id"); + expect(query.orderItems[0].direction).toBe(SortDirection.Desc); + }); + + it('captures forward and reverse relation join semantics', () => { + const organization = new SelectQuery('Organization').select(['id', 'name']); + const children = new SelectQuery('Child').select(['id', 'parent']); + const query = new SelectQuery('Person') + .relationQuery('organization', organization, 'organization', 'id', false) + .relationQuery('childList', children, 'id', 'parent', true); + + expect(query.relations).toEqual([ + { name: 'organization', query: organization, localKey: 'organization', foreignKey: 'id', many: false }, + { name: 'childList', query: children, localKey: 'id', foreignKey: 'parent', many: true }, + ]); + }); + + it('SelectQuery should support aggregations and groupBy', () => { + const query = new SelectQuery("Task") + .aggregate("Count", "id", "taskCount") + .groupBy("status"); + + expect(query.aggregateItems.length).toBe(1); + expect(query.aggregateItems[0].function).toBe("Count"); + expect(query.aggregateItems[0].field).toBe("id"); + expect(query.aggregateItems[0].alias).toBe("taskCount"); + + expect(query.groupByItems.length).toBe(1); + expect(query.groupByItems[0]).toBe("status"); + }); + + it('SelectQuery should preserve nested relation limit in JSON', () => { + const query = new SelectQuery('Order').relationQuery( + 'lines', + new SelectQuery('OrderLine').order(OrderBy.desc('id')).limit(3), + ); + + const payload = JSON.parse(JSON.stringify(query)); + + expect(payload.relations[0].name).toBe('lines'); + expect(payload.relations[0].query.limitValue).toBe(3); + expect(payload.relations[0].query.orderItems[0].field).toBe('id'); + }); + + it('MutationQuery should build correctly', () => { + const mut = new MutationQuery("Task", "Create", { name: "New Task" }, 1, "Creation comment"); + + expect(mut.entity).toBe("Task"); + expect(mut.action).toBe("Create"); + expect(mut.payload.name).toBe("New Task"); + expect(mut.id).toBe(1); + expect(mut.comment).toBe("Creation comment"); + }); +}); diff --git a/source/teaql-ts/tests/browser-sqlite.test.ts b/source/teaql-ts/tests/browser-sqlite.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..5931faf7e1d9cb2c6e0fd5e9cb282d23a5901c1e --- /dev/null +++ b/source/teaql-ts/tests/browser-sqlite.test.ts @@ -0,0 +1,138 @@ +import { UserContext } from '../src/core/context'; +import { + DelegatingMutationPolicyRegistry, + MutationPolicyError, +} from '../src/core/mutation-policy'; +import { + BrowserSQLiteDriver, + BrowserSQLiteTeaQLClient, + BrowserSQLiteWorkerLike, +} from '../src/sql/browser-sqlite'; +import { + BrowserSQLiteRequest, + BrowserSQLiteResponse, +} from '../src/sql/browser-sqlite-protocol'; + +class FakeWorker implements BrowserSQLiteWorkerLike { + readonly requests: BrowserSQLiteRequest[] = []; + terminated = false; + private readonly messageListeners = new Set<(event: MessageEvent) => void>(); + private readonly errorListeners = new Set<(event: ErrorEvent) => void>(); + + postMessage(message: BrowserSQLiteRequest): void { + this.requests.push(message); + queueMicrotask(() => { + let result: unknown; + if (message.operation === 'query') { + const sql = String(message.payload?.sql ?? ''); + result = sql.startsWith('SELECT') + ? { rows: [{ id: 1, name: 'Local' }], rowCount: 1 } + : { rows: [], rowCount: 0 }; + } + const event = { data: { + type: 'teaql-browser-sqlite-response', requestId: message.requestId, result, + } } as MessageEvent; + for (const listener of this.messageListeners) listener(event); + }); + } + + addEventListener(type: 'message' | 'error', listener: any): void { + if (type === 'message') this.messageListeners.add(listener); + else this.errorListeners.add(listener); + } + + removeEventListener(type: 'message' | 'error', listener: any): void { + if (type === 'message') this.messageListeners.delete(listener); + else this.errorListeners.delete(listener); + } + + terminate(): void { this.terminated = true; } +} + +describe('BrowserSQLiteDriver', () => { + test('defaults to a deterministic in-memory database', async () => { + const worker = new FakeWorker(); + const driver = await BrowserSQLiteDriver.open(worker); + + expect(worker.requests[0]).toMatchObject({ + operation: 'open', + payload: { storage: 'memory', databaseName: 'teaql-browser.sqlite3' }, + }); + await driver.close(); + expect(worker.terminated).toBe(true); + }); + + test('supports explicit OPFS and buffered stream compatibility', async () => { + const worker = new FakeWorker(); + const driver = await BrowserSQLiteDriver.open(worker, { + storage: 'opfs', databaseName: 'demo.sqlite3', terminateWorkerOnClose: false, + }); + + const rows: unknown[] = []; + for await (const row of driver.stream('SELECT id, name FROM demo')) rows.push(row); + expect(rows).toEqual([{ id: 1, name: 'Local' }]); + expect(worker.requests[0].payload).toMatchObject({ storage: 'opfs', databaseName: 'demo.sqlite3' }); + await driver.close(); + expect(worker.terminated).toBe(false); + }); + + test('serializes a transaction and rolls it back on failure', async () => { + const worker = new FakeWorker(); + const driver = await BrowserSQLiteDriver.open(worker); + + await expect(driver.transaction(async session => { + await session.query('UPDATE demo SET name = ?', ['Changed']); + throw new Error('reject mutation'); + })).rejects.toThrow('reject mutation'); + + expect(worker.requests.filter(request => request.operation === 'query') + .map(request => request.payload?.sql)).toEqual([ + 'BEGIN IMMEDIATE', 'UPDATE demo SET name = ?', 'ROLLBACK', + ]); + await driver.close(); + }); + + test('reset invalidates schema state and explicitly reconciles it again', async () => { + const worker = new FakeWorker(); + const client = await BrowserSQLiteTeaQLClient.open(worker, {}); + const context = new UserContext().insertResource('dataService', client); + client.setUserContext(context); + + await context.ensureSchema(); + await client.reset(context); + + expect(worker.requests.filter(request => request.operation === 'reset')).toHaveLength(1); + expect(worker.requests.filter(request => + request.operation === 'query' && String(request.payload?.sql).includes('teaql_id_space'), + )).toHaveLength(2); + await client.close(); + }); + + test('rejects path-like database names', async () => { + await expect(BrowserSQLiteDriver.open(new FakeWorker(), { + databaseName: '../outside.sqlite3', + })).rejects.toThrow('simple file name'); + }); + + test.each(['memory', 'opfs'] as const)( + '%s profile applies Mutation Policy before sending SQL to the worker', + async storage => { + const worker = new FakeWorker(); + const client = await BrowserSQLiteTeaQLClient.open(worker, {}, { storage }); + const context = new UserContext().withMutationPolicyRegistry( + new DelegatingMutationPolicyRegistry(() => ({ + identity: { policyId: 'browser-demo', version: '1', fingerprint: 'sha256:demo' }, + review: () => ({ verdict: 'deny', code: 'DEMO_DENIED', message: 'disabled' }), + })), + ); + client.setUserContext(context); + const queriesBefore = worker.requests.filter(request => request.operation === 'query').length; + + await expect(client.executeMutation({ + entity: 'Demo', action: 'Create', payload: { name: 'blocked' }, comment: 'demo', + })).rejects.toThrow(MutationPolicyError); + expect(worker.requests.filter(request => request.operation === 'query')).toHaveLength(queriesBefore); + await client.close(); + }, + ); +}); diff --git a/source/teaql-ts/tests/checker.test.ts b/source/teaql-ts/tests/checker.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..e6302382cc004bb17a56780172252a064cae771f --- /dev/null +++ b/source/teaql-ts/tests/checker.test.ts @@ -0,0 +1,163 @@ +import { CheckException, CheckResult, EntityChecker, EntityRoot, MutationIntent, ObjectLocation, RuntimeModule, UserContext } from '../src'; +import { AbstractSQLTeaQLClient, TeaQLSqlDriver } from '../src/sql/core'; + +class Driver implements TeaQLSqlDriver { + readonly databaseKind = 'sqlite' as const; + transactions = 0; + statements: string[] = []; + query = async (sql: string) => { this.statements.push(sql); return { rows: sql.startsWith('SELECT') ? [{ id: '1', version: 1, userEmail: 'a@b.test' }] : [], rowCount: 1 }; }; + stream = async function* () {}; + identifier = (value: string) => `"${value}"`; + placeholder = () => '?'; + encode = (value: any) => value; + contains = () => ''; + aggregateFunction = (name: string) => name; + ensureSchema = async () => {}; + transaction = async (work: (session: any) => Promise) => { this.transactions++; return work(this); }; + nextId = async () => '1'; + ensureIdFloor = async () => {}; + close = async () => {}; +} + +class Client extends AbstractSQLTeaQLClient { + constructor(driver: Driver) { super(driver, {}); } +} + +test('checker failure is structured, save scoped, and runs before SQL transaction', async () => { + const driver = new Driver(); + const context = new UserContext(); + let calls = 0; + const checker: EntityChecker = { + checkAndFix(ctx, mutation, results: CheckResult[]) { + calls++; + expect(ctx.getResource('fixTime')).toBeInstanceOf(Date); + if (!mutation.payload.name) results.push({ ruleId: 'required', location: ObjectLocation.property('name') }); + }, + }; + const client = new Client(driver).setUserContext(context).install(new RuntimeModule({ + Task: { table: 'task', columns: {} }, + }, { Task: checker })); + const mutation = { entity: 'Task', action: 'Create', payload: {}, comment: 'test' }; + + for (let attempt = 0; attempt < 2; attempt++) { + await expect(client.executeMutation(mutation)).rejects.toBeInstanceOf(CheckException); + } + expect(calls).toBe(2); + expect(driver.transactions).toBe(0); + expect(context.getResource('fixTime')).toBeUndefined(); +}); + +test('canonical multiword mutation key reaches checker and native SQL schema', async () => { + const driver = new Driver(); + const checker: EntityChecker = { + checkAndFix(_context, mutation, results) { + if (!mutation.payload.user_email) { + results.push({ ruleId: 'required', location: ObjectLocation.property('user_email') }); + } + }, + }; + const client = new Client(driver).setUserContext(new UserContext()).install(new RuntimeModule({ + User: { table: 'user_data', columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + userEmail: { columnName: 'email_address', modelName: 'user_email', logicalType: 'text', decode: 'native' }, + } }, + }, { User: checker })); + + const result = await client.executeMutation({ + entity: 'User', action: 'Create', payload: { user_email: 'a@b.test' }, comment: 'test canonical key', + }); + expect(result.persistedRecord?.userEmail).toBe('a@b.test'); + expect(driver.statements.some(sql => sql.includes('"email_address"'))).toBe(true); +}); + +test('update checker can add fixes to an immutable mutation ledger snapshot', async () => { + const driver = new Driver(); + const context = new UserContext(); + const ledgerRoot = new EntityRoot(); + const ledgerKey = { entity: 'Task', id: '1' } as const; + const checker: EntityChecker = { + checkAndFix(ctx, mutation) { + expect(ctx.getResource('fixTime')).toBeInstanceOf(Date); + mutation.payload.update_time = ctx.getResource('fixTime'); + }, + }; + const client = new Client(driver).setUserContext(context).install(new RuntimeModule({ + Task: { table: 'task_data', columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + name: { columnName: 'name', logicalType: 'text', decode: 'native' }, + updateTime: { columnName: 'update_time', modelName: 'update_time', logicalType: 'datetime', decode: 'date' }, + } }, + }, { Task: checker })); + + const immutableLedgerPayload = Object.freeze({ name: 'Updated task' }); + await expect(client.executeMutation({ + entity: 'Task', action: 'Update', payload: immutableLedgerPayload, + id: '1', version: 1, comment: 'update task', ledgerKey, ledgerRoot, + })).resolves.toBeDefined(); + + expect(Object.isFrozen(immutableLedgerPayload)).toBe(true); + expect((immutableLedgerPayload as Record).update_time).toBeUndefined(); + expect(ledgerRoot.change(ledgerKey).update_time).toBeInstanceOf(Date); + expect(driver.statements.some(sql => sql.includes('"update_time" = ?'))).toBe(true); +}); + +test('one graph captures one fix clock and clears it after commit', async () => { + const driver = new Driver(); + const context = new UserContext(); + const observed: Date[] = []; + const checker: EntityChecker = { + checkAndFix(ctx, mutation) { + const now = ctx.requireResource('fixTime'); + observed.push(now); + mutation.payload.create_time = now; + }, + }; + const client = new Client(driver).setUserContext(context).install(new RuntimeModule({ + Task: { table: 'task_data', columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + createTime: { columnName: 'create_time', modelName: 'create_time', logicalType: 'datetime', decode: 'date' }, + } }, + }, { Task: checker })); + + await client.executeGraphSave(new MutationIntent('fix graph'), async graph => { + await client.executeMutation(graph.request({ entity: 'Task', action: 'Create', payload: {} })); + await new Promise(resolve => setTimeout(resolve, 5)); + await client.executeMutation(graph.request({ entity: 'Task', action: 'Create', payload: {} })); + }); + + expect(observed).toHaveLength(2); + expect(observed[0]).toBe(observed[1]); + expect(driver.transactions).toBe(1); + expect(context.getResource('fixTime')).toBeUndefined(); +}); + +test('independent concurrent graph saves are serialized instead of joining', async () => { + const driver = new Driver(); + const client = new Client(driver).install(new RuntimeModule({ + Task: { table: 'task_data', columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + name: { columnName: 'name', logicalType: 'text', decode: 'string' }, + } }, + })); + const events: string[] = []; + + const first = client.executeGraphSave(new MutationIntent('first'), async graph => { + events.push('first:start'); + await new Promise(resolve => setTimeout(resolve, 10)); + await client.executeMutation(graph.request({ entity: 'Task', action: 'Create', payload: { name: 'first' } })); + events.push('first:end'); + }); + const second = client.executeGraphSave(new MutationIntent('second'), async graph => { + events.push('second:start'); + await client.executeMutation(graph.request({ entity: 'Task', action: 'Create', payload: { name: 'second' } })); + events.push('second:end'); + }); + + await Promise.all([first, second]); + expect(events).toEqual(['first:start', 'first:end', 'second:start', 'second:end']); + expect(driver.transactions).toBe(2); +}); diff --git a/source/teaql-ts/tests/client.test.ts b/source/teaql-ts/tests/client.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..6ff7d42dfaeaf86595721ab95557a34af1bec0b7 --- /dev/null +++ b/source/teaql-ts/tests/client.test.ts @@ -0,0 +1,298 @@ +import { TeaQLClient } from '../src/tfp/client'; +import { SelectQuery, SortDirection, OrderBy, MutationQuery } from '../src/core/ast'; +import { RuntimeOperation, RuntimeTelemetry, RuntimeTelemetryScope } from '../src/core/telemetry'; +import { SmartList } from '../src/core/smart-list'; +import { + DelegatingMutationPolicyApprovalProvider, + DelegatingMutationPolicyRegistry, + MutationPolicyError, +} from '../src/core/mutation-policy'; +import { UserContext } from '../src/core/context'; + +class TfpRecordingTelemetry implements RuntimeTelemetry { + readonly events: Array<{ operation: RuntimeOperation; outcome?: string; cardinality?: number }> = []; + start(operation: RuntimeOperation): RuntimeTelemetryScope { + const event = { operation } as { operation: RuntimeOperation; outcome?: string; cardinality?: number }; + this.events.push(event); + return { + success: completion => { + event.outcome = 'success'; + event.cardinality = completion?.attributes?.['teaql.result.cardinality'] as number | undefined; + }, + failure: () => { event.outcome = 'failure'; }, + }; + } +} + +// Mock fetch globally +global.fetch = jest.fn(); + +const federalQuery = (entity: string) => new SelectQuery(entity) + .comment('conformance query').purpose('conformance test'); + +describe('TeaQLClient Backend/Node.js Tests', () => { + beforeEach(() => { + (global.fetch as jest.Mock).mockClear(); + }); + + it('should serialize SelectQuery correctly and send via fetch', async () => { + // 1. Arrange: Setup mock response + const mockData = [{ id: 1, name: "Test User" }]; + (global.fetch as jest.Mock).mockResolvedValue({ + ok: true, + json: async () => ({ data: mockData }) + }); + + // 2. Arrange: Create client and query + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }); + const query = federalQuery("User") + .filter({ "name": { "$eq": "Test User" } }) + .order(OrderBy.desc("id")) + .limit(10); + + // 3. Act: Execute query + const result = await client.executeQuery(query); + + // 4. Assert: Check response and fetch payload + expect(result).toBeInstanceOf(SmartList); + expect(Array.from(result)).toEqual(mockData); + expect(global.fetch).toHaveBeenCalledTimes(1); + + // Check fetch arguments + const [url, options] = (global.fetch as jest.Mock).mock.calls[0]; + expect(url).toBe('http://localhost:8080/api/query'); + expect(options.method).toBe('POST'); + expect(options.headers['Content-Type']).toBe('application/json'); + + // Ensure the query was correctly serialized to JSON + const body = JSON.parse(options.body); + expect(body.entity).toBe("User"); + expect(body.limitValue).toBe(10); + expect(body.filterCondition.name.$eq).toBe("Test User"); + expect(body.orderItems[0].field).toBe("id"); + expect(body.orderItems[0].direction).toBe(SortDirection.Desc); + }); + + it('serializes canonical facets and restores SmartList facet metadata', async () => { + (global.fetch as jest.Mock).mockResolvedValue({ + ok: true, + json: async () => ({ data: [], facets: { statusCount: [{ code: 'NEW', count: 5 }] } }) + }); + + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }); + const query = federalQuery("Task"); + + const facetQuery = federalQuery("TaskStatus") + .select(['id', 'code']) + .aggregate("Count", "id", "count"); + query.facetBy("statusCount", "status", { toQuery: () => facetQuery }); + + const result = await client.executeQuery(query); + expect(global.fetch).toHaveBeenCalledTimes(1); + const body = JSON.parse((global.fetch as jest.Mock).mock.calls[0][1].body); + expect(body.facets[0].facetName).toBe('statusCount'); + expect(body.facets[0].relationName).toBe('status'); + expect(body.facets[0].query.entity).toBe('TaskStatus'); + expect(result.facet('statusCount')?.[0]).toEqual({ code: 'NEW', count: 5 }); + }); + + it('should support mutations and correctly serialize them to /mutate', async () => { + const mockResponse = { success: true, saved_data: [{ id: 1, name: "Created" }] }; + (global.fetch as jest.Mock).mockResolvedValue({ + ok: true, + json: async () => mockResponse + }); + + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }); + const mutation = new MutationQuery("Task", "Create", { name: "Created" }, undefined, "create task"); + + const result = await client.executeMutation(mutation); + + expect(result).toEqual(mockResponse); + expect(global.fetch).toHaveBeenCalledTimes(1); + + const [url, options] = (global.fetch as jest.Mock).mock.calls[0]; + expect(url).toBe('http://localhost:8080/api/mutate'); + expect(options.method).toBe('POST'); + + const body = JSON.parse(options.body); + expect(body.entity).toBe("Task"); + expect(body.action).toBe("Create"); + expect(body.payload.name).toBe("Created"); + expect(body.comment).toBe("create task"); + }); + + it('applies client-profile Mutation Policy before issuing a TFP mutation', async () => { + const context = new UserContext().withMutationPolicyRegistry( + new DelegatingMutationPolicyRegistry(() => ({ + identity: { policyId: 'client-demo', version: '1', fingerprint: 'sha256:client' }, + review: () => ({ verdict: 'deny', code: 'CLIENT_DENIED', message: 'disabled' }), + })), + ); + const client = new TeaQLClient({ + baseUrl: 'http://localhost:8080/api', userContext: context, + }); + + await expect(client.executeMutation( + new MutationQuery('Task', 'Create', { name: 'blocked' }, undefined, 'demo'), + )).rejects.toThrow(MutationPolicyError); + expect(global.fetch).not.toHaveBeenCalled(); + }); + + it('retains approved client-profile governance without serializing it', async () => { + (global.fetch as jest.Mock).mockResolvedValue({ + ok: true, json: async () => ({ success: true }), + }); + const identity = { policyId: 'client-demo', version: '1', fingerprint: 'sha256:client' }; + const context = new UserContext() + .withMutationPolicyRegistry(new DelegatingMutationPolicyRegistry(() => ({ + identity, review: () => ({ verdict: 'allow' }), + }))) + .withMutationPolicyApprovalProvider(new DelegatingMutationPolicyApprovalProvider( + policy => ({ policy, approvedBy: 'demo-owner', approvedAt: new Date() }), + )); + const client = new TeaQLClient({ + baseUrl: 'http://localhost:8080/api', userContext: context, + }); + + await client.executeMutation( + new MutationQuery('Task', 'Create', { name: 'allowed' }, undefined, 'demo'), + ); + expect(client.mutationGovernanceTrace[0].approvalStatus).toBe('approved'); + expect((global.fetch as jest.Mock).mock.calls[0][1].body) + .not.toContain('mutationGovernance'); + }); + + it('records balanced TFP client query and mutation lifecycles', async () => { + const telemetry = new TfpRecordingTelemetry(); + (global.fetch as jest.Mock) + .mockResolvedValueOnce({ ok: true, json: async () => ({ data: [{ id: 1 }] }) }) + .mockResolvedValueOnce({ ok: true, json: async () => ({ success: true }) }); + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api', runtimeTelemetry: telemetry }); + + await client.executeQuery(federalQuery('Task')); + await client.executeMutation(new MutationQuery('Task', 'Create', {}, undefined, 'test')); + + expect(telemetry.events.map(event => [ + event.operation.family, + event.operation.name, + event.operation.attributes?.['teaql.tfp.role'], + event.outcome, + ])).toEqual([ + ['tfp', 'client.query', 'client', 'success'], + ['tfp', 'client.mutation', 'client', 'success'], + ]); + expect(telemetry.events[0].cardinality).toBe(1); + }); + + it('records TFP transport failure and rethrows the original error', async () => { + const telemetry = new TfpRecordingTelemetry(); + const transportError = new Error('network unavailable'); + (global.fetch as jest.Mock).mockRejectedValue(transportError); + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }) + .setRuntimeTelemetry(telemetry); + + await expect(client.executeQuery(federalQuery('Task'))).rejects.toBe(transportError); + expect(telemetry.events).toHaveLength(1); + expect(telemetry.events[0].outcome).toBe('failure'); + }); + + it('injects trace metadata inside the TFP client operation without touching payload', async () => { + const telemetry = new TfpRecordingTelemetry() as TfpRecordingTelemetry & RuntimeTelemetry; + telemetry.inject = carrier => { carrier.traceparent = '00-trace-span-01'; }; + (global.fetch as jest.Mock).mockResolvedValue({ + ok: true, json: async () => ({ data: [] }), + }); + const client = new TeaQLClient({ + baseUrl: 'http://localhost:8080/api', runtimeTelemetry: telemetry, + }); + + await client.executeQuery(federalQuery('Task')); + + const [, options] = (global.fetch as jest.Mock).mock.calls[0]; + expect(options.headers.traceparent).toBe('00-trace-span-01'); + expect(options.body).not.toContain('traceparent'); + }); + + it('keeps TFP requests working when propagation injection fails', async () => { + const telemetry = new TfpRecordingTelemetry() as TfpRecordingTelemetry & RuntimeTelemetry; + telemetry.inject = () => { throw new Error('propagator unavailable'); }; + (global.fetch as jest.Mock).mockResolvedValue({ + ok: true, json: async () => ({ data: [] }), + }); + + await new TeaQLClient({ + baseUrl: 'http://localhost:8080/api', runtimeTelemetry: telemetry, + }).executeQuery(federalQuery('Task')); + expect(global.fetch).toHaveBeenCalledTimes(1); + }); + + it('uses trusted authentication headers for mutations without serializing context', async () => { + (global.fetch as jest.Mock).mockResolvedValue({ ok: true, json: async () => ({ success: true }) }); + const client = new TeaQLClient({ + baseUrl: 'http://localhost:8080/api/', + getHeaders: async () => ({ Authorization: 'Bearer trusted-session' }), + }); + const mutation = new MutationQuery('Task', 'Update', { id: 1 }, 2, 'update task'); + + await client.executeMutation(mutation); + + const [url, options] = (global.fetch as jest.Mock).mock.calls[0]; + expect(url).toBe('http://localhost:8080/api/mutate'); + expect(options.headers.Authorization).toBe('Bearer trusted-session'); + expect(options.body).not.toContain('trusted-session'); + }); + + it('rejects streaming over the ordinary federation protocol without issuing HTTP', async () => { + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }); + const consume = async () => { + for await (const _chunk of client.executeForStream(federalQuery('Task'))) { /* consume */ } + }; + await expect(consume()).rejects.toThrow(/dedicated streaming protocol/); + expect(global.fetch).not.toHaveBeenCalled(); + }); + + it.each(['hardLimit', 'hard_limit', 'hard_limit_value']) ( + 'rejects remote hard-limit injection through %s without issuing HTTP', + async (field) => { + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }); + const query = federalQuery('Order') as SelectQuery & Record; + query[field] = 20_000; + + await expect(client.executeQuery(query)).rejects.toThrow('TFP_FORBIDDEN_FIELD'); + expect(global.fetch).not.toHaveBeenCalled(); + }, + ); + + it.each(['continuousPageFetch', 'continuous_page_fetch', 'continuousPageRuntime']) ( + 'rejects remote local cursor policy field %s without issuing HTTP', + async (field) => { + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }); + const query = federalQuery('Order') as SelectQuery & Record; + query[field] = { namespace: 'attacker', ttlSeconds: 999 }; + await expect(client.executeQuery(query)).rejects.toThrow('TFP_FORBIDDEN_FIELD'); + expect(global.fetch).not.toHaveBeenCalled(); + }, + ); + + it.each(['idSetPagination', 'id_set_pagination', 'paginationWithIdSet']) ( + 'rejects remote ID-set retention policy field %s without issuing HTTP', + async (field) => { + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }); + const query = federalQuery('Order') as SelectQuery & Record; + query[field] = { namespace: 'attacker', ttlSeconds: 999, maxIds: 9_999_999 }; + await expect(client.executeQuery(query)).rejects.toThrow('TFP_FORBIDDEN_FIELD'); + expect(global.fetch).not.toHaveBeenCalled(); + }, + ); + + it('rejects nested remote hard-limit injection without issuing HTTP', async () => { + const client = new TeaQLClient({ baseUrl: 'http://localhost:8080/api' }); + const nested = new SelectQuery('OrderLine') as SelectQuery & Record; + nested.hard_limit = 20_000; + const query = federalQuery('Order').relationQuery('lines', nested); + + await expect(client.executeQuery(query)).rejects.toThrow('TFP_FORBIDDEN_FIELD'); + expect(global.fetch).not.toHaveBeenCalled(); + }); +}); diff --git a/source/teaql-ts/tests/context.test.ts b/source/teaql-ts/tests/context.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..6cf4d130bd37299da21b2f5dc8a6dc5b0b8f6c97 --- /dev/null +++ b/source/teaql-ts/tests/context.test.ts @@ -0,0 +1,34 @@ +import { UserContext } from '../src/core/context'; +import { SelectQuery } from '../src/core/ast'; + +describe('UserContext', () => { + it('stores runtime dependencies during context initialization', () => { + const service = { name: 'data-service' }; + const context = new UserContext().insertResource('dataService', service); + + expect(context.requireResource('dataService')).toBe(service); + }); + + it('prepares a query without serializing trusted runtime resources', () => { + const query = new SelectQuery('Order'); + const context = new UserContext().insertResource('tenant', 'trusted-tenant'); + expect(context.prepareQuery(query)).toBe(query); + expect(JSON.stringify(query)).not.toContain('trusted-tenant'); + }); + + it('fails closed when a required runtime dependency is absent', () => { + const context = new UserContext(); + + expect(() => context.requireResource('dataService')).toThrow( + 'Required UserContext resource is missing: dataService', + ); + }); + + it('binds a typed active root and rejects missing or mismatched types', () => { + const context = new UserContext(); + expect(() => context.requireActiveRoot('Tenant')).toThrow('context root missing'); + context.withActiveRoot({ entity: 'Tenant', id: 42 }); + expect(context.requireActiveRoot('Tenant').id).toBe(42); + expect(() => context.requireActiveRoot('Store')).toThrow('context root type_mismatch'); + }); +}); diff --git a/source/teaql-ts/tests/debug-sql.test.ts b/source/teaql-ts/tests/debug-sql.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..22c06719b9767190bf87b6706db866de029fe596 --- /dev/null +++ b/source/teaql-ts/tests/debug-sql.test.ts @@ -0,0 +1,67 @@ +import { debugSQL } from '../src/sql/core'; +import { Values } from '../src/core/value'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +describe('debugSQL', () => { + test('renders positional SQL that can be copied into SQLite or MySQL', () => { + expect(debugSQL( + "SELECT * FROM school WHERE name = ? AND active = ? AND phone IS ? AND note = '?'", + ["O'Brien School", true, null], + )).toBe( + "SELECT * FROM school WHERE name = 'O''Brien School' AND active = TRUE AND phone IS NULL AND note = '?'", + ); + }); + + test('renders numbered placeholders repeatedly and ignores SQL string literals', () => { + expect(debugSQL("SELECT $2, $1, $1, '$2'", ["O'Brien", 7])) + .toBe("SELECT 7, 'O''Brien', 'O''Brien', '$2'"); + expect(debugSQL('SELECT @p2, @p1', ['first', 'second'])) + .toBe("SELECT 'second', 'first'"); + }); + + test('preserves comments and renders SQLite temporal storage literals', () => { + expect(debugSQL( + "-- line ? $1\nSELECT '?', \"identifier?\", ?, ? /* block ? */", + [Values.Date('2024-02-29'), Values.Timestamp(1787110200123)], + )).toBe( + "-- line ? $1\nSELECT '?', \"identifier?\", '2024-02-29', 1787110200123 /* block ? */", + ); + }); + + test('temporal debug SQL matches prepared SQLite storage', async () => { + const driver = new SQLiteDriver(':memory:'); + try { + await driver.query('CREATE TABLE temporal_fixture(id INTEGER, d TEXT, t INTEGER)'); + await driver.query( + 'INSERT INTO temporal_fixture VALUES (?, ?, ?) /* ignored ? */', + [1, '2024-02-29', -123], + ); + const literal = debugSQL( + '/* teaql source=temporal ? */ INSERT INTO temporal_fixture VALUES (?, ?, ?)', + [Values.I64(2), Values.Date('2024-02-29'), Values.Timestamp(-123)], + ); + await driver.query(literal); + const result = await driver.query( + 'SELECT d, t, typeof(d) AS dt, typeof(t) AS tt FROM temporal_fixture ORDER BY id', + ); + expect(result.rows).toEqual([ + { d: '2024-02-29', t: -123, dt: 'text', tt: 'integer' }, + { d: '2024-02-29', t: -123, dt: 'text', tt: 'integer' }, + ]); + } finally { + await driver.close(); + } + }); + + test('renders PostgreSQL and MySQL typed temporal literals', () => { + const values = [Values.Date('2024-02-29'), Values.Timestamp(-315521754322)]; + expect(debugSQL( + '-- ignored $1\nSELECT $1, $2 /* ignored $2 */', values, 'postgresql', + )).toBe( + "-- ignored $1\nSELECT DATE '2024-02-29', TIMESTAMPTZ '1960-01-02T03:04:05.678Z' /* ignored $2 */", + ); + expect(debugSQL('SELECT ?, ? /* ignored ? */', values, 'mysql')).toBe( + "SELECT CAST('2024-02-29' AS DATE), CAST('1960-01-02 03:04:05.678' AS DATETIME(3)) /* ignored ? */", + ); + }); +}); diff --git a/source/teaql-ts/tests/dynamic-search-sqlite.test.ts b/source/teaql-ts/tests/dynamic-search-sqlite.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..c9730f0e4442f0cd282dc9506c708cfd4d749c79 --- /dev/null +++ b/source/teaql-ts/tests/dynamic-search-sqlite.test.ts @@ -0,0 +1,70 @@ +import { mergeDynamicSearch, SearchModel } from '../src/core/dynamic-search'; +import { OrderBy, SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { RuntimeModule } from '../src/core/runtime-module'; +import { EntitySchema } from '../src/sql/core'; +import { SQLiteTeaQLClient } from '../src/sql/sqlite'; + +const models: Record = { + Order: {fields: {id: 'integer', name: 'string', tenant: 'integer', customer: 'integer'}, relations: {customer: 'Customer'}}, + Customer: {fields: {id: 'integer', name: 'string', tenant: 'integer'}, relations: {}}, +}; +const numberColumn = (name: string) => ({columnName: name, logicalType: 'integer' as const, decode: 'number' as const}); +const schemas: Record = Object.fromEntries(['Order', 'Customer'].map(entity => [entity, { + table: entity.toLowerCase() + '_data', + columns: {id: numberColumn('id'), version: numberColumn('version'), tenant: numberColumn('tenant'), + name: {columnName: 'name', logicalType: 'text', decode: 'native'}, + ...(entity === 'Order' ? {customer: numberColumn('customer')} : {})}, +}])) as Record; + +test('unknown clauses disappear while real SQLite execution retains tenant scope and nested sibling', async () => { + const client = new SQLiteTeaQLClient(':memory:', {}).install(new RuntimeModule(schemas)) as SQLiteTeaQLClient; + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const tenant of [1, 2]) { + const customer = await client.executeMutation({entity: 'Customer', action: 'Create', + payload: {name: 'Ada', tenant}, comment: 'seed scoped search fixture'}); + await client.executeMutation({entity: 'Order', action: 'Create', + payload: {name: 'matched', tenant, customer: Number(customer.id)}, comment: 'seed scoped order'}); + } + const base = new SelectQuery('Order').filter({tenant: {$eq: 1}}).limit(10) + .comment('what: read scoped orders').purpose('why: verify dynamic search'); + base.orderItems.push(OrderBy.asc('id')); + const before = JSON.stringify(base); + const warn = jest.fn(); + const {query, warnings} = mergeDynamicSearch(base, {filter: { + removed: 'SECRET', 'missing.name': 'SECRET', 'customer.removed': 'SECRET', + 'customer.name': {$eq: 'Ada'}, name: {$eq: 'matched'}, + }, orderBy: [{field: 'removed', direction: 'desc'}]}, models, { + filter: (path, predicate) => { + if (path === 'customer.name') { + const child = new SelectQuery('Customer').filter({$and: [ + {tenant: {$eq: 1}}, {version: {$gte: 1}}, {name: predicate}, + ]}); + return {customer: {$inSubquery: {query: child, field: 'id'}}}; + } + return {[path]: predicate}; + }, + order: (path, direction) => direction === 'asc' ? OrderBy.asc(path) : OrderBy.desc(path), + }, warn); + const rows = await client.executeQuery(query); + expect(rows).toHaveLength(1); + expect(rows[0].tenant).toBe(1); + expect(query.limitValue).toBe(10); + expect(query.orderItems).toEqual(base.orderItems); + expect(JSON.stringify(base)).toBe(before); + expect(warnings).toHaveLength(4); + expect(JSON.stringify(warn.mock.calls)).not.toContain('SECRET'); + } finally { await client.close(); } +}); + +test('binding failure cannot mutate scoped query or publish partial warnings', () => { + const base = new SelectQuery('Order').filter({tenant: 1}).limit(10); + const before = JSON.stringify(base); + const warn = jest.fn(); + expect(() => mergeDynamicSearch(base, {filter: {removed: 'secret', name: 'ok'}}, models, { + filter: () => { throw new Error('unsupported trusted binding'); }, order: () => OrderBy.asc('id'), + }, warn)).toThrow(); + expect(JSON.stringify(base)).toBe(before); + expect(warn).not.toHaveBeenCalled(); +}); diff --git a/source/teaql-ts/tests/dynamic-search.test.ts b/source/teaql-ts/tests/dynamic-search.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..cdf81990bfc80447582a6b16dad59a82ae5ab28c --- /dev/null +++ b/source/teaql-ts/tests/dynamic-search.test.ts @@ -0,0 +1,76 @@ +import { normalizeDynamicSearch, SearchModel } from '../src/core/dynamic-search'; + +const models: Record = { + Order: { fields: { id: 'integer', name: 'string', amount: 'number' }, relations: { customer: 'Customer' } }, + Customer: { fields: { name: 'string' }, relations: {} }, +}; + +test('DYN-WARN-001 through 006: complete unknown clauses vanish, siblings remain, no values leak', () => { + const warn = jest.fn(); + const result = normalizeDynamicSearch({ filter: { + removed: 'SECRET', 'missing.name': 'SECRET', 'customer.removed': 'SECRET', name: 'valid', + }, orderBy: [{ field: 'removed', direction: 'asc' }, { field: 'id', direction: 'desc' }] }, 'Order', models, warn); + expect(result.search.filter).toEqual({ name: { $eq: 'valid' } }); + expect(result.search.orderBy).toEqual([{ field: 'id', direction: 'desc' }]); + expect(result.warnings.map(w => w.fieldPath)).toEqual(['removed', 'missing.name', 'customer.removed', 'removed']); + expect(result.warnings.every(w => w.code === 'DYNAMIC_SEARCH_UNKNOWN_FIELD' && w.entity === 'Order')).toBe(true); + expect(JSON.stringify(warn.mock.calls)).not.toContain('SECRET'); +}); + +test('DYN-WARN-008: default log omits untrusted path, returned warning retains it', () => { + const path = 'CLIENT_SECRET_FIELD_PATH_91'; + const log = jest.spyOn(console, 'warn').mockImplementation(() => {}); + try { + const result = normalizeDynamicSearch({filter: {[path]: 'SECRET_VALUE_99'}}, 'Order', models); + expect(result.warnings[0].fieldPath).toBe(path); + expect(log).toHaveBeenCalledWith(expect.objectContaining({ + code: 'DYNAMIC_SEARCH_UNKNOWN_FIELD', fieldPath: '', + })); + expect(JSON.stringify(log.mock.calls)).not.toContain(path); + expect(JSON.stringify(log.mock.calls)).not.toContain('SECRET_VALUE_99'); + } finally { + log.mockRestore(); + } +}); + +test('valid nested fields are retained without partial relation construction', () => { + expect(normalizeDynamicSearch({filter: {'customer.name': {$contains: 'Ada'}}}, 'Order', models).search.filter) + .toEqual({'customer.name': {$contains: 'Ada'}}); +}); + +test('DYN-WARN-007: malformed input and context injection are fatal', () => { + for (const input of ['{', '[]', 'null', '{} {}', '{"tenant":1}', '{"hardLimit":999999}', '{"policy":{}}']) { + expect(() => normalizeDynamicSearch(input, 'Order', models)).toThrow(); + } +}); + +test('operator, known-field conversion, resource limits and dangerous paths stay fatal', () => { + for (const input of [ + {filter: {removed: {$invented: 1}}}, {filter: {amount: 'not numeric'}}, + {filter: {id: 1.5}}, {filter: {'constructor.name': 'x'}}, + {filter: {name: {$in: 'not-array'}}}, {orderBy: [{field: 'name', direction: 'sideways'}]}, + ]) expect(() => normalizeDynamicSearch(input, 'Order', models)).toThrow(); + expect(() => normalizeDynamicSearch({filter: {name: 'a', amount: 1}}, 'Order', models, jest.fn(), 1)).toThrow(); +}); + +test('fatal sibling produces neither input mutations nor partial warning emissions', () => { + const warn = jest.fn(); + const source = {filter: {removed: 'secret', amount: 'bad'}}; + const before = JSON.stringify(source); + expect(() => normalizeDynamicSearch(source, 'Order', models, warn)).toThrow(); + expect(warn).not.toHaveBeenCalled(); + expect(JSON.stringify(source)).toBe(before); +}); + +test('date, millisecond timestamp and decimal validation retain exact values', () => { + const typed: Record = {Ledger: {fields: { + date: 'date', created: 'timestamp', amount: 'decimal', + }, relations: {}}}; + const result = normalizeDynamicSearch({filter: {date: '2024-02-29', created: 1709164800000, + amount: '9007199254740993.01'}}, 'Ledger', typed); + expect(result.search.filter!.amount).toEqual({$eq: '9007199254740993.01'}); + for (const filter of [{date: '2025-02-29'}, {date: '0000-01-01'}, {created: '2024-02-29'}, {created: 1.5}, + {amount: 'NaN'}, {amount: Infinity}]) { + expect(() => normalizeDynamicSearch({filter}, 'Ledger', typed)).toThrow(); + } +}); diff --git a/source/teaql-ts/tests/entity-root-ownership.test.ts b/source/teaql-ts/tests/entity-root-ownership.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..f87ce31036312f53d498d31a577b95fc4076beb1 --- /dev/null +++ b/source/teaql-ts/tests/entity-root-ownership.test.ts @@ -0,0 +1,60 @@ +import { EntityRoot } from '../src/core/entity-root'; + +test('imports only one typed entity and retains all foreign pending state', () => { + const source = new EntityRoot(), receiver = new EntityRoot(); + const reached = { entity: 'OrderItem', id: '1' }, unrelated = { entity: 'Payment', id: '1' }; + source.setOriginalVersion(reached, 3); source.setOriginalVersion(unrelated, 7); + source.set(reached, 'name', 'reached'); source.set(unrelated, 'reference_code', 'unrelated'); + source.markAsNew(unrelated); + source.setTraceChain(reached, [{ kind: 'auditReason', name: 'OrderItem', entityId: '1', detail: 'local reason' }]); + const before = source.snapshot(); + receiver.mergeEntityFrom(source, reached); + expect(receiver.change(reached)).toEqual({ name: 'reached' }); + expect(receiver.originalVersion(reached)).toBe(3); + expect(receiver.traceChain(reached)).toEqual(source.traceChain(reached)); + expect(receiver.change(unrelated)).toEqual({}); expect(receiver.isNew(unrelated)).toBe(false); + expect(receiver.originalVersion(unrelated)).toBeUndefined(); + receiver.clearEntity(reached); + expect(source.snapshot()).toEqual(before); expect(source.hasPending(reached)).toBe(true); +}); + +test('retains clean hydration and typed lifecycle without creating a change', () => { + const source = new EntityRoot(), receiver = new EntityRoot(); + const key = { entity: 'Order', id: '1' }; + source.setOriginalVersion(key, 2); receiver.mergeEntityFrom(source, key); + expect(receiver.hasPending(key)).toBe(false); expect(receiver.snapshot()).toEqual([]); + expect(receiver.originalVersion(key)).toBe(2); + source.markAsDeleted(key); receiver.mergeEntityFrom(source, key); + expect(receiver.hasPending(key)).toBe(true); expect(receiver.isDeleted(key)).toBe(true); + expect(source.isDeleted(key)).toBe(true); +}); + +test.each(['single', 'whole', 'rekey'])('rejects conflicting loaded versions atomically: %s', mode => { + const target = new EntityRoot(), source = new EntityRoot(); + const key = { entity: 'Order', id: '1' }, otherType = { entity: 'Payment', id: '1' }; + target.setOriginalVersion(key, 2); target.set(key, 'name', 'receiver'); + source.setOriginalVersion(key, 3); source.set(key, 'name', 'foreign'); + source.set(otherType, 'reference_code', 'must not import first'); + const before = target.snapshot(); + if (mode === 'rekey') { + const temporary = { entity: 'Order', id: -1 }; + target.setOriginalVersion(temporary, 3); target.set(temporary, 'name', 'temporary'); + expect(() => target.rekey(temporary, key)).toThrow('ENTITY_VERSION_CONFLICT'); + expect(target.change(temporary)).toEqual({ name: 'temporary' }); + } else { + expect(() => mode === 'single' ? target.mergeEntityFrom(source, key) : target.mergeFrom(source)).toThrow('ENTITY_VERSION_CONFLICT'); + expect(target.snapshot()).toEqual(before); + } + expect(target.originalVersion(key)).toBe(2); expect(target.change(key)).toEqual({ name: 'receiver' }); + expect(target.change(otherType)).toEqual({}); expect(source.originalVersion(key)).toBe(3); +}); + +test('permits distinct entity types sharing an ID and explicit post-commit version advancement', () => { + const root = new EntityRoot(), order = { entity: 'Order', id: '1' }, payment = { entity: 'Payment', id: '1' }; + root.setOriginalVersion(order, 2); root.setOriginalVersion(payment, 7); + root.set(order, 'name', 'change'); + expect(() => root.setOriginalVersion(order, 3)).toThrow('ENTITY_VERSION_CONFLICT'); + expect(() => root.acceptCommittedVersion(order, 3)).toThrow('ENTITY_COMMIT_PENDING'); + root.clearEntity(order); root.acceptCommittedVersion(order, 3); + expect(root.originalVersion(order)).toBe(3); expect(root.originalVersion(payment)).toBe(7); +}); diff --git a/source/teaql-ts/tests/entity-root.test.ts b/source/teaql-ts/tests/entity-root.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..86a7f95abbc4a1d7c4e86e58579c3340a0d35471 --- /dev/null +++ b/source/teaql-ts/tests/entity-root.test.ts @@ -0,0 +1,31 @@ +import { EntityRoot } from '../src/core/entity-root'; + +test('entity root tracks final values, versions and lifecycle', () => { + const root = new EntityRoot(); + const order = { entity: 'Order', id: 10 } as const; + const line = { entity: 'OrderLine', id: 20 } as const; + root.setOriginalVersion(order, 3); + root.set(order, 'status', 'pending'); + root.set(order, 'status', 'confirmed'); + root.set(line, 'quantity', 2); + root.markAsNew(line); + const entries = new Map(root.snapshot().map(change => [change.key.entity, change])); + expect(entries.get('Order')?.values.status).toBe('confirmed'); + expect(root.originalVersion(order)).toBe(3); + expect(root.isNew(line)).toBe(true); + root.markAsDeleted(line); + expect(root.isDeleted(line)).toBe(true); + expect(root.snapshot()).toHaveLength(1); + root.clearCommitted(); + expect(root.snapshot()).toHaveLength(0); + expect(root.isNew(line)).toBe(false); + expect(root.isDeleted(line)).toBe(false); +}); + +test('entity root merges, rekeys and clears one entity', () => { + const child = new EntityRoot(); const temporary = { entity: 'Line', id: -1 }; const persisted = { entity: 'Line', id: 42 }; + child.markAsNew(temporary); child.set(temporary, 'quantity', 2); + const root = new EntityRoot(); root.mergeFrom(child); root.rekey(temporary, persisted); + expect(root.isNew(persisted)).toBe(true); expect(root.change(persisted).quantity).toBe(2); + root.clearEntity(persisted); expect(root.isNew(persisted)).toBe(false); expect(root.change(persisted)).toEqual({}); +}); diff --git a/source/teaql-ts/tests/expo-sqlite.test.ts b/source/teaql-ts/tests/expo-sqlite.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..cb8e14061e68324201e5ec9ca8bf0faf435ec277 --- /dev/null +++ b/source/teaql-ts/tests/expo-sqlite.test.ts @@ -0,0 +1,163 @@ +import { UserContext } from '../src/core/context'; +import Database from 'better-sqlite3'; +import { MutationQuery, OrderBy, SelectQuery } from '../src/core/ast'; +import { + ExpoSQLiteBindValue, + ExpoSQLiteDatabaseLike, + ExpoSQLiteExecuteResult, + ExpoSQLiteStatement, + ExpoSQLiteTeaQLClient, +} from '../src/sql/expo-sqlite'; +import { EntitySchema } from '../src/sql/core'; + +class TestExpoResult + implements ExpoSQLiteExecuteResult { + private index = 0; + + constructor( + private readonly rows: T[], + public readonly changes: number, + ) {} + + async getAllAsync(): Promise { + return [...this.rows]; + } + + [Symbol.asyncIterator](): AsyncIterableIterator { + return this; + } + + async next(): Promise> { + if (this.index >= this.rows.length) return { done: true, value: undefined }; + return { done: false, value: this.rows[this.index++] }; + } +} + +class TestExpoStatement implements ExpoSQLiteStatement { + constructor(private readonly statement: Database.Statement) {} + + async executeAsync>( + values: ExpoSQLiteBindValue[], + ): Promise> { + if (this.statement.reader) { + return new TestExpoResult(this.statement.all(...values) as T[], 0); + } + const result = this.statement.run(...values); + return new TestExpoResult([], result.changes); + } + + async finalizeAsync(): Promise { + // better-sqlite3 finalizes statements with their owning connection. + } +} + +class TestExpoDatabase implements ExpoSQLiteDatabaseLike { + private readonly database = new Database(':memory:'); + public closed = false; + + async execAsync(sql: string): Promise { + this.database.exec(sql); + } + + async prepareAsync(sql: string): Promise { + return new TestExpoStatement(this.database.prepare(sql)); + } + + async withExclusiveTransactionAsync( + work: (transaction: ExpoSQLiteDatabaseLike) => Promise, + ): Promise { + this.database.exec('BEGIN IMMEDIATE'); + try { + await work(this); + this.database.exec('COMMIT'); + } catch (error) { + this.database.exec('ROLLBACK'); + throw error; + } + } + + async closeAsync(): Promise { + this.database.close(); + this.closed = true; + } +} + +const schemas: Record = { + Order: { + table: 'orders', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + name: { columnName: 'name', logicalType: 'text', decode: 'native' }, + active: { columnName: 'active', logicalType: 'boolean', decode: 'native' }, + }, + }, +}; + +describe('Expo SQLite TeaQL driver', () => { + it('ensures schema, persists governed mutations, and queries real SQLite', async () => { + const database = new TestExpoDatabase(); + const client = new ExpoSQLiteTeaQLClient(database, schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + + await expect(client.executeMutation( + new MutationQuery('Order', 'Create', { name: 'unsafe' }), + )).rejects.toMatchObject({ code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'mutation' }); + + const created = await client.executeMutation( + new MutationQuery( + 'Order', 'Create', { name: 'first', active: true }, undefined, + 'create local order', + ), + ); + expect(created).toMatchObject({ + success: true, + metadata: { statements: [{ operation: 'insert', affectedRows: 1 }, { operation: 'select', resultCount: 1 }] }, + id: '1', + version: 1, + persistedRecord: { id: '1', version: 1, name: 'first', active: true }, + }); + + const rows = await client.executeQuery( + new SelectQuery('Order') + .comment('render local orders') + .purpose('browse order history') + .order(OrderBy.asc('id')), + ); + expect(rows).toEqual([{ id: '1', version: 1, name: 'first', active: true }]); + expect(client.auditTrace[0].reason).toBe('create local order'); + + await client.close(); + expect(database.closed).toBe(true); + }); + + it('uses optimistic versions, hard limits, and true async cursor streaming', async () => { + const database = new TestExpoDatabase(); + const client = new ExpoSQLiteTeaQLClient(database, schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (let index = 1; index <= 5; index++) { + await client.executeMutation(new MutationQuery( + 'Order', 'Create', { name: `order-${index}`, active: true }, + String(index), 'seed local order', + )); + } + + await expect(client.executeMutation({ + entity: 'Order', action: 'Update', id: '1', version: 99, + payload: { name: 'stale' }, comment: 'reject stale update', + })).rejects.toThrow(/Optimistic lock/); + + expect(() => new SelectQuery('Order').limit(10_001).prepareForList()) + .toThrow(/QUERY_HARD_LIMIT_EXCEEDED/); + + const chunks: any[][] = []; + const query = new SelectQuery('Order') + .comment('stream local orders') + .purpose('render a long local list') + .order(OrderBy.asc('id')); + for await (const chunk of client.executeForStream(query, 2)) chunks.push(chunk); + expect(chunks.map(chunk => chunk.length)).toEqual([2, 2, 1]); + expect(chunks.flat().map(row => row.id)).toEqual(['1', '2', '3', '4', '5']); + await client.close(); + }); +}); diff --git a/source/teaql-ts/tests/facet.test.ts b/source/teaql-ts/tests/facet.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..2e81a9fd11f580bae7cfb51b15047dcf21797153 --- /dev/null +++ b/source/teaql-ts/tests/facet.test.ts @@ -0,0 +1,69 @@ +import { executeRelationFacets, SelectQuery } from '../src'; + +describe('relation facets', () => { + const rowsByEntity: Record[]> = { + School: [ + { id: 1, name: 'Riverside', schoolType: 1001, annualBudget: 120 }, + { id: 2, name: 'Riverside Annex', schoolType: 1001, annualBudget: 80 }, + { id: 3, name: 'Other', schoolType: 1002, annualBudget: 50 }, + ], + SchoolType: [ + { id: 1001, code: 'PRIMARY' }, + { id: 1002, code: 'SECONDARY' }, + { id: 1003, code: 'VOCATIONAL' }, + ], + }; + + function service() { + return { + async executeQuery(query: SelectQuery): Promise[]> { + let rows = [...rowsByEntity[query.entity]]; + const filters = query.filterCondition?.$and ?? []; + for (const filter of filters) { + if (filter.name?.$contains) { + rows = rows.filter(row => String(row.name).includes(filter.name.$contains)); + } + } + return rows; + }, + }; + } + + it('merges the outer filter into counts and preserves all facet values by default', async () => { + const outer = new SelectQuery('School').filter({ $and: [{ name: { $contains: 'Riverside' } }] }) + .comment('load school facets').purpose('verify filtered facet membership'); + const nested = new SelectQuery('SchoolType').aggregate('Count', 'id', 'schoolCount'); + const request = { toQuery: () => nested }; + outer.facetBy('types', 'schoolType', request); + + const facets = await executeRelationFacets(service(), query => query, outer, outer.facets); + expect(facets.types.map(row => [row.code, row.schoolCount])).toEqual([ + ['PRIMARY', 2], ['SECONDARY', 0], ['VOCATIONAL', 0], + ]); + }); + + it('can restrict facet values to the filtered outer result', async () => { + const outer = new SelectQuery('School').filter({ $and: [{ name: { $contains: 'Riverside' } }] }) + .comment('load school facets').purpose('verify filtered facet membership'); + const nested = new SelectQuery('SchoolType').aggregate('Count', 'id', 'schoolCount'); + outer.facetBy('types', 'schoolType', { toQuery: () => nested }, false); + + const facets = await executeRelationFacets(service(), query => query, outer, outer.facets); + expect(facets.types.map(row => [row.code, row.schoolCount])).toEqual([['PRIMARY', 2]]); + }); + + it('returns multiple aggregate measures for each facet value', async () => { + const outer = new SelectQuery('School') + .comment('aggregate school facets') + .purpose('verify multiple facet measures'); + const nested = new SelectQuery('SchoolType') + .aggregate('Count', 'id', 'schoolCount') + .aggregate('Sum', 'annualBudget', 'totalBudget'); + outer.facetBy('types', 'schoolType', { toQuery: () => nested }); + + const facets = await executeRelationFacets(service(), query => query, outer, outer.facets); + expect(facets.types.map(row => [row.code, row.schoolCount, row.totalBudget])).toEqual([ + ['PRIMARY', 2, 200], ['SECONDARY', 1, 50], ['VOCATIONAL', 0, 0], + ]); + }); +}); diff --git a/source/teaql-ts/tests/fixtures/graph-mutation-lineage-v1.json b/source/teaql-ts/tests/fixtures/graph-mutation-lineage-v1.json new file mode 100644 index 0000000000000000000000000000000000000000..3ee6702455baf6c7f1d861703e0f462293714538 --- /dev/null +++ b/source/teaql-ts/tests/fixtures/graph-mutation-lineage-v1.json @@ -0,0 +1,37 @@ +{ + "contract": "teaql.graph-mutation-lineage.v1", + "owningIssue": "https://github.com/teaql/teaql-conformance/issues/99", + "evidenceLevel": "normative-fixture-not-runtime-proof", + "notes": [ + "nodeId is a fixture-local handle only. Runtime identity remains (entityType, assignedEntityId).", + "The root comment is the Mutation Request comment and must appear once, not once for the request plus once for the root entity.", + "For unit token recovery, parentage and final assigned IDs are supplied by the fixture. Only real planner/provider/audit integration proves capture, allocation, deletion and commit ordering.", + "Compare keyed per-entity observations and ordered nodes within each lineage. Do not impose this fixture's sibling order on a runtime's SQL batch scheduler.", + "localComment=null or blank describes defensive graph state, not a permitted blank public audited-save request." + ], + "cases": [ + {"id":"normative-order","coverage":["TC-MUT-01","TC-MUT-02","TC-MUT-03","TC-MUT-04","TC-MUT-05","TC-MUT-06","TC-MUT-09"],"requestComment":"submit order","nodes":[{"nodeId":"order","entityType":"Order","entityId":100,"parent":null,"localComment":"submit order","operation":"save"},{"nodeId":"item","entityType":"OrderItem","entityId":201,"parent":"order","localComment":null,"operation":"save"},{"nodeId":"payment","entityType":"Payment","entityId":301,"parent":"order","localComment":"authorize payment","operation":"save"},{"nodeId":"attempt","entityType":"PaymentAttempt","entityId":401,"parent":"payment","localComment":null,"operation":"save"},{"nodeId":"shipment","entityType":"Shipment","entityId":501,"parent":"order","localComment":"dispatch shipment","operation":"save"},{"nodeId":"deleted-item","entityType":"OrderItem","entityId":202,"parent":"order","localComment":"remove unavailable item","operation":"delete"}],"expected":[{"nodeId":"order","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"}]},{"nodeId":"item","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"}]},{"nodeId":"payment","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"AuditReason","name":"Payment","entityId":301,"detail":"authorize payment"}]},{"nodeId":"attempt","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"AuditReason","name":"Payment","entityId":301,"detail":"authorize payment"}]},{"nodeId":"shipment","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"AuditReason","name":"Shipment","entityId":501,"detail":"dispatch shipment"}]},{"nodeId":"deleted-item","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"AuditReason","name":"OrderItem","entityId":202,"detail":"remove unavailable item"}]}]}, + {"id":"same-id-different-types","coverage":["TC-MUT-08"],"requestComment":"submit order","nodes":[{"nodeId":"order","entityType":"Order","entityId":1,"parent":null,"localComment":"submit order","operation":"save"},{"nodeId":"payment","entityType":"Payment","entityId":1,"parent":"order","localComment":"authorize payment","operation":"save"}],"expected":[{"nodeId":"order","lineage":[{"kind":"AuditReason","name":"Order","entityId":1,"detail":"submit order"}]},{"nodeId":"payment","lineage":[{"kind":"AuditReason","name":"Order","entityId":1,"detail":"submit order"},{"kind":"AuditReason","name":"Payment","entityId":1,"detail":"authorize payment"}]}]}, + {"id":"complete-ledger-chain-replaces-fallback","coverage":["TC-MUT-10"],"requestComment":"submit order","nodes":[{"nodeId":"order","entityType":"Order","entityId":100,"parent":null,"localComment":"submit order","operation":"save"},{"nodeId":"payment","entityType":"Payment","entityId":301,"parent":"order","localComment":"authorize payment","operation":"save","ledgerLineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"AuditReason","name":"Payment","entityId":301,"detail":"special approval"}]},{"nodeId":"item","entityType":"OrderItem","entityId":201,"parent":"order","localComment":null,"operation":"save","ledgerLineage":[]}],"expected":[{"nodeId":"order","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"}]},{"nodeId":"payment","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"AuditReason","name":"Payment","entityId":301,"detail":"special approval"}]},{"nodeId":"item","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"}]}]}, + {"id":"blank-local-defensive-inheritance","coverage":["TC-MUT-11"],"requestComment":"submit order","nodes":[{"nodeId":"order","entityType":"Order","entityId":100,"parent":null,"localComment":"submit order","operation":"save"},{"nodeId":"item","entityType":"OrderItem","entityId":201,"parent":"order","localComment":" \t ","operation":"save"}],"expected":[{"nodeId":"order","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"}]},{"nodeId":"item","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"}]}]}, + {"id":"late-assigned-id","coverage":["TC-MUT-07"],"requestComment":"submit order","nodes":[{"nodeId":"order","entityType":"Order","entityId":100,"parent":null,"localComment":"submit order","operation":"save"},{"nodeId":"payment","entityType":"Payment","entityId":null,"parent":"order","localComment":"authorize payment","operation":"save","assignedEntityId":601}],"expected":[{"nodeId":"order","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"}]},{"nodeId":"payment","lineage":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"AuditReason","name":"Payment","entityId":601,"detail":"authorize payment"}]}]} + ], + "requiredIntegrationCases": [ + { + "id": "TC-MUT-12", + "requirement": "Execute two independent graphs concurrently in one real Context; observe isolated emitted lineages." + }, + { + "id": "TC-MUT-13", + "requirement": "Fail the provider after planning; retain failed SQL lineage and emit no committed audit event." + }, + { + "id": "TC-MUT-14", + "requirement": "Commit the write and fail readback; retain successful write and independently traced readback failure." + }, + { + "id": "TC-MUT-15", + "requirement": "Drive normative-order with unchanged generated Mutation/Q/E APIs; assert emitted commands, SQL metadata and safe committed audit sinks; run twice without cleanup." + } + ] +} diff --git a/source/teaql-ts/tests/fixtures/request-intent-v1.json b/source/teaql-ts/tests/fixtures/request-intent-v1.json new file mode 100644 index 0000000000000000000000000000000000000000..b348abaa97911e59fa83a0b58214c2d94d1d7d37 --- /dev/null +++ b/source/teaql-ts/tests/fixtures/request-intent-v1.json @@ -0,0 +1,259 @@ +{ + "contract": "teaql.request-intent.v1", + "cases": [ + { + "id": "Q01-missing", + "kind": "query", + "input": { + "purpose": "render orders" + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "Q02-null", + "kind": "query", + "input": { + "comment": null, + "purpose": "render orders" + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "Q03-empty", + "kind": "query", + "input": { + "comment": "", + "purpose": "render orders" + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "Q04-ascii-blank", + "kind": "query", + "input": { + "comment": " \t\r\n", + "purpose": "render orders" + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "Q05-unicode-blank", + "kind": "query", + "input": { + "comment": " ", + "purpose": "render orders" + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "Q06-purpose-missing", + "kind": "query", + "input": { + "comment": "load orders" + }, + "error": { + "code": "QUERY_PURPOSE_REQUIRED", + "field": "purpose" + } + }, + { + "id": "Q07-purpose-blank", + "kind": "query", + "input": { + "comment": "load orders", + "purpose": " " + }, + "error": { + "code": "QUERY_PURPOSE_REQUIRED", + "field": "purpose" + } + }, + { + "id": "Q08-preserve", + "kind": "query", + "input": { + "comment": " load orders ", + "purpose": "render orders" + }, + "expected": { + "comment": " load orders ", + "purpose": "render orders" + } + }, + { + "id": "Q09-trace-only", + "kind": "query", + "input": { + "trace": [ + { + "kind": "Comment", + "detail": "load orders" + }, + { + "kind": "Purpose", + "detail": "render orders" + } + ] + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "Q10-logs-disabled", + "kind": "query", + "input": { + "purpose": "render orders", + "logging": false + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "M01-missing", + "kind": "mutation", + "input": {}, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "M02-null", + "kind": "mutation", + "input": { + "comment": null + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "M03-empty", + "kind": "mutation", + "input": { + "comment": "" + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "M04-ascii-blank", + "kind": "mutation", + "input": { + "comment": " \t\r\n" + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "M05-unicode-blank", + "kind": "mutation", + "input": { + "comment": " " + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "M06-preserve", + "kind": "mutation", + "input": { + "comment": " submit order " + }, + "expected": { + "comment": " submit order " + } + }, + { + "id": "M07-trace-only", + "kind": "mutation", + "input": { + "trace": [ + { + "kind": "AuditReason", + "detail": "submit order" + } + ] + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "M08-batch-child-only", + "kind": "mutation", + "input": { + "children": [ + { + "comment": "create item" + }, + { + "comment": "delete item" + } + ] + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + }, + { + "id": "M09-blank-route-tail", + "kind": "mutation", + "input": { + "comment": "submit order", + "trace": [ + { + "kind": "AuditReason", + "detail": "authorize payment" + }, + { + "kind": "Entity", + "detail": "" + } + ] + }, + "expected": { + "comment": "submit order" + } + }, + { + "id": "M10-logs-disabled", + "kind": "mutation", + "input": { + "logging": false + }, + "error": { + "code": "REQUEST_COMMENT_REQUIRED", + "field": "comment" + } + } + ] +} diff --git a/source/teaql-ts/tests/fixtures/sql-trace-path-v1.json b/source/teaql-ts/tests/fixtures/sql-trace-path-v1.json new file mode 100644 index 0000000000000000000000000000000000000000..90354189e3e70416bd1869426f1926ffdffbfdb1 --- /dev/null +++ b/source/teaql-ts/tests/fixtures/sql-trace-path-v1.json @@ -0,0 +1,35 @@ +{ + "contract": "teaql.sql-trace-path.v1", + "owningIssue": "https://github.com/teaql/teaql-conformance/issues/99", + "evidenceLevel": "pure-algorithm", + "notes": [ + "Input source frames here are authored unit-test inputs, not proof of generated Q or Mutation execution.", + "Every case must be idempotent. Intent values are compared separately; source text is preserved verbatim.", + "A rebuilt noncanonical mutation path currently has no Entity ID; an already canonical path preserves its existing IDs.", + "Empty-source is a helper boundary, not permission to execute a request without required intent." + ], + "cases": [ + {"id":"TC-SQL-01","operation":"select","backend":"sqlite","source":[{"kind":"Comment","name":"School","entityId":null,"detail":"what: load school graph"},{"kind":"Purpose","name":"School","entityId":null,"detail":"why: render details"},{"kind":"Relation","name":"platform","entityId":null,"detail":"School.platform"},{"kind":"Relation","name":"organization","entityId":null,"detail":"Platform.organization"}],"expectedIntent":{"comment":"what: load school graph","purpose":"why: render details","auditReason":null},"expectedPath":[{"kind":"Operation","name":"School","entityId":null,"detail":"query"},{"kind":"Request","name":"School","entityId":null,"detail":""},{"kind":"Relation","name":"platform","entityId":null,"detail":"School.platform"},{"kind":"Relation","name":"organization","entityId":null,"detail":"Platform.organization"},{"kind":"Provider","name":"sqlite","entityId":null,"detail":""},{"kind":"Sql","name":"select","entityId":null,"detail":""}]}, + {"id":"TC-SQL-02","operation":"update","backend":"ignored-new-backend","source":[{"kind":"Operation","name":"Order","entityId":null,"detail":"mutation"},{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"Entity","name":"OrderItem","entityId":201,"detail":""},{"kind":"Relation","name":"items","entityId":null,"detail":"Order.items"},{"kind":"Comment","name":"Order","entityId":null,"detail":"update graph"},{"kind":"Provider","name":"postgres","entityId":null,"detail":""},{"kind":"Sql","name":"update","entityId":null,"detail":""}],"expectedIntent":{"comment":"update graph","purpose":null,"auditReason":"submit order"},"expectedPath":[{"kind":"Operation","name":"Order","entityId":null,"detail":"mutation"},{"kind":"Entity","name":"OrderItem","entityId":201,"detail":""},{"kind":"Relation","name":"items","entityId":null,"detail":"Order.items"},{"kind":"Provider","name":"postgres","entityId":null,"detail":""},{"kind":"Sql","name":"update","entityId":null,"detail":""}]}, + {"id":"TC-SQL-03","operation":"update","backend":"postgres","source":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"Entity","name":"Order","entityId":100,"detail":""},{"kind":"Entity","name":"OrderItem","entityId":201,"detail":""}],"expectedIntent":{"comment":null,"purpose":null,"auditReason":"submit order"},"expectedPath":[{"kind":"Operation","name":"Order","entityId":null,"detail":"mutation"},{"kind":"Entity","name":"OrderItem","entityId":null,"detail":""},{"kind":"Provider","name":"postgres","entityId":null,"detail":""},{"kind":"Sql","name":"update","entityId":null,"detail":""}]}, + {"id":"TC-SQL-04-insert","operation":"insert","backend":"postgres","source":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"insert order"},{"kind":"Entity","name":"Order","entityId":100,"detail":""}],"expectedIntent":{"comment":null,"purpose":null,"auditReason":"insert order"},"expectedPath":[{"kind":"Operation","name":"Order","entityId":null,"detail":"mutation"},{"kind":"Entity","name":"Order","entityId":null,"detail":""},{"kind":"Provider","name":"postgres","entityId":null,"detail":""},{"kind":"Sql","name":"insert","entityId":null,"detail":""}]}, + {"id":"TC-SQL-04-update","operation":"update","backend":"postgres","source":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"update order"},{"kind":"Entity","name":"Order","entityId":100,"detail":""}],"expectedIntent":{"comment":null,"purpose":null,"auditReason":"update order"},"expectedPath":[{"kind":"Operation","name":"Order","entityId":null,"detail":"mutation"},{"kind":"Entity","name":"Order","entityId":null,"detail":""},{"kind":"Provider","name":"postgres","entityId":null,"detail":""},{"kind":"Sql","name":"update","entityId":null,"detail":""}]}, + {"id":"TC-SQL-04-delete","operation":"delete","backend":"postgres","source":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"delete order"},{"kind":"Entity","name":"Order","entityId":100,"detail":""}],"expectedIntent":{"comment":null,"purpose":null,"auditReason":"delete order"},"expectedPath":[{"kind":"Operation","name":"Order","entityId":null,"detail":"mutation"},{"kind":"Entity","name":"Order","entityId":null,"detail":""},{"kind":"Provider","name":"postgres","entityId":null,"detail":""},{"kind":"Sql","name":"delete","entityId":null,"detail":""}]}, + {"id":"TC-SQL-04-recover","operation":"recover","backend":"postgres","source":[{"kind":"AuditReason","name":"Order","entityId":100,"detail":"recover order"},{"kind":"Entity","name":"Order","entityId":100,"detail":""}],"expectedIntent":{"comment":null,"purpose":null,"auditReason":"recover order"},"expectedPath":[{"kind":"Operation","name":"Order","entityId":null,"detail":"mutation"},{"kind":"Entity","name":"Order","entityId":null,"detail":""},{"kind":"Provider","name":"postgres","entityId":null,"detail":""},{"kind":"Sql","name":"recover","entityId":null,"detail":""}]}, + {"id":"TC-SQL-05","operation":"select","backend":" \t ","source":[{"kind":"Comment","name":"School","entityId":null,"detail":"load school"},{"kind":"Purpose","name":"School","entityId":null,"detail":"render school"}],"expectedIntent":{"comment":"load school","purpose":"render school","auditReason":null},"expectedPath":[{"kind":"Operation","name":"School","entityId":null,"detail":"query"},{"kind":"Request","name":"School","entityId":null,"detail":""},{"kind":"Provider","name":"unknown","entityId":null,"detail":""},{"kind":"Sql","name":"select","entityId":null,"detail":""}]}, + {"id":"TC-SQL-06","operation":"select","backend":"sqlite","source":[{"kind":"Comment","name":"School","entityId":null,"detail":"old comment"},{"kind":"Purpose","name":"School","entityId":null,"detail":"old purpose"},{"kind":"AuditReason","name":"School","entityId":1,"detail":"old reason"},{"kind":"Comment","name":"School","entityId":null,"detail":" new comment "},{"kind":"Purpose","name":"School","entityId":null,"detail":"new purpose"},{"kind":"AuditReason","name":"School","entityId":1,"detail":"new reason"},{"kind":"Entity","name":"School","entityId":1,"detail":""}],"expectedIntent":{"comment":" new comment ","purpose":"new purpose","auditReason":"new reason"},"expectedPath":[{"kind":"Operation","name":"School","entityId":null,"detail":"query"},{"kind":"Request","name":"School","entityId":null,"detail":""},{"kind":"Provider","name":"sqlite","entityId":null,"detail":""},{"kind":"Sql","name":"select","entityId":null,"detail":""}]}, + {"id":"BOUNDARY-empty-source","operation":"select","backend":"","source":[],"expectedIntent":{"comment":null,"purpose":null,"auditReason":null},"expectedPath":[{"kind":"Operation","name":"unknown","entityId":null,"detail":"query"},{"kind":"Request","name":"unknown","entityId":null,"detail":""},{"kind":"Provider","name":"unknown","entityId":null,"detail":""},{"kind":"Sql","name":"select","entityId":null,"detail":""}]}, + {"id":"BOUNDARY-blank-first-name","operation":"update","backend":"postgres","source":[{"kind":"Entity","name":"  ","entityId":null,"detail":"not intent"},{"kind":"AuditReason","name":"Order","entityId":100,"detail":"submit order"},{"kind":"Entity","name":"OrderItem","entityId":201,"detail":""}],"expectedIntent":{"comment":null,"purpose":null,"auditReason":"submit order"},"expectedPath":[{"kind":"Operation","name":"Order","entityId":null,"detail":"mutation"},{"kind":"Entity","name":"OrderItem","entityId":null,"detail":""},{"kind":"Provider","name":"postgres","entityId":null,"detail":""},{"kind":"Sql","name":"update","entityId":null,"detail":""}]}, + {"id":"BOUNDARY-three-level-shape","operation":"select","backend":"sqlite","source":[{"kind":"Comment","name":"School","entityId":null,"detail":"load school graph"},{"kind":"Purpose","name":"School","entityId":null,"detail":"render school"},{"kind":"Relation","name":"platform","entityId":null,"detail":"School.platform"},{"kind":"Relation","name":"organization","entityId":null,"detail":"Platform.organization"},{"kind":"Relation","name":"region","entityId":null,"detail":"Organization.region"}],"expectedIntent":{"comment":"load school graph","purpose":"render school","auditReason":null},"expectedPath":[{"kind":"Operation","name":"School","entityId":null,"detail":"query"},{"kind":"Request","name":"School","entityId":null,"detail":""},{"kind":"Relation","name":"platform","entityId":null,"detail":"School.platform"},{"kind":"Relation","name":"organization","entityId":null,"detail":"Platform.organization"},{"kind":"Relation","name":"region","entityId":null,"detail":"Organization.region"},{"kind":"Provider","name":"sqlite","entityId":null,"detail":""},{"kind":"Sql","name":"select","entityId":null,"detail":""}]} + ], + "requiredIntegrationCases": [ + { + "id": "TC-SQL-07", + "requirement": "Generated Q constructs three relation levels; observe real provider metadata without test-injected frames." + }, + { + "id": "TC-SQL-08", + "requirement": "Existing privacy projection masks secret intent before every sink without changing the path structure." + } + ] +} diff --git a/source/teaql-ts/tests/generated-scalar-search.test.ts b/source/teaql-ts/tests/generated-scalar-search.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc909baa082f84adbc63ca165eef436e13bc12a2 --- /dev/null +++ b/source/teaql-ts/tests/generated-scalar-search.test.ts @@ -0,0 +1,67 @@ +import { SelectQuery, OrderBy } from '../src/core/ast'; +import { mergeGeneratedScalarSearch, GeneratedSearchModel } from '../src/core/dynamic-search'; +import { RuntimeModule } from '../src/core/runtime-module'; +import { UserContext } from '../src/core/context'; +import { SQLiteTeaQLClient } from '../src/sql/sqlite'; + +const models: Record = { + Invoice: { + fields: {referenceCode: 'string', reference_code: 'string', totalAmount: 'decimal', active: 'boolean', owner: 'integer', payload: 'unsupported'}, + relations: {owner: 'Owner'}, + queryFields: {referenceCode: 'referenceCode', reference_code: 'referenceCode', totalAmount: 'totalAmount', active: 'active', owner: 'owner'}, + }, + Owner: {fields: {name: 'string'}, relations: {}, queryFields: {name: 'name'}}, +}; + +test('generated scalar search applies every valid sibling and preserves scope, order and ownership', async () => { + const columns = { + id: {columnName: 'id', logicalType: 'integer' as const, decode: 'number' as const}, + version: {columnName: 'version', logicalType: 'integer' as const, decode: 'number' as const}, + tenant: {columnName: 'tenant', logicalType: 'integer' as const, decode: 'number' as const}, + referenceCode: {columnName: 'reference_code', logicalType: 'text' as const, decode: 'native' as const}, + totalAmount: {columnName: 'total_amount', logicalType: 'decimal' as const, decode: 'number' as const}, + active: {columnName: 'active', logicalType: 'boolean' as const, decode: 'native' as const}, + }; + const client = new SQLiteTeaQLClient(':memory:', {}).install(new RuntimeModule({Invoice: {table: 'invoice_data', columns}})) as SQLiteTeaQLClient; + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const [tenant, referenceCode, totalAmount, active] of [[1, 'KEEP-1', 100, true], [1, 'KEEP-2', 20, true], [2, 'KEEP-3', 100, true]]) { + await client.executeMutation({entity: 'Invoice', action: 'Create', payload: {tenant, referenceCode, totalAmount, active}, comment: 'seed scalar search'}); + } + const base = new SelectQuery('Invoice').filter({tenant: {$eq: 1}}).select(['id', 'referenceCode']).limit(4) + .order(OrderBy.asc('id')).comment('load scoped invoices').purpose('verify generated scalar search'); + const before = JSON.stringify(base), warnings = jest.fn(); + const input = {filter: {reference_code: {$contains: 'KEEP'}, totalAmount: {$gte: '50.00'}, active: true, removed: 'PRIVATE'}, + orderBy: [{field: 'reference_code', direction: 'desc'}]}; + const {query} = mergeGeneratedScalarSearch(base, input, models, warnings); + input.filter.reference_code.$contains = 'changed'; + expect(JSON.stringify(base)).toBe(before); + expect(query.limitValue).toBe(4); + expect(query.commentText).toBe(base.commentText); + expect(query.purposeText).toBe(base.purposeText); + expect(query.orderItems.map(order => order.field)).toEqual(['id', 'referenceCode']); + const rows = await client.executeQuery(query); + expect(rows.map(row => row.referenceCode)).toEqual(['KEEP-1']); + expect(warnings).toHaveBeenCalledTimes(1); + expect(JSON.stringify(warnings.mock.calls)).not.toContain('PRIVATE'); + } finally { await client.close(); } +}); + +test('known relation paths require trusted bindings and fail atomically instead of being dropped', () => { + const base = new SelectQuery('Invoice').filter({tenant: 1}).limit(4); + const before = JSON.stringify(base), warnings = jest.fn(); + expect(() => mergeGeneratedScalarSearch(base, {filter: {removed: 'secret', 'owner.name': 'Ada'}}, models, warnings)) + .toThrow('trusted relation binding'); + expect(JSON.stringify(base)).toBe(before); + expect(warnings).not.toHaveBeenCalled(); +}); + +test.each([{filter: {active: 'true'}}, {filter: {totalAmount: {$contains: '1'}}}, + {filter: {referenceCode: {$rawSQL: 'true'}}}, {filter: {}, context: {actor: 'admin'}}, + {filter: {payload: null}}, {orderBy: [{field: 'payload', direction: 'asc'}]}, + {filter: {referenceCode: {$contains: null}}}, {filter: {totalAmount: {$gt: null}}}])( + 'invalid known values and trusted controls remain fatal: %j', input => { + const base = new SelectQuery('Invoice').filter({tenant: 1}); + expect(() => mergeGeneratedScalarSearch(base, input, models)).toThrow(); + expect(base.filterCondition).toEqual({tenant: 1}); + }); diff --git a/source/teaql-ts/tests/i18n.test.ts b/source/teaql-ts/tests/i18n.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..f7baabcff55c0dcb6bcde63e94bd6196446635df --- /dev/null +++ b/source/teaql-ts/tests/i18n.test.ts @@ -0,0 +1,3 @@ +import { CheckResult,I18nCatalog,locales,ObjectLocation,UnsupportedLocaleError,UserContext } from '../src'; +test('15 locales x 5 checker rules',()=>{const rules:CheckResult[]=[{ruleId:'required',location:ObjectLocation.property('name')},{ruleId:'min',location:ObjectLocation.property('age'),inputValue:1,systemValue:2},{ruleId:'max',location:ObjectLocation.property('age'),inputValue:3,systemValue:2},{ruleId:'min_length',location:ObjectLocation.property('name'),inputValue:'a',systemValue:2},{ruleId:'max_length',location:ObjectLocation.property('name'),inputValue:'abc',systemValue:2}];let cells=0;for(const locale of locales)for(const source of rules){const result=I18nCatalog.builtin.translate({...source},locale);expect(result.message).toBeTruthy();expect(result.message).not.toMatch(/^checker\./);cells++;}expect(cells).toBe(75);}); +test('alias and invalid locale preserve context',()=>{const context=new UserContext().setLocaleCode('ZH_hans');expect(context.locale).toBe('zh-CN');expect(()=>context.setLocaleCode('xx')).toThrow(UnsupportedLocaleError);expect(context.locale).toBe('zh-CN');}); diff --git a/source/teaql-ts/tests/loaded-scalar-snapshot.test.ts b/source/teaql-ts/tests/loaded-scalar-snapshot.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..27b8a1bb98a9ea6d3833771eb0e2db81d321ed54 --- /dev/null +++ b/source/teaql-ts/tests/loaded-scalar-snapshot.test.ts @@ -0,0 +1,55 @@ +import { LoadedScalarSnapshot } from '../src/core/loaded-scalar-snapshot'; +import { MutationRequest } from '../src/core/request-intent'; + +it('retains independent loaded provenance outside entity serialization after property edits', () => { + const first = { name: 'FIRST-PRIVATE', details: { count: 1 } }; + const second = { name: 'SECOND-PRIVATE', details: { count: 2 } }; + LoadedScalarSnapshot.captureFor(first, first); + LoadedScalarSnapshot.captureFor(second, second); + first.name = 'edited'; first.details.count = 9; + expect(LoadedScalarSnapshot.forEntity(first)?.values()).toEqual({ name: 'FIRST-PRIVATE', details: { count: 1 } }); + expect(LoadedScalarSnapshot.forEntity(second)?.values()).toEqual(second); + expect(LoadedScalarSnapshot.forEntity({})).toBeUndefined(); + expect(Object.keys(first)).toEqual(['name', 'details']); + expect(JSON.stringify(first)).not.toContain('FIRST-PRIVATE'); +}); + +it('restores the original immutable snapshot on rollback and releases absent provenance', () => { + const entity = {}; + const loaded = LoadedScalarSnapshot.captureFor(entity, { secret: 'original' }); + LoadedScalarSnapshot.captureFor(entity, { secret: 'committed candidate' }); + expect(LoadedScalarSnapshot.forEntity(entity)?.values().secret).toBe('committed candidate'); + LoadedScalarSnapshot.restoreFor(entity, loaded); + expect(LoadedScalarSnapshot.forEntity(entity)?.values().secret).toBe('original'); + LoadedScalarSnapshot.restoreFor(entity, undefined); + expect(LoadedScalarSnapshot.forEntity(entity)).toBeUndefined(); +}); + +it('owns scalar JSON/date values without changing request payload or serializing provenance', () => { + const original = { name: 'PRIVATE-OLD-VALUE', details: { values: ['original'] }, when: new Date('2026-01-01') }; + const snapshot = new LoadedScalarSnapshot(original); + original.name = 'changed'; original.details.values[0] = 'changed'; original.when.setUTCFullYear(2030); + const mutation = { entity: 'Payment', action: 'Update', payload: { name: 'next' }, comment: 'update fixture' }; + const request = new MutationRequest(mutation).withLoadedSnapshot(snapshot); + const values = request.loadedValues() as typeof original; + expect(values.name).toBe('PRIVATE-OLD-VALUE'); + expect(values.details.values).toEqual(['original']); + expect(values.when.getUTCFullYear()).toBe(2026); + values.details.values[0] = 'second change'; values.when.setUTCFullYear(2040); + expect((request.loadedValues() as typeof original).details.values).toEqual(['original']); + expect((request.loadedValues() as typeof original).when.getUTCFullYear()).toBe(2026); + expect(request.mutation.payload).toEqual({ name: 'next' }); + expect(JSON.stringify([snapshot, request])).not.toContain('PRIVATE-OLD-VALUE'); + expect(new MutationRequest({ ...mutation, loadedValues: { name: 'forged' } }).loadedValues()).toEqual({}); +}); + +it('does not redact public old scalars from audit prose, but keeps masked and unknown values private', () => { + const request = new MutationRequest({ entity: 'Payment', id: '99', action: 'Update', + payload: {}, comment: 'page 1 PUBLIC OLDPRIVATE UNKNOWN' }) + .withLoadedSnapshot(new LoadedScalarSnapshot({ version: 1, name: 'PUBLIC', secret: 'OLDPRIVATE' })); + const audit = request.auditProjection({ entity: 'Payment', id: '99' }, {}, { + parameterizedSQL: '', sqlOrigin: 'generated', parameters: [1, 'PUBLIC', 'OLDPRIVATE', 'UNKNOWN'], + parameterLogPolicies: ['plain', 'plain', 'masked', 'unknown'], + }); + expect(audit.reason).toBe('page 1 PUBLIC [REDACTED] [REDACTED]'); +}); diff --git a/source/teaql-ts/tests/local-cache.test.ts b/source/teaql-ts/tests/local-cache.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..f290b6c275ab6d1b0898e1e592cd5e518812cfb5 --- /dev/null +++ b/source/teaql-ts/tests/local-cache.test.ts @@ -0,0 +1,18 @@ +import { LocalCache } from '../src/core/local-cache'; + +describe('LocalCache', () => { + beforeEach(() => jest.useFakeTimers()); + afterEach(() => jest.useRealTimers()); + + it('shares values, removes entries, and expires TTL entries', () => { + const cache = new LocalCache(); + cache.put('persistent', { id: 7 }); + expect(cache.get<{ id: number }>('persistent')).toEqual({ id: 7 }); + cache.remove('persistent'); + expect(cache.get('persistent')).toBeUndefined(); + + cache.put('temporary', 'value', 1); + jest.advanceTimersByTime(1_000); + expect(cache.get('temporary')).toBeUndefined(); + }); +}); diff --git a/source/teaql-ts/tests/log-privacy.test.ts b/source/teaql-ts/tests/log-privacy.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..4632c98ae3392d68c761a964d29419157a8e7476 --- /dev/null +++ b/source/teaql-ts/tests/log-privacy.test.ts @@ -0,0 +1,64 @@ +import { mkdtempSync, readFileSync, appendFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { PLAINTEXT_LOG_ENV, PLAINTEXT_LOG_ACK, projectSQLLog } from '../src/core/log-privacy'; +import { SQLExecutionMetadata, TextDiagnosticSQLLogSink } from '../src/sql/core'; + +const oldSetting = process.env[PLAINTEXT_LOG_ENV]; +beforeEach(() => { delete process.env[PLAINTEXT_LOG_ENV]; }); +afterAll(() => { + if (oldSetting === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = oldSetting; +}); + +function fixture(field = 'name'): SQLExecutionMetadata { + return { + operation: 'update', comment: 'edit PRIVATE-CUSTOMER-CANARY', purpose: 'test logging', + traceChain: [ + { kind: 'purpose', name: 'Customer', detail: 'test logging' }, + { kind: 'comment', name: 'Customer', detail: 'edit PRIVATE-CUSTOMER-CANARY' }, + ], + tracePath: [{ level: 0, kind: 'request', name: 'edit PRIVATE-CUSTOMER-CANARY' }], + parameterizedSQL: `UPDATE customer SET ${field} = ?`, parameters: ['PRIVATE-CUSTOMER-CANARY'], + debugSQL: `UPDATE customer SET ${field} = 'PRIVATE-CUSTOMER-CANARY'`, + elapsedMicros: 1, affectedRows: 1, resultSummary: '1 rows affected', + }; +} + +it.each([undefined, '', 'true', '1', `${PLAINTEXT_LOG_ACK} `, PLAINTEXT_LOG_ACK.toLowerCase()])( + 'redacts default/file logs for invalid opt-in %s without modifying input', setting => { + if (setting !== undefined) process.env[PLAINTEXT_LOG_ENV] = setting; + const file = join(mkdtempSync(join(tmpdir(), 'teaql-ts-log-')), 'runtime.log'); + const raw = fixture(); + new TextDiagnosticSQLLogSink(text => appendFileSync(file, text)).write(raw); + const log = readFileSync(file, 'utf8'); + expect(log).not.toContain('PRIVATE-CUSTOMER-CANARY'); + expect(log).toContain('NOT REPLAYABLE'); + expect(log).toContain('1 rows affected'); + expect(raw.parameters[0]).toBe('PRIVATE-CUSTOMER-CANARY'); + }, +); + +it('accepts only the exact opt-in and warns without values', () => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const warning = jest.spyOn(console, 'warn').mockImplementation(() => {}); + const output: string[] = []; + try { + new TextDiagnosticSQLLogSink(text => output.push(text)).write({ ...fixture(), parameterLogPolicies: ['masked'] }); + expect(output[0]).toContain('PRIVATE-CUSTOMER-CANARY'); + expect(warning).toHaveBeenCalledWith(expect.stringContaining('may be written to disk')); + expect(JSON.stringify(warning.mock.calls)).not.toContain('PRIVATE-CUSTOMER-CANARY'); + } finally { warning.mockRestore(); } +}); + +it.each(['password', 'accessToken', 'private_key', 'api_key', 'refresh_token'])( + 'never exposes %s on opt-in', field => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + expect(JSON.stringify(projectSQLLog(fixture(field)))).not.toContain('PRIVATE-CUSTOMER-CANARY'); + }, +); + +it('fails closed for unclassified literal SQL', () => { + expect(projectSQLLog({ ...fixture(), parameterizedSQL: "SELECT 'INLINE-CANARY'", parameters: [] }).parameterizedSQL) + .toBe('[REDACTED SQL; NOT REPLAYABLE]'); +}); diff --git a/source/teaql-ts/tests/masking-contract.test.ts b/source/teaql-ts/tests/masking-contract.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..9d9a7751a107291079dfa4253bbfeece3d2a6d4b --- /dev/null +++ b/source/teaql-ts/tests/masking-contract.test.ts @@ -0,0 +1,50 @@ +import { TextDiagnosticSQLLogSink, SQLExecutionMetadata } from '../src/sql/core'; +import { PLAINTEXT_LOG_ENV, PLAINTEXT_LOG_ACK, maskAuditValue } from '../src/core/log-privacy'; +import { readFileSync } from 'fs'; +import { join } from 'path'; + +const golden = readFileSync(join(__dirname, '../test-vectors/masking-v1.tsv'), 'utf8') + .trimEnd().split('\n').slice(1).map(line => line.split('\t')); +it.each(golden)('mask golden: %s', (_case, raw, expected) => { + expect(maskAuditValue(raw)).toBe(expected); +}); + +const cases = [['', ''], ['Ada', '***'], ['12345678', '********'], + ['ABCDEFGH', 'AB****GH'], ['Riverside', 'Ri*****de'], ["O'Reilly", "O'****ly"]]; +const previous = process.env[PLAINTEXT_LOG_ENV]; +beforeEach(() => { delete process.env[PLAINTEXT_LOG_ENV]; }); +afterEach(() => { + if (previous === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = previous; +}); +function entry(value: string): SQLExecutionMetadata { + return { operation: 'update', parameterizedSQL: 'UPDATE customer SET name = ?', + parameters: [value], debugSQL: "UPDATE customer SET name = '" + value.replace(/'/g, "''") + "'", + tracePath: [], comment: 'what: edit customer', purpose: 'why: verify mask contract', + elapsedMicros: 1, affectedRows: 1, resultSummary: '1 row affected' }; +} +it.each(cases)('mask contract: inline SQL for %s', (raw, masked) => { + const source = entry(raw); const output: string[] = []; + new TextDiagnosticSQLLogSink(line => output.push(line)).write(source); + const log = output.join('\n'); + expect(source.parameters).toEqual([raw]); + // Unknown parameter provenance: retain SQL, but expose no value or partial mask. + expect(log).toContain("name = '"); + if (raw.length >= 8 && !masked.startsWith('*')) expect(log).not.toContain(masked.replace(/'/g, "''")); + expect(log.toLowerCase()).toContain('masked'); + expect(log).not.toContain('name = ?'); + expect(log).not.toContain('[REDACTED SQL'); + if (raw) expect(log).not.toContain("'" + raw.replace(/'/g, "''") + "'"); +}); +it('mask contract: every plaintext record identifies debug provenance', () => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const output: string[] = []; const sink = new TextDiagnosticSQLLogSink(line => output.push(line)); + sink.write({ ...entry('Riverside'), parameterLogPolicies: ['masked'] }); + sink.write({ ...entry('Riverside'), parameterLogPolicies: ['masked'] }); + expect(output).toHaveLength(2); + for (const log of output) { + expect(log).toContain("'Riverside'"); + expect(log.toUpperCase()).toContain('DEBUG'); + expect(log.toUpperCase()).toContain('PLAINTEXT'); + } +}); diff --git a/source/teaql-ts/tests/mutation-policy.test.ts b/source/teaql-ts/tests/mutation-policy.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..b57de4ae020f1f3ae562afa5bc18da544ab8e931 --- /dev/null +++ b/source/teaql-ts/tests/mutation-policy.test.ts @@ -0,0 +1,295 @@ +import { + DelegatingMutationGovernanceSink, + DelegatingMutationPolicyApprovalProvider, + DelegatingMutationPolicyRegistry, + MISSING_MUTATION_POLICY, + MISSING_MUTATION_POLICY_APPROVAL, + MutationDecision, + MutationGovernanceWarning, + MutationPlan, + MutationPolicy, + MutationPolicyError, + MutationPolicyIdentity, + MutationIntent, + UserContext, +} from '../src'; +import { + AbstractSQLTeaQLClient, + SqlSession, + TeaQLSqlDriver, +} from '../src/sql/core'; + +const schemas = { + Order: { table: 'order_data', columns: { + id: { columnName: 'id', logicalType: 'integer' as const, decode: 'string' as const }, + version: { columnName: 'version', logicalType: 'integer' as const, decode: 'number' as const }, + name: { columnName: 'name', logicalType: 'text' as const, decode: 'string' as const }, + } }, + OrderLine: { table: 'order_line_data', columns: { + id: { columnName: 'id', logicalType: 'integer' as const, decode: 'string' as const }, + version: { columnName: 'version', logicalType: 'integer' as const, decode: 'number' as const }, + name: { columnName: 'name', logicalType: 'text' as const, decode: 'string' as const }, + } }, +}; + +class RecordingDriver implements TeaQLSqlDriver, SqlSession { + readonly databaseKind = 'sqlite' as const; + providerMutations = 0; + persistedMutations = 0; + transactions = 0; + commits = 0; + rollbacks = 0; + private next = 0; + private pendingMutations = 0; + + async query(sql: string): Promise { + if (/^\s*(?:INSERT|UPDATE|DELETE)/i.test(sql)) { + this.providerMutations++; + this.pendingMutations++; + } + if (/^\s*SELECT/i.test(sql)) { + return { rows: [{ id: String(this.next), version: 1, name: 'persisted' }], rowCount: 1 }; + } + return { rows: [], rowCount: 1 }; + } + async *stream(): AsyncIterable {} + identifier(value: string): string { return `"${value}"`; } + placeholder(): string { return '?'; } + encode(value: any): any { return value; } + contains(): string { return ''; } + aggregateFunction(name: string): string { return name; } + async ensureSchema(): Promise {} + async transaction(work: (session: SqlSession) => Promise): Promise { + this.transactions++; + this.pendingMutations = 0; + try { + const result = await work(this); + this.persistedMutations += this.pendingMutations; + this.pendingMutations = 0; + this.commits++; + return result; + } catch (error) { + this.pendingMutations = 0; + this.rollbacks++; + throw error; + } + } + async nextId(): Promise { this.next++; return String(this.next); } + async ensureIdFloor(): Promise {} + async close(): Promise {} +} + +class Client extends AbstractSQLTeaQLClient { + constructor(driver: RecordingDriver) { super(driver, schemas); } +} + +class TestPolicy implements MutationPolicy { + constructor( + readonly identity: MutationPolicyIdentity, + private readonly reviewer: (plan: MutationPlan) => MutationDecision, + ) {} + review(_context: unknown, plan: MutationPlan): MutationDecision { + return this.reviewer(plan); + } +} + +const identity = Object.freeze({ + policyId: 'orders', version: '1', fingerprint: 'sha256:orders-v1', +}); + +function approvedContext(policy: MutationPolicy): UserContext { + return new UserContext() + .withMutationPolicyRegistry(new DelegatingMutationPolicyRegistry(() => policy)) + .withMutationPolicyApprovalProvider(new DelegatingMutationPolicyApprovalProvider( + requested => ({ policy: requested, approvedBy: 'security-owner', approvedAt: new Date() }), + )); +} + +test('whole graph is reviewed immutably and its governance reaches every audit event', async () => { + const observed: Record = {}; + const policy = new TestPolicy(identity, plan => { + observed.operationCount = plan.operations.length; + observed.firstName = plan.operations[0].changedValues.name; + observed.frozen = Object.isFrozen(plan) + && Object.isFrozen(plan.operations) + && Object.isFrozen(plan.operations[0].changedValues); + return { verdict: 'allow' }; + }); + const context = approvedContext(policy); + const driver = new RecordingDriver(); + const client = new Client(driver).setUserContext(context); + const order = { entity: 'Order', action: 'Create', payload: { name: 'DRAFT' }, comment: 'submit order' }; + const line = { entity: 'OrderLine', action: 'Create', payload: { name: 'LINE-1' }, comment: 'submit line' }; + + await client.executeGraphSave(new MutationIntent('submit order'), async graph => { + client.preflightMutation(graph.request(order)); + client.preflightMutation(graph.request(line)); + order.payload.name = 'CHANGED-AFTER-PREFLIGHT'; + await client.executeMutation(graph.request({ ...order, payload: { name: 'DRAFT' } })); + await client.executeMutation(graph.request(line)); + }); + + expect(observed).toEqual({ operationCount: 2, firstName: 'DRAFT', frozen: true }); + expect(driver.providerMutations).toBe(2); + expect(driver.persistedMutations).toBe(2); + expect(driver.commits).toBe(1); + expect(client.auditTrace).toHaveLength(2); + expect(client.auditTrace.map(event => + (event.mutationGovernance as any).approvalStatus)).toEqual(['approved', 'approved']); + expect((client.auditTrace[0].mutationGovernance as any).executionId) + .toBe((client.auditTrace[1].mutationGovernance as any).executionId); +}); + +test('customer denial happens before SQL and incomplete reviewed graphs roll back', async () => { + const deniedDriver = new RecordingDriver(); + const denied = new Client(deniedDriver).setUserContext(approvedContext( + new TestPolicy(identity, () => ({ + verdict: 'deny', code: 'ORDER_DENIED', message: 'orders are disabled', + })), + )); + + await expect(denied.executeGraphSave(new MutationIntent('deny'), async graph => { + const mutation = { entity: 'Order', action: 'Create', payload: { name: 'D' }, comment: 'deny' }; + denied.preflightMutation(graph.request(mutation)); + await denied.executeMutation(graph.request(mutation)); + })).rejects.toThrow(/ORDER_DENIED/); + expect(deniedDriver.providerMutations).toBe(0); + expect(deniedDriver.persistedMutations).toBe(0); + expect(deniedDriver.rollbacks).toBe(1); + + const incompleteDriver = new RecordingDriver(); + const incomplete = new Client(incompleteDriver).setUserContext(approvedContext( + new TestPolicy(identity, () => ({ verdict: 'allow' })), + )); + const first = { entity: 'Order', action: 'Create', payload: { name: 'A' }, comment: 'first' }; + const second = { entity: 'OrderLine', action: 'Create', payload: { name: 'B' }, comment: 'second' }; + await expect(incomplete.executeGraphSave(new MutationIntent('incomplete graph'), async graph => { + incomplete.preflightMutation(graph.request(first)); + incomplete.preflightMutation(graph.request(second)); + await incomplete.executeMutation(graph.request(first)); + })).rejects.toThrow(/were not executed/); + expect(incompleteDriver.providerMutations).toBe(1); + expect(incompleteDriver.persistedMutations).toBe(0); + expect(incompleteDriver.commits).toBe(0); + expect(incompleteDriver.rollbacks).toBe(1); +}); + +test('missing policy and approval warnings are stable, deduplicated, and fail open', () => { + const warnings: MutationGovernanceWarning[] = []; + const context = new UserContext().withMutationGovernanceSink( + new DelegatingMutationGovernanceSink((_context, warning) => { + warnings.push(warning); + if (warnings.length === 1) throw new Error('warning sink unavailable'); + }), + ); + const plan: MutationPlan = { + executionId: 'warning-1', requestKey: 'Order.saveGraph', rootEntityType: 'Order', + auditReason: 'verify missing-policy warnings', + operations: [{ kind: 'update', entity: 'Order', entityId: '1', + originalVersion: 1, changedValues: { name: 'updated' } }], + }; + const generated = context.reviewMutationPlan(plan); + context.reviewMutationPlan({ ...plan, executionId: 'warning-2' }); + expect(generated.warningCodes).toEqual([MISSING_MUTATION_POLICY]); + expect(warnings.map(warning => warning.firstOccurrence)).toEqual([true, false]); + + const customerWarnings: MutationGovernanceWarning[] = []; + const customer = new UserContext() + .withMutationPolicyRegistry(new DelegatingMutationPolicyRegistry(() => + new TestPolicy(identity, () => ({ verdict: 'allow' })))) + .withMutationGovernanceSink(new DelegatingMutationGovernanceSink( + (_context, warning) => customerWarnings.push(warning), + )); + const unapproved = customer.reviewMutationPlan(plan); + expect(unapproved.warningCodes).toEqual([MISSING_MUTATION_POLICY_APPROVAL]); + expect(unapproved.approvalStatus).toBe('missing'); + + customer.withMutationPolicyApprovalProvider(new DelegatingMutationPolicyApprovalProvider( + () => ({ + policy: { ...identity, fingerprint: 'sha256:different' }, + approvedBy: 'security-owner', + approvedAt: new Date(), + }), + )); + expect(customer.reviewMutationPlan({ ...plan, executionId: 'mismatch' }).approvalStatus) + .toBe('missing'); +}); + +test('warning sink failure does not change generated-default persistence', async () => { + const driver = new RecordingDriver(); + const context = new UserContext().withMutationGovernanceSink( + new DelegatingMutationGovernanceSink(() => { throw new Error('sink unavailable'); }), + ); + const client = new Client(driver).setUserContext(context); + + await expect(client.executeMutation({ + entity: 'Order', action: 'Create', payload: { name: 'allowed' }, comment: 'default', + })).resolves.toBeDefined(); + expect(driver.persistedMutations).toBe(1); + expect((client.auditTrace[0].mutationGovernance as any).warningCodes) + .toEqual([MISSING_MUTATION_POLICY]); +}); + +test('customer policy requires complete generated preflight for graph saves', async () => { + const driver = new RecordingDriver(); + const client = new Client(driver).setUserContext(approvedContext( + new TestPolicy(identity, () => ({ verdict: 'allow' })), + )); + await expect(client.executeGraphSave(new MutationIntent('unplanned'), graph => client.executeMutation(graph.request({ + entity: 'Order', action: 'Create', payload: { name: 'unplanned' }, comment: 'unplanned', + })))).rejects.toThrow(MutationPolicyError); + expect(driver.providerMutations).toBe(0); +}); + +test('cyclic policy values fail explicitly instead of overflowing the stack', () => { + const payload: Record = { name: 'cycle' }; + payload.self = payload; + const context = new UserContext(); + expect(() => context.reviewMutationPlan({ + executionId: 'cyclic-plan', requestKey: 'Order.saveGraph', rootEntityType: 'Order', + auditReason: 'reject cyclic policy values', + operations: [{ kind: 'update', entity: 'Order', entityId: '1', + originalVersion: 1, changedValues: payload }], + })).toThrow(/must not contain cycles/); +}); + +test('failed graph lifecycle initialization releases the save queue', async () => { + const context = new UserContext(); + const driver = new RecordingDriver(); + const client = new Client(driver).setUserContext(context); + context.beginMutationPolicyGraph(); + + await expect(client.executeGraphSave(new MutationIntent('lifecycle'), async () => undefined)) + .rejects.toThrow(/already active/); + context.endMutationPolicyGraph(); + + await expect(client.executeGraphSave(new MutationIntent('lifecycle'), async () => undefined)).resolves.toBeUndefined(); + expect(driver.transactions).toBe(1); + expect(driver.commits).toBe(1); +}); + +test('stable ledger identity tolerates parent ids assigned during graph execution', async () => { + const driver = new RecordingDriver(); + const client = new Client(driver).setUserContext(approvedContext( + new TestPolicy(identity, plan => { + expect(plan.operations[1].changedValues.name).toBeUndefined(); + return { verdict: 'allow' }; + }), + )); + const parent = { entity: 'Order', action: 'Create', payload: { name: 'parent' }, + comment: 'create graph', ledgerKey: { entity: 'Order', id: -1 } }; + const childBefore = { entity: 'OrderLine', action: 'Create', + payload: { name: { id: undefined, label: 'parent' } }, comment: 'create graph', + ledgerKey: { entity: 'OrderLine', id: -2 } }; + const childAfter = { ...childBefore, payload: { name: { id: '1', label: 'parent' } } }; + + await client.executeGraphSave(new MutationIntent('create graph'), async graph => { + client.preflightMutation(graph.request(parent)); + client.preflightMutation(graph.request(childBefore)); + await client.executeMutation(graph.request(parent)); + await client.executeMutation(graph.request(childAfter)); + }); + + expect(driver.persistedMutations).toBe(2); + expect(driver.commits).toBe(1); +}); diff --git a/source/teaql-ts/tests/nested-facet-trace.test.ts b/source/teaql-ts/tests/nested-facet-trace.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..1a2a2b614b06ad1e33196c26c1ef93c4eafe435d --- /dev/null +++ b/source/teaql-ts/tests/nested-facet-trace.test.ts @@ -0,0 +1,349 @@ +import { OrderBy, SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { executeRelationFacets } from '../src/core/facet'; +import { SmartList } from '../src/core/smart-list'; +import { AbstractSQLTeaQLClient, EntitySchema, SQLExecutionEvidenceStore } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +// Native metadata only: runtime derivation must produce every observed frame. +const schemas: Record = {}; +for (const [entity, field, target] of [ + ['School', 'platform', 'Platform'], ['Platform', 'organization', 'Organization'], + ['Organization', '', ''], +]) { + schemas[entity] = { + table: `${entity.toLowerCase()}_data`, + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string', logPolicy: 'plain' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number', logPolicy: 'plain' }, + name: { columnName: 'name', logicalType: 'text', decode: 'string', logPolicy: 'masked' }, + ...(field ? { [field]: { columnName: field, logicalType: 'integer' as const, + decode: 'string' as const, logPolicy: 'plain' as const } } : {}), + }, + relations: field ? { [field]: { targetEntity: target, localKey: field, foreignKey: 'id', many: false } } : {}, + }; +} +schemas.Platform.relations!.schools = { targetEntity: 'School', localKey: 'id', foreignKey: 'platform', many: true }; +class Client extends AbstractSQLTeaQLClient { + constructor(readonly transport = new SQLiteDriver(':memory:')) { super(transport, schemas); } +} + +async function fixture(logging: boolean) { + const client = new Client().setDiagnosticSQLLogSink(undefined); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const [entity, id, payload] of [ + ['Organization', '1', { name: 'North' }], ['Organization', '2', { name: 'South' }], + ['Platform', '1', { name: 'Alpha', organization: '1' }], + ['Platform', '2', { name: 'Beta', organization: '2' }], + ['Platform', '3', { name: 'Empty', organization: '2' }], + ['School', '1', { name: 'A', platform: '1' }], + ['School', '2', { name: 'B', platform: '1' }], + ['School', '3', { name: 'C', platform: '2' }], + ] as const) await client.executeMutation({ entity, action: 'Create', id, + payload: { ...payload }, comment: 'seed native facet trace example' }); + const evidence = new SQLExecutionEvidenceStore(); + const diagnostics: unknown[] = []; + client.setRuntimeTelemetrySink(evidence).setQueryLoggingEnabled(logging); + client.setDiagnosticSQLLogSink({ write: entry => { diagnostics.push(entry); } }); + return { client, evidence, diagnostics }; +} + +function facets(includeAll: boolean) { + const platform = new SelectQuery('Platform').limit(10).aggregate('Count', 'id', 'schoolCount'); + platform.facetBy('organizations', 'organization', { + toQuery: () => new SelectQuery('Organization').limit(10).aggregate('Count', 'id', 'platformCount'), + }, includeAll); + return new SelectQuery('School').limit(10).facetBy('platforms', 'platform', { toQuery: () => platform }, includeAll); +} + +function assertPaths(entries: ReturnType, root: string, + routes: string[][], comment: string) { + expect(entries.length).toBe(routes.length); + entries.forEach((entry, index) => { + expect(entry.comment).toBe(comment); + expect(entry.purpose).toBe('verify nested facet ownership'); + expect(entry.executionOutcome).toBe('success'); + expect(entry.tracePath.map(node => [node.kind, node.name, node.detail ?? ''])).toEqual([ + ['operation', root, 'query'], ['request', root, ''], + ...routes[index].map(field => ['relation', field.split('.').pop(), field]), + ['provider', 'sqlite', ''], ['sql', 'select', ''], + ]); + }); +} + +it.each([true, false])('ID-set collection owns a helper and cache hits do not invent SQL, logging=%p', async logging => { + const f = await fixture(logging); + try { + const context = new UserContext().insertResource('dataService', f.client); + const reads = jest.spyOn(f.client.transport, 'query'); + const page = (offset: number) => context.prepareQuery(new SelectQuery('School') + .select(['id', 'version', 'name']).order(OrderBy.desc('id')) + .offset(offset).limit(1).comment('load school page').purpose('render school page') + .optimizePaginationWithIdSetConfig('request-tree-schools', 60, 10)); + expect((await f.client.executeQuery(page(1))).map(row => row.id)).toEqual(['2']); + expect(context.idSetPaginationPlan).toBe('ID_SET_BUILD'); + expect(context.idSetPaginationCount).toBe(3); + expect(context.idSetPaginationCountAccuracy).toBe('EXACT'); + const first = f.evidence.snapshot(); + expect(first).toHaveLength(2); + expect(first[0].traceChain?.map(node => node.detail)).toEqual([ + 'render school page', 'load school page', 'collect School IDs for pagination']); + expect(first[1].traceChain?.map(node => node.detail)).toEqual(['render school page', 'load school page']); + f.evidence.enableAll(); f.diagnostics.length = 0; + reads.mockClear(); + expect((await f.client.executeQuery(page(0))).map(row => row.id)).toEqual(['3']); + expect(context.idSetPaginationPlan).toBe('ID_SET_HIT'); + expect(context.idSetPaginationCount).toBe(3); + expect(context.idSetPaginationCountAccuracy).toBe('EXACT'); + expect(reads).toHaveBeenCalledTimes(1); + expect(reads.mock.calls[0][0]).not.toMatch(/COUNT\(/i); + const second = f.evidence.snapshot(); + expect(second).toHaveLength(1); + expect(second[0].traceChain?.map(node => node.detail)).toEqual(['render school page', 'load school page']); + expect(f.diagnostics).toHaveLength(logging ? 1 : 0); + expect((second[0].tracePath ?? []).some(node => node.kind === 'relation')).toBe(false); + console.log(`RTC_COM_07_CACHE_PASS logging=${logging} accuracy=EXACT hit_statements=1`); + } finally { await f.client.close(); } +}); + +it.each([true, false])('keeps native nested facet sibling comments isolated, logging=%p', async logging => { + const f = await fixture(logging); + try { + const outer = new SelectQuery('School').limit(10).comment('load branches').purpose('render branches'); + for (const alias of ['left', 'right']) { + const organizations = new SelectQuery('Organization').limit(10).aggregate('Count', 'id', 'platformCount') + .comment(`load ${alias} organizations`); + const platforms = new SelectQuery('Platform').limit(10).aggregate('Count', 'id', 'schoolCount') + .comment(`load ${alias} platforms`); + platforms.facetBy('organizations', 'organization', {toQuery: () => organizations}, true, + {kind: 'facet', method: 'facetByOrganizationAs', alias: 'organizations', relation: 'organization'}); + outer.facetBy(alias, 'platform', {toQuery: () => platforms}, true, + {kind: 'facet', method: 'facetByPlatformAs', alias, relation: 'platform'}); + } + const before = JSON.stringify(outer); + const result = await executeRelationFacets(f.client, query => query, outer, outer.facets); + for (const alias of ['left', 'right']) { + expect(result[alias].map(row => [row.id, row.schoolCount])).toEqual([['1', 2], ['2', 1], ['3', 0]]); + expect(result[alias].facets.organizations?.map(row => [row.id, row.platformCount])).toEqual([['1', 1], ['2', 2]]); + const prefix = ['render branches', 'load branches', `facetByPlatformAs('${alias}')`]; + const chains = f.evidence.snapshot().map(entry => entry.traceChain!.map(node => node.detail)) + .filter(chain => chain[2] === prefix[2]); + expect(chains).toHaveLength(4); + expect(chains).toContainEqual([...prefix, 'aggregate platform']); + expect(chains).toContainEqual([...prefix, `load ${alias} platforms`]); + for (const local of ['aggregate organization', `load ${alias} organizations`]) + expect(chains).toContainEqual([...prefix, `load ${alias} platforms`, "facetByOrganizationAs('organizations')", local]); + } + expect(f.evidence.snapshot()).toHaveLength(8); + expect(f.diagnostics).toHaveLength(logging ? 8 : 0); + expect(JSON.stringify(outer)).toBe(before); + console.log(`RTC_COM_06_PASS logging=${logging} nested=true siblings=true`); + } finally { await f.client.close(); } +}); + +it.each([true, false])('executes nested facets with inherited roots, logging=%p', async logging => { + const f = await fixture(logging); + try { + const outer = facets(false).filter({ platform: { $eq: '1' } }) + .comment('load nested facets').purpose('verify nested facet ownership'); + const before = JSON.stringify(outer); + const result = await executeRelationFacets(f.client, query => query, outer, outer.facets); + expect(result.platforms.map(row => [row.id, row.schoolCount])).toEqual([['1', 2]]); + expect(result.platforms.facets.organizations?.map(row => [row.id, row.platformCount])).toEqual([['1', 1]]); + expect(JSON.stringify(outer)).toBe(before); + // Diagnostics may be disabled independently of the explicitly installed + // execution-evidence observer. It still observes actual SQL metadata. + assertPaths(f.evidence.snapshot(), 'School', [ + [], ['School.platform'], ['School.platform'], ['School.platform', 'Platform.organization'], + ], 'load nested facets'); + expect(f.diagnostics).toHaveLength(logging ? 4 : 0); + } finally { await f.client.close(); } +}); + +it.each([true, false])('ID-set helper redacts a secret bound only by a selected descendant, logging=%p', async logging => { + const f = await fixture(logging); + try { + const context = new UserContext().insertResource('dataService', f.client); + const query = new SelectQuery('School').order(OrderBy.desc('id')).offset(1).limit(1) + .comment('load Alpha school page').purpose('inspect Alpha selections') + .relationQuery('platform', new SelectQuery('Platform').limit(5).filter({name: {$eq: 'Alpha'}}), 'platform', 'id', false) + .optimizePaginationWithIdSetConfig('private-id-set', 60, 10); + const rows = await f.client.executeQuery(context.prepareQuery(query)); + expect(rows.map(row => row.id)).toEqual(['2']); + const facts = f.evidence.snapshot(); + expect(facts).toHaveLength(3); + expect(facts[0].traceChain?.map(node => node.detail)).toEqual([ + 'inspect [REDACTED] selections', 'load [REDACTED] school page', 'collect School IDs for pagination']); + expect(JSON.stringify(facts)).not.toContain('Alpha'); + expect(JSON.stringify(f.diagnostics)).not.toContain('Alpha'); + } finally { await f.client.close(); } +}); + +it.each([true, false])('preserves explicit facet SUM comments and rejects blank input with logging=%p', async logging => { + for (const comment of ['sum visible school IDs', '', ' \t', '\u0085']) { + const f = await fixture(logging); + try { + const sum = new SelectQuery('School').aggregate('Sum', 'id', 'schoolTotal').comment(comment); + const originalSum = JSON.stringify(sum); + const values = new SelectQuery('Platform').limit(10).comment('load platform facets') + .aggregate('Count', 'id', 'schoolCount').relationAggregate('schools', 'schoolTotal', sum); + const outer = new SelectQuery('School').limit(10).comment('load schools').purpose('render school list') + .facetBy('platforms', 'platform', { toQuery: () => values }, false, + { kind: 'facet', method: 'facetByPlatformAs', alias: 'platforms', relation: 'platform' }); + if (comment !== 'sum visible school IDs') { + await expect(executeRelationFacets(f.client, query => query, outer, outer.facets)).rejects.toThrow(); + expect(f.evidence.snapshot().every(entry => (entry.traceChain ?? []).length <= 4)).toBe(true); + continue; + } + const results = await executeRelationFacets(f.client, query => query, outer, outer.facets); + expect(results.platforms.map(row => [row.id, row.schoolTotal])).toEqual([['1', 3], ['2', 3]]); + const facts = f.evidence.snapshot(); + expect(facts).toHaveLength(3); + expect(f.diagnostics).toHaveLength(logging ? 3 : 0); + const aggregateFacts = facts.filter(entry => { + const chain = entry.traceChain ?? []; + return chain[chain.length - 1]?.detail === comment; + }); + expect(aggregateFacts).toHaveLength(1); + expect((aggregateFacts[0].traceChain ?? []).map(node => node.detail)).toEqual(['render school list', 'load schools', + "facetByPlatformAs('platforms')", 'aggregate platform', comment]); + expect(sum.commentText).toBe(comment); + expect(JSON.stringify(sum)).toBe(originalSum); + } finally { await f.client.close(); } + } +}); + +it.each([[true, 0], [true, 32], [false, 0], [false, 32]])( + 'retains facets separately on each loaded relation, includeAll=%p threshold=%p', async (includeAll, threshold) => { + const f = await fixture(true); + try { + const outer = new SelectQuery('Platform').limit(10) + .comment('load per-parent facets').purpose('verify nested facet ownership'); + outer.relations.push({ name: 'schools', query: facets(Boolean(includeAll)).limit(1) + .topNProbeParentThreshold(Number(threshold)) }); + const rows = await f.client.executeQuery(outer); + expect(rows.map(row => row.schools.length)).toEqual([1, 1, 0]); + for (const [index, row] of rows.entries()) { + expect(row.schools).toBeInstanceOf(SmartList); + const platforms = row.schools.facets.platforms as SmartList; + expect(platforms.map(value => [value.id, value.schoolCount])).toEqual(includeAll + ? [['1', index === 0 ? 2 : 0], ['2', index === 1 ? 1 : 0], ['3', 0]] + : index < 2 ? [[String(index + 1), index === 0 ? 2 : 1]] : []); + const organizations = platforms.facets.organizations!; + expect(organizations.map(value => [value.id, value.platformCount])).toEqual(includeAll + ? [['1', 1], ['2', 2]] : index < 2 ? [[String(index + 1), 1]] : []); + } + const paths = f.evidence.snapshot().map(entry => entry.tracePath + .filter(node => node.kind === 'relation').map(node => node.detail)); + expect(paths.some(path => path.join('/') === 'Platform.schools/School.platform/Platform.organization')).toBe(true); + for (const entry of f.evidence.snapshot()) { + expect(entry.tracePath[0]).toMatchObject({ kind: 'operation', name: 'Platform', detail: 'query' }); + expect(entry.tracePath[1]).toMatchObject({ kind: 'request', name: 'Platform' }); + expect(entry.comment).toBe('load per-parent facets'); + expect(entry.purpose).toBe('verify nested facet ownership'); + } + } finally { await f.client.close(); } +}); + +it('keeps inherited private intent safe through nested facet success/failure and the next request', async () => { + const f = await fixture(true); + const outer = new SelectQuery('Platform').limit(10).filter({ name: { $eq: 'Alpha' } }) + .comment('load Alpha facets').purpose('inspect Alpha selections'); + outer.relations.push({ name: 'schools', query: facets(false) }); + const original = f.client.transport.query.bind(f.client.transport); + const failure = new Error('driver detail Alpha'); + let failOrganization = true; + jest.spyOn(f.client.transport, 'query').mockImplementation((sql, values) => { + if (failOrganization && /FROM "organization_data"/.test(sql)) return Promise.reject(failure); + return original(sql, values); + }); + try { + await expect(f.client.executeQuery(outer)).rejects.toBe(failure); + const failed = f.evidence.snapshot(); + expect(failed[failed.length - 1].executionOutcome).toBe('failure'); + expect(failed[failed.length - 1].tracePath.filter(node => node.kind === 'relation') + .map(node => node.detail)).toEqual(['Platform.schools', 'School.platform', 'Platform.organization']); + expect(JSON.stringify(failed)).not.toContain('Alpha'); + expect(JSON.stringify(f.diagnostics)).not.toContain('Alpha'); + failOrganization = false; + const rows = await f.client.executeQuery(outer); + expect(rows[0].name).toBe('Alpha'); + expect(rows[0].schools.facets.platforms[0].schoolCount).toBe(2); + expect(JSON.stringify(f.evidence.snapshot())).not.toContain('Alpha'); + expect(outer.commentText).toBe('load Alpha facets'); + // No Context/global accumulation of a previous request's private values. + await f.client.executeQuery(new SelectQuery('Organization').limit(1) + .comment('Alpha is ordinary prose here').purpose('independent request')); + const all = f.evidence.snapshot(); + expect(all[all.length - 1].comment).toBe('Alpha is ordinary prose here'); + } finally { await f.client.close(); } +}); + +it('protects early membership SQL from a secret bound only by a later nested facet', async () => { + const f = await fixture(true); + try { + const outer = facets(false).comment('inspect North facets').purpose('verify North privacy'); + outer.facets[0].query.facets[0].query.filter({ name: { $eq: 'North' } }); + const result = await executeRelationFacets(f.client, query => query, outer, outer.facets); + expect(result.platforms.facets.organizations?.map(row => row.name)).toEqual(['North']); + const entries = f.evidence.snapshot(); + expect(entries.length).toBe(4); + expect(JSON.stringify(entries)).not.toContain('North'); + expect(outer.commentText).toBe('inspect North facets'); + } finally { await f.client.close(); } +}); + +it.each([['mixed', false], ['mixed', true], ['all-null', false], ['all-null', true]] as const)( + 'null local keys never count orphan children: page=%s includeAll=%p', async (page, includeAll) => { + const column = (name: string) => ({ columnName: name, logicalType: 'integer' as const, + decode: 'string' as const, logPolicy: 'plain' as const }); + const identity = { id: column('id'), version: column('version') }; + const model: Record = { + Parent: { table: 'nullable_facet_parent', columns: { ...identity, code: column('code') }, + relations: { children: { targetEntity: 'Child', localKey: 'code', foreignKey: 'parentCode', many: true } } }, + Child: { table: 'nullable_facet_child', columns: { + ...identity, parentCode: column('parent_code'), tag: column('tag'), + }, relations: { tag: { targetEntity: 'Tag', localKey: 'tag', foreignKey: 'id', many: false } } }, + Tag: { table: 'nullable_facet_tag', columns: identity }, + }; + class NullableClient extends AbstractSQLTeaQLClient { + constructor() { super(new SQLiteDriver(':memory:'), model); } + } + const client = new NullableClient().setDiagnosticSQLLogSink(undefined); + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const [entity, id, payload] of [ + ['Parent', '1', { code: '10' }], ['Parent', '2', { code: null }], + ['Tag', '100', {}], ['Tag', '200', {}], + ['Child', '1', { parentCode: '10', tag: '100' }], + ['Child', '2', { parentCode: null, tag: '200' }], + ] as const) await client.executeMutation({ entity, id, action: 'Create', payload: { ...payload }, + comment: 'seed nullable relation facet fixture' }); + const children = new SelectQuery('Child').limit(2).facetBy('tags', 'tag', { + toQuery: () => new SelectQuery('Tag').limit(10).aggregate('Count', 'id', 'childCount'), + }, includeAll); + const query = new SelectQuery('Parent').limit(2) + .comment('load nullable relation facets').purpose('exclude orphan membership') + .relationQuery('children', children); + if (page === 'all-null') query.filter({ id: { $eq: '2' } }); + const evidence = new SQLExecutionEvidenceStore(); + client.setRuntimeTelemetrySink(evidence); + const rows = await client.executeQuery(query); + expect(rows.map(row => row.id)).toEqual(page === 'mixed' ? ['1', '2'] : ['2']); + for (const row of rows) { + const hasKey = row.code !== null; + expect(row.children.map((child: any) => child.id)).toEqual(hasKey ? ['1'] : []); + expect(row.children).toBeInstanceOf(SmartList); + const tags = row.children.facets?.tags as SmartList | undefined; + expect(tags).toBeInstanceOf(SmartList); + expect(tags?.map(tag => [tag.id, tag.childCount])).toEqual(includeAll + ? [['100', hasKey ? 1 : 0], ['200', 0]] : hasKey ? [['100', 1]] : []); + } + for (const entry of evidence.snapshot()) { + expect(entry.tracePath[0]).toMatchObject({ kind: 'operation', name: 'Parent', detail: 'query' }); + expect(entry.tracePath[1]).toMatchObject({ kind: 'request', name: 'Parent' }); + expect(entry.comment).toBe('load nullable relation facets'); + expect(entry.purpose).toBe('exclude orphan membership'); + } + } finally { await client.close(); } +}); diff --git a/source/teaql-ts/tests/numeric-partition-trace.test.ts b/source/teaql-ts/tests/numeric-partition-trace.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..eada016e104521e4411d20f97f7c9f996f9030b1 --- /dev/null +++ b/source/teaql-ts/tests/numeric-partition-trace.test.ts @@ -0,0 +1,140 @@ +import { OrderBy, SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { PLAINTEXT_LOG_ENV } from '../src/core/log-privacy'; +import { + AbstractSQLTeaQLClient, EntitySchema, SQLExecutionEvidenceStore, + SQLExecutionMetadata, SqlQueryResult, +} from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +// TC-SQL-10 native subset: public numeric grouping and relation-derived windows. +// SelectQuery has no HAVING or public root partitionBy API; do not invent one. +const SECRET = 'PRIVATE-NUMERIC-PARTITION'; +const integer = (columnName: string) => ({ columnName, logicalType: 'integer' as const, + decode: 'number' as const, logPolicy: 'plain' as const }); +const identity = { id: integer('id'), version: integer('version') }; +const schemas: Record = { + GroupRoot: { table: 'group_root', columns: identity, relations: { + owners: { targetEntity: 'GroupOwner', localKey: 'id', foreignKey: 'rootId', many: true }, + } }, + GroupOwner: { table: 'group_owner', columns: { ...identity, rootId: integer('root_id') }, relations: { + samples: { targetEntity: 'MetricSample', localKey: 'id', foreignKey: 'ownerId', many: true }, + } }, + MetricSample: { table: 'metric_sample', auditMaskFields: ['name'], columns: { + ...identity, ownerId: integer('owner_id'), bucket: integer('bucket'), + name: { columnName: 'name', logicalType: 'text', decode: 'string', logPolicy: 'plain' }, + } }, +}; + +class Driver extends SQLiteDriver { + readonly reads: Array<{ sql: string; values: unknown[] }> = []; + override async query(sql: string, values: any[] = []): Promise { + if (sql.startsWith('SELECT')) this.reads.push({ sql, values: [...values] }); + return super.query(sql, values); + } +} +class Client extends AbstractSQLTeaQLClient { + constructor(readonly transport = new Driver(':memory:')) { super(transport, schemas); } +} + +async function fixture(logging: boolean) { + const client = new Client().setDiagnosticSQLLogSink(undefined); + await new UserContext().insertResource('dataService', client).ensureSchema(); + await client.executeMutation({ entity: 'GroupRoot', action: 'Create', id: 1, payload: {}, comment: 'seed group root' }); + for (const id of [1, 2, 3]) await client.executeMutation({ entity: 'GroupOwner', action: 'Create', id, + payload: { rootId: 1 }, comment: 'seed numeric group owner' }); + // Different per-owner counts, a filtered row, an orphan, and an empty owner. + const samples = [[1, 20], [1, 10], [1, 10], [1, 20], [2, 20], [2, 20], [2, 10], [null, 30]]; + for (const [index, [ownerId, bucket]] of samples.entries()) await client.executeMutation({ + entity: 'MetricSample', action: 'Create', id: index + 1, + payload: { ownerId, bucket, name: index === 3 ? 'excluded' : SECRET }, comment: 'seed numeric sample', + }); + const evidence = new SQLExecutionEvidenceStore(); + const diagnostics: SQLExecutionMetadata[] = []; + client.setRuntimeTelemetrySink(evidence).setQueryLoggingEnabled(logging) + .setDiagnosticSQLLogSink({ write: entry => { diagnostics.push(entry); } }); + client.transport.reads.length = 0; + return { client, evidence, diagnostics }; +} + +const previousPlaintext = process.env[PLAINTEXT_LOG_ENV]; +beforeEach(() => { delete process.env[PLAINTEXT_LOG_ENV]; }); +afterEach(() => { + if (previousPlaintext === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = previousPlaintext; +}); + +const cases = ['root', 'window', 'probe'].flatMap(shape => + [true, false].flatMap(logging => [1, 10].map(limit => ({ shape, logging, limit })))); +test.each(cases)('numeric grouping $shape logging=$logging limit=$limit', async ({ shape, logging, limit }) => { + const f = await fixture(logging); + try { + expect(schemas.MetricSample.relations?.bucket).toBeUndefined(); + const grouped = new SelectQuery('MetricSample').groupBy('ownerId').groupBy('bucket') + .aggregate('Count', 'id', 'n').filter({ name: { $eq: SECRET }, ownerId: { $isNull: false } }) + .order(OrderBy.desc('bucket')).limit(limit); + const root = shape === 'root' ? 'MetricSample' : 'GroupRoot'; + const query = (shape === 'root' ? grouped.order(OrderBy.asc('ownerId')) + : new SelectQuery('GroupRoot').limit(1).relationQuery('owners', + new SelectQuery('GroupOwner').limit(10).order(OrderBy.asc('id')) + .relationQuery('samples', grouped.topNProbeParentThreshold(shape === 'window' ? 0 : 32)))) + .comment(`count numeric groups ${SECRET}`).purpose(`render numeric groups ${SECRET}`); + const original = JSON.stringify(query); + const rows = await f.client.executeQuery(query); + if (shape === 'root') { + expect(rows.map(row => [row.ownerId, row.bucket, row.n])) + .toEqual([[1, 20, 1], [2, 20, 2], [1, 10, 2], [2, 10, 1]].slice(0, limit)); + } else { + expect(rows).toHaveLength(1); + expect(rows[0].owners.map((owner: any) => [owner.id, + owner.samples.map((row: any) => [row.bucket, row.n])])).toEqual([ + [1, [[20, 1], [10, 2]].slice(0, limit)], + [2, [[20, 2], [10, 1]].slice(0, limit)], [3, []], + ]); + for (const owner of rows[0].owners) for (const sample of owner.samples) { + expect(sample).not.toHaveProperty('__teaql_partition_rank'); + } + } + expect(JSON.stringify(query)).toBe(original); + const entries = f.evidence.snapshot(); + const routes = shape === 'root' ? [[]] : [[], ['GroupRoot.owners'], + ...Array.from({ length: shape === 'window' ? 1 : 3 }, () => ['GroupRoot.owners', 'GroupOwner.samples'])]; + expect(entries).toHaveLength(routes.length); + expect(f.client.transport.reads).toHaveLength(routes.length); + expect(f.diagnostics).toHaveLength(logging ? routes.length : 0); + entries.forEach((entry, index) => { + expect(entry.tracePath.map(node => [node.kind, node.name, node.detail ?? ''])).toEqual([ + ['operation', root, 'query'], ['request', root, ''], + ...routes[index].map(field => ['relation', field.split('.').pop(), field]), + ['provider', 'sqlite', ''], ['sql', 'select', ''], + ]); + expect(entry.executionOutcome).toBe('success'); + expect(entry.comment).toContain('count numeric groups'); + expect(entry.purpose).toContain('render numeric groups'); + console.log(`NUMERIC_SQL shape=${shape} logging=${logging} limit=${limit} ` + + JSON.stringify({ sql: entry.parameterizedSQL, path: entry.tracePath })); + }); + // The future-only child operand must protect the very first root statement. + expect(JSON.stringify(entries)).not.toContain(SECRET); + expect(JSON.stringify(f.diagnostics)).not.toContain(SECRET); + if (shape !== 'root') expect(f.client.transport.reads[0].values).not.toContain(SECRET); + const groupedReads = f.client.transport.reads.filter(read => read.sql.includes('COUNT(')); + expect(groupedReads).toHaveLength(shape === 'probe' ? 3 : 1); + for (const read of groupedReads) { + expect(read.values).toContain(SECRET); + expect(read.sql).toContain('GROUP BY "owner_id", "bucket"'); + expect(read.sql.includes('ROW_NUMBER() OVER')).toBe(shape === 'window'); + expect(read.sql).toContain('ORDER BY "bucket" DESC, "owner_id" ASC'); + expect(read.sql).not.toContain(', "id" ASC'); + } + f.evidence.enableAll(); + f.diagnostics.length = 0; + await f.client.executeQuery(new SelectQuery('GroupRoot').limit(1) + .comment(SECRET).purpose('independent numeric query')); + expect(f.evidence.snapshot()[0].comment).toBe(SECRET); + expect(f.evidence.snapshot()[0].tracePath.map(node => node.name)) + .toEqual(['GroupRoot', 'GroupRoot', 'sqlite', 'select']); + expect(f.diagnostics).toHaveLength(logging ? 1 : 0); + console.log(`NUMERIC_RESULT shape=${shape} logging=${logging} limit=${limit} SQL=${routes.length} counts=verified`); + } finally { await f.client.close(); } +}); diff --git a/source/teaql-ts/tests/object-location.test.ts b/source/teaql-ts/tests/object-location.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..e0a0e03ad8ce52903722dff6c973032f5f6e93b2 --- /dev/null +++ b/source/teaql-ts/tests/object-location.test.ts @@ -0,0 +1,22 @@ +import { checkResultToWire, ObjectLocation } from '../src'; + +test('renders canonical, native, and JSON locations from one structure', () => { + const location = ObjectLocation.root().property('order_items').index(2).property('user_url'); + expect(location.modelPath()).toBe('order_items[2].user_url'); + expect(location.nativePath()).toBe('orderItems[2].userUrl'); + expect(location.instancePath()).toBe('/orderItems/2/userUrl'); + expect(location.instancePath('snake_case')).toBe('/order_items/2/user_url'); + expect(location.instancePath('PascalCase')).toBe('/OrderItems/2/UserUrl'); +}); + +test('wire checker path preserves an accepted submitted alias', () => { + const wire = checkResultToWire({ + ruleId: 'required', + entityType: 'customer_account', + location: ObjectLocation.property('user_url'), + sourceInstancePath: '/user_url', + }); + expect(wire.instancePath).toBe('/userUrl'); + expect(wire.sourceInstancePath).toBe('/user_url'); + expect(wire.location).toEqual([{kind: 'property', name: 'user_url'}]); +}); diff --git a/source/teaql-ts/tests/opentelemetry.test.ts b/source/teaql-ts/tests/opentelemetry.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..d599cc16ff2a3e546be37eb83bfbd0473b9d175a --- /dev/null +++ b/source/teaql-ts/tests/opentelemetry.test.ts @@ -0,0 +1,178 @@ +import { context, metrics, propagation } from '@opentelemetry/api'; +import { W3CTraceContextPropagator } from '@opentelemetry/core'; +import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks'; +import { + BasicTracerProvider, + InMemorySpanExporter, + SimpleSpanProcessor, +} from '@opentelemetry/sdk-trace-base'; +import { + AggregationTemporality, + InMemoryMetricExporter, + MeterProvider, + PeriodicExportingMetricReader, +} from '@opentelemetry/sdk-metrics'; +import { + InMemoryLogRecordExporter, + LoggerProvider, + SimpleLogRecordProcessor, +} from '@opentelemetry/sdk-logs'; +import { observeRuntimeOperation } from '../src/core/telemetry'; +import { OpenTelemetryRuntimeTelemetry } from '../src/telemetry/opentelemetry'; + +test('exports safe balanced spans through the official OpenTelemetry SDK', async () => { + context.setGlobalContextManager(new AsyncLocalStorageContextManager().enable()); + const exporter = new InMemorySpanExporter(); + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] }); + const metricExporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE); + const metricReader = new PeriodicExportingMetricReader({ + exporter: metricExporter, + exportIntervalMillis: 60_000, + }); + const meterProvider = new MeterProvider({ readers: [metricReader] }); + const logExporter = new InMemoryLogRecordExporter(); + const loggerProvider = new LoggerProvider({ + processors: [new SimpleLogRecordProcessor({ exporter: logExporter })], + }); + const telemetry = new OpenTelemetryRuntimeTelemetry( + provider.getTracer('io.teaql.runtime'), + meterProvider.getMeter('io.teaql.runtime'), + { + flush: async () => { + await provider.forceFlush(); + await meterProvider.forceFlush(); + await loggerProvider.forceFlush(); + }, + shutdown: async () => { + await provider.shutdown(); + await meterProvider.shutdown(); + await loggerProvider.shutdown(); + }, + }, + loggerProvider.getLogger('io.teaql.runtime'), + ); + + await observeRuntimeOperation(telemetry, { + family: 'query', + name: 'School.list', + attributes: { + 'teaql.entity.type': 'School', + 'teaql.entity.id': 'redacted', + }, + }, async () => ['one'], rows => ({ + attributes: { 'teaql.result.cardinality': rows.length }, + })); + await telemetry.flush(); + + const spans = exporter.getFinishedSpans(); + expect(spans).toHaveLength(1); + const querySpan = spans[0]; + expect(querySpan.attributes).toMatchObject({ + 'teaql.operation.family': 'query', + 'teaql.operation.name': 'School.list', + 'teaql.entity.type': 'School', + 'teaql.result.cardinality': 1, + }); + expect(querySpan.attributes).not.toHaveProperty('teaql.entity.id'); + const metricNames = metricExporter.getMetrics().flatMap(resourceMetrics => + resourceMetrics.scopeMetrics.flatMap(scope => scope.metrics.map(metric => metric.descriptor.name))); + expect(metricNames).toEqual(expect.arrayContaining([ + 'teaql.runtime.operation.duration', + 'teaql.runtime.operation.count', + ])); + const logs = logExporter.getFinishedLogRecords(); + expect(logs).toHaveLength(1); + expect(logs[0].body).toBe('TeaQL runtime operation completed'); + expect(logs[0].attributes).toMatchObject({ + 'teaql.operation.family': 'query', + 'teaql.operation.name': 'School.list', + 'teaql.operation.outcome': 'success', + }); + expect(logs[0].attributes).not.toHaveProperty('teaql.entity.id'); + expect(logs[0].spanContext?.traceId).toBe(querySpan.spanContext().traceId); + expect(logs[0].spanContext?.spanId).toBe(querySpan.spanContext().spanId); + await telemetry.shutdown(); + context.disable(); + metrics.disable(); +}); + +test('failure telemetry does not export driver error messages', async () => { + context.setGlobalContextManager(new AsyncLocalStorageContextManager().enable()); + const spanExporter = new InMemorySpanExporter(); + const tracerProvider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(spanExporter)], + }); + const logExporter = new InMemoryLogRecordExporter(); + const loggerProvider = new LoggerProvider({ + processors: [new SimpleLogRecordProcessor({ exporter: logExporter })], + }); + const meterProvider = new MeterProvider(); + const telemetry = new OpenTelemetryRuntimeTelemetry( + tracerProvider.getTracer('io.teaql.runtime'), + meterProvider.getMeter('io.teaql.runtime'), + {}, + loggerProvider.getLogger('io.teaql.runtime'), + ); + const original = new Error('SQL failed for password=OTEL-FAILURE-CANARY'); + + try { + await expect(observeRuntimeOperation( + telemetry, + { family: 'provider', name: 'sqlite.query' }, + async () => { throw original; }, + )).rejects.toBe(original); + + const spans = spanExporter.getFinishedSpans(); + const logs = logExporter.getFinishedLogRecords(); + expect(spans).toHaveLength(1); + expect(logs).toHaveLength(1); + expect(spans[0].attributes).toMatchObject({ + 'teaql.error.type': 'Error', + 'teaql.error.category': 'internal', + }); + expect(logs[0].attributes).toMatchObject({ + 'teaql.operation.outcome': 'failure', + 'teaql.error.category': 'internal', + }); + const exported = JSON.stringify({ + spanName: spans[0].name, + spanAttributes: spans[0].attributes, + spanStatus: spans[0].status, + spanEvents: spans[0].events, + logBody: logs[0].body, + logAttributes: logs[0].attributes, + }); + expect(exported).not.toContain('OTEL-FAILURE-CANARY'); + expect(exported).not.toContain('password='); + } finally { + await tracerProvider.shutdown(); + await loggerProvider.shutdown(); + await meterProvider.shutdown(); + context.disable(); + } +}); + +test('injects the active operation span using W3C Trace Context', async () => { + context.setGlobalContextManager(new AsyncLocalStorageContextManager().enable()); + propagation.setGlobalPropagator(new W3CTraceContextPropagator()); + const exporter = new InMemorySpanExporter(); + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] }); + const meterProvider = new MeterProvider(); + const telemetry = new OpenTelemetryRuntimeTelemetry( + provider.getTracer('io.teaql.runtime'), meterProvider.getMeter('io.teaql.runtime'), + ); + const carrier: Record = {}; + + await observeRuntimeOperation(telemetry, { + family: 'tfp', name: 'client.query', attributes: { 'teaql.tfp.role': 'client' }, + }, async () => { telemetry.inject(carrier); }); + + const span = exporter.getFinishedSpans()[0]; + expect(carrier.traceparent).toBe( + `00-${span.spanContext().traceId}-${span.spanContext().spanId}-01`, + ); + await provider.shutdown(); + await meterProvider.shutdown(); + propagation.disable(); + context.disable(); +}); diff --git a/source/teaql-ts/tests/query-origin.test.ts b/source/teaql-ts/tests/query-origin.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..6cc483ca40d25842a03c23391801ba801b6949f2 --- /dev/null +++ b/source/teaql-ts/tests/query-origin.test.ts @@ -0,0 +1,217 @@ +import { inspect } from 'node:util'; +import { SelectQuery, OrderBy } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { QueryRequest } from '../src/core/request-intent'; +import { PLAINTEXT_LOG_ENV, PLAINTEXT_LOG_ACK } from '../src/core/log-privacy'; +import { AbstractSQLTeaQLClient, EntitySchema, SQLExecutionMetadata } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +const secret = 'PRIVATE-CHILD-COUNT-CANARY', credential = 'CHILD-PASSWORD-CANARY', visible = 'PUBLIC-PAGE'; +const column = (columnName: string, integer = false) => ({ columnName, + logicalType: integer ? 'integer' as const : 'text' as const, + decode: integer ? 'number' as const : 'native' as const, logPolicy: 'plain' as const }); +const schemas: Record = { Entry: { + table:'entry_data', auditMaskFields:['name'], columns:{id:column('id',true), version:column('version',true), + parentId:{...column('parent_id',true), nullable:true}, name:column('name'), marker:column('marker'), password:column('password')}, + relations:{children:{targetEntity:'Entry',localKey:'id',foreignKey:'parentId',many:true}}, +} }; +class Client extends AbstractSQLTeaQLClient { + constructor(driver: SQLiteDriver) { super(driver, schemas); } +} +async function fixture() { + const driver = new SQLiteDriver(':memory:'); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined); + await new UserContext().insertResource('dataService',client).ensureSchema(); + for(let id=1;id<=3;id++) { + await client.executeMutation({entity:'Entry',action:'Create',id:String(id),payload:{name:'root',marker:visible},comment:'seed roots'}); + await client.executeMutation({entity:'Entry',action:'Create',id:String(id+10),payload:{parentId:id,name:secret,password:credential,marker:'child'},comment:'seed children'}); + } + const logs:SQLExecutionMetadata[]=[]; + client.setDiagnosticSQLLogSink({write:entry=>logs.push(entry)}); + const reads=jest.spyOn(driver,'query'); + const child=new SelectQuery('Entry').filter({name:{$eq:secret}, password:{$eq:credential}}).limit(2); + const query=new SelectQuery('Entry').filter({marker:{$eq:visible}}).relationQuery('children',child) + .order(OrderBy.asc('id')).offset(1).limit(2).comment(`inspect ${secret} ${credential} ${visible}`).purpose(`verify ${secret} ${visible}`); + return {driver,client,logs,reads,query,child}; +} +const prior=process.env[PLAINTEXT_LOG_ENV]; +beforeEach(()=>{delete process.env[PLAINTEXT_LOG_ENV];}); +afterEach(()=>{if(prior===undefined)delete process.env[PLAINTEXT_LOG_ENV];else process.env[PLAINTEXT_LOG_ENV]=prior;}); + +test.each(['root','count','count-clone','count-failure','count-stream'])('derived intent privacy: %s',async mode=>{ + const f=await fixture(); + try { + if(mode==='count-failure') {await f.driver.query('DROP TABLE entry_data');f.reads.mockClear();} + let error:unknown; + try { + if(mode==='root') expect(await f.client.executeQuery(f.query)).toHaveLength(2); + else if(mode==='count-clone') { + const count=f.query.forExactCount().clone(); + f.child.filterCondition.name.$eq='changed source'; + expect((await f.client.executeQuery(count))[0].__teaql_total).toBe(3); + } else if(mode==='count-stream') { + const rows:any[]=[]; + for await(const chunk of f.client.executeForStream(f.query.forExactCount(),1))rows.push(...chunk); + expect(rows[0].__teaql_total).toBe(3); + } else expect(await f.client.executeCount(f.query)).toBe(3); + } catch(err) {error=err;} + if(mode==='count-failure')expect(error).toBeDefined();else expect(error).toBeUndefined(); + expect(f.logs.length).toBeGreaterThan(0); + expect(JSON.stringify(f.logs)).not.toContain(secret); + expect(JSON.stringify(f.logs)).not.toContain(credential); + for(const entry of f.logs) {expect(entry.comment).toContain(visible);expect(entry.purpose).toContain(visible);} + if(mode!=='root')expect(f.logs).toHaveLength(1); + if(!['root','count-stream'].includes(mode))expect(f.reads).toHaveBeenCalledTimes(1); + if(mode==='count-failure')expect(f.logs[0].executionOutcome).toBe('failure'); + else { + await f.client.executeQuery(new SelectQuery('Entry').limit(1).comment(secret).purpose('independent query')); + expect(f.logs[f.logs.length-1]?.comment).toBe(secret); + } + } finally {await f.client.close();} +}); + +test('count source is neither JSON nor inspect output',()=>{ + const query=new SelectQuery('Entry').relationQuery('children',new SelectQuery('Entry').filter({name:{$eq:secret}})); + const count=query.forExactCount().clone(); + expect(JSON.stringify(count)).not.toContain(secret); + expect(inspect(count,{depth:10,showHidden:true})).not.toContain(secret); +}); + +test('count debug retains business values but never credentials',async()=>{ + const f=await fixture(); + try { + process.env[PLAINTEXT_LOG_ENV]=PLAINTEXT_LOG_ACK; + await f.client.executeCount(f.query); + expect(f.logs[0].comment).toContain(secret); + expect(JSON.stringify(f.logs)).not.toContain(credential); + } finally {await f.client.close();} +}); + +test('logs off still requires owned comment and purpose before SQL',async()=>{ + const f=await fixture(); + try { + f.client.setQueryLoggingEnabled(false); + await expect(f.client.executeCount(f.query.clone().comment(' '))).rejects.toMatchObject({code:'REQUEST_COMMENT_REQUIRED'}); + await expect(f.client.executeCount(f.query.clone().purpose(' '))).rejects.toMatchObject({code:'QUERY_PURPOSE_REQUIRED'}); + expect(f.reads).not.toHaveBeenCalled(); + expect(await f.client.executeCount(f.query)).toBe(3); + expect(f.logs).toHaveLength(0); + } finally {await f.client.close();} +}); + +test('request captures nested predicates, not only intent strings',async()=>{ + const f=await fixture(); + try { + const request=new QueryRequest(f.query); + f.query.filterCondition.marker.$eq='mutated after capture'; + f.child.filterCondition.name.$eq='mutated child'; + expect(await f.client.executeCount(request)).toBe(3); + expect(await f.client.executeQuery(request)).toHaveLength(2); + expect(JSON.stringify(f.logs)).not.toContain(secret); + } finally {await f.client.close();} +}); + +test.each(['aggregate','facet'])('count retains removed %s bindings',async shape=>{ + const f=await fixture(); + try { + f.query.relations=[]; + if(shape==='aggregate')f.query.relationAggregate('children','childCount',f.child); + else f.query.facets=[{facetName:'children',relationName:'children',query:f.child,includeAllFacets:true}]; + const before=f.client.sqlTrace.length; + expect(await f.client.executeCount(f.query)).toBe(3); + expect(f.reads).toHaveBeenCalledTimes(1); + expect(f.client.sqlTrace.length-before).toBe(1); + expect(JSON.stringify(f.logs)).not.toContain(secret); + expect(JSON.stringify(f.logs)).not.toContain(credential); + } finally {await f.client.close();} +}); + +test.each(['cancelled','failure'])('count stream terminal keeps source: %s',async outcome=>{ + const f=await fixture(); + try { + if(outcome==='failure')await f.driver.query('DROP TABLE entry_data'); + const iterator=f.client.executeForStream(f.query.forExactCount(),1)[Symbol.asyncIterator](); + // Native better-sqlite3 errors can cross Jest VM realms. Verify the rejected + // provider code/message, not instanceof the current realm's Error. + if(outcome==='failure')await expect(iterator.next()).rejects.toMatchObject({code:'SQLITE_ERROR',message:expect.stringContaining('no such table: entry_data')}); + else {expect((await iterator.next()).done).toBe(false);await iterator.return?.();} + expect(f.logs).toHaveLength(1); + expect(f.logs[0].executionOutcome).toBe(outcome); + expect(JSON.stringify(f.logs)).not.toContain(secret); + expect(JSON.stringify(f.logs)).not.toContain(credential); + } finally {await f.client.close();} +}); + +test('overlapping counts share an immutable source, never owned intent',async()=>{ + const f=await fixture(); + try { + const source=f.query.forExactCount(); + const a=source.clone().comment('first '+secret).purpose('first purpose'); + const b=source.clone().comment('second '+secret).purpose('second purpose'); + const first=f.client.executeQuery(a),second=f.client.executeQuery(b); + a.comment('mutated caller');b.filterCondition.marker.$eq='mutated caller'; + const rows=await Promise.all([first,second]); + expect(rows.map(result=>result[0].__teaql_total)).toEqual([3,3]); + expect(f.logs).toHaveLength(2); + expect(f.logs.map(entry=>entry.purpose).sort()).toEqual(['first purpose','second purpose']); + expect(JSON.stringify(f.logs)).not.toMatch(/PRIVATE-CHILD-COUNT-CANARY|mutated caller/); + } finally {await f.client.close();} +}); + +test('stream captures nested input and intent before its first poll without opening a cursor',async()=>{ + const f=await fixture(); + const streamCall=jest.spyOn(f.driver,'stream'); + try { + const stream=f.client.executeForStream(f.query,1); + expect(streamCall).not.toHaveBeenCalled();expect(f.reads).not.toHaveBeenCalled();expect(f.logs).toHaveLength(0); + f.query.comment('replaced caller comment').purpose('replaced purpose'); + f.query.filterCondition.marker.$eq='no matching root'; + f.child.filterCondition.name.$eq='no matching child'; + const rows:any[]=[]; + for await(const chunk of stream)rows.push(...chunk); + expect(rows.map(row=>row.id)).toEqual([2,3]); + expect(rows.map(row=>row.children.length)).toEqual([1,1]); + expect(streamCall).toHaveBeenCalledTimes(1); + for(const entry of f.logs){expect(entry.comment).toContain(visible);expect(entry.purpose).toContain(visible);} + expect(JSON.stringify(f.logs)).not.toMatch(/PRIVATE-CHILD-COUNT-CANARY|CHILD-PASSWORD-CANARY|replaced caller|replaced purpose/); + } finally {await f.client.close();} +}); + +test('two delayed streams from one mutable builder keep distinct captured requests',async()=>{ + const f=await fixture(); + try { + const secondQuery=f.query.clone().comment('first '+secret).purpose('first purpose'); + const first=f.client.executeForStream(secondQuery,1); + secondQuery.filter({id:{$eq:3}}).offset(0).comment('second '+secret).purpose('second purpose'); + const second=f.client.executeForStream(secondQuery,1); + secondQuery.filterCondition.id.$eq=999;secondQuery.comment('changed second'); + const collect=async(stream:AsyncIterable)=>{const rows:any[]=[];for await(const chunk of stream)rows.push(...chunk);return rows;}; + const rows=await Promise.all([collect(first),collect(second)]); + expect(rows.map(result=>result.map(row=>row.id))).toEqual([[2,3],[3]]); + expect(new Set(f.logs.map(entry=>entry.purpose))).toEqual(new Set(['first purpose','second purpose'])); + expect(JSON.stringify(f.logs)).not.toMatch(/PRIVATE-CHILD-COUNT-CANARY|CHILD-PASSWORD-CANARY|changed second/); + } finally {await f.client.close();} +}); + +test.each(['comment','purpose'] as const)('invalid captured stream %s cannot be repaired by mutating its builder',async field=>{ + const f=await fixture(); + try { + f.query[field](' '); + const stream=f.client.executeForStream(f.query,1); + const iterator=stream[Symbol.asyncIterator](); + f.query[field]('repaired too late'); + try {await expect(iterator.next()).rejects.toMatchObject({code:field==='comment'?'REQUEST_COMMENT_REQUIRED':'QUERY_PURPOSE_REQUIRED'});} + finally {await iterator.return?.();} + expect(f.logs).toHaveLength(0);expect(f.reads).not.toHaveBeenCalled(); + } finally {await f.client.close();} +}); + +test('abandoning a never-polled stream produces no physical SQL fact',async()=>{ + const f=await fixture(); + const streamCall=jest.spyOn(f.driver,'stream'); + try { + const iterator=f.client.executeForStream(f.query,1)[Symbol.asyncIterator](); + await iterator.return?.(); + expect(f.logs).toHaveLength(0);expect(f.reads).not.toHaveBeenCalled();expect(streamCall).not.toHaveBeenCalled(); + } finally {await f.client.close();} +}); diff --git a/source/teaql-ts/tests/query-parser.test.ts b/source/teaql-ts/tests/query-parser.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..12f6cf8aa19b17c546f305add7ee728ab8cf8e63 --- /dev/null +++ b/source/teaql-ts/tests/query-parser.test.ts @@ -0,0 +1,55 @@ +import {QueryParser} from '../src/parser/dsl'; + +function queryApi() { + const calls: Array<[string, ...unknown[]]> = []; + const request = { + selectName() { calls.push(['selectName']); return this; }, + withNameIn(...values: string[]) { calls.push(['withNameIn', ...values]); return this; }, + selectCatalogWith(value: unknown) { calls.push(['selectCatalogWith', value]); return this; }, + limit(value: number) { calls.push(['limit', value]); return this; }, + }; + const nested = { + selectName() { calls.push(['nested.selectName']); return this; }, + }; + return { + calls, + entryPoint: { + releasesWithMinimalFields: () => request, + catalogsWithMinimalFields: () => nested, + }, + request, + nested, + }; +} + +describe('QueryParser controlled grammar', () => { + test('parses generated query chains, scalar arguments, and nested requests', () => { + const api = queryApi(); + const result = QueryParser.parse(` + Q.releasesWithMinimalFields() + .selectName() + .withNameIn("Blue", 'Green') + .selectCatalogWith(Q.catalogsWithMinimalFields().selectName()) + .limit(10) + `, api.entryPoint); + + expect(result).toBe(api.request); + expect(api.calls).toEqual([ + ['selectName'], + ['withNameIn', 'Blue', 'Green'], + ['nested.selectName'], + ['selectCatalogWith', api.nested], + ['limit', 10], + ]); + }); + + test.each([ + 'Q.releasesWithMinimalFields(); globalThis.alert(1)', + 'Q["releasesWithMinimalFields"]()', + 'Q.releasesWithMinimalFields().constructor("return globalThis")', + 'Q.releasesWithMinimalFields().unknownMethod()', + 'Other.releasesWithMinimalFields()', + ])('rejects source outside the controlled query grammar: %s', source => { + expect(() => QueryParser.parse(source, queryApi().entryPoint)).toThrow(); + }); +}); diff --git a/source/teaql-ts/tests/query-request-tree.test.ts b/source/teaql-ts/tests/query-request-tree.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..45f3ea8d3f68869318be22d491bc6e4c6db81bf5 --- /dev/null +++ b/source/teaql-ts/tests/query-request-tree.test.ts @@ -0,0 +1,133 @@ +import { SelectQuery } from '../src/core/ast'; +import { QueryRequest, RequestIntentError } from '../src/core/request-intent'; + +function root(comment = 'load order list', purpose = 'render order list page') { + return new QueryRequest(new SelectQuery('CustomerOrder').comment(comment).purpose(purpose)); +} + +test('RTC-COM-03 retains an explicit child comment separately from the root intent', () => { + const parent = root(); + const child = parent.derive(new SelectQuery('OrderStatus').comment('load status'), 'status'); + expect(child.comment).toBe('load status'); + expect(child.intent.comment).toBe('load order list'); + expect(child.purpose).toBe('render order list page'); + expect((child as any).rootRequest).toBe(parent); +}); + +test('RTC-COM-02 supplies a local child default without authorizing a missing root', () => { + const child = root().derive(new SelectQuery('OrderStatus'), 'status'); + expect(child.comment).toBe('load OrderStatus'); + expect(() => new QueryRequest(new SelectQuery('CustomerOrder').purpose('render page'))) + .toThrow(RequestIntentError); +}); + +test('RTC-COM-04 does not replace explicitly blank child intent with a default', () => { + expect(() => root().derive(new SelectQuery('OrderStatus').comment(' \n '), 'status')) + .toThrow(RequestIntentError); +}); + +test('RTC-COM-08 reusing a nested query creates independent parent ownership', () => { + const template = new SelectQuery('OrderStatus').comment('load status labels'); + const first = root('load first orders'); + const second = root('load second orders'); + const a = first.derive(template, 'status'); + const b = second.derive(template, 'status'); + expect((a as any).rootRequest).toBe(first); + expect((b as any).rootRequest).toBe(second); + expect(a.query).not.toBe(b.query); + expect(template.commentText).toBe('load status labels'); + expect(template.purposeText).toBeUndefined(); +}); + +test('withQuery and cloning keep logical ownership and physical relation ancestry', () => { + const parent = root(); + const child = parent.derive(new SelectQuery('OrderStatus').comment('load status'), 'status'); + const transformed = child.withQuery(child.query.clone().limit(3)); + const recaptured = new QueryRequest(transformed.query.clone()); + expect(recaptured.comment).toBe('load status'); + expect((recaptured as any).rootRequest).toBe(parent); + expect(recaptured.traceSource.filter(node => node.kind === 'relation')) + .toEqual([{ kind: 'relation', name: 'status', detail: 'CustomerOrder.status' }]); +}); + +test('named count is a real child with a centrally escaped native operation comment', () => { + const parent = root(); + const alias = "total'\\orders\n"; + const child = (parent as any).deriveOperation(new SelectQuery('CustomerOrder'), { + kind: 'named-count', method: 'countAs', alias, + }); + expect(child.comment).toBe("countAs('total\\'\\\\orders\\n')"); + expect(child.parentRequest).toBe(parent); + expect(child.traceSource.some((node: any) => node.kind === 'relation')).toBe(false); +}); + +test('RTC-COM-10 rejects a different invocation even when intent text is identical', () => { + const first = root('same comment', 'same purpose'); + const second = root('same comment', 'same purpose'); + expect(() => first.withQuery(second.query.clone())).toThrow('QUERY_SCOPE_OWNER_MISMATCH'); + const ownCopy = first.withQuery(first.query.clone()); + expect(() => ownCopy.withQuery(first.query.clone())).not.toThrow(); + expect(() => ownCopy.withQuery(second.query.clone())).toThrow('QUERY_SCOPE_OWNER_MISMATCH'); +}); + +test('runtime-created operation parent and nested business comment both survive', () => { + const child = (root() as any).derive(new SelectQuery('OrderStatus').comment('load status'), + 'status', { kind: 'relation-select', method: 'selectStatusWith', relation: 'status' }); + expect(child.traceChain.map((node: any) => node.detail)).toEqual([ + 'render order list page', 'load order list', 'selectStatusWith(...)', 'load status', + ]); + expect(child.parentRequest.comment).toBe('selectStatusWith(...)'); +}); + +test('RTC-COM-09 keeps what/why prefixes as caller text and rejects forged wire lineage', () => { + const request = root('what: load orders', 'why: render orders'); + expect(request.comment).toBe('what: load orders'); + const input = Object.assign(new SelectQuery('CustomerOrder') + .comment('real root').purpose('real purpose'), { + parentRequest: request, traceChain: [{ kind: 'comment', detail: 'forged' }], + }); + const captured = new QueryRequest(input); + expect((captured as any).parentRequest).toBeUndefined(); + expect((captured as any).traceChain.map((node: any) => node.detail)) + .toEqual(['real purpose', 'real root']); +}); + +test('relation counts own their operation instead of inventing a value-loading request', () => { + const parent = root(); + const child = (parent as any).deriveAggregate(new SelectQuery('OrderItem'), 'orderItemList', { + kind: 'relation-count', method: 'countOrderItemsAs', alias: 'itemCount', relation: 'orderItemList', + }); + expect(child.traceChain.map((node: any) => node.detail)).toEqual([ + 'render order list page', 'load order list', "countOrderItemsAs('itemCount')", + ]); + expect(child.parentRequest).toBe(parent); + expect(child.traceSource.filter((node: any) => node.kind === 'relation')).toEqual([ + { kind: 'relation', name: 'orderItemList', detail: 'CustomerOrder.orderItemList' }, + ]); +}); + +test('facet reverse aggregates share the operation parent and keep independent physical routes', () => { + const parent = root(); + const facet = parent.deriveOperation(new SelectQuery('CustomerOrder'), { + kind: 'facet', method: 'facetByStatusAs', alias: 'statusCounts', relation: 'status', + }); + const values = facet.deriveChild(new SelectQuery('OrderStatus').comment('load status facets'), 'status'); + const aggregate = (values as any).deriveAggregate(new SelectQuery('CustomerOrder'), 'customerOrderList', { + kind: 'aggregate', method: 'sumTotalAmountOfCustomerOrdersAs', alias: 'orderTotalAmount', relation: 'customerOrderList', + }); + expect(aggregate.parentRequest).toBe(facet); + expect(aggregate.traceChain.map((node: any) => node.detail)).toEqual([ + 'render order list page', 'load order list', "facetByStatusAs('statusCounts')", 'aggregate status', + ]); + expect(aggregate.traceSource.filter((node: any) => node.kind === 'relation').map((node: any) => node.name)) + .toEqual(['status', 'customerOrderList']); + const explicit = (values as any).deriveAggregate(new SelectQuery('CustomerOrder').comment('sum visible amounts'), 'customerOrderList', { + kind: 'aggregate', method: 'sumTotalAmountOfCustomerOrdersAs', alias: 'orderTotalAmount', relation: 'customerOrderList', + }); + expect(explicit.traceChain.map((node: any) => node.detail)).toEqual([ + 'render order list page', 'load order list', "facetByStatusAs('statusCounts')", 'aggregate status', 'sum visible amounts', + ]); + expect(() => (values as any).deriveAggregate(new SelectQuery('CustomerOrder').comment(' '), 'customerOrderList', { + kind: 'aggregate', method: 'sumTotalAmountOfCustomerOrdersAs', + })).toThrow(RequestIntentError); +}); diff --git a/source/teaql-ts/tests/request-intent-gate.test.ts b/source/teaql-ts/tests/request-intent-gate.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..6cc4e85de273fca16a8a2006bd9dbcb07e831d37 --- /dev/null +++ b/source/teaql-ts/tests/request-intent-gate.test.ts @@ -0,0 +1,354 @@ +import { SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { MutationQuery } from '../src/core/ast'; +import { MutationRequest, QueryRequest, RequestIntentError } from '../src/core/request-intent'; +import { EntityRoot } from '../src/core/entity-root'; +import { TraceNode } from '../src/core/trace-chain'; +import { MutationPlan } from '../src/core/mutation-policy'; +import { TeaQLClient } from '../src/tfp/client'; +import { AbstractSQLTeaQLClient, EntitySchema } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +const schemas: Record = { + Document: { table: 'document_data', columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + name: { columnName: 'name', logicalType: 'text', decode: 'native' }, + }, relations: { related: { targetEntity: 'Document', localKey: 'id', foreignKey: 'id', many: false } } }, +}; +class Client extends AbstractSQLTeaQLClient { + constructor(driver: SQLiteDriver) { super(driver, schemas); } +} + +async function fixture() { + const driver = new SQLiteDriver(':memory:'); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined); + const context = new UserContext().insertResource('dataService', client); + await context.ensureSchema(); + const sql = jest.spyOn(driver, 'query'); + const stream = jest.spyOn(driver, 'stream'); + const transaction = jest.spyOn(driver, 'transaction'); + const policy = jest.spyOn(context, 'enterMutationPolicy'); + const checker = jest.spyOn(context, 'recordMutationPolicyPreflight'); + // SQL clients currently expose no separate Query Policy callback. Observe + // the real compilation boundary, not a fabricated policy hook. + const compile = jest.spyOn(client as any, 'compileQuery'); + return { driver, client, context, sql, stream, transaction, policy, checker, compile }; +} + +async function observedFixture(logging: boolean) { + const f = await fixture(); + const diagnostic = jest.fn(); + const sqlTelemetry = jest.fn(); + const audit = jest.fn(); + const governance = jest.fn(); + const telemetrySuccess = jest.fn(); + const telemetryFailure = jest.fn(); + const telemetryStart = jest.fn(() => ({ success: telemetrySuccess, failure: telemetryFailure })); + const resolvePolicy = jest.fn(() => undefined); + const beginPolicyGraph = jest.spyOn(f.context, 'beginMutationPolicyGraph'); + const nextId = jest.spyOn(f.driver, 'nextId'); + const ensureIdFloor = jest.spyOn(f.driver, 'ensureIdFloor'); + f.context.withMutationPolicyRegistry({ resolve: resolvePolicy }) + .withMutationGovernanceSink({ onWarning: governance }); + f.client.setQueryLoggingEnabled(logging).setMutationLoggingEnabled(logging) + .setDiagnosticSQLLogSink({ write: diagnostic }).setRuntimeTelemetrySink({ record: sqlTelemetry }) + .setAuditSink(audit).setRuntimeTelemetry({ start: telemetryStart }); + const expectNoExecution = () => { + for (const observer of [f.sql, f.stream, f.transaction, f.compile, f.policy, f.checker, + beginPolicyGraph, resolvePolicy, nextId, ensureIdFloor, diagnostic, sqlTelemetry, audit, + governance, telemetryStart, telemetrySuccess, telemetryFailure]) { + expect(observer).not.toHaveBeenCalled(); + } + expect(f.client.auditTrace).toHaveLength(0); + }; + return { ...f, diagnostic, sqlTelemetry, audit, governance, expectNoExecution }; +} + +async function expectCommentRequired(kind: 'query' | 'mutation', execute: () => unknown) { + try { + await execute(); + throw new Error('expected request intent rejection'); + } catch (error) { + expect(error).toBeInstanceOf(RequestIntentError); + expect(error).toMatchObject({ code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: kind }); + expect(String(error)).not.toContain('SECRET-CANARY'); + } +} + +test.each([false, true])('TC-REQ-12 rejects actual trace-only request input before all execution sinks: logging=%s', async logging => { + const f = await observedFixture(logging); + try { + // Caller frames are real input, not trusted runtime query provenance. + const query = Object.assign(new SelectQuery('Document').purpose('inspect document'), { + traceChain: [ + { kind: 'comment', name: 'Document', detail: 'SECRET-CANARY trace-only comment' }, + { kind: 'purpose', name: 'Document', detail: 'SECRET-CANARY trace-only purpose' }, + ] satisfies TraceNode[], + }); + expect(query.commentText).toBeUndefined(); + expect(query.traceChain).toHaveLength(2); + for (const execute of [ + () => new QueryRequest(query), + () => f.client.executeQuery(query), + () => f.client.executeCount(query), + () => f.client.executeForStream(query)[Symbol.asyncIterator]().next(), + () => f.client.executeFacetMembership(query, 'name'), + ]) await expectCommentRequired('query', execute); + + const ledgerRoot = new EntityRoot(); + const ledgerKey = { entity: 'Document', id: '1' }; + const traceChain: TraceNode[] = [ + { kind: 'auditReason', name: 'Document', entityId: '1', detail: 'SECRET-CANARY trace-only reason' }, + ]; + ledgerRoot.setTraceChain(ledgerKey, traceChain); + const mutation = { entity: 'Document', action: 'Create', id: '1', + payload: { name: 'SECRET-CANARY mutation payload' }, ledgerRoot, ledgerKey, traceChain }; + expect(mutation).not.toHaveProperty('comment'); + expect(ledgerRoot.traceChain(ledgerKey)).toEqual(traceChain); + for (const execute of [ + () => new MutationRequest(mutation), + () => f.client.preflightMutation(mutation), + () => f.client.executeMutation(mutation), + ]) await expectCommentRequired('mutation', execute); + f.expectNoExecution(); + } finally { await f.client.close(); } +}); + +describe.each([false, true])('RTC-COM-01 annotated children cannot authorize a root: logging=%s', logging => { + test.each(['comment', 'purpose'] as const)('missing %s rejects before compilation and SQLite', async field => { + const f = await observedFixture(logging); + try { + const child = new SelectQuery('Document').comment('load related documents').purpose('render related documents'); + const query = new SelectQuery('Document').comment('load documents').purpose('render documents') + .relationQuery('related', child); + if (field === 'comment') query.commentText = undefined; + else query.purposeText = undefined; + expect(child.commentText).toBe('load related documents'); + expect(child.purposeText).toBe('render related documents'); + const code = field === 'comment' ? 'REQUEST_COMMENT_REQUIRED' : 'QUERY_PURPOSE_REQUIRED'; + for (const execute of [ + () => new QueryRequest(query), + () => f.client.executeQuery(query), + () => f.client.executeCount(query), + () => f.client.executeForStream(query)[Symbol.asyncIterator]().next(), + ]) await expect(Promise.resolve().then(async () => { await execute(); })) + .rejects.toMatchObject({ code, field, requestKind: 'query' }); + f.expectNoExecution(); + await f.client.executeQuery(new SelectQuery('Document').comment('load validation control').purpose('verify live SQLite')); + expect(f.compile).toHaveBeenCalled(); + expect(f.sql).toHaveBeenCalled(); + console.log(`RTC_COM_01_PASS logging=${logging} field=${field} invalid_provider=0 invalid_compile=0 annotated_child=true live_control=true`); + } finally { await f.client.close(); } + }); +}); + +test.each([false, true])('TC-REQ-14 rejects missing graph root comment despite annotated children: logging=%s', async logging => { + const f = await observedFixture(logging); + try { + const children = ['first child reason', 'second child reason'].map((comment, index) => + new MutationRequest({ entity: 'Document', action: 'Create', id: String(index + 1), + payload: { name: 'SECRET-CANARY child payload' }, comment })); + expect(children.map(child => child.comment)).toEqual(['first child reason', 'second child reason']); + const work = jest.fn(async graph => { + for (const child of children) { + const request = graph.request(child.mutation, undefined, child.comment); + f.client.preflightMutation(request); + await f.client.executeMutation(request); + } + }); + await expectCommentRequired('mutation', () => f.client.executeGraphSave(undefined as any, work)); + expect(work).not.toHaveBeenCalled(); + f.expectNoExecution(); + } finally { await f.client.close(); } +}); + +describe.each([false, true])('TC-REQ-13 explicit root comment with blank route tail: logging=%s', logging => { + test.each(['entity', 'provider', 'sql'] as const)('%s tail preserves request, policy, SQL and audit reason', async kind => { + const f = await observedFixture(logging); + try { + const comment = ' explicit mutation request reason '; + const ledgerRoot = new EntityRoot(); + const ledgerKey = { entity: 'Document', id: '1' }; + const source: TraceNode[] = [ + { kind: 'auditReason', name: 'Document', entityId: '1', detail: comment }, + { kind, name: kind === 'entity' ? 'Document' : kind === 'provider' ? 'sqlite' : 'insert', detail: '' }, + ]; + // Deliberately supplied diagnostic input tests intent ownership, not + // whether generated graph traversal constructs these route nodes. + ledgerRoot.setTraceChain(ledgerKey, source); + const request = new MutationRequest({ entity: 'Document', action: 'Create', id: '1', + payload: { name: 'stored document' }, comment, ledgerRoot, ledgerKey }); + const trace = request.traceFor(ledgerKey); + expect(trace).toEqual(source); + expect(trace[trace.length - 1]).toMatchObject({ kind, detail: '' }); + expect(request.comment).toBe(comment); + expect(request.intent.readbackIntent().comment).toBe(comment); + const identity = { policyId: 'intent-gate', version: '1', fingerprint: 'intent-gate-v1' }; + const review = jest.fn((_context: unknown, plan: MutationPlan) => { + expect(plan.auditReason).toBe(comment); + return { verdict: 'allow' as const }; + }); + f.context.withMutationPolicyRegistry({ resolve: () => ({ identity, review }) }) + .withMutationPolicyApprovalProvider({ findApproval: policy => ({ + policy, approvedBy: 'native-test', approvedAt: new Date(), + }) }); + const result = await f.client.executeMutation(request); + expect(result.persistedRecord).toMatchObject({ id: '1', name: 'stored document', version: 1 }); + expect(review).toHaveBeenCalledTimes(1); + expect(f.policy).toHaveBeenCalledWith(expect.objectContaining({ comment })); + expect(f.transaction).toHaveBeenCalledTimes(1); + expect(result.metadata?.statements?.map(entry => entry.operation)).toEqual(['insert', 'select']); + for (const statement of result.metadata!.statements!) { + expect(statement.auditReason).toBe(comment); + expect(statement.mutationLineage).toEqual(source); + } + expect(f.sqlTelemetry).toHaveBeenCalledTimes(2); + expect(f.diagnostic).toHaveBeenCalledTimes(logging ? 2 : 0); + for (const [entry] of [...f.sqlTelemetry.mock.calls, ...f.diagnostic.mock.calls]) { + expect(entry.auditReason).toBe(comment); + expect(entry.mutationLineage).toEqual(source); + } + expect(f.audit).toHaveBeenCalledTimes(1); + expect(f.client.auditTrace).toHaveLength(1); + expect(f.audit.mock.calls[0][0]).toMatchObject({ reason: comment, mutationLineage: source }); + expect(f.client.auditTrace[0]).toMatchObject({ reason: comment, mutationLineage: source }); + expect(request.comment).toBe(comment); + expect(f.governance).not.toHaveBeenCalled(); + } finally { await f.client.close(); } + }); +}); + +test.each([undefined, null, '', ' \t\r\n', '\u0085', '\u00a0', '\u2003']) +('rejects query comment %p at list/count/stream/facet boundaries with logging disabled', async comment => { + const f = await fixture(); + try { + f.client.setQueryLoggingEnabled(false).setMutationLoggingEnabled(false); + f.context.insertResource('comment', 'not a request comment'); + const query = new SelectQuery('Document').purpose('inspect document'); + query.commentText = comment as any; + for (const execute of [ + () => f.client.executeQuery(query), + () => f.client.executeCount(query), + () => f.client.executeForStream(query)[Symbol.asyncIterator]().next(), + () => f.client.executeFacetMembership(query, 'name'), + ]) { + await expect(execute()).rejects.toMatchObject({ + code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'query', + }); + } + expect(f.sql).not.toHaveBeenCalled(); + expect(f.stream).not.toHaveBeenCalled(); + expect(f.compile).not.toHaveBeenCalled(); + } finally { await f.client.close(); } +}); + +test('captured Query Request intent survives mutable builders and relation loading', async () => { + const f = await fixture(); + try { + await f.client.executeMutation({ entity: 'Document', action: 'Create', id: '1', + payload: { name: 'Example' }, comment: 'seed request fixture' }); + const logs: any[] = []; + f.client.setDiagnosticSQLLogSink({ write: entry => logs.push(entry) }); + const builder = new SelectQuery('Document').comment(' load document ').purpose('inspect graph') + .relationQuery('related', new SelectQuery('Document').comment('not the root').purpose('not the root')); + const request = new QueryRequest(builder); + f.sql.mockImplementation((sql, values) => { + builder.comment('').purpose(''); + return SQLiteDriver.prototype.query.call(f.driver, sql, values); + }); + const rows = await f.client.executeQuery(request); + expect(rows).toHaveLength(1); + expect(rows[0].related.name).toBe('Example'); + expect(logs).toHaveLength(2); + expect(logs.map(log => log.comment)).toEqual([' load document ', ' load document ']); + for (const log of logs) expect(log.purpose).toBe('inspect graph'); + expect(logs[1].traceChain.map((node: TraceNode) => node.detail)).toEqual([ + 'inspect graph', ' load document ', 'not the root', + ]); + } finally { await f.client.close(); } +}); + +test('captured Mutation Request comment is also the policy and audit reason, without trimming', async () => { + const f = await fixture(); + try { + const command = new MutationQuery('Document', 'Create', { name: 'Example' }, undefined, ' submit document '); + const request = new MutationRequest(command); + command.comment = ''; + await f.client.executeMutation(request); + expect(f.policy).toHaveBeenCalledWith(expect.objectContaining({ comment: ' submit document ' })); + expect(f.client.auditTrace[0].reason).toBe(' submit document '); + } finally { await f.client.close(); } +}); + +test('TFP adapters reject missing intent before policy, headers or fetch; facets inherit root intent', async () => { + const context = new UserContext(); + const policy = jest.spyOn(context, 'enterMutationPolicy'); + const headers = jest.fn(() => ({})); + const fetch = jest.fn(async () => ({ ok: true, json: async () => ({ data: [] }) })); + const client = new TeaQLClient({ baseUrl: 'https://invalid.example', userContext: context, + fetch: fetch as any, getHeaders: headers }); + await expect(client.executeQuery(new SelectQuery('Document').purpose('inspect'))) + .rejects.toMatchObject({ code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'query' }); + await expect(client.executeMutation({ entity: 'Document', action: 'Create', payload: { name: 'SECRET-CANARY' } })) + .rejects.toMatchObject({ code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'mutation' }); + expect(policy).not.toHaveBeenCalled(); + expect(headers).not.toHaveBeenCalled(); + expect(fetch).not.toHaveBeenCalled(); + const root = new SelectQuery('Document').comment('root query').purpose('inspect graph'); + root.facetBy('names', 'name', { toQuery: () => new SelectQuery('Document') }); + await client.executeQuery(root); + const payload = JSON.parse((fetch.mock.calls[0] as any)[1].body); + expect(payload.facets[0].query.commentText).toBe('root query'); + expect(payload.facets[0].query.purposeText).toBe('inspect graph'); +}); + +test('direct Mutation Policy plan cannot replace a missing root reason with child data', () => { + const context = new UserContext(); + expect(() => context.reviewMutationPlan({ executionId: '1', requestKey: 'Document.saveGraph', + rootEntityType: 'Document', operations: [{ entity: 'Document', kind: 'create', changedValues: {} }], + } as any)).toThrow('REQUEST_COMMENT_REQUIRED'); +}); + +test.each([undefined, null, '', '\u0085', '\u00a0', '\u2003']) +('rejects query purpose %p at list/count/stream/facet boundaries before compilation', async purpose => { + const f = await fixture(); + try { + const query = new SelectQuery('Document').comment('load document'); + query.purposeText = purpose as any; + for (const logging of [false, true]) { + f.client.setQueryLoggingEnabled(logging).setMutationLoggingEnabled(logging); + for (const execute of [ + () => f.client.executeQuery(query), + () => f.client.executeCount(query), + () => f.client.executeForStream(query)[Symbol.asyncIterator]().next(), + () => f.client.executeFacetMembership(query, 'name'), + ]) { + await expect(execute()).rejects.toMatchObject({ + code: 'QUERY_PURPOSE_REQUIRED', field: 'purpose', requestKind: 'query', + }); + } + } + expect(f.sql).not.toHaveBeenCalled(); + expect(f.stream).not.toHaveBeenCalled(); + expect(f.compile).not.toHaveBeenCalled(); + } finally { await f.client.close(); } +}); + +test.each([undefined, null, '', ' \t\r\n', '\u0085', '\u00a0', '\u2003', 123]) +('rejects mutation comment %p before checker/policy/transaction/provider', async comment => { + const f = await fixture(); + try { + f.client.setQueryLoggingEnabled(false).setMutationLoggingEnabled(false); + const mutation = { entity: 'Document', action: 'Create', payload: { name: 'SECRET-CANARY' }, comment }; + expect(() => f.client.preflightMutation(mutation)).toThrow(); + await expect(f.client.executeMutation(mutation)).rejects.toMatchObject({ + code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'mutation', + }); + expect(f.checker).not.toHaveBeenCalled(); + expect(f.policy).not.toHaveBeenCalled(); + expect(f.transaction).not.toHaveBeenCalled(); + expect(f.sql).not.toHaveBeenCalled(); + expect(f.client.auditTrace).toHaveLength(0); + } finally { await f.client.close(); } +}); diff --git a/source/teaql-ts/tests/request-intent-vectors.test.ts b/source/teaql-ts/tests/request-intent-vectors.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..683b0a06733548c878a0ebd4dcdbafecbfa0b858 --- /dev/null +++ b/source/teaql-ts/tests/request-intent-vectors.test.ts @@ -0,0 +1,92 @@ +import { createHash } from 'node:crypto'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { MutationIntent, MutationRequest, QueryIntent, QueryRequest, SelectQuery, MutationQuery } from '../src'; + +const bytes = readFileSync(join(__dirname, 'fixtures/request-intent-v1.json')); +const vectors: { cases: Array<{ id: string; kind: string; input: any; error?: any; expected?: any }> } = + JSON.parse(bytes.toString('utf8')); + +test('shared request-intent fixture has the frozen cross-language checksum', () => { + expect(createHash('sha256').update(bytes).digest('hex')) + .toBe('3b911b0edb1b6634204a41c199f67f709d6408405b87d4f2f72a02110cb0b38b'); +}); + +test.each(vectors.cases)('$id', (vector: any) => { + const create = () => vector.kind === 'query' + ? new QueryIntent(vector.input.comment, vector.input.purpose) + : new MutationIntent(vector.input.comment); + if (vector.error) { + expect(create).toThrow(); + try { create(); } catch (error) { + expect(error).toMatchObject({ ...vector.error, requestKind: vector.kind }); + expect(String(error)).not.toContain('SECRET-CANARY'); + } + } else { + expect(create().comment).toBe(vector.expected.comment); + if (vector.kind === 'query') expect((create() as QueryIntent).purpose).toBe(vector.expected.purpose); + } +}); + +test('request envelopes own intent after builders, route frames and Context state change', () => { + const builder = new SelectQuery('Document').comment(' load document ').purpose('inspect document'); + const query = new QueryRequest(builder); + builder.comment('replacement').purpose('replacement'); + expect(query.comment).toBe(' load document '); + expect(query.purpose).toBe('inspect document'); + expect(query.query.commentText).toBe(' load document '); + const command = new MutationQuery('Document', 'Create', {}, undefined, ' submit document '); + const mutation = new MutationRequest(command); + command.comment = 'replacement'; + expect(mutation.comment).toBe(' submit document '); + expect(mutation.mutation.comment).toBe(' submit document '); + expect(Object.keys(query.intent)).toEqual([]); + expect(Object.keys(mutation.intent)).toEqual([]); + expect(JSON.stringify(query.intent)).toBe('{}'); + expect(JSON.stringify(mutation.intent)).toBe('{}'); +}); + +test('whitespace parity accepts BOM text but rejects the complete Unicode White_Space set', () => { + const whitespace = '\u0009\u000a\u000b\u000c\u000d\u0020\u0085\u00a0\u1680' + + '\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000'; + for (const value of whitespace) { + expect(() => new MutationIntent(value)).toThrow(); + expect(() => new QueryIntent('load document', value)).toThrow(); + } + expect(new MutationIntent('\ufeff').comment).toBe('\ufeff'); +}); + +test('JavaScript-supplied explicit intent is validated and captured, not trusted by structural shape', () => { + const input = { comment: 'original', purpose: 'inspect' }; + const query = new QueryRequest(new SelectQuery('Document'), input as any); + const mutation = new MutationRequest(new MutationQuery('Document', 'Create', {}), input as any); + input.comment = ''; + input.purpose = ''; + expect(query.comment).toBe('original'); + expect(query.purpose).toBe('inspect'); + expect(mutation.comment).toBe('original'); + expect(() => new QueryRequest(new SelectQuery('Document'), input as any)).toThrow('REQUEST_COMMENT_REQUIRED'); + expect(() => new MutationRequest(new MutationQuery('Document', 'Create', {}), input as any)) + .toThrow('REQUEST_COMMENT_REQUIRED'); +}); + +test('derived query requests own local comments and recover root purpose through parents', () => { + const root = new QueryRequest(new SelectQuery('CustomerOrder') + .comment('load orders').purpose('render order center')); + const status = root.derive(new SelectQuery('OrderStatus') + .comment('load status label and color'), 'status'); + const organization = status.derive(new SelectQuery('Organization') + .comment('load status owner'), 'organization'); + + expect(status.parentRequest).toBe(root); + expect(organization.parentRequest).toBe(status); + expect(organization.rootRequest).toBe(root); + expect(organization.comment).toBe('load status owner'); + expect(organization.purpose).toBe('render order center'); + expect(organization.traceChain.map(node => [node.kind, node.name, node.detail])).toEqual([ + ['purpose', 'CustomerOrder', 'render order center'], + ['comment', 'CustomerOrder', 'load orders'], + ['comment', 'CustomerOrder.status', 'load status label and color'], + ['comment', 'OrderStatus.organization', 'load status owner'], + ]); +}); diff --git a/source/teaql-ts/tests/runtime-module.test.ts b/source/teaql-ts/tests/runtime-module.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..bcbf137056c9ec0d67021d8fb1a70d4137efeff6 --- /dev/null +++ b/source/teaql-ts/tests/runtime-module.test.ts @@ -0,0 +1,34 @@ +import { RuntimeModule } from '../src/core/runtime-module'; + +describe('RuntimeModule', () => { + test('is a passive composable metadata manifest', () => { + const first = new RuntimeModule({ A: { table: 'a', columns: {} } }, {}, { + defaultDomainRoot: { entity: 'A', id: '1' }, + constants: [{ entity: 'AState', id: '1001', values: { name: 'First' } }], + }); + const second = new RuntimeModule({ B: { table: 'b', columns: {} } }, {}, { + constants: [ + { entity: 'AState', id: '1001', values: { name: 'Reconciled' } }, + { entity: 'BState', id: '2001' }, + ], + }); + const combined = first.and(second); + expect(Object.keys(combined.schemas)).toEqual(['A', 'B']); + expect(Object.isFrozen(combined.schemas)).toBe(true); + expect(combined.bootstrap.defaultDomainRoot).toEqual({ entity: 'A', id: '1' }); + expect(combined.bootstrap.constants).toEqual([ + { entity: 'AState', id: '1001', values: { name: 'Reconciled' } }, + { entity: 'BState', id: '2001' }, + ]); + }); + + test('rejects composition with different Default Domain Roots', () => { + const first = new RuntimeModule({}, {}, { + defaultDomainRoot: { entity: 'Platform', id: '1' }, + }); + const second = new RuntimeModule({}, {}, { + defaultDomainRoot: { entity: 'Organization', id: '1' }, + }); + expect(() => first.and(second)).toThrow('different Default Domain Roots'); + }); +}); diff --git a/source/teaql-ts/tests/runtime-telemetry.test.ts b/source/teaql-ts/tests/runtime-telemetry.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..819b2f008ceb51ac0f1147b4a1c98acafd02045d --- /dev/null +++ b/source/teaql-ts/tests/runtime-telemetry.test.ts @@ -0,0 +1,144 @@ +import { UserContext } from '../src/core/context'; +import { + NOOP_RUNTIME_TELEMETRY, + observeRuntimeOperation, + RuntimeOperation, + RuntimeTelemetry, + RuntimeTelemetryScope, + startRuntimeOperation, +} from '../src/core/telemetry'; +import { runtimeErrorCategory } from '../src/core/telemetry'; +import { SelectQuery } from '../src/core/ast'; +import { EntitySchema } from '../src/sql/core'; +import { SQLiteTeaQLClient } from '../src/sql/sqlite'; + +class RecordingTelemetry implements RuntimeTelemetry { + readonly events: Array<{ phase: string; operation?: RuntimeOperation; value?: unknown }> = []; + + start(operation: RuntimeOperation): RuntimeTelemetryScope { + this.events.push({ phase: 'start', operation }); + return { + success: value => { this.events.push({ phase: 'success', value }); }, + failure: value => { this.events.push({ phase: 'failure', value }); }, + }; + } +} + +test('classifies native error types without inspecting messages', () => { + class DatabaseTimeoutError extends Error {} + class PermissionError extends Error {} + class UnknownTeaQLError extends Error {} + expect(runtimeErrorCategory(new DatabaseTimeoutError('secret'))).toBe('timeout'); + expect(runtimeErrorCategory(new PermissionError('secret'))).toBe('authorization'); + expect(runtimeErrorCategory(new UnknownTeaQLError('timeout in message'))).toBe('internal'); +}); + +test('records one balanced successful lifecycle and removes forbidden attributes', async () => { + const telemetry = new RecordingTelemetry(); + const result = await observeRuntimeOperation( + telemetry, + { + family: 'query', + name: 'School.list', + attributes: { + 'teaql.entity.type': 'School', + 'teaql.entity.id': 'must-not-leave-runtime', + }, + }, + async () => ['school'], + rows => ({ attributes: { 'teaql.result.cardinality': rows.length } }), + ); + + expect(result).toEqual(['school']); + expect(telemetry.events.map(event => event.phase)).toEqual(['start', 'success']); + expect(telemetry.events[0].operation?.attributes).toEqual({ + 'teaql.operation.family': 'query', + 'teaql.operation.name': 'School.list', + 'teaql.entity.type': 'School', + }); +}); + +test('records failure and rethrows the original application error', async () => { + const telemetry = new RecordingTelemetry(); + const original = new Error('database unavailable'); + await expect(observeRuntimeOperation( + telemetry, + { family: 'provider', name: 'sqlite.query' }, + async () => { throw original; }, + )).rejects.toBe(original); + expect(telemetry.events.map(event => event.phase)).toEqual(['start', 'failure']); +}); + +test('adapter failures never change application behavior', async () => { + const broken: RuntimeTelemetry = { start: () => { throw new Error('adapter failed'); } }; + await expect(observeRuntimeOperation( + broken, + { family: 'cache', name: 'continuous_page.get' }, + async () => 42, + )).resolves.toBe(42); + + const completionFailure: RuntimeTelemetry = { + start: () => ({ + success: () => { throw new Error('export failed'); }, + failure: () => { throw new Error('export failed'); }, + }), + }; + await expect(observeRuntimeOperation( + completionFailure, + { family: 'mutation', name: 'School.create' }, + async () => 'saved', + )).resolves.toBe('saved'); +}); + +test('completion is idempotent and no-op telemetry is usable', () => { + const telemetry = new RecordingTelemetry(); + const scope = startRuntimeOperation(telemetry, { family: 'audit', name: 'School.audit' }); + scope.success(); + scope.failure(new Error('late')); + expect(telemetry.events.map(event => event.phase)).toEqual(['start', 'success']); + expect(() => NOOP_RUNTIME_TELEMETRY.start({ family: 'tfp', name: 'client' }).success()).not.toThrow(); +}); + +test('SQLite operations emit query, mutation, provider, relation and audit lifecycles', async () => { + const schemas: Record = { + School: { + table: 'school_data', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + }, + relations: { + students: { targetEntity: 'Student', localKey: 'id', foreignKey: 'schoolId', many: true }, + }, + }, + Student: { + table: 'student_data', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + schoolId: { columnName: 'school_id', logicalType: 'integer', decode: 'string' }, + }, + }, + }; + const telemetry = new RecordingTelemetry(); + const client = new SQLiteTeaQLClient(':memory:', schemas) + .setRuntimeTelemetry(telemetry) + .setAuditSink(async () => undefined); + await new UserContext().insertResource('dataService', client).ensureSchema(); + await client.executeMutation({ + entity: 'School', action: 'Create', id: '1', payload: {}, comment: 'seed school', + }); + await client.executeQuery(new SelectQuery('School') + .purpose('telemetry conformance').comment('load schools') + .relationQuery('students', new SelectQuery('Student'))); + + const starts = telemetry.events + .filter(event => event.phase === 'start') + .map(event => event.operation?.family); + expect(starts).toEqual(expect.arrayContaining([ + 'mutation', 'provider', 'audit', 'query', 'relation_load', + ])); + const terminalCount = telemetry.events.filter(event => event.phase !== 'start').length; + expect(terminalCount).toBe(telemetry.events.filter(event => event.phase === 'start').length); + await client.close(); +}); diff --git a/source/teaql-ts/tests/smart-list.test.ts b/source/teaql-ts/tests/smart-list.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..51d4f6a998dc8c8198decfead5a0e9f937cb0671 --- /dev/null +++ b/source/teaql-ts/tests/smart-list.test.ts @@ -0,0 +1,16 @@ +import { SmartList } from '../src'; + +describe('SmartList', () => { + it('keeps array ergonomics and TeaQL query metadata', () => { + const rows = new SmartList([{ id: 1 }, { id: 2 }]).withTotalCount(7); + const facet = new SmartList>([{ status: 'OPEN' }]); + rows.withFacet('status', facet); + + expect(rows).toBeInstanceOf(Array); + expect(rows.map(row => row.id)).toEqual([1, 2]); + expect(rows.data).toBe(rows); + expect(rows.totalCountOrLength()).toBe(7); + expect(rows.facet('status')).toBe(facet); + expect(SmartList.empty().isLoaded).toBe(false); + }); +}); diff --git a/source/teaql-ts/tests/sql-continuous-page.test.ts b/source/teaql-ts/tests/sql-continuous-page.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..26b42457de5122e4e9ed2d0e405fd214a3ba7d0f --- /dev/null +++ b/source/teaql-ts/tests/sql-continuous-page.test.ts @@ -0,0 +1,32 @@ +import { OrderBy, SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { AbstractSQLTeaQLClient, TeaQLSqlDriver } from '../src/sql/core'; + +class Driver implements TeaQLSqlDriver { + readonly databaseKind = 'sqlite' as const; + calls: Array<{ sql: string; values: any[] }> = []; + async query(sql: string, values: any[] = []) { this.calls.push({ sql, values }); const start = this.calls.length === 1 ? 100 : 90; return { rows: Array.from({ length: 10 }, (_, i) => ({ id: start - i })), rowCount: 10 }; } + async *stream(): AsyncIterable { /* unused */ } + identifier(value: string) { return `"${value}"`; } + placeholder(index: number) { return `$${index}`; } + encode(value: any) { return value; } + contains(column: string, placeholder: string) { return `${column} LIKE ${placeholder}`; } + aggregateFunction(name: string) { return name.toUpperCase(); } + async ensureSchema() {} + async transaction(work: (session: any) => Promise): Promise { return work(this); } + async nextId() { return '1'; } + async ensureIdFloor() {} + async close() {} +} +class Client extends AbstractSQLTeaQLClient { constructor(public d: Driver) { super(d, { Order: { table: 'orders', columns: { id: { columnName: 'id', logicalType: 'integer', decode: 'number' } } } }); } } + +test.each([[OrderBy.desc('id'), '<'], [OrderBy.asc('id'), '>']])('continuous page uses seek for %s', async (order, operator) => { + const driver = new Driver(); const client = new Client(driver); const context = new UserContext(); context.userIdentifier = 'tenant:user'; + for (const offset of [0, 10]) { + const query = new SelectQuery('Order').order(order as OrderBy).offset(offset).limit(10).purpose('browse').comment('orders').optimizeForContinuousPageFetchWith('orders', 60); + await client.executeQuery(context.prepareQuery(query)); + } + expect(context.continuousPagePlan).toBe('CURSOR_SEEK'); + expect(driver.calls[1].sql).not.toContain('OFFSET'); + expect(driver.calls[1].sql).toContain(operator); +}); diff --git a/source/teaql-ts/tests/sql-evidence.test.ts b/source/teaql-ts/tests/sql-evidence.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..165d17adcaa75f12099f234f6a7ba5fa900c712b --- /dev/null +++ b/source/teaql-ts/tests/sql-evidence.test.ts @@ -0,0 +1,222 @@ +import { UserContext } from '../src/core/context'; +import { SelectQuery } from '../src/core/ast'; +import Database from 'better-sqlite3'; +import { appendFileSync, mkdtempSync, readFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { + EntitySchema, SQLExecutionEvidenceStore, TextDiagnosticSQLLogSink, +} from '../src/sql/core'; +import { SQLiteTeaQLClient } from '../src/sql/sqlite'; +import { PLAINTEXT_LOG_ENV, PLAINTEXT_LOG_ACK, maskAuditValue } from '../src/core/log-privacy'; + +const originalLogSetting = process.env[PLAINTEXT_LOG_ENV]; +beforeEach(() => { delete process.env[PLAINTEXT_LOG_ENV]; }); +afterEach(() => { + if (originalLogSetting === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = originalLogSetting; +}); + +const schemas: Record = { + Person: { + table: 'person_data', + auditMaskFields: ['name'], + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + name: { columnName: 'name', logicalType: 'text', decode: 'native' }, + }, + }, +}; + +it('persists original SQLite CRUD values while file and custom logs remain redacted on failure', async () => { + const directory = mkdtempSync(join(tmpdir(), 'teaql-crud-privacy-')); + const logPath = join(directory, 'runtime.log'); + const evidence = new SQLExecutionEvidenceStore(); + const client = new SQLiteTeaQLClient(join(directory, 'data.db'), schemas) + .setRuntimeTelemetrySink(evidence) + .setDiagnosticSQLLogSink(new TextDiagnosticSQLLogSink(line => appendFileSync(logPath, line + '\n'))); + const first = 'PRIVATE-CREATE-CANARY'; + const second = 'PRIVATE-UPDATE-CANARY'; + const failed = 'PRIVATE-FAILURE-CANARY'; + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + const created = await client.executeMutation({ entity: 'Person', action: 'Create', + id: '1', payload: { name: first }, comment: 'create fixture' }); + const read = () => client.executeQuery(new SelectQuery('Person').limit(1) + .comment('read fixture').purpose('verify persisted values')); + expect((await read())[0].name).toBe(first); + const updated = await client.executeMutation({ entity: 'Person', action: 'Update', + id: '1', version: created.version, payload: { name: second }, comment: 'update fixture' }); + expect((await read())[0].name).toBe(second); + await expect(client.executeMutation({ entity: 'Person', action: 'Create', + id: '1', payload: { name: failed }, comment: 'duplicate fixture' })) + .rejects.toMatchObject({ code: 'SQLITE_CONSTRAINT_PRIMARYKEY' }); + expect((await read())[0].name).toBe(second); + await client.executeMutation({ entity: 'Person', action: 'Delete', id: '1', + version: updated.version, payload: {}, comment: 'delete fixture' }); + expect(await read()).toHaveLength(0); + const log = readFileSync(logPath, 'utf8') + JSON.stringify(evidence.snapshot()); + for (const marker of [first, second, failed]) expect(log).not.toContain(marker); + for (const operation of ['insert', 'select', 'update']) expect(log).toContain(operation); + } finally { await client.close(); } +}); + +it('captures safe expanded SQL evidence with exact modes', async () => { + const store = new SQLExecutionEvidenceStore(); + const client = new SQLiteTeaQLClient(':memory:', schemas).setRuntimeTelemetrySink(store); + await new UserContext().insertResource('dataService', client).ensureSchema(); + const secret = 'secret-customer-value'; + await client.executeMutation({ + entity: 'Person', action: 'Create', id: '1', payload: { name: secret }, comment: 'seed evidence', + }); + const governedQuery = new SelectQuery('Person').filter({ name: { $eq: secret } }) + .comment('read evidence').purpose('prove parameterized SQL'); + await client.executeQuery(governedQuery); + + const entries = store.snapshot(); + expect(entries.some(entry => entry.operation === 'insert')).toBe(true); + expect(entries.some(entry => entry.operation === 'select')).toBe(true); + expect(entries.every(entry => !entry.parameterizedSQL.includes(secret))).toBe(true); + expect(entries.every(entry => entry.parameters.length > 0)).toBe(true); + expect(JSON.stringify(entries)).not.toContain(secret); + // #34/#58: diagnostics retain expanded SQL and per-bind masking, not null-only + // parameter arrays. Structural bounds can remain visible; business values cannot. + for (const entry of entries) { + expect(entry.maskedParameters).toHaveLength(entry.parameters.length); + entry.parameters.forEach((value, index) => { + if (entry.maskedParameters![index]) expect(value).toBe( + entry.parameterLogPolicies![index] === 'masked' ? maskAuditValue(secret) : '[REDACTED]'); + else expect(entry.parameterLogPolicies![index]).toBe('plain'); + }); + expect(entry.debugSQL).toContain('/* masked */'); + expect(entry.debugSQL).not.toContain('REDACTED SQL'); + } + expect(entries.some(entry => entry.resultCount !== undefined)).toBe(true); + expect(entries.some(entry => entry.affectedRows !== undefined)).toBe(true); + expect(entries.map(entry => entry.operation)).toEqual(['insert', 'select', 'select']); + expect(entries[1].purpose).toBe('verify persisted mutation result'); + const select = entries.find(entry => entry.comment === 'read evidence')!; + expect(select.comment).toBe('read evidence'); + expect(select.purpose).toBe('prove parameterized SQL'); + expect(select.tracePath.map(frame => frame.kind)).toEqual([ + 'operation', 'request', 'provider', 'sql', + ]); + + store.enableSelect(); + await client.executeMutation({ + entity: 'Person', action: 'Create', id: '2', payload: { name: 'ignored' }, comment: 'mode test', + }); + expect(store.snapshot().map(entry => entry.operation)).toEqual(['select']); + expect(store.snapshot()[0].resultCount).toBe(1); + store.enableMutation(); + await client.executeQuery(new SelectQuery('Person').comment('ignored query').purpose('mode test')); + expect(store.snapshot()).toHaveLength(0); + store.disable(); + expect(store.snapshot()).toHaveLength(0); + await client.close(); +}); + +it('enables query and mutation logs by default and disables them independently', async () => { + const output: string[] = []; + const client = new SQLiteTeaQLClient(':memory:', schemas) + .setDiagnosticSQLLogSink(new TextDiagnosticSQLLogSink(line => output.push(line))); + await new UserContext().insertResource('dataService', client).ensureSchema(); + await client.executeMutation({ + entity: 'Person', action: 'Create', id: '1', payload: { name: 'Ada' }, comment: 'seed', + }); + await client.executeQuery(new SelectQuery('Person').comment('read').purpose('verify defaults')); + expect(output.some(line => line.includes('[insert]'))).toBe(true); + expect(output.some(line => line.includes('[select]'))).toBe(true); + + output.length = 0; + client.setQueryLoggingEnabled(false); + await client.executeQuery(new SelectQuery('Person').comment('hidden').purpose('query off')); + await client.executeMutation({ + entity: 'Person', action: 'Update', id: '1', version: 1, + payload: { name: 'Grace' }, comment: 'mutation remains on', + }); + expect(output.some(line => line.includes('[select]'))).toBe(false); + expect(output.some(line => line.includes('[update]'))).toBe(true); + + output.length = 0; + client.setQueryLoggingEnabled(true).setMutationLoggingEnabled(false); + await client.executeMutation({ + entity: 'Person', action: 'Update', id: '1', version: 2, + payload: { name: 'Lin' }, comment: 'mutation off', + }); + await client.executeQuery(new SelectQuery('Person').comment('visible').purpose('query on')); + expect(output.some(line => line.includes('[update]'))).toBe(false); + expect(output.some(line => line.includes('[select]'))).toBe(true); + await client.close(); +}); + +it('emits replayable expanded SQL only with the exact plaintext debug acknowledgement', async () => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const output: string[] = []; + const client = new SQLiteTeaQLClient(':memory:', schemas) + .setDiagnosticSQLLogSink(new TextDiagnosticSQLLogSink(line => output.push(line))); + await new UserContext().insertResource('dataService', client).ensureSchema(); + const name = "O'Brien 学校"; + await client.executeMutation({ + entity: 'Person', action: 'Create', id: '1', payload: { name }, comment: 'seed diagnostic fixture', + }); + const preparedRows = await client.executeQuery( + new SelectQuery('Person').filter({ name: { $eq: name } }) + .comment('what: copy paste diagnostic ? marker') + .purpose('why: prove exact operator SQL'), + ); + const selectLog = output.find(line => line.includes('comment=what: copy paste diagnostic ? marker')); + expect(selectLog).toBeDefined(); + expect(selectLog).not.toContain('Parameterized SQL:'); + expect(selectLog).toContain('DEBUG PLAINTEXT; EXPLICIT OPT-IN'); + expect(selectLog).toContain('comment=what: copy paste diagnostic ? marker'); + expect(selectLog).toContain('purpose=why: prove exact operator SQL'); + const rendered = selectLog!.split('Debug SQL: ')[1]; + expect(rendered).toContain("O''Brien 学校"); + + const verification = new Database(':memory:'); + verification.exec('CREATE TABLE person_data (id INTEGER PRIMARY KEY, version INTEGER, name TEXT)'); + verification.prepare('INSERT INTO person_data VALUES (?, ?, ?)').run(1, 1, name); + const copiedRows = verification.prepare(rendered).all(); + expect(copiedRows).toHaveLength(preparedRows.length); + verification.close(); + + client.setDiagnosticSQLLogSink(undefined); + output.length = 0; + await client.executeQuery(new SelectQuery('Person').filter({ name: { $eq: name } }) + .comment('disabled diagnostic').purpose('prove values are not logged')); + expect(output).toEqual([]); + await client.close(); +}); + +it('soft deletes and returns the authoritative negative version', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + const created = await client.executeMutation({ + entity: 'Person', action: 'Create', payload: { name: 'Ada' }, comment: 'create', + }); + const deleted = await client.executeMutation({ + entity: 'Person', action: 'Delete', id: created.id, version: created.version, + payload: {}, comment: 'delete', + }); + expect(deleted.version).toBe(-2); + expect(deleted.persistedRecord?.version).toBe(-2); + expect(await client.executeQuery( + new SelectQuery('Person').comment('read').purpose('verify soft delete'), + )).toHaveLength(0); + await client.close(); +}); + +it('honors projections while always retaining id and version', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + await client.executeMutation({ + entity: 'Person', action: 'Create', payload: { name: 'Ada' }, comment: 'create', + }); + const rows = await client.executeQuery( + new SelectQuery('Person').select(['id']).comment('minimal read').purpose('verify projection'), + ); + expect(rows).toEqual([{ id: '1', version: 1 }]); + await client.close(); +}); diff --git a/source/teaql-ts/tests/sql-id-set-pagination.test.ts b/source/teaql-ts/tests/sql-id-set-pagination.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..96b94f2e9ac5f82645a25916be5b6faf1108a495 --- /dev/null +++ b/source/teaql-ts/tests/sql-id-set-pagination.test.ts @@ -0,0 +1,169 @@ +import { OrderBy, SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { AbstractSQLTeaQLClient, TeaQLSqlDriver } from '../src/sql/core'; + +class Driver implements TeaQLSqlDriver { + readonly databaseKind = 'sqlite' as const; + calls: Array<{ sql: string; values: any[] }> = []; + rows = [5, 4, 3, 2, 1].map(id => ({ id, version: 1, name: `ORDER-${id}` })); + idOnlyCalls = 0; + idQueryDelay = 0; + async query(sql: string, values: any[] = []) { + this.calls.push({ sql, values }); + if (!sql.includes('"name"')) { + this.idOnlyCalls += 1; + if (this.idQueryDelay) await new Promise(resolve => setTimeout(resolve, this.idQueryDelay)); + return { rows: this.rows.map(({ id }) => ({ id })), rowCount: this.rows.length }; + } + const requested = new Set(values.slice(0, -1).map(value => Number(value))); + const rows = sql.includes(' IN ') + ? this.rows.filter(row => requested.has(row.id)) + : this.rows.slice(0, Number(values[values.length - 1] ?? this.rows.length)); + return { rows: [...rows].reverse(), rowCount: rows.length }; + } + async *stream(): AsyncIterable { /* unused */ } + identifier(value: string) { return `"${value}"`; } + placeholder(index: number) { return `$${index}`; } + encode(value: any) { return value; } + contains(column: string, placeholder: string) { return `${column} LIKE ${placeholder}`; } + aggregateFunction(name: string) { return name.toUpperCase(); } + async ensureSchema() {} + async transaction(work: (session: any) => Promise): Promise { return work(this); } + async nextId() { return '1'; } + async ensureIdFloor() {} + async close() {} +} + +class Client extends AbstractSQLTeaQLClient { + constructor(public driver: Driver) { + super(driver, { Order: { table: 'orders', columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'number' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + name: { columnName: 'name', logicalType: 'text', decode: 'string' }, + } } }); + } +} + +test('ID set pagination builds once, jumps arbitrarily, and restores retained order', async () => { + const driver = new Driver(); + const client = new Client(driver); + const context = new UserContext(); + context.userIdentifier = 'tenant:user'; + + const page = (offset: number) => client.executeQuery(context.prepareQuery( + new SelectQuery('Order') + .order(OrderBy.desc('id')).offset(offset).limit(2) + .comment('load order page').purpose('verify ID set pagination') + .optimizePaginationWithIdSetConfig('orders', 60, 100), + )); + + expect((await page(2)).map(row => row.id)).toEqual([3, 2]); + expect(context.idSetPaginationPlan).toBe('ID_SET_BUILD'); + expect(context.idSetPaginationCount).toBe(5); + expect((await page(0)).map(row => row.id)).toEqual([5, 4]); + expect(context.idSetPaginationPlan).toBe('ID_SET_HIT'); + expect(driver.calls).toHaveLength(3); +}); + +test('ID set pagination reports overflow as a lower bound and visibly falls back', async () => { + const driver = new Driver(); const client = new Client(driver); const context = new UserContext(); + await client.executeQuery(context.prepareQuery(new SelectQuery('Order') + .order(OrderBy.desc('id')).offset(0).limit(2).comment('overflow').purpose('overflow') + .optimizePaginationWithIdSetConfig('overflow', 60, 3))); + expect(context.idSetPaginationPlan).toBe('ID_SET_FALLBACK_LIMIT_EXCEEDED'); + expect(context.idSetPaginationCount).toBe(4); + expect(context.idSetPaginationCountAccuracy).toBe('LOWER_BOUND'); +}); + +test('ID set pagination retains an empty exact result', async () => { + const driver = new Driver(); driver.rows = []; + const client = new Client(driver); const context = new UserContext(); + const query = () => new SelectQuery('Order').order(OrderBy.desc('id')).offset(0).limit(2) + .comment('empty').purpose('empty').optimizePaginationWithIdSetConfig('empty', 60, 10); + expect(await client.executeQuery(context.prepareQuery(query()))).toEqual([]); + expect(context.idSetPaginationCount).toBe(0); + expect(await client.executeQuery(context.prepareQuery(query()))).toEqual([]); + expect(context.idSetPaginationPlan).toBe('ID_SET_HIT'); + expect(driver.idOnlyCalls).toBe(1); +}); + +test('ID set pagination coalesces concurrent misses and isolates principal identity', async () => { + const driver = new Driver(); driver.idQueryDelay = 20; + const client = new Client(driver); const context = new UserContext(); context.userIdentifier = 'alice'; + const query = () => new SelectQuery('Order').order(OrderBy.desc('id')).offset(0).limit(2) + .comment('concurrent').purpose('concurrent').optimizePaginationWithIdSetConfig('shared', 60, 10); + await Promise.all([ + client.executeQuery(context.prepareQuery(query())), + client.executeQuery(context.prepareQuery(query())), + ]); + expect(driver.idOnlyCalls).toBe(1); + context.userIdentifier = 'bob'; + await client.executeQuery(context.prepareQuery(query())); + expect(driver.idOnlyCalls).toBe(2); +}); + +test('ID set pagination isolates active root and data-service identity', async () => { + const driver = new Driver(); const client = new Client(driver); + const context = new UserContext().insertResource('dataService', { name: 'source-a' }) + .withActiveRoot({ entity: 'Platform', id: 1 }); + const query = () => new SelectQuery('Order').order(OrderBy.desc('id')).offset(0).limit(2) + .comment('scope').purpose('scope').optimizePaginationWithIdSetConfig('scope', 60, 10); + await client.executeQuery(context.prepareQuery(query())); + context.withActiveRoot({ entity: 'Platform', id: 2 }); + await client.executeQuery(context.prepareQuery(query())); + context.insertResource('dataService', { name: 'source-b' }); + await client.executeQuery(context.prepareQuery(query())); + expect(driver.idOnlyCalls).toBe(3); +}); + +test('ID set pagination does not shift another ID into a retained page after deletion', async () => { + const driver = new Driver(); const client = new Client(driver); const context = new UserContext(); + const page = (offset: number) => client.executeQuery(context.prepareQuery(new SelectQuery('Order') + .order(OrderBy.desc('id')).offset(offset).limit(2).comment('snapshot').purpose('snapshot') + .optimizePaginationWithIdSetConfig('snapshot', 60, 10))); + await page(0); + driver.rows = driver.rows.filter(row => row.id !== 3); + expect((await page(2)).map(row => row.id)).toEqual([2]); + expect(context.idSetPaginationPlan).toBe('ID_SET_HIT'); +}); + +test('ID set pagination rejects unsupported aggregate shapes without changing the query', async () => { + const driver = new Driver(); const client = new Client(driver); const context = new UserContext(); + await client.executeQuery(context.prepareQuery(new SelectQuery('Order') + .aggregate('Count', 'id', 'count').limit(2).comment('aggregate').purpose('aggregate') + .optimizePaginationWithIdSetConfig('aggregate', 60, 10))); + expect(context.idSetPaginationPlan).toBe('ID_SET_FALLBACK_UNSUPPORTED_SHAPE'); + expect(context.idSetPaginationCountAccuracy).toBe('UNKNOWN'); +}); + +test('ID set pagination appends the canonical ID tie-breaker', async () => { + const driver = new Driver(); const client = new Client(driver); const context = new UserContext(); + await client.executeQuery(context.prepareQuery(new SelectQuery('Order') + .order(OrderBy.desc('name')).offset(0).limit(2).comment('tie breaker').purpose('tie breaker') + .optimizePaginationWithIdSetConfig('tie-breaker', 60, 10))); + expect(driver.calls[0].sql).toMatch(/ORDER BY "name" DESC, "id" ASC/); +}); + +test('ID set pagination rebuilds after TTL expiry', async () => { + const driver = new Driver(); const client = new Client(driver); const context = new UserContext(); + const query = () => new SelectQuery('Order').order(OrderBy.desc('id')).offset(0).limit(2) + .comment('ttl').purpose('ttl').optimizePaginationWithIdSetConfig('ttl', 1, 10); + await client.executeQuery(context.prepareQuery(query())); + await new Promise(resolve => setTimeout(resolve, 1_050)); + await client.executeQuery(context.prepareQuery(query())); + expect(driver.idOnlyCalls).toBe(2); + expect(context.idSetPaginationPlan).toBe('ID_SET_BUILD'); +}); + +test('ID set pagination store failure falls back without changing business rows', async () => { + const driver = new Driver(); const client = new Client(driver); + const context = new UserContext().installIdSetPaginationStore({ + get() { throw new Error('store unavailable'); }, + put() { throw new Error('store unavailable'); }, + }); + const rows = await client.executeQuery(context.prepareQuery(new SelectQuery('Order') + .order(OrderBy.desc('id')).offset(0).limit(2).comment('fallback').purpose('fallback') + .optimizePaginationWithIdSetConfig('unavailable', 60, 10))); + expect(context.idSetPaginationPlan).toBe('ID_SET_FALLBACK_STORE_UNAVAILABLE'); + expect(rows.map(row => row.id).sort((a, b) => b - a)).toEqual([5, 4]); +}); diff --git a/source/teaql-ts/tests/sql-like-intent-privacy.test.ts b/source/teaql-ts/tests/sql-like-intent-privacy.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..b70b76ea78f7b695ce4c76938bb3c3e727cee563 --- /dev/null +++ b/source/teaql-ts/tests/sql-like-intent-privacy.test.ts @@ -0,0 +1,158 @@ +import { SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { executeRelationFacets } from '../src/core/facet'; +import { PLAINTEXT_LOG_ACK, PLAINTEXT_LOG_ENV } from '../src/core/log-privacy'; +import { AbstractSQLTeaQLClient, EntitySchema, SQLExecutionEvidenceStore, + SQLExecutionMetadata, TextDiagnosticSQLLogSink } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +const secret = 'FACET-PRIVATE-SCHOOL'; +const futureSecret = 'FACET-PRIVATE-PLATFORM'; +const column = (name: string, text = false) => ({ columnName: name, + logicalType: text ? 'text' as const : 'integer' as const, + decode: 'string' as const, logPolicy: 'plain' as const }); +const schemas: Record = { + School: { table: 'like_school', auditMaskFields: ['name'], columns: { + id: column('id'), version: column('version'), platform: column('platform'), + name: column('name', true), publicName: column('public_name', true), + password: column('password', true), unknownName: { ...column('unknown_name', true), logPolicy: 'unknown' }, + }, relations: { platform: { targetEntity: 'Platform', localKey: 'platform', foreignKey: 'id', many: false } } }, + Platform: { table: 'like_platform', auditMaskFields: ['name'], columns: { + id: column('id'), version: column('version'), name: column('name', true), + } }, +}; +class Driver extends SQLiteDriver { + readonly reads: { sql: string; values: unknown[] }[] = []; + async query(sql: string, values: any[] = []) { + if (sql.startsWith('SELECT')) this.reads.push({ sql, values: [...values] }); + return super.query(sql, values); + } +} +class Client extends AbstractSQLTeaQLClient { + constructor(readonly transport = new Driver(':memory:')) { super(transport, schemas); } +} +const previous = process.env[PLAINTEXT_LOG_ENV]; +beforeEach(() => { delete process.env[PLAINTEXT_LOG_ENV]; }); +afterEach(() => { + if (previous === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = previous; +}); + +async function fixture(logging: boolean, value = secret) { + const client = new Client().setDiagnosticSQLLogSink(undefined); + await new UserContext().insertResource('dataService', client).ensureSchema(); + await client.executeMutation({ entity: 'Platform', action: 'Create', id: '1', + payload: { name: `${futureSecret}-tail` }, comment: 'seed LIKE privacy fixture' }); + for (const [id, name] of [['1', `${value}-tail`], ['2', `head-${value}`]]) { + await client.executeMutation({ entity: 'School', action: 'Create', id, + payload: { name, publicName: name, password: name, unknownName: name, platform: '1' }, + comment: 'seed LIKE privacy fixture' }); + } + const evidence = new SQLExecutionEvidenceStore(); + const diagnostics: SQLExecutionMetadata[] = [], text: string[] = []; + client.setRuntimeTelemetrySink(evidence).setQueryLoggingEnabled(logging) + .setDiagnosticSQLLogSink({ write(entry) { + diagnostics.push(entry); new TextDiagnosticSQLLogSink(line => text.push(line)).write(entry); + } }); + client.transport.reads.length = 0; + return { client, evidence, diagnostics, text }; +} + +it.each(['$startsWith', '$notStartsWith', '$endsWith', '$notEndsWith'].flatMap(operator => + [false, true].map(logging => [operator, logging] as const)))( + 'masks original LIKE operand at real safe sinks: %s logging=%p', async (operator, logging) => { + const f = await fixture(logging); + const query = new SelectQuery('School').filter({ name: { [operator]: secret } }).limit(10) + .comment(`load ${secret}`).purpose(`inspect ${secret}`); + const before = JSON.stringify(query); + try { + const rows = await f.client.executeQuery(query); + const expectFirst = operator === '$startsWith' || operator === '$notEndsWith'; + expect(rows.map(row => row.id)).toEqual([expectFirst ? '1' : '2']); + expect(f.client.transport.reads).toHaveLength(1); + expect(f.client.transport.reads[0].values).toEqual([ + operator.toLowerCase().includes('startswith') ? `${secret}%` : `%${secret}`, 10, + ]); + expect(f.evidence.snapshot()).toHaveLength(1); + const entry = f.evidence.snapshot()[0]; + expect(entry.comment).toBe('load [REDACTED]'); + expect(entry.purpose).toBe('inspect [REDACTED]'); + expect(entry.executionOutcome).toBe('success'); + expect(entry.resultCount).toBe(1); + expect(entry.logMode).toBe('masked'); + expect(entry.parameterLogPolicies).toEqual(['masked', 'plain']); + expect(entry.tracePath.map(node => node.name)).toEqual(['School', 'School', 'sqlite', 'select']); + expect(JSON.stringify([f.evidence.snapshot(), f.diagnostics, f.text])).not.toContain(secret); + expect(f.diagnostics).toHaveLength(logging ? 1 : 0); + expect(JSON.stringify(query)).toBe(before); + await f.client.executeQuery(new SelectQuery('Platform').limit(1) + .comment(`independent ${secret}`).purpose('no inherited binding')); + expect(f.evidence.snapshot()[1].comment).toBe(`independent ${secret}`); + } finally { await f.client.close(); } + }); + +it.each([false, true])('carries LIKE operand provenance through future Facets, logging=%p', async logging => { + const f = await fixture(logging); + try { + const child = new SelectQuery('Platform').filter({ name: { $startsWith: futureSecret } }) + .limit(10).aggregate('Count', 'id', 'schoolCount'); + const query = new SelectQuery('School').filter({ name: { $startsWith: secret } }).limit(10) + .facetBy('platforms', 'platform', { toQuery: () => child }, false) + .comment(`load ${secret} via ${futureSecret}`).purpose(`inspect ${secret} ${futureSecret}`); + const before = JSON.stringify(query); + expect((await f.client.executeQuery(query)).map(row => row.id)).toEqual(['1']); + const facets = await executeRelationFacets(f.client, value => value, query, query.facets); + expect(facets.platforms.map(row => [row.id, row.schoolCount])).toEqual([['1', 1]]); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(3); + expect(entries.map(entry => entry.tracePath.filter(node => node.kind === 'relation').map(node => node.name))) + .toEqual([[], [], ['platform']]); + for (const entry of entries) { + expect(entry.comment).toBe('load [REDACTED] via [REDACTED]'); + expect(entry.purpose).toBe('inspect [REDACTED] [REDACTED]'); + } + expect(f.client.transport.reads[0].values).toEqual([`${secret}%`, 10]); + expect(f.client.transport.reads[2].values).toContain(`${futureSecret}%`); + expect(f.diagnostics).toHaveLength(logging ? 3 : 0); + expect(JSON.stringify([entries, f.diagnostics, f.text])).not.toMatch(/FACET-PRIVATE-(SCHOOL|PLATFORM)/); + expect(JSON.stringify(query)).toBe(before); + } finally { await f.client.close(); } +}); + +it.each(['$eq', '$startsWith'])('does not infer sensitive substrings by stripping literal wildcards: %s', async operator => { + const literal = '%LITERAL_WILDCARD%\\'; + const f = await fixture(true, literal); + try { + const operand = operator === '$eq' ? `${literal}-tail` : literal; + const query = new SelectQuery('School').filter({ name: { [operator]: operand } }).limit(10) + .comment(`private ${operand}; public LITERAL_WILDCARD`).purpose('preserve exact operand'); + // Preserve the existing SQL LIKE semantics: the caller's leading % is + // still a wildcard, so the prefix form matches both seeded rows. + expect(await f.client.executeQuery(query)).toHaveLength(operator === '$eq' ? 1 : 2); + expect(f.client.transport.reads[0].values).toEqual([operator === '$eq' ? operand : `${operand}%`, 10]); + expect(f.evidence.snapshot()[0].comment).toBe('private [REDACTED]; public LITERAL_WILDCARD'); + expect(query.commentText).toBe(`private ${operand}; public LITERAL_WILDCARD`); + } finally { await f.client.close(); } +}); + +it.each(['name', 'publicName', 'password', 'unknownName'].flatMap(field => + [false, true].map(debug => [field, debug] as const)))( + 'retains original field policy for LIKE operand: %s debug=%p', async (field, debug) => { + const f = await fixture(true); + if (debug) process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + try { + const query = new SelectQuery('School').filter({ [field]: { $startsWith: secret } }).limit(10) + .comment(`load ${secret}`).purpose('verify source policy'); + expect(await f.client.executeQuery(query)).toHaveLength(1); + const visible = field === 'publicName' || (field === 'name' && debug); + expect(f.evidence.snapshot()[0].comment).toBe(`load ${visible ? secret : '[REDACTED]'}`); + expect(f.client.transport.reads[0].values).toEqual([`${secret}%`, 10]); + if (!visible) expect(JSON.stringify([f.evidence.snapshot(), f.diagnostics, f.text])).not.toContain(secret); + if (debug && field === 'name') { + delete process.env[PLAINTEXT_LOG_ENV]; + const safeText: string[] = []; + new TextDiagnosticSQLLogSink(line => safeText.push(line)).write(f.diagnostics[0]); + expect(safeText.join('\n')).not.toContain(secret); + } + } finally { await f.client.close(); } + }); diff --git a/source/teaql-ts/tests/sql-mask-lifecycle.test.ts b/source/teaql-ts/tests/sql-mask-lifecycle.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..a4019be49e1a2b69995bcffc5be0a93ce7f0756b --- /dev/null +++ b/source/teaql-ts/tests/sql-mask-lifecycle.test.ts @@ -0,0 +1,408 @@ +import { UserContext } from '../src/core/context'; +import { SelectQuery } from '../src/core/ast'; +import { PLAINTEXT_LOG_ENV, PLAINTEXT_LOG_ACK, projectSQLLog } from '../src/core/log-privacy'; +import { AbstractSQLTeaQLClient, EntitySchema, SQLExecutionMetadata, SQLExecutionEvidenceStore, + TextDiagnosticSQLLogSink, SqlQueryResult } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; +import { GraphMutationSession, MutationIntent } from '../src/core/request-intent'; + +const schema: Record = { Customer: { + table: 'customer_data', auditMaskFields: ['display_name'], columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string', logPolicy: 'plain' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number', logPolicy: 'plain' }, + displayName: { columnName: 'display_name', logicalType: 'text', decode: 'native', logPolicy: 'plain' }, + publicAddress: { columnName: 'public_address', logicalType: 'text', decode: 'native', logPolicy: 'plain' }, + passwordHash: { columnName: 'password_hash', logicalType: 'text', decode: 'native', logPolicy: 'plain' }, + }, +} }; + +class Driver extends SQLiteDriver { + fault?: Error; + readbackFault?: Error; + readbackRows?: number; + failStreamAfter?: number; + closedCursor = false; + values: unknown[] = []; + async query(sql: string, values: any[] = []): Promise { + if (sql.startsWith('SELECT') && sql.includes('customer_data') && sql.includes('WHERE "id" = ?')) { + if (this.readbackFault) throw this.readbackFault; + if (this.readbackRows !== undefined) { + const result = await super.query(sql, values); + return { rowCount: this.readbackRows, rows: Array.from({ length: this.readbackRows }, () => result.rows[0]) }; + } + } + if (this.fault && sql.includes('customer_data')) { + this.values = [...values]; + throw this.fault; + } + return super.query(sql, values); + } + async *stream(sql: string, values: any[] = []): AsyncIterable { + this.values = [...values]; + let seen = 0; + try { + for await (const row of super.stream(sql, values)) { + if (this.failStreamAfter === seen++) throw this.fault; + yield row; + } + } finally { this.closedCursor = true; } + } +} +class Client extends AbstractSQLTeaQLClient { + constructor(driver: Driver) { super(driver, schema); } +} +const previous = process.env[PLAINTEXT_LOG_ENV]; +beforeEach(() => { delete process.env[PLAINTEXT_LOG_ENV]; }); +afterEach(() => { + if (previous === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = previous; +}); + +async function fixture() { + const driver = new Driver(':memory:'); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (let id = 1; id <= 3; id++) await client.executeMutation({ + entity: 'Customer', action: 'Create', id: String(id), + payload: { displayName: 'Riverside', publicAddress: '1 Runtime Road', passwordHash: 'PASSWORD-CANARY' }, + comment: 'seed lifecycle fixture', + }); + const logs: SQLExecutionMetadata[] = [], output: string[] = []; + const evidence = new SQLExecutionEvidenceStore(); + client.setRuntimeTelemetrySink(evidence).setDiagnosticSQLLogSink({ write(entry) { + logs.push(entry); new TextDiagnosticSQLLogSink(line => output.push(line)).write(entry); + } }); + return { driver, client, logs, output, evidence }; +} +function query() { + return new SelectQuery('Customer').filter({ displayName: { $eq: 'Riverside' }, + publicAddress: { $eq: '1 Runtime Road' }, passwordHash: { $eq: 'PASSWORD-CANARY' } }) + .limit(10).comment('what: stream matching customers').purpose('why: verify lifecycle masking'); +} +function verify(f: Awaited>, outcome: string, count?: number) { + expect(f.logs).toHaveLength(1); + const entry = f.logs[0]; + expect(entry.executionOutcome).toBe(outcome); + expect(entry.resultCount).toBe(count); + expect(entry.tracePath.length).toBeGreaterThan(0); + const all = JSON.stringify([f.logs, f.output, f.evidence.snapshot()]); + expect(all).not.toContain('Riverside'); + expect(all).not.toContain('PASSWORD-CANARY'); + expect(all).not.toContain('DRIVER-CANARY'); + expect(entry.debugSQL).toContain('Ri*****de'); + expect(entry.debugSQL).toContain('1 Runtime Road'); + expect(f.output.join('\n')).toContain(`outcome=${outcome}`); +} + +it.each(['complete', 'cancel', 'consumer-error', 'provider-error'])( + 'logs masked SQL once when the stream ends: %s', async mode => { + const f = await fixture(); + const fault = new Error('Riverside DRIVER-CANARY PASSWORD-CANARY'); + if (mode === 'provider-error') { f.driver.fault = fault; f.driver.failStreamAfter = 1; } + try { + const consume = async () => { + for await (const rows of f.client.executeForStream(query(), 1)) { + expect(rows[0].displayName).toBe('Riverside'); + if (mode === 'cancel') break; + if (mode === 'consumer-error') throw fault; + } + }; + if (mode.endsWith('error')) await expect(consume()).rejects.toBe(fault); + else await consume(); + verify(f, mode === 'complete' ? 'success' : mode === 'provider-error' ? 'failure' : 'cancelled', mode === 'complete' ? 3 : 1); + expect(f.driver.closedCursor).toBe(true); + expect(f.driver.values).toContain('Riverside'); + expect(f.driver.values).toContain('PASSWORD-CANARY'); + } finally { await f.client.close(); } + }); + +it('records an empty stream and honors the query logging switch', async () => { + const f = await fixture(); + try { + const empty = query().filter({ id: { $eq: '999' } }); + for await (const rows of f.client.executeForStream(empty, 2)) expect(rows).toHaveLength(0); + expect(f.logs).toHaveLength(1); + expect(f.logs[0].resultCount).toBe(0); + f.logs.length = 0; f.evidence.enableAll(); f.client.setQueryLoggingEnabled(false); + for await (const _rows of f.client.executeForStream(query(), 2)) { /* consume */ } + expect(f.logs).toHaveLength(0); + expect(f.evidence.snapshot()).toHaveLength(1); + expect(f.evidence.snapshot()[0].resultCount).toBe(3); + } finally { await f.client.close(); } +}); + +it('records failed list SQL without logging or changing the original driver error', async () => { + const f = await fixture(); + const fault = new Error('Riverside DRIVER-CANARY PASSWORD-CANARY'); + f.driver.fault = fault; + try { + await expect(f.client.executeQuery(query())).rejects.toBe(fault); + verify(f, 'failure'); + expect(f.logs[0].affectedRows).toBeUndefined(); + } finally { await f.client.close(); } +}); + +it.each(['Create', 'Update', 'Delete'])('records failed %s with audit reason, not exception payload', async action => { + const f = await fixture(); + const fault = new Error('Riverside DRIVER-CANARY PASSWORD-CANARY'); + f.driver.fault = fault; + try { + const targetID = action === 'Create' ? '4' : '1'; + await expect(f.client.executeMutation({ entity: 'Customer', action, id: targetID, + version: 1, payload: { displayName: 'Riverside', publicAddress: '1 Runtime Road', passwordHash: 'PASSWORD-CANARY' }, + comment: `verify failed mutation ${targetID}` })).rejects.toBe(fault); + expect(f.logs).toHaveLength(1); + expect(f.logs[0].executionOutcome).toBe('failure'); + expect(f.logs[0].auditReason).toBe('verify failed mutation [REDACTED]'); + expect(f.logs[0].affectedRows).toBeUndefined(); + const all = JSON.stringify([f.logs, f.output, f.evidence.snapshot()]); + expect(all).not.toMatch(/Riverside|PASSWORD-CANARY|DRIVER-CANARY/); + expect(f.logs[0].debugSQL).not.toContain('?'); + } finally { await f.client.close(); } +}); + +it('does not redact a structural row count when the target ID is short', async () => { + const f = await fixture(); + try { + await f.client.executeMutation({entity:'Customer',action:'Update',id:'1',version:1, + payload:{publicAddress:'Changed Road'},comment:'update target 1'}); + expect(f.logs.map(entry => entry.operation)).toEqual(['update', 'select']); + expect(f.logs[0].auditReason).toBe('update target [REDACTED]'); + expect(f.logs[0].resultSummary).toBe('1 rows affected'); + expect(f.logs[0].parameters).toContain('1'); + } finally { await f.client.close(); } +}); + +it.each(['Create', 'Update', 'Delete'])( + 'scrubs the target id from successful %s audit reason but keeps the typed id', async action => { + const f = await fixture(); + try { + if (action !== 'Create') { + await f.client.executeMutation({ + entity: 'Customer', action: 'Create', id: '1001', + payload: { displayName: 'Seed', publicAddress: 'Seed Road' }, + comment: 'seed audit target', + }); + } + const mutation = { + entity: 'Customer', action, id: '1001', version: 1, + payload: action === 'Delete' ? {} : { displayName: 'Changed' }, + comment: `${action.toLowerCase()} target 1001`, + }; + await f.client.executeMutation(mutation); + const auditTrace = f.client.auditTrace; + const audit = auditTrace[auditTrace.length - 1]; + expect(audit?.id).toBe('1001'); + expect(audit?.reason).toBe(`${action.toLowerCase()} target [REDACTED]`); + const sqlEntry = f.logs[f.logs.length - 1]; + expect(sqlEntry.auditReason).toBe(`${action.toLowerCase()} target [REDACTED]`); + expect(JSON.stringify(sqlEntry.tracePath)).not.toContain('1001'); + expect(sqlEntry).not.toHaveProperty('targetID'); + expect(sqlEntry.parameters).toContain('1001'); + expect(sqlEntry.mutationLineage?.[0].entityId).toBe('1001'); + expect(sqlEntry.mutationLineage?.[0].detail).toBe(`${action.toLowerCase()} target [REDACTED]`); + expect(Object.isFrozen(sqlEntry.mutationLineage?.[0])).toBe(true); + expect(mutation.id).toBe('1001'); + expect(mutation.comment).toContain('1001'); + } finally { await f.client.close(); } + }); + +it('does not report prefetched but undelivered rows on a stream failure', async () => { + const f = await fixture(); + const fault = new Error('DRIVER-CANARY'); + f.driver.fault = fault; f.driver.failStreamAfter = 1; + try { + const consume = async () => { for await (const _rows of f.client.executeForStream(query(), 3)) { /* consume */ } }; + await expect(consume()).rejects.toBe(fault); + verify(f, 'failure', 0); + expect(f.driver.closedCursor).toBe(true); + } finally { await f.client.close(); } +}); + +it('keeps credentials private and labels each debug stream/failure record', async () => { + const f = await fixture(); + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + try { + for await (const _rows of f.client.executeForStream(query(), 1)) break; + f.driver.fault = new Error('DRIVER-CANARY'); + await expect(f.client.executeQuery(query())).rejects.toBe(f.driver.fault); + expect(f.logs).toHaveLength(2); + for (const entry of f.logs) { + expect(entry.debugSQL).toContain('Riverside'); + expect(entry.debugSQL).toContain('EXPLICIT OPT-IN'); + expect(entry.debugSQL).toContain('NOT REPLAYABLE'); + expect(JSON.stringify(entry)).not.toMatch(/PASSWORD-CANARY|DRIVER-CANARY/); + } + } finally { await f.client.close(); } +}); + +it('does not replace a driver error with a diagnostic-sink error', async () => { + const f = await fixture(); + const fault = new Error('DRIVER-CANARY'); + f.driver.fault = fault; + f.client.setDiagnosticSQLLogSink({ write() { throw new Error('SINK-FAILURE'); } }); + try { + await expect(f.client.executeQuery(query())).rejects.toBe(fault); + f.driver.failStreamAfter = 0; + const consume = async () => { for await (const _rows of f.client.executeForStream(query(), 1)) { /* consume */ } }; + await expect(consume()).rejects.toBe(fault); + expect(f.driver.closedCursor).toBe(true); + } finally { await f.client.close(); } +}); + +it('keeps successful SQL and graph mutation independent of broken diagnostic sinks', async () => { + const f = await fixture(); + let evidenceCalls = 0; + let diagnosticCalls = 0; + f.client.setRuntimeTelemetrySink({ record(entry) { + evidenceCalls++; + expect(JSON.stringify(entry)).not.toContain('PASSWORD-CANARY'); + throw new Error('EVIDENCE-SINK-FAILURE'); + } }).setDiagnosticSQLLogSink({ write(entry) { + diagnosticCalls++; + expect(JSON.stringify(entry)).not.toContain('PASSWORD-CANARY'); + throw new Error('DIAGNOSTIC-SINK-FAILURE'); + } }); + try { + await expect(f.client.executeMutation({ + entity: 'Customer', action: 'Create', id: '4', + payload: { displayName: 'Riverside', publicAddress: '1 Runtime Road', + passwordHash: 'PASSWORD-CANARY' }, + comment: 'what: create customer despite logging failure', + })).resolves.toMatchObject({ success: true, id: '4' }); + const rows = await f.client.executeQuery(query()); + expect(rows).toHaveLength(4); + const driverFault = new Error('DRIVER-CANARY'); + f.driver.fault = driverFault; + await expect(f.client.executeQuery(query())).rejects.toBe(driverFault); + expect(evidenceCalls).toBeGreaterThan(0); + expect(diagnosticCalls).toBeGreaterThan(0); + } finally { await f.client.close(); } +}); + +it.each(['Create', 'Update', 'Delete'].flatMap(action => ['error','empty','multiple'].map(mode => ({action,mode}))))( + 'retains independent write/readback facts for $action/$mode', async ({action,mode}) => { + const f = await fixture(); + const fault = new Error('DRIVER-CANARY Riverside PASSWORD-CANARY'); + if (mode === 'error') f.driver.readbackFault = fault; + else f.driver.readbackRows = mode === 'empty' ? 0 : 2; + try { + const mutation = { entity:'Customer', action, id:action === 'Create' ? '4':'1', version:1, + payload:{displayName:'Riverside',passwordHash:'PASSWORD-CANARY'}, + comment: action === 'Delete' ? 'what: delete customer' : 'what: write Riverside PASSWORD-CANARY' }; + const pending = f.client.executeMutation(mutation); + if (mode === 'error') await expect(pending).rejects.toBe(fault); + else await expect(pending).rejects.toThrow('could not be read back'); + expect(f.logs).toHaveLength(2); + expect(f.logs[0].executionOutcome).toBe('success'); + expect(f.logs[0].affectedRows).toBe(1); + expect(f.logs[1].operation).toBe('select'); + expect(f.logs[1].executionOutcome).toBe(mode === 'error' ? 'failure':'success'); + expect(f.logs[1].resultCount).toBe(mode === 'error' ? undefined : mode === 'empty' ? 0:2); + expect(f.logs[1].affectedRows).toBeUndefined(); + expect(f.logs[1].auditReason).toContain('what:'); + expect(f.logs[1].debugSQL).toContain('SELECT'); + expect(f.logs[1].debugSQL).not.toContain('?'); + expect(JSON.stringify([f.logs,f.output,f.evidence.snapshot()])).not.toMatch(/Riverside|PASSWORD-CANARY|DRIVER-CANARY/); + f.driver.readbackFault = undefined; f.driver.readbackRows = undefined; + const rows = await f.driver.query('SELECT * FROM customer_data'); + expect(rows.rowCount).toBe(3); + expect(rows.rows[0].version).toBe(1); + expect(rows.rows[0].display_name).toBe('Riverside'); + } finally { await f.client.close(); } + }); + +it('preserves original error when the readback diagnostic sink fails', async () => { + const f = await fixture(); + const fault = new Error('READBACK-FAILURE'); + f.driver.readbackFault = fault; + let observed = 0; + f.client.setDiagnosticSQLLogSink({write(entry) { observed++; if(entry.operation === 'select') throw new Error('SINK-FAILURE'); }}); + try { + await expect(f.client.executeMutation({entity:'Customer',action:'Update',id:'1',version:1,payload:{displayName:'Riverside'},comment:'verify failed readback'})).rejects.toBe(fault); + expect(observed).toBe(2); + expect((await f.driver.query('SELECT version FROM customer_data')).rows[0].version).toBe(1); + } finally { await f.client.close(); } +}); + +it.each(['debug','disabled','success'])('handles readback mode %s without changing business values', async mode => { + const f = await fixture(); + if (mode === 'debug') process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + if (mode === 'disabled') f.client.setQueryLoggingEnabled(false).setMutationLoggingEnabled(false); + if (mode !== 'success') f.driver.readbackFault = new Error('READBACK-FAILURE'); + try { + const pending = f.client.executeMutation({entity:'Customer',action:'Update',id:'1',version:1, + payload:{displayName:'Riverside',passwordHash:'PASSWORD-CANARY'},comment:'what: update Riverside PASSWORD-CANARY'}); + if (mode === 'success') { + const result = await pending; + expect(result.persistedRecord?.displayName).toBe('Riverside'); + expect(result.persistedRecord?.passwordHash).toBe('PASSWORD-CANARY'); + expect(f.logs.map(entry => entry.operation)).toEqual(['update', 'select']); + } else await expect(pending).rejects.toBe(f.driver.readbackFault); + if (mode === 'disabled') { + expect(f.logs).toHaveLength(0); + expect(f.evidence.snapshot().map(entry => entry.executionOutcome)).toEqual(['success', 'failure']); + } + if (mode === 'debug') { + expect(f.logs).toHaveLength(2); + for (const entry of f.logs) { + expect(entry.auditReason).toContain('Riverside'); + expect(entry.debugSQL).toContain('EXPLICIT OPT-IN'); + expect(JSON.stringify(entry)).not.toContain('PASSWORD-CANARY'); + } + delete process.env[PLAINTEXT_LOG_ENV]; + for (const entry of f.logs) { + const safe = projectSQLLog(entry); + expect(safe.auditReason).toContain('what: update'); + expect(JSON.stringify(safe)).not.toMatch(/Riverside|PASSWORD-CANARY/); + // Copying a record loses the private safe alternative. Unknown inherited + // intent must then fail closed rather than survive in plaintext. + expect(JSON.stringify(projectSQLLog({...entry}))).not.toMatch(/Riverside|PASSWORD-CANARY/); + } + } + } finally { await f.client.close(); } +}); + +it.each(['write','readback'])('retains partial graph SQL facts and rolls back after %s failure', async phase => { + const f = await fixture(); + const fault = new Error('GRAPH-FAILURE'); + const create = (id:string, graph?: GraphMutationSession) => { + const mutation = {entity:'Customer',action:'Create',id, + payload:{displayName:'Riverside',passwordHash:'PASSWORD-CANARY'},comment:'what: insert Riverside PASSWORD-CANARY'}; + return f.client.executeMutation(graph ? graph.request(mutation) : mutation); + }; + try { + await expect(f.client.executeGraphSave(new MutationIntent('what: insert Riverside PASSWORD-CANARY'), async graph => { + await create('4', graph); + if(phase === 'write') f.driver.fault = fault; + else f.driver.readbackFault = fault; + await create('5', graph); + await create('6', graph); + })).rejects.toBe(fault); + expect(f.logs.map(entry => entry.executionOutcome)).toEqual(phase === 'write' + ? ['success','success','failure'] : ['success','success','success','failure']); + expect(f.logs[1].operation).toBe('select'); + expect(f.logs[1].resultCount).toBe(1); + expect(JSON.stringify([f.logs,f.output,f.evidence.snapshot()])).not.toMatch(/Riverside|PASSWORD-CANARY|GRAPH-FAILURE/); + f.driver.fault = undefined; f.driver.readbackFault = undefined; + expect((await f.driver.query('SELECT * FROM customer_data')).rowCount).toBe(3); + f.logs.length = 0; + await create('7'); + expect(f.logs.map(entry => entry.operation)).toEqual(['insert', 'select']); + expect((await f.driver.query('SELECT * FROM customer_data')).rowCount).toBe(4); + } finally { await f.client.close(); } +}); + +it.each(['AbortError','TimeoutError'])('records readback cancellation reported by the driver: %s', async name => { + const f = await fixture(); + const fault = new Error('CANCEL-CANARY'); fault.name = name; + f.driver.readbackFault = fault; + try { + await expect(f.client.executeMutation({entity:'Customer',action:'Update',id:'1',version:1, + payload:{displayName:'Riverside'},comment:'what: update Riverside'})).rejects.toBe(fault); + expect(f.logs.map(entry=>entry.executionOutcome)).toEqual(['success','cancelled']); + expect(f.logs[1].resultCount).toBeUndefined(); + expect(JSON.stringify(f.logs)).not.toMatch(/Riverside|CANCEL-CANARY/); + expect((await f.driver.query('SELECT version FROM customer_data')).rows[0].version).toBe(1); + } finally { await f.client.close(); } +}); diff --git a/source/teaql-ts/tests/sql-masking-policy.test.ts b/source/teaql-ts/tests/sql-masking-policy.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..fcb5a903eb0f303208d891bc2e561e45b2b31d1c --- /dev/null +++ b/source/teaql-ts/tests/sql-masking-policy.test.ts @@ -0,0 +1,247 @@ +import { UserContext } from '../src/core/context'; +import { SelectQuery } from '../src/core/ast'; +import { PLAINTEXT_LOG_ENV, PLAINTEXT_LOG_ACK, projectSQLLog } from '../src/core/log-privacy'; +import { EntitySchema, SQLExecutionMetadata, TextDiagnosticSQLLogSink } from '../src/sql/core'; +import { SQLiteTeaQLClient } from '../src/sql/sqlite'; + +const previous = process.env[PLAINTEXT_LOG_ENV]; +beforeEach(() => { delete process.env[PLAINTEXT_LOG_ENV]; }); +afterEach(() => { + if (previous === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = previous; +}); + +function metadata(sql: string, parameters: unknown[]): SQLExecutionMetadata { + return { operation: 'select', tracePath: [], parameterizedSQL: sql, parameters, + debugSQL: '', elapsedMicros: 1, resultSummary: 'one row', + comment: 'what: load a bounded customer', purpose: 'why: verify safe diagnostics' }; +} + +it('renders mixed field policies through the existing dialect renderer', () => { + const raw = { ...metadata('SELECT $1, $2, $1', ["O'Reilly", true]), + databaseKind: 'postgresql' as const, parameterLogPolicies: ['masked', 'plain'] as const }; + const safe = projectSQLLog(raw); + expect(safe.debugSQL).toContain("'O''****ly' /* masked */, TRUE, 'O''****ly' /* masked */"); + expect(safe.maskedParameters).toEqual([true, false]); + expect(safe.debugSQL).not.toContain("O''Reilly"); + expect(raw.parameters).toEqual(["O'Reilly", true]); + expect(projectSQLLog(safe)).toBe(safe); +}); + +it.each([1, 'customer'])('preserves the compiled SQL structure through a copied projection: %s', value => { + const sql = 'SELECT id FROM customer WHERE name = ? LIMIT 10000'; + const safe = projectSQLLog({...metadata(sql,[value]),sqlOrigin:'generated'}); + expect(safe.parameterizedSQL).toBe(sql); + expect(projectSQLLog({...safe}).debugSQL).toContain('FROM customer'); + expect(projectSQLLog({...safe}).debugSQL).toContain('LIMIT 10000'); +}); + +it.each([false,true])('projects inherited unknown/nested credentials without retaining their source (debug=%s)', debug => { + if(debug) process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const source = {parameterizedSQL:'UPDATE customer SET a=?, b=?, c=?, d=?',sqlOrigin:'generated' as const, + parameters:['Riverside','UNKNOWN-CANARY',{apiKey:'NESTED-CANARY'},12345], + parameterLogPolicies:['masked','unknown','plain','masked'] as const}; + const raw = {...metadata('SELECT id FROM customer WHERE id=?',['1']),sqlOrigin:'generated' as const, + parameterLogPolicies:['plain'] as const,auditReason:'what: inspect Riverside UNKNOWN-CANARY NESTED-CANARY 12345'}; + const projected = projectSQLLog(raw,source); + expect(projected.auditReason?.includes('Riverside')).toBe(debug); + expect(projected.auditReason?.includes('12345')).toBe(debug); + expect(JSON.stringify(projected)).not.toMatch(/UNKNOWN-CANARY|NESTED-CANARY/); + expect(Object.getOwnPropertySymbols(projected)).toHaveLength(0); + expect(Object.keys(projected)).not.toContain('inherited'); + expect(source.parameters[0]).toBe('Riverside'); + if(!debug) { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + expect(JSON.stringify(projectSQLLog({...projected}))).not.toMatch(/Riverside|UNKNOWN-CANARY|NESTED-CANARY/); + expect(projectSQLLog({...projected}).logMode).toBe('masked'); + } +}); + +it('preserves typed plain literals while masking derived and collection values', () => { + const raw = { ...metadata('SELECT ?, ?, ?, ?', [ + { type: 'Date', value: '2024-02-29' }, { type: 'Timestamp', value: -123 }, + ['Riverside', '12345678'], null]), databaseKind: 'postgresql' as const, + parameterLogPolicies: ['plain', 'plain', 'masked', 'masked'] as const }; + const safe = projectSQLLog(raw); + expect(safe.debugSQL).toContain("DATE '2024-02-29'"); + expect(safe.debugSQL).toContain("TIMESTAMPTZ '1969-12-31T23:59:59.877Z'"); + expect(safe.debugSQL).toContain('Ri*****de'); + expect(safe.debugSQL).not.toContain('Riverside'); + expect(safe.debugSQL).toContain('NULL /* masked */'); +}); + +it('uses trusted compiler identifiers and ignores fake placeholders in literals/comments', () => { + const raw = { ...metadata("SELECT `field?`, 'constant?', ? /* static ? */", ['Riverside']), + sqlOrigin: 'generated' as const, parameterLogPolicies: ['masked'] as const }; + expect(projectSQLLog(raw).debugSQL).toContain("`field?`, 'constant?', 'Ri*****de' /* masked */"); +}); + +it.each(['SELECT $0', 'SELECT $2', 'SELECT ?, ?', 'SELECT @p0', 'SELECT 1'])( + 'fails closed for bind mismatch: %s', sql => { + const safe = projectSQLLog(metadata(sql, ['CANARY-MISSING-BIND'])); + expect(safe.debugSQL).toContain('NOT REPLAYABLE'); + expect(safe.debugSQL).not.toContain('CANARY-MISSING-BIND'); + expect(safe.debugSQL).not.toContain('SELECT'); + }); + +it('cannot expose credentials with a forged plain policy during debug', () => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const safe = projectSQLLog({ ...metadata('UPDATE customer SET password = ?', ['CREDENTIAL-CANARY']), + parameterLogPolicies: ['plain'] }); + expect(JSON.stringify(safe)).not.toContain('CREDENTIAL-CANARY'); + expect(safe.debugSQL).toContain('masked'); + expect(safe.maskedParameters).toEqual([true]); +}); + +it.each([false, true])('preserves generated field policies beside credential columns (debug=%s)', debug => { + if (debug) process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const raw: SQLExecutionMetadata = { + ...metadata('SELECT password_hash FROM customer WHERE display_name = ? AND public_address = ? AND password_hash = ?', + ['Riverside', '1 Runtime Road', 'PASSWORD-CANARY']), + sqlOrigin: 'generated', parameterLogPolicies: ['masked', 'plain', 'credential'], + }; + const safe = projectSQLLog(raw); + expect(safe.parameterLogPolicies).toEqual(raw.parameterLogPolicies); + expect(safe.debugSQL).toContain(debug ? 'Riverside' : 'Ri*****de'); + expect(safe.debugSQL).toContain('1 Runtime Road'); + expect(JSON.stringify(safe)).not.toContain('PASSWORD-CANARY'); + expect(projectSQLLog(safe)).toBe(safe); + expect(raw.parameters[2]).toBe('PASSWORD-CANARY'); +}); + +it.each([undefined, ['unknown'], ['unsupported-policy']])( + 'keeps unclassified bindings private even with explicit debug opt-in: %s', supplied => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const raw = { ...metadata('SELECT ?', ['UNKNOWN-BINDING-CANARY']), + parameterLogPolicies: supplied as SQLExecutionMetadata['parameterLogPolicies'], + comment: 'what: locate UNKNOWN-BINDING-CANARY' }; + const safe = projectSQLLog(raw); + expect(JSON.stringify(safe)).not.toContain('UNKNOWN-BINDING-CANARY'); + expect(safe.maskedParameters).toEqual([true]); + expect(safe.debugSQL).toContain('SELECT'); + expect(safe.debugSQL).toContain('NOT REPLAYABLE'); + expect(raw.parameters).toEqual(['UNKNOWN-BINDING-CANARY']); + }); + +it('only explicit business policies permit plaintext debug, never unknown or credential values', () => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const safe = projectSQLLog({ ...metadata('SELECT ?, ?, ?, ?', + ['Ordinary', 'Riverside', 'UNKNOWN-BINDING-CANARY', 'CREDENTIAL-CANARY']), + parameterLogPolicies: ['plain', 'masked', 'unknown', 'credential'] }); + expect(safe.parameters).toEqual(['Ordinary', 'Riverside', '[REDACTED]', '[REDACTED]']); + expect(safe.maskedParameters).toEqual([false, false, true, true]); +}); + +it('omits untrusted inline credentials even during debug and explains the omission', () => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const raw = metadata("UPDATE customer SET password = 'INLINE-CREDENTIAL-CANARY'", []); + const output: string[] = []; + new TextDiagnosticSQLLogSink(line => output.push(line)).write(raw); + expect(output.join('\n')).not.toContain('INLINE-CREDENTIAL-CANARY'); + expect(output.join('\n')).toContain('SQL omitted: untrusted-literal-sql'); + expect(JSON.stringify(projectSQLLog(raw))).not.toContain('INLINE-CREDENTIAL-CANARY'); +}); + +it('preserves operational counts even when their digits match a masked binding', () => { + const safe = projectSQLLog({ ...metadata('SELECT ?', [1]), resultCount: 1 }); + expect(safe.resultSummary).toBe('1 rows returned'); + expect(safe.parameters).toEqual(['[REDACTED]']); +}); + +it('explains invalid policy/bind counts without leaking values or driver errors', () => { + const raw = { ...metadata('SELECT ?', ['COUNT-CANARY']), parameterLogPolicies: [] }; + expect(projectSQLLog(raw).omissionReason).toBe('policy-count-mismatch'); + expect(projectSQLLog(metadata('SELECT ?, ?', ['COUNT-CANARY'])).omissionReason) + .toBe('unsupported-or-mismatched-bindings'); + expect(JSON.stringify(projectSQLLog(raw))).not.toContain('COUNT-CANARY'); +}); + +it('reprojects when debug is disabled and never recovers plaintext from a safe projection', () => { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const raw = { ...metadata('SELECT ?', ['Riverside']), parameterLogPolicies: ['masked'] as const }; + const debug = projectSQLLog(raw); + expect(debug.debugSQL).toContain('Riverside'); + delete process.env[PLAINTEXT_LOG_ENV]; + const safe = projectSQLLog(debug); + expect(JSON.stringify(safe)).not.toContain('Riverside'); + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + expect(projectSQLLog(safe)).toBe(safe); + expect(raw.parameters).toEqual(['Riverside']); +}); + +it('compiles trusted field policies on real SQLite mutations and predicates before logging', async () => { + const schemas: Record = { Customer: { + table: 'customer_data', auditMaskFields: ['display_name'], columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + displayName: { columnName: 'display_name', modelName: 'display_name', logicalType: 'text', decode: 'native' }, + active: { columnName: 'active', logicalType: 'boolean', decode: 'native', logPolicy: 'plain' }, + passwordHash: { columnName: 'password_hash', logicalType: 'text', decode: 'native', logPolicy: 'plain' }, + }, + } }; + const captured: SQLExecutionMetadata[] = []; + const output: string[] = []; + const text = new TextDiagnosticSQLLogSink(line => output.push(line)); + const client = new SQLiteTeaQLClient(':memory:', schemas).setDiagnosticSQLLogSink({ + write: entry => { captured.push(entry); text.write(entry); }, + }); + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + const created = await client.executeMutation({ entity: 'Customer', action: 'Create', id: '1', + payload: { display_name: 'Riverside', active: true, passwordHash: 'PASSWORD-CANARY' }, comment: 'seed a customer' }); + const query = new SelectQuery('Customer').filter({ displayName: { $in: ['Riverside', 'Other'] }, active: { $eq: true } }) + .limit(1).comment('what: find the customer').purpose('why: verify field policy propagation'); + const rows = await client.executeQuery(query); + expect(rows[0].displayName).toBe('Riverside'); + expect(captured[0].parameterLogPolicies).toContain('masked'); + expect(output.join('\n')).toContain('Ri*****de'); + expect(output.join('\n')).toContain('LIMIT 1'); + expect(output.join('\n')).not.toContain('Riverside'); + expect(output.join('\n')).not.toContain('Parameterized SQL:'); + expect(output.join('\n')).not.toContain('REDACTED SQL'); + const selects = captured.filter(entry => entry.operation === 'select'); + expect(selects).toHaveLength(2); + expect(selects[0].purpose).toBe('verify persisted mutation result'); + const sql = selects[1]; + expect(sql.maskedParameters).toEqual([true, true, false, false]); + await client.executeMutation({ entity: 'Customer', action: 'Update', id: '1', version: created.version, + payload: { display_name: "O'Reilly" }, comment: 'rename customer' }); + expect(output.join('\n')).toContain("O''****ly"); + expect(output.join('\n')).not.toContain("O''Reilly"); + } finally { await client.close(); } +}); + +it.each([false, true])('distinguishes old missing mask metadata from explicit empty (declared=%s)', async declared => { + const customer: EntitySchema = { + table: 'customer_data', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string', logPolicy: 'plain' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number', logPolicy: 'plain' }, + displayName: { columnName: 'display_name', logicalType: 'text', decode: 'native', logPolicy: 'plain' }, + }, + }; + if (declared) customer.auditMaskFields = []; + const captured: SQLExecutionMetadata[] = []; + const output: string[] = []; + const text = new TextDiagnosticSQLLogSink(line => output.push(line)); + const client = new SQLiteTeaQLClient(':memory:', { Customer: customer }).setDiagnosticSQLLogSink({ + write: entry => { captured.push(entry); text.write(entry); }, + }); + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + await client.executeMutation({ entity: 'Customer', action: 'Create', id: '1', + payload: { displayName: 'Riverside' }, comment: 'seed old descriptor fixture' }); + const rows = await client.executeQuery(new SelectQuery('Customer') + .filter({ displayName: { $eq: 'Riverside' } }).limit(1) + .comment('what: find old descriptor').purpose('why: verify fail-closed upgrade')); + expect(rows[0].displayName).toBe('Riverside'); + const logged = captured.find(entry => entry.operation === 'select' && + entry.comment === 'what: find old descriptor'); + expect(logged?.parameterLogPolicies).toContain(declared ? 'plain' : 'unknown'); + if (declared) expect(output.join('\n')).toContain('Riverside'); + else { + expect(output.join('\n')).toContain('[REDACTED]'); + expect(output.join('\n')).not.toContain('Riverside'); + } + } finally { await client.close(); } +}); diff --git a/source/teaql-ts/tests/sql-masking-real-databases.test.ts b/source/teaql-ts/tests/sql-masking-real-databases.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..0c02505dd12f2f1a872639c577564ab13d1aee3b --- /dev/null +++ b/source/teaql-ts/tests/sql-masking-real-databases.test.ts @@ -0,0 +1,69 @@ +import { SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { EntitySchema, TextDiagnosticSQLLogSink } from '../src/sql/core'; +import { MySQLDriver, MySQLTeaQLClient } from '../src/sql/mysql'; +import { PostgreSQLDriver, PostgreSQLTeaQLClient } from '../src/sql/postgres'; + +const cases = [ + ['PostgreSQL', 'TEAQL_TEST_POSTGRES_URL', + (url: string, schemas: Record) => new PostgreSQLTeaQLClient(url, schemas), + (url: string) => new PostgreSQLDriver(url)], + ['MySQL', 'TEAQL_TEST_MYSQL_URL', + (url: string, schemas: Record) => new MySQLTeaQLClient(url, schemas), + (url: string) => new MySQLDriver(url)], +] as const; + +describe.each(cases)('%s live SQL masking', (name, envName, createClient, createDriver) => { + const url = process.env[envName]?.trim(); + const required = process.env.TEAQL_REQUIRE_LIVE_DB?.toLowerCase() === 'true'; + const testIfConfigured = url || required ? test : test.skip; + + testIfConfigured('preserves execution values while rendering field-aware Q and mutation logs', async () => { + if (!url) throw new Error(`${envName} is required for live provider tests`); + const table = `teaql_mask_${name.toLowerCase()}_${process.pid}_${Date.now()}`; + const schemas: Record = { Customer: { + table, + auditMaskFields: ['display_name', 'password_hash'], + columns: { + id: { columnName: 'id', modelName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', modelName: 'version', logicalType: 'integer', decode: 'number' }, + displayName: { columnName: 'display_name', modelName: 'display_name', logicalType: 'text', decode: 'native' }, + publicAddress: { columnName: 'public_address', modelName: 'public_address', logicalType: 'text', decode: 'native', logPolicy: 'plain' }, + passwordHash: { columnName: 'password_hash', modelName: 'password_hash', logicalType: 'text', decode: 'native' }, + }, + } }; + const lines: string[] = []; + const client = createClient(url!, schemas) + .setDiagnosticSQLLogSink(new TextDiagnosticSQLLogSink(line => lines.push(line))); + const context = new UserContext().insertResource('dataService', client); + const cleanupDriver = createDriver(url!); + try { + await context.ensureSchema(); + await client.executeMutation({ + entity: 'Customer', action: 'Create', id: '1', + payload: { display_name: 'Riverside', public_address: '1 Runtime Road', password_hash: 'PASSWORD-CANARY' }, + comment: 'what: create a masked customer', + }); + const rows = await client.executeQuery(new SelectQuery('Customer') + .filter({ displayName: { $eq: 'Riverside' }, publicAddress: { $eq: '1 Runtime Road' } }) + .limit(1) + .comment('what: read a masked customer') + .purpose('why: verify live-provider SQL masking')); + expect(rows).toHaveLength(1); + expect(rows[0].displayName).toBe('Riverside'); + expect(rows[0].publicAddress).toBe('1 Runtime Road'); + const logged = lines.join('\n'); + expect(logged).toContain('Ri*****de'); + expect(logged).toContain('1 Runtime Road'); + expect(logged).toContain('what: read a masked customer'); + expect(logged).toContain('why: verify live-provider SQL masking'); + expect(logged).toContain('SELECT'); + expect(logged).not.toContain('Riverside'); + expect(logged).not.toContain('PASSWORD-CANARY'); + } finally { + await client.close(); + await cleanupDriver.query(`DROP TABLE IF EXISTS ${cleanupDriver.identifier(table)}`); + await cleanupDriver.close(); + } + }); +}); diff --git a/source/teaql-ts/tests/sql-mutation-readback.test.ts b/source/teaql-ts/tests/sql-mutation-readback.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..036ddd1444480f4054a925e581f00f2d70b903dc --- /dev/null +++ b/source/teaql-ts/tests/sql-mutation-readback.test.ts @@ -0,0 +1,97 @@ +import { UserContext } from '../src/core/context'; +import { AbstractSQLTeaQLClient, EntitySchema, SQLExecutionEvidenceStore, SQLExecutionMetadata } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; +import { PLAINTEXT_LOG_ACK, PLAINTEXT_LOG_ENV, projectSQLLog } from '../src/core/log-privacy'; + +const schemas: Record = { Customer: { + table: 'readback_customer', auditMaskFields: ['name'], columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string', logPolicy: 'plain' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number', logPolicy: 'plain' }, + name: { columnName: 'name', logicalType: 'text', decode: 'string', logPolicy: 'plain' }, + passwordHash: { columnName: 'password_hash', logicalType: 'text', decode: 'string', logPolicy: 'plain' }, + }, +} }; +class Client extends AbstractSQLTeaQLClient { + constructor(driver: SQLiteDriver) { super(driver, schemas); } +} + +it.each(['Create', 'Update', 'Delete'].flatMap(action => [0, 1, 2, 3].map(mode => ({ action, mode }))))( + 'retains actual successful write/SELECT facts for $action with logging mode $mode', async ({ action, mode }) => { + const driver = new SQLiteDriver(':memory:'); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined); + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + if (action !== 'Create') await client.executeMutation({ entity: 'Customer', action: 'Create', + id: '17', payload: { name: 'PRIVATE-CUSTOMER' }, comment: 'seed readback fixture' }); + const evidence = new SQLExecutionEvidenceStore(), logs: SQLExecutionMetadata[] = []; + client.setRuntimeTelemetrySink(evidence).setDiagnosticSQLLogSink({ write(entry) { logs.push(entry); } }) + .setMutationLoggingEnabled(Boolean(mode & 1)).setQueryLoggingEnabled(Boolean(mode & 2)); + const comment = action === 'Delete' ? 'delete fixture' : 'persist PRIVATE-CUSTOMER'; + const result = await client.executeMutation({ entity: 'Customer', action, id: '17', version: 1, + payload: action === 'Delete' ? {} : { name: 'PRIVATE-CUSTOMER' }, comment }); + const operation = action === 'Create' ? 'insert' : action.toLowerCase(); + expect(result.persistedRecord?.name).toBe('PRIVATE-CUSTOMER'); + expect(result).toMatchObject({ metadata: { operation, affectedRows: 1, statements: [ + { operation, affectedRows: 1, executionOutcome: 'success' }, + { operation: 'select', resultCount: 1, comment, executionOutcome: 'success', parameters: ['17'] }, + ] } }); + expect(Object.isFrozen(result.metadata?.statements)).toBe(true); + if (action !== 'Delete') expect(result.metadata?.statements?.[0].parameters).toContain('PRIVATE-CUSTOMER'); + const entries = evidence.snapshot(); + expect(entries.map(entry => entry.operation)).toEqual([operation, 'select']); + expect(entries[1]?.tracePath.map(node => node.kind)).toEqual(['operation', 'request', 'provider', 'sql']); + expect(entries[1]?.tracePath[0].name).toBe('Customer'); + expect(entries[1]?.mutationLineage).toEqual(entries[0]?.mutationLineage); + expect(logs.map(entry => entry.operation)).toEqual([ + ...(mode & 1 ? [operation] : []), ...(mode & 2 ? ['select'] : []), + ]); + expect(JSON.stringify([logs, entries])).not.toContain('PRIVATE-CUSTOMER'); + expect(client.auditTrace.filter(event => event.reason !== 'seed readback fixture')).toHaveLength(1); + } finally { await client.close(); } + }); + +it('retains result facts without sinks and safely reprojects nested readbacks after debug revocation', async () => { + const previous = process.env[PLAINTEXT_LOG_ENV]; + const driver = new SQLiteDriver(':memory:'); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined); + try { + delete process.env[PLAINTEXT_LOG_ENV]; + await new UserContext().insertResource('dataService', client).ensureSchema(); + const result = await client.executeMutation({ entity: 'Customer', action: 'Create', id: '23', + payload: { name: 'PRIVATE-CUSTOMER', passwordHash: 'PASSWORD-CANARY' }, + comment: 'persist PRIVATE-CUSTOMER PASSWORD-CANARY' }); + expect(result.metadata?.statements?.map(entry => entry.operation)).toEqual(['insert', 'select']); + const safe = projectSQLLog(result.metadata!); + expect(JSON.stringify(safe)).not.toContain('PRIVATE-CUSTOMER'); + expect(safe.statements?.[1].comment).toBe('persist [REDACTED] [REDACTED]'); + expect(JSON.stringify(safe)).not.toContain('PASSWORD-CANARY'); + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const debug = projectSQLLog(result.metadata!); + expect(debug.statements?.[1].comment).toBe('persist PRIVATE-CUSTOMER [REDACTED]'); + expect(JSON.stringify(debug)).not.toContain('PASSWORD-CANARY'); + delete process.env[PLAINTEXT_LOG_ENV]; + expect(JSON.stringify(projectSQLLog(debug))).not.toContain('PRIVATE-CUSTOMER'); + expect(result.persistedRecord?.name).toBe('PRIVATE-CUSTOMER'); + expect(result.metadata?.comment).toBeUndefined(); + expect(result.metadata?.auditReason).toBe('persist PRIVATE-CUSTOMER PASSWORD-CANARY'); + } finally { + if (previous === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = previous; + await client.close(); + } +}); + +it.each(['Update', 'Delete'])('does not invent a readback or committed audit for unmatched %s', async action => { + const driver = new SQLiteDriver(':memory:'); + const evidence = new SQLExecutionEvidenceStore(); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined).setRuntimeTelemetrySink(evidence); + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + await expect(client.executeMutation({ entity: 'Customer', action, id: '99', version: 1, + payload: action === 'Delete' ? {} : { name: 'missing' }, comment: 'update absent fixture' })) + .rejects.toThrow('Optimistic lock failed'); + expect(evidence.snapshot()).toHaveLength(1); + expect(evidence.snapshot()[0]).toMatchObject({ operation: action.toLowerCase(), executionOutcome: 'success', affectedRows: 0 }); + expect(client.auditTrace).toHaveLength(0); + } finally { await client.close(); } +}); diff --git a/source/teaql-ts/tests/sql-relation-intent.test.ts b/source/teaql-ts/tests/sql-relation-intent.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..6a7914f66a904c165ab858a9ce2fb7077aa2fcfd --- /dev/null +++ b/source/teaql-ts/tests/sql-relation-intent.test.ts @@ -0,0 +1,116 @@ +import { SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { PLAINTEXT_LOG_ENV, PLAINTEXT_LOG_ACK, projectSQLLog } from '../src/core/log-privacy'; +import { AbstractSQLTeaQLClient, EntitySchema, SQLExecutionMetadata, SqlQueryResult } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +const column = (columnName: string, integer = false) => ({ columnName, + logicalType: integer ? 'integer' as const : 'text' as const, + decode: integer ? 'string' as const : 'native' as const, logPolicy: 'plain' as const }); +const schemas: Record = { + Customer: { table: 'customer_data', auditMaskFields: ['name'], columns: { + id: column('id', true), version: column('version', true), name: column('name'), password: column('password'), + }, relations: { orders: { targetEntity: 'Order', localKey: 'id', foreignKey: 'customerId', many: true } } }, + Order: { table: 'order_data', auditMaskFields: ['name'], columns: { + id: column('id', true), version: column('version', true), customerId: column('customer_id', true), name: column('name'), + }, relations: { lines: { targetEntity: 'Line', localKey: 'id', foreignKey: 'orderId', many: true } } }, + Line: { table: 'line_data', columns: { + id: column('id', true), version: column('version', true), orderId: column('order_id', true), + } }, +}; +class Driver extends SQLiteDriver { + failingTable?: string; + readonly failure = new Error('DRIVER-CANARY'); + readonly reads: Array<{ sql: string; values: any[] }> = []; + async query(sql: string, values: any[] = []): Promise { + if (sql.startsWith('SELECT')) { + this.reads.push({ sql, values: [...values] }); + if (this.failingTable && sql.includes(this.failingTable)) throw this.failure; + } + return super.query(sql, values); + } + async *stream(sql: string, values: any[] = []): AsyncIterable { + this.reads.push({ sql, values: [...values] }); + yield* super.stream(sql, values); + } +} +class Client extends AbstractSQLTeaQLClient { + readonly dispatched: string[] = []; + constructor(driver: Driver) { super(driver, schemas); } + override async executeQuery(query: any): Promise { + this.dispatched.push(query.entity); + return super.executeQuery(query); + } +} +async function fixture() { + const driver = new Driver(':memory:'); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const [entity, payload] of [ + ['Customer', { name: 'Riverside', password: 'PASSWORD-CANARY' }], + ['Order', { customerId: '1', name: 'Lakeside' }], + ['Line', { orderId: '1' }], + ] as const) await client.executeMutation({ entity, action: 'Create', id: '1', payload, comment: 'seed relation fixture' }); + const logs: SQLExecutionMetadata[] = []; + client.setDiagnosticSQLLogSink({ write: entry => logs.push(entry) }); + driver.reads.length = 0; + return { client, driver, logs }; +} +const previous = process.env[PLAINTEXT_LOG_ENV]; +beforeEach(() => { delete process.env[PLAINTEXT_LOG_ENV]; }); +afterEach(() => { + if (previous === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = previous; +}); + +const cases = ['batch', 'probe', 'window', 'aggregate', 'nested', 'stream'].flatMap(shape => + [false, true].flatMap(debug => [false, true].map(failure => ({ shape, debug, failure })))); +test.each(cases)('relation intent $shape debug=$debug failure=$failure', async ({ shape, debug, failure }) => { + const f = await fixture(); + try { + if (debug) process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + if (failure) f.driver.failingTable = shape === 'nested' ? 'line_data' : 'order_data'; + const query = new SelectQuery('Customer').filter({ name: { $eq: 'Riverside' }, password: { $eq: 'PASSWORD-CANARY' } }) + .limit(1).comment('what: load Riverside PASSWORD-CANARY details').purpose('why: verify derived query intent'); + const child = new SelectQuery('Order'); + if (shape === 'probe') child.limit(1).topNProbeParentThreshold(32); + if (shape === 'window') child.limit(1).topNProbeParentThreshold(0); + if (shape === 'nested') child.filter({ name: { $eq: 'Lakeside' } }).relationQuery('lines', new SelectQuery('Line').limit(2)); + if (shape === 'aggregate') query.relationAggregate('orders', 'count', child); + else if (shape === 'batch') query.relation('orders'); + else query.relationQuery('orders', child); + const execute = async () => { + if (shape !== 'stream') return f.client.executeQuery(query); + const rows: any[] = []; + for await (const chunk of f.client.executeForStream(query, 1)) rows.push(...chunk); + return rows; + }; + if (failure) await expect(execute()).rejects.toBe(f.driver.failure); + else expect(await execute()).toHaveLength(1); + expect(f.client.dispatched).toEqual(shape === 'stream' ? ['Order'] + : shape === 'nested' ? ['Customer', 'Order', 'Line'] : ['Customer', 'Order']); + expect(f.logs).toHaveLength(shape === 'nested' ? 3 : 2); + const entry = f.logs.find(item => item.parameterizedSQL.includes(shape === 'nested' ? 'line_data' : 'order_data'))!; + expect(entry.comment).toContain('what: load'); + expect(entry.purpose).toBe('why: verify derived query intent'); + expect(entry.executionOutcome).toBe(failure ? 'failure' : 'success'); + expect(entry.comment?.includes('Riverside')).toBe(debug); + expect(JSON.stringify(f.logs)).not.toContain('PASSWORD-CANARY'); + if (!debug) expect(JSON.stringify(f.logs)).not.toContain('Riverside'); + expect(entry.debugSQL).toContain(shape === 'nested' ? 'line_data' : 'order_data'); + expect(entry.parameters).toHaveLength(f.driver.reads[f.driver.reads.length - 1].values.length); + expect(f.driver.reads[0].values).toContain('PASSWORD-CANARY'); + if (shape === 'batch') expect(entry.parameterizedSQL).toContain(' IN ('); + if (shape === 'window') expect(entry.parameterizedSQL).toMatch(/ROW_NUMBER\(\) OVER/i); + if (shape === 'probe') { + expect(entry.parameterizedSQL).not.toContain(' IN ('); + expect(entry.parameterizedSQL).not.toMatch(/ROW_NUMBER/i); + } + delete process.env[PLAINTEXT_LOG_ENV]; + expect(JSON.stringify(projectSQLLog(entry))).not.toMatch(/Riverside|PASSWORD-CANARY/); + f.driver.failingTable = undefined; + await f.client.executeQuery(new SelectQuery('Customer').limit(1) + .comment('what: independent Riverside').purpose('why: verify provenance isolation')); + expect(f.logs[f.logs.length - 1].comment).toBe('what: independent Riverside'); + } finally { await f.client.close(); } +}); diff --git a/source/teaql-ts/tests/sql-relation-membership.test.ts b/source/teaql-ts/tests/sql-relation-membership.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..30744b2462e9527c57202291605fb0764b912af8 --- /dev/null +++ b/source/teaql-ts/tests/sql-relation-membership.test.ts @@ -0,0 +1,139 @@ +import { SelectQuery, OrderBy } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { AbstractSQLTeaQLClient, EntitySchema, SQLExecutionEvidenceStore, SQLExecutionMetadata, SqlQueryResult } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +const column = (columnName: string, integer = false) => ({ columnName, + logicalType: integer ? 'integer' as const : 'text' as const, + decode: integer ? 'string' as const : 'native' as const, logPolicy: 'plain' as const }); +const identity = { id: column('id', true), version: column('version', true) }; +const model: Record = { + Owner: { table: 'owner_data', auditMaskFields: [], columns: identity, + relations: { parents: { targetEntity: 'Parent', localKey: 'id', foreignKey: 'ownerId', many: true } } }, + Parent: { table: 'parent_data', auditMaskFields: ['name'], columns: { + ...identity, ownerId: column('owner_id', true), code: column('code'), name: column('name'), + }, relations: { children: { targetEntity: 'Child', localKey: 'code', foreignKey: 'parentRef', many: true } } }, + Child: { table: 'child_data', auditMaskFields: [], columns: { ...identity, parentRef: column('parent_ref') }, + relations: { + parentRef: { targetEntity: 'Parent', localKey: 'parentRef', foreignKey: 'code', many: false }, + parentAgain: { targetEntity: 'Parent', localKey: 'parentRef', foreignKey: 'code', many: false }, + } }, +}; +class Driver extends SQLiteDriver { + reads = 0; + async query(sql: string, values: any[] = []): Promise { + if (sql.startsWith('SELECT')) this.reads++; + return super.query(sql, values); + } + async *stream(sql: string, values: any[] = []): AsyncIterable { + this.reads++; + yield* super.stream(sql, values); + } +} +class Client extends AbstractSQLTeaQLClient { + constructor(driver: Driver, schemas = model) { super(driver, schemas); } +} +async function fixture() { + const driver = new Driver(':memory:'); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const [entity, id, payload] of [ + ['Owner', '1', {}], + ['Parent', '1', { ownerId: '1', code: 'P-A', name: 'PRIVATE-PARENT' }], + ['Parent', '2', { ownerId: '1', code: 'P-B', name: 'PRIVATE-EMPTY' }], + ['Child', '1', { parentRef: 'P-A' }], ['Child', '2', { parentRef: 'P-A' }], + ] as const) await client.executeMutation({ entity, id, action: 'Create', payload, + comment: 'seed native relation membership fixture' }); + const evidence = new SQLExecutionEvidenceStore(); + const logs: SQLExecutionMetadata[] = []; + client.setRuntimeTelemetrySink(evidence); + client.setDiagnosticSQLLogSink({ write: entry => logs.push(entry) }); + driver.reads = 0; + return { client, driver, evidence, logs }; +} +const cases = ['list', 'stream-full', 'stream-tail'].flatMap(mode => + [false, true].flatMap(nested => [false, true].flatMap(logging => + ['scalar-control', 'visible', 'filtered', 'filtered-sibling'].map(shape => ({ mode, nested, logging, shape }))))); +test.each(cases)('membership $mode nested=$nested logging=$logging $shape', async ({ mode, nested, logging, shape }) => { + const f = await fixture(); + try { + f.client.setQueryLoggingEnabled(logging); + const child = new SelectQuery('Child').order(OrderBy.asc('id')).limit(10).topNProbeParentThreshold(0) + .relationAggregate('parentRef', 'parentCount', new SelectQuery('Parent')); + if (shape !== 'scalar-control') child.relationQuery('parentRef', new SelectQuery('Parent') + .filter({ name: { $eq: shape === 'visible' ? 'PRIVATE-PARENT' : 'NOT-VISIBLE' } })); + if (shape === 'filtered-sibling') child.relationQuery('parentAgain', new SelectQuery('Parent')); + const parents = new SelectQuery('Parent').order(OrderBy.asc('id')).limit(2).topNProbeParentThreshold(0) + .relationQuery('children', child); + const query = (nested ? new SelectQuery('Owner').limit(1).relationQuery('parents', parents) : parents) + .comment('load parent membership').purpose('verify scalar keys across relation hydration'); + const rows: any[] = []; + if (mode === 'list') rows.push(...await f.client.executeQuery(query)); + else for await (const chunk of f.client.executeForStream(query, mode === 'stream-full' ? 1 : 3)) rows.push(...chunk); + const loaded = nested ? rows[0].parents : rows; + expect(loaded).toHaveLength(2); + expect(loaded[0].children).toHaveLength(2); + expect(loaded[1].children).toEqual([]); + for (const row of loaded[0].children) { + expect(row.parentCount).toBe(1); + if (shape === 'scalar-control') expect(row.parentRef).toBe('P-A'); + else if (shape === 'visible') expect(row.parentRef.code).toBe('P-A'); + else { + expect(row.parentRef).toEqual({ code: 'P-A' }); + expect(Object.prototype.hasOwnProperty.call(row.parentRef, 'name')).toBe(false); + } + if (shape === 'filtered-sibling') expect(row.parentAgain.code).toBe('P-A'); + } + const expected = 4 + Number(nested) + Number(mode === 'stream-full' && !nested) + - Number(shape === 'scalar-control') + Number(shape === 'filtered-sibling'); + expect(f.driver.reads).toBe(expected); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(expected); + expect(f.logs).toHaveLength(logging ? expected : 0); + { + expect(entries.every(e => e.comment === 'load parent membership' && e.purpose === query.purposeText)).toBe(true); + expect(JSON.stringify(entries)).not.toContain('PRIVATE-PARENT'); + const count = entries.find(e => /COUNT\(/i.test(e.parameterizedSQL))!; + expect(count.tracePath.map(frame => [frame.kind, frame.name])).toEqual([ + ['operation', query.entity], ['request', query.entity], + ...(nested ? [['relation', 'parents']] : []), ['relation', 'children'], ['relation', 'parentRef'], + ['provider', 'sqlite'], ['sql', 'select'], + ]); + } + const plain = await f.client.executeQuery(new SelectQuery('Child').limit(2) + .comment('independent request').purpose('verify no assembly state escapes')); + expect(plain.map(row => row.parentRef)).toEqual(['P-A', 'P-A']); + expect(plain.map(row => Object.keys(row).sort())).toEqual([['id', 'parentRef', 'version'], ['id', 'parentRef', 'version']]); + const final = f.evidence.snapshot(); + expect(final[final.length - 1].tracePath.map(frame => frame.kind)) + .toEqual(['operation', 'request', 'provider', 'sql']); + } finally { await f.client.close(); } +}); + +test('ID reference keeps identity while actual SQL NULL stays null', async () => { + const driver = new Driver(':memory:'); + const client = new Client(driver, { + Parent: model.Parent, + Child: { ...model.Child, columns: { ...identity, parentRef: column('parent_ref', true) }, + relations: { parent: { targetEntity: 'Parent', localKey: 'parentRef', foreignKey: 'id', many: false } } }, + }).setDiagnosticSQLLogSink(undefined); + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const [entity, id, payload] of [ + ['Parent', '1', { name: 'visible' }], + ['Child', '1', { parentRef: '1' }], ['Child', '2', { parentRef: null }], + ] as const) await client.executeMutation({ entity, id, action: 'Create', payload, + comment: 'seed nullable ID reference' }); + const plain = await client.executeQuery(new SelectQuery('Child').select(['id']).limit(2) + .comment('load identity only').purpose('prove unrequested relation stays absent')); + expect(plain.every(row => !Object.prototype.hasOwnProperty.call(row, 'parent'))).toBe(true); + const rows = await client.executeQuery(new SelectQuery('Child').select(['id']) + .order(OrderBy.asc('id')).limit(2).relationQuery('parent', new SelectQuery('Parent') + .filter({ name: { $eq: 'absent' } })) + .comment('load filtered ID references').purpose('distinguish NotLoaded details from SQL NULL')); + expect(rows[0].parent).toEqual({ id: '1' }); + expect(rows[0].parentRef).toBe('1'); + expect(rows[1].parent).toBeNull(); + expect(rows[1].parentRef).toBeNull(); + } finally { await client.close(); } +}); diff --git a/source/teaql-ts/tests/sql-relation.test.ts b/source/teaql-ts/tests/sql-relation.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..465cfeee27eaeb81885ae8becd1ea95ad35cf4cf --- /dev/null +++ b/source/teaql-ts/tests/sql-relation.test.ts @@ -0,0 +1,425 @@ +import { UserContext } from '../src/core/context'; +import { OrderBy, SelectQuery } from '../src/core/ast'; +import { EntitySchema } from '../src/sql/core'; +import { SQLiteDriver, SQLiteTeaQLClient } from '../src/sql/sqlite'; +import { executeRelationFacets } from '../src/core/facet'; +import { RuntimeOperation, RuntimeTelemetry } from '../src/core/telemetry'; + +const schemas: Record = { + Order: { + table: 'orders', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + }, + relations: { + lines: { targetEntity: 'OrderLine', localKey: 'id', foreignKey: 'orderId', many: true }, + }, + }, + OrderLine: { + table: 'orderline', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + orderId: { columnName: 'order_id', logicalType: 'integer', decode: 'string' }, + name: { columnName: 'name', logicalType: 'text', decode: 'native' }, + state: { columnName: 'state', logicalType: 'text', decode: 'native' }, + amount: { columnName: 'amount', logicalType: 'decimal', decode: 'number' }, + }, + }, + QueryRecord: { + table: 'query_record', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + requiredText: { columnName: 'required_text', logicalType: 'text', decode: 'native' }, + optionalText: { columnName: 'optional_text', logicalType: 'text', decode: 'native' }, + requiredInteger: { columnName: 'required_integer', logicalType: 'integer', decode: 'number' }, + optionalLong: { columnName: 'optional_long', logicalType: 'integer', decode: 'string' }, + requiredDecimal: { columnName: 'required_decimal', logicalType: 'decimal', decode: 'string' }, + requiredFloat: { columnName: 'required_float', logicalType: 'double', decode: 'number' }, + requiredDouble: { columnName: 'required_double', logicalType: 'double', decode: 'number' }, + requiredDate: { columnName: 'required_date', logicalType: 'date', decode: 'date' }, + requiredTime: { columnName: 'required_time', logicalType: 'integer', decode: 'number' }, + requiredTimestamp: { columnName: 'required_timestamp', logicalType: 'datetime', decode: 'date' }, + active: { columnName: 'active', logicalType: 'boolean', decode: 'native' }, + reviewed: { columnName: 'reviewed', logicalType: 'boolean', decode: 'native' }, + }, + }, +}; + +describe('SQLite relation loading', () => { + it('executes the complete scalar fixture including nullable boolean on SQLite', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + const rows = [ + ['1', 'Alpha', 'optional', 42, '42000000000', '42.125', 42.5, 42.75, '2026-08-29', 34_200_000, '2026-08-29T09:30:00.000Z', true, false], + ['2', 'Beta', null, 7, null, '7.500', 7.5, 7.75, '2026-08-30', 36_000_000, '2026-08-30T10:00:00.000Z', false, null], + ['3', 'Gamma', 'tail', 99, '99000000000', '99.875', 99.5, 99.75, '2026-08-31', 37_800_000, '2026-08-31T10:30:00.000Z', true, true], + ] as const; + for (const [id, requiredText, optionalText, requiredInteger, optionalLong, + requiredDecimal, requiredFloat, requiredDouble, requiredDate, requiredTime, + requiredTimestamp, active, reviewed] of rows) { + await client.executeMutation({ + entity: 'QueryRecord', action: 'Create', id, + payload: { + requiredText, optionalText, requiredInteger, optionalLong, requiredDecimal, + requiredFloat, requiredDouble, requiredDate: new Date(`${requiredDate}T00:00:00.000Z`), + requiredTime, requiredTimestamp: new Date(requiredTimestamp), active, reviewed, + }, + comment: 'seed complete query scalar fixture', + }); + } + + const query = (filter: Record) => client.executeQuery( + new SelectQuery('QueryRecord').filter(filter) + .comment('what: execute complete scalar predicate') + .purpose('why: retain Query conformance evidence') + .order(OrderBy.asc('id')), + ); + expect((await query({ requiredText: { $eq: 'Alpha' } })).map(row => row.id)).toEqual(['1']); + expect((await query({ requiredText: { $ne: 'Alpha' } })).map(row => row.id)).toEqual(['2', '3']); + expect((await query({ requiredText: { $in: ['Alpha', 'Gamma'] } })).map(row => row.id)).toEqual(['1', '3']); + expect((await query({ requiredText: { $startsWith: 'Al' } })).map(row => row.id)).toEqual(['1']); + expect((await query({ requiredText: { $endsWith: 'ma' } })).map(row => row.id)).toEqual(['3']); + expect((await query({ requiredText: { $contains: 'et' } })).map(row => row.id)).toEqual(['2']); + expect((await query({ requiredInteger: { $between: [40, 100] } })).map(row => row.id)).toEqual(['1', '3']); + expect((await query({ requiredDecimal: { $gt: '50' } })).map(row => row.id)).toEqual(['3']); + expect((await query({ requiredFloat: { $lte: 7.5 } })).map(row => row.id)).toEqual(['2']); + expect((await query({ requiredDouble: { $gte: 99.75 } })).map(row => row.id)).toEqual(['3']); + expect((await query({ requiredDate: { $between: [new Date('2026-08-30T00:00:00.000Z'), new Date('2026-08-31T00:00:00.000Z')] } })).map(row => row.id)).toEqual(['2', '3']); + expect((await query({ requiredTime: { $gt: 36_000_000 } })).map(row => row.id)).toEqual(['3']); + expect((await query({ requiredTimestamp: { $lt: new Date('2026-08-30T12:00:00.000Z') } })).map(row => row.id)).toEqual(['1', '2']); + expect((await query({ optionalText: { $isNull: true } })).map(row => row.id)).toEqual(['2']); + expect((await query({ optionalLong: { $isNull: false } })).map(row => row.id)).toEqual(['1', '3']); + expect((await query({ active: { $eq: false } })).map(row => row.id)).toEqual(['2']); + expect((await query({ reviewed: { $eq: true } })).map(row => row.id)).toEqual(['3']); + expect((await query({ reviewed: { $eq: false } })).map(row => row.id)).toEqual(['1']); + expect((await query({ reviewed: { $isNull: true } })).map(row => row.id)).toEqual(['2']); + await client.close(); + }); + + it('executes positive and negative relation subqueries with bound values', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + await client.executeMutation({ entity: 'Order', action: 'Create', id: '1', payload: {}, comment: 'seed first order' }); + await client.executeMutation({ entity: 'Order', action: 'Create', id: '2', payload: {}, comment: 'seed second order' }); + await client.executeMutation({ entity: 'Order', action: 'Create', id: '3', payload: {}, comment: 'seed empty order' }); + await client.executeMutation({ entity: 'OrderLine', action: 'Create', id: '11', payload: { orderId: '1', name: 'included' }, comment: 'seed included line' }); + await client.executeMutation({ entity: 'OrderLine', action: 'Create', id: '12', payload: { orderId: '2', name: 'excluded' }, comment: 'seed excluded line' }); + await client.executeMutation({ entity: 'OrderLine', action: 'Create', id: '13', payload: { orderId: null, name: 'orphan' }, comment: 'seed orphan line' }); + const firstOrder = new SelectQuery('Order').filter({ id: { $eq: '1' } }); + + const included = await client.executeQuery( + new SelectQuery('OrderLine') + .filter({ orderId: { $inSubquery: { query: firstOrder, field: 'id' } } }) + .comment('what: select lines of first order') + .purpose('why: verify positive relation predicate'), + ); + const excluded = await client.executeQuery( + new SelectQuery('OrderLine') + .filter({ orderId: { $notInSubquery: { query: firstOrder, field: 'id' } } }) + .comment('what: exclude lines of first order') + .purpose('why: verify negative relation predicate'), + ); + + expect(included.map(row => row.name)).toEqual(['included']); + expect(excluded.map(row => row.name)).toEqual(['excluded']); + + const lineIds = async (filter: Record) => (await client.executeQuery( + new SelectQuery('OrderLine').filter(filter).order(OrderBy.asc('id')) + .comment('what: execute complete forward relation predicate') + .purpose('why: retain complete relation fixture evidence'), + )).map(row => row.id); + const orderIds = async (filter: Record) => (await client.executeQuery( + new SelectQuery('Order').filter(filter).order(OrderBy.asc('id')) + .comment('what: execute complete reverse relation predicate') + .purpose('why: retain complete relation fixture evidence'), + )).map(row => row.id); + expect(await lineIds({ orderId: { $isNull: false } })).toEqual(['11', '12']); + expect(await lineIds({ orderId: { $isNull: true } })).toEqual(['13']); + expect(await lineIds({ orderId: { $inSubquery: { query: firstOrder, field: 'id' } } })).toEqual(['11']); + expect(await lineIds({ orderId: { $notInSubquery: { query: firstOrder, field: 'id' } } })).toEqual(['12']); + + const allLines = new SelectQuery('OrderLine'); + expect(await orderIds({ id: { $inSubquery: { query: allLines, field: 'orderId' } } })).toEqual(['1', '2']); + expect(await orderIds({ id: { $notInSubquery: { query: allLines, field: 'orderId' } } })).toEqual(['3']); + expect(client.sqlTrace.some(sql => sql.includes(' IN (SELECT '))).toBe(true); + expect(client.sqlTrace.some(sql => sql.includes(' NOT IN (SELECT '))).toBe(true); + await client.close(); + }); + + it('counts the exact filtered set without page, order, projection, or relations', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const id of ['11', '12', '13', '14', '15', '16']) { + await client.executeMutation({ entity: 'Order', action: 'Create', id, payload: {}, comment: 'seed page' }); + } + const query = new SelectQuery('Order') + .filter({ id: { $lte: '15' } }).order(OrderBy.asc('id')).offset(2).limit(2) + .relationQuery('lines', new SelectQuery('OrderLine')) + .purpose('render page').comment('list filtered orders'); + const rows = await client.executeQuery(query); + const total = await client.executeCount(query); + expect(rows.map(row => row.id)).toEqual(['13', '14']); + expect(total).toBe(5); + const countSql = client.sqlTrace[client.sqlTrace.length - 1]; + expect(countSql).toContain('COUNT('); + expect(countSql).not.toContain(' ORDER BY '); + expect(countSql).not.toContain(' OFFSET '); + await client.close(); + }); + it('enforces the formal runtime hard limit at the SQL list boundary', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + const query = new SelectQuery('Order').purpose('test hard limit').comment('bounded list'); + + await client.executeQuery(query); + + expect(query.limitValue).toBe(10_000); + expect(client.sqlTrace[client.sqlTrace.length - 1]).toContain(' LIMIT '); + await expect(client.executeQuery( + new SelectQuery('Order') + .purpose('test hard limit rejection') + .comment('reject oversized list') + .limit(10_001), + )).rejects.toThrow('QUERY_HARD_LIMIT_EXCEEDED'); + await client.close(); + }); + + it('enforces runtime governance and sends immutable audit events to the app sink', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + await expect(client.executeQuery(new SelectQuery('Order'))).rejects.toMatchObject({ + code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'query', + }); + await expect(client.executeMutation({ entity: 'Order', action: 'Create', payload: {} })) + .rejects.toMatchObject({ code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'mutation' }); + const sink: Readonly>[] = []; + client.setAuditSink(event => { sink.push(event); }); + await client.executeMutation({ entity: 'Order', action: 'Create', id: '10', payload: {}, comment: 'create governed order' }); + expect(client.auditTrace).toHaveLength(1); + expect(sink).toHaveLength(1); + expect(Object.isFrozen(sink[0])).toBe(true); + expect(sink[0].reason).toBe('create governed order'); + await client.close(); + }); + + it('executes inclusive range and IN predicates in SQL', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const id of ['11', '12', '13']) { + await client.executeMutation({ entity: 'Order', action: 'Create', id, payload: {}, comment: 'seed order' }); + } + const rows = await client.executeQuery( + new SelectQuery('Order').purpose('test range').comment('range query').filter({ + $and: [ + { id: { $in: ['11', '12', '99'] } }, + { id: { $gte: '11' } }, + { id: { $lte: '12' } }, + ], + }).order(OrderBy.asc('id')), + ); + expect(rows.map(row => row.id)).toEqual(['11', '12']); + const sql = client.sqlTrace[client.sqlTrace.length - 1]; + expect(sql).toContain(' IN ('); + expect(sql).toContain(' >= '); + expect(sql).toContain(' <= '); + await client.close(); + }); + + it('registers Soundex during ensureSchema and executes SoundingLike on SQLite', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const [id, name] of [['101', 'Robert'], ['102', 'Rupert'], ['103', 'Alice']]) { + await client.executeMutation({ entity: 'OrderLine', action: 'Create', id, payload: { name }, comment: 'seed phonetic query' }); + } + const rows = await client.executeQuery( + new SelectQuery('OrderLine').purpose('test phonetic query').comment('execute registered soundex') + .filter({ name: { $soundLike: 'Robert' } }).order(OrderBy.asc('id')), + ); + expect(rows.map(row => row.name)).toEqual(['Robert', 'Rupert']); + await client.close(); + }); + + it('computes relation facet membership with grouped SQL and include-all semantics', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const id of ['11', '12', '13']) { + await client.executeMutation({ entity: 'Order', action: 'Create', id, payload: {}, comment: 'seed order facet' }); + } + for (const [id, orderId, name, amount] of [ + ['101', '11', 'Riverside one', 120], ['102', '11', 'Riverside two', 80], ['103', '12', 'Other', 50], + ]) { + await client.executeMutation({ + entity: 'OrderLine', action: 'Create', id, payload: { orderId, name, amount }, comment: 'seed line facet', + }); + } + const outer = new SelectQuery('OrderLine') + .purpose('render order facet').comment('count Riverside lines') + .filter({ name: { $contains: 'Riverside' } }); + outer.facetBy('orders', 'orderId', { + toQuery: () => new SelectQuery('Order') + .aggregate('Count', 'id', 'lineCount') + .aggregate('Sum', 'amount', 'totalAmount') + .purpose('render order facet').comment('load order facet values'), + }); + + const facets = await executeRelationFacets(client, query => query, outer, outer.facets); + expect(facets.orders.map(row => [row.id, row.lineCount, row.totalAmount])).toEqual([ + ['11', 2, 200], ['12', 0, 0], ['13', 0, 0], + ]); + expect(client.sqlTrace.some(sql => sql.includes('GROUP BY') + && sql.includes('COUNT(') && sql.includes('SUM('))).toBe(true); + await client.close(); + }); + + it('applies nested limit independently to every parent', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const orderId of ['11', '12']) { + await client.executeMutation({ entity: 'Order', action: 'Create', id: orderId, payload: {}, comment: 'seed order' }); + for (let index = 1; index <= 5; index++) { + const id = `${orderId}${index}`; + await client.executeMutation({ + entity: 'OrderLine', + action: 'Create', + id, + payload: { orderId, name: `line-${id}` }, + comment: 'seed line', + }); + } + } + const query = new SelectQuery('Order').purpose('test relations').comment('relation query') + .order(OrderBy.asc('id')) + .relationQuery('lines', new SelectQuery('OrderLine').order(OrderBy.desc('id')).limit(3)); + + const rows = await client.executeQuery(query); + + expect(rows).toHaveLength(2); + expect(rows.map(row => row.lines.length)).toEqual([3, 3]); + expect(rows.flatMap(row => row.lines).every( + (line: any) => line.__teaql_partition_rank === undefined, + )).toBe(true); + await client.close(); + }); + + it('loads relation assembly keys implicitly without exposing them in the requested shape', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + await client.executeMutation({ + entity: 'Order', action: 'Create', id: '21', payload: {}, comment: 'seed projected relation parent', + }); + await client.executeMutation({ + entity: 'OrderLine', action: 'Create', id: '211', + payload: { orderId: '21', name: 'visible name', state: 'internal state' }, + comment: 'seed projected relation child', + }); + const child = new SelectQuery('OrderLine').select(['name']); + const rows = await client.executeQuery( + new SelectQuery('Order') + .relationQuery('lines', child) + .comment('what: load a projected child relation') + .purpose('why: prove relation keys remain runtime-internal'), + ); + + expect(child.selectItems).toEqual(['name']); + expect(rows[0].lines).toHaveLength(1); + expect(rows[0].lines[0]).toMatchObject({ name: 'visible name' }); + expect(rows[0].lines[0]).not.toHaveProperty('orderId'); + expect(rows[0].lines[0]).not.toHaveProperty('state'); + expect(client.sqlTrace[1]).toContain('order_id'); + await client.close(); + }); + + it('TOPN-001..011 selects governed plans with equivalent SQLite results', async () => { + const operations: RuntimeOperation[] = []; + const telemetry: RuntimeTelemetry = { + start(operation) { + operations.push(operation); + return { success: () => undefined, failure: () => undefined }; + }, + }; + const client = new SQLiteTeaQLClient(':memory:', schemas).setRuntimeTelemetry(telemetry); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const orderId of ['1', '2', '3']) { + await client.executeMutation({ + entity: 'Order', action: 'Create', id: orderId, payload: {}, comment: 'seed Top-N order', + }); + } + for (const [id, orderId, state] of [ + ['11', '1', 'visible'], ['12', '1', 'visible'], ['13', '1', 'visible'], + ['14', '1', 'hidden'], ['21', '2', 'visible'], ['22', '2', 'visible'], + ['23', '2', 'visible'], + ]) { + await client.executeMutation({ + entity: 'OrderLine', action: 'Create', id, + payload: { orderId, name: 'same', state }, comment: 'seed Top-N line', + }); + } + + const load = async (threshold?: number) => { + client.sqlTrace.length = 0; + const child = new SelectQuery('OrderLine') + .filter({ state: { $eq: 'visible' } }) + .order(OrderBy.desc('name')).limit(2); + if (threshold !== undefined) child.topNProbeParentThreshold(threshold); + const rows = await client.executeQuery( + new SelectQuery('Order').order(OrderBy.asc('id')) + .relationQuery('lines', child) + .comment('what: load per-parent Top-N fixture') + .purpose('why: verify plan equivalence'), + ); + return { + result: Object.fromEntries(rows.map(row => [row.id, row.lines.map((line: any) => line.id)])), + sql: [...client.sqlTrace], + }; + }; + + const probe = await load(); + const window = await load(0); + expect(probe.result).toEqual(window.result); + expect(window.result).toEqual({ '1': ['11', '12'], '2': ['21', '22'], '3': [] }); + expect(probe.sql).toHaveLength(4); + expect(window.sql).toHaveLength(2); + expect(window.sql[1]).toContain('ROW_NUMBER() OVER'); + expect([...probe.sql, ...window.sql].some(sql => /count\s*\(/i.test(sql))).toBe(false); + + expect((await load(3)).sql).toHaveLength(4); + expect((await load(2)).sql).toHaveLength(2); + expect((await load(3)).result).toEqual((await load(3)).result); + + client.sqlTrace.length = 0; + const empty = await client.executeQuery( + new SelectQuery('Order').filter({ id: { $eq: '999' } }) + .relationQuery('lines', new SelectQuery('OrderLine').limit(2)) + .comment('what: load empty Top-N parents').purpose('why: verify typed empty result'), + ); + expect(empty).toEqual([]); + expect(client.sqlTrace).toHaveLength(1); + + const relationOperation = [...operations].reverse().find(operation => + operation.family === 'relation_load' && operation.attributes?.['teaql.relation.parent_count'] === 3, + ); + expect(relationOperation?.attributes).toMatchObject({ + 'teaql.relation.parent_count': 3, + 'teaql.relation.per_parent_limit': 2, + 'teaql.relation.configured_probe_threshold': 3, + 'teaql.relation.selected_plan': 'bounded_probes', + 'teaql.relation.probe_count': 3, + }); + await client.close(); + }); + + it('TOPN-012 ensures the canonical relation index idempotently on SQLite', async () => { + const driver = new SQLiteDriver(':memory:'); + await driver.ensureSchema(schemas); + await driver.ensureSchema(schemas); + const indexes = await driver.query( + "SELECT name, sql FROM sqlite_master WHERE type='index' " + + "AND tbl_name='orderline' AND name='idx_orderline_order_id_id'", + ); + expect(indexes.rows).toHaveLength(1); + await driver.close(); + }); +}); diff --git a/source/teaql-ts/tests/sql-stream.test.ts b/source/teaql-ts/tests/sql-stream.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..9b85d9895b3309ccb6a8914bb98ab54c0f3f9f92 --- /dev/null +++ b/source/teaql-ts/tests/sql-stream.test.ts @@ -0,0 +1,94 @@ +import { UserContext } from '../src/core/context'; +import { OrderBy, SelectQuery } from '../src/core/ast'; +import { EntitySchema, SQLExecutionEvidenceStore } from '../src/sql/core'; +import { QueryRequest } from '../src/core/request-intent'; +import { SQLiteTeaQLClient } from '../src/sql/sqlite'; +import { PostgreSQLDriver } from '../src/sql/postgres'; +import { MySQLDriver } from '../src/sql/mysql'; + +const schemas: Record = { + Order: { + table: 'orders', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + }, + }, +}; + +describe('SQLite true streaming query', () => { + it.each([true, false])('preserves a native named-count owner on a real cursor, logging=%p', async logging => { + const client = new SQLiteTeaQLClient(':memory:', schemas).setDiagnosticSQLLogSink(undefined); + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (const id of ['1', '2']) await client.executeMutation({entity:'Order', action:'Create', id, + payload:{}, comment:'seed native cursor fixture'}); + const evidence = new SQLExecutionEvidenceStore(), diagnostics: unknown[] = []; + client.setRuntimeTelemetrySink(evidence).setDiagnosticSQLLogSink({write: entry => diagnostics.push(entry)}) + .setQueryLoggingEnabled(logging); + const root = new QueryRequest(new SelectQuery('Order').comment('load order totals').purpose('render totals')); + const counted = root.deriveOperation(root.query.forExactCount('totalOrders'), + {kind:'named-count',method:'countAs',alias:'totalOrders'}); + const chunks: any[][] = []; + for await (const chunk of client.executeForStream(counted.query, 1)) chunks.push(chunk); + expect(chunks.flat().map(row=>row.totalOrders)).toEqual([2]); + const entries = evidence.snapshot(); + expect(entries).toHaveLength(1); expect(diagnostics).toHaveLength(logging ? 1 : 0); + expect(entries[0].traceChain?.map(node=>node.detail)).toEqual(['render totals','load order totals',"countAs('totalOrders')"]); + expect(entries[0].executionOutcome).toBe('success'); + expect((entries[0].tracePath ?? []).some(node=>node.kind==='relation')).toBe(false); + expect(root.traceChain).toHaveLength(2); + } finally { await client.close(); } + }); + + it('yields bounded chunks from the statement iterator', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + for (let id = 1; id <= 5; id++) { + await client.executeMutation({ + entity: 'Order', action: 'Create', id: String(id), payload: {}, comment: 'seed stream fixture', + }); + } + const query = new SelectQuery('Order') + .comment('stream orders') + .purpose('verify cursor streaming') + .order(OrderBy.asc('id')); + const chunks: any[][] = []; + for await (const chunk of client.executeForStream(query, 2)) chunks.push(chunk); + expect(chunks.map(chunk => chunk.length)).toEqual([2, 2, 1]); + expect(chunks.flat().map(row => row.id)).toEqual(['1', '2', '3', '4', '5']); + await client.close(); + }); + + it('rejects missing governance and invalid chunk sizes at iteration time', async () => { + const client = new SQLiteTeaQLClient(':memory:', schemas); + await new UserContext().insertResource('dataService', client).ensureSchema(); + const consume = async (stream: AsyncIterable) => { + for await (const _chunk of stream) { /* consume */ } + }; + await expect(consume(client.executeForStream(new SelectQuery('Order'), 10))) + .rejects.toMatchObject({ code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'query' }); + const query = new SelectQuery('Order').comment('invalid size').purpose('verify validation'); + await expect(consume(client.executeForStream(query, 0))).rejects.toThrow(/positive integer/); + await client.close(); + }); +}); + +describe('real SQL driver streams', () => { + for (const [name, envName, createDriver, sql] of [ + ['PostgreSQL', 'TEAQL_TEST_POSTGRES_URL', (url: string) => new PostgreSQLDriver(url), + 'SELECT id FROM (VALUES (1), (2), (3), (4), (5)) AS fixture(id) ORDER BY id'], + ['MySQL', 'TEAQL_TEST_MYSQL_URL', (url: string) => new MySQLDriver(url), + 'SELECT id FROM (SELECT 1 id UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5) fixture ORDER BY id'], + ] as const) (process.env[envName] ? it : it.skip)(`streams rows from ${name}`, async () => { + const url = process.env[envName]; + const driver = createDriver(url!); + const ids: number[] = []; + try { + for await (const row of driver.stream(sql)) ids.push(Number(row.id)); + } finally { + await driver.close(); + } + expect(ids).toEqual([1, 2, 3, 4, 5]); + }); +}); diff --git a/source/teaql-ts/tests/sql-telemetry-correlation.test.ts b/source/teaql-ts/tests/sql-telemetry-correlation.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..c24efb316d1516d587edd3c2d05f104e93e0313c --- /dev/null +++ b/source/teaql-ts/tests/sql-telemetry-correlation.test.ts @@ -0,0 +1,135 @@ +import { context, trace, ROOT_CONTEXT } from '@opentelemetry/api'; +import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks'; +import { BasicTracerProvider, SimpleSpanProcessor, InMemorySpanExporter } from '@opentelemetry/sdk-trace-base'; +import { LoggerProvider, SimpleLogRecordProcessor, InMemoryLogRecordExporter } from '@opentelemetry/sdk-logs'; +import { MeterProvider } from '@opentelemetry/sdk-metrics'; +import { OpenTelemetryRuntimeTelemetry } from '../src/telemetry/opentelemetry'; +import { AbstractSQLTeaQLClient, EntitySchema } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; +import { SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; + +test('a broken optional SQL-diagnostic capability cannot change a real query result or expose its error', async () => { + const warning = jest.spyOn(console, 'warn').mockImplementation(() => {}); + const diagnostic = jest.fn(); + class Client extends AbstractSQLTeaQLClient { + constructor() {super(new SQLiteDriver(':memory:'), {School: {table:'school_data',columns:{ + id:{columnName:'id',logicalType:'integer',decode:'string'},version:{columnName:'version',logicalType:'integer',decode:'number'}, + }}});} + } + const client = new Client().setDiagnosticSQLLogSink(undefined).setRuntimeTelemetry({ + start: () => ({success() {},failure() {}}), recordDiagnostic: diagnostic, + recordsSQLDiagnostics: () => {throw new Error('PRIVATE-CUSTOM-CAPABILITY');}, + }); + try { + await new UserContext().insertResource('dataService',client).ensureSchema(); + const rows = await client.executeQuery(new SelectQuery('School').limit(1) + .comment('inspect empty fixture').purpose('verify fail-open capability')); + expect(rows).toEqual([]);expect(diagnostic).not.toHaveBeenCalled(); + expect(JSON.stringify(warning.mock.calls)).not.toContain('PRIVATE-CUSTOM-CAPABILITY'); + } finally {await client.close();warning.mockRestore();} +}); + +test('out-of-order SQL completion retains its own span and does not replace global SDK context', async () => { + const beforeProvider = trace.getTracerProvider(); + const beforeContext = context.active(); + const manager = new AsyncLocalStorageContextManager().enable(); + const spanExporter = new InMemorySpanExporter(); + const logExporter = new InMemoryLogRecordExporter(); + const tracerProvider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(spanExporter)] }); + const loggerProvider = new LoggerProvider({ processors: [new SimpleLogRecordProcessor({ exporter: logExporter })] }); + const meterProvider = new MeterProvider(); + const telemetry = new OpenTelemetryRuntimeTelemetry(tracerProvider.getTracer('io.teaql.runtime'), + meterProvider.getMeter('io.teaql.runtime'), {}, loggerProvider.getLogger('io.teaql.runtime'), { + active: () => manager.active() === ROOT_CONTEXT ? context.active() : manager.active(), + with: (active, work) => manager.with(active, work), + }); + const schemas: Record = { School: { table: 'school_data', columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + } } }; + class Driver extends SQLiteDriver { + concurrent = false; + private calls = 0; + private releaseFirst!: () => void; + private readonly secondFinished = new Promise(resolve => { this.releaseFirst = resolve; }); + async query(sql: string, values: any[]) { + if (!this.concurrent) return super.query(sql, values); + const call = ++this.calls; + if (call === 1) await this.secondFinished; + const result = await super.query(sql, values); + if (call === 2) this.releaseFirst(); + return result; + } + } + const driver = new Driver(':memory:'); + class Client extends AbstractSQLTeaQLClient { + constructor() { super(driver, schemas); } + } + const client = new Client().setRuntimeTelemetry(telemetry).setDiagnosticSQLLogSink(undefined); + try { + await new UserContext().insertResource('dataService', client).ensureSchema(); + driver.concurrent = true; + await Promise.all([1, 2].map(limit => client.executeQuery(new SelectQuery('School').limit(limit) + .comment(`concurrent ${limit}`).purpose('verify isolated SQL identity')))); + await Promise.all([tracerProvider.forceFlush(), loggerProvider.forceFlush()]); + const logs = logExporter.getFinishedLogRecords().filter(log => log.body === 'TeaQL SQL execution'); + const spans = spanExporter.getFinishedSpans(); + expect(logs).toHaveLength(2); + expect(logs.map(log => log.attributes['teaql.intent.comment'])).toEqual(['concurrent 2', 'concurrent 1']); + for (const log of logs) { + const provider = spans.find(span => span.spanContext().spanId === log.spanContext?.spanId); + expect(provider?.attributes['teaql.operation.family']).toBe('provider'); + const query = spans.find(span => span.spanContext().spanId === provider?.parentSpanContext?.spanId); + expect(query?.attributes['teaql.operation.family']).toBe('query'); + expect(provider?.spanContext().traceId).toBe(log.spanContext?.traceId); + } + expect(new Set(logs.map(log => log.spanContext?.traceId)).size).toBe(2); + expect(trace.getTracerProvider()).toBe(beforeProvider); + expect(context.active()).toBe(beforeContext); + } finally { + await client.close(); + await Promise.all([tracerProvider.shutdown(), loggerProvider.shutdown(), meterProvider.shutdown()]); + manager.disable(); + } +}); + +test('an existing customer SDK stays installed and receives no TeaQL-owned exports', async () => { + const externalManager = new AsyncLocalStorageContextManager().enable(); + context.setGlobalContextManager(externalManager); + const externalExporter = new InMemorySpanExporter(); + const externalProvider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(externalExporter)] }); + trace.setGlobalTracerProvider(externalProvider); + const originalGlobalProvider = trace.getTracerProvider(); + const manager = new AsyncLocalStorageContextManager().enable(); + const ownExporter = new InMemorySpanExporter(); + const ownProvider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(ownExporter)] }); + const meterProvider = new MeterProvider(); + const telemetry = new OpenTelemetryRuntimeTelemetry(ownProvider.getTracer('io.teaql.runtime'), + meterProvider.getMeter('io.teaql.runtime'), {}, undefined, { + active: () => manager.active() === ROOT_CONTEXT ? context.active() : manager.active(), + with: (active, work) => manager.with(active, work), + }); + const externalSpan = externalProvider.getTracer('customer').startSpan('HTTP request'); + try { + await context.with(trace.setSpan(context.active(), externalSpan), async () => { + const scope = telemetry.start({ family: 'query', name: 'Order.list' }); + await scope.run!(async () => {}); scope.success(); + expect(trace.getTracerProvider()).toBe(originalGlobalProvider); + expect(trace.getSpan(context.active())).toBe(externalSpan); + }); + await ownProvider.forceFlush(); + expect(ownExporter.getFinishedSpans()).toHaveLength(1); + expect(ownExporter.getFinishedSpans()[0].parentSpanContext?.spanId).toBe(externalSpan.spanContext().spanId); + expect(externalExporter.getFinishedSpans()).toHaveLength(0); + await ownProvider.shutdown(); manager.disable(); + externalSpan.end(); await externalProvider.forceFlush(); + expect(externalExporter.getFinishedSpans()).toHaveLength(1); + expect(trace.getTracerProvider()).toBe(originalGlobalProvider); + } finally { + externalSpan.end(); + await ownProvider.shutdown(); manager.disable(); + await externalProvider.shutdown(); await meterProvider.shutdown(); + context.disable(); trace.disable(); externalManager.disable(); + } +}); diff --git a/source/teaql-ts/tests/sqlite-bootstrap.test.ts b/source/teaql-ts/tests/sqlite-bootstrap.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..d71823109079a324326cbaa78363a31268b9777b --- /dev/null +++ b/source/teaql-ts/tests/sqlite-bootstrap.test.ts @@ -0,0 +1,192 @@ +import { UserContext } from '../src/core/context'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { SelectQuery } from '../src/core/ast'; +import { RuntimeModule } from '../src/core/runtime-module'; +import { EntitySchema, SQLExecutionEvidenceStore } from '../src/sql/core'; +import { MutationRequest } from '../src/core/request-intent'; +import { SQLiteTeaQLClient } from '../src/sql/sqlite'; +import { + DelegatingMutationPolicyApprovalProvider, + DelegatingMutationPolicyRegistry, +} from '../src/core/mutation-policy'; + +function assertProviderSchemaAPIIsHidden(client: SQLiteTeaQLClient): void { + // @ts-expect-error Ensure Schema is intentionally available only through UserContext. + void client.ensureSchema; +} + +void assertProviderSchemaAPIIsHidden; + +const schemas: Record = { + Platform: { + table: 'platform_data', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + name: { columnName: 'name', logicalType: 'text', decode: 'native' }, + }, + }, + OrderStatus: { + table: 'order_status_data', + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, + name: { columnName: 'name', logicalType: 'text', decode: 'native' }, + code: { columnName: 'code', logicalType: 'text', decode: 'native' }, + }, + }, +}; + +function moduleWithStatus(name: string): RuntimeModule { + return new RuntimeModule(schemas, {}, { + defaultDomainRoot: { entity: 'Platform', id: '1', values: { name: 'Default Platform' } }, + constants: [{ entity: 'OrderStatus', id: '1001', values: { name, code: 'PENDING' } }], + }); +} + +function read(entity: string): SelectQuery { + return new SelectQuery(entity).comment('read bootstrap evidence').purpose('verify Ensure Schema'); +} + +it.each([false, true])('metadata bootstrap owns request intent and committed audit with logging=%p', async logging => { + const client = new SQLiteTeaQLClient(':memory:', {}).install(moduleWithStatus('Pending')) as SQLiteTeaQLClient; + const evidence = new SQLExecutionEvidenceStore(); + client.setRuntimeTelemetrySink(evidence); + client.setQueryLoggingEnabled(logging).setMutationLoggingEnabled(logging); + const mutate = jest.spyOn(client, 'executeMutation'); + const context = new UserContext().insertResource('dataService', client) + .insertResource('bootstrapActor', 'prior actor').insertResource('bootstrapCategory', 'prior category'); + try { + await context.ensureSchema(); + await context.ensureSchema(); + expect(context.getResource('bootstrapActor')).toBe('prior actor'); + expect(context.getResource('bootstrapCategory')).toBe('prior category'); + expect(mutate).toHaveBeenCalledTimes(2); + for (const [request] of mutate.mock.calls) { + expect(request).toBeInstanceOf(MutationRequest); + expect(request.comment).toBe('reconcile model bootstrap data'); + } + const events = client.auditTrace; + expect(events).toHaveLength(2); + expect(events.map(event => event.entity)).toEqual(['Platform', 'OrderStatus']); + for (const event of events) { + expect(event.actor).toBe('teaql-generated-bootstrap'); + expect(event.category).toBe('runtime-bootstrap'); + } + const entries = evidence.snapshot(); + expect(entries).toHaveLength(8); // two lookup/insert/readback triples, then two no-op lookups + expect(entries.filter(entry => entry.comment === 'inspect model bootstrap record')).toHaveLength(4); + for (const entry of entries) { + expect((entry.comment ?? entry.auditReason)?.trim()).toBeTruthy(); + if (entry.operation === 'select') expect(entry.purpose?.trim()).toBeTruthy(); + expect(entry.tracePath.map(node => node.kind)).toEqual([ + 'operation', entry.operation === 'select' ? 'request' : 'entity', 'provider', 'sql', + ]); + } + } finally { await client.close(); } +}); + +it('preflights the complete bootstrap graph before a customer policy reviews it', async () => { + const client = new SQLiteTeaQLClient(':memory:', {}).install(moduleWithStatus('Pending')) as SQLiteTeaQLClient; + const identity = Object.freeze({ policyId: 'bootstrap-review', version: '1', fingerprint: 'sha256:test' }); + const review = jest.fn((_context, plan) => ({ verdict: 'allow' as const })); + const context = new UserContext().insertResource('dataService', client) + .withMutationPolicyRegistry(new DelegatingMutationPolicyRegistry(() => ({ identity, review }))) + .withMutationPolicyApprovalProvider(new DelegatingMutationPolicyApprovalProvider( + policy => ({ policy, approvedBy: 'test', approvedAt: new Date(0) }), + )); + try { + await context.ensureSchema(); + expect(review).toHaveBeenCalledTimes(1); + expect(review.mock.calls[0][1].operations.map((operation: { entity: string }) => operation.entity)) + .toEqual(['Platform', 'OrderStatus']); + } finally { await client.close(); } +}); + +it.each([false, true])('metadata bootstrap cannot bypass Checker with logging=%p', async logging => { + const checkAndFix = jest.fn(() => { throw new Error('constant checker refused'); }); + const client = new SQLiteTeaQLClient(':memory:', {}).install(new RuntimeModule( + schemas, { OrderStatus: { checkAndFix } }, moduleWithStatus('Pending').bootstrap, + )) as SQLiteTeaQLClient; + client.setQueryLoggingEnabled(logging).setMutationLoggingEnabled(logging); + const context = new UserContext().insertResource('dataService', client); + try { + await expect(context.ensureSchema()) + .rejects.toThrow('constant checker refused'); + expect(checkAndFix).toHaveBeenCalledTimes(1); + expect(client.auditTrace).toEqual([]); + expect(context.getResource('bootstrapActor')).toBeUndefined(); + expect(context.getResource('bootstrapCategory')).toBeUndefined(); + expect(await client.executeQuery(read('Platform'))).toEqual([]); + expect(await client.executeQuery(read('OrderStatus'))).toEqual([]); + } finally { await client.close(); } +}); + +it('serializes bootstrap callers without losing the active bootstrap actor', async () => { + const client = new SQLiteTeaQLClient(':memory:', {}).install(moduleWithStatus('Pending')) as SQLiteTeaQLClient; + const callers = [new UserContext(), new UserContext()] + .map(context => context.insertResource('dataService', client)); + try { + await Promise.all(callers.map(context => context.ensureSchema())); + expect(client.auditTrace).toHaveLength(2); + for (const event of client.auditTrace) expect(event.actor).toBe('teaql-generated-bootstrap'); + for (const caller of callers) expect(caller.getResource('bootstrapActor')).toBeUndefined(); + expect(await client.executeQuery(read('OrderStatus'))).toEqual([ + expect.objectContaining({ id: '1001', version: 1, code: 'PENDING' }), + ]); + } finally { await client.close(); } +}); + +it('does not mistake a soft-deleted constant for a missing primary key', async () => { + const client = new SQLiteTeaQLClient(':memory:', {}).install(moduleWithStatus('Pending')) as SQLiteTeaQLClient; + const context = new UserContext().insertResource('dataService', client); + try { + await context.ensureSchema(); + await client.executeMutation({ entity: 'OrderStatus', action: 'Delete', id: '1001', + version: 1, comment: 'retire a constant for the bootstrap identity regression' }); + const audits = client.auditTrace.length; + await context.ensureSchema(); + expect(client.auditTrace).toHaveLength(audits); + expect(await client.executeQuery(read('OrderStatus'))).toEqual([]); + } finally { await client.close(); } +}); + +it('reconciles bootstrap data idempotently and advances ID spaces', async () => { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'teaql-ts-bootstrap-')); + const database = path.join(directory, 'bootstrap.sqlite'); + try { + const first = new SQLiteTeaQLClient(database, {}).install(moduleWithStatus('Pending')) as SQLiteTeaQLClient; + await new UserContext().insertResource('dataService', first).ensureSchema(); + await new UserContext().insertResource('dataService', first).ensureSchema(); + + expect(await first.executeQuery(read('Platform'))).toEqual([ + expect.objectContaining({ id: '1', version: 1, name: 'Default Platform' }), + ]); + expect(await first.executeQuery(read('OrderStatus'))).toEqual([ + expect.objectContaining({ id: '1001', version: 1, name: 'Pending', code: 'PENDING' }), + ]); + + const isolated = await first.executeMutation({ + entity: 'Platform', action: 'Create', payload: { name: 'Isolated Platform' }, + comment: 'create an isolated data graph', + }); + expect(isolated.id).not.toBe('1'); + await first.close(); + + const second = new SQLiteTeaQLClient(database, {}).install( + moduleWithStatus('Awaiting Payment'), + ) as SQLiteTeaQLClient; + await new UserContext().insertResource('dataService', second).ensureSchema(); + expect(await second.executeQuery(read('Platform'))).toHaveLength(2); + expect(await second.executeQuery(read('OrderStatus'))).toEqual([ + expect.objectContaining({ + id: '1001', version: 2, name: 'Awaiting Payment', code: 'PENDING', + }), + ]); + await second.close(); + } finally { + fs.rmSync(directory, { recursive: true, force: true }); + } +}); diff --git a/source/teaql-ts/tests/sqlite-id-space.test.ts b/source/teaql-ts/tests/sqlite-id-space.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..59764f83c3701bb0f949898ed0d71d4e74f18a21 --- /dev/null +++ b/source/teaql-ts/tests/sqlite-id-space.test.ts @@ -0,0 +1,60 @@ +import { mkdtempSync, rmSync } from 'fs'; +import { tmpdir } from 'os'; +import { join } from 'path'; +import { SQLiteDriver } from '../src/sql/sqlite'; + +describe('SQLite ID-space generator', () => { + test('uses portable optimistic allocation across independent drivers', async () => { + const directory = mkdtempSync(join(tmpdir(), 'teaql-id-space-')); + const database = join(directory, 'ids.db'); + const first = new SQLiteDriver(database); + const second = new SQLiteDriver(database); + try { + await first.ensureSchema({}); + expect(await first.transaction(session => first.nextId(session, 'Order'))).toBe('1'); + expect(await second.transaction(session => second.nextId(session, 'Order'))).toBe('2'); + expect(await first.transaction(session => first.nextId(session, 'Customer'))).toBe('1'); + await first.transaction(session => first.ensureIdFloor(session, 'SeededType', '1001')); + expect(await second.transaction(session => second.nextId(session, 'SeededType'))).toBe('1002'); + + const values: string[] = []; + for (let index = 0; index < 20; index += 1) { + const driver = index % 2 === 0 ? first : second; + values.push(await driver.transaction(session => driver.nextId(session, 'Order'))); + } + expect(new Set(values).size).toBe(20); + expect(values.map(Number).sort((a, b) => a - b)).toEqual( + Array.from({ length: 20 }, (_, index) => index + 3), + ); + } finally { + await first.close(); + await second.close(); + rmSync(directory, { recursive: true, force: true }); + } + }); + + test('re-reads and retries after losing an optimistic update', async () => { + const directory = mkdtempSync(join(tmpdir(), 'teaql-id-space-retry-')); + const driver = new SQLiteDriver(join(directory, 'ids.db')); + let selected = 0; + const session = { + async query(sql: string) { + if (sql.startsWith('SELECT')) { + selected += 1; + return { rows: [{ id: selected === 1 ? 7 : 8 }], rowCount: 1 }; + } + if (sql.startsWith('UPDATE')) { + return { rows: [], rowCount: selected === 1 ? 0 : 1 }; + } + throw new Error(`unexpected SQL: ${sql}`); + }, + async *stream() { /* unused */ }, + }; + try { + expect(await driver.nextId(session, 'Order')).toBe('9'); + } finally { + await driver.close(); + rmSync(directory, { recursive: true, force: true }); + } + }); +}); diff --git a/source/teaql-ts/tests/standard-telemetry-exporter.test.ts b/source/teaql-ts/tests/standard-telemetry-exporter.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..cc189c9b038de124535ef865a620f03e6148113b --- /dev/null +++ b/source/teaql-ts/tests/standard-telemetry-exporter.test.ts @@ -0,0 +1,105 @@ +import { createServer, type Server } from 'node:http'; +import { diag, DiagLogLevel } from '@opentelemetry/api'; +import { createStandardNodePipeline } from '../src/telemetry/standard-node-sdk'; +import { acknowledgementResult, OwnedOTLPHTTP, validateAcknowledgementBytes } from '../src/telemetry/owned-otlp-http'; + +const canary = 'TEAQL_REMOTE_RESPONSE_PRIVATE_CANARY'; +const listen = (server: Server) => new Promise(resolve => server.listen(0, '127.0.0.1', () => + resolve((server.address() as {port: number}).port))); +const close = (server: Server) => new Promise(resolve => server.close(() => resolve())); + +test('actual owned SDK never logs receiver text and never retries a partially accepted batch', async () => { + const diagnostics: unknown[] = []; + const write = (...values: unknown[]) => { diagnostics.push(values); }; + const logger = { error: write, warn: write, info: write, debug: write, verbose: write }; + diag.setLogger(logger, DiagLogLevel.ALL); + const requests: Record = {}; + const server = createServer(async (request, response) => { + await new Promise(resolve => { request.on('data', () => {}); request.once('end', () => resolve()); }); + const signal = request.url!.split('/').pop()!; + requests[signal] = (requests[signal] || 0) + 1; + const protobuf = request.headers['content-type'] === 'application/x-protobuf'; + response.setHeader('Content-Type', protobuf ? 'application/x-protobuf' : 'application/json'); + if (protobuf) { + const text = Buffer.from(canary); + const partial = Buffer.concat([Buffer.from([0x08, 0x01, 0x12, text.length]), text]); + response.end(Buffer.concat([Buffer.from([0x0a, partial.length]), partial])); + } else response.end(JSON.stringify({ partialSuccess: { rejectedSpans: 1, rejectedLogRecords: 1, + rejectedDataPoints: 1, errorMessage: canary } })); + }); + const port = await listen(server); + const pipeline = createStandardNodePipeline('sdk-private-response-probe', `http://127.0.0.1:${port}`); + try { + pipeline.telemetry.start({family: 'query', name: 'controlled query'}).success(); + await pipeline.flush(); + expect(requests.traces).toBe(1); + expect(requests.logs).toBe(1); + expect(requests.metrics).toBe(1); + expect(JSON.stringify(diagnostics)).not.toContain(canary); + for (const response of Object.values(pipeline.health().responses)) { + expect(response.rejected).toBe(1); + expect(response.partialSuccess).toBe(1); + expect(response.invalidResponses).toBe(0); + } + } finally { + try { await pipeline.shutdown(); } finally { diag.disable(); await close(server); } + } +}, 15000); + +test.each([ + [0x00], [0x09], [0x15, 0x01], [0x80], Array(11).fill(0xff), [0x08, 0x00], + [0x0a, 0x03, 0x12, 0x01, 0xff], [0x0a, 0x02, 0x08, 0x80], [0x93, 0x03], +])('strict framing rejects malformed acknowledgement without trusting native tolerant decoding: %j', (...bytes) => { + expect(() => validateAcknowledgementBytes(Uint8Array.from(bytes))).toThrow('telemetry acknowledgement'); +}); + +test('zero rejection wrappers are accepted; warnings, rejections and failed batch entries stay distinct', () => { + validateAcknowledgementBytes(Uint8Array.from([0x0a, 0x00])); + expect(acknowledgementResult('logs', {partialSuccess: {}}, 4)).toEqual({rejected: 0, kind: undefined}); + expect(acknowledgementResult('metrics', {partialSuccess: {rejectedDataPoints: 0, errorMessage: canary}}, 7)) + .toEqual({rejected: 0, kind: 'warning'}); + expect(acknowledgementResult('metrics', {partialSuccess: {rejectedDataPoints: 3}}, 7)) + .toEqual({rejected: 3, kind: 'partial_success'}); + for (const count of [-1, 8, 1.5, Number.MAX_SAFE_INTEGER + 1]) + expect(() => acknowledgementResult('metrics', {partialSuccess: {rejectedDataPoints: count}}, 7)).toThrow(); + expect(() => validateAcknowledgementBytes(new Uint8Array(4 * 1024 * 1024 + 1))).toThrow(); +}); + +test('real HTTP failure never retries or passes private body/transport details to customer SDK diagnostics', async () => { + const diagnostics: unknown[] = [], requests: Record = {}; + const write = (...values: unknown[]) => {diagnostics.push(values);}; + const logger = {error: write, warn: write, info: write, debug: write, verbose: write}; + diag.setLogger(logger, DiagLogLevel.ALL); + const server = createServer((request, response) => { + request.on('data', () => {}); + request.once('end', () => { + const signal = request.url!.split('/').pop()!; + requests[signal] = (requests[signal] || 0) + 1; + response.statusCode = 503; response.end(canary); + }); + }); + const port = await listen(server), pipeline = createStandardNodePipeline('sdk-failure-probe', `http://127.0.0.1:${port}`); + try { + pipeline.telemetry.start({family: 'query', name: 'controlled query'}).success(); + await expect(pipeline.flush()).rejects.toThrow('TeaQL telemetry export incomplete'); + expect(requests).toEqual({traces: 1, logs: 1, metrics: 1}); + expect(pipeline.health().traceSpansFailed).toBe(1); + expect(pipeline.health().logRecordsFailed).toBe(1); + expect(pipeline.health().metricDataObjectsFailed).toBeGreaterThan(1); + expect(JSON.stringify(diagnostics)).not.toContain(canary); + expect(JSON.stringify(diagnostics)).not.toContain('items to be sent'); + } finally { + try { await pipeline.shutdown(); } finally {diag.disable(); await close(server);} + } +}, 15000); + +test('owned transport enforces an entire-attempt deadline rather than only socket idle time', async () => { + const transport = new OwnedOTLPHTTP(); + const server = createServer((request, _response) => {request.on('data', () => {});}); + const port = await listen(server), started = performance.now(); + try { + expect(await transport.send(`http://127.0.0.1:${port}/v1/traces`, new Uint8Array())).toEqual({}); + expect(performance.now() - started).toBeGreaterThanOrEqual(2900); + expect(performance.now() - started).toBeLessThan(3800); + } finally {transport.close(); await close(server);} +}, 10000); diff --git a/source/teaql-ts/tests/standard-telemetry-module.test.ts b/source/teaql-ts/tests/standard-telemetry-module.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..71bc2f0b82a47becd878516e2f6872137a40a1a1 --- /dev/null +++ b/source/teaql-ts/tests/standard-telemetry-module.test.ts @@ -0,0 +1,44 @@ +import { startStandardNodeTelemetry } from '../src/telemetry/standard-node'; +import { TELEMETRY_ENVIRONMENT } from '../src/core/telemetry-startup'; + +const mockFlush = jest.fn(async () => {}); +const mockShutdown = jest.fn(async () => {}); +const mockCreate = jest.fn((..._args: unknown[]) => ({ telemetry: { start: () => ({ success() {}, failure() {} }) }, + flush: mockFlush, shutdown: mockShutdown })); +jest.mock('../src/telemetry/standard-node-sdk', () => ({ createStandardNodePipeline: (...args: unknown[]) => mockCreate(...args) })); + +const previous = { ...process.env }; +beforeEach(() => { + for (const name of Object.values(TELEMETRY_ENVIRONMENT)) delete process.env[name]; + mockCreate.mockClear(); mockFlush.mockClear(); mockShutdown.mockClear(); + jest.spyOn(console, 'info').mockImplementation(() => {}); + jest.spyOn(console, 'warn').mockImplementation(() => {}); +}); +afterEach(() => { process.env = { ...previous }; jest.restoreAllMocks(); }); + +test('disabled mode announces support but constructs no SDK pipeline', async () => { + expect(await startStandardNodeTelemetry()).toBeUndefined(); + expect(mockCreate).not.toHaveBeenCalled(); + expect(console.info).toHaveBeenCalledWith(expect.stringContaining('TEAQL_TELEMETRY_ENABLED=true')); +}); + +test('matching clients share an owned pipeline; release is reference-counted and idempotent', async () => { + process.env.TEAQL_TELEMETRY_ENABLED = 'true'; + process.env.TEAQL_TELEMETRY_SERVICE_NAME = 'test-shared'; + process.env.TEAQL_TELEMETRY_OTLP_ENDPOINT = 'http://localhost:4318'; + const [one, two] = await Promise.all([startStandardNodeTelemetry(), startStandardNodeTelemetry()]); + expect(mockCreate).toHaveBeenCalledTimes(1); + expect(one!.telemetry).toBe(two!.telemetry); + await one!.flush(); expect(mockFlush).toHaveBeenCalledTimes(1); + await one!.release(); await one!.release(); expect(mockShutdown).not.toHaveBeenCalled(); + await two!.release(); expect(mockShutdown).toHaveBeenCalledTimes(1); +}); + +test('SDK construction failure is fail-open and does not expose its exception', async () => { + process.env.TEAQL_TELEMETRY_ENABLED = 'true'; + process.env.TEAQL_TELEMETRY_SERVICE_NAME = 'test-failure'; + process.env.TEAQL_TELEMETRY_OTLP_ENDPOINT = 'http://localhost:4318'; + mockCreate.mockImplementationOnce(() => { throw new Error('PRIVATE-CREDENTIAL'); }); + expect(await startStandardNodeTelemetry()).toBeUndefined(); + expect(JSON.stringify((console.warn as jest.Mock).mock.calls)).not.toContain('PRIVATE-CREDENTIAL'); +}); diff --git a/source/teaql-ts/tests/standard-telemetry-queue.test.ts b/source/teaql-ts/tests/standard-telemetry-queue.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..65f31f9b1f0ada275829b1cb5d57b1fcdd92ccb5 --- /dev/null +++ b/source/teaql-ts/tests/standard-telemetry-queue.test.ts @@ -0,0 +1,61 @@ +import { createServer, type ServerResponse } from 'node:http'; +import { createStandardNodePipeline } from '../src/telemetry/standard-node-sdk'; + +test('flush waits for a batch already exporting before the flush invocation', async () => { + let held: ServerResponse | undefined; + let received!: () => void; + const first = new Promise(resolve => {received = resolve;}); + const server = createServer((request, response) => { + request.on('data', () => {}); + request.once('end', () => { + response.setHeader('Content-Type', 'application/x-protobuf'); + if (request.url === '/v1/traces' && !held) {held = response; received();} + else response.end(Buffer.from([0x0a,0x00])); + }); + }); + const port = await new Promise(resolve => server.listen(0,'127.0.0.1',() => + resolve((server.address() as {port:number}).port))); + const pipeline = createStandardNodePipeline('flush-prefix-probe', `http://127.0.0.1:${port}`); + try { + for (let index = 0; index < 128; index++) pipeline.telemetry.start({family:'query',name:'prefix probe'}).success(); + await first; + const flushing = pipeline.flush(); + const early = await Promise.race([flushing.then(() => 'completed'), + new Promise(resolve => setTimeout(() => resolve('pending'), 100))]); + expect(early).toBe('pending'); + held!.end(Buffer.from([0x0a,0x00])); + await flushing; + expect(pipeline.health().queues.traces.outstanding).toBe(0); + } finally { + held?.end(Buffer.from([0x0a,0x00])); + try {await pipeline.shutdown();} finally {await new Promise(resolve => server.close(() => resolve()));} + } +},15000); + +test('backlogged shutdown settles every admitted record before returning within its finite budget', async () => { + const server = createServer((request, _response) => {request.on('data', () => {});}); + const port = await new Promise(resolve => server.listen(0,'127.0.0.1',() => + resolve((server.address() as {port:number}).port))); + const pipeline = createStandardNodePipeline('shutdown-backlog-probe',`http://127.0.0.1:${port}`); + try { + for (let index = 0; index < 2300; index++) pipeline.telemetry.start({family:'query',name:'backlog probe'}).success(); + expect(pipeline.health().queues.traces.outstanding).toBe(2048); + expect(pipeline.health().queues.logs.outstanding).toBe(2048); + const started = performance.now(); + await pipeline.shutdown().catch(() => {}); + expect(performance.now() - started).toBeLessThan(6500); + expect(pipeline.health().queues.traces.outstanding).toBe(0); + expect(pipeline.health().queues.logs.outstanding).toBe(0); + const health = pipeline.health(); + expect(health.queues.logs.retired).toBeGreaterThan(0); + for (const signal of ['traces','logs'] as const) { + const queue = health.queues[signal]; + expect(queue.exporting).toBe(0); + expect(queue.admitted).toBe(queue.completed + queue.retired); + expect(queue.overflow).toBe(252); + } + pipeline.telemetry.start({family:'query',name:'late probe'}).success(); + expect(pipeline.health().queues.traces.postShutdown).toBe(1); + expect(pipeline.health().queues.logs.postShutdown).toBe(1); + } finally {await new Promise(resolve => server.close(() => resolve()));} +},15000); diff --git a/source/teaql-ts/tests/telemetry-export-health.test.ts b/source/teaql-ts/tests/telemetry-export-health.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..29274531bc569c28a795347ddaad8f7ea81f90a5 --- /dev/null +++ b/source/teaql-ts/tests/telemetry-export-health.test.ts @@ -0,0 +1,95 @@ +import { ExportHealth, lifecycleDeadline } from '../src/telemetry/export-health'; + +test('queue capacity includes in-flight records and diagnoses every lost record without log flooding', () => { + const losses = jest.fn(); + const warning = jest.spyOn(console, 'warn').mockImplementation(() => {}); + try { + const health = new ExportHealth('logs', 2, losses); + expect(health.admit()).toBe(true); expect(health.admit()).toBe(true); + expect(health.admit()).toBe(false); expect(health.admit()).toBe(false); + expect(health.pendingRecords).toBe(2); + expect(losses.mock.calls).toEqual([[1, 'logs', 'queue_overflow'], [1, 'logs', 'queue_overflow']]); + expect(warning).toHaveBeenCalledTimes(1); + health.complete(1, false); + expect(health.admit()).toBe(true); expect(health.pendingRecords).toBe(2); + health.complete(2, true); + expect(health.pendingRecords).toBe(0); + expect(losses).toHaveBeenLastCalledWith(2, 'logs', 'export_failure'); + expect(warning).toHaveBeenCalledTimes(2); + } finally { warning.mockRestore(); } +}); + +test('export loss observer errors are not business errors and do not prevent draining', () => { + const warning = jest.spyOn(console, 'warn').mockImplementation(() => { throw new Error('writer'); }); + try { + const health = new ExportHealth('traces', 1, () => { throw new Error('counter'); }); + health.admit(); + expect(() => health.complete(1, true)).not.toThrow(); + expect(health.pendingRecords).toBe(0); + expect(health.admit()).toBe(true); + } finally { warning.mockRestore(); } +}); + +test('lifecycle operations have a finite deadline and clear the timer on completion', async () => { + await expect(lifecycleDeadline(Promise.resolve(7), 100)).resolves.toBe(7); + await expect(lifecycleDeadline(new Promise(() => {}), 10)).rejects.toThrow('lifecycle timed out'); +}); + +test('close rejects late admission but still settles previously handed-off records', () => { + const losses = jest.fn(), warning = jest.spyOn(console, 'warn').mockImplementation(() => {}); + try { + const health = new ExportHealth('traces', 1, losses); + expect(health.admit()).toBe(true); + health.close(); + expect(health.admit()).toBe(false); + expect(health.pendingRecords).toBe(1); + expect(losses).toHaveBeenLastCalledWith(1, 'traces', 'shutdown'); + health.complete(1, true); + expect(health.pendingRecords).toBe(0); + expect(health.failedRecords).toBe(1); + } finally {warning.mockRestore();} +}); + +test('failed SDK handoff releases its reservation without joining the accepted flush prefix', async () => { + const losses = jest.fn(), warning = jest.spyOn(console, 'warn').mockImplementation(() => {}); + try { + const health = new ExportHealth('traces', 1, losses), record = {}; + health.handoff(record, () => {throw new Error('PRIVATE-SDK-FAILURE');}); + expect(health.snapshot()).toMatchObject({admitted: 0, outstanding: 0, completed: 0, handoffFailed: 1}); + await health.waitForPrefix(); + health.handoff({}, () => {}); + expect(health.snapshot()).toMatchObject({admitted: 1, outstanding: 1}); + expect(losses).toHaveBeenCalledWith(1, 'traces', 'handoff_failure'); + expect(JSON.stringify(warning.mock.calls)).not.toContain('PRIVATE-SDK-FAILURE'); + } finally {warning.mockRestore();} +}); + +test('later export completion cannot satisfy an older accepted-record flush prefix', async () => { + const health = new ExportHealth('logs', 2, () => {}), first = {}, later = {}; + health.handoff(first, () => {}); + const earlier = health.beginExport([first])!; + let done = false; + const prefix = health.waitForPrefix().then(() => {done = true;}); + health.handoff(later, () => {}); + health.beginExport([later])!.complete(false); + await Promise.resolve(); expect(done).toBe(false); + earlier.complete(false); await prefix; + expect(health.snapshot()).toMatchObject({admitted: 2, completed: 2, outstanding: 0}); +}); + +test('queued retirement is distinct from an in-flight failed attempt and is counted once', async () => { + const losses = jest.fn(), warning = jest.spyOn(console, 'warn').mockImplementation(() => {}); + try { + const health = new ExportHealth('logs', 3, losses), active = {}, queued = {}; + health.handoff(active, () => {}); health.handoff(queued, () => {}); + const exporting = health.beginExport([active])!; + health.close(); health.abortQueued(); health.abortQueued(); + expect(health.beginExport([queued])).toBeUndefined(); + expect(health.snapshot()).toMatchObject({retired: 1, outstanding: 1, exporting: 1, completed: 0}); + exporting.complete(true); exporting.complete(true); + await health.waitForIdle(); + expect(health.snapshot()).toMatchObject({retired: 1, outstanding: 0, exporting: 0, completed: 1}); + expect(health.failedRecords).toBe(1); + expect(losses.mock.calls).toEqual([[1,'logs','shutdown'],[1,'logs','export_failure']]); + } finally {warning.mockRestore();} +}); diff --git a/source/teaql-ts/tests/telemetry-startup.test.ts b/source/teaql-ts/tests/telemetry-startup.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..77e711e4f558cb9b6114e13d925edb26de1883c4 --- /dev/null +++ b/source/teaql-ts/tests/telemetry-startup.test.ts @@ -0,0 +1,70 @@ +import { readTelemetryStartupConfiguration, telemetryStartupMessage, TELEMETRY_ENVIRONMENT, telemetryNotice } from '../src/core/telemetry-startup'; +import { projectSafeSQLLog, PLAINTEXT_LOG_ACK, PLAINTEXT_LOG_ENV } from '../src/core/log-privacy'; +import { sqlDiagnosticEvent } from '../src/core/sql-diagnostic-event'; +import type { SQLExecutionMetadata } from '../src/sql/core'; + +test('a broken startup log writer cannot change application behavior', () => { + const info = jest.spyOn(console, 'info').mockImplementation(() => { throw new Error('broken writer'); }); + const warn = jest.spyOn(console, 'warn').mockImplementation(() => { throw new Error('broken writer'); }); + try { + expect(() => telemetryNotice('startup')).not.toThrow(); + expect(() => telemetryNotice('export unavailable', true)).not.toThrow(); + } finally { info.mockRestore(); warn.mockRestore(); } +}); + +test('disabled startup reports the three enablement parameters without reading unrelated values', () => { + const configuration = readTelemetryStartupConfiguration({ + TEAQL_TELEMETRY_SERVICE_NAME: 'PRIVATE-SERVICE', TEAQL_TELEMETRY_OTLP_ENDPOINT: 'PRIVATE-ENDPOINT', + }); + expect(configuration).toEqual({ enabled: false }); + const text = telemetryStartupMessage(configuration); + for (const key of Object.values(TELEMETRY_ENVIRONMENT)) expect(text).toContain(key); + expect(text).toContain('supported, disabled'); + expect(text).not.toContain('PRIVATE-'); +}); + +test('enabled configuration announces full recording and concrete safe settings', () => { + const configuration = readTelemetryStartupConfiguration({ TEAQL_TELEMETRY_ENABLED: 'TRUE', + TEAQL_TELEMETRY_SERVICE_NAME: 'order-service', TEAQL_TELEMETRY_OTLP_ENDPOINT: 'http://localhost:4318/' }); + expect(configuration.enabled).toBe(true); + expect(configuration.endpoint).toBe('http://localhost:4318'); + expect(telemetryStartupMessage(configuration)).toContain('full recording, masked SQL'); + expect(telemetryStartupMessage(configuration)).toContain('order-service'); +}); + +test.each(['http://secret:password@localhost:4318', 'http://localhost:4318?token=SECRET', + 'http://localhost:4318#SECRET', 'file:///SECRET'])('invalid endpoint is not echoed: %s', endpoint => { + const configuration = readTelemetryStartupConfiguration({ TEAQL_TELEMETRY_ENABLED: 'true', + TEAQL_TELEMETRY_SERVICE_NAME: 'orders', TEAQL_TELEMETRY_OTLP_ENDPOINT: endpoint }); + expect(configuration).toEqual({ enabled: false, error: 'invalid-endpoint' }); + expect(telemetryStartupMessage(configuration)).not.toContain(endpoint); + expect(telemetryStartupMessage(configuration)).not.toContain('SECRET'); +}); + +test('invalid enable and missing configuration cannot claim telemetry is enabled', () => { + expect(readTelemetryStartupConfiguration({ TEAQL_TELEMETRY_ENABLED: 'yes' }).error).toBe('invalid-enable'); + expect(readTelemetryStartupConfiguration({ TEAQL_TELEMETRY_ENABLED: 'true' }).error).toBe('invalid-service'); + expect(readTelemetryStartupConfiguration({ TEAQL_TELEMETRY_ENABLED: 'false' })).toEqual({ enabled: false }); +}); + +test('telemetry safe projection preserves masking even during local plaintext debug', () => { + const before = process.env[PLAINTEXT_LOG_ENV]; + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + try { + const input: SQLExecutionMetadata = { operation: 'select', tracePath: [], + traceChain: [{ kind: 'comment', name: 'Order', detail: 'load PRIVATE-PARAM', entityId: 'PRIVATE-ID' }], + parameterizedSQL: 'SELECT id FROM orders WHERE order_number = ?', parameters: ['PRIVATE-PARAM'], + parameterLogPolicies: ['masked'], sqlOrigin: 'generated', debugSQL: '', elapsedMicros: 17, + resultSummary: '1 row returned', resultCount: 1, comment: 'load PRIVATE-PARAM' }; + const projected = projectSafeSQLLog(input); + const event = sqlDiagnosticEvent(projected, { traceId: '1'.repeat(32), spanId: '2'.repeat(16) }); + expect(event.attributes['teaql.sql.debug']).toContain('masked'); + expect(JSON.stringify(event)).not.toContain('PRIVATE-PARAM'); + expect(JSON.stringify(event)).not.toContain('PRIVATE-ID'); + expect(event.attributes['teaql.intent.comment']).toContain('[REDACTED]'); + expect(event.correlation?.spanId).toBe('2'.repeat(16)); + expect(event.attributes).not.toHaveProperty('parameters'); + } finally { + if (before === undefined) delete process.env[PLAINTEXT_LOG_ENV]; else process.env[PLAINTEXT_LOG_ENV] = before; + } +}); diff --git a/source/teaql-ts/tests/temporal-real-databases.test.ts b/source/teaql-ts/tests/temporal-real-databases.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..1f982982e19ddc6102eb0ef53195fe2c1e4a8658 --- /dev/null +++ b/source/teaql-ts/tests/temporal-real-databases.test.ts @@ -0,0 +1,39 @@ +import { Values } from '../src/core/value'; +import { debugSQL } from '../src/sql/core'; +import { MySQLDriver } from '../src/sql/mysql'; +import { PostgreSQLDriver } from '../src/sql/postgres'; + +const cases = [ + ['PostgreSQL', 'TEAQL_TEST_POSTGRES_URL', (url: string) => new PostgreSQLDriver(url), + 'DATE', 'TIMESTAMPTZ(3)', '$1, $2, $3', 'postgresql'], + ['MySQL', 'TEAQL_TEST_MYSQL_URL', (url: string) => new MySQLDriver(url), + 'DATE', 'DATETIME(3)', '?, ?, ?', 'mysql'], +] as const; + +describe.each(cases)('%s temporal SQL', (_name, env, create, dateType, timestampType, placeholders, kind) => { + const url = process.env[env]; + const testIfConfigured = url ? test : test.skip; + testIfConfigured('prepared and diagnostic SQL store equivalent values', async () => { + const driver = create(url!); + try { + await driver.query('DROP TABLE IF EXISTS teaql_temporal_runtime_fixture'); + await driver.query(`CREATE TABLE teaql_temporal_runtime_fixture(id INTEGER, d ${dateType}, t ${timestampType})`); + const millis = -315521754322; + await driver.query( + `INSERT INTO teaql_temporal_runtime_fixture VALUES (${placeholders}) /* ignored ? $1 */`, + [1, '2024-02-29', new Date(millis)], + ); + const literal = debugSQL( + `/* teaql source=temporal.verify ? $1 */ INSERT INTO teaql_temporal_runtime_fixture VALUES (${placeholders})`, + [Values.I64(2), Values.Date('2024-02-29'), Values.Timestamp(millis)], kind, + ); + await driver.query(literal); + const rows = await driver.query('SELECT d, t FROM teaql_temporal_runtime_fixture ORDER BY id'); + expect(String(rows.rows[0].d)).toBe(String(rows.rows[1].d)); + expect(new Date(rows.rows[0].t).getTime()).toBe(new Date(rows.rows[1].t).getTime()); + } finally { + await driver.query('DROP TABLE IF EXISTS teaql_temporal_runtime_fixture'); + await driver.close(); + } + }); +}); diff --git a/source/teaql-ts/tests/tools.test.ts b/source/teaql-ts/tests/tools.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..30f58fca2823d91c872e0e42e68381eac9a60c4c --- /dev/null +++ b/source/teaql-ts/tests/tools.test.ts @@ -0,0 +1,32 @@ +import { + ContextTools, FetchHttpToolProvider, HTTP_TOOL, ToolPolicy, UserContext, +} from '../src'; + +describe('context Tool API', () => { + test('requires trusted policy and preserves native string response', async () => { + const fetchImpl = jest.fn().mockResolvedValue({ ok: true, status: 200, text: async () => 'ok' }); + const context = new UserContext(); + const tools = ContextTools.builder(context) + .policy(ToolPolicy.builder().allow(HTTP_TOOL).build()) + .provider(new FetchHttpToolProvider(fetchImpl as unknown as typeof fetch)) + .build(); + + await expect(tools.get(HTTP_TOOL).get('https://example.com').purpose('status').execute()) + .resolves.toBe('ok'); + expect(fetchImpl).toHaveBeenCalledWith('https://example.com', { method: 'GET' }); + }); + + test('rejects denied, unknown and blank-intent operations', async () => { + const context = new UserContext(); + const provider = new FetchHttpToolProvider(jest.fn() as unknown as typeof fetch); + const denied = ContextTools.builder(context).provider(provider).build(); + expect(() => denied.get(HTTP_TOOL)).toThrow('Tool denied by policy: http'); + + const allowed = ContextTools.builder(context) + .policy(ToolPolicy.builder().allow(HTTP_TOOL).build()).provider(provider).build(); + await expect(allowed.get(HTTP_TOOL).get('https://example.com').purpose(' ').execute()) + .rejects.toThrow('requires non-empty intent'); + expect(() => allowed.get({ id: 'unknown', risk: 'MEMORY_ONLY' })) + .toThrow('Tool not available: unknown'); + }); +}); diff --git a/source/teaql-ts/tests/trace-chain-graph-vectors.test.ts b/source/teaql-ts/tests/trace-chain-graph-vectors.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..9eee39be64b18a9fb0db3647e638bdcf759fe59a --- /dev/null +++ b/source/teaql-ts/tests/trace-chain-graph-vectors.test.ts @@ -0,0 +1,59 @@ +import fixture from './fixtures/graph-mutation-lineage-v1.json'; +import { EntityRoot } from '../src/core/entity-root'; +import { GraphMutationSession, MutationIntent } from '../src/core/request-intent'; +import { MutationTraceScope, TraceNode } from '../src/core/trace-chain'; + +it.each(fixture.cases)('recovers the shared $id graph fixture without claiming provider proof', input => { + const graph = new GraphMutationSession(new MutationIntent(input.requestComment)); + const scopes = new Map(); + const ledger = new EntityRoot(); + for (const node of input.nodes) { + const assigned = (node as any).assignedEntityId ?? node.entityId; + const key = { entity: node.entityType, id: assigned }; + if ('ledgerLineage' in node) ledger.setTraceChain(key, (node.ledgerLineage as any[]).map(item => + ({ ...item, kind: 'auditReason' as const }))); + const request = graph.request({ entity: node.entityType, ledgerRoot: ledger, ledgerKey: key }, + node.parent ? scopes.get(node.parent) : undefined, node.localComment ?? undefined); + scopes.set(node.nodeId, request.scopeFor(key)); + const expected = input.expected.find(item => item.nodeId === node.nodeId)!; + expect(request.traceFor(key)).toEqual(expected.lineage.map(item => ({ ...item, kind: 'auditReason' }))); + } +}); + +it('shares immutable ancestors and preserves unsigned-64 identity through deep recovery', () => { + const graph = new GraphMutationSession(new MutationIntent('submit order')); + const root = graph.request({ entity: 'Order' }).scopeFor({ entity: 'Order', id: 18446744073709551615n }); + const inherited = graph.request({ entity: 'OrderItem' }, root, ' \t\u0085'); + expect(inherited.scopeFor({ entity: 'OrderItem', id: '1' })).toBe(root); + let scope = root; + for (let index = 0; index < 2000; index++) scope = new MutationTraceScope(scope, + { kind: 'auditReason', name: 'Child', entityId: index, detail: 'local reason' }); + const nodes = scope.recover(); + expect(nodes).toHaveLength(2001); + expect(nodes[0].entityId).toBe(18446744073709551615n); + expect(Object.isFrozen(nodes)).toBe(true); + expect(Object.isFrozen(nodes[0])).toBe(true); +}); + +it('snapshots trace-only entries through merge, typed rekey and clear', () => { + const source = new EntityRoot(); + const original: TraceNode[] = [{ kind: 'auditReason', name: 'Order', entityId: '1', detail: 'submit order' }]; + source.setTraceChain({ entity: 'Order', id: -1 }, original); + original[0] = { ...original[0], detail: 'caller changed reason' }; + const target = new EntityRoot(); target.mergeFrom(source); + target.rekey({ entity: 'Order', id: -1 }, { entity: 'Order', id: '1' }); + expect(target.traceChain({ entity: 'Payment', id: '1' })).toBeUndefined(); + expect(target.traceChain({ entity: 'Order', id: 1 })).toBeUndefined(); + expect(target.traceChain({ entity: 'Order', id: '1' })?.[0].detail).toBe('submit order'); + target.clearEntity({ entity: 'Order', id: '1' }); + expect(target.traceChain({ entity: 'Order', id: '1' })).toBeUndefined(); +}); + +it('rejects a parent token from an independent graph without altering either root intent', () => { + const first = new GraphMutationSession(new MutationIntent('first operation')); + const second = new GraphMutationSession(new MutationIntent('second operation')); + const scope = first.request({ entity: 'Order' }).scopeFor({ entity: 'Order', id: '1' }); + expect(() => second.request({ entity: 'Payment' }, scope)).toThrow('GRAPH_TRACE_SCOPE_MISMATCH'); + expect(second.request({ entity: 'Order' }).traceFor({ entity: 'Order', id: '1' })[0].detail).toBe('second operation'); + expect(scope.recover()[0].detail).toBe('first operation'); +}); diff --git a/source/teaql-ts/tests/trace-chain-graph.test.ts b/source/teaql-ts/tests/trace-chain-graph.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..bc8b81d419ea9441b9aaff51458bab6595d1fb01 --- /dev/null +++ b/source/teaql-ts/tests/trace-chain-graph.test.ts @@ -0,0 +1,538 @@ +import { UserContext } from '../src/core/context'; +import { AbstractSQLTeaQLClient, EntitySchema, MutationResult, SQLExecutionEvidenceStore, SQLExecutionMetadata } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; +import { GraphCommittedError, GraphMutationSession, MutationIntent, MutationRequest } from '../src/core/request-intent'; +import { EntityRoot } from '../src/core/entity-root'; +import { MutationTraceScope, TraceNode } from '../src/core/trace-chain'; +import { RuntimeModule } from '../src/core/runtime-module'; +import { LoadedScalarSnapshot } from '../src/core/loaded-scalar-snapshot'; +import { projectSQLLog, PLAINTEXT_LOG_ENV, PLAINTEXT_LOG_ACK } from '../src/core/log-privacy'; + +it('preflights sibling loaded values before any write, without changing the payload', async () => { + const f = await fixture(); + const oldValue = 'PRIVATE-OLD-PAYMENT', newValue = 'PRIVATE-NEW-PAYMENT'; + const evidence = new SQLExecutionEvidenceStore(); + try { + await f.client.executeMutation({ entity: 'Payment', id: '11', action: 'Create', + payload: { name: oldValue }, comment: 'seed prior payment' }); + f.client.setRuntimeTelemetrySink(evidence); + const root = { entity: 'Order', action: 'Create', payload: { name: 'root fixture' } }; + const child = { entity: 'Payment', id: '11', version: 1, action: 'Update', payload: { name: newValue } }; + const snapshot = new LoadedScalarSnapshot({ name: oldValue }); + f.client.setQueryLoggingEnabled(false).setMutationLoggingEnabled(false); + await f.client.executeGraphSave(new MutationIntent(`replace ${oldValue} with ${newValue}`), async graph => { + f.client.preflightMutation(graph.request(root)); + f.client.preflightMutation(graph.request(child).withLoadedSnapshot(snapshot)); + const request = graph.request(root); + const saved = await f.client.executeMutation(request); + expect(JSON.stringify(projectSQLLog(saved.metadata!))).not.toContain(oldValue); + const previous = process.env[PLAINTEXT_LOG_ENV]; + try { + process.env[PLAINTEXT_LOG_ENV] = PLAINTEXT_LOG_ACK; + const debug = projectSQLLog(saved.metadata!); + expect(debug.auditReason).toContain(oldValue); + delete process.env[PLAINTEXT_LOG_ENV]; + expect(JSON.stringify(projectSQLLog(debug))).not.toContain(oldValue); + expect(JSON.stringify(projectSQLLog(saved.metadata!))).not.toContain(newValue); + } finally { + if (previous === undefined) delete process.env[PLAINTEXT_LOG_ENV]; + else process.env[PLAINTEXT_LOG_ENV] = previous; + } + await f.client.executeMutation(graph.request(child, request.scopeFor({ entity: 'Order', id: saved.id })) + .withLoadedSnapshot(snapshot)); + }); + expect(evidence.snapshot()).toHaveLength(4); + expect(JSON.stringify(evidence.snapshot())).not.toContain(oldValue); + expect(JSON.stringify(evidence.snapshot())).not.toContain(newValue); + expect(JSON.stringify(f.client.auditTrace)).not.toContain(oldValue); + expect(child.payload).toEqual({ name: newValue }); + expect((await f.driver.query('SELECT name FROM payment_data WHERE id = ?', ['11'])).rows[0].name).toBe(newValue); + } finally { await f.client.close(); } +}); + +const schemas: Record = { Order: { + table: 'order_data', auditMaskFields: ['name'], columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string', logPolicy: 'plain' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number', logPolicy: 'plain' }, + name: { columnName: 'name', logicalType: 'text', decode: 'string', logPolicy: 'plain' }, + }, +} }; +for (const name of ['OrderItem', 'Payment', 'PaymentAttempt', 'Shipment']) schemas[name] = { + ...schemas.Order, table: `${name.toLowerCase()}_data`, +}; +class Client extends AbstractSQLTeaQLClient { + constructor(driver: SQLiteDriver) { super(driver, schemas); } +} + +it('installs frozen generated module metadata without mutating its registration map', async () => { + const driver = new SQLiteDriver(':memory:'); + const module = new RuntimeModule(schemas); + class FrozenClient extends AbstractSQLTeaQLClient { + constructor() { super(driver, module.schemas); } + } + const client = new FrozenClient().setDiagnosticSQLLogSink(undefined); + try { + expect(Object.isFrozen(module.schemas)).toBe(true); + expect(() => client.install(module)).not.toThrow(); + await new UserContext().insertResource('dataService', client).ensureSchema(); + expect(Object.isFrozen(module.schemas)).toBe(true); + } finally { await client.close(); } +}); +async function fixture() { + const driver = new SQLiteDriver(':memory:'); + const client = new Client(driver).setDiagnosticSQLLogSink(undefined); + await new UserContext().insertResource('dataService', client).ensureSchema(); + return { driver, client }; +} + +it('emits no committed audit while the graph is still running or after rollback', async () => { + const f = await fixture(); + const observed: unknown[] = []; + f.client.setAuditSink(event => { observed.push(event); }); + const failure = new Error('later graph failure'); + try { + await expect(f.client.executeGraphSave(new MutationIntent('submit order'), async graph => { + await f.client.executeMutation(graph.request({ entity: 'Order', action: 'Create', payload: { name: 'first' } })); + expect(observed).toHaveLength(0); + expect(f.client.auditTrace).toHaveLength(0); + throw failure; + })).rejects.toBe(failure); + expect(observed).toHaveLength(0); + expect(f.client.auditTrace).toHaveLength(0); + expect((await f.driver.query('SELECT * FROM order_data')).rowCount).toBe(0); + } finally { await f.client.close(); } +}); + +function reasons(nodes: readonly TraceNode[] | unknown): unknown { + return (nodes as readonly TraceNode[]).map(node => [node.kind, node.name, node.entityId, node.detail]); +} + +it.each([false, true])('TC-MUT-11 blank local reasons inherit at real sinks, logging=%p', async logging => { + const f = await fixture(); + const sql = new SQLExecutionEvidenceStore(); + const diagnostic = jest.fn(); + const audit: Readonly>[] = []; + const commands: Array<{ entity: string; id: string; lineage: readonly TraceNode[] }> = []; + const blanks = [undefined, '', ' \t\r\n', '\u0085', '\u00a0', '\u2003']; + const root = { kind: 'auditReason', name: 'Order', entityId: '100', detail: 'submit order' } as const; + const payment = { kind: 'auditReason', name: 'Payment', entityId: '201', detail: 'authorize payment' } as const; + const shipment = { kind: 'auditReason', name: 'Shipment', entityId: '301', detail: 'dispatch shipment' } as const; + f.client.setQueryLoggingEnabled(logging).setMutationLoggingEnabled(logging) + .setRuntimeTelemetrySink(sql).setDiagnosticSQLLogSink({ write: diagnostic }) + .setAuditSink(event => { audit.push(event); }); + const query = jest.spyOn(f.driver, 'query'), transaction = jest.spyOn(f.driver, 'transaction'); + try { + for (const blank of blanks) { + await expect(f.client.executeMutation({ entity: 'Order', action: 'Create', + id: '999', payload: { name: 'must not persist' }, comment: blank })).rejects.toMatchObject({ + code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'mutation', + }); + } + expect(query).not.toHaveBeenCalled(); + expect(transaction).not.toHaveBeenCalled(); + expect(sql.snapshot()).toHaveLength(0); + expect(audit).toHaveLength(0); + expect(diagnostic).not.toHaveBeenCalled(); + + await f.client.executeGraphSave(new MutationIntent('submit order'), async graph => { + const rootScope = graph.request({ entity: 'Order' }).scopeFor({ entity: 'Order', id: '100' }); + const paymentScope = graph.request({ entity: 'Payment' }, rootScope, 'authorize payment') + .scopeFor({ entity: 'Payment', id: '201' }); + const sibling = graph.request({ entity: 'Shipment', action: 'Create', id: '301', + payload: { name: 'sibling' } }, rootScope, 'dispatch shipment'); + for (const [index, blank] of blanks.entries()) { + const id = String(400 + index); + // Pass the blank value to the runtime unchanged. Do not substitute a + // parent trace or filter the local reason in the test. + const request = graph.request({ entity: 'PaymentAttempt', action: 'Create', id, + payload: { name: `attempt-${index}` } }, paymentScope, blank); + expect(request.scopeFor({ entity: 'PaymentAttempt', id })).toBe(paymentScope); + const result = await f.client.executeMutation(request); + commands.push({ entity: 'PaymentAttempt', id, lineage: request.traceFor({ entity: 'PaymentAttempt', id }) }); + expect(result.metadata?.mutationLineage).toEqual([root, payment]); + expect(result.metadata?.statements?.map(statement => statement.operation)).toEqual(['insert', 'select']); + expect(audit).toHaveLength(0); + } + const result = await f.client.executeMutation(sibling); + commands.push({ entity: 'Shipment', id: '301', lineage: sibling.traceFor({ entity: 'Shipment', id: '301' }) }); + expect(result.metadata?.mutationLineage).toEqual([root, shipment]); + expect(paymentScope.recover()).toEqual([root, payment]); + expect(rootScope.recover()).toEqual([root]); + expect(audit).toHaveLength(0); + }); + const expected = [...blanks.map(() => [root, payment]), [root, shipment]]; + expect(commands.map(command => command.lineage)).toEqual(expected); + expect(audit.map(event => event.mutationLineage)).toEqual(expected); + expect(audit.map(event => [event.entity, String(event.id)])) + .toEqual(commands.map(command => [command.entity, command.id])); + expect(sql.snapshot().map(statement => statement.mutationLineage)) + .toEqual(expected.flatMap(lineage => [lineage, lineage])); + expect(sql.snapshot().map(statement => statement.operation)) + .toEqual(expected.flatMap(() => ['insert', 'select'])); + expect(sql.snapshot().every(statement => statement.executionOutcome === 'success' + && statement.auditReason === 'submit order')).toBe(true); + expect(diagnostic).toHaveBeenCalledTimes(logging ? expected.length * 2 : 0); + expect((await f.driver.query('SELECT id, name FROM paymentattempt_data ORDER BY id')).rows) + .toEqual(blanks.map((_, index) => ({ id: 400 + index, name: `attempt-${index}` }))); + } finally { await f.client.close(); } +}); + +it('retains all six native graph lineages at request, physical SQL, and committed audit boundaries', async () => { + const f = await fixture(); + for (const [entity, id] of [['Order', '1'], ['OrderItem', '1'], ['Payment', '1'], + ['PaymentAttempt', '1'], ['Shipment', '1'], ['OrderItem', '2']]) { + await f.client.executeMutation({ entity, id, action: 'Create', payload: { name: `${entity}-fixture-${id}` }, comment: 'prepare fixture' }); + } + const commands: Array = []; + const sql = new SQLExecutionEvidenceStore(); + const audit: Readonly>[] = []; + f.client.setRuntimeTelemetrySink(sql).setAuditSink(event => { audit.push(event); }); + try { + await f.client.executeGraphSave(new MutationIntent('submit order'), async graph => { + for (const [entity, id] of [['Order', '1'], ['OrderItem', '1'], ['Payment', '1'], + ['PaymentAttempt', '1'], ['Shipment', '1'], ['OrderItem', '2']]) { + f.client.preflightMutation(graph.request({ entity, id, version: 1, + action: entity === 'OrderItem' && id === '2' ? 'Delete' : 'Update', + payload: { name: `${entity}-changed-${id}` } })); + } + const apply = async (entity: string, id: string, parent?: MutationTraceScope, + local?: string, action = 'Update') => { + const request = graph.request({ entity, id, action, version: 1, + payload: { name: `${entity}-changed-${id}` } }, parent, local); + await f.client.executeMutation(request); + commands.push(request.traceFor({ entity, id })); + return request.scopeFor({ entity, id }); + }; + const root = await apply('Order', '1'); + await apply('OrderItem', '1', root); + const payment = await apply('Payment', '1', root, 'authorize payment'); + await apply('PaymentAttempt', '1', payment); + await apply('Shipment', '1', root, 'dispatch shipment'); + await apply('OrderItem', '2', root, 'remove unavailable item', 'Delete'); + expect(audit).toHaveLength(0); + }); + const root = ['auditReason', 'Order', '1', 'submit order']; + const expected = [[root], [root], [root, ['auditReason', 'Payment', '1', 'authorize payment']], + [root, ['auditReason', 'Payment', '1', 'authorize payment']], + [root, ['auditReason', 'Shipment', '1', 'dispatch shipment']], + [root, ['auditReason', 'OrderItem', '2', 'remove unavailable item']]]; + expect(commands.map(reasons)).toEqual(expected); + expect(sql.snapshot().map(entry => reasons(entry.mutationLineage))).toEqual(expected.flatMap(lineage => [lineage, lineage])); + expect(audit.map(event => reasons(event.mutationLineage))).toEqual(expected); + expect(sql.snapshot().map(entry => entry.auditReason)).toEqual(Array(12).fill('submit order')); + expect(sql.snapshot().every(entry => entry.tracePath[0].name === 'Order')).toBe(true); + expect(sql.snapshot().map(entry => entry.operation)).toEqual(['update', 'update', 'update', 'update', 'update', 'delete'].flatMap(op => [op, 'select'])); + expect(sql.snapshot().filter(entry => entry.operation === 'select').every(entry => entry.resultCount === 1 + && entry.tracePath.map(node => node.kind).join('/') === 'operation/request/provider/sql')).toBe(true); + expect(audit.every(event => Object.isFrozen(event.mutationLineage))).toBe(true); + } finally { await f.client.close(); } +}); + +it('materializes database-assigned IDs and preserves independent concurrent graphs on one Context', async () => { + const f = await fixture(); + const sql = new SQLExecutionEvidenceStore(); + f.client.setRuntimeTelemetrySink(sql); + const create = (reason: string) => f.client.executeGraphSave(new MutationIntent(reason), async graph => { + const rootRequest = graph.request({ entity: 'Order', action: 'Create', payload: { name: `fixture-${reason}` } }); + const root = await f.client.executeMutation(rootRequest); + const parent = rootRequest.scopeFor({ entity: 'Order', id: root.id }); + const childRequest = graph.request({ entity: 'Payment', action: 'Create', payload: { name: 'payment-fixture' } }, parent, 'authorize payment'); + return f.client.executeMutation(childRequest); + }); + try { + const results = await Promise.all([create('first operation'), create('second operation')]); + const audit = f.client.auditTrace; + expect(audit).toHaveLength(4); + for (const [index, reason] of ['first operation', 'second operation'].entries()) { + expect(results[index].metadata?.auditReason).toBe(reason); + expect(results[index].metadata?.statements?.map(entry => entry.operation)).toEqual(['insert', 'select']); + const entries = sql.snapshot().filter(entry => entry.auditReason === reason); + expect(entries).toHaveLength(4); + expect(entries.map(entry => entry.operation)).toEqual(['insert', 'select', 'insert', 'select']); + expect(reasons(entries[3].mutationLineage)).toEqual([ + ['auditReason', 'Order', String(index + 1), reason], + ['auditReason', 'Payment', String(index + 1), 'authorize payment'], + ]); + expect(reasons(entries[2].mutationLineage)).toEqual(reasons(entries[3].mutationLineage)); + expect(reasons(audit[index * 2 + 1].mutationLineage)).toEqual(reasons(entries[3].mutationLineage)); + expect(results[index].metadata?.statements?.[1].mutationLineage).toEqual(entries[3].mutationLineage); + } + } finally { await f.client.close(); } +}); + +it('uses a complete per-type ledger override without changing sibling fallback', async () => { + const f = await fixture(); + const ledger = new EntityRoot(); + const key = { entity: 'Payment', id: -1 }; + const override: TraceNode[] = [{ kind: 'auditReason', name: 'Order', entityId: '100', detail: 'submit order' }, + { kind: 'auditReason', name: 'Payment', entityId: '1', detail: 'review payment exception' }]; + ledger.setTraceChain(key, override); + override[1] = { ...override[1], detail: 'MUTATED-CALLER-SOURCE' }; + try { + await f.client.executeGraphSave(new MutationIntent('submit order'), async graph => { + const request = graph.request({ entity: 'Payment', action: 'Create', payload: { name: 'payment-fixture' }, ledgerRoot: ledger, ledgerKey: key }); + await f.client.executeMutation(request); + await f.client.executeMutation(graph.request({ entity: 'Order', action: 'Create', payload: { name: 'order-fixture' } })); + }); + expect(reasons(f.client.auditTrace[0].mutationLineage)).toEqual([ + ['auditReason', 'Order', '100', 'submit order'], + ['auditReason', 'Payment', '1', 'review payment exception'], + ]); + expect(reasons(f.client.auditTrace[1].mutationLineage)).toEqual([['auditReason', 'Order', '1', 'submit order']]); + ledger.rekey(key, { entity: 'Payment', id: '1' }); + expect(ledger.traceChain(key)).toBeUndefined(); + expect(ledger.traceChain({ entity: 'Order', id: '1' })).toBeUndefined(); + const other = new EntityRoot(); other.mergeFrom(ledger); + expect(other.traceChain({ entity: 'Payment', id: '1' })).toEqual(ledger.traceChain({ entity: 'Payment', id: '1' })); + other.clearCommitted(); expect(other.traceChain({ entity: 'Payment', id: '1' })).toBeUndefined(); + } finally { await f.client.close(); } +}); + +it.each([false, true].flatMap(logging => [false, true].map(empty => ({ logging, empty }))))( + 'retains native ledger override or empty fallback at every emitted boundary: %j', async ({ logging, empty }) => { + const f = await fixture(); + const targets = [['Order', '100'], ['Payment', '1'], ['OrderItem', '1'], ['Shipment', '1']]; + for (const [entity, id] of targets) await f.client.executeMutation({ + entity, id, action: 'Create', payload: { name: `${entity}-before` }, comment: 'seed ledger fixture', + }); + const secret = 'LEDGER-PRIVATE-PAYMENT'; + const reason = `submit using ${secret}`; + const root: TraceNode = Object.freeze({ kind: 'auditReason', name: 'Order', entityId: '100', detail: reason }); + const leaf: TraceNode = Object.freeze({ kind: 'auditReason', name: 'Payment', entityId: '1', detail: `review ${secret}` }); + // Explicit complete native input: this is not a generated-planner writer proof. + const callerChain: readonly TraceNode[] = Object.freeze(empty ? [] : [root, leaf]); + const callerBefore = JSON.stringify(callerChain); + const ledger = new EntityRoot(); + ledger.setTraceChain({ entity: 'Payment', id: '1' }, callerChain); + ledger.setTraceChain({ entity: 'OrderItem', id: '1' }, []); + expect(ledger.traceChain({ entity: 'Payment', id: '1' })).not.toBe(callerChain); + expect(ledger.traceChain({ entity: 'Shipment', id: '1' })).toBeUndefined(); + + const context = new UserContext(); + f.client.setUserContext(context); + const policy = jest.spyOn(context, 'enterMutationPolicy'); + const sql = new SQLExecutionEvidenceStore(); + const diagnostics: SQLExecutionMetadata[] = []; + const audits: Readonly>[] = []; + let inTransaction = false, commits = 0; + const transaction = f.driver.transaction.bind(f.driver); + jest.spyOn(f.driver, 'transaction').mockImplementation(async work => { + inTransaction = true; + try { const result = await transaction(work); commits++; return result; } + finally { inTransaction = false; } + }); + f.client.setQueryLoggingEnabled(logging).setMutationLoggingEnabled(logging) + .setRuntimeTelemetrySink(sql).setDiagnosticSQLLogSink({ write: entry => diagnostics.push(entry) }) + .setAuditSink(event => { + expect(inTransaction).toBe(false); + expect(commits).toBe(audits.length < 4 ? 1 : 2); + audits.push(event); + }); + const query = f.driver.query.bind(f.driver); + const physical = jest.spyOn(f.driver, 'query'); + const commands: Array<{ entity: string; id: string; comment: string; + payload: unknown; lineage: readonly TraceNode[] }> = []; + const execute = f.client.executeMutation.bind(f.client); + jest.spyOn(f.client, 'executeMutation').mockImplementation(async request => { + expect(request).toBeInstanceOf(MutationRequest); + const mutation = request.mutation; + commands.push({ entity: mutation.entity, id: mutation.id, comment: request.comment, + payload: { ...mutation.payload }, lineage: request.traceFor({ entity: mutation.entity, id: mutation.id }) }); + return execute(request); + }); + const results: MutationResult[] = []; + const names = ['root-after', secret, 'item-after', 'shipment-after']; + const payloads = names.map(name => Object.freeze({ name })); + try { + await f.client.executeGraphSave(new MutationIntent(reason), async graph => { + const mutations = targets.map(([entity, id], index) => ({ entity, id, version: 1, + action: 'Update', payload: payloads[index], ledgerRoot: ledger, ledgerKey: { entity, id } })); + const rootRequest = graph.request(mutations[0]); + const parent = rootRequest.scopeFor({ entity: 'Order', id: '100' }); + const requests = [rootRequest, graph.request(mutations[1], parent), + graph.request(mutations[2], parent), graph.request(mutations[3], parent)]; + // Capture the future Payment's marked value before the first root SQL. + for (const request of requests) f.client.preflightMutation(request); + for (const request of requests) { + results.push(await f.client.executeMutation(request)); + expect(audits).toHaveLength(0); + } + expect(graph.intent.comment).toBe(reason); + }); + + const expected = [[root], empty ? [root] : [root, leaf], [root], [root]]; + const safe = expected.map(nodes => nodes.map(node => ({ ...node, + detail: node.detail!.replace(secret, '[REDACTED]') }))); + expect(commands).toHaveLength(4); + expect(commands.map(command => [command.entity, command.id])).toEqual(targets); + expect(commands.map(command => reasons(command.lineage))).toEqual(expected.map(reasons)); + expect(commands.map(command => command.comment)).toEqual(Array(4).fill(reason)); + expect(commands.map(command => command.payload)).toEqual(payloads); + expect(policy.mock.calls.map(([input]) => { + const mutation = input as { entity: string; id: string; comment: string; payload: unknown }; + return [mutation.entity, mutation.id, mutation.comment, mutation.payload]; + })) + .toEqual(targets.map(([entity, id], index) => [entity, id, reason, payloads[index]])); + expect(commits).toBe(1); + expect(physical).toHaveBeenCalledTimes(8); + const raw = results.flatMap(result => [...result.metadata!.statements!]); + expect(raw.map(entry => [entry.parameterizedSQL, [...entry.parameters]])) + .toEqual(physical.mock.calls.map(([statement, values]) => [statement, values])); + expect(raw.map(entry => entry.parameters)).toEqual(targets.flatMap(([, id], index) => [[names[index], id, 1], [id]])); + expect(raw.map(entry => reasons(entry.mutationLineage))).toEqual(expected.flatMap(nodes => [reasons(nodes), reasons(nodes)])); + expect(raw.map(entry => entry.auditReason)).toEqual(Array(8).fill(reason)); + expect(raw.map(entry => entry.operation)).toEqual(Array(4).fill(['update', 'select']).flat()); + expect(raw.every(entry => entry.executionOutcome === 'success')).toBe(true); + for (const [index, result] of results.entries()) { + expect(result).toMatchObject({ success: true, id: targets[index][1], version: 2, + persistedRecord: { id: targets[index][1], version: 2, name: names[index] } }); + expect(result.metadata!.statements![0].affectedRows).toBe(1); + expect(result.metadata!.statements![1].resultCount).toBe(1); + expect(result.metadata!.statements![0].tracePath.map(node => [node.kind, node.name])) + .toEqual([['operation', 'Order'], ['entity', targets[index][0]], ['provider', 'sqlite'], ['sql', 'update']]); + expect(result.metadata!.statements![1].tracePath.map(node => [node.kind, node.name])) + .toEqual([['operation', 'Order'], ['request', 'Order'], ['provider', 'sqlite'], ['sql', 'select']]); + } + expect(sql.snapshot()).toHaveLength(8); + expect(diagnostics).toHaveLength(logging ? 8 : 0); + expect(diagnostics).toEqual(logging ? sql.snapshot() : []); + expect(audits.map(event => [event.entity, event.id, event.version])).toEqual(targets.map(([entity, id]) => [entity, id, 2])); + expect(audits.map(event => reasons(event.mutationLineage))).toEqual(safe.map(reasons)); + expect(audits.map(event => event.reason)).toEqual(Array(4).fill('submit using [REDACTED]')); + expect(sql.snapshot().map(entry => reasons(entry.mutationLineage))).toEqual(safe.flatMap(nodes => [reasons(nodes), reasons(nodes)])); + expect(sql.snapshot().map(entry => entry.auditReason)).toEqual(Array(8).fill('submit using [REDACTED]')); + for (const entry of [...sql.snapshot(), ...diagnostics]) { + expect(JSON.stringify(entry)).not.toContain(secret); + } + expect(JSON.stringify(audits)).not.toContain(secret); + expect(audits.every(event => Object.isFrozen(event) && Object.isFrozen(event.mutationLineage))).toBe(true); + expect(JSON.stringify(callerChain)).toBe(callerBefore); + expect(ledger.traceChain({ entity: 'Payment', id: '1' })).toEqual(callerChain); + expect(payloads).toEqual(names.map(name => ({ name }))); + for (const [index, [entity, id]] of targets.entries()) { + expect((await query(`SELECT name, version FROM ${schemas[entity].table} WHERE id = ?`, [id])).rows) + .toEqual([{ name: names[index], version: 2 }]); + } + + // Native owners explicitly clear their ledger; raw requests do not promise generated cleanup. + ledger.clearCommitted(); + expect(ledger.traceChain({ entity: 'Payment', id: '1' })).toBeUndefined(); + const nextReason = `independent mention ${secret}`; + await f.client.executeGraphSave(new MutationIntent(nextReason), async graph => { + const request = graph.request({ entity: 'Payment', id: '1', version: 2, action: 'Update', + payload: { name: 'following-value' }, ledgerRoot: ledger, ledgerKey: { entity: 'Payment', id: '1' } }); + f.client.preflightMutation(request); + const result = await f.client.executeMutation(request); + expect(result.persistedRecord).toMatchObject({ id: '1', version: 3, name: 'following-value' }); + }); + expect(commits).toBe(2); + expect(commands).toHaveLength(5); + expect(physical).toHaveBeenCalledTimes(10); + expect(sql.snapshot()).toHaveLength(10); + expect(diagnostics).toHaveLength(logging ? 10 : 0); + expect(audits).toHaveLength(5); + const next = [['auditReason', 'Payment', '1', nextReason]]; + expect(reasons(commands[4].lineage)).toEqual(next); + expect(reasons(audits[4].mutationLineage)).toEqual(next); + expect(audits[4].reason).toBe(nextReason); + expect(sql.snapshot().slice(8).map(entry => reasons(entry.mutationLineage))).toEqual([next, next]); + expect(sql.snapshot().slice(8).map(entry => entry.auditReason)).toEqual([nextReason, nextReason]); + expect(JSON.stringify(callerChain)).toBe(callerBefore); + } finally { await f.client.close(); } + }); + +it('rejects missing root intent before opening a transaction even when logging is disabled', async () => { + const f = await fixture(); + const transaction = jest.spyOn(f.driver, 'transaction'); + f.client.setMutationLoggingEnabled(false).setQueryLoggingEnabled(false); + try { + await expect(f.client.executeGraphSave(undefined as any, async () => { throw new Error('should not run'); })) + .rejects.toMatchObject({ code: 'REQUEST_COMMENT_REQUIRED', field: 'comment' }); + expect(transaction).not.toHaveBeenCalled(); + expect(f.client.auditTrace).toHaveLength(0); + } finally { await f.client.close(); } +}); + +it('cannot silently join an unrelated active transaction or reuse an expired graph capability', async () => { + const f = await fixture(); + let expired!: GraphMutationSession; + const mutation = { entity: 'Order', action: 'Create', payload: { name: 'order-fixture' }, comment: 'unrelated operation' }; + try { + await f.client.executeGraphSave(new MutationIntent('submit order'), async graph => { + expired = graph; + await expect(f.client.executeMutation(mutation)).rejects.toThrow('GRAPH_MUTATION_SESSION_REQUIRED'); + await f.client.executeMutation(graph.request(mutation)); + }); + await expect(f.client.executeMutation(expired.request(mutation))).rejects.toThrow('GRAPH_MUTATION_SESSION_REQUIRED'); + expect((await f.driver.query('SELECT * FROM order_data')).rowCount).toBe(1); + } finally { await f.client.close(); } +}); + +it('publishes later committed events and runs cleanup after one audit sink fails', async () => { + const f = await fixture(); + const calls: string[] = []; + let count = 0; + f.client.setAuditSink(() => { calls.push('audit'); if (++count === 1) throw new Error('audit sink failed'); }); + try { + await expect(f.client.executeGraphSave(new MutationIntent('submit order'), async graph => { + for (const name of ['first-fixture', 'second-fixture']) + await f.client.executeMutation(graph.request({ entity: 'Order', action: 'Create', payload: { name } })); + f.client.afterGraphRollback(() => { calls.push('rollback'); }); + f.client.afterGraphCommit(() => { calls.push('cleanup'); }); + })).rejects.toMatchObject({ committed: true }); + expect(calls).toEqual(['cleanup', 'audit', 'audit']); + expect((await f.driver.query('SELECT * FROM order_data')).rowCount).toBe(2); + expect(f.client.auditTrace).toHaveLength(2); + await f.client.executeGraphSave(new MutationIntent('next independent operation'), async () => undefined); + } finally { await f.client.close(); } +}); + +it.each([false, true])('redacts sibling-owned private values throughout graph intent and readback: failure=%s', async failReadback => { + const f = await fixture(); + const sql = new SQLExecutionEvidenceStore(); + f.client.setRuntimeTelemetrySink(sql); + const secret = 'SIBLING-PRIVATE-CANARY'; + const reason = `submit using ${secret}`; + const query = f.driver.query.bind(f.driver); + if (failReadback) jest.spyOn(f.driver, 'query').mockImplementation(async (statement, values) => { + if (statement.startsWith('SELECT') && statement.includes('payment_data') && statement.includes('WHERE "id" = ?')) + throw new Error('injected readback failure'); + return query(statement, values); + }); + try { + const operation = f.client.executeGraphSave(new MutationIntent(reason), async graph => { + const root = { entity: 'Order', action: 'Create', payload: { name: 'root-fixture' } }; + const child = { entity: 'Payment', action: 'Create', payload: { name: secret } }; + f.client.preflightMutation(graph.request(root)); + f.client.preflightMutation(graph.request(child)); + const request = graph.request(root); + const saved = await f.client.executeMutation(request); + await f.client.executeMutation(graph.request(child, request.scopeFor({ entity: 'Order', id: saved.id }), 'authorize payment')); + expect(graph.intent.comment).toBe(reason); + }); + if (failReadback) await expect(operation).rejects.toThrow('injected readback failure'); + else await operation; + expect(JSON.stringify(sql.snapshot())).not.toContain(secret); + expect(JSON.stringify(f.client.auditTrace)).not.toContain(secret); + expect(sql.snapshot().every(entry => entry.auditReason === 'submit using [REDACTED]')).toBe(true); + if (failReadback) expect(f.client.auditTrace).toHaveLength(0); + else expect((await query('SELECT name FROM payment_data')).rows[0].name).toBe(secret); + await f.client.executeMutation({ entity: 'Order', action: 'Create', payload: { name: 'next-fixture' }, comment: reason }); + expect(sql.snapshot()[sql.snapshot().length - 1].auditReason).toBe(reason); + } finally { await f.client.close(); } +}); + +it('does not invoke rollback callbacks when a commit callback fails after database commit', async () => { + const f = await fixture(); + const calls: string[] = []; + try { + await expect(f.client.executeGraphSave(new MutationIntent('submit order'), async graph => { + await f.client.executeMutation(graph.request({ entity: 'Order', action: 'Create', payload: { name: 'committed' } })); + f.client.afterGraphRollback(() => { calls.push('rollback'); }); + f.client.afterGraphCommit(() => { calls.push('broken'); throw new Error('commit callback failed'); }); + f.client.afterGraphCommit(() => { calls.push('cleanup'); }); + })).rejects.toBeInstanceOf(GraphCommittedError); + expect((await f.driver.query('SELECT * FROM order_data')).rowCount).toBe(1); + expect(calls).toEqual(['broken', 'cleanup']); + } finally { await f.client.close(); } +}); diff --git a/source/teaql-ts/tests/trace-chain-sql.test.ts b/source/teaql-ts/tests/trace-chain-sql.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..06004fb4b5878a2cca7a95a3635464aa1bc93161 --- /dev/null +++ b/source/teaql-ts/tests/trace-chain-sql.test.ts @@ -0,0 +1,593 @@ +import { SelectQuery } from '../src/core/ast'; +import { UserContext } from '../src/core/context'; +import { AbstractSQLTeaQLClient, EntitySchema, SQLExecutionEvidenceStore, SqlQueryResult } from '../src/sql/core'; +import { SQLiteDriver } from '../src/sql/sqlite'; +import { executeRelationFacets } from '../src/core/facet'; + +const schemas: Record = {}; +for (const [entity, relation, target] of [ + ['School', 'platform', 'Platform'], ['Platform', 'organization', 'Organization'], + ['Organization', 'region', 'Region'], ['Region', '', ''], +]) { + schemas[entity] = { + table: `${entity.toLowerCase()}_data`, auditMaskFields: [], + columns: { + id: { columnName: 'id', logicalType: 'integer', decode: 'string', logPolicy: 'plain' }, + version: { columnName: 'version', logicalType: 'integer', decode: 'number', logPolicy: 'plain' }, + name: { columnName: 'name', logicalType: 'text', decode: 'string', logPolicy: 'plain' }, + ...(relation ? { [relation]: { columnName: relation, logicalType: 'integer' as const, + decode: 'string' as const, logPolicy: 'plain' as const } } : {}), + }, + relations: relation ? { [relation]: { targetEntity: target, localKey: relation, + foreignKey: 'id', many: false } } : {}, + }; +} + +class Driver extends SQLiteDriver { + readbackFailure?: Error; + aggregateFailure?: Error; + aggregateCalls = 0; + async query(sql: string, values: any[] = []): Promise { + if (/COUNT\(/i.test(sql) && sql.includes('platform_data')) { + this.aggregateCalls++; + if (this.aggregateFailure) throw this.aggregateFailure; + } + if (this.readbackFailure && sql.includes('school_data') && sql.startsWith('SELECT') + && sql.includes('WHERE "id" = ?')) throw this.readbackFailure; + return super.query(sql, values); + } +} +class Client extends AbstractSQLTeaQLClient { + constructor(driver: Driver, model = schemas) { super(driver, model); } +} +async function fixture(privatePlatformName = false) { + const driver = new Driver(':memory:'); + const model: Record = privatePlatformName ? { ...schemas, Platform: { + ...schemas.Platform, columns: { ...schemas.Platform.columns, + name: { ...schemas.Platform.columns.name, logPolicy: 'masked' } }, + } } : schemas; + const client = new Client(driver, model).setDiagnosticSQLLogSink(undefined); + const context = new UserContext().insertResource('dataService', client); + await context.ensureSchema(); + for (const [entity, relation, target] of [ + ['Region', '', ''], ['Organization', 'region', 'Region'], + ['Platform', 'organization', 'Organization'], ['School', 'platform', 'Platform'], + ]) await client.executeMutation({ entity, action: 'Create', id: '1', + payload: { name: entity, ...(target ? { [relation]: '1' } : {}) }, comment: 'seed native SQL trace fixture' }); + const evidence = new SQLExecutionEvidenceStore(); + client.setRuntimeTelemetrySink(evidence); + return { driver, client, context, evidence }; +} +function graphQuery(comment = 'load school graph') { + const region = new SelectQuery('Region').limit(1).comment('load region'); + const organization = new SelectQuery('Organization').limit(1).comment('load organization'); + organization.relations.push({ name: 'region', query: region }); + const platform = new SelectQuery('Platform').limit(1).comment('load platform'); + platform.relations.push({ name: 'organization', query: organization }); + const school = new SelectQuery('School').limit(1).comment(comment).purpose('inspect native graph trace'); + school.relations.push({ name: 'platform', query: platform }); + return school; +} + +it.each([false, true])('compound aggregates emit one physical SQLite statement: logging=%p', async logging => { + const f = await fixture(); + try { + const diagnostics: unknown[] = []; + f.client.setQueryLoggingEnabled(logging).setDiagnosticSQLLogSink({write: entry => diagnostics.push(entry)}); + const reads = jest.spyOn(f.driver, 'query'); + const query = new SelectQuery('School').aggregate('Count', 'id', 'schoolCount').aggregate('Sum', 'id', 'idTotal') + .comment('calculate school totals').purpose('render totals'); + const rows = await f.client.executeQuery(query); + expect(rows).toHaveLength(1); + expect(rows[0]).toMatchObject({schoolCount: 1, idTotal: 1}); + expect(reads).toHaveBeenCalledTimes(1); + expect(reads.mock.calls[0][0]).toMatch(/COUNT\(/i); + expect(reads.mock.calls[0][0]).toMatch(/SUM\(/i); + const facts = f.evidence.snapshot(); + expect(facts).toHaveLength(1); + expect(facts[0].traceChain!.map(node => node.detail)).toEqual(['render totals', 'calculate school totals']); + expect(diagnostics).toHaveLength(logging ? 1 : 0); + console.log(`RTC_COM_07_AGGREGATE_PASS logging=${logging} expressions=2 statements=1`); + } finally { await f.client.close(); } +}); + +it('derives three relation frames from actual SQLite loading without injected trace frames', async () => { + const f = await fixture(); + try { + const rows = await f.client.executeQuery(graphQuery()); + expect(rows[0].platform.organization.region.name).toBe('Region'); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(4); + const route = [['platform', 'School.platform'], ['organization', 'Platform.organization'], + ['region', 'Organization.region']]; + const comments = ['load school graph', 'load platform', 'load organization', 'load region']; + entries.forEach((entry, index) => { + expect(entry.comment).toBe('load school graph'); + expect(entry.purpose).toBe('inspect native graph trace'); + expect(entry.traceChain?.map(node => node.detail)).toEqual([ + 'inspect native graph trace', 'load school graph', ...comments.slice(1, index + 1), + ]); + expect(entry.tracePath.map(frame => [frame.kind, frame.name, (frame as any).detail ?? ''])).toEqual([ + ['operation', 'School', 'query'], ['request', 'School', ''], + ...route.slice(0, index).map(([name, detail]) => ['relation', name, detail]), + ['provider', 'sqlite', ''], ['sql', 'select', ''], + ]); + }); + } finally { await f.client.close(); } +}); + +it.each([false, true])('retains native operation parents, explicit comments and local defaults in real SQLite evidence: logging=%p', async logging => { + const f = await fixture(); + try { + f.client.setQueryLoggingEnabled(logging); + const diagnostics: unknown[] = []; + f.client.setDiagnosticSQLLogSink({ write: entry => diagnostics.push(entry) }); + const reads = jest.spyOn(f.driver, 'query'); + const query = graphQuery('load schools').purpose('render school list'); + query.relations[0].operation = { kind: 'relation-select', method: 'selectPlatformWith', relation: 'platform' }; + query.relations[0].query!.comment('load visible platforms'); + query.relations[0].query!.relations[0].operation = { + kind: 'relation-select', method: 'selectOrganizationWith', relation: 'organization', + }; + expect((await f.client.executeQuery(query))[0].platform.organization.name).toBe('Organization'); + const entries = f.evidence.snapshot(); + expect(reads).toHaveBeenCalledTimes(4); + expect(entries).toHaveLength(4); // retained evidence is independent of diagnostic logging + expect(diagnostics).toHaveLength(logging ? 4 : 0); + expect(entries[1].traceChain!.map(node => node.detail)).toEqual([ + 'render school list', 'load schools', 'selectPlatformWith(...)', 'load visible platforms', + ]); + expect(entries[2].traceChain!.map(node => node.detail)).toEqual([ + 'render school list', 'load schools', 'selectPlatformWith(...)', 'load visible platforms', + 'selectOrganizationWith(...)', 'load organization', + ]); + expect(entries.every(entry => entry.comment === 'load schools')).toBe(true); + expect(query.relations[0].query!.relations[0].query!.commentText).toBe('load organization'); + console.log(`RTC_COM_02_PASS logging=${logging} explicit=both`); + } finally { await f.client.close(); } +}); + +it.each([false, true])('rejects explicitly blank relation comments before child SQLite: logging=%p', async logging => { + const f = await fixture(); + try { + f.client.setQueryLoggingEnabled(logging); + const reads = jest.spyOn(f.driver, 'query'); + for (const blank of ['', ' \t', '\u0085']) { + reads.mockClear(); + const query = graphQuery(); + query.relations[0].query!.comment(blank); + await expect(f.client.executeQuery(query)).rejects.toMatchObject({ field: 'comment', requestKind: 'query' }); + expect(reads.mock.calls.length).toBeLessThanOrEqual(1); + expect(reads.mock.calls.some(([sql]) => sql.includes('FROM "platform_data"'))).toBe(false); + expect(query.relations[0].query!.commentText).toBe(blank); + console.log(`RTC_COM_04_RELATION_PASS logging=${logging} invalid_child_provider=0`); + } + reads.mockClear(); + expect((await f.client.executeQuery(graphQuery()))[0].platform.organization.region.name).toBe('Region'); + expect(reads).toHaveBeenCalledTimes(4); + } finally { await f.client.close(); } +}); + +it.each([false, true])('rejects explicitly blank facet value comments before value SQLite: logging=%p', async logging => { + const f = await fixture(); + try { + f.client.setQueryLoggingEnabled(logging); + const reads = jest.spyOn(f.driver, 'query'); + for (const blank of ['', ' \t', '\u0085']) { + reads.mockClear(); + const child = new SelectQuery('Platform').aggregate('Count', 'id', 'schoolCount').comment(blank); + const outer = new SelectQuery('School').comment('load schools').purpose('validate facet input'); + outer.facetBy('platformCounts', 'platform', { toQuery: () => child }, true, { + kind: 'facet', method: 'facetByPlatformAs', relation: 'platform', alias: 'platformCounts', + }); + await expect(executeRelationFacets(f.client, query => query, outer, outer.facets)) + .rejects.toMatchObject({ field: 'comment', requestKind: 'query' }); + expect(reads.mock.calls.some(([sql]) => sql.includes('FROM "platform_data"'))).toBe(false); + expect(child.commentText).toBe(blank); + console.log(`RTC_COM_04_FACET_PASS logging=${logging} invalid_value_provider=0`); + } + } finally { await f.client.close(); } +}); + +it.each([false, true])('retains named and unnamed exact-count intent in real SQLite: logging=%p', async logging => { + const f = await fixture(); + try { + f.client.setQueryLoggingEnabled(logging); + const diagnostics: unknown[] = []; + f.client.setDiagnosticSQLLogSink({write: entry => diagnostics.push(entry)}); + const query = new SelectQuery('School').limit(1).comment('load schools').purpose('render school list'); + expect(await f.client.executeCount(query, 'totalSchools', { + kind: 'named-count', method: 'countAs', alias: 'totalSchools', + })).toBe(1); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(1); + expect(entries[0].parameterizedSQL).toContain('totalSchools'); + expect(entries[0].traceChain!.map(node => node.detail)).toEqual([ + 'render school list', 'load schools', "countAs('totalSchools')", + ]); + expect(entries[0].tracePath.some(node => node.kind === 'relation')).toBe(false); + f.evidence.enableAll(); diagnostics.length = 0; + expect(await f.client.executeCount(query)).toBe(1); + const defaults = f.evidence.snapshot(); + expect(defaults).toHaveLength(1); + expect(defaults[0].parameterizedSQL).toContain('__teaql_total'); + expect(defaults[0].traceChain!.map(node => node.detail)).toEqual([ + 'render school list', 'load schools', 'framework: named-count', + ]); + expect(defaults[0].tracePath.some(node => node.kind === 'relation')).toBe(false); + expect(diagnostics).toHaveLength(logging ? 1 : 0); + expect(query.commentText).toBe('load schools'); + console.log(`RTC_COM_05_PASS logging=${logging} named=true unnamed=true`); + } finally { await f.client.close(); } +}); + +it('shares one named facet operation between the aggregate and value-query SQLite branches', async () => { + const f = await fixture(); + try { + const nested = new SelectQuery('Platform').aggregate('Count', 'id', 'schoolCount') + .comment('load platform facets'); + const outer = new SelectQuery('School').comment('load schools').purpose('render school list'); + outer.facetBy('platformCounts', 'platform', { toQuery: () => nested }, true, { + kind: 'facet', method: 'facetByPlatformAs', relation: 'platform', alias: 'platformCounts', + }); + const facets = await executeRelationFacets(f.client, query => query, outer, outer.facets); + expect(facets.platformCounts.map(row => row.schoolCount)).toEqual([1]); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(2); + const prefix = ['render school list', 'load schools', "facetByPlatformAs('platformCounts')"]; + expect(entries[0].traceChain!.map(node => node.detail)).toEqual([...prefix, 'aggregate platform']); + expect(entries[0].parameterizedSQL).toContain('AS "schoolCount"'); + expect(entries[1].traceChain!.map(node => node.detail)).toEqual([...prefix, 'load platform facets']); + } finally { await f.client.close(); } +}); + +it('assembles minimal reverse children using a private key without publishing an unselected field', async () => { + const f = await fixture(); + const model = { ...schemas, Platform: { ...schemas.Platform, relations: { + ...schemas.Platform.relations, + schoolList: { targetEntity: 'School', localKey: 'id', foreignKey: 'platform', many: true }, + } } }; + const client = new Client(f.driver, model).setDiagnosticSQLLogSink(undefined); + try { + const child = new SelectQuery('School').select(['name']).limit(3).comment('load school previews'); + const query = new SelectQuery('Platform').select(['name']).limit(1) + .comment('load platforms').purpose('render bounded previews') + .relationQuery('schoolList', child, 'id', 'platform', true, { + kind: 'relation-select', method: 'selectSchoolListWith', relation: 'schoolList', + }); + const rows = await client.executeQuery(query); + expect(rows[0].schoolList).toHaveLength(1); + expect(rows[0].schoolList[0].name).toBe('School'); + expect(Object.prototype.hasOwnProperty.call(rows[0].schoolList[0], 'platform')).toBe(false); + expect(child.selectItems).toEqual(['name']); + } finally { await f.client.close(); } +}); + +it.each([false, true])('prefixes and escaped facet aliases preserve bindings under privacy projection: logging=%p', async logging => { + const f = await fixture(true); + const secret = 'TRACE-PRIVATE-CANARY'; + try { + await f.client.executeMutation({entity: 'Platform', action: 'Update', id: '1', version: 1, + payload: {name: secret}, comment: 'seed privacy canary'}); + f.client.setQueryLoggingEnabled(logging); + const diagnostics: unknown[] = []; + f.client.setDiagnosticSQLLogSink({write: entry => diagnostics.push(entry)}); + const reads = jest.spyOn(f.driver, 'query'); + for (const privateInput of [false, true]) { + f.evidence.enableAll(); diagnostics.length = 0; reads.mockClear(); + const alias = 'choices"\\\n' + (privateInput ? secret : ''); + const comment = privateInput ? `what: load ${secret}` : 'what: load schools'; + const purpose = privateInput ? `why: inspect ${secret}` : 'why: inspect schools'; + const child = new SelectQuery('Platform').limit(10).aggregate('Count', 'id', 'schoolCount') + .comment(privateInput ? `load ${secret} facets` : 'load platform facets'); + if (privateInput) child.filter({name: {$eq: secret}}); + const query = new SelectQuery('School').limit(10).comment(comment).purpose(purpose) + .facetBy(alias, 'platform', {toQuery: () => child}, false, + {kind: 'facet', method: 'facetByPlatformAs', alias, relation: 'platform'}); + const before = JSON.stringify(query); + const result = await executeRelationFacets(f.client, query => query, query, query.facets); + expect(result[alias]).toHaveLength(1); + expect(result[alias][0]).toMatchObject({id: '1', name: secret, schoolCount: 1}); + const facts = f.evidence.snapshot(); + expect(facts).toHaveLength(2); expect(reads).toHaveBeenCalledTimes(2); + expect(diagnostics).toHaveLength(logging ? 2 : 0); + const safeComment = privateInput ? 'what: load [REDACTED]' : comment; + const safePurpose = privateInput ? 'why: inspect [REDACTED]' : purpose; + const chains = facts.map(entry => entry.traceChain!.map(node => node.detail)); + for (const local of ['aggregate platform', privateInput ? 'load [REDACTED] facets' : 'load platform facets']) + expect(chains).toContainEqual([safePurpose, safeComment, 'facetByPlatformAs(\'choices"\\\\\\n' + (privateInput ? '[REDACTED]' : '') + '\')', local]); + if (privateInput) { + expect(JSON.stringify(facts)).not.toContain(secret); + expect(reads.mock.calls.some(call => call[1]?.includes(secret))).toBe(true); + } + expect(JSON.stringify(query)).toBe(before); + } + console.log(`RTC_COM_09_12_PASS logging=${logging} plain=true private=true escaped=true bindings=true`); + } finally { await f.client.close(); } +}); + +it('projects private operands out of nested business trace comments as well as SQL diagnostics', async () => { + const f = await fixture(true); + try { + const query = graphQuery('load Platform graph'); + query.relations[0].query!.filter({ name: { $eq: 'Platform' } }).comment('load Platform details'); + await f.client.executeQuery(query); + expect(f.evidence.snapshot()).toHaveLength(4); + for (const entry of f.evidence.snapshot()) { + expect(entry.traceChain).toBeDefined(); + expect(entry.traceChain!.map(node => node.detail).join('/')).not.toContain('Platform'); + } + } finally { await f.client.close(); } +}); + +it('keeps successful write and failed readback as separate canonical statement paths', async () => { + const f = await fixture(); + const failure = new Error('READBACK-CANARY'); + f.driver.readbackFailure = failure; + try { + await expect(f.client.executeMutation({ entity: 'School', action: 'Update', id: '1', version: 1, + payload: { name: 'Changed' }, comment: 'rename school' })).rejects.toBe(failure); + const entries = f.evidence.snapshot(); + expect(entries.map(entry => entry.executionOutcome)).toEqual(['success', 'failure']); + entries.forEach((entry, index) => { + expect(entry.auditReason).toBe('rename school'); + expect(entry.tracePath.map(frame => [frame.kind, frame.name])).toEqual([ + ['operation', 'School'], [index === 0 ? 'entity' : 'request', 'School'], + ['provider', 'sqlite'], ['sql', index === 0 ? 'update' : 'select'], + ]); + }); + } finally { await f.client.close(); } +}); + +it('does not accept forged route metadata from a public query object', async () => { + const f = await fixture(); + try { + const query = new SelectQuery('School').limit(1).comment('read school').purpose('verify route ownership'); + (query as any).__teaqlTracePath = [{ level: 0, kind: 'relation', name: 'FORGED-RELATION' }]; + await f.client.executeQuery(query); + expect(JSON.stringify(f.evidence.snapshot())).not.toContain('FORGED-RELATION'); + expect(f.evidence.snapshot()[0].tracePath.map(frame => frame.kind)) + .toEqual(['operation', 'request', 'provider', 'sql']); + } finally { await f.client.close(); } +}); + +it('propagates typed facet provenance through actual membership and nested relation queries', async () => { + const f = await fixture(); + try { + const nested = new SelectQuery('Platform').aggregate('Count', 'id', 'schoolCount'); + nested.relations.push({ name: 'organization', query: new SelectQuery('Organization').limit(1) }); + const outer = new SelectQuery('School').limit(1).comment('load platform facets').purpose('inspect native facets'); + outer.facetBy('platforms', 'platform', { toQuery: () => nested }); + const facets = await executeRelationFacets(f.client, query => query, outer, outer.facets); + expect(facets.platforms[0].schoolCount).toBe(1); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(3); + expect(entries.map(entry => entry.tracePath.filter(frame => frame.kind === 'relation') + .map(frame => [frame.name, frame.detail]))).toEqual([ + [], [['platform', 'School.platform']], + [['platform', 'School.platform'], ['organization', 'Platform.organization']], + ]); + expect(entries.map(entry => entry.traceChain?.map(node => node.detail))).toEqual([ + ['inspect native facets', 'load platform facets', "framework: facet platform 'platforms'", 'aggregate platform'], + ['inspect native facets', 'load platform facets', "framework: facet platform 'platforms'", 'load Platform'], + ['inspect native facets', 'load platform facets', "framework: facet platform 'platforms'", + 'load Platform', 'load Organization'], + ]); + expect(entries.every(entry => entry.comment === 'load platform facets')).toBe(true); + } finally { await f.client.close(); } +}); + +it('preserves local relation names for a real relation aggregate', async () => { + const f = await fixture(); + try { + const query = new SelectQuery('School').limit(1).comment('load relation count').purpose('inspect aggregate provenance'); + query.relationAggregates.push({ relationName: 'platform', alias: 'platformCount', singleResult: true, + query: new SelectQuery('Platform').aggregate('Count', 'id', 'platformCount') }); + expect((await f.client.executeQuery(query))[0].platformCount).toBe(1); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(2); + expect(entries[1].tracePath.filter(frame => frame.kind === 'relation')) + .toEqual([{ kind: 'relation', name: 'platform', detail: 'School.platform', level: 2 }]); + } finally { await f.client.close(); } +}); + +it('retains query semantics and provenance when a three-level graph is streamed', async () => { + const f = await fixture(); + try { + const chunks = []; + for await (const chunk of f.client.executeForStream(graphQuery('stream school graph'), 1)) chunks.push(chunk); + expect(chunks[0][0].platform.organization.region.name).toBe('Region'); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(4); + expect(entries.every(entry => entry.tracePath[0].name === 'School' && entry.tracePath[0].detail === 'query')).toBe(true); + expect(entries.map(entry => entry.tracePath.filter(frame => frame.kind === 'relation').length).sort()).toEqual([0, 1, 2, 3]); + } finally { await f.client.close(); } +}); + +it.each([[false, false], [true, false], [false, true], [true, true]])( + 'isolates two live native query graphs with logging=%p sharedTemplate=%p', async (logging, sharedTemplate) => { + const f = await fixture(); + let release!: () => void; + const gate = new Promise(resolve => { release = resolve; }); + let bothEntered!: () => void; + const entered = new Promise(resolve => { bothEntered = resolve; }); + let roots = 0; + let timeout: ReturnType | undefined; + let pending: Promise[] = []; + const original = f.driver.query.bind(f.driver); + jest.spyOn(f.driver, 'query').mockImplementation(async (sql, values) => { + const rows = await original(sql, values); + if (/FROM "school_data"/.test(sql)) { + roots++; + if (roots === 2) bothEntered(); + await gate; + } + return rows; + }); + try { + f.client.setQueryLoggingEnabled(logging); + const template = graphQuery().relations[0].query!; + const templateBefore = JSON.stringify(template); + const build = (comment: string, purpose: string) => { + const query = graphQuery(comment).purpose(purpose); + if (sharedTemplate) query.relations[0].query = template; + return f.context.prepareQuery(query); + }; + const assertTemplateUnchanged = () => { + expect(JSON.stringify(template)).toBe(templateBefore); + }; + const first = build('first independent query', 'render first graph'); + const second = build('second independent query', 'render second graph'); + // Query optimization observers legitimately initialize these optional + // public fields to undefined; that is not a runtime-owned trace frame. + f.context.idSetPaginationCount = undefined; + f.context.continuousPageCursorId = undefined; + // Both operations resolve the same trusted service from the same Context. + // Context resources are application-owned; a live query must not insert an + // ambient trace stack into them or add runtime frames as Context properties. + const contextResources = (f.context as unknown as { resources: Map }).resources; + const resourcesBefore = new Map(contextResources); + const contextKeysBefore = Reflect.ownKeys(f.context); + const service = f.context.requireResource('dataService'); + expect(service).toBe(f.client); + pending = [service.executeQuery(first), service.executeQuery(second)]; + const completed = Promise.all(pending); + // Unlike Promise.all alone, this proves both real root SQL calls have + // finished while neither operation can return or load its descendants. + await Promise.race([entered, completed.then(() => { throw new Error('queries escaped the overlap barrier'); }), + new Promise((_, reject) => { timeout = setTimeout(() => reject(new Error('root overlap timeout')), 3000); })]); + expect(roots).toBe(2); + expect(f.evidence.snapshot()).toHaveLength(0); + expect(Reflect.ownKeys(f.context)).toEqual(contextKeysBefore); + expect(contextResources).toEqual(resourcesBefore); + expect(first.commentText).toBe('first independent query'); + expect(second.commentText).toBe('second independent query'); + assertTemplateUnchanged(); + release(); + const results = await completed; + expect(Reflect.ownKeys(f.context)).toEqual(contextKeysBefore); + expect(contextResources).toEqual(resourcesBefore); + expect(results.map(rows => rows.length)).toEqual([1, 1]); + expect(results.map(rows => rows[0].platform.organization.region.name)).toEqual(['Region', 'Region']); + assertTemplateUnchanged(); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(8); + for (const [reason, purpose] of [['first independent query', 'render first graph'], + ['second independent query', 'render second graph']]) { + const own = entries.filter(entry => entry.comment === reason); + expect(own).toHaveLength(4); + own.forEach((entry, depth) => { + expect(entry.purpose).toBe(purpose); + expect(entry.executionOutcome).toBe('success'); + expect(entry.tracePath.map(frame => [frame.kind, frame.name])).toEqual([ + ['operation', 'School'], ['request', 'School'], + ...['platform', 'organization', 'region'].slice(0, depth).map(name => ['relation', name]), + ['provider', 'sqlite'], ['sql', 'select'], + ]); + }); + } + } finally { + if (timeout) clearTimeout(timeout); + release(); + await Promise.allSettled(pending); + await f.client.close(); + } +}); + +describe('streamed relation aggregates', () => { + function request() { + const query = new SelectQuery('School').limit(2) + .comment('stream school counts').purpose('inspect streamed aggregate provenance'); + query.relationAggregates.push({ relationName: 'platform', alias: 'platformCount', singleResult: true, + query: new SelectQuery('Platform').aggregate('Count', 'id', 'platformCount') }); + return query; + } + + it.each([1, 2])('populates counts for chunk size %i with logging on and off', async chunkSize => { + for (const logging of [true, false]) { + const f = await fixture(); + try { + f.client.setQueryLoggingEnabled(logging); + const chunks = []; + for await (const chunk of f.client.executeForStream(request(), chunkSize)) chunks.push(chunk); + expect(chunks.map(chunk => chunk.map(row => row.platformCount))).toEqual([[1]]); + expect(f.driver.aggregateCalls).toBe(1); + if (logging) { + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(2); + expect(entries.map(entry => entry.executionOutcome)).toEqual(['success', 'success']); + expect(entries.every(entry => entry.comment === 'stream school counts')).toBe(true); + expect(entries.every(entry => entry.purpose === 'inspect streamed aggregate provenance')).toBe(true); + expect(entries[0].tracePath.map(frame => [frame.kind, frame.name])).toEqual([ + ['operation', 'School'], ['request', 'School'], ['relation', 'platform'], + ['provider', 'sqlite'], ['sql', 'select'], + ]); + expect(entries[1].tracePath.map(frame => frame.kind)) + .toEqual(['operation', 'request', 'provider', 'sql']); + } + } finally { await f.client.close(); } + } + }); + + it('completes the delivered aggregate before early stream cancellation', async () => { + const f = await fixture(); + try { + for await (const chunk of f.client.executeForStream(request(), 1)) { + expect(chunk[0].platformCount).toBe(1); + break; + } + expect(f.driver.aggregateCalls).toBe(1); + expect(f.evidence.snapshot().map(entry => entry.executionOutcome)).toEqual(['success', 'cancelled']); + // A later independent request must not inherit the aggregate's relation path. + await f.client.executeQuery(new SelectQuery('Region').limit(1) + .comment('independent region').purpose('verify stream scope isolation')); + const independent = f.evidence.snapshot(); + expect(independent[independent.length - 1].tracePath.map(frame => [frame.kind, frame.name])).toEqual([ + ['operation', 'Region'], ['request', 'Region'], ['provider', 'sqlite'], ['sql', 'select'], + ]); + } finally { await f.client.close(); } + }); + + it.each(['list', 'stream'])('%s preserves scalar membership when loading and aggregating the same relation', async mode => { + const f = await fixture(true); + try { + const query = request().comment('inspect Platform count'); + query.relationAggregates[0].query.filter({ name: { $eq: 'Platform' } }); + const child = new SelectQuery('Platform').limit(1); + child.relationAggregates.push({ relationName: 'organization', alias: 'organizationCount', singleResult: true, + query: new SelectQuery('Organization').aggregate('Count', 'id', 'organizationCount') }); + query.relations.push({ name: 'platform', query: child }); + const chunks = []; + if (mode === 'list') chunks.push(await f.client.executeQuery(query)); + else for await (const chunk of f.client.executeForStream(query, 1)) chunks.push(chunk); + expect(chunks[0][0].platformCount).toBe(1); + expect(chunks[0][0].platform.organizationCount).toBe(1); + const entries = f.evidence.snapshot(); + expect(entries).toHaveLength(4); + expect(entries.every(entry => entry.comment === 'inspect [REDACTED] count')).toBe(true); + expect(entries.every(entry => entry.tracePath[0].name === 'School')).toBe(true); + expect(entries.map(entry => entry.tracePath.filter(frame => frame.kind === 'relation').map(frame => frame.name))) + .toEqual(mode === 'list' ? [[], ['platform'], ['platform'], ['platform', 'organization']] + : [['platform'], ['platform'], ['platform', 'organization'], []]); + } finally { await f.client.close(); } + }); + + it.each([1, 2])('retains aggregate and stream failures before delivery, chunk size %i', async chunkSize => { + const f = await fixture(); + const failure = new Error('aggregate failed'); + f.driver.aggregateFailure = failure; + let delivered = 0; + try { + await expect((async () => { + for await (const chunk of f.client.executeForStream(request(), chunkSize)) delivered += chunk.length; + })()).rejects.toBe(failure); + expect(delivered).toBe(0); + expect(f.driver.aggregateCalls).toBe(1); + const entries = f.evidence.snapshot(); + expect(entries.map(entry => entry.executionOutcome)).toEqual(['failure', 'failure']); + expect(entries.map(entry => entry.tracePath.filter(frame => frame.kind === 'relation').map(frame => frame.name))) + .toEqual([['platform'], []]); + expect(entries.every(entry => entry.comment === 'stream school counts')).toBe(true); + } finally { await f.client.close(); } + }); +}); diff --git a/source/teaql-ts/tests/trace-chain-vectors.test.ts b/source/teaql-ts/tests/trace-chain-vectors.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..992f9f35e6aa3bbd773a927363d065753939390d --- /dev/null +++ b/source/teaql-ts/tests/trace-chain-vectors.test.ts @@ -0,0 +1,56 @@ +import { canonicalSQLTracePath, cloneTraceNodes, TraceKind, TraceNode } from '../src/core/trace-chain'; +import vectors from './fixtures/sql-trace-path-v1.json'; +import { QueryRequest } from '../src/core/request-intent'; +import { SelectQuery } from '../src/core/ast'; + +const kind = (name: string): TraceKind => (name[0].toLowerCase() + name.slice(1)) as TraceKind; +const sourceNode = (node: { kind: string; name: string; entityId: number | null; detail: string }): TraceNode => ({ + kind: kind(node.kind), name: node.name, entityId: node.entityId, detail: node.detail, +}); +const logical = (node: TraceNode) => ({ kind: node.kind[0].toUpperCase() + node.kind.slice(1), + name: node.name, entityId: node.entityId ?? null, detail: node.detail ?? '' }); + +it.each(vectors.cases)('passes frozen Rust SQL path vector $id and idempotence', vector => { + const input = vector.source.map(sourceNode); + const before = JSON.stringify(input); + const result = canonicalSQLTracePath(input, vector.backend, vector.operation as any); + expect(result.tracePath.map(logical)).toEqual(vector.expectedPath); + expect({ comment: result.comment ?? null, purpose: result.purpose ?? null, + auditReason: result.auditReason ?? null }).toEqual(vector.expectedIntent); + expect(canonicalSQLTracePath(result.tracePath, 'must-not-replace-provider', vector.operation as any).tracePath) + .toEqual(result.tracePath); + expect(JSON.stringify(input)).toBe(before); +}); + +it('owns immutable source nodes and preserves full unsigned-64 identity without numeric conversion', () => { + const original: TraceNode[] = [{ kind: 'operation', name: 'Order', detail: 'mutation' }, + { kind: 'entity', name: 'Payment', entityId: '18446744073709551615', detail: '' }, + { kind: 'provider', name: 'sqlite', detail: '' }, { kind: 'sql', name: 'update', detail: '' }]; + const saved = canonicalSQLTracePath(original, 'sqlite', 'update').tracePath; + (original[1] as any).entityId = 'wrong'; + expect(saved[1].entityId).toBe('18446744073709551615'); + expect(Object.isFrozen(saved)).toBe(true); + expect(saved.every(Object.isFrozen)).toBe(true); + const exact = cloneTraceNodes([{ kind: 'entity', name: 'Payment', entityId: 18446744073709551615n }]); + expect(exact[0].entityId).toBe(18446744073709551615n); +}); + +it('keeps independent immutable request sources across shared builders and derived snapshots', () => { + const first = new QueryRequest(new SelectQuery('School').comment('first').purpose('first purpose')); + const second = new QueryRequest(new SelectQuery('School').comment('second').purpose('second purpose')); + const builder = new SelectQuery('Platform'); + const one = first.derive(builder, 'platform'); + const two = second.derive(builder, 'alternatePlatform'); + builder.entity = 'Changed'; + expect(one.query.entity).toBe('Platform'); + expect(one.comment).toBe('load Platform'); + expect(two.comment).toBe('load Platform'); + expect(one.traceSource.map(node => node.detail)).toEqual(['first', 'first purpose', 'School.platform']); + expect(two.traceSource.map(node => node.detail)).toEqual(['second', 'second purpose', 'School.alternatePlatform']); + expect(first.traceSource).toHaveLength(2); + expect(new QueryRequest(one.query).traceSource).toEqual(one.traceSource); + expect(one.withQuery(one.query.clone()).traceSource).toEqual(one.traceSource); + expect(one.traceSource.every(Object.isFrozen)).toBe(true); + expect(JSON.stringify(one.query)).not.toContain('traceSource'); + expect(JSON.parse(JSON.stringify(one.query)).commentText).toBe('load Platform'); +}); diff --git a/source/teaql-ts/tests/wire-fields.test.ts b/source/teaql-ts/tests/wire-fields.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..e5b25e00aec15b5fb577d020a76f6abbc53c9095 --- /dev/null +++ b/source/teaql-ts/tests/wire-fields.test.ts @@ -0,0 +1,74 @@ +import { + createWireEntityMetadata, + encodeWireOutput, + normalizeWireInput, + retainSubmittedPaths, + WireInputError, +} from '../src/core/wire-fields'; +import { ObjectLocation } from '../src/core/object-location'; + +describe('generated wire-field metadata reference adapter', () => { + test.each([ + ['camelCase', 'userUrl', 'apiClientUrl'], + ['snake_case', 'user_url', 'api_client_url'], + ['PascalCase', 'UserUrl', 'ApiClientUrl'], + ] as const)('uses explicit %s metadata without serializer defaults', (profile, userUrl, apiClientUrl) => { + const metadata = createWireEntityMetadata( + 'UserProfile', ['user_url', 'api_client_url'], profile, + ); + expect(metadata.fields.user_url.wireName).toBe(userUrl); + expect(encodeWireOutput({ user_url: '/u', api_client_url: '/api' }, metadata)) + .toEqual({ [userUrl]: '/u', [apiClientUrl]: '/api' }); + expect(normalizeWireInput({ [userUrl]: '/u' }, metadata).values) + .toEqual({ user_url: '/u' }); + }); + + it('retains the exact submitted pointer for a declared legacy alias', () => { + const metadata = createWireEntityMetadata( + 'UserProfile', ['user_url'], 'camelCase', { user_url: ['user_url'] }, + ); + const normalized = normalizeWireInput({ user_url: '/legacy' }, metadata, '/profile'); + expect(normalized.values).toEqual({ user_url: '/legacy' }); + expect(normalized.sourceInstancePaths).toEqual({ user_url: '/profile/user_url' }); + expect(retainSubmittedPaths([{ + ruleId: 'required', entityType: 'UserProfile', + location: ObjectLocation.property('user_url'), + }], normalized)[0]).toMatchObject({ + sourceInstancePath: '/profile/user_url', + location: ObjectLocation.property('user_url'), + }); + }); + + it('rejects canonical and alias spellings before checker or mutation execution', () => { + const metadata = createWireEntityMetadata( + 'UserProfile', ['user_url'], 'camelCase', { user_url: ['user_url'] }, + ); + expect(() => normalizeWireInput({ userUrl: '/new', user_url: '/old' }, metadata)) + .toThrow(WireInputError); + try { + normalizeWireInput({ userUrl: '/new', user_url: '/old' }, metadata); + } catch (error) { + expect(error).toMatchObject({ + code: 'WIRE_FIELD_COLLISION', instancePath: '/user_url', + }); + } + }); + + it('rejects unknown fields and escapes their submitted JSON pointer', () => { + const metadata = createWireEntityMetadata('UserProfile', ['user_url']); + try { + normalizeWireInput({ 'bad~/name': true }, metadata); + throw new Error('expected normalization to reject the unknown field'); + } catch (error) { + expect(error).toMatchObject({ + code: 'WIRE_UNKNOWN_FIELD', instancePath: '/bad~0~1name', + }); + } + }); + + it('rejects ambiguous metadata before accepting input', () => { + expect(() => createWireEntityMetadata( + 'Collision', ['user_url', 'legacy'], 'camelCase', { legacy: ['userUrl'] }, + )).toThrow("maps to both 'user_url' and 'legacy'"); + }); +}); diff --git a/source/teaql-ts/tsconfig.json b/source/teaql-ts/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..0fe8d7e48c8781e1746c7192333cfa2eb70bc0cc --- /dev/null +++ b/source/teaql-ts/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "CommonJS", + "moduleResolution": "node", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "strict": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"] +} diff --git a/style.css b/style.css deleted file mode 100644 index 114adf441e9032febb46bc056b2a8bb651075f0d..0000000000000000000000000000000000000000 --- a/style.css +++ /dev/null @@ -1,28 +0,0 @@ -body { - padding: 2rem; - font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif; -} - -h1 { - font-size: 16px; - margin-top: 0; -} - -p { - color: rgb(107, 114, 128); - font-size: 15px; - margin-bottom: 10px; - margin-top: 5px; -} - -.card { - max-width: 620px; - margin: 0 auto; - padding: 16px; - border: 1px solid lightgray; - border-radius: 16px; -} - -.card p:last-child { - margin-bottom: 0; -} diff --git a/work-items.html b/work-items.html new file mode 100644 index 0000000000000000000000000000000000000000..5678d61125ebad3bb4c143319b0d5ca5b52015e5 --- /dev/null +++ b/work-items.html @@ -0,0 +1,28 @@ + + + + + + + TeaQL Browser SQLite WorkItems + + + + + + +
+

TEAQL TYPESCRIPT RUNTIME

+

Browser-local Data Service

+

Generated Q APIs and audited mutations, backed by SQLite/WASM.

+

Open the order management center

+

Open the generated order TraceChain page

+
+ + +
+

Starting SQLite/WASM…

+

+    
+ +