@shellicar/cosmos-query-builder 1.0.0-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Stephen Hellicar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # @shellicar/cosmos-query-builder
2
+
3
+ > A type-safe query builder for [Azure Cosmos DB for NoSQL](https://docs.microsoft.com/en-us/azure/cosmos-db/nosql/)
4
+
5
+ > **Note**: This library is for Azure Cosmos DB for NoSQL (formerly SQL API). For MongoDB API, see [Azure Cosmos DB for MongoDB](https://docs.microsoft.com/en-us/azure/cosmos-db/mongodb/).
6
+
7
+ ## Installation & Quick Start
8
+
9
+ ```sh
10
+ npm i --save @shellicar/cosmos-query-builder
11
+ ```
12
+
13
+ ```sh
14
+ pnpm add @shellicar/cosmos-query-builder
15
+ ```
16
+
17
+ ## Quick Example
18
+
19
+ ```ts
20
+ import { createCosmosQueryBuilder, SortDirection } from '@shellicar/cosmos-query-builder';
21
+
22
+ const builder = createCosmosQueryBuilder<Person>();
23
+
24
+ builder.where('type', 'eq', 'Person');
25
+ builder.where('age', 'gt', 18);
26
+ builder.orderBy('created', SortDirection.Desc);
27
+ builder.limit(50);
28
+
29
+ const results = await builder.getAll(container);
30
+ ```
31
+
32
+ For a complete working example, see [examples/simple/src/main.ts](../../examples/simple/src/main.ts).
33
+
34
+ ## Documentation
35
+
36
+ For full documentation, visit the [GitHub repository](https://github.com/shellicar/cosmos-query-builder).
@@ -0,0 +1 @@
1
+ "use strict";var e=Object.defineProperty,t=(t,s)=>e(t,"name",{value:s,configurable:!0}),s=class{static{t(this,"ILogger")}},r=class{static{t(this,"ICosmosQueryBuilder")}},i={eq:"=",ne:"!=",ge:">=",gt:">",le:"<=",lt:"<"},n=class extends s{static{t(this,"DefaultLogger")}debug(e,...t){}info(e,...t){}error(e,...t){}warn(e,...t){}verbose(e,...t){}},o=class extends r{static{t(this,"CosmosQueryBuilder")}_orderBy;_select="*";_groupBy=null;_join="";_from="c";_queries=[];_parameters=[];_limit;_logger;constructor(e){super(),this._logger=e?.logger??new n}get queries(){return this._queries}set queries(e){this._queries=e}get parameters(){return this._parameters}set parameters(e){this._parameters=e}handleStringFilter(e,t){return this.handleFilterObject(e,t)}handleUuidFilter(e,t){return this.handleFilterObject(e,t)}handleInstantFilter(e,t){return this.handleFilterObject(e,t)}handleFilterObject(e,t){const{__typeInfo:s,...r}=t;for(const[t,s]of Object.entries(r).filter(e=>void 0!==e[1])){const r=e,n=`@p${this._parameters.length}`,o=i[t],u=`(${r} ?? null)`;if(null!=o)this._queries.push(`${u} ${o} ${n}`);else if("ieq"===t)this._queries.push(`StringEquals(${u}, ${n}, true)`);else if("ine"===t)this._queries.push(`Not(StringEquals(${u}, ${n}, true))`);else if("like"===t)this._queries.push(`Contains(${u}, ${n}, true)`);else{if("in"!==t)throw new Error(`Unknown operator ${t}`);this._queries.push(`ARRAY_CONTAINS(${n}, ${u})`)}this._parameters.push({name:n,value:s})}}_buildQuery(e,t="c"){if(null!=e){const{__typeInfo:s,...r}=e,i=Object.keys(r);for(const s of i){const r=e[s],i=r.__typeInfo??null,n=`${t}.${s}`;if("object"!=typeof r||null==r)throw new Error(`Unhandled type ${i}`);"StringFilter"===i?this.handleStringFilter(n,r):"InstantFilter"===i?this.handleInstantFilter(n,r):"UUIDFilter"===i?this.handleUuidFilter(n,r):this._buildQuery(r,n)}}}buildQuery(e,t="c"){this._buildQuery(e,t)}orderBy(e,t){this._orderBy=null==e||null==t?void 0:`\nORDER BY\n c.${e} ${t}`}groupBy(e){this._groupBy=`\nGROUP BY\n ${e}`}select(e){this._select=e}parameter(e,t){this._parameters.push({name:e,value:t})}limit(e){this._limit=e}join(e,t){this._join=`${e} IN c.${t}`}whereFuzzy(e,t){const s=`@p${this._parameters.length}`,r=[];for(const e of t){const t=`Contains(c.${e}, ${s}, true)`;r.push(t)}const i=`(${r.join(" OR ")})`;this._queries.push(i),this._parameters.push({name:s,value:e})}whereRaw(e,t,s){const r=`@p${this._parameters.length}`,n=i[t];this._queries.push(`${e} ${n} ${r}`),this._parameters.push({name:r,value:s})}whereOr(e){const t=[];for(const s of e){const{field:e,operator:r,value:n}=s,o=`@p${this._parameters.length}`;if("isNull"===r)t.push(`(c.${e} ?? null) = null`);else if("contains"===r)t.push(`ARRAY_CONTAINS(c.${e}, ${o})`);else if("in"===r)t.push(`ARRAY_CONTAINS(${o}, c.${e})`);else{const s=i[r];null!=s&&void 0!==n&&(t.push(`c.${e} ${s} ${o}`),this._parameters.push({name:o,value:n}))}}t.length>0&&this._queries.push(`(${t.join(" OR ")})`)}where(e,t,s){const r=`@p${this._parameters.length}`;if("isNull"===t){const t=`(c.${e} ?? null) = null`;this._queries.push(t)}else if("contains"===t){if(void 0!==s){const t=`ARRAY_CONTAINS(c.${e}, ${r})`;this._queries.push(t),this._parameters.push({name:r,value:s})}}else if("in"===t){if(void 0!==s){const t=`ARRAY_CONTAINS(${r}, c.${e})`;this._queries.push(t),this._parameters.push({name:r,value:s})}}else{const n=i[t];null!=n&&void 0!==s&&(this._queries.push(`c.${e} ${n} ${r}`),this._parameters.push({name:r,value:s}))}}filter(e){const t=`@p${this._parameters.length}`;this._queries.push(e.clause.replace("@",t)),null!=e.parameter&&this._parameters.push({name:t,value:e.parameter})}query(){const e=[];if(e.push(`SELECT\n ${this._select}`),e.push(`FROM\n ${this._from}`),""!==this._join&&e.push(`JOIN\n ${this._join}`),this._queries.length>0){e.push("WHERE");const t=this._queries.join("\n AND ");e.push(t)}null!=this._orderBy&&e.push(this._orderBy),null!=this._groupBy&&e.push(this._groupBy),null!=this._limit&&(e.push("OFFSET 0"),e.push(`LIMIT ${this._limit}`));const t={query:e.join("\n"),parameters:this.parameters};return this._logger.verbose("Cosmos Query",t),t}async getOne(e){const t=this.query(),s=e.items.query(t),r=await s.fetchNext();return this._logger.verbose("Cosmos Result",{result:r}),r.resources?.[0]??null}async getAll(e,t,s){const r=this.query(),i=e.items.query(r,{continuationToken:s??void 0,maxItemCount:t??void 0});let n;try{n=await i.fetchAll()}catch(e){throw this._logger.error("Cosmos Query Error",e),e}this._logger.verbose("Cosmos Result",{result:n}),this.select("VALUE COUNT(1)"),this.orderBy();const o=this.query(),u=e.items.query(o);let l;try{l=await u.fetchAll()}catch(e){throw this._logger.error("Cosmos Count Query Error",e),e}const h=l.resources?.[0]??0;return{continuationToken:n.continuationToken,count:n.resources?.length??0,items:n.resources??[],hasMoreResults:n.hasMoreResults,totalCount:h}}patch(...e){return{operations:e.map(e=>{if("remove"===e.op)return{op:e.op,path:e.path};if(void 0!==e.value)return{op:e.op,path:e.path,value:e.value};throw new Error(`Value is required for operation: ${e.op}`)})}}};function u(e){return new o(e)}t(u,"createCosmosQueryBuilder");var l=(e=>(e.Asc="ASC",e.Desc="DESC",e))(l||{});exports.ILogger=s,exports.SortDirection=l,exports.createCosmosQueryBuilder=u;//# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/public/interfaces.ts","../../src/private/consts.ts","../../src/private/DefaultLogger.ts","../../src/private/CosmosQueryBuilder.ts","../../src/public/createCosmosQueryBuilder.ts","../../src/public/enums.ts"],"names":["SortDirection"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { JSONValue, PatchRequestBody, SqlQuerySpec } from '@azure/cosmos';\nimport type { ExtractPatchPathExpressions, ExtractPathExpressions, PatchPathValue, PathValue } from '../private/types';\nimport type { SortDirection } from './enums';\nimport type { BasicOpCode, Container, ExtendedOpCode, FetchResult, InstantFilter, StringFilter, UUIDFilter } from './types';\n\nexport abstract class ILogger {\n public abstract debug(message?: any, ...optionalParams: any[]): void;\n public abstract info(message?: any, ...optionalParams: any[]): void;\n public abstract error(message?: any, ...optionalParams: any[]): void;\n public abstract warn(message?: any, ...optionalParams: any[]): void;\n public abstract verbose(message?: any, ...optionalParams: any[]): void;\n}\n\nexport abstract class ICosmosQueryBuilder<T extends Record<string, any>> {\n /**\n * Sets the maximum number of items to return\n * @param limit Maximum number of items\n * @example\n * ```typescript\n * builder.limit(100);\n * ```\n */\n public abstract limit(limit: number): void;\n\n /**\n * Adds a JOIN clause to the query\n * @param value JOIN alias\n * @param statement Field path to join on\n * @example\n * ```typescript\n * builder.join('b', 'bones');\n * ```\n */\n public abstract join<P extends ExtractPathExpressions<T>>(value: string, statement: P): void;\n\n /**\n * Sets the SELECT clause for the query\n * @param value SELECT clause string\n * @example\n * ```typescript\n * builder.select('COUNT(1) as count, UPPER(c.name.givenName) as name');\n * ```\n */\n public abstract select(value: string): void;\n\n /**\n * Sets the GROUP BY clause for the query\n * @param value GROUP BY expression\n * @example\n * ```typescript\n * builder.groupBy('UPPER(c.sex)');\n * ```\n */\n public abstract groupBy(value: string): void;\n\n /**\n * Performs fuzzy search across multiple fields\n * @param value Search term\n * @param fields Array of field paths to search in\n * @example\n * ```typescript\n * builder.whereFuzzy('steve', ['name.givenName', 'name.familyName', 'email']);\n * ```\n */\n public abstract whereFuzzy<P extends ExtractPathExpressions<T>>(value: string, fields: [P, ...P[]]): void;\n\n /**\n * Adds a raw WHERE clause with field, operator, and value\n * @param field Field name as string\n * @param operator SQL operator (excluding isNull, contains, in)\n * @param value Value to compare against\n * @example\n * ```typescript\n * builder.whereRaw('p.id', 'eq', 'some-id');\n * ```\n */\n public abstract whereRaw(field: string, operator: Exclude<ExtendedOpCode, 'isNull' | 'contains' | 'in'>, value: JSONValue): void;\n\n /**\n * Adds an OR clause to match items satisfying any of the given conditions\n * @param conditions Array of field/operator/value conditions\n * @example\n * ```typescript\n * builder.whereOr([\n * { field: 'name.givenName', operator: 'eq', value: 'John' },\n * { field: 'name.familyName', operator: 'eq', value: 'Smith' }\n * ]);\n * ```\n */\n public abstract whereOr(conditions: Array<{ field: string; operator: ExtendedOpCode; value: JSONValue }>): void;\n\n /**\n * Creates a JSON patch document for Cosmos DB patch operations\n * @param operations Array of patch operations (set, add, replace, remove)\n * @returns Patch request body for Cosmos DB\n * @example\n * ```typescript\n * const operations = builder.patch({\n * op: 'replace',\n * path: '/name/givenName',\n * value: 'Smith',\n * });\n * const item = container.item('id', 'partitionKey');\n * await item.patch<Person>(operations);\n * ```\n */\n public abstract patch<P extends ExtractPatchPathExpressions<T>>(...operations: Array<{ path: P; op: 'set' | 'add' | 'replace'; value: PatchPathValue<T, P> } | { path: P; op: 'remove' }>): PatchRequestBody;\n\n /**\n * Builds query conditions from a structured object with type filters\n * Supports {@link StringFilter}, {@link UUIDFilter}, and {@link InstantFilter} types\n * @param query Query object with nested field filters containing __typeInfo\n * @param prefix Path prefix for nested queries (defaults to 'c')\n * @example\n * ```typescript\n * type PersonFilter = {\n * name?: {\n * givenName?: StringFilter;\n * };\n * };\n * const filter = {\n * name: {\n * givenName: { __typeInfo: 'StringFilter', eq: 'John' }\n * },\n * } satisfies PersonFilter;\n * builder.buildQuery(filter);\n * ```\n */\n public abstract buildQuery(query: Record<string, any> | undefined | null, prefix?: string): void;\n\n /**\n * Adds a WHERE clause with type-safe field access and operators\n * @param field Type-safe field path\n * @param operator SQL operator\n * @example\n * ```typescript\n * builder.where('name.givenName', 'eq', 'John');\n * builder.where('age', 'gt', 18);\n * builder.where('bones', 'contains', 'arm');\n * builder.where('name.givenName', 'in', ['John', 'Jane']);\n * builder.where('deletedAt', 'isNull');\n * ```\n */\n public abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'isNull'): void;\n public abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'in', value: readonly PathValue<T, P>[]): void;\n public abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'contains', value: PathValue<T, P>[number]): void;\n public abstract where<P extends ExtractPathExpressions<T>, V extends PathValue<T, P>>(field: P, operator: BasicOpCode, value: V): void;\n\n /**\n * Clears any existing ordering\n */\n public abstract orderBy(): void;\n\n /**\n * Sets ordering by field and direction\n * @param field Field path to order by\n * @param direction Sort direction (ASC/DESC)\n */\n public abstract orderBy<P extends ExtractPathExpressions<T>>(field: P, direction: SortDirection): void;\n\n /**\n * Builds and returns the final SQL query specification\n * @returns SQL query specification with parameters\n */\n public abstract query(): SqlQuerySpec;\n\n /**\n * Executes the query and returns the first result\n * @param container Cosmos DB container to query\n * @returns First matching item or null\n */\n public abstract getOne<TSelect = T>(container: Container): Promise<TSelect | null>;\n\n /**\n * Executes the query and returns paginated results with total count\n * @param container Cosmos DB container to query\n * @param limit Maximum number of items per page\n * @param cursor Continuation token for pagination\n * @returns Paginated results with metadata\n */\n public abstract getAll<TSelect = T>(container: Container, limit?: number | null | undefined, cursor?: string | null | undefined): Promise<FetchResult<TSelect>>;\n}\n","export const operators: Record<string, string | undefined> = {\n eq: '=',\n ne: '!=',\n ge: '>=',\n gt: '>',\n le: '<=',\n lt: '<',\n} as const;\n","import { ILogger } from '../public/interfaces';\n\nexport class DefaultLogger extends ILogger {\n public debug(_message?: any, ..._optionalParams: any[]): void {}\n public info(_message?: any, ..._optionalParams: any[]): void {}\n public error(_message?: any, ..._optionalParams: any[]): void {}\n public warn(_message?: any, ..._optionalParams: any[]): void {}\n public verbose(_message?: any, ..._optionalParams: any[]): void {}\n}\n","import type { JSONValue, PatchRequestBody, SqlParameter, SqlQuerySpec } from '@azure/cosmos';\nimport type { SortDirection } from '../public/enums';\nimport { ICosmosQueryBuilder, type ILogger } from '../public/interfaces';\nimport type { BasicOpCode, Container, CosmosQueryBuilderOptions, ExtendedOpCode, FeedResponse, FetchResult, InstantFilter, StringFilter, UUIDFilter } from '../public/types';\nimport { operators } from './consts';\nimport { DefaultLogger } from './DefaultLogger';\nimport type { ExtractPatchPathExpressions, ExtractPathExpressions, PatchPathValue, PathValue, StringFilterData } from './types';\n\nexport class CosmosQueryBuilder<T extends Record<string, any>> extends ICosmosQueryBuilder<T> {\n private _orderBy?: string;\n private _select = '*';\n private _groupBy: string | null = null;\n private _join = '';\n private _from = 'c';\n private _queries: string[] = [];\n private _parameters: SqlParameter[] = [];\n private _limit: number | undefined;\n private _logger: ILogger;\n\n public constructor(options?: CosmosQueryBuilderOptions) {\n super();\n this._logger = options?.logger ?? new DefaultLogger();\n }\n\n public get queries(): string[] {\n return this._queries;\n }\n\n public set queries(value: string[]) {\n this._queries = value;\n }\n\n public get parameters(): SqlParameter[] {\n return this._parameters;\n }\n\n public set parameters(value: SqlParameter[]) {\n this._parameters = value;\n }\n\n private handleStringFilter(prefix: string, value: StringFilter) {\n return this.handleFilterObject(prefix, value);\n }\n\n private handleUuidFilter(prefix: string, value: UUIDFilter) {\n return this.handleFilterObject(prefix, value);\n }\n\n private handleInstantFilter(prefix: string, value: InstantFilter) {\n return this.handleFilterObject(prefix, value);\n }\n\n private handleFilterObject(prefix: string, value: StringFilterData & { __typeInfo: string }) {\n const { __typeInfo, ...rest } = value;\n for (const [key, value2] of Object.entries(rest).filter((x) => x[1] !== undefined)) {\n const path = prefix;\n const parameterName = `@p${this._parameters.length}`;\n const operator = operators[key];\n\n // Default to null to allow null comparison when parent object is not defined\n const queryKey = `(${path} ?? null)`;\n if (operator != null) {\n this._queries.push(`${queryKey} ${operator} ${parameterName}`);\n } else {\n if (key === 'ieq') {\n this._queries.push(`StringEquals(${queryKey}, ${parameterName}, true)`);\n } else if (key === 'ine') {\n this._queries.push(`Not(StringEquals(${queryKey}, ${parameterName}, true))`);\n } else if (key === 'like') {\n this._queries.push(`Contains(${queryKey}, ${parameterName}, true)`);\n } else if (key === 'in') {\n this._queries.push(`ARRAY_CONTAINS(${parameterName}, ${queryKey})`);\n } else {\n throw new Error(`Unknown operator ${key}`);\n }\n }\n this._parameters.push({ name: parameterName, value: value2 });\n }\n }\n\n private _buildQuery(query: Record<string, any> | null | undefined, prefix = 'c'): void {\n if (query != null) {\n const { __typeInfo, ...rest } = query;\n const queryKeys = Object.keys(rest);\n\n for (const key of queryKeys) {\n const value = query[key];\n const type: string | null = value.__typeInfo ?? null;\n const subPath = `${prefix}.${key}`;\n\n if (typeof value === 'object' && value != null) {\n if (type === 'StringFilter') {\n this.handleStringFilter(subPath, value);\n } else if (type === 'InstantFilter') {\n this.handleInstantFilter(subPath, value);\n } else if (type === 'UUIDFilter') {\n this.handleUuidFilter(subPath, value);\n } else {\n this._buildQuery(value, subPath);\n }\n } else {\n throw new Error(`Unhandled type ${type}`);\n }\n }\n }\n }\n\n public override buildQuery(query: Record<string, any> | undefined | null, prefix = 'c'): void {\n this._buildQuery(query, prefix);\n }\n\n public override orderBy(): void;\n public override orderBy<P extends ExtractPathExpressions<T>>(field: P, direction: SortDirection): void;\n public override orderBy<P extends ExtractPathExpressions<T>>(field?: P, direction?: SortDirection) {\n if (field == null || direction == null) {\n this._orderBy = undefined;\n } else {\n this._orderBy = `\\nORDER BY\\n c.${field} ${direction}`;\n }\n }\n\n public override groupBy(value: string): void {\n this._groupBy = `\\nGROUP BY\\n ${value}`;\n }\n\n public override select(value: string): void {\n this._select = value;\n }\n\n private parameter(name: string, value: JSONValue): void {\n this._parameters.push({\n name,\n value,\n });\n }\n\n public override limit(limit: number): void {\n this._limit = limit;\n }\n\n public override join<P extends ExtractPathExpressions<T>>(value: string, statement: P): void {\n this._join = `${value} IN c.${statement}`;\n }\n\n public override whereFuzzy<P extends ExtractPathExpressions<T>>(value: string, fields: [P, ...P[]]): void {\n const parameterName = `@p${this._parameters.length}`;\n const lines: string[] = [];\n for (const field of fields) {\n const clause = `Contains(c.${field}, ${parameterName}, true)`;\n lines.push(clause);\n }\n const queryLine = `(${lines.join(' OR ')})`;\n this._queries.push(queryLine);\n this._parameters.push({ name: parameterName, value });\n }\n\n public override whereRaw(field: string, operator: Exclude<ExtendedOpCode, 'isNull' | 'contains' | 'in'>, value: JSONValue): void {\n const parameterName = `@p${this._parameters.length}`;\n const sqlOperator = operators[operator];\n this._queries.push(`${field} ${sqlOperator} ${parameterName}`);\n this._parameters.push({ name: parameterName, value });\n }\n\n public override whereOr(conditions: Array<{ field: string; operator: ExtendedOpCode; value: JSONValue }>): void {\n const orClauses: string[] = [];\n for (const condition of conditions) {\n const { field, operator, value } = condition;\n const parameterName = `@p${this._parameters.length}`;\n\n if (operator === 'isNull') {\n orClauses.push(`(c.${field} ?? null) = null`);\n } else if (operator === 'contains') {\n orClauses.push(`ARRAY_CONTAINS(c.${field}, ${parameterName})`);\n } else if (operator === 'in') {\n orClauses.push(`ARRAY_CONTAINS(${parameterName}, c.${field})`);\n } else {\n const sqlOperator = operators[operator];\n if (sqlOperator != null && value !== undefined) {\n orClauses.push(`c.${field} ${sqlOperator} ${parameterName}`);\n this._parameters.push({ name: parameterName, value });\n }\n }\n }\n\n if (orClauses.length > 0) {\n this._queries.push(`(${orClauses.join(' OR ')})`);\n }\n }\n\n public override where<P extends ExtractPathExpressions<T>>(field: P, operator: 'isNull'): void;\n public override where<P extends ExtractPathExpressions<T>>(field: P, operator: 'in', value: readonly PathValue<T, P>[]): void;\n public override where<P extends ExtractPathExpressions<T>>(field: P, operator: 'contains', value: PathValue<T, P>[number]): void;\n public override where<P extends ExtractPathExpressions<T>, V extends PathValue<T, P>>(field: P, operator: BasicOpCode, value: V): void;\n public override where<P extends ExtractPathExpressions<T>, V extends PathValue<T, P>>(field: P, operator: ExtendedOpCode, value?: V | readonly V[]): void {\n const parameterName = `@p${this._parameters.length}`;\n\n if (operator === 'isNull') {\n const clause = `(c.${field} ?? null) = null`;\n this._queries.push(clause);\n } else if (operator === 'contains') {\n if (value !== undefined) {\n const clause = `ARRAY_CONTAINS(c.${field}, ${parameterName})`;\n this._queries.push(clause);\n this._parameters.push({ name: parameterName, value });\n }\n } else if (operator === 'in') {\n // Handle 'IN' operator\n if (value !== undefined) {\n const clause = `ARRAY_CONTAINS(${parameterName}, c.${field})`;\n this._queries.push(clause);\n this._parameters.push({ name: parameterName, value });\n }\n } else {\n const sqlOperator = operators[operator];\n if (sqlOperator != null && value !== undefined) {\n this._queries.push(`c.${field} ${sqlOperator} ${parameterName}`);\n this._parameters.push({ name: parameterName, value });\n }\n }\n }\n\n public filter(x: { clause: string; parameter?: JSONValue }): void {\n const paramName = `@p${this._parameters.length}`;\n this._queries.push(x.clause.replace('@', paramName));\n if (x.parameter != null) {\n this._parameters.push({\n name: paramName,\n value: x.parameter,\n });\n }\n }\n\n public override query(): SqlQuerySpec {\n const lines: string[] = [];\n lines.push(`SELECT\\n ${this._select}`);\n lines.push(`FROM\\n ${this._from}`);\n if (this._join !== '') {\n lines.push(`JOIN\\n ${this._join}`);\n }\n\n if (this._queries.length > 0) {\n lines.push('WHERE');\n const where = this._queries.join('\\n AND ');\n lines.push(where);\n }\n\n if (this._orderBy != null) {\n lines.push(this._orderBy);\n }\n if (this._groupBy != null) {\n lines.push(this._groupBy);\n }\n if (this._limit != null) {\n lines.push('OFFSET 0');\n lines.push(`LIMIT ${this._limit}`);\n }\n\n const queryText = lines.join('\\n');\n const result = {\n query: queryText,\n parameters: this.parameters,\n };\n this._logger.verbose('Cosmos Query', result);\n return result;\n }\n\n public override async getOne<TSelect = T>(container: Container): Promise<TSelect | null> {\n const itemsQuery = this.query();\n const itemsIterator = container.items.query<TSelect>(itemsQuery);\n const items = await itemsIterator.fetchNext();\n this._logger.verbose('Cosmos Result', { result: items });\n return items.resources?.[0] ?? null;\n }\n\n public override async getAll<TSelect>(container: Container, limit?: number | null | undefined, cursor?: string | null | undefined): Promise<FetchResult<TSelect>> {\n const itemsQuery = this.query();\n const itemsIterator = container.items.query<TSelect>(itemsQuery, {\n continuationToken: cursor ?? undefined,\n maxItemCount: limit ?? undefined,\n });\n let items: FeedResponse<TSelect>;\n try {\n items = await itemsIterator.fetchAll();\n } catch (err) {\n this._logger.error('Cosmos Query Error', err);\n throw err;\n }\n this._logger.verbose('Cosmos Result', { result: items });\n\n this.select('VALUE COUNT(1)');\n this.orderBy();\n\n const countQuery = this.query();\n const countIterator = container.items.query<number>(countQuery);\n\n let count: FeedResponse<number>;\n try {\n count = await countIterator.fetchAll();\n } catch (err) {\n this._logger.error('Cosmos Count Query Error', err);\n throw err;\n }\n\n const totalCount = count.resources?.[0] ?? 0;\n\n const result: FetchResult<TSelect> = {\n continuationToken: items.continuationToken,\n count: items.resources?.length ?? 0,\n items: items.resources ?? [],\n hasMoreResults: items.hasMoreResults,\n totalCount,\n };\n return result;\n }\n\n public override patch<P extends ExtractPatchPathExpressions<T>>(...operations: Array<{ path: P; op: 'set' | 'add' | 'replace'; value: PatchPathValue<T, P> } | { path: P; op: 'remove' }>): PatchRequestBody {\n const patchOperations = operations.map((opDef) => {\n if (opDef.op === 'remove') {\n return { op: opDef.op, path: opDef.path };\n }\n\n if (opDef.value !== undefined) {\n return { op: opDef.op, path: opDef.path, value: opDef.value };\n }\n\n throw new Error(`Value is required for operation: ${opDef.op}`);\n });\n\n return { operations: patchOperations };\n }\n}\n","import { CosmosQueryBuilder } from '../private/CosmosQueryBuilder';\nimport type { ICosmosQueryBuilder } from './interfaces';\nimport type { CosmosQueryBuilderOptions } from './types';\n\nexport function createCosmosQueryBuilder<T extends Record<string, any>>(options?: CosmosQueryBuilderOptions): ICosmosQueryBuilder<T> {\n return new CosmosQueryBuilder<T>(options);\n}\n","export enum SortDirection {\n Asc = 'ASC',\n Desc = 'DESC',\n}\n"]}
@@ -0,0 +1,252 @@
1
+ import { SqlQuerySpec, JSONValue, PatchRequestBody } from '@azure/cosmos';
2
+
3
+ type ArrayElement<T> = T extends (infer U)[] ? U : never;
4
+ type PathBuilder<T, Sep extends string, K extends keyof T = keyof T> = K extends string ? T[K] extends Record<string, any> | null ? T[K] extends ArrayLike<any> ? K | `${K}[${number}]` | `${K}[${number}]${Sep}${PathBuilder<NonNullable<ArrayElement<T[K]>>, Sep>}` : K | `${K}${Sep}${PathBuilder<NonNullable<T[K]>, Sep>}` : K : never;
5
+ type DotPath<T> = PathBuilder<T, '.'>;
6
+ type SlashPathCore<T> = PathBuilder<T, '/'>;
7
+ type ExtractPathExpressions<T> = DotPath<T>;
8
+ type ExtractPatchPathExpressions<T> = `/${SlashPathCore<T>}` | `/${SlashPathCore<T>}/-`;
9
+ type PathValueResolver<T, P extends string, Sep extends string> = P extends `${infer K}${Sep}${infer Rest}` ? K extends keyof T ? PathValueResolver<NonNullable<T[K]>, Rest, Sep> : never : P extends `${infer K}[${infer _Index}]${infer Rest}` ? K extends keyof T ? T[K] extends (infer R)[] | null ? Rest extends '' ? NonNullable<R> : Rest extends `${Sep}${infer More}` ? PathValueResolver<NonNullable<R>, More, Sep> : never : never : never : P extends keyof T ? T[P] : T extends Record<string, any> ? T[keyof T] : never;
10
+ type PathValue<T, P extends string> = PathValueResolver<T, P, '.'>;
11
+ type PatchPathValue<T, P extends string> = P extends `/${infer Rest}` ? PathValueResolver<T, Rest, '/'> : never;
12
+
13
+ declare enum SortDirection {
14
+ Asc = "ASC",
15
+ Desc = "DESC"
16
+ }
17
+
18
+ type UUIDFilter = {
19
+ __typeInfo: 'UUIDFilter';
20
+ eq?: string;
21
+ ne?: string;
22
+ };
23
+ type InstantFilter = {
24
+ __typeInfo: 'InstantFilter';
25
+ eq?: string;
26
+ ieq?: string;
27
+ in?: string;
28
+ ine?: string;
29
+ like?: string;
30
+ ne?: string;
31
+ };
32
+ type StringFilter = {
33
+ __typeInfo: 'StringFilter';
34
+ eq?: string;
35
+ ieq?: string;
36
+ in?: string;
37
+ ine?: string;
38
+ like?: string;
39
+ ne?: string;
40
+ };
41
+ type ExtendedOpCode = BasicOpCode | 'contains' | 'in' | 'isNull';
42
+ type BasicOpCode = 'eq' | 'gt' | 'lt' | 'ge' | 'le' | 'ne';
43
+ type FetchResult<T> = {
44
+ items: T[];
45
+ continuationToken: string;
46
+ hasMoreResults: boolean;
47
+ totalCount: number;
48
+ count: number;
49
+ };
50
+ type CosmosQueryBuilderOptions = {
51
+ /**
52
+ * Custom implementation for logger.
53
+ * @defaultValue undefined (no logging)
54
+ */
55
+ logger?: ILogger;
56
+ };
57
+ type FeedOptions = {
58
+ continuationToken?: string | null;
59
+ maxItemCount?: number | null;
60
+ };
61
+ interface FeedResponse<TResource> {
62
+ readonly resources?: TResource[];
63
+ readonly hasMoreResults: boolean;
64
+ get continuationToken(): string;
65
+ }
66
+ interface QueryIterator<TResource> {
67
+ fetchNext(): Promise<FeedResponse<TResource>>;
68
+ fetchAll(): Promise<FeedResponse<TResource>>;
69
+ }
70
+ interface Container {
71
+ items: {
72
+ query<TResource>(querySpec: SqlQuerySpec, options?: FeedOptions): QueryIterator<TResource>;
73
+ };
74
+ }
75
+
76
+ declare abstract class ILogger {
77
+ abstract debug(message?: any, ...optionalParams: any[]): void;
78
+ abstract info(message?: any, ...optionalParams: any[]): void;
79
+ abstract error(message?: any, ...optionalParams: any[]): void;
80
+ abstract warn(message?: any, ...optionalParams: any[]): void;
81
+ abstract verbose(message?: any, ...optionalParams: any[]): void;
82
+ }
83
+ declare abstract class ICosmosQueryBuilder<T extends Record<string, any>> {
84
+ /**
85
+ * Sets the maximum number of items to return
86
+ * @param limit Maximum number of items
87
+ * @example
88
+ * ```typescript
89
+ * builder.limit(100);
90
+ * ```
91
+ */
92
+ abstract limit(limit: number): void;
93
+ /**
94
+ * Adds a JOIN clause to the query
95
+ * @param value JOIN alias
96
+ * @param statement Field path to join on
97
+ * @example
98
+ * ```typescript
99
+ * builder.join('b', 'bones');
100
+ * ```
101
+ */
102
+ abstract join<P extends ExtractPathExpressions<T>>(value: string, statement: P): void;
103
+ /**
104
+ * Sets the SELECT clause for the query
105
+ * @param value SELECT clause string
106
+ * @example
107
+ * ```typescript
108
+ * builder.select('COUNT(1) as count, UPPER(c.name.givenName) as name');
109
+ * ```
110
+ */
111
+ abstract select(value: string): void;
112
+ /**
113
+ * Sets the GROUP BY clause for the query
114
+ * @param value GROUP BY expression
115
+ * @example
116
+ * ```typescript
117
+ * builder.groupBy('UPPER(c.sex)');
118
+ * ```
119
+ */
120
+ abstract groupBy(value: string): void;
121
+ /**
122
+ * Performs fuzzy search across multiple fields
123
+ * @param value Search term
124
+ * @param fields Array of field paths to search in
125
+ * @example
126
+ * ```typescript
127
+ * builder.whereFuzzy('steve', ['name.givenName', 'name.familyName', 'email']);
128
+ * ```
129
+ */
130
+ abstract whereFuzzy<P extends ExtractPathExpressions<T>>(value: string, fields: [P, ...P[]]): void;
131
+ /**
132
+ * Adds a raw WHERE clause with field, operator, and value
133
+ * @param field Field name as string
134
+ * @param operator SQL operator (excluding isNull, contains, in)
135
+ * @param value Value to compare against
136
+ * @example
137
+ * ```typescript
138
+ * builder.whereRaw('p.id', 'eq', 'some-id');
139
+ * ```
140
+ */
141
+ abstract whereRaw(field: string, operator: Exclude<ExtendedOpCode, 'isNull' | 'contains' | 'in'>, value: JSONValue): void;
142
+ /**
143
+ * Adds an OR clause to match items satisfying any of the given conditions
144
+ * @param conditions Array of field/operator/value conditions
145
+ * @example
146
+ * ```typescript
147
+ * builder.whereOr([
148
+ * { field: 'name.givenName', operator: 'eq', value: 'John' },
149
+ * { field: 'name.familyName', operator: 'eq', value: 'Smith' }
150
+ * ]);
151
+ * ```
152
+ */
153
+ abstract whereOr(conditions: Array<{
154
+ field: string;
155
+ operator: ExtendedOpCode;
156
+ value: JSONValue;
157
+ }>): void;
158
+ /**
159
+ * Creates a JSON patch document for Cosmos DB patch operations
160
+ * @param operations Array of patch operations (set, add, replace, remove)
161
+ * @returns Patch request body for Cosmos DB
162
+ * @example
163
+ * ```typescript
164
+ * const operations = builder.patch({
165
+ * op: 'replace',
166
+ * path: '/name/givenName',
167
+ * value: 'Smith',
168
+ * });
169
+ * const item = container.item('id', 'partitionKey');
170
+ * await item.patch<Person>(operations);
171
+ * ```
172
+ */
173
+ abstract patch<P extends ExtractPatchPathExpressions<T>>(...operations: Array<{
174
+ path: P;
175
+ op: 'set' | 'add' | 'replace';
176
+ value: PatchPathValue<T, P>;
177
+ } | {
178
+ path: P;
179
+ op: 'remove';
180
+ }>): PatchRequestBody;
181
+ /**
182
+ * Builds query conditions from a structured object with type filters
183
+ * Supports {@link StringFilter}, {@link UUIDFilter}, and {@link InstantFilter} types
184
+ * @param query Query object with nested field filters containing __typeInfo
185
+ * @param prefix Path prefix for nested queries (defaults to 'c')
186
+ * @example
187
+ * ```typescript
188
+ * type PersonFilter = {
189
+ * name?: {
190
+ * givenName?: StringFilter;
191
+ * };
192
+ * };
193
+ * const filter = {
194
+ * name: {
195
+ * givenName: { __typeInfo: 'StringFilter', eq: 'John' }
196
+ * },
197
+ * } satisfies PersonFilter;
198
+ * builder.buildQuery(filter);
199
+ * ```
200
+ */
201
+ abstract buildQuery(query: Record<string, any> | undefined | null, prefix?: string): void;
202
+ /**
203
+ * Adds a WHERE clause with type-safe field access and operators
204
+ * @param field Type-safe field path
205
+ * @param operator SQL operator
206
+ * @example
207
+ * ```typescript
208
+ * builder.where('name.givenName', 'eq', 'John');
209
+ * builder.where('age', 'gt', 18);
210
+ * builder.where('bones', 'contains', 'arm');
211
+ * builder.where('name.givenName', 'in', ['John', 'Jane']);
212
+ * builder.where('deletedAt', 'isNull');
213
+ * ```
214
+ */
215
+ abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'isNull'): void;
216
+ abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'in', value: readonly PathValue<T, P>[]): void;
217
+ abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'contains', value: PathValue<T, P>[number]): void;
218
+ abstract where<P extends ExtractPathExpressions<T>, V extends PathValue<T, P>>(field: P, operator: BasicOpCode, value: V): void;
219
+ /**
220
+ * Clears any existing ordering
221
+ */
222
+ abstract orderBy(): void;
223
+ /**
224
+ * Sets ordering by field and direction
225
+ * @param field Field path to order by
226
+ * @param direction Sort direction (ASC/DESC)
227
+ */
228
+ abstract orderBy<P extends ExtractPathExpressions<T>>(field: P, direction: SortDirection): void;
229
+ /**
230
+ * Builds and returns the final SQL query specification
231
+ * @returns SQL query specification with parameters
232
+ */
233
+ abstract query(): SqlQuerySpec;
234
+ /**
235
+ * Executes the query and returns the first result
236
+ * @param container Cosmos DB container to query
237
+ * @returns First matching item or null
238
+ */
239
+ abstract getOne<TSelect = T>(container: Container): Promise<TSelect | null>;
240
+ /**
241
+ * Executes the query and returns paginated results with total count
242
+ * @param container Cosmos DB container to query
243
+ * @param limit Maximum number of items per page
244
+ * @param cursor Continuation token for pagination
245
+ * @returns Paginated results with metadata
246
+ */
247
+ abstract getAll<TSelect = T>(container: Container, limit?: number | null | undefined, cursor?: string | null | undefined): Promise<FetchResult<TSelect>>;
248
+ }
249
+
250
+ declare function createCosmosQueryBuilder<T extends Record<string, any>>(options?: CosmosQueryBuilderOptions): ICosmosQueryBuilder<T>;
251
+
252
+ export { type BasicOpCode, type CosmosQueryBuilderOptions, type FetchResult, ICosmosQueryBuilder, ILogger, type InstantFilter, type ExtendedOpCode as OpCode, SortDirection, type StringFilter, type UUIDFilter, createCosmosQueryBuilder };
@@ -0,0 +1,252 @@
1
+ import { SqlQuerySpec, JSONValue, PatchRequestBody } from '@azure/cosmos';
2
+
3
+ type ArrayElement<T> = T extends (infer U)[] ? U : never;
4
+ type PathBuilder<T, Sep extends string, K extends keyof T = keyof T> = K extends string ? T[K] extends Record<string, any> | null ? T[K] extends ArrayLike<any> ? K | `${K}[${number}]` | `${K}[${number}]${Sep}${PathBuilder<NonNullable<ArrayElement<T[K]>>, Sep>}` : K | `${K}${Sep}${PathBuilder<NonNullable<T[K]>, Sep>}` : K : never;
5
+ type DotPath<T> = PathBuilder<T, '.'>;
6
+ type SlashPathCore<T> = PathBuilder<T, '/'>;
7
+ type ExtractPathExpressions<T> = DotPath<T>;
8
+ type ExtractPatchPathExpressions<T> = `/${SlashPathCore<T>}` | `/${SlashPathCore<T>}/-`;
9
+ type PathValueResolver<T, P extends string, Sep extends string> = P extends `${infer K}${Sep}${infer Rest}` ? K extends keyof T ? PathValueResolver<NonNullable<T[K]>, Rest, Sep> : never : P extends `${infer K}[${infer _Index}]${infer Rest}` ? K extends keyof T ? T[K] extends (infer R)[] | null ? Rest extends '' ? NonNullable<R> : Rest extends `${Sep}${infer More}` ? PathValueResolver<NonNullable<R>, More, Sep> : never : never : never : P extends keyof T ? T[P] : T extends Record<string, any> ? T[keyof T] : never;
10
+ type PathValue<T, P extends string> = PathValueResolver<T, P, '.'>;
11
+ type PatchPathValue<T, P extends string> = P extends `/${infer Rest}` ? PathValueResolver<T, Rest, '/'> : never;
12
+
13
+ declare enum SortDirection {
14
+ Asc = "ASC",
15
+ Desc = "DESC"
16
+ }
17
+
18
+ type UUIDFilter = {
19
+ __typeInfo: 'UUIDFilter';
20
+ eq?: string;
21
+ ne?: string;
22
+ };
23
+ type InstantFilter = {
24
+ __typeInfo: 'InstantFilter';
25
+ eq?: string;
26
+ ieq?: string;
27
+ in?: string;
28
+ ine?: string;
29
+ like?: string;
30
+ ne?: string;
31
+ };
32
+ type StringFilter = {
33
+ __typeInfo: 'StringFilter';
34
+ eq?: string;
35
+ ieq?: string;
36
+ in?: string;
37
+ ine?: string;
38
+ like?: string;
39
+ ne?: string;
40
+ };
41
+ type ExtendedOpCode = BasicOpCode | 'contains' | 'in' | 'isNull';
42
+ type BasicOpCode = 'eq' | 'gt' | 'lt' | 'ge' | 'le' | 'ne';
43
+ type FetchResult<T> = {
44
+ items: T[];
45
+ continuationToken: string;
46
+ hasMoreResults: boolean;
47
+ totalCount: number;
48
+ count: number;
49
+ };
50
+ type CosmosQueryBuilderOptions = {
51
+ /**
52
+ * Custom implementation for logger.
53
+ * @defaultValue undefined (no logging)
54
+ */
55
+ logger?: ILogger;
56
+ };
57
+ type FeedOptions = {
58
+ continuationToken?: string | null;
59
+ maxItemCount?: number | null;
60
+ };
61
+ interface FeedResponse<TResource> {
62
+ readonly resources?: TResource[];
63
+ readonly hasMoreResults: boolean;
64
+ get continuationToken(): string;
65
+ }
66
+ interface QueryIterator<TResource> {
67
+ fetchNext(): Promise<FeedResponse<TResource>>;
68
+ fetchAll(): Promise<FeedResponse<TResource>>;
69
+ }
70
+ interface Container {
71
+ items: {
72
+ query<TResource>(querySpec: SqlQuerySpec, options?: FeedOptions): QueryIterator<TResource>;
73
+ };
74
+ }
75
+
76
+ declare abstract class ILogger {
77
+ abstract debug(message?: any, ...optionalParams: any[]): void;
78
+ abstract info(message?: any, ...optionalParams: any[]): void;
79
+ abstract error(message?: any, ...optionalParams: any[]): void;
80
+ abstract warn(message?: any, ...optionalParams: any[]): void;
81
+ abstract verbose(message?: any, ...optionalParams: any[]): void;
82
+ }
83
+ declare abstract class ICosmosQueryBuilder<T extends Record<string, any>> {
84
+ /**
85
+ * Sets the maximum number of items to return
86
+ * @param limit Maximum number of items
87
+ * @example
88
+ * ```typescript
89
+ * builder.limit(100);
90
+ * ```
91
+ */
92
+ abstract limit(limit: number): void;
93
+ /**
94
+ * Adds a JOIN clause to the query
95
+ * @param value JOIN alias
96
+ * @param statement Field path to join on
97
+ * @example
98
+ * ```typescript
99
+ * builder.join('b', 'bones');
100
+ * ```
101
+ */
102
+ abstract join<P extends ExtractPathExpressions<T>>(value: string, statement: P): void;
103
+ /**
104
+ * Sets the SELECT clause for the query
105
+ * @param value SELECT clause string
106
+ * @example
107
+ * ```typescript
108
+ * builder.select('COUNT(1) as count, UPPER(c.name.givenName) as name');
109
+ * ```
110
+ */
111
+ abstract select(value: string): void;
112
+ /**
113
+ * Sets the GROUP BY clause for the query
114
+ * @param value GROUP BY expression
115
+ * @example
116
+ * ```typescript
117
+ * builder.groupBy('UPPER(c.sex)');
118
+ * ```
119
+ */
120
+ abstract groupBy(value: string): void;
121
+ /**
122
+ * Performs fuzzy search across multiple fields
123
+ * @param value Search term
124
+ * @param fields Array of field paths to search in
125
+ * @example
126
+ * ```typescript
127
+ * builder.whereFuzzy('steve', ['name.givenName', 'name.familyName', 'email']);
128
+ * ```
129
+ */
130
+ abstract whereFuzzy<P extends ExtractPathExpressions<T>>(value: string, fields: [P, ...P[]]): void;
131
+ /**
132
+ * Adds a raw WHERE clause with field, operator, and value
133
+ * @param field Field name as string
134
+ * @param operator SQL operator (excluding isNull, contains, in)
135
+ * @param value Value to compare against
136
+ * @example
137
+ * ```typescript
138
+ * builder.whereRaw('p.id', 'eq', 'some-id');
139
+ * ```
140
+ */
141
+ abstract whereRaw(field: string, operator: Exclude<ExtendedOpCode, 'isNull' | 'contains' | 'in'>, value: JSONValue): void;
142
+ /**
143
+ * Adds an OR clause to match items satisfying any of the given conditions
144
+ * @param conditions Array of field/operator/value conditions
145
+ * @example
146
+ * ```typescript
147
+ * builder.whereOr([
148
+ * { field: 'name.givenName', operator: 'eq', value: 'John' },
149
+ * { field: 'name.familyName', operator: 'eq', value: 'Smith' }
150
+ * ]);
151
+ * ```
152
+ */
153
+ abstract whereOr(conditions: Array<{
154
+ field: string;
155
+ operator: ExtendedOpCode;
156
+ value: JSONValue;
157
+ }>): void;
158
+ /**
159
+ * Creates a JSON patch document for Cosmos DB patch operations
160
+ * @param operations Array of patch operations (set, add, replace, remove)
161
+ * @returns Patch request body for Cosmos DB
162
+ * @example
163
+ * ```typescript
164
+ * const operations = builder.patch({
165
+ * op: 'replace',
166
+ * path: '/name/givenName',
167
+ * value: 'Smith',
168
+ * });
169
+ * const item = container.item('id', 'partitionKey');
170
+ * await item.patch<Person>(operations);
171
+ * ```
172
+ */
173
+ abstract patch<P extends ExtractPatchPathExpressions<T>>(...operations: Array<{
174
+ path: P;
175
+ op: 'set' | 'add' | 'replace';
176
+ value: PatchPathValue<T, P>;
177
+ } | {
178
+ path: P;
179
+ op: 'remove';
180
+ }>): PatchRequestBody;
181
+ /**
182
+ * Builds query conditions from a structured object with type filters
183
+ * Supports {@link StringFilter}, {@link UUIDFilter}, and {@link InstantFilter} types
184
+ * @param query Query object with nested field filters containing __typeInfo
185
+ * @param prefix Path prefix for nested queries (defaults to 'c')
186
+ * @example
187
+ * ```typescript
188
+ * type PersonFilter = {
189
+ * name?: {
190
+ * givenName?: StringFilter;
191
+ * };
192
+ * };
193
+ * const filter = {
194
+ * name: {
195
+ * givenName: { __typeInfo: 'StringFilter', eq: 'John' }
196
+ * },
197
+ * } satisfies PersonFilter;
198
+ * builder.buildQuery(filter);
199
+ * ```
200
+ */
201
+ abstract buildQuery(query: Record<string, any> | undefined | null, prefix?: string): void;
202
+ /**
203
+ * Adds a WHERE clause with type-safe field access and operators
204
+ * @param field Type-safe field path
205
+ * @param operator SQL operator
206
+ * @example
207
+ * ```typescript
208
+ * builder.where('name.givenName', 'eq', 'John');
209
+ * builder.where('age', 'gt', 18);
210
+ * builder.where('bones', 'contains', 'arm');
211
+ * builder.where('name.givenName', 'in', ['John', 'Jane']);
212
+ * builder.where('deletedAt', 'isNull');
213
+ * ```
214
+ */
215
+ abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'isNull'): void;
216
+ abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'in', value: readonly PathValue<T, P>[]): void;
217
+ abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'contains', value: PathValue<T, P>[number]): void;
218
+ abstract where<P extends ExtractPathExpressions<T>, V extends PathValue<T, P>>(field: P, operator: BasicOpCode, value: V): void;
219
+ /**
220
+ * Clears any existing ordering
221
+ */
222
+ abstract orderBy(): void;
223
+ /**
224
+ * Sets ordering by field and direction
225
+ * @param field Field path to order by
226
+ * @param direction Sort direction (ASC/DESC)
227
+ */
228
+ abstract orderBy<P extends ExtractPathExpressions<T>>(field: P, direction: SortDirection): void;
229
+ /**
230
+ * Builds and returns the final SQL query specification
231
+ * @returns SQL query specification with parameters
232
+ */
233
+ abstract query(): SqlQuerySpec;
234
+ /**
235
+ * Executes the query and returns the first result
236
+ * @param container Cosmos DB container to query
237
+ * @returns First matching item or null
238
+ */
239
+ abstract getOne<TSelect = T>(container: Container): Promise<TSelect | null>;
240
+ /**
241
+ * Executes the query and returns paginated results with total count
242
+ * @param container Cosmos DB container to query
243
+ * @param limit Maximum number of items per page
244
+ * @param cursor Continuation token for pagination
245
+ * @returns Paginated results with metadata
246
+ */
247
+ abstract getAll<TSelect = T>(container: Container, limit?: number | null | undefined, cursor?: string | null | undefined): Promise<FetchResult<TSelect>>;
248
+ }
249
+
250
+ declare function createCosmosQueryBuilder<T extends Record<string, any>>(options?: CosmosQueryBuilderOptions): ICosmosQueryBuilder<T>;
251
+
252
+ export { type BasicOpCode, type CosmosQueryBuilderOptions, type FetchResult, ICosmosQueryBuilder, ILogger, type InstantFilter, type ExtendedOpCode as OpCode, SortDirection, type StringFilter, type UUIDFilter, createCosmosQueryBuilder };
@@ -0,0 +1 @@
1
+ var e=Object.defineProperty,t=(t,s)=>e(t,"name",{value:s,configurable:!0}),s=class{static{t(this,"ILogger")}},r=class{static{t(this,"ICosmosQueryBuilder")}},i={eq:"=",ne:"!=",ge:">=",gt:">",le:"<=",lt:"<"},n=class extends s{static{t(this,"DefaultLogger")}debug(e,...t){}info(e,...t){}error(e,...t){}warn(e,...t){}verbose(e,...t){}},u=class extends r{static{t(this,"CosmosQueryBuilder")}_orderBy;_select="*";_groupBy=null;_join="";_from="c";_queries=[];_parameters=[];_limit;_logger;constructor(e){super(),this._logger=e?.logger??new n}get queries(){return this._queries}set queries(e){this._queries=e}get parameters(){return this._parameters}set parameters(e){this._parameters=e}handleStringFilter(e,t){return this.handleFilterObject(e,t)}handleUuidFilter(e,t){return this.handleFilterObject(e,t)}handleInstantFilter(e,t){return this.handleFilterObject(e,t)}handleFilterObject(e,t){const{__typeInfo:s,...r}=t;for(const[t,s]of Object.entries(r).filter(e=>void 0!==e[1])){const r=e,n=`@p${this._parameters.length}`,u=i[t],o=`(${r} ?? null)`;if(null!=u)this._queries.push(`${o} ${u} ${n}`);else if("ieq"===t)this._queries.push(`StringEquals(${o}, ${n}, true)`);else if("ine"===t)this._queries.push(`Not(StringEquals(${o}, ${n}, true))`);else if("like"===t)this._queries.push(`Contains(${o}, ${n}, true)`);else{if("in"!==t)throw new Error(`Unknown operator ${t}`);this._queries.push(`ARRAY_CONTAINS(${n}, ${o})`)}this._parameters.push({name:n,value:s})}}_buildQuery(e,t="c"){if(null!=e){const{__typeInfo:s,...r}=e,i=Object.keys(r);for(const s of i){const r=e[s],i=r.__typeInfo??null,n=`${t}.${s}`;if("object"!=typeof r||null==r)throw new Error(`Unhandled type ${i}`);"StringFilter"===i?this.handleStringFilter(n,r):"InstantFilter"===i?this.handleInstantFilter(n,r):"UUIDFilter"===i?this.handleUuidFilter(n,r):this._buildQuery(r,n)}}}buildQuery(e,t="c"){this._buildQuery(e,t)}orderBy(e,t){this._orderBy=null==e||null==t?void 0:`\nORDER BY\n c.${e} ${t}`}groupBy(e){this._groupBy=`\nGROUP BY\n ${e}`}select(e){this._select=e}parameter(e,t){this._parameters.push({name:e,value:t})}limit(e){this._limit=e}join(e,t){this._join=`${e} IN c.${t}`}whereFuzzy(e,t){const s=`@p${this._parameters.length}`,r=[];for(const e of t){const t=`Contains(c.${e}, ${s}, true)`;r.push(t)}const i=`(${r.join(" OR ")})`;this._queries.push(i),this._parameters.push({name:s,value:e})}whereRaw(e,t,s){const r=`@p${this._parameters.length}`,n=i[t];this._queries.push(`${e} ${n} ${r}`),this._parameters.push({name:r,value:s})}whereOr(e){const t=[];for(const s of e){const{field:e,operator:r,value:n}=s,u=`@p${this._parameters.length}`;if("isNull"===r)t.push(`(c.${e} ?? null) = null`);else if("contains"===r)t.push(`ARRAY_CONTAINS(c.${e}, ${u})`);else if("in"===r)t.push(`ARRAY_CONTAINS(${u}, c.${e})`);else{const s=i[r];null!=s&&void 0!==n&&(t.push(`c.${e} ${s} ${u}`),this._parameters.push({name:u,value:n}))}}t.length>0&&this._queries.push(`(${t.join(" OR ")})`)}where(e,t,s){const r=`@p${this._parameters.length}`;if("isNull"===t){const t=`(c.${e} ?? null) = null`;this._queries.push(t)}else if("contains"===t){if(void 0!==s){const t=`ARRAY_CONTAINS(c.${e}, ${r})`;this._queries.push(t),this._parameters.push({name:r,value:s})}}else if("in"===t){if(void 0!==s){const t=`ARRAY_CONTAINS(${r}, c.${e})`;this._queries.push(t),this._parameters.push({name:r,value:s})}}else{const n=i[t];null!=n&&void 0!==s&&(this._queries.push(`c.${e} ${n} ${r}`),this._parameters.push({name:r,value:s}))}}filter(e){const t=`@p${this._parameters.length}`;this._queries.push(e.clause.replace("@",t)),null!=e.parameter&&this._parameters.push({name:t,value:e.parameter})}query(){const e=[];if(e.push(`SELECT\n ${this._select}`),e.push(`FROM\n ${this._from}`),""!==this._join&&e.push(`JOIN\n ${this._join}`),this._queries.length>0){e.push("WHERE");const t=this._queries.join("\n AND ");e.push(t)}null!=this._orderBy&&e.push(this._orderBy),null!=this._groupBy&&e.push(this._groupBy),null!=this._limit&&(e.push("OFFSET 0"),e.push(`LIMIT ${this._limit}`));const t={query:e.join("\n"),parameters:this.parameters};return this._logger.verbose("Cosmos Query",t),t}async getOne(e){const t=this.query(),s=e.items.query(t),r=await s.fetchNext();return this._logger.verbose("Cosmos Result",{result:r}),r.resources?.[0]??null}async getAll(e,t,s){const r=this.query(),i=e.items.query(r,{continuationToken:s??void 0,maxItemCount:t??void 0});let n;try{n=await i.fetchAll()}catch(e){throw this._logger.error("Cosmos Query Error",e),e}this._logger.verbose("Cosmos Result",{result:n}),this.select("VALUE COUNT(1)"),this.orderBy();const u=this.query(),o=e.items.query(u);let l;try{l=await o.fetchAll()}catch(e){throw this._logger.error("Cosmos Count Query Error",e),e}const h=l.resources?.[0]??0;return{continuationToken:n.continuationToken,count:n.resources?.length??0,items:n.resources??[],hasMoreResults:n.hasMoreResults,totalCount:h}}patch(...e){return{operations:e.map(e=>{if("remove"===e.op)return{op:e.op,path:e.path};if(void 0!==e.value)return{op:e.op,path:e.path,value:e.value};throw new Error(`Value is required for operation: ${e.op}`)})}}};function o(e){return new u(e)}t(o,"createCosmosQueryBuilder");var l=(e=>(e.Asc="ASC",e.Desc="DESC",e))(l||{});export{s as ILogger,l as SortDirection,o as createCosmosQueryBuilder};//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/public/interfaces.ts","../../src/private/consts.ts","../../src/private/DefaultLogger.ts","../../src/private/CosmosQueryBuilder.ts","../../src/public/createCosmosQueryBuilder.ts","../../src/public/enums.ts"],"names":["SortDirection"],"mappings":"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","file":"index.js","sourcesContent":["import type { JSONValue, PatchRequestBody, SqlQuerySpec } from '@azure/cosmos';\nimport type { ExtractPatchPathExpressions, ExtractPathExpressions, PatchPathValue, PathValue } from '../private/types';\nimport type { SortDirection } from './enums';\nimport type { BasicOpCode, Container, ExtendedOpCode, FetchResult, InstantFilter, StringFilter, UUIDFilter } from './types';\n\nexport abstract class ILogger {\n public abstract debug(message?: any, ...optionalParams: any[]): void;\n public abstract info(message?: any, ...optionalParams: any[]): void;\n public abstract error(message?: any, ...optionalParams: any[]): void;\n public abstract warn(message?: any, ...optionalParams: any[]): void;\n public abstract verbose(message?: any, ...optionalParams: any[]): void;\n}\n\nexport abstract class ICosmosQueryBuilder<T extends Record<string, any>> {\n /**\n * Sets the maximum number of items to return\n * @param limit Maximum number of items\n * @example\n * ```typescript\n * builder.limit(100);\n * ```\n */\n public abstract limit(limit: number): void;\n\n /**\n * Adds a JOIN clause to the query\n * @param value JOIN alias\n * @param statement Field path to join on\n * @example\n * ```typescript\n * builder.join('b', 'bones');\n * ```\n */\n public abstract join<P extends ExtractPathExpressions<T>>(value: string, statement: P): void;\n\n /**\n * Sets the SELECT clause for the query\n * @param value SELECT clause string\n * @example\n * ```typescript\n * builder.select('COUNT(1) as count, UPPER(c.name.givenName) as name');\n * ```\n */\n public abstract select(value: string): void;\n\n /**\n * Sets the GROUP BY clause for the query\n * @param value GROUP BY expression\n * @example\n * ```typescript\n * builder.groupBy('UPPER(c.sex)');\n * ```\n */\n public abstract groupBy(value: string): void;\n\n /**\n * Performs fuzzy search across multiple fields\n * @param value Search term\n * @param fields Array of field paths to search in\n * @example\n * ```typescript\n * builder.whereFuzzy('steve', ['name.givenName', 'name.familyName', 'email']);\n * ```\n */\n public abstract whereFuzzy<P extends ExtractPathExpressions<T>>(value: string, fields: [P, ...P[]]): void;\n\n /**\n * Adds a raw WHERE clause with field, operator, and value\n * @param field Field name as string\n * @param operator SQL operator (excluding isNull, contains, in)\n * @param value Value to compare against\n * @example\n * ```typescript\n * builder.whereRaw('p.id', 'eq', 'some-id');\n * ```\n */\n public abstract whereRaw(field: string, operator: Exclude<ExtendedOpCode, 'isNull' | 'contains' | 'in'>, value: JSONValue): void;\n\n /**\n * Adds an OR clause to match items satisfying any of the given conditions\n * @param conditions Array of field/operator/value conditions\n * @example\n * ```typescript\n * builder.whereOr([\n * { field: 'name.givenName', operator: 'eq', value: 'John' },\n * { field: 'name.familyName', operator: 'eq', value: 'Smith' }\n * ]);\n * ```\n */\n public abstract whereOr(conditions: Array<{ field: string; operator: ExtendedOpCode; value: JSONValue }>): void;\n\n /**\n * Creates a JSON patch document for Cosmos DB patch operations\n * @param operations Array of patch operations (set, add, replace, remove)\n * @returns Patch request body for Cosmos DB\n * @example\n * ```typescript\n * const operations = builder.patch({\n * op: 'replace',\n * path: '/name/givenName',\n * value: 'Smith',\n * });\n * const item = container.item('id', 'partitionKey');\n * await item.patch<Person>(operations);\n * ```\n */\n public abstract patch<P extends ExtractPatchPathExpressions<T>>(...operations: Array<{ path: P; op: 'set' | 'add' | 'replace'; value: PatchPathValue<T, P> } | { path: P; op: 'remove' }>): PatchRequestBody;\n\n /**\n * Builds query conditions from a structured object with type filters\n * Supports {@link StringFilter}, {@link UUIDFilter}, and {@link InstantFilter} types\n * @param query Query object with nested field filters containing __typeInfo\n * @param prefix Path prefix for nested queries (defaults to 'c')\n * @example\n * ```typescript\n * type PersonFilter = {\n * name?: {\n * givenName?: StringFilter;\n * };\n * };\n * const filter = {\n * name: {\n * givenName: { __typeInfo: 'StringFilter', eq: 'John' }\n * },\n * } satisfies PersonFilter;\n * builder.buildQuery(filter);\n * ```\n */\n public abstract buildQuery(query: Record<string, any> | undefined | null, prefix?: string): void;\n\n /**\n * Adds a WHERE clause with type-safe field access and operators\n * @param field Type-safe field path\n * @param operator SQL operator\n * @example\n * ```typescript\n * builder.where('name.givenName', 'eq', 'John');\n * builder.where('age', 'gt', 18);\n * builder.where('bones', 'contains', 'arm');\n * builder.where('name.givenName', 'in', ['John', 'Jane']);\n * builder.where('deletedAt', 'isNull');\n * ```\n */\n public abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'isNull'): void;\n public abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'in', value: readonly PathValue<T, P>[]): void;\n public abstract where<P extends ExtractPathExpressions<T>>(field: P, operator: 'contains', value: PathValue<T, P>[number]): void;\n public abstract where<P extends ExtractPathExpressions<T>, V extends PathValue<T, P>>(field: P, operator: BasicOpCode, value: V): void;\n\n /**\n * Clears any existing ordering\n */\n public abstract orderBy(): void;\n\n /**\n * Sets ordering by field and direction\n * @param field Field path to order by\n * @param direction Sort direction (ASC/DESC)\n */\n public abstract orderBy<P extends ExtractPathExpressions<T>>(field: P, direction: SortDirection): void;\n\n /**\n * Builds and returns the final SQL query specification\n * @returns SQL query specification with parameters\n */\n public abstract query(): SqlQuerySpec;\n\n /**\n * Executes the query and returns the first result\n * @param container Cosmos DB container to query\n * @returns First matching item or null\n */\n public abstract getOne<TSelect = T>(container: Container): Promise<TSelect | null>;\n\n /**\n * Executes the query and returns paginated results with total count\n * @param container Cosmos DB container to query\n * @param limit Maximum number of items per page\n * @param cursor Continuation token for pagination\n * @returns Paginated results with metadata\n */\n public abstract getAll<TSelect = T>(container: Container, limit?: number | null | undefined, cursor?: string | null | undefined): Promise<FetchResult<TSelect>>;\n}\n","export const operators: Record<string, string | undefined> = {\n eq: '=',\n ne: '!=',\n ge: '>=',\n gt: '>',\n le: '<=',\n lt: '<',\n} as const;\n","import { ILogger } from '../public/interfaces';\n\nexport class DefaultLogger extends ILogger {\n public debug(_message?: any, ..._optionalParams: any[]): void {}\n public info(_message?: any, ..._optionalParams: any[]): void {}\n public error(_message?: any, ..._optionalParams: any[]): void {}\n public warn(_message?: any, ..._optionalParams: any[]): void {}\n public verbose(_message?: any, ..._optionalParams: any[]): void {}\n}\n","import type { JSONValue, PatchRequestBody, SqlParameter, SqlQuerySpec } from '@azure/cosmos';\nimport type { SortDirection } from '../public/enums';\nimport { ICosmosQueryBuilder, type ILogger } from '../public/interfaces';\nimport type { BasicOpCode, Container, CosmosQueryBuilderOptions, ExtendedOpCode, FeedResponse, FetchResult, InstantFilter, StringFilter, UUIDFilter } from '../public/types';\nimport { operators } from './consts';\nimport { DefaultLogger } from './DefaultLogger';\nimport type { ExtractPatchPathExpressions, ExtractPathExpressions, PatchPathValue, PathValue, StringFilterData } from './types';\n\nexport class CosmosQueryBuilder<T extends Record<string, any>> extends ICosmosQueryBuilder<T> {\n private _orderBy?: string;\n private _select = '*';\n private _groupBy: string | null = null;\n private _join = '';\n private _from = 'c';\n private _queries: string[] = [];\n private _parameters: SqlParameter[] = [];\n private _limit: number | undefined;\n private _logger: ILogger;\n\n public constructor(options?: CosmosQueryBuilderOptions) {\n super();\n this._logger = options?.logger ?? new DefaultLogger();\n }\n\n public get queries(): string[] {\n return this._queries;\n }\n\n public set queries(value: string[]) {\n this._queries = value;\n }\n\n public get parameters(): SqlParameter[] {\n return this._parameters;\n }\n\n public set parameters(value: SqlParameter[]) {\n this._parameters = value;\n }\n\n private handleStringFilter(prefix: string, value: StringFilter) {\n return this.handleFilterObject(prefix, value);\n }\n\n private handleUuidFilter(prefix: string, value: UUIDFilter) {\n return this.handleFilterObject(prefix, value);\n }\n\n private handleInstantFilter(prefix: string, value: InstantFilter) {\n return this.handleFilterObject(prefix, value);\n }\n\n private handleFilterObject(prefix: string, value: StringFilterData & { __typeInfo: string }) {\n const { __typeInfo, ...rest } = value;\n for (const [key, value2] of Object.entries(rest).filter((x) => x[1] !== undefined)) {\n const path = prefix;\n const parameterName = `@p${this._parameters.length}`;\n const operator = operators[key];\n\n // Default to null to allow null comparison when parent object is not defined\n const queryKey = `(${path} ?? null)`;\n if (operator != null) {\n this._queries.push(`${queryKey} ${operator} ${parameterName}`);\n } else {\n if (key === 'ieq') {\n this._queries.push(`StringEquals(${queryKey}, ${parameterName}, true)`);\n } else if (key === 'ine') {\n this._queries.push(`Not(StringEquals(${queryKey}, ${parameterName}, true))`);\n } else if (key === 'like') {\n this._queries.push(`Contains(${queryKey}, ${parameterName}, true)`);\n } else if (key === 'in') {\n this._queries.push(`ARRAY_CONTAINS(${parameterName}, ${queryKey})`);\n } else {\n throw new Error(`Unknown operator ${key}`);\n }\n }\n this._parameters.push({ name: parameterName, value: value2 });\n }\n }\n\n private _buildQuery(query: Record<string, any> | null | undefined, prefix = 'c'): void {\n if (query != null) {\n const { __typeInfo, ...rest } = query;\n const queryKeys = Object.keys(rest);\n\n for (const key of queryKeys) {\n const value = query[key];\n const type: string | null = value.__typeInfo ?? null;\n const subPath = `${prefix}.${key}`;\n\n if (typeof value === 'object' && value != null) {\n if (type === 'StringFilter') {\n this.handleStringFilter(subPath, value);\n } else if (type === 'InstantFilter') {\n this.handleInstantFilter(subPath, value);\n } else if (type === 'UUIDFilter') {\n this.handleUuidFilter(subPath, value);\n } else {\n this._buildQuery(value, subPath);\n }\n } else {\n throw new Error(`Unhandled type ${type}`);\n }\n }\n }\n }\n\n public override buildQuery(query: Record<string, any> | undefined | null, prefix = 'c'): void {\n this._buildQuery(query, prefix);\n }\n\n public override orderBy(): void;\n public override orderBy<P extends ExtractPathExpressions<T>>(field: P, direction: SortDirection): void;\n public override orderBy<P extends ExtractPathExpressions<T>>(field?: P, direction?: SortDirection) {\n if (field == null || direction == null) {\n this._orderBy = undefined;\n } else {\n this._orderBy = `\\nORDER BY\\n c.${field} ${direction}`;\n }\n }\n\n public override groupBy(value: string): void {\n this._groupBy = `\\nGROUP BY\\n ${value}`;\n }\n\n public override select(value: string): void {\n this._select = value;\n }\n\n private parameter(name: string, value: JSONValue): void {\n this._parameters.push({\n name,\n value,\n });\n }\n\n public override limit(limit: number): void {\n this._limit = limit;\n }\n\n public override join<P extends ExtractPathExpressions<T>>(value: string, statement: P): void {\n this._join = `${value} IN c.${statement}`;\n }\n\n public override whereFuzzy<P extends ExtractPathExpressions<T>>(value: string, fields: [P, ...P[]]): void {\n const parameterName = `@p${this._parameters.length}`;\n const lines: string[] = [];\n for (const field of fields) {\n const clause = `Contains(c.${field}, ${parameterName}, true)`;\n lines.push(clause);\n }\n const queryLine = `(${lines.join(' OR ')})`;\n this._queries.push(queryLine);\n this._parameters.push({ name: parameterName, value });\n }\n\n public override whereRaw(field: string, operator: Exclude<ExtendedOpCode, 'isNull' | 'contains' | 'in'>, value: JSONValue): void {\n const parameterName = `@p${this._parameters.length}`;\n const sqlOperator = operators[operator];\n this._queries.push(`${field} ${sqlOperator} ${parameterName}`);\n this._parameters.push({ name: parameterName, value });\n }\n\n public override whereOr(conditions: Array<{ field: string; operator: ExtendedOpCode; value: JSONValue }>): void {\n const orClauses: string[] = [];\n for (const condition of conditions) {\n const { field, operator, value } = condition;\n const parameterName = `@p${this._parameters.length}`;\n\n if (operator === 'isNull') {\n orClauses.push(`(c.${field} ?? null) = null`);\n } else if (operator === 'contains') {\n orClauses.push(`ARRAY_CONTAINS(c.${field}, ${parameterName})`);\n } else if (operator === 'in') {\n orClauses.push(`ARRAY_CONTAINS(${parameterName}, c.${field})`);\n } else {\n const sqlOperator = operators[operator];\n if (sqlOperator != null && value !== undefined) {\n orClauses.push(`c.${field} ${sqlOperator} ${parameterName}`);\n this._parameters.push({ name: parameterName, value });\n }\n }\n }\n\n if (orClauses.length > 0) {\n this._queries.push(`(${orClauses.join(' OR ')})`);\n }\n }\n\n public override where<P extends ExtractPathExpressions<T>>(field: P, operator: 'isNull'): void;\n public override where<P extends ExtractPathExpressions<T>>(field: P, operator: 'in', value: readonly PathValue<T, P>[]): void;\n public override where<P extends ExtractPathExpressions<T>>(field: P, operator: 'contains', value: PathValue<T, P>[number]): void;\n public override where<P extends ExtractPathExpressions<T>, V extends PathValue<T, P>>(field: P, operator: BasicOpCode, value: V): void;\n public override where<P extends ExtractPathExpressions<T>, V extends PathValue<T, P>>(field: P, operator: ExtendedOpCode, value?: V | readonly V[]): void {\n const parameterName = `@p${this._parameters.length}`;\n\n if (operator === 'isNull') {\n const clause = `(c.${field} ?? null) = null`;\n this._queries.push(clause);\n } else if (operator === 'contains') {\n if (value !== undefined) {\n const clause = `ARRAY_CONTAINS(c.${field}, ${parameterName})`;\n this._queries.push(clause);\n this._parameters.push({ name: parameterName, value });\n }\n } else if (operator === 'in') {\n // Handle 'IN' operator\n if (value !== undefined) {\n const clause = `ARRAY_CONTAINS(${parameterName}, c.${field})`;\n this._queries.push(clause);\n this._parameters.push({ name: parameterName, value });\n }\n } else {\n const sqlOperator = operators[operator];\n if (sqlOperator != null && value !== undefined) {\n this._queries.push(`c.${field} ${sqlOperator} ${parameterName}`);\n this._parameters.push({ name: parameterName, value });\n }\n }\n }\n\n public filter(x: { clause: string; parameter?: JSONValue }): void {\n const paramName = `@p${this._parameters.length}`;\n this._queries.push(x.clause.replace('@', paramName));\n if (x.parameter != null) {\n this._parameters.push({\n name: paramName,\n value: x.parameter,\n });\n }\n }\n\n public override query(): SqlQuerySpec {\n const lines: string[] = [];\n lines.push(`SELECT\\n ${this._select}`);\n lines.push(`FROM\\n ${this._from}`);\n if (this._join !== '') {\n lines.push(`JOIN\\n ${this._join}`);\n }\n\n if (this._queries.length > 0) {\n lines.push('WHERE');\n const where = this._queries.join('\\n AND ');\n lines.push(where);\n }\n\n if (this._orderBy != null) {\n lines.push(this._orderBy);\n }\n if (this._groupBy != null) {\n lines.push(this._groupBy);\n }\n if (this._limit != null) {\n lines.push('OFFSET 0');\n lines.push(`LIMIT ${this._limit}`);\n }\n\n const queryText = lines.join('\\n');\n const result = {\n query: queryText,\n parameters: this.parameters,\n };\n this._logger.verbose('Cosmos Query', result);\n return result;\n }\n\n public override async getOne<TSelect = T>(container: Container): Promise<TSelect | null> {\n const itemsQuery = this.query();\n const itemsIterator = container.items.query<TSelect>(itemsQuery);\n const items = await itemsIterator.fetchNext();\n this._logger.verbose('Cosmos Result', { result: items });\n return items.resources?.[0] ?? null;\n }\n\n public override async getAll<TSelect>(container: Container, limit?: number | null | undefined, cursor?: string | null | undefined): Promise<FetchResult<TSelect>> {\n const itemsQuery = this.query();\n const itemsIterator = container.items.query<TSelect>(itemsQuery, {\n continuationToken: cursor ?? undefined,\n maxItemCount: limit ?? undefined,\n });\n let items: FeedResponse<TSelect>;\n try {\n items = await itemsIterator.fetchAll();\n } catch (err) {\n this._logger.error('Cosmos Query Error', err);\n throw err;\n }\n this._logger.verbose('Cosmos Result', { result: items });\n\n this.select('VALUE COUNT(1)');\n this.orderBy();\n\n const countQuery = this.query();\n const countIterator = container.items.query<number>(countQuery);\n\n let count: FeedResponse<number>;\n try {\n count = await countIterator.fetchAll();\n } catch (err) {\n this._logger.error('Cosmos Count Query Error', err);\n throw err;\n }\n\n const totalCount = count.resources?.[0] ?? 0;\n\n const result: FetchResult<TSelect> = {\n continuationToken: items.continuationToken,\n count: items.resources?.length ?? 0,\n items: items.resources ?? [],\n hasMoreResults: items.hasMoreResults,\n totalCount,\n };\n return result;\n }\n\n public override patch<P extends ExtractPatchPathExpressions<T>>(...operations: Array<{ path: P; op: 'set' | 'add' | 'replace'; value: PatchPathValue<T, P> } | { path: P; op: 'remove' }>): PatchRequestBody {\n const patchOperations = operations.map((opDef) => {\n if (opDef.op === 'remove') {\n return { op: opDef.op, path: opDef.path };\n }\n\n if (opDef.value !== undefined) {\n return { op: opDef.op, path: opDef.path, value: opDef.value };\n }\n\n throw new Error(`Value is required for operation: ${opDef.op}`);\n });\n\n return { operations: patchOperations };\n }\n}\n","import { CosmosQueryBuilder } from '../private/CosmosQueryBuilder';\nimport type { ICosmosQueryBuilder } from './interfaces';\nimport type { CosmosQueryBuilderOptions } from './types';\n\nexport function createCosmosQueryBuilder<T extends Record<string, any>>(options?: CosmosQueryBuilderOptions): ICosmosQueryBuilder<T> {\n return new CosmosQueryBuilder<T>(options);\n}\n","export enum SortDirection {\n Asc = 'ASC',\n Desc = 'DESC',\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@shellicar/cosmos-query-builder",
3
+ "private": false,
4
+ "version": "1.0.0-preview.1",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Stephen Hellicar",
8
+ "description": "A type-safe query builder for Azure Cosmos DB for NoSQL",
9
+ "keywords": [
10
+ "query",
11
+ "builder",
12
+ "azure",
13
+ "cosmos",
14
+ "db",
15
+ "cosmosdb",
16
+ "nosql",
17
+ "typescript"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/shellicar/cosmos-query-builder.git"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/shellicar/cosmos-query-builder/issues"
25
+ },
26
+ "homepage": "https://github.com/shellicar/cosmos-query-builder#readme",
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "main": "./dist/cjs/index.cjs",
31
+ "module": "./dist/esm/index.js",
32
+ "types": "./dist/esm/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "require": {
36
+ "types": "./dist/cjs/index.d.cts",
37
+ "default": "./dist/cjs/index.cjs"
38
+ },
39
+ "import": {
40
+ "types": "./dist/esm/index.d.ts",
41
+ "default": "./dist/esm/index.js"
42
+ }
43
+ }
44
+ },
45
+ "files": [
46
+ "dist"
47
+ ],
48
+ "devDependencies": {
49
+ "@azure/cosmos": "^4.5.1",
50
+ "@shellicar/build-clean": "^1.0.0",
51
+ "@tsconfig/node20": "^20.1.6",
52
+ "@tsconfig/node22": "^22.0.2",
53
+ "@types/node": "^24.3.0",
54
+ "terser": "^5.43.1",
55
+ "tsup": "^8.5.0",
56
+ "typescript": "^5.9.2",
57
+ "vitest": "^3.2.4"
58
+ },
59
+ "peerDependencies": {
60
+ "@azure/cosmos": ">=4.0.0 <5.0.0"
61
+ },
62
+ "scripts": {
63
+ "build": "tsup-node",
64
+ "dev": "tsup-node --watch",
65
+ "type-check": "tsc -p tsconfig.check.json"
66
+ }
67
+ }