diff --git a/source/browser-sqlite/assist/create-customer.md b/source/browser-sqlite/assist/create-customer.md deleted file mode 100644 index 699c893bc74bbd83e1c52695e895457b66b3a681..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/create-customer.md +++ /dev/null @@ -1,82 +0,0 @@ - - -# 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/browser-sqlite/assist/create-customer_order.md b/source/browser-sqlite/assist/create-customer_order.md deleted file mode 100644 index 25e4ad7c6e890752a03135d6e3a69318075ba741..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/create-customer_order.md +++ /dev/null @@ -1,92 +0,0 @@ - - -# 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/browser-sqlite/assist/create-order_item.md b/source/browser-sqlite/assist/create-order_item.md deleted file mode 100644 index 570fa467c3825d766262eceeaee127024d23cd1b..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/create-order_item.md +++ /dev/null @@ -1,86 +0,0 @@ - - -# 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/browser-sqlite/assist/debug.md b/source/browser-sqlite/assist/debug.md deleted file mode 100644 index e03a34676b91d66208245b58588269099e3abea0..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/debug.md +++ /dev/null @@ -1,101 +0,0 @@ - - -# 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/browser-sqlite/assist/expression-customer_order.md b/source/browser-sqlite/assist/expression-customer_order.md deleted file mode 100644 index 5a2afd7281378070a8a7de14157051d62726ea84..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/expression-customer_order.md +++ /dev/null @@ -1,135 +0,0 @@ - - -# 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/browser-sqlite/assist/query-customer_order.md b/source/browser-sqlite/assist/query-customer_order.md deleted file mode 100644 index e8802eba2e3467b14ef6de45d83310bcdc95d7da..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/query-customer_order.md +++ /dev/null @@ -1,104 +0,0 @@ - - -# 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/browser-sqlite/assist/query-customer_order.order_item_list.md b/source/browser-sqlite/assist/query-customer_order.order_item_list.md deleted file mode 100644 index fb6d9cc9ca2da6b79a60e7540cd324b1ce0eeb0a..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/query-customer_order.order_item_list.md +++ /dev/null @@ -1,66 +0,0 @@ - - -# 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/browser-sqlite/assist/query-customer_order.status.md b/source/browser-sqlite/assist/query-customer_order.status.md deleted file mode 100644 index 30c09ab3e3668a4c8fcdba07bd4dae8869a1ea9d..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/query-customer_order.status.md +++ /dev/null @@ -1,72 +0,0 @@ - - -# 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/browser-sqlite/assist/query-order_item.md b/source/browser-sqlite/assist/query-order_item.md deleted file mode 100644 index 7bfe7baf0ecbb99a4aa9b88f109742222b693b06..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/query-order_item.md +++ /dev/null @@ -1,97 +0,0 @@ - - -# 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/browser-sqlite/assist/query-order_status.customer_order_list.md b/source/browser-sqlite/assist/query-order_status.customer_order_list.md deleted file mode 100644 index d56ca5fb1c6b750eec6e9ea95d5ef4f1c0a71e4c..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/query-order_status.customer_order_list.md +++ /dev/null @@ -1,66 +0,0 @@ - - -# 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/browser-sqlite/assist/query-order_status.md b/source/browser-sqlite/assist/query-order_status.md deleted file mode 100644 index f60c801d950a09212ce851164c7090bfdedc4ec4..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/assist/query-order_status.md +++ /dev/null @@ -1,104 +0,0 @@ - - -# 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/browser-sqlite/index.html b/source/browser-sqlite/index.html deleted file mode 100644 index 85396982e396e5f51f2b612c54fe864c51c822e8..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/index.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - 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

-
- - - -
- - - - -

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/source/browser-sqlite/order-model.xml b/source/browser-sqlite/order-model.xml deleted file mode 100644 index d343c387dcb487ca85551e72ec8bd70d965f6e15..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/order-model.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - <_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/browser-sqlite/orders-lib/package.json b/source/browser-sqlite/orders-lib/package.json deleted file mode 100644 index b91ad7420933e0d9b3dbb9ab9173e9bc3d815830..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "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/browser-sqlite/orders-lib/src/generated-bootstrap.ts b/source/browser-sqlite/orders-lib/src/generated-bootstrap.ts deleted file mode 100644 index b0458cb91bdca98d6fbab0a1eb1c0c53fb73d305..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated-bootstrap.ts +++ /dev/null @@ -1,69 +0,0 @@ -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/browser-sqlite/orders-lib/src/generated-search-models.ts b/source/browser-sqlite/orders-lib/src/generated-search-models.ts deleted file mode 100644 index 2ed841d2ddb74e211dc1257a6448ae63984e3ed7..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated-search-models.ts +++ /dev/null @@ -1,124 +0,0 @@ -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/browser-sqlite/orders-lib/src/generated/E.ts b/source/browser-sqlite/orders-lib/src/generated/E.ts deleted file mode 100644 index 17c3f3391887f2f471b6b8fb232871fbac8a282f..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/E.ts +++ /dev/null @@ -1,859 +0,0 @@ -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'), - ); - } - return new ValueExpression( - this.value.platform 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'), - ); - } - return new ValueExpression( - this.value.platform 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'), - ); - } - return new ValueExpression( - this.value.customer 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'), - ); - } - return new ValueExpression( - this.value.status 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'), - ); - } - return new ValueExpression( - this.value.customerOrder 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/browser-sqlite/orders-lib/src/generated/Q.ts b/source/browser-sqlite/orders-lib/src/generated/Q.ts deleted file mode 100644 index 89574ca4242c30c0aa10ea4e7993ef3df1f529aa..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/Q.ts +++ /dev/null @@ -1,44 +0,0 @@ -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/browser-sqlite/orders-lib/src/generated/models/Customer.ts b/source/browser-sqlite/orders-lib/src/generated/models/Customer.ts deleted file mode 100644 index 11e63d64a5153ac9eae796abf6380cd936fc64b0..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/models/Customer.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, 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: [], 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)) { - (this as any)._customerOrderList = (init as any).customerOrderList.map( - (child: unknown) => child instanceof CustomerOrder - ? child - : CustomerOrder.fromRecord(child as Record), - ); - 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)); - } - - private teaqlEntityKey(): EntityKey { return { entity: "Customer", id: (this as any)._ledgerId }; } - private teaqlAttachRoot(root: EntityRoot): this { - if ((this as any)._root !== root) { root.mergeFrom((this as any)._root); (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 { - if (!comment?.trim()) { - throw new Error("Security audit failure: auditAs() requires a non-empty reason"); - } - (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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - const action = (this as any)._action; - if (action === "Update") { - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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); - 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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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, - }; - const oldKey = this.teaqlEntityKey(); - Object.assign(this, result.persistedRecord); - (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; - (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); - 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(): CustomerOrder[] { - return (this as any)._customerOrderList; - } -} \ No newline at end of file diff --git a/source/browser-sqlite/orders-lib/src/generated/models/CustomerOrder.ts b/source/browser-sqlite/orders-lib/src/generated/models/CustomerOrder.ts deleted file mode 100644 index 7d1e7c609703de5db69af105642c1aa062c4dc8f..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/models/CustomerOrder.ts +++ /dev/null @@ -1,305 +0,0 @@ -import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, 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: [], 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)) { - (this as any)._orderItemList = (init as any).orderItemList.map( - (child: unknown) => child instanceof OrderItem - ? child - : OrderItem.fromRecord(child as Record), - ); - 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)); - } - - private teaqlEntityKey(): EntityKey { return { entity: "CustomerOrder", id: (this as any)._ledgerId }; } - private teaqlAttachRoot(root: EntityRoot): this { - if ((this as any)._root !== root) { root.mergeFrom((this as any)._root); (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 { - if (!comment?.trim()) { - throw new Error("Security audit failure: auditAs() requires a non-empty reason"); - } - (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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - const action = (this as any)._action; - if (action === "Update") { - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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); - 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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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, - }; - const oldKey = this.teaqlEntityKey(); - Object.assign(this, result.persistedRecord); - (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; - (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); - 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(): OrderItem[] { - return (this as any)._orderItemList; - } -} \ No newline at end of file diff --git a/source/browser-sqlite/orders-lib/src/generated/models/OrderItem.ts b/source/browser-sqlite/orders-lib/src/generated/models/OrderItem.ts deleted file mode 100644 index 0eda7dcddc80c795409809e91de891202436f92e..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/models/OrderItem.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, 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)); - } - - private teaqlEntityKey(): EntityKey { return { entity: "OrderItem", id: (this as any)._ledgerId }; } - private teaqlAttachRoot(root: EntityRoot): this { - if ((this as any)._root !== root) { root.mergeFrom((this as any)._root); (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 { - if (!comment?.trim()) { - throw new Error("Security audit failure: auditAs() requires a non-empty reason"); - } - (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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - const action = (this as any)._action; - if (action === "Update") { - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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, - }; - const oldKey = this.teaqlEntityKey(); - Object.assign(this, result.persistedRecord); - (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; - (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/browser-sqlite/orders-lib/src/generated/models/OrderStatus.ts b/source/browser-sqlite/orders-lib/src/generated/models/OrderStatus.ts deleted file mode 100644 index af708eae78a3ab570c0a41bb5706690ff6599233..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/models/OrderStatus.ts +++ /dev/null @@ -1,279 +0,0 @@ -import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, 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: [], 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)) { - (this as any)._customerOrderList = (init as any).customerOrderList.map( - (child: unknown) => child instanceof CustomerOrder - ? child - : CustomerOrder.fromRecord(child as Record), - ); - 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)); - } - - private teaqlEntityKey(): EntityKey { return { entity: "OrderStatus", id: (this as any)._ledgerId }; } - private teaqlAttachRoot(root: EntityRoot): this { - if ((this as any)._root !== root) { root.mergeFrom((this as any)._root); (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 { - if (!comment?.trim()) { - throw new Error("Security audit failure: auditAs() requires a non-empty reason"); - } - (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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - const action = (this as any)._action; - if (action === "Update") { - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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); - 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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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, - }; - const oldKey = this.teaqlEntityKey(); - Object.assign(this, result.persistedRecord); - (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; - (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); - 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(): CustomerOrder[] { - return (this as any)._customerOrderList; - } -} \ No newline at end of file diff --git a/source/browser-sqlite/orders-lib/src/generated/models/Platform.ts b/source/browser-sqlite/orders-lib/src/generated/models/Platform.ts deleted file mode 100644 index 903edd17a7151dd68ca08347f7bc1f9a7992739e..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/models/Platform.ts +++ /dev/null @@ -1,276 +0,0 @@ -import { CheckException, EntityKey, EntityRoot, GraphMutationSession, LoadedScalarSnapshot, MutationIntent, MutationTraceScope, ObjectLocation, 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: [], writable: true, enumerable: false }); - Object.defineProperty(this, "_customerList", { value: [], 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)) { - (this as any)._orderStatusList = (init as any).orderStatusList.map( - (child: unknown) => child instanceof OrderStatus - ? child - : OrderStatus.fromRecord(child as Record), - ); - this.markLoaded("orderStatusList"); - } - if (Array.isArray((init as any).customerList)) { - (this as any)._customerList = (init as any).customerList.map( - (child: unknown) => child instanceof Customer - ? child - : Customer.fromRecord(child as Record), - ); - 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)); - } - - private teaqlEntityKey(): EntityKey { return { entity: "Platform", id: (this as any)._ledgerId }; } - private teaqlAttachRoot(root: EntityRoot): this { - if ((this as any)._root !== root) { root.mergeFrom((this as any)._root); (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 { - if (!comment?.trim()) { - throw new Error("Security audit failure: auditAs() requires a non-empty reason"); - } - (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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - const action = (this as any)._action; - if (action === "Update") { - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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); - 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); - 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 && !(this as any)._comment?.trim()) { - throw new Error("Security audit failure: auditAs() must be called before save()"); - } - 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(new LoadedScalarSnapshot(this.teaqlMutationPayload())); - 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, - }; - const oldKey = this.teaqlEntityKey(); - Object.assign(this, result.persistedRecord); - (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; - (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); - 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); - 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(): OrderStatus[] { - return (this as any)._orderStatusList; - } - - customerList(): Customer[] { - return (this as any)._customerList; - } -} \ No newline at end of file diff --git a/source/browser-sqlite/orders-lib/src/generated/requests/CustomerOrderRequest.ts b/source/browser-sqlite/orders-lib/src/generated/requests/CustomerOrderRequest.ts deleted file mode 100644 index 88db869884a07a69c04c8623ea99ce8f15464e40..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/requests/CustomerOrderRequest.ts +++ /dev/null @@ -1,1206 +0,0 @@ -import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, TeaQLPage, UserContext, executeRelationFacets } from '../../teaql-ts'; -import { CustomerOrder } from '../models/CustomerOrder'; -import { mergeGeneratedScalarSearch, DynamicSearchWarning } 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) => this.executeForListInternal(context), - (context) => this.executeForRowsInternal(context), - (context, offset, limit) => this.executeForPageInternal(context, offset, limit), - (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.filters.length > 0) { - this.query.filter({ "$and": this.filters }); - } - - const service = context.requireResource("dataService"); - const rows = await service.executeQuery(context.prepareQuery(this.query)); - const queryRoot = new EntityRoot(); - 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, queryRoot)); - 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 executeForPageInternal( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - this.query.offset(offset).limit(limit); - if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); - const service = context.requireResource("dataService"); - const useIdSet = this.query.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( - this.query, this._pageCountAlias, countOperation); - const pageQuery = this.query.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(context.prepareQuery(pageQuery)); - const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" - ? context.idSetPaginationCount! - : (totalCountBeforeRows ?? await service.executeCount(this.query, this._pageCountAlias, countOperation)); - const queryRoot = new EntityRoot(); - const data = new SmartList(rows.map((row: unknown) => - row instanceof CustomerOrder - ? row - : CustomerOrder.fromRecord(row as Record, queryRoot))); - 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), this.query, this.query.facets); - } - return { data, totalCount, offset, limit }; - } - - private async *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 queryRoot = new EntityRoot(); - for await (const chunk of service.executeForStream(this.query, chunkSize)) { - for (const entity of chunk) { - yield entity instanceof CustomerOrder - ? entity - : CustomerOrder.fromRecord(entity as Record, queryRoot); - } - } - } - - private ensureIntent(): void { - 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"); - } - } - -} - -export class ExecutableCustomerOrderRequest { - constructor( - private readonly execute: (context: UserContext) => Promise>, - private readonly executeRows: (context: UserContext) => Promise>>, - private readonly page: ( - context: UserContext, offset: number, limit: number, - ) => 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); - } - - executeForPage( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - return this.page(context, offset, limit); - } - - 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/browser-sqlite/orders-lib/src/generated/requests/CustomerRequest.ts b/source/browser-sqlite/orders-lib/src/generated/requests/CustomerRequest.ts deleted file mode 100644 index 8f57982206811922242c13785420ea9e2fe2a92d..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/requests/CustomerRequest.ts +++ /dev/null @@ -1,795 +0,0 @@ -import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, TeaQLPage, UserContext, executeRelationFacets } from '../../teaql-ts'; -import { Customer } from '../models/Customer'; -import { mergeGeneratedScalarSearch, DynamicSearchWarning } 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) => this.executeForListInternal(context), - (context) => this.executeForRowsInternal(context), - (context, offset, limit) => this.executeForPageInternal(context, offset, limit), - (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.filters.length > 0) { - this.query.filter({ "$and": this.filters }); - } - - const service = context.requireResource("dataService"); - const rows = await service.executeQuery(context.prepareQuery(this.query)); - const queryRoot = new EntityRoot(); - 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, queryRoot)); - 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 executeForPageInternal( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - this.query.offset(offset).limit(limit); - if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); - const service = context.requireResource("dataService"); - const useIdSet = this.query.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( - this.query, this._pageCountAlias, countOperation); - const pageQuery = this.query.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(context.prepareQuery(pageQuery)); - const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" - ? context.idSetPaginationCount! - : (totalCountBeforeRows ?? await service.executeCount(this.query, this._pageCountAlias, countOperation)); - const queryRoot = new EntityRoot(); - const data = new SmartList(rows.map((row: unknown) => - row instanceof Customer - ? row - : Customer.fromRecord(row as Record, queryRoot))); - 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), this.query, this.query.facets); - } - return { data, totalCount, offset, limit }; - } - - private async *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 queryRoot = new EntityRoot(); - for await (const chunk of service.executeForStream(this.query, chunkSize)) { - for (const entity of chunk) { - yield entity instanceof Customer - ? entity - : Customer.fromRecord(entity as Record, queryRoot); - } - } - } - - private ensureIntent(): void { - 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"); - } - } - -} - -export class ExecutableCustomerRequest { - constructor( - private readonly execute: (context: UserContext) => Promise>, - private readonly executeRows: (context: UserContext) => Promise>>, - private readonly page: ( - context: UserContext, offset: number, limit: number, - ) => 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); - } - - executeForPage( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - return this.page(context, offset, limit); - } - - 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/browser-sqlite/orders-lib/src/generated/requests/OrderItemRequest.ts b/source/browser-sqlite/orders-lib/src/generated/requests/OrderItemRequest.ts deleted file mode 100644 index 915ebea00b4e2d0bf8b53b68bf9611dc5007f888..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/requests/OrderItemRequest.ts +++ /dev/null @@ -1,909 +0,0 @@ -import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, TeaQLPage, UserContext, executeRelationFacets } from '../../teaql-ts'; -import { OrderItem } from '../models/OrderItem'; -import { mergeGeneratedScalarSearch, DynamicSearchWarning } 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) => this.executeForListInternal(context), - (context) => this.executeForRowsInternal(context), - (context, offset, limit) => this.executeForPageInternal(context, offset, limit), - (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.filters.length > 0) { - this.query.filter({ "$and": this.filters }); - } - - const service = context.requireResource("dataService"); - const rows = await service.executeQuery(context.prepareQuery(this.query)); - const queryRoot = new EntityRoot(); - 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, queryRoot)); - 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 executeForPageInternal( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - this.query.offset(offset).limit(limit); - if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); - const service = context.requireResource("dataService"); - const useIdSet = this.query.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( - this.query, this._pageCountAlias, countOperation); - const pageQuery = this.query.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(context.prepareQuery(pageQuery)); - const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" - ? context.idSetPaginationCount! - : (totalCountBeforeRows ?? await service.executeCount(this.query, this._pageCountAlias, countOperation)); - const queryRoot = new EntityRoot(); - const data = new SmartList(rows.map((row: unknown) => - row instanceof OrderItem - ? row - : OrderItem.fromRecord(row as Record, queryRoot))); - 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), this.query, this.query.facets); - } - return { data, totalCount, offset, limit }; - } - - private async *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 queryRoot = new EntityRoot(); - for await (const chunk of service.executeForStream(this.query, chunkSize)) { - for (const entity of chunk) { - yield entity instanceof OrderItem - ? entity - : OrderItem.fromRecord(entity as Record, queryRoot); - } - } - } - - private ensureIntent(): void { - 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"); - } - } - -} - -export class ExecutableOrderItemRequest { - constructor( - private readonly execute: (context: UserContext) => Promise>, - private readonly executeRows: (context: UserContext) => Promise>>, - private readonly page: ( - context: UserContext, offset: number, limit: number, - ) => 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); - } - - executeForPage( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - return this.page(context, offset, limit); - } - - 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/browser-sqlite/orders-lib/src/generated/requests/OrderStatusRequest.ts b/source/browser-sqlite/orders-lib/src/generated/requests/OrderStatusRequest.ts deleted file mode 100644 index 8dd561efb47f7ea14b881537d5df8f5394bb48b8..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/requests/OrderStatusRequest.ts +++ /dev/null @@ -1,1162 +0,0 @@ -import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, TeaQLPage, UserContext, executeRelationFacets } from '../../teaql-ts'; -import { OrderStatus } from '../models/OrderStatus'; -import { mergeGeneratedScalarSearch, DynamicSearchWarning } 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) => this.executeForListInternal(context), - (context) => this.executeForRowsInternal(context), - (context, offset, limit) => this.executeForPageInternal(context, offset, limit), - (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.filters.length > 0) { - this.query.filter({ "$and": this.filters }); - } - - const service = context.requireResource("dataService"); - const rows = await service.executeQuery(context.prepareQuery(this.query)); - const queryRoot = new EntityRoot(); - 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, queryRoot)); - 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 executeForPageInternal( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - this.query.offset(offset).limit(limit); - if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); - const service = context.requireResource("dataService"); - const useIdSet = this.query.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( - this.query, this._pageCountAlias, countOperation); - const pageQuery = this.query.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(context.prepareQuery(pageQuery)); - const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" - ? context.idSetPaginationCount! - : (totalCountBeforeRows ?? await service.executeCount(this.query, this._pageCountAlias, countOperation)); - const queryRoot = new EntityRoot(); - const data = new SmartList(rows.map((row: unknown) => - row instanceof OrderStatus - ? row - : OrderStatus.fromRecord(row as Record, queryRoot))); - 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), this.query, this.query.facets); - } - return { data, totalCount, offset, limit }; - } - - private async *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 queryRoot = new EntityRoot(); - for await (const chunk of service.executeForStream(this.query, chunkSize)) { - for (const entity of chunk) { - yield entity instanceof OrderStatus - ? entity - : OrderStatus.fromRecord(entity as Record, queryRoot); - } - } - } - - private ensureIntent(): void { - 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"); - } - } - -} - -export class ExecutableOrderStatusRequest { - constructor( - private readonly execute: (context: UserContext) => Promise>, - private readonly executeRows: (context: UserContext) => Promise>>, - private readonly page: ( - context: UserContext, offset: number, limit: number, - ) => 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); - } - - executeForPage( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - return this.page(context, offset, limit); - } - - 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/browser-sqlite/orders-lib/src/generated/requests/PlatformRequest.ts b/source/browser-sqlite/orders-lib/src/generated/requests/PlatformRequest.ts deleted file mode 100644 index 459321a070eff1e3784738faa1efd1f15a604d87..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/generated/requests/PlatformRequest.ts +++ /dev/null @@ -1,791 +0,0 @@ -import { EntityRoot, SelectQuery, SmartList, TeaQLDataService, TeaQLPage, UserContext, executeRelationFacets } from '../../teaql-ts'; -import { Platform } from '../models/Platform'; -import { mergeGeneratedScalarSearch, DynamicSearchWarning } 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) => this.executeForListInternal(context), - (context) => this.executeForRowsInternal(context), - (context, offset, limit) => this.executeForPageInternal(context, offset, limit), - (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.filters.length > 0) { - this.query.filter({ "$and": this.filters }); - } - - const service = context.requireResource("dataService"); - const rows = await service.executeQuery(context.prepareQuery(this.query)); - const queryRoot = new EntityRoot(); - 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, queryRoot)); - 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 executeForPageInternal( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - this.query.offset(offset).limit(limit); - if (this.filters.length > 0) this.query.filter({ "$and": this.filters }); - const service = context.requireResource("dataService"); - const useIdSet = this.query.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( - this.query, this._pageCountAlias, countOperation); - const pageQuery = this.query.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(context.prepareQuery(pageQuery)); - const totalCount = useIdSet && context.idSetPaginationCountAccuracy === "EXACT" - ? context.idSetPaginationCount! - : (totalCountBeforeRows ?? await service.executeCount(this.query, this._pageCountAlias, countOperation)); - const queryRoot = new EntityRoot(); - const data = new SmartList(rows.map((row: unknown) => - row instanceof Platform - ? row - : Platform.fromRecord(row as Record, queryRoot))); - 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), this.query, this.query.facets); - } - return { data, totalCount, offset, limit }; - } - - private async *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 queryRoot = new EntityRoot(); - for await (const chunk of service.executeForStream(this.query, chunkSize)) { - for (const entity of chunk) { - yield entity instanceof Platform - ? entity - : Platform.fromRecord(entity as Record, queryRoot); - } - } - } - - private ensureIntent(): void { - 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"); - } - } - -} - -export class ExecutablePlatformRequest { - constructor( - private readonly execute: (context: UserContext) => Promise>, - private readonly executeRows: (context: UserContext) => Promise>>, - private readonly page: ( - context: UserContext, offset: number, limit: number, - ) => 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); - } - - executeForPage( - context: UserContext, offset: number, limit: number, - ): Promise> { - this.ensureIntent(); - return this.page(context, offset, limit); - } - - 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/browser-sqlite/orders-lib/src/runtime-module.ts b/source/browser-sqlite/orders-lib/src/runtime-module.ts deleted file mode 100644 index 6acd8901738de1cf9c62144bac04a2da46fec691..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/runtime-module.ts +++ /dev/null @@ -1,150 +0,0 @@ -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/browser-sqlite/orders-lib/src/teaql-schemas.ts b/source/browser-sqlite/orders-lib/src/teaql-schemas.ts deleted file mode 100644 index 879ae338448bc5e7d73d2e91a1cdc034d3a97213..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/teaql-schemas.ts +++ /dev/null @@ -1,34 +0,0 @@ -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/browser-sqlite/orders-lib/src/teaql-ts.ts b/source/browser-sqlite/orders-lib/src/teaql-ts.ts deleted file mode 100644 index b54a29ac3c12fb072cf4c292e22bb2e644b56319..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/src/teaql-ts.ts +++ /dev/null @@ -1,308 +0,0 @@ -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/browser-sqlite/orders-lib/teaql-i18n.json b/source/browser-sqlite/orders-lib/teaql-i18n.json deleted file mode 100644 index c69942a7adf7c471b956b29df700f8472446e43a..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/teaql-i18n.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "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/browser-sqlite/orders-lib/tsconfig.json b/source/browser-sqlite/orders-lib/tsconfig.json deleted file mode 100644 index 18139f743ca48c921f9a21e51be3b1485651513c..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/orders-lib/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "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/browser-sqlite/package-lock.json b/source/browser-sqlite/package-lock.json deleted file mode 100644 index 7e5f50ec71de3b0c822e3c2ddc25ab23226bd37f..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/package-lock.json +++ /dev/null @@ -1,1624 +0,0 @@ -{ - "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:vendor/teaql-teaql-0.3.0.tgz" - }, - "devDependencies": { - "puppeteer-core": "25.10.0", - "typescript": "5.9.2", - "vite": "^7.3.6" - } - }, - "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/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==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "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": { - "name": "@teaql/teaql", - "version": "0.3.0", - "resolved": "file:vendor/teaql-teaql-0.3.0.tgz", - "integrity": "sha512-au422aLCU34kwRxBu4rjqbiMCxpStQzTBek73/dUKw+SbJVMDNoo/VqkcgI8C4leKEF5p4ozH+QosGuSp+PIWw==", - "license": "Apache-2.0", - "dependencies": { - "node-fetch": "^2.7.0" - }, - "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/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/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "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/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==", - "license": "BSD-2-Clause" - }, - "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==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.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/browser-sqlite/package.json b/source/browser-sqlite/package.json deleted file mode 100644 index fd121aeb5c19e5c560a52e9b90a36ac26c7f4086..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "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" - }, - "dependencies": { - "@sqlite.org/sqlite-wasm": "3.53.0-build1", - "teaql-ts": "file:vendor/teaql-teaql-0.3.0.tgz" - }, - "devDependencies": { - "puppeteer-core": "25.10.0", - "typescript": "5.9.2", - "vite": "^7.3.6" - } -} diff --git a/source/browser-sqlite/scripts/smoke.mjs b/source/browser-sqlite/scripts/smoke.mjs deleted file mode 100644 index ebf221c1e05a361a4202ba01ae332385b723d706..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/scripts/smoke.mjs +++ /dev/null @@ -1,130 +0,0 @@ -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/')).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 || '/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.equal(response.resultCode, 0); assert.equal(response.status, 'YES'); - assert.equal(response.version, '1.001'); assert.equal(response.recordCount, 3); - 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/', {waitUntil: 'networkidle0'}); - await waitReady('MEMORY'); const baseline = await inspect('memory-first', 8); - await page.select('#example', 'all'); - await page.waitForFunction(() => { - const text = document.querySelector('#result')?.textContent; - return text && JSON.parse(text).metadata.totalCount === 4; - }); - const all = JSON.parse(await page.$eval('#result', element => element.textContent)); - assert.equal(all.data[0].orderNumber, 'KEEP-003'); - assert.deepEqual(all.facets.statusCounts.map(row => [row.orderCount, row.orderTotalAmount]), [[1, 100], [3, 1400], [0, null]]); - 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('#evidence-rows tr', rows => rows.length), 0); - assert.equal(await page.$eval('#sql', element => element.textContent), '[]'); - await page.click('#preset'); await waitReady('MEMORY'); - assert.deepEqual(await inspect('restored-preset', 8), baseline); - 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, queryPresetSwitch: true, forbiddenConstructorRejected: true, - 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/browser-sqlite/src/main.ts b/source/browser-sqlite/src/main.ts deleted file mode 100644 index 3da12fc319b5a90e8ce1260760a025474a231b24..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/src/main.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { BrowserSQLiteTeaQLClient, type BrowserSQLiteStorage } from 'teaql-ts/sql/browser-sqlite'; -import { DelegatingMutationPolicyApprovalProvider, DelegatingMutationPolicyRegistry, QueryParser, UserContext } from 'teaql-ts'; -import type { TeaQLPage } 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 { webResponse } from './web-response'; -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 example = document.querySelector('#example')!; -const filteredSearch = JSON.stringify(JSON.stringify({filter: {orderNumber: {$contains: 'KEEP'}}})); -const preset = `Q.customerOrdersWithMinimalFields() - .filterByJson(${filteredSearch}) - .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")`; -search.value = preset; -type Runtime = {client: BrowserSQLiteTeaQLClient; context: UserContext; evidence: SQLExecutionEvidenceStore; diagnostics: SQLExecutionMetadata[]}; -let active: Runtime | undefined; -const opfsAvailable = globalThis.crossOriginIsolated && typeof navigator.storage?.getDirectory === 'function'; -persist.checked = opfsAvailable && localStorage.getItem('teaql-browser-order-storage') === 'opfs'; -persist.disabled = !opfsAvailable; -if (!opfsAvailable) document.querySelector('#opfs-note')!.textContent = '(not available on this host; memory remains fully browser-local)'; - -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 { - output.textContent = ''; - trace.textContent = ''; - sql.textContent = '[]'; - evidenceRows.replaceChildren(); - runtime.evidence.enableAll(); runtime.diagnostics.length = 0; - type Order = NonNullable[0]>; - type Executable = {executeForPage(context: UserContext, offset: number, size: number): Promise>}; - const request = QueryParser.parse(search.value, Q) as Executable & {dynamicSearchWarnings?: readonly unknown[]}; - if (typeof request?.executeForPage !== 'function') throw new Error('The query must contain a generated executable Q request'); - runtime.client.setRuntimeTelemetrySink(runtime.evidence).setQueryLoggingEnabled(logging.checked) - .setDiagnosticSQLLogSink({write: entry => runtime.diagnostics.push(entry)}); - const page = await request.executeForPage(runtime.context, 1, 1); - const responseBase = webResponse(page.data); - const response = { - resultCode: responseBase.resultCode, status: responseBase.status, version: responseBase.version, - recordCount: page.totalCount, - 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 = preset; example.value = 'filtered'; run.click(); -}); -example.addEventListener('change', () => { - search.value = example.value === 'all' ? preset.replace(filteredSearch, JSON.stringify('{}')) : preset; - run.click(); -}); -search.addEventListener('keydown', event => { - if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') 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/browser-sqlite/src/sqlite.worker.ts b/source/browser-sqlite/src/sqlite.worker.ts deleted file mode 100644 index 02811edbc65c86fdd90ce1b6df7a34616e08bd35..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/src/sqlite.worker.ts +++ /dev/null @@ -1,4 +0,0 @@ -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/browser-sqlite/src/style.css b/source/browser-sqlite/src/style.css deleted file mode 100644 index ee331be0dea768988ca49c731538def02633e527..0000000000000000000000000000000000000000 --- a/source/browser-sqlite/src/style.css +++ /dev/null @@ -1,14 +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/source/runtime/LICENSE b/source/runtime/LICENSE deleted file mode 100644 index 57bc88a15a0ee8266c259b2667e64608d3f7e292..0000000000000000000000000000000000000000 --- a/source/runtime/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - 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/runtime/package-lock.json b/source/runtime/package-lock.json deleted file mode 100644 index cf3bae727e9ca772e5575db6ed81b07b6b50a888..0000000000000000000000000000000000000000 --- a/source/runtime/package-lock.json +++ /dev/null @@ -1,12385 +0,0 @@ -{ - "name": "@teaql/teaql", - "version": "0.3.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "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/@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/runtime/package.json b/source/runtime/package.json deleted file mode 100644 index b9ce9a9f0dc398cee793e51363323e4c06680f5a..0000000000000000000000000000000000000000 --- a/source/runtime/package.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "name": "@teaql/teaql", - "version": "0.3.0", - "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/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" - ] - } - }, - "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/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/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 - }, - "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/runtime/scripts/build-esm.mjs b/source/runtime/scripts/build-esm.mjs deleted file mode 100644 index ae7f0b67f0830807680b0c0a79944d8659888477..0000000000000000000000000000000000000000 --- a/source/runtime/scripts/build-esm.mjs +++ /dev/null @@ -1,28 +0,0 @@ -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', - }, - 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/runtime/scripts/fixtures/checker-overlap-command.sh b/source/runtime/scripts/fixtures/checker-overlap-command.sh deleted file mode 100644 index e9f4915fe1e62e13353406b57a81a086a22a58fd..0000000000000000000000000000000000000000 --- a/source/runtime/scripts/fixtures/checker-overlap-command.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/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/runtime/scripts/generate-query-parser.mjs b/source/runtime/scripts/generate-query-parser.mjs deleted file mode 100644 index 66e0676bc045ffb95d9f618e07d0ab38e3f353a8..0000000000000000000000000000000000000000 --- a/source/runtime/scripts/generate-query-parser.mjs +++ /dev/null @@ -1,9 +0,0 @@ -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/runtime/scripts/run-checker-overlap.sh b/source/runtime/scripts/run-checker-overlap.sh deleted file mode 100644 index 81fca8768aaabe4c0c6563088dad01fef02b9043..0000000000000000000000000000000000000000 --- a/source/runtime/scripts/run-checker-overlap.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/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/runtime/scripts/test-checker-overlap-guard.sh b/source/runtime/scripts/test-checker-overlap-guard.sh deleted file mode 100644 index 935ae36a21d2881ab97ee3aeef46ee1fb49d1a73..0000000000000000000000000000000000000000 --- a/source/runtime/scripts/test-checker-overlap-guard.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/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/runtime/scripts/verify-checker-overlap.sh b/source/runtime/scripts/verify-checker-overlap.sh deleted file mode 100644 index f6f449f9a6fd530a9a9c2f1bc6a534c26e7ccc96..0000000000000000000000000000000000000000 --- a/source/runtime/scripts/verify-checker-overlap.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/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/runtime/scripts/verify-current-aggregate.sh b/source/runtime/scripts/verify-current-aggregate.sh deleted file mode 100644 index 4470cf46e4665d3c53cbc365031ecad6dad539c8..0000000000000000000000000000000000000000 --- a/source/runtime/scripts/verify-current-aggregate.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/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/runtime/scripts/verify-examples.sh b/source/runtime/scripts/verify-examples.sh deleted file mode 100644 index f4d2df0673dc2464f962d517424fa7495c940380..0000000000000000000000000000000000000000 --- a/source/runtime/scripts/verify-examples.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/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 - -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_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/runtime/src/core/ast.ts b/source/runtime/src/core/ast.ts deleted file mode 100644 index 5a241f3f891c5e5eebc4f007032404900f376bdd..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/ast.ts +++ /dev/null @@ -1,326 +0,0 @@ -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/runtime/src/core/checker.ts b/source/runtime/src/core/checker.ts deleted file mode 100644 index 7240d416d01d747f0ad3b4ebac59058cc4d3eaaf..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/checker.ts +++ /dev/null @@ -1,13 +0,0 @@ -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/runtime/src/core/context.ts b/source/runtime/src/core/context.ts deleted file mode 100644 index 7b7dc509c55e4bb826f1a6704ea1f93cbf7165ed..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/context.ts +++ /dev/null @@ -1,287 +0,0 @@ -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 { - 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/runtime/src/core/dynamic-search.ts b/source/runtime/src/core/dynamic-search.ts deleted file mode 100644 index ece2d671658f1b77e62441ac998c1825035d2934..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/dynamic-search.ts +++ /dev/null @@ -1,183 +0,0 @@ -/** 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/runtime/src/core/entity-root.ts b/source/runtime/src/core/entity-root.ts deleted file mode 100644 index f9119ad50830b583e82567bf2be901e3d4ae464c..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/entity-root.ts +++ /dev/null @@ -1,117 +0,0 @@ -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/runtime/src/core/i18n.ts b/source/runtime/src/core/i18n.ts deleted file mode 100644 index 24d5e6445a0dc147b628a4c6e89f08ce9c65b1d8..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/i18n.ts +++ /dev/null @@ -1,19 +0,0 @@ -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/runtime/src/core/local-cache.ts b/source/runtime/src/core/local-cache.ts deleted file mode 100644 index f21a309351b39ac08739b81e97cec243d7607171..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/local-cache.ts +++ /dev/null @@ -1,36 +0,0 @@ -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/runtime/src/core/log-privacy.ts b/source/runtime/src/core/log-privacy.ts deleted file mode 100644 index ba528fbda0b0f4dcead01d610ada353ca2dac30c..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/log-privacy.ts +++ /dev/null @@ -1,233 +0,0 @@ -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; -} - -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'], - // 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/runtime/src/core/mutation-policy.ts b/source/runtime/src/core/mutation-policy.ts deleted file mode 100644 index d7eb41e0ae9e23609a9a9bb24e74ea72e7c0513b..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/mutation-policy.ts +++ /dev/null @@ -1,467 +0,0 @@ -/** 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/runtime/src/core/object-location.ts b/source/runtime/src/core/object-location.ts deleted file mode 100644 index 1212deb49099f71f07fd243568870022e82e30f3..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/object-location.ts +++ /dev/null @@ -1,66 +0,0 @@ -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/runtime/src/core/query-snapshot.ts b/source/runtime/src/core/query-snapshot.ts deleted file mode 100644 index 5a123282d5360b15b534b14bcf5d57be522ab589..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/query-snapshot.ts +++ /dev/null @@ -1,36 +0,0 @@ -// 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/runtime/src/core/request-intent.ts b/source/runtime/src/core/request-intent.ts deleted file mode 100644 index c32090e7d213cbe319118d6f5a9556600f886eb0..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/request-intent.ts +++ /dev/null @@ -1,331 +0,0 @@ -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; - this.#intent = intent === undefined - ? 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 previous = queryExecutionOwner(query); - const owner = previous instanceof QueryRequest - && previous.intent.comment === this.#intent.comment - && previous.purpose === this.#intent.purpose ? previous : 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; - // Internal derivations cannot pick a nested builder's different intent. - for (const [field, value] of [ - ['commentText', this.intent.comment], ['purposeText', this.purpose], - ['_comment', this.intent.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 { - const parent = this.deriveOperation(this.query, operation ?? { kind: 'relation-select', relation }); - return parent.deriveChild(query, relation); - } - - /** 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): 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: 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/runtime/src/core/runtime-module.ts b/source/runtime/src/core/runtime-module.ts deleted file mode 100644 index fdd507c94af00e8e6381a39b192a878ef69e003e..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/runtime-module.ts +++ /dev/null @@ -1,72 +0,0 @@ -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/runtime/src/core/schema-capability.ts b/source/runtime/src/core/schema-capability.ts deleted file mode 100644 index 830b7e00de26d60dc0c1b874b296cc05045f243f..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/schema-capability.ts +++ /dev/null @@ -1,8 +0,0 @@ -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/runtime/src/core/smart-list.ts b/source/runtime/src/core/smart-list.ts deleted file mode 100644 index 5784ddba3a3fd518cca2762a37c362853e83cd10..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/smart-list.ts +++ /dev/null @@ -1,63 +0,0 @@ -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/runtime/src/core/telemetry.ts b/source/runtime/src/core/telemetry.ts deleted file mode 100644 index 104d4a1eb39542a97d9d28d856e0b6e4ea972cbe..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/telemetry.ts +++ /dev/null @@ -1,138 +0,0 @@ -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 RuntimeTelemetryScope { - success(completion?: RuntimeOperationCompletion): void; - failure(error: unknown): void; - run?(work: () => Promise): Promise; -} - -/** Provider-neutral TeaQL lifecycle contract. Implementations must be fail open. */ -export interface RuntimeTelemetry { - start(operation: RuntimeOperation): RuntimeTelemetryScope; - inject?(carrier: Record): void; - flush?(): void | Promise; - shutdown?(): void | Promise; -} - -/** 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 { - 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/runtime/src/core/tools.ts b/source/runtime/src/core/tools.ts deleted file mode 100644 index e971761a04e95a00ec262563dcc35a2da9374496..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/tools.ts +++ /dev/null @@ -1,123 +0,0 @@ -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/runtime/src/core/trace-chain.ts b/source/runtime/src/core/trace-chain.ts deleted file mode 100644 index 665e5c4d4894649d6495895898306dc78f341df2..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/trace-chain.ts +++ /dev/null @@ -1,86 +0,0 @@ -/** 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/runtime/src/core/value.ts b/source/runtime/src/core/value.ts deleted file mode 100644 index 429ee6c89a63226d38f38face7681a574127e74a..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/value.ts +++ /dev/null @@ -1,47 +0,0 @@ -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/runtime/src/core/wire-fields.ts b/source/runtime/src/core/wire-fields.ts deleted file mode 100644 index be877b3d771bf1b0061d834a2812f8f77ac854d7..0000000000000000000000000000000000000000 --- a/source/runtime/src/core/wire-fields.ts +++ /dev/null @@ -1,146 +0,0 @@ -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/runtime/src/index.ts b/source/runtime/src/index.ts deleted file mode 100644 index 2dda868a0ff2c8adfe5bacb951737a515f039678..0000000000000000000000000000000000000000 --- a/source/runtime/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -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 { FacetQueryService } from './core/facet'; -export * from './meta/descriptors'; -export * from './tfp/client'; -export * from './parser/dsl'; diff --git a/source/runtime/src/meta/descriptors.ts b/source/runtime/src/meta/descriptors.ts deleted file mode 100644 index 3fdcc3cce845cc1a97135595d620e97c40521ba4..0000000000000000000000000000000000000000 --- a/source/runtime/src/meta/descriptors.ts +++ /dev/null @@ -1,169 +0,0 @@ -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/runtime/src/parser/dsl.ts b/source/runtime/src/parser/dsl.ts deleted file mode 100644 index 5062340d4cb6cbd6ae7c0c8e919f0bfe5c67c44a..0000000000000000000000000000000000000000 --- a/source/runtime/src/parser/dsl.ts +++ /dev/null @@ -1,52 +0,0 @@ -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/runtime/src/parser/query-parser.generated.ts b/source/runtime/src/parser/query-parser.generated.ts deleted file mode 100644 index ba02cd51ad8cd783e4b833ecef7a9eebfac4648e..0000000000000000000000000000000000000000 --- a/source/runtime/src/parser/query-parser.generated.ts +++ /dev/null @@ -1,1334 +0,0 @@ -// @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/runtime/src/sql/browser-sqlite-protocol.ts b/source/runtime/src/sql/browser-sqlite-protocol.ts deleted file mode 100644 index 1bc43481e3059d54c31c7b1497e2aafaab2e8808..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/browser-sqlite-protocol.ts +++ /dev/null @@ -1,29 +0,0 @@ -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/runtime/src/sql/browser-sqlite-worker.ts b/source/runtime/src/sql/browser-sqlite-worker.ts deleted file mode 100644 index f2155facbe264afdec74a258bb51503bd01915a8..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/browser-sqlite-worker.ts +++ /dev/null @@ -1,140 +0,0 @@ -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/runtime/src/sql/browser-sqlite.ts b/source/runtime/src/sql/browser-sqlite.ts deleted file mode 100644 index 18b1333ebb55f9ec73d5f7e19a7e835da71df6e1..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/browser-sqlite.ts +++ /dev/null @@ -1,296 +0,0 @@ -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/runtime/src/sql/core.ts b/source/runtime/src/sql/core.ts deleted file mode 100644 index ab259839eb4ce55d833d8e9dca94d1c528daa616..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/core.ts +++ /dev/null @@ -1,1909 +0,0 @@ -import { - observeRuntimeOperation, - RuntimeTelemetry, - 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, logValueStrings, scrubLogText, credentialName, inheritSQLLogBindings, retainSQLLogProvenance } from '../core/log-privacy'; -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 { 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 { - 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; - tracePath: readonly SQLTraceFrame[]; - /** Root intent and immutable request-parent comments, distinct from the physical route. */ - traceChain?: readonly TraceNode[]; - /** 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, 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, - 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 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.runtimeTelemetry = telemetry; - return this; - } - - private recordSQL( - operation: SQLExecutionOperation, parameterizedSQL: string, parameters: readonly unknown[], - startedAt: number, resultCount?: number, affectedRows?: number, - intent: SQLLogIntent = {}, - executionOutcome: SQLExecutionOutcome = 'success', - inherited?: SQLLogBindingSource, - ): SQLExecutionMetadata { - const isSelect = operation === 'select'; - const logsEnabled = isSelect ? this.queryLoggingEnabled : this.mutationLoggingEnabled; - const { targetID, inheritedBindings, ...visibleIntent } = intent; - const metadata = Object.freeze({ - operation, ...visibleIntent, executionOutcome, - 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.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 { - const startedAt = Date.now(); - let result: SqlQueryResult; - try { result = await 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); - statements?.push(metadata); - } - finally { throw error; } - } - const metadata = this.recordSQL(operation, sql, values, startedAt, - operation === 'select' ? result.rowCount : undefined, - operation === 'select' ? undefined : result.rowCount, intent, 'success', inherited); - statements?.push(metadata); - return result; - } - - /** Package-internal physical capability used only by UserContext.ensureSchema(). */ - async [contextSchemaCapability](context: UserContext): Promise { - 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 => { - for (const record of records) await this.reconcileBootstrapEntity(this.graphMutationSession!, graph, record); - }); - } - - private async reconcileBootstrapEntity(session: SqlSession, graph: GraphMutationSession, 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) { - await this.executeMutation(graph.request({ entity: record.entity, action: 'Create', - id: record.id, version: 0, payload: { ...record.values } })); - } else { - const row = current.rows[0]; - const changed = entries.filter(entry => !sameBootstrapValue(row[entry.column], entry.value)); - if (changed.length) { - // Checker sees the fully loaded object, not a partial update projection. - await this.executeMutation(graph.request({ entity: record.entity, action: 'Update', - id: record.id, version: Number(row[schema.columns.version?.columnName ?? 'version']), - payload: { ...this.decodeRowForSchema(schema, row), ...record.values } })); - } - } - await this.driver.ensureIdFloor(session, record.entity, record.id); - } - - async executeGraphSave(intent: MutationIntent, work: (graph: GraphMutationSession) => Promise): Promise { - // Root intent is mandatory before lifecycle initialization or provider work. - const graph = new GraphMutationSession(intent); - // 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(); - } - } - - 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 { - // 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(), - }, - }); - 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; - } - } - - 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 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)); - let record: Record; - try { - result = await session.query(sql, values); - 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) { - // 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?._comment ?? query?.commentText, query?._purpose ?? query?.purposeText); - 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 QueryIntent(query._comment ?? query.commentText, query._purpose ?? query.purposeText); - 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 ?? []), ...(current.facets ?? [])]) { - if (child.query) stack.push(child.query); - } - } - return source; - } - - private async executeQueryWithIntent(query: any, inherited?: SQLLogBindingSource, - assembly?: RelationAssembly): Promise { - const scope = startRuntimeOperation(this.runtimeTelemetry, { - family: 'query', - name: `${String(query?.entity || 'unknown')}.list`, - attributes: { 'teaql.entity.type': String(query?.entity || 'unknown') }, - }); - 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), - () => observeRuntimeOperation(this.runtimeTelemetry, { - family: 'provider', - name: `${this.driver.databaseKind}.query`, - attributes: { - 'teaql.provider.kind': this.driver.databaseKind, - 'teaql.provider.operation': '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; - } - } - - 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 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]; - const aliases = countAliases.length ? [...countAliases] : ['__teaql_facet_count']; - query.aggregateItems = aliases.map(alias => ({ function: 'Count', field: 'id', alias })); - (query as any)[this.internalQueryToken] = true; - const rows = await this.executeQuery>(query); - return new Map(rows.flatMap(row => { - const value = row[relationName]; - const count = Number(row[aliases[0]] ?? 0); - return value === null || value === undefined ? [] : [[String(value), count]]; - })); - } - - 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 { - 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 startedAt = Date.now(); - let outcome: SQLExecutionOutcome = 'cancelled'; - let delivered = 0; - let chunk: any[] = []; - const descendantBindings = this.descendantBindings(query, sql, values, inherited); - try { - for await (const rawRow of this.driver.stream(sql, values)) { - chunk.push(this.decodeRow(query.entity, rawRow, 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'; - 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); } catch { /* preserve driver failure */ } - } else { - this.recordSQL('select', sql, values, startedAt, delivered, undefined, - this.queryLogIntent(query), outcome, inherited); - } - } - } - - 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 QueryIntent(query._comment ?? query.commentText, query._purpose ?? query.purposeText); - 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 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, - _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); - } - 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 QueryIntent(query._comment ?? query.commentText, query._purpose ?? query.purposeText); - 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 { - await this.driver.close(); - } -} - -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/runtime/src/sql/expo-sqlite.ts b/source/runtime/src/sql/expo-sqlite.ts deleted file mode 100644 index 62c852ba85b91c58714e8d2893d73ee4e0bdca2f..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/expo-sqlite.ts +++ /dev/null @@ -1,229 +0,0 @@ -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/runtime/src/sql/index.ts b/source/runtime/src/sql/index.ts deleted file mode 100644 index c5f5b2c005bf004cb73a4f452f5884bb2334fb6a..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './core'; -export * from './postgres'; -export * from './mysql'; -export * from './sqlite'; -export * from './expo-sqlite'; diff --git a/source/runtime/src/sql/log-rendering.ts b/source/runtime/src/sql/log-rendering.ts deleted file mode 100644 index 2f796cb3a38a453a5bb4e4287932bbdd485eb9da..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/log-rendering.ts +++ /dev/null @@ -1,142 +0,0 @@ -/** 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/runtime/src/sql/mysql.ts b/source/runtime/src/sql/mysql.ts deleted file mode 100644 index 9dd3bce67939277595a84504806618d7e45253d4..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/mysql.ts +++ /dev/null @@ -1,203 +0,0 @@ -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); - } -} diff --git a/source/runtime/src/sql/postgres.ts b/source/runtime/src/sql/postgres.ts deleted file mode 100644 index 256bbfabedcffb97bb4b531ff6be7e3909ad7db4..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/postgres.ts +++ /dev/null @@ -1,190 +0,0 @@ -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); - } -} diff --git a/source/runtime/src/sql/sqlite.ts b/source/runtime/src/sql/sqlite.ts deleted file mode 100644 index 8d593b941ab4c009f29594b9b3926ff009a4246b..0000000000000000000000000000000000000000 --- a/source/runtime/src/sql/sqlite.ts +++ /dev/null @@ -1,212 +0,0 @@ -import Database from 'better-sqlite3'; -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); - } -} diff --git a/source/runtime/src/telemetry/opentelemetry.ts b/source/runtime/src/telemetry/opentelemetry.ts deleted file mode 100644 index 9f14842452a4b5106d9ec634ba2fbe2a698b3945..0000000000000000000000000000000000000000 --- a/source/runtime/src/telemetry/opentelemetry.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { - Attributes, - context, - Meter, - propagation, - Span, - SpanStatusCode, - Tracer, - trace, -} from '@opentelemetry/api'; -import type { Logger } from '@opentelemetry/api-logs'; -import { - RuntimeAttributeValue, - RuntimeOperation, - RuntimeOperationCompletion, - RuntimeTelemetry, - RuntimeTelemetryScope, - runtimeErrorCategory, -} from '../core/telemetry'; - -export interface OpenTelemetryRuntimeLifecycle { - flush?: () => void | Promise; - shutdown?: () => void | Promise; -} - -/** 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, - ) { - 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, - }); - const activeContext = trace.setSpan(context.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({ - 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) => - context.with(activeContext, () => finishInContext(outcome, completion, errorCategory)); - - return { - run: work => context.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); - }, - }; - } - - inject(carrier: Record): void { - propagation.inject(context.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/runtime/src/tfp/client.ts b/source/runtime/src/tfp/client.ts deleted file mode 100644 index 7913fb52cda471af94c5f43823a1fc1cda792628..0000000000000000000000000000000000000000 --- a/source/runtime/src/tfp/client.ts +++ /dev/null @@ -1,187 +0,0 @@ -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/runtime/tsconfig.json b/source/runtime/tsconfig.json deleted file mode 100644 index 0fe8d7e48c8781e1746c7192333cfa2eb70bc0cc..0000000000000000000000000000000000000000 --- a/source/runtime/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "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/**/*"] -}