crud-query-parser 0.0.3 → 1.0.0

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.
Files changed (64) hide show
  1. package/README.md +144 -36
  2. package/dist/adapters/array/index.d.mts +90 -0
  3. package/dist/adapters/array/index.d.ts +90 -0
  4. package/dist/adapters/array/index.js +2 -0
  5. package/dist/adapters/array/index.js.map +1 -0
  6. package/dist/adapters/array/index.mjs +2 -0
  7. package/dist/adapters/array/index.mjs.map +1 -0
  8. package/dist/adapters/dynamodb/index.d.mts +239 -0
  9. package/dist/adapters/dynamodb/index.d.ts +239 -0
  10. package/dist/adapters/dynamodb/index.js +2 -0
  11. package/dist/adapters/dynamodb/index.js.map +1 -0
  12. package/dist/adapters/dynamodb/index.mjs +2 -0
  13. package/dist/adapters/dynamodb/index.mjs.map +1 -0
  14. package/dist/adapters/mongodb/index.d.mts +163 -0
  15. package/dist/adapters/mongodb/index.d.ts +163 -0
  16. package/dist/adapters/mongodb/index.js +2 -0
  17. package/dist/adapters/mongodb/index.js.map +1 -0
  18. package/dist/adapters/mongodb/index.mjs +2 -0
  19. package/dist/adapters/mongodb/index.mjs.map +1 -0
  20. package/dist/adapters/typeorm/index.d.mts +87 -10
  21. package/dist/adapters/typeorm/index.d.ts +87 -10
  22. package/dist/adapters/typeorm/index.js +1 -1
  23. package/dist/adapters/typeorm/index.js.map +1 -1
  24. package/dist/adapters/typeorm/index.mjs +1 -1
  25. package/dist/adapters/typeorm/index.mjs.map +1 -1
  26. package/dist/{crud-request-CvDKp6Iy.d.mts → crud-request-DLo0ZuzD.d.mts} +42 -1
  27. package/dist/{crud-request-CvDKp6Iy.d.ts → crud-request-DLo0ZuzD.d.ts} +42 -1
  28. package/dist/{crud-request-where.builder-mP8y-fQp.d.mts → crud-request-where.builder-CBx-JZhl.d.mts} +1 -1
  29. package/dist/{crud-request-where.builder-D60W-QEd.d.ts → crud-request-where.builder-CqbP5LT9.d.ts} +1 -1
  30. package/dist/filters/index.d.mts +11 -2
  31. package/dist/filters/index.d.ts +11 -2
  32. package/dist/filters/index.js +1 -1
  33. package/dist/filters/index.js.map +1 -1
  34. package/dist/filters/index.mjs +1 -1
  35. package/dist/filters/index.mjs.map +1 -1
  36. package/dist/helpers/express/index.d.mts +30 -0
  37. package/dist/helpers/express/index.d.ts +30 -0
  38. package/dist/helpers/express/index.js +2 -0
  39. package/dist/helpers/express/index.js.map +1 -0
  40. package/dist/helpers/express/index.mjs +2 -0
  41. package/dist/helpers/express/index.mjs.map +1 -0
  42. package/dist/helpers/nestjs/index.d.mts +4 -3
  43. package/dist/helpers/nestjs/index.d.ts +4 -3
  44. package/dist/helpers/nestjs/index.js +1 -1
  45. package/dist/helpers/nestjs/index.js.map +1 -1
  46. package/dist/helpers/nestjs/index.mjs +1 -1
  47. package/dist/helpers/nestjs/index.mjs.map +1 -1
  48. package/dist/index.d.mts +12 -4
  49. package/dist/index.d.ts +12 -4
  50. package/dist/index.js +1 -1
  51. package/dist/index.js.map +1 -1
  52. package/dist/index.mjs +1 -1
  53. package/dist/index.mjs.map +1 -1
  54. package/dist/parsers/crud/index.d.mts +73 -10
  55. package/dist/parsers/crud/index.d.ts +73 -10
  56. package/dist/parsers/crud/index.js +1 -1
  57. package/dist/parsers/crud/index.js.map +1 -1
  58. package/dist/parsers/crud/index.mjs +1 -1
  59. package/dist/parsers/crud/index.mjs.map +1 -1
  60. package/dist/{query-adapter-Vebxws3V.d.ts → query-adapter-CZhPC1aq.d.ts} +3 -3
  61. package/dist/{query-adapter-BliD9hJN.d.mts → query-adapter-sgeUb8CV.d.mts} +3 -3
  62. package/dist/{request-parser-B-fK5GnP.d.ts → request-parser-Cr3cxMRw.d.ts} +4 -4
  63. package/dist/{request-parser-WaQBZsYG.d.mts → request-parser-DzuXbRsB.d.mts} +4 -4
  64. package/package.json +211 -133
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/dynamodb/dynamodb.query-adapter.ts","../../../src/utils/functions.ts","../../../src/utils/field-path.ts","../../../src/utils/objects.ts"],"sourcesContent":["import {\r\n AttributeValue,\r\n DynamoDBClient,\r\n GetItemCommand,\r\n GetItemInput,\r\n QueryCommand,\r\n QueryInput,\r\n ScanCommand,\r\n ScanInput,\r\n} from '@aws-sdk/client-dynamodb';\r\nimport { marshall, unmarshall } from '@aws-sdk/util-dynamodb';\r\nimport { CrudRequestWhere, CrudRequestWhereField, CrudRequestWhereOperator } from '../../models/crud-request-where';\r\nimport { CrudRequest, CrudRequestOrder, ParsedRequestSelect } from '../../models/crud-request';\r\nimport { QueryAdapter } from '../../models/query-adapter';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { FieldPath } from '../../models/field-path';\r\nimport { pathEquals, pathParse } from '../../utils/field-path';\r\nimport { ensureArray, ensureEmpty } from '../../utils/functions';\r\nimport { createGetManyResult } from '../../utils/objects';\r\n\r\nexport interface DynamoDBQueryAdapterOptions {\r\n /**\r\n * The DynamoDB client\r\n */\r\n client: DynamoDBClient;\r\n\r\n /**\r\n * The DynamoDB table name\r\n */\r\n tableName: string;\r\n\r\n /**\r\n * The table partition key\r\n */\r\n partitionKey: string;\r\n\r\n /**\r\n * The table sort key\r\n */\r\n sortKey?: string;\r\n\r\n /**\r\n * Whether the count will be disabled in getMany(). Disabling count saves read capacity units.\r\n */\r\n disableCount?: boolean;\r\n\r\n /**\r\n * Whether a Scan command should not run when a GetItem or Query command are not possible\r\n */\r\n disableScan?: boolean;\r\n}\r\n\r\n/**\r\n * Represents a generic DynamoDB query\r\n */\r\nexport type DynamoDBQuery = Partial<GetItemInput> & Partial<ScanInput> & Partial<QueryInput>;\r\n\r\n/**\r\n * Represents a command input that is either a DynamoDB GetItem, DynamoDB Query or a DynamoDB Scan\r\n */\r\nexport type GetOrQueryOrScanInput =\r\n { count: GetItemInput, full: GetItemInput, type: 'get' } |\r\n { count: QueryInput, full: QueryInput, type: 'query' } |\r\n { count: ScanInput, full: ScanInput, type: 'scan' };\r\n\r\nexport interface DynamoDBQueryContext {\r\n /**\r\n * Whether the query should split the primary keys from the filter expressions to the key parameter\r\n */\r\n allowKeySplitting?: boolean;\r\n\r\n /**\r\n * The key parameter\r\n */\r\n key?: CrudRequestWhereField[];\r\n}\r\n\r\n/**\r\n * Adapts queries to DynamoDB query builder object.\r\n *\r\n * Not supported:\r\n * - Ordering by any other field except the sort key\r\n * - Page\r\n * - Offset\r\n * - Relations\r\n *\r\n * The ordering only works for the sort key and in query operations.\r\n * It's ignored in scan operations.\r\n */\r\nexport class DynamoDBQueryAdapter implements QueryAdapter<DynamoDBQuery> {\r\n\r\n protected readonly partitionKey: FieldPath;\r\n protected readonly sortKey?: FieldPath;\r\n\r\n constructor(\r\n protected readonly options: DynamoDBQueryAdapterOptions,\r\n ) {\r\n this.partitionKey = pathParse(options.partitionKey);\r\n this.sortKey = options.sortKey ? pathParse(options.sortKey) : undefined;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build(baseQuery: DynamoDBQuery, request: CrudRequest): DynamoDBQuery {\r\n const { full } = this.buildBaseGetOrQueryOrScan(baseQuery, request);\r\n\r\n return full;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E>(baseQuery: DynamoDBQuery, request: CrudRequest): Promise<GetManyResult<E>> {\r\n const input = this.buildBaseGetOrQueryOrScan(baseQuery, request);\r\n\r\n const [data, total] = await this.fetchDataAndCount<E>(input, true);\r\n\r\n const limit = request.limit || baseQuery.Limit;\r\n\r\n return createGetManyResult(data, total || 0, 0, limit);\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E>(baseQuery: DynamoDBQuery, request: CrudRequest): Promise<E | null> {\r\n const input = this.buildBaseGetOrQueryOrScan(baseQuery, { ...request, limit: 1 });\r\n\r\n const [data] = await this.fetchDataAndCount<E>(input, false);\r\n\r\n if (data.length === 0)\r\n return null;\r\n\r\n return data[0];\r\n }\r\n\r\n /**\r\n * Creates a DynamoDB Query input\r\n *\r\n * @param baseQuery The base query\r\n * @param request The crud request\r\n */\r\n public buildQuery(baseQuery: Partial<QueryInput>, request: CrudRequest): QueryInput {\r\n const query: QueryInput = {\r\n ...baseQuery,\r\n TableName: baseQuery.TableName || this.options.tableName,\r\n };\r\n const ctx: DynamoDBQueryContext = { allowKeySplitting: true };\r\n\r\n this.adaptProjection(query, request.select);\r\n this.adaptFilter(query, ctx, request.where);\r\n this.adaptOrder(query, request.order);\r\n this.adaptLimit(query, request.limit);\r\n\r\n if (ctx.key)\r\n this.adaptQueryKeyExpression(query, ctx.key);\r\n\r\n return query;\r\n }\r\n\r\n /**\r\n * Creates a DynamoDB Scan input\r\n *\r\n * @param baseQuery The base query\r\n * @param request The crud request\r\n */\r\n public buildScan(baseQuery: Partial<ScanInput>, request: CrudRequest): ScanInput {\r\n const scan: ScanInput = {\r\n ...baseQuery,\r\n TableName: baseQuery.TableName || this.options.tableName,\r\n };\r\n const ctx: DynamoDBQueryContext = { allowKeySplitting: false };\r\n\r\n this.adaptProjection(scan, request.select);\r\n this.adaptFilter(scan, ctx, request.where);\r\n this.adaptLimit(scan, request.limit);\r\n\r\n return scan;\r\n }\r\n\r\n /**\r\n * Creates a DynamoDB GetItem input\r\n *\r\n * @param baseQuery The base query\r\n * @param request The crud request\r\n */\r\n public buildGetItem(baseQuery: Partial<GetItemInput>, request: CrudRequest): GetItemInput {\r\n const query: GetItemInput = {\r\n ...baseQuery,\r\n TableName: baseQuery.TableName || this.options.tableName,\r\n Key: baseQuery.Key,\r\n };\r\n const ctx: DynamoDBQueryContext = { allowKeySplitting: true };\r\n\r\n this.adaptProjection(query, request.select);\r\n this.adaptFilter({}, ctx, request.where);\r\n\r\n if (ctx.key)\r\n this.adaptGetItemKey(query, ctx.key);\r\n\r\n return query;\r\n }\r\n\r\n /**\r\n * Creates a DynamoDB GetItem, Query or Scan input, based on whether the partition key and sort key are present in the where conditions\r\n *\r\n * @param baseInput The base query\r\n * @param request The crud request\r\n */\r\n protected buildBaseGetOrQueryOrScan(\r\n baseInput: DynamoDBQuery,\r\n request: CrudRequest,\r\n ): GetOrQueryOrScanInput {\r\n const input: DynamoDBQuery = {\r\n ...baseInput,\r\n TableName: baseInput.TableName || this.options.tableName,\r\n };\r\n const ctx: DynamoDBQueryContext = { allowKeySplitting: true };\r\n\r\n this.adaptFilter(input, ctx, request.where);\r\n\r\n const mapResult = (type: 'get' | 'query' | 'scan'): GetOrQueryOrScanInput => {\r\n const count = {\r\n ...input,\r\n ExpressionAttributeNames: { ...input.ExpressionAttributeNames },\r\n ExpressionAttributeValues: { ...input.ExpressionAttributeValues },\r\n Select: 'COUNT',\r\n };\r\n\r\n this.adaptProjection(input, request.select);\r\n this.adaptOrder(input, request.order);\r\n this.adaptLimit(input, request.limit);\r\n\r\n return { count: count as any, full: input as any, type };\r\n };\r\n\r\n // In case there is an existing GetItem key\r\n if (input.Key)\r\n return mapResult('get');\r\n\r\n // In case there is an existing Query key\r\n if (input.KeyConditionExpression)\r\n return mapResult('query');\r\n\r\n const operation = this.getAvailableCommandByKey(input, ctx.key);\r\n\r\n // GetItem\r\n if (operation === 'get' && ctx.key) {\r\n this.adaptGetItemKey(input, ctx.key);\r\n\r\n return mapResult('get');\r\n }\r\n\r\n // Query\r\n if (operation === 'query' && ctx.key) {\r\n this.adaptQueryKeyExpression(input, ctx.key);\r\n\r\n return mapResult('query');\r\n }\r\n\r\n // In case there are keys, we'll add them back to the filter expression\r\n if (ctx.key)\r\n this.adaptFilterKeyExpression(input, ctx.key);\r\n\r\n // Scan\r\n return mapResult('scan');\r\n }\r\n\r\n /**\r\n * Fetches data through a GetItem, Query or Scan command. Optionally fetches the count too.\r\n *\r\n * @param mixed The GetItem, Query or Scan input\r\n * @param fetchCount Whether it should fetch the total number of items too.\r\n */\r\n protected async fetchDataAndCount<E>(mixed: GetOrQueryOrScanInput, fetchCount: boolean): Promise<[E[], number?]> {\r\n if (mixed.type === 'get') {\r\n const result = await this.options.client.send(new GetItemCommand(mixed.full));\r\n\r\n if (!result.Item)\r\n return [[], 0];\r\n\r\n return [[this.unmarshall<E>(result.Item)], 1];\r\n }\r\n\r\n const shouldFetchCount = fetchCount && !this.options.disableCount;\r\n\r\n if (mixed.type === 'query') {\r\n const [output, count] = await Promise.all([\r\n this.options.client.send(new QueryCommand(mixed.full)),\r\n shouldFetchCount ? this.options.client.send(new QueryCommand(mixed.count)) : undefined,\r\n ]);\r\n\r\n const items = (output.Items || []).map(item => this.unmarshall<E>(item));\r\n\r\n return [items, count?.Count];\r\n }\r\n\r\n if (mixed.type === 'scan' && !this.options.disableScan) {\r\n const [output, count] = await Promise.all([\r\n this.options.client.send(new ScanCommand(mixed.full)),\r\n shouldFetchCount ? this.options.client.send(new ScanCommand(mixed.count)) : undefined,\r\n ]);\r\n\r\n const items = (output.Items || []).map(item => this.unmarshall<E>(item));\r\n\r\n return [items, count?.Count];\r\n }\r\n\r\n throw new Error('The partition key is missing in the query. Scan is disabled');\r\n }\r\n\r\n /**\r\n * Gets the command to run based on the key combination available.\r\n *\r\n * If the complete primary key is available, it results in GetItem.\r\n * If only the partition key is available but not the sort key, it results in Query.\r\n * If no keys are available, it resutls in Scan.\r\n *\r\n * @param input The DynamoDB query\r\n * @param keys The primary keys\r\n */\r\n protected getAvailableCommandByKey(input: DynamoDBQuery, keys: CrudRequestWhereField[] | undefined): 'get' | 'query' | 'scan' {\r\n if (!keys)\r\n return 'scan';\r\n\r\n let hasPartitionKeyEq: boolean = false;\r\n let hasSortKeyEq: boolean = !this.sortKey;\r\n\r\n for (const where of keys) {\r\n const isEq = where.operator === CrudRequestWhereOperator.EQ;\r\n\r\n // Partition Key\r\n if (pathEquals(where.field, this.partitionKey) && isEq)\r\n hasPartitionKeyEq = true;\r\n\r\n // Sort Key\r\n if (this.sortKey && pathEquals(where.field, this.sortKey) && isEq)\r\n hasSortKeyEq = true;\r\n }\r\n\r\n if (hasPartitionKeyEq && hasSortKeyEq && !input.FilterExpression)\r\n return 'get';\r\n\r\n if (hasPartitionKeyEq)\r\n return 'query';\r\n\r\n return 'scan';\r\n }\r\n\r\n /**\r\n * Adapts the key conditions into a key expression\r\n *\r\n * @param query The DynamoDB query\r\n * @param keys The key conditions\r\n */\r\n protected adaptQueryKeyExpression(query: Partial<QueryInput>, keys: CrudRequestWhereField[]): void {\r\n const condition: string[] = [];\r\n\r\n for (const where of keys) {\r\n const result = this.mapWhereOperators(query, where);\r\n\r\n query.ExpressionAttributeValues = {\r\n ...(query.ExpressionAttributeValues || {}),\r\n ...this.marshall(result.params),\r\n };\r\n\r\n condition.push(result.where);\r\n }\r\n\r\n query.KeyConditionExpression = condition.join(' AND ');\r\n }\r\n\r\n /**\r\n * Adapts the key conditions into a filter expression\r\n *\r\n * @param query The DynamoDB query\r\n * @param keys The key conditions\r\n */\r\n protected adaptFilterKeyExpression(query: Partial<ScanInput>, keys: CrudRequestWhereField[]): void {\r\n const condition: string[] = [];\r\n\r\n for (const where of keys) {\r\n const result = this.mapWhereOperators(query, where);\r\n\r\n query.ExpressionAttributeValues = {\r\n ...(query.ExpressionAttributeValues || {}),\r\n ...this.marshall(result.params),\r\n };\r\n\r\n condition.push(result.where);\r\n }\r\n\r\n if (query.FilterExpression)\r\n query.FilterExpression = condition.join(' AND ') + ' AND ' + this.wrapParenthesis(query.FilterExpression);\r\n else\r\n query.FilterExpression = condition.join(' AND ');\r\n }\r\n\r\n /**\r\n * Adapts the key conditions into a key object\r\n *\r\n * @param query The DynamoDB query\r\n * @param keys The key conditions\r\n */\r\n protected adaptGetItemKey(query: Partial<GetItemInput>, keys: CrudRequestWhereField[]): void {\r\n const key: Record<string, unknown> = query.Key ? this.unmarshall(query.Key) : {};\r\n\r\n for (const where of keys) {\r\n if (where.operator !== CrudRequestWhereOperator.EQ)\r\n continue;\r\n\r\n key[where.field.join('.')] = where.value;\r\n }\r\n\r\n query.Key = this.marshall(key);\r\n }\r\n\r\n /**\r\n * Adapts a list of select fields into a projection expression\r\n *\r\n * @param query The DynamoDB query\r\n * @param select The select fields\r\n */\r\n protected adaptProjection(query: DynamoDBQuery, select: ParsedRequestSelect): void {\r\n if (select.length === 0)\r\n return;\r\n\r\n const existing = query.ProjectionExpression?.split(',').map(exp => exp.trim()).filter(exp => !!exp) || [];\r\n const attributes = select.map(f => this.registerAttribute(query, f.field));\r\n\r\n query.ProjectionExpression = [...new Set([...existing, ...attributes])].join(', ');\r\n }\r\n\r\n /**\r\n * Adapts the order field that matches the sort key to a DynamoDB Query\r\n *\r\n * @param query The DynamoDB query\r\n * @param order The order fields\r\n */\r\n protected adaptOrder(query: DynamoDBQuery, order: CrudRequestOrder[]): void {\r\n const sortKey = this.sortKey;\r\n\r\n if (!sortKey)\r\n return;\r\n\r\n const sort = order.find(o => pathEquals(o.field, sortKey));\r\n\r\n if (!sort)\r\n return;\r\n\r\n query.ScanIndexForward = sort.order === 'ASC';\r\n }\r\n\r\n /**\r\n * Adapts a where condition into a DynamoDB filter\r\n *\r\n * @param query The DynamoDB query\r\n * @param ctx The builder context\r\n * @param where The where condition\r\n */\r\n protected adaptFilter(query: DynamoDBQuery, ctx: DynamoDBQueryContext, where: CrudRequestWhere): void {\r\n const filter = this.mapWhere(query, ctx, where, true);\r\n\r\n if (!filter)\r\n return;\r\n\r\n const existingFilter = query.FilterExpression;\r\n\r\n query.FilterExpression = existingFilter ?\r\n `${this.wrapParenthesis(existingFilter)} AND ${this.wrapParenthesis(filter)}` : filter;\r\n }\r\n\r\n /**\r\n * Adapts the limit\r\n *\r\n * @param query The DynamoDB query\r\n * @param limit The limit value\r\n */\r\n protected adaptLimit(query: DynamoDBQuery, limit: number | undefined): void {\r\n if (limit)\r\n query.Limit = limit;\r\n }\r\n\r\n /**\r\n * Maps a where condition into a filter expression\r\n *\r\n * @param query The DynamoDB query\r\n * @param ctx The query builder context\r\n * @param where The where condition\r\n * @param isTopLevelAnd Whether this is the top level AND condition\r\n */\r\n protected mapWhere(\r\n query: DynamoDBQuery,\r\n ctx: DynamoDBQueryContext,\r\n where: CrudRequestWhere,\r\n isTopLevelAnd: boolean = false,\r\n ): string | undefined {\r\n // AND\r\n if (where.and && where.and.length > 0) {\r\n if (where.and.length === 1)\r\n return this.mapWhere(query, ctx, where.and[0], isTopLevelAnd);\r\n\r\n return this.wrapParenthesis(\r\n where.and\r\n .map(item => this.mapWhere(query, ctx, item, isTopLevelAnd))\r\n .filter(query => !!query)\r\n .join(' AND ')\r\n );\r\n }\r\n\r\n // OR\r\n if (where.or && where.or.length > 0) {\r\n if (where.or.length === 1)\r\n return this.mapWhere(query, ctx, where.or[0], isTopLevelAnd);\r\n\r\n return this.wrapParenthesis(\r\n where.or\r\n .map(item => this.mapWhere(query, ctx, item, false))\r\n .filter(query => !!query)\r\n .join(' OR ')\r\n );\r\n }\r\n\r\n // Condition\r\n if (where.field) {\r\n // Checks whether this field is in the top-level AND condition and is a primary key\r\n if (isTopLevelAnd && ctx.allowKeySplitting) {\r\n const isPrimaryKey =\r\n (pathEquals(this.partitionKey, where.field) && where.operator === CrudRequestWhereOperator.EQ)\r\n || (this.sortKey && pathEquals(this.sortKey, where.field));\r\n\r\n if (isPrimaryKey) {\r\n ctx.key = ctx.key || [];\r\n ctx.key.push(where);\r\n\r\n return undefined;\r\n }\r\n }\r\n\r\n const result = this.mapWhereOperators(query, where);\r\n\r\n query.ExpressionAttributeValues = {\r\n ...(query.ExpressionAttributeValues || {}),\r\n ...this.marshall(result.params),\r\n };\r\n\r\n return result.where;\r\n }\r\n }\r\n\r\n /**\r\n * Maps a where condition into an expression and its parameters\r\n *\r\n * @param query The DynamoDB query\r\n * @param where The where condition\r\n */\r\n protected mapWhereOperators(\r\n query: DynamoDBQuery,\r\n where: CrudRequestWhereField,\r\n ): { where: string, params: Record<string, any> } {\r\n const field = this.registerAttribute(query, where.field);\r\n const param = this.createUniqueParam(query, field.replace('#', ':'));\r\n\r\n let value = where.value;\r\n\r\n switch (where.operator) {\r\n case CrudRequestWhereOperator.EQ:\r\n return { where: `${field} = ${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NEQ:\r\n return { where: `${field} <> ${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.LT:\r\n return { where: `${field} < ${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.LTE:\r\n return { where: `${field} <= ${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.GT:\r\n return { where: `${field} > ${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.GTE:\r\n return { where: `${field} >= ${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.STARTS:\r\n return { where: `begins_with(${field}, ${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS:\r\n return { where: `contains(${field}, ${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS:\r\n return { where: `NOT contains(${field}, ${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.BETWEEN:\r\n const arr = ensureArray('BETWEEN operator', value, 2);\r\n\r\n return {\r\n where: `${field} BETWEEN ${param}_start AND ${param}_end`,\r\n params: { [`${param}_start`]: arr[0], [`${param}_end`]: arr[1] },\r\n };\r\n\r\n case CrudRequestWhereOperator.IN:\r\n value = ensureArray('IN operator', value, 1);\r\n\r\n return {\r\n where: `${field} IN (${value.map((_, i) => param + '_' + i).join(', ')})`,\r\n params: value.reduce((prev, val, i) => ({\r\n ...prev,\r\n [param + '_' + i]: val,\r\n }), {}),\r\n };\r\n\r\n case CrudRequestWhereOperator.NOT_IN:\r\n value = ensureArray('NOT IN operator', value, 1);\r\n\r\n return {\r\n where: `NOT (${field} IN (${value.map((_, i) => param + '_' + i).join(', ')}))`,\r\n params: value.reduce((prev, val, i) => ({\r\n ...prev,\r\n [param + '_' + i]: val,\r\n }), {}),\r\n };\r\n\r\n case CrudRequestWhereOperator.IS_NULL:\r\n ensureEmpty('IS NULL operator', value);\r\n\r\n return { where: `(attribute_not_exists(${field}) OR ${field} = :null)`, params: { ':null': null } };\r\n\r\n case CrudRequestWhereOperator.NOT_NULL:\r\n ensureEmpty('NOT NULL operator', value);\r\n\r\n return { where: `(attribute_exists(${field}) AND ${field} <> :null)`, params: { ':null': null } };\r\n }\r\n\r\n throw new Error(`Operator not supported in DynamoDB \"${where.operator}\"`);\r\n }\r\n\r\n /**\r\n * Generates the attribute name and registers an attribute to the query\r\n *\r\n * @param query The DynamoDB query\r\n * @param field The field path\r\n */\r\n protected registerAttribute(query: DynamoDBQuery, field: FieldPath): string {\r\n const fieldName = field.join('.');\r\n const baseName = '#' + fieldName.replace(/[^A-Za-z0-9_]/g, '_');\r\n\r\n let attributeName = baseName;\r\n let interaction = 1;\r\n\r\n const names = query.ExpressionAttributeNames || {};\r\n\r\n // This avoids attribute name conflicts\r\n while (names[attributeName] && names[attributeName] !== fieldName) {\r\n attributeName = baseName + interaction.toString();\r\n interaction++;\r\n }\r\n\r\n names[attributeName] = fieldName;\r\n query.ExpressionAttributeNames = names;\r\n\r\n return attributeName;\r\n }\r\n\r\n /**\r\n * Creates a unique query parameter name based on a field\r\n *\r\n * @param query The DynamoDB query\r\n * @param name The parameter name, which should start with \":\"\r\n */\r\n protected createUniqueParam(query: DynamoDBQuery, name: string): string {\r\n let param = name;\r\n let iteration: number = 1;\r\n\r\n while (query.ExpressionAttributeValues?.[param]) {\r\n param = name + iteration.toString();\r\n iteration++;\r\n }\r\n\r\n return param;\r\n }\r\n\r\n /**\r\n * Wraps an expression with parenthesis\r\n *\r\n * @param expression The filter expression\r\n */\r\n protected wrapParenthesis(expression: string): string {\r\n if (!expression)\r\n return '';\r\n\r\n if (expression.startsWith('(') && expression.endsWith(')'))\r\n return expression;\r\n\r\n return `(${expression})`;\r\n }\r\n\r\n /**\r\n * Converts an object into DynamoDB's attribute key-value structure\r\n *\r\n * @param data The object\r\n */\r\n protected marshall<T>(data: T): Record<string, AttributeValue> {\r\n return marshall(data);\r\n }\r\n\r\n /**\r\n * Converts a DynamoDB's attribute key-value structure into an object\r\n *\r\n * @param data The attribute key-value\r\n */\r\n protected unmarshall<T>(data: Record<string, AttributeValue>): T {\r\n return unmarshall(data) as T;\r\n }\r\n\r\n}\r\n","export function ensurePrimitive(fieldName: string, data: any): number | string | boolean | Date {\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number or boolean`);\r\n}\r\n\r\nexport function ensurePrimitiveOrNull(fieldName: string, data: any): number | string | boolean | Date | undefined | null {\r\n if (data === null || data === undefined)\r\n return data;\r\n\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number, boolean or null`);\r\n}\r\n\r\nexport function ensureString(fieldName: string, data: any): string {\r\n if (typeof data === 'string')\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string`);\r\n}\r\n\r\nexport function ensureArray<T>(fieldName: string, data: T[] | any, minLength: number = 0): T[] {\r\n if (!Array.isArray(data) || data.length < minLength)\r\n throw new Error(`${fieldName} must be an array with at least ${minLength} items`);\r\n\r\n return data;\r\n}\r\n\r\nexport function ensureEmpty(fieldName: string, data: any) {\r\n if (isValid(data) && data !== true)\r\n throw new Error(`${fieldName} must be true, null or undefined`);\r\n}\r\n\r\nexport function isValid<T>(value: T | undefined | null): value is T {\r\n return value !== null && value !== undefined;\r\n}\r\n\r\nexport function getOffset(offset: number | undefined, limit?: number, page?: number): number {\r\n return offset ?? (limit && page ? limit * (page - 1) : 0);\r\n}\r\n\r\nexport interface Type<T> extends Function { new (... args: any[]): T; }\r\n\r\nexport function createInstance<T extends object>(clazzOrInstance: T | Type<T> | undefined): T | undefined {\r\n if (typeof clazzOrInstance === 'function')\r\n return new clazzOrInstance();\r\n\r\n if (typeof clazzOrInstance === 'object')\r\n return clazzOrInstance as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n","import { isValid } from './functions';\r\n\r\n/**\r\n * Parses a path by splitting it by dots\r\n *\r\n * @param value The full path as a string or the parts already split\r\n */\r\nexport function pathParse(value: string | string[]): string[] {\r\n if (typeof value === 'string')\r\n return value.split('.');\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Checks whether two field paths are equal\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] is equal to [\"path\", \"to\", \"field\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathEquals(path1: string[], path2: string[]): boolean {\r\n if (path1.length !== path2.length)\r\n return false;\r\n\r\n return path1.every((p1, i) => path2[i] === p1);\r\n}\r\n\r\n/**\r\n * Checks whether a path starts with another path.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] starts with [\"path\"] or [\"path\", \"to\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathStartsWith(path: string[], start: string[]): boolean {\r\n if (path.length < start.length)\r\n return false;\r\n\r\n return start.every((start, i) => path[i] === start);\r\n}\r\n\r\n/**\r\n * Checks whether the base of a path matches.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] has a base of [\"path\", \"to\"] but not [\"path\"]\r\n */\r\nexport function pathHasBase(path: string[], base: string[]): boolean {\r\n if (path.length - 1 !== base.length)\r\n return false;\r\n\r\n return base.every((start, i) => path[i] === start);\r\n}\r\n\r\n/**\r\n * Breaks a path into the base part and the field name part\r\n *\r\n * @param path The full path\r\n */\r\nexport function pathGetBaseAndName(path: string[]): [string[], string] {\r\n if (path.length === 0)\r\n throw new Error('Cannot break an empty path');\r\n\r\n const base = [...path];\r\n const name = base.pop()!;\r\n\r\n return [base, name];\r\n}\r\n\r\n\r\n/**\r\n * Gets the last part of the path: the field name\r\n *\r\n * @param path The full path\r\n */\r\nexport function pathGetFieldName(path: string[]): string {\r\n return path.length > 0 ? path[path.length - 1] : '';\r\n}\r\n\r\n/**\r\n * Sets a value for the given path\r\n *\r\n * @param obj The root object\r\n * @param field The full field path\r\n */\r\nexport function pathGetValue(obj: object, field: string[]): any {\r\n let value: any = obj;\r\n\r\n for (let i = 0; i < field.length; i++) {\r\n const name = field[i];\r\n\r\n if (!isValid(value))\r\n return undefined;\r\n\r\n if (typeof value !== 'object')\r\n throw new Error(`Cannot get ${name} as it is not an object (got ${typeof value})`);\r\n\r\n value = value[name];\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Sets a value for the given path\r\n *\r\n * @param obj The root object\r\n * @param field The full field path\r\n * @param value The value to be set\r\n */\r\nexport function pathSetValue(obj: object, field: string[], value: any): void {\r\n let self: any = obj;\r\n\r\n for (let i = 0; i < field.length; i++) {\r\n const name = field[i];\r\n\r\n if (typeof self !== 'object')\r\n throw new Error(`Cannot set ${name} as it is not an object (got ${typeof self})`);\r\n\r\n const isLast = i === field.length - 1;\r\n\r\n if (isLast)\r\n self[name] = value;\r\n else if (!isValid(self[name]))\r\n self = self[name] = {};\r\n else\r\n self = self[name];\r\n }\r\n}\r\n","import { GetManyResult } from '../models/get-many-result';\r\nimport { CrudRequest } from '../models/crud-request';\r\n\r\n/**\r\n * Creates a CrudRequest object, filling required missing properties with empty values\r\n */\r\nexport function createCrudRequest(crudRequest?: Partial<CrudRequest>): CrudRequest {\r\n return {\r\n select: [],\r\n relations: [],\r\n order: [],\r\n where: { and: [] },\r\n ...crudRequest,\r\n };\r\n}\r\n\r\n/**\r\n * Creates a GetManyResult object\r\n *\r\n * @param data The entity list to be returned\r\n * @param total The total amount of entities in the database\r\n * @param offset The offset used for querying\r\n * @param limit The limit used for querying\r\n */\r\nexport function createGetManyResult<T>(data: T[], total: number, offset: number, limit?: number): GetManyResult<T> {\r\n const count = data.length;\r\n const actualLimit = limit ?? total;\r\n const page = actualLimit > 0 ? Math.floor(offset / actualLimit) + 1 : 1;\r\n const pageCount = actualLimit > 0 ? Math.ceil(total / actualLimit) : 0;\r\n\r\n return {\r\n data,\r\n count,\r\n total,\r\n page,\r\n pageCount,\r\n };\r\n}\r\n"],"mappings":"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","names":["GetItemCommand","QueryCommand","ScanCommand","marshall","unmarshall","ensureArray","fieldName","data","minLength","__name","ensureEmpty","isValid","value","pathParse","value","__name","pathEquals","path1","path2","p1","i","createGetManyResult","data","total","offset","limit","count","actualLimit","page","pageCount","__name","DynamoDBQueryAdapter","options","pathParse","__name","baseQuery","request","full","input","data","total","limit","createGetManyResult","query","ctx","scan","baseInput","mapResult","type","count","operation","mixed","fetchCount","result","GetItemCommand","shouldFetchCount","output","QueryCommand","item","ScanCommand","keys","hasPartitionKeyEq","hasSortKeyEq","where","isEq","pathEquals","condition","key","select","existing","exp","attributes","f","order","sortKey","sort","o","filter","existingFilter","isTopLevelAnd","field","param","value","arr","ensureArray","_","i","prev","val","ensureEmpty","fieldName","baseName","attributeName","interaction","names","name","iteration","expression","marshall","unmarshall"]}
@@ -0,0 +1,163 @@
1
+ import { Filter, Condition, FindCursor, Collection, Document, WithId } from 'mongodb';
2
+ import { Q as QueryAdapter, G as GetManyResult } from '../../query-adapter-sgeUb8CV.mjs';
3
+ import { C as CrudRequest, d as CrudRequestWhere, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType } from '../../crud-request-DLo0ZuzD.mjs';
4
+ import { Query, HydratedDocument } from 'mongoose';
5
+
6
+ declare abstract class BaseMongoQueryAdapter {
7
+ /**
8
+ * Adapts the query select list into a MongoDB projection
9
+ *
10
+ * @param crudRequest The crud request
11
+ */
12
+ buildProjection(crudRequest: CrudRequest): Record<string, true>;
13
+ /**
14
+ * Adapts the query order into a MongoDB sort order
15
+ *
16
+ * @param crudRequest The crud request
17
+ */
18
+ buildSort(crudRequest: CrudRequest): [string, -1 | 1][];
19
+ /**
20
+ * Adapts the query offset, page and limit into the MongoDB skip
21
+ *
22
+ * @param crudRequest The crud request
23
+ */
24
+ buildSkip(crudRequest: CrudRequest): number;
25
+ /**
26
+ * Adapts the query where conditions into a MongoDB filter
27
+ *
28
+ * @param crudRequest The crud request
29
+ */
30
+ buildFilter<E>(crudRequest: CrudRequest): Filter<E>;
31
+ /**
32
+ * Maps the where condition into a cursor filter
33
+ *
34
+ * @param where The where condition
35
+ */
36
+ protected mapFilter<E>(where: CrudRequestWhere): Filter<E>;
37
+ /**
38
+ * Maps the query operator into a cursor condition operator
39
+ *
40
+ * @param operator The condition operator
41
+ * @param value The condition value
42
+ */
43
+ protected mapCondition(operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType | CrudRequestWhereValueType[]): Condition<any>;
44
+ }
45
+
46
+ interface MongoQueryAdapterOptions {
47
+ /**
48
+ * Whether you want to disable the fetching the total in `getMany()`
49
+ */
50
+ disableCount?: boolean;
51
+ }
52
+ declare class MongoDBQueryAdapter extends BaseMongoQueryAdapter implements QueryAdapter<FindCursor | Collection, Document> {
53
+ private readonly options;
54
+ constructor(options?: MongoQueryAdapterOptions);
55
+ /**
56
+ * @inheritDoc
57
+ */
58
+ build<E extends Document>(base: FindCursor<WithId<E>> | Collection<E>, request: CrudRequest): FindCursor<WithId<E>>;
59
+ /**
60
+ * @inheritDoc
61
+ */
62
+ getMany<E extends Document>(base: FindCursor<E> | Collection<E>, request: CrudRequest): Promise<GetManyResult<WithId<E>>>;
63
+ /**
64
+ * @inheritDoc
65
+ */
66
+ getOne<E extends Document>(base: FindCursor<E> | Collection<E>, request: CrudRequest): Promise<WithId<E> | null>;
67
+ /**
68
+ * Fetches the count from a cursor or a collection
69
+ *
70
+ * @param base The cursor or collection
71
+ * @param cursor The actual cursor
72
+ * @param filter The filter
73
+ */
74
+ protected getCount<E extends Document>(base: FindCursor<E> | Collection<E>, cursor: FindCursor<WithId<E>>, filter: Filter<E>): Promise<number>;
75
+ /**
76
+ * Adapts the query select list into a projection
77
+ *
78
+ * @param cursor The cursor
79
+ * @param crudRequest The request
80
+ */
81
+ protected adaptProjection<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): void;
82
+ /**
83
+ * Adapts the query order into a sort order
84
+ *
85
+ * @param cursor The cursor
86
+ * @param crudRequest The request
87
+ */
88
+ protected adaptSort<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): void;
89
+ /**
90
+ * Adapts the query offset and limit into the cursor skip and limit
91
+ *
92
+ * @param cursor The cursor
93
+ * @param crudRequest The request
94
+ */
95
+ protected adaptSkipAndLimit<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): [number, number?];
96
+ /**
97
+ * Adapts the query where conditions into a cursor filter
98
+ *
99
+ * @param cursor The cursor
100
+ * @param crudRequest The request
101
+ */
102
+ protected adaptFilter<E>(cursor: FindCursor<WithId<E>>, crudRequest: CrudRequest): Filter<E>;
103
+ }
104
+
105
+ interface MongooseQueryAdapterOptions {
106
+ /**
107
+ * Whether you want to disable the fetching the total count in `getMany()`
108
+ */
109
+ disableCount?: boolean;
110
+ }
111
+ type MongooseQuery = Query<any, any>;
112
+ declare class MongooseQueryAdapter extends BaseMongoQueryAdapter implements QueryAdapter<Query<any, any>, HydratedDocument<any>> {
113
+ private readonly options;
114
+ constructor(options?: MongooseQueryAdapterOptions);
115
+ /**
116
+ * @inheritDoc
117
+ */
118
+ build<E extends HydratedDocument<any>, Q extends Query<any, E>>(baseQuery: Q, request: CrudRequest): Q;
119
+ /**
120
+ * @inheritDoc
121
+ */
122
+ getMany<E extends HydratedDocument<any>>(baseQuery: Query<any, E>, request: CrudRequest): Promise<GetManyResult<E>>;
123
+ /**
124
+ * @inheritDoc
125
+ */
126
+ getOne<E extends HydratedDocument<any>>(baseQuery: Query<any, E>, request: CrudRequest): Promise<E | null>;
127
+ /**
128
+ * Fetches the count from a query
129
+ *
130
+ * @param query The query
131
+ */
132
+ protected getCount(query: MongooseQuery): Promise<number>;
133
+ /**
134
+ * Adapts the request select list into a projection
135
+ *
136
+ * @param query The query
137
+ * @param crudRequest The request
138
+ */
139
+ protected adaptProjection(query: MongooseQuery, crudRequest: CrudRequest): void;
140
+ /**
141
+ * Adapts the request order into a sort order
142
+ *
143
+ * @param query The query
144
+ * @param crudRequest The request
145
+ */
146
+ protected adaptSort(query: MongooseQuery, crudRequest: CrudRequest): void;
147
+ /**
148
+ * Adapts the request offset and limit into the cursor skip and limit
149
+ *
150
+ * @param query The query
151
+ * @param crudRequest The request
152
+ */
153
+ protected adaptSkipAndLimit(query: MongooseQuery, crudRequest: CrudRequest): [number, number?];
154
+ /**
155
+ * Adapts the request where conditions into a query where
156
+ *
157
+ * @param query The query
158
+ * @param crudRequest The request
159
+ */
160
+ protected adaptFilter(query: MongooseQuery, crudRequest: CrudRequest): void;
161
+ }
162
+
163
+ export { MongoDBQueryAdapter, type MongoQueryAdapterOptions, MongooseQueryAdapter, type MongooseQueryAdapterOptions };
@@ -0,0 +1,163 @@
1
+ import { Filter, Condition, FindCursor, Collection, Document, WithId } from 'mongodb';
2
+ import { Q as QueryAdapter, G as GetManyResult } from '../../query-adapter-CZhPC1aq.js';
3
+ import { C as CrudRequest, d as CrudRequestWhere, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType } from '../../crud-request-DLo0ZuzD.js';
4
+ import { Query, HydratedDocument } from 'mongoose';
5
+
6
+ declare abstract class BaseMongoQueryAdapter {
7
+ /**
8
+ * Adapts the query select list into a MongoDB projection
9
+ *
10
+ * @param crudRequest The crud request
11
+ */
12
+ buildProjection(crudRequest: CrudRequest): Record<string, true>;
13
+ /**
14
+ * Adapts the query order into a MongoDB sort order
15
+ *
16
+ * @param crudRequest The crud request
17
+ */
18
+ buildSort(crudRequest: CrudRequest): [string, -1 | 1][];
19
+ /**
20
+ * Adapts the query offset, page and limit into the MongoDB skip
21
+ *
22
+ * @param crudRequest The crud request
23
+ */
24
+ buildSkip(crudRequest: CrudRequest): number;
25
+ /**
26
+ * Adapts the query where conditions into a MongoDB filter
27
+ *
28
+ * @param crudRequest The crud request
29
+ */
30
+ buildFilter<E>(crudRequest: CrudRequest): Filter<E>;
31
+ /**
32
+ * Maps the where condition into a cursor filter
33
+ *
34
+ * @param where The where condition
35
+ */
36
+ protected mapFilter<E>(where: CrudRequestWhere): Filter<E>;
37
+ /**
38
+ * Maps the query operator into a cursor condition operator
39
+ *
40
+ * @param operator The condition operator
41
+ * @param value The condition value
42
+ */
43
+ protected mapCondition(operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType | CrudRequestWhereValueType[]): Condition<any>;
44
+ }
45
+
46
+ interface MongoQueryAdapterOptions {
47
+ /**
48
+ * Whether you want to disable the fetching the total in `getMany()`
49
+ */
50
+ disableCount?: boolean;
51
+ }
52
+ declare class MongoDBQueryAdapter extends BaseMongoQueryAdapter implements QueryAdapter<FindCursor | Collection, Document> {
53
+ private readonly options;
54
+ constructor(options?: MongoQueryAdapterOptions);
55
+ /**
56
+ * @inheritDoc
57
+ */
58
+ build<E extends Document>(base: FindCursor<WithId<E>> | Collection<E>, request: CrudRequest): FindCursor<WithId<E>>;
59
+ /**
60
+ * @inheritDoc
61
+ */
62
+ getMany<E extends Document>(base: FindCursor<E> | Collection<E>, request: CrudRequest): Promise<GetManyResult<WithId<E>>>;
63
+ /**
64
+ * @inheritDoc
65
+ */
66
+ getOne<E extends Document>(base: FindCursor<E> | Collection<E>, request: CrudRequest): Promise<WithId<E> | null>;
67
+ /**
68
+ * Fetches the count from a cursor or a collection
69
+ *
70
+ * @param base The cursor or collection
71
+ * @param cursor The actual cursor
72
+ * @param filter The filter
73
+ */
74
+ protected getCount<E extends Document>(base: FindCursor<E> | Collection<E>, cursor: FindCursor<WithId<E>>, filter: Filter<E>): Promise<number>;
75
+ /**
76
+ * Adapts the query select list into a projection
77
+ *
78
+ * @param cursor The cursor
79
+ * @param crudRequest The request
80
+ */
81
+ protected adaptProjection<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): void;
82
+ /**
83
+ * Adapts the query order into a sort order
84
+ *
85
+ * @param cursor The cursor
86
+ * @param crudRequest The request
87
+ */
88
+ protected adaptSort<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): void;
89
+ /**
90
+ * Adapts the query offset and limit into the cursor skip and limit
91
+ *
92
+ * @param cursor The cursor
93
+ * @param crudRequest The request
94
+ */
95
+ protected adaptSkipAndLimit<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): [number, number?];
96
+ /**
97
+ * Adapts the query where conditions into a cursor filter
98
+ *
99
+ * @param cursor The cursor
100
+ * @param crudRequest The request
101
+ */
102
+ protected adaptFilter<E>(cursor: FindCursor<WithId<E>>, crudRequest: CrudRequest): Filter<E>;
103
+ }
104
+
105
+ interface MongooseQueryAdapterOptions {
106
+ /**
107
+ * Whether you want to disable the fetching the total count in `getMany()`
108
+ */
109
+ disableCount?: boolean;
110
+ }
111
+ type MongooseQuery = Query<any, any>;
112
+ declare class MongooseQueryAdapter extends BaseMongoQueryAdapter implements QueryAdapter<Query<any, any>, HydratedDocument<any>> {
113
+ private readonly options;
114
+ constructor(options?: MongooseQueryAdapterOptions);
115
+ /**
116
+ * @inheritDoc
117
+ */
118
+ build<E extends HydratedDocument<any>, Q extends Query<any, E>>(baseQuery: Q, request: CrudRequest): Q;
119
+ /**
120
+ * @inheritDoc
121
+ */
122
+ getMany<E extends HydratedDocument<any>>(baseQuery: Query<any, E>, request: CrudRequest): Promise<GetManyResult<E>>;
123
+ /**
124
+ * @inheritDoc
125
+ */
126
+ getOne<E extends HydratedDocument<any>>(baseQuery: Query<any, E>, request: CrudRequest): Promise<E | null>;
127
+ /**
128
+ * Fetches the count from a query
129
+ *
130
+ * @param query The query
131
+ */
132
+ protected getCount(query: MongooseQuery): Promise<number>;
133
+ /**
134
+ * Adapts the request select list into a projection
135
+ *
136
+ * @param query The query
137
+ * @param crudRequest The request
138
+ */
139
+ protected adaptProjection(query: MongooseQuery, crudRequest: CrudRequest): void;
140
+ /**
141
+ * Adapts the request order into a sort order
142
+ *
143
+ * @param query The query
144
+ * @param crudRequest The request
145
+ */
146
+ protected adaptSort(query: MongooseQuery, crudRequest: CrudRequest): void;
147
+ /**
148
+ * Adapts the request offset and limit into the cursor skip and limit
149
+ *
150
+ * @param query The query
151
+ * @param crudRequest The request
152
+ */
153
+ protected adaptSkipAndLimit(query: MongooseQuery, crudRequest: CrudRequest): [number, number?];
154
+ /**
155
+ * Adapts the request where conditions into a query where
156
+ *
157
+ * @param query The query
158
+ * @param crudRequest The request
159
+ */
160
+ protected adaptFilter(query: MongooseQuery, crudRequest: CrudRequest): void;
161
+ }
162
+
163
+ export { MongoDBQueryAdapter, type MongoQueryAdapterOptions, MongooseQueryAdapter, type MongooseQueryAdapterOptions };
@@ -0,0 +1,2 @@
1
+ "use strict";var l=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var u=(o,n)=>l(o,"name",{value:n,configurable:!0});var h=(o,n)=>{for(var t in n)l(o,t,{get:n[t],enumerable:!0})},S=(o,n,t,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of R(n))!b.call(o,r)&&r!==t&&l(o,r,{get:()=>n[r],enumerable:!(e=C(n,r))||e.enumerable});return o};var $=o=>S(l({},"__esModule",{value:!0}),o);var x={};h(x,{MongoDBQueryAdapter:()=>g,MongooseQueryAdapter:()=>T});module.exports=$(x);function s(o,n){if(typeof n=="string")return n;throw new Error(`${o} must be a string`)}u(s,"ensureString");function m(o,n,t=0){if(!Array.isArray(n)||n.length<t)throw new Error(`${o} must be an array with at least ${t} items`);return n}u(m,"ensureArray");function N(o,n,t){return o??(n&&t?n*(t-1):0)}u(N,"getOffset");function a(o){return o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}u(a,"escapeRegex");var d=class{static{u(this,"BaseMongoQueryAdapter")}buildProjection(n){return n.select.reduce((t,e)=>(t[e.field.join(".")]=!0,t),{})}buildSort(n){return n.order.map(t=>[t.field.join("."),t.order==="DESC"?-1:1])}buildSkip(n){return N(n.offset,n.limit,n.page)}buildFilter(n){return this.mapFilter(n.where)}mapFilter(n){return n.and&&n.and.length>0?{$and:n.and.map(t=>this.mapFilter(t))}:n.or&&n.or.length>0?{$or:n.or.map(t=>this.mapFilter(t))}:n.field?{[n.field.join(".")]:this.mapCondition(n.operator,n.value)}:{}}mapCondition(n,t){switch(n){case"eq":return t;case"neq":return{$ne:t};case"gt":return{$gt:t};case"gte":return{$gte:t};case"lt":return{$lt:t};case"lte":return{$lte:t};case"in":return{$in:t};case"not_in":return{$nin:t};case"is_null":return{$eq:null};case"not_null":return{$ne:null};case"between":let e=m("BETWEEN operator",t,2);return{$gte:e[0],$lte:e[1]};case"contains":return{$regex:a(s("CONTAINS operator",t))};case"not_contains":return{$not:{$regex:a(s("CONTAINS operator",t))}};case"starts":return{$regex:"^"+a(s("STARTS operator",t))};case"ends":return{$regex:a(s("ENDS operator",t))+"$"};case"eq_lower":return{$regex:"^"+a(s("EQ LOWER operator",t))+"$",$options:"i"};case"neq_lower":return{$not:{$regex:"^"+a(s("NEQ LOWER operator",t))+"$",$options:"i"}};case"contains_lower":return{$regex:a(s("CONTAINS LOWER operator",t)),$options:"i"};case"not_contains_lower":return{$not:{$regex:a(s("NOT CONTAINS LOWER operator",t)),$options:"i"}};case"starts_lower":return{$regex:"^"+a(s("STARTS LOWER operator",t)),$options:"i"};case"ends_lower":return{$regex:a(s("ENDS LOWER operator",t))+"$",$options:"i"};case"in_lower":return{$in:m("IN LOWER operator",t,1).map((r,i)=>({$regex:"^"+a(s(`IN LOWER [${i}] operator`,r))+"$",$options:"i"}))};case"not_in_lower":return{$nin:m("NOT IN LOWER operator",t,1).map((r,i)=>({$regex:"^"+a(s(`NOT IN LOWER [${i}] operator`,r))+"$",$options:"i"}))}}throw new Error(`Unsupported operator ${n}.`)}};function f(o,n,t,e){let r=o.length,i=e??n,p=i>0?Math.floor(t/i)+1:1,c=i>0?Math.ceil(n/i):0;return{data:o,count:r,total:n,page:p,pageCount:c}}u(f,"createGetManyResult");var g=class extends d{constructor(t={}){super();this.options=t}static{u(this,"MongoDBQueryAdapter")}build(t,e){let r="find"in t?t.find():t;return this.adaptFilter(r,e),this.adaptProjection(r,e),this.adaptSort(r,e),this.adaptSkipAndLimit(r,e),r}async getMany(t,e){let r="find"in t?t.find():t,i=this.adaptFilter(r,e),p=await this.getCount(t,r,i);this.adaptProjection(r,e),this.adaptSort(r,e);let[c,E]=this.adaptSkipAndLimit(r,e),y=await r.toArray();return f(y,p,c,E)}async getOne(t,e){let r="find"in t?t.find():t;return this.adaptFilter(r,e),this.adaptProjection(r,e),this.adaptSort(r,e),this.adaptSkipAndLimit(r,e),await r.next()}async getCount(t,e,r){return this.options.disableCount?0:"countDocuments"in t&&typeof t.countDocuments=="function"?await t.countDocuments(r):"count"in t&&typeof e.count=="function"?await e.count():0}adaptProjection(t,e){e.select.length!==0&&t.project(this.buildProjection(e))}adaptSort(t,e){e.order.length!==0&&t.sort(this.buildSort(e))}adaptSkipAndLimit(t,e){let r=this.buildSkip(e),i=e.limit;return r&&t.skip(r),i&&t.limit(i),[r,i]}adaptFilter(t,e){let r=this.buildFilter(e);return t.filter(r),r}};var T=class extends d{constructor(t={}){super();this.options=t}static{u(this,"MongooseQueryAdapter")}build(t,e){let r=t.clone();return this.adaptFilter(r,e),this.adaptProjection(r,e),this.adaptSort(r,e),this.adaptSkipAndLimit(r,e),r}async getMany(t,e){let r=t.clone();this.adaptFilter(r,e);let i=r.clone();this.adaptProjection(r,e),this.adaptSort(r,e);let[p,c]=this.adaptSkipAndLimit(r,e),E=await this.getCount(i),y=await r.exec();return f(y,E,p,c)}async getOne(t,e){let r=t.clone();this.adaptFilter(r,e),this.adaptProjection(r,e),this.adaptSort(r,e);let i=await r.limit(1).exec();return i.length===0?null:i[0]}async getCount(t){return this.options.disableCount?0:t.countDocuments()}adaptProjection(t,e){e.select.length!==0&&t.projection(this.buildProjection(e))}adaptSort(t,e){e.order.length!==0&&t.sort(this.buildSort(e))}adaptSkipAndLimit(t,e){let r=this.buildSkip(e),i=e.limit;return r&&t.skip(r),i&&t.limit(i),[r,i]}adaptFilter(t,e){t.where(this.buildFilter(e))}};0&&(module.exports={MongoDBQueryAdapter,MongooseQueryAdapter});
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/mongodb/index.ts","../../../src/utils/functions.ts","../../../src/adapters/mongodb/base-mongo.query-adapter.ts","../../../src/utils/objects.ts","../../../src/adapters/mongodb/mongodb.query-adapter.ts","../../../src/adapters/mongodb/mongoose.query-adapter.ts"],"sourcesContent":["\r\nexport * from './mongodb.query-adapter';\r\nexport * from './mongoose.query-adapter';\r\n","export function ensurePrimitive(fieldName: string, data: any): number | string | boolean | Date {\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number or boolean`);\r\n}\r\n\r\nexport function ensurePrimitiveOrNull(fieldName: string, data: any): number | string | boolean | Date | undefined | null {\r\n if (data === null || data === undefined)\r\n return data;\r\n\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number, boolean or null`);\r\n}\r\n\r\nexport function ensureString(fieldName: string, data: any): string {\r\n if (typeof data === 'string')\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string`);\r\n}\r\n\r\nexport function ensureArray<T>(fieldName: string, data: T[] | any, minLength: number = 0): T[] {\r\n if (!Array.isArray(data) || data.length < minLength)\r\n throw new Error(`${fieldName} must be an array with at least ${minLength} items`);\r\n\r\n return data;\r\n}\r\n\r\nexport function ensureEmpty(fieldName: string, data: any) {\r\n if (isValid(data) && data !== true)\r\n throw new Error(`${fieldName} must be true, null or undefined`);\r\n}\r\n\r\nexport function isValid<T>(value: T | undefined | null): value is T {\r\n return value !== null && value !== undefined;\r\n}\r\n\r\nexport function getOffset(offset: number | undefined, limit?: number, page?: number): number {\r\n return offset ?? (limit && page ? limit * (page - 1) : 0);\r\n}\r\n\r\nexport interface Type<T> extends Function { new (... args: any[]): T; }\r\n\r\nexport function createInstance<T extends object>(clazzOrInstance: T | Type<T> | undefined): T | undefined {\r\n if (typeof clazzOrInstance === 'function')\r\n return new clazzOrInstance();\r\n\r\n if (typeof clazzOrInstance === 'object')\r\n return clazzOrInstance as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n","import type { Condition, Filter } from 'mongodb';\r\nimport { CrudRequest } from '../../models/crud-request';\r\nimport { CrudRequestWhere, CrudRequestWhereOperator, CrudRequestWhereValueType } from '../../models/crud-request-where';\r\nimport { ensureArray, ensureString, escapeRegex, getOffset } from '../../utils/functions';\r\n\r\nexport abstract class BaseMongoQueryAdapter {\r\n\r\n /**\r\n * Adapts the query select list into a MongoDB projection\r\n *\r\n * @param crudRequest The crud request\r\n */\r\n public buildProjection(crudRequest: CrudRequest): Record<string, true> {\r\n return crudRequest.select.reduce<Record<string, true>>((obj, item) => {\r\n obj[item.field.join('.')] = true;\r\n\r\n return obj;\r\n }, {});\r\n }\r\n\r\n /**\r\n * Adapts the query order into a MongoDB sort order\r\n *\r\n * @param crudRequest The crud request\r\n */\r\n public buildSort(crudRequest: CrudRequest): [string, -1 | 1][] {\r\n return crudRequest.order.map<[string, -1 | 1]>(\r\n item => [item.field.join('.'), item.order === 'DESC' ? -1 : 1],\r\n );\r\n }\r\n\r\n /**\r\n * Adapts the query offset, page and limit into the MongoDB skip\r\n *\r\n * @param crudRequest The crud request\r\n */\r\n public buildSkip(crudRequest: CrudRequest): number {\r\n return getOffset(crudRequest.offset, crudRequest.limit, crudRequest.page);\r\n }\r\n\r\n /**\r\n * Adapts the query where conditions into a MongoDB filter\r\n *\r\n * @param crudRequest The crud request\r\n */\r\n public buildFilter<E>(crudRequest: CrudRequest): Filter<E> {\r\n return this.mapFilter<E>(crudRequest.where);\r\n }\r\n\r\n /**\r\n * Maps the where condition into a cursor filter\r\n *\r\n * @param where The where condition\r\n */\r\n protected mapFilter<E>(where: CrudRequestWhere): Filter<E> {\r\n if (where.and && where.and.length > 0) {\r\n return { $and: where.and.map(item => this.mapFilter(item)) };\r\n }\r\n\r\n if (where.or && where.or.length > 0) {\r\n return { $or: where.or.map(item => this.mapFilter(item)) };\r\n }\r\n\r\n if (where.field) {\r\n return { [where.field.join('.') as any]: this.mapCondition(where.operator, where.value) };\r\n }\r\n\r\n return {};\r\n }\r\n\r\n /**\r\n * Maps the query operator into a cursor condition operator\r\n *\r\n * @param operator The condition operator\r\n * @param value The condition value\r\n */\r\n protected mapCondition(\r\n operator: CrudRequestWhereOperator,\r\n value: CrudRequestWhereValueType | CrudRequestWhereValueType[],\r\n ): Condition<any> {\r\n switch (operator) {\r\n case CrudRequestWhereOperator.EQ:\r\n return value;\r\n\r\n case CrudRequestWhereOperator.NEQ:\r\n return { $ne: value };\r\n\r\n case CrudRequestWhereOperator.GT:\r\n return { $gt: value };\r\n\r\n case CrudRequestWhereOperator.GTE:\r\n return { $gte: value };\r\n\r\n case CrudRequestWhereOperator.LT:\r\n return { $lt: value };\r\n\r\n case CrudRequestWhereOperator.LTE:\r\n return { $lte: value };\r\n\r\n case CrudRequestWhereOperator.IN:\r\n return { $in: value };\r\n\r\n case CrudRequestWhereOperator.NOT_IN:\r\n return { $nin: value };\r\n\r\n case CrudRequestWhereOperator.IS_NULL:\r\n return { $eq: null };\r\n\r\n case CrudRequestWhereOperator.NOT_NULL:\r\n return { $ne: null };\r\n\r\n case CrudRequestWhereOperator.BETWEEN:\r\n const arr = ensureArray('BETWEEN operator', value, 2);\r\n\r\n return { $gte: arr[0], $lte: arr[1] };\r\n\r\n case CrudRequestWhereOperator.CONTAINS:\r\n return { $regex: escapeRegex(ensureString('CONTAINS operator', value)) };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS:\r\n return { $not: { $regex: escapeRegex(ensureString('CONTAINS operator', value)) } };\r\n\r\n case CrudRequestWhereOperator.STARTS:\r\n return { $regex: '^' + escapeRegex(ensureString('STARTS operator', value)) };\r\n\r\n case CrudRequestWhereOperator.ENDS:\r\n return { $regex: escapeRegex(ensureString('ENDS operator', value)) + '$' };\r\n\r\n case CrudRequestWhereOperator.EQ_LOWER:\r\n return { $regex: '^' + escapeRegex(ensureString('EQ LOWER operator', value)) + '$', $options: 'i' };\r\n\r\n case CrudRequestWhereOperator.NEQ_LOWER:\r\n return { $not: { $regex: '^' + escapeRegex(ensureString('NEQ LOWER operator', value)) + '$', $options: 'i' } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS_LOWER:\r\n return { $regex: escapeRegex(ensureString('CONTAINS LOWER operator', value)), $options: 'i' };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS_LOWER:\r\n return { $not: { $regex: escapeRegex(ensureString('NOT CONTAINS LOWER operator', value)), $options: 'i' } };\r\n\r\n case CrudRequestWhereOperator.STARTS_LOWER:\r\n return { $regex: '^' + escapeRegex(ensureString('STARTS LOWER operator', value)), $options: 'i' };\r\n\r\n case CrudRequestWhereOperator.ENDS_LOWER:\r\n return { $regex: escapeRegex(ensureString('ENDS LOWER operator', value)) + '$', $options: 'i' };\r\n\r\n case CrudRequestWhereOperator.IN_LOWER:\r\n return {\r\n $in: ensureArray('IN LOWER operator', value, 1).map((item, i) => (\r\n { $regex: '^' + escapeRegex(ensureString(`IN LOWER [${i}] operator`, item)) + '$', $options: 'i' }\r\n )),\r\n };\r\n\r\n case CrudRequestWhereOperator.NOT_IN_LOWER:\r\n return {\r\n $nin: ensureArray('NOT IN LOWER operator', value, 1).map((item, i) => (\r\n { $regex: '^' + escapeRegex(ensureString(`NOT IN LOWER [${i}] operator`, item)) + '$', $options: 'i' }\r\n )),\r\n };\r\n }\r\n\r\n throw new Error(`Unsupported operator ${operator}.`);\r\n }\r\n\r\n}\r\n","import { GetManyResult } from '../models/get-many-result';\r\nimport { CrudRequest } from '../models/crud-request';\r\n\r\n/**\r\n * Creates a CrudRequest object, filling required missing properties with empty values\r\n */\r\nexport function createCrudRequest(crudRequest?: Partial<CrudRequest>): CrudRequest {\r\n return {\r\n select: [],\r\n relations: [],\r\n order: [],\r\n where: { and: [] },\r\n ...crudRequest,\r\n };\r\n}\r\n\r\n/**\r\n * Creates a GetManyResult object\r\n *\r\n * @param data The entity list to be returned\r\n * @param total The total amount of entities in the database\r\n * @param offset The offset used for querying\r\n * @param limit The limit used for querying\r\n */\r\nexport function createGetManyResult<T>(data: T[], total: number, offset: number, limit?: number): GetManyResult<T> {\r\n const count = data.length;\r\n const actualLimit = limit ?? total;\r\n const page = actualLimit > 0 ? Math.floor(offset / actualLimit) + 1 : 1;\r\n const pageCount = actualLimit > 0 ? Math.ceil(total / actualLimit) : 0;\r\n\r\n return {\r\n data,\r\n count,\r\n total,\r\n page,\r\n pageCount,\r\n };\r\n}\r\n","import type { Collection, Document, Filter, FindCursor, WithId } from 'mongodb';\r\nimport { QueryAdapter } from '../../models/query-adapter';\r\nimport { CrudRequest } from '../../models/crud-request';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { BaseMongoQueryAdapter } from './base-mongo.query-adapter';\r\nimport { createGetManyResult } from '../../utils/objects';\r\n\r\nexport interface MongoQueryAdapterOptions {\r\n /**\r\n * Whether you want to disable the fetching the total in `getMany()`\r\n */\r\n disableCount?: boolean;\r\n}\r\n\r\nexport class MongoDBQueryAdapter extends BaseMongoQueryAdapter implements QueryAdapter<FindCursor | Collection, Document> {\r\n\r\n constructor(\r\n private readonly options: MongoQueryAdapterOptions = {},\r\n ) {\r\n super();\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build<E extends Document>(base: FindCursor<WithId<E>> | Collection<E>, request: CrudRequest): FindCursor<WithId<E>> {\r\n const cursor = 'find' in base ? base.find() : base;\r\n\r\n this.adaptFilter(cursor, request);\r\n this.adaptProjection(cursor, request);\r\n this.adaptSort(cursor, request);\r\n this.adaptSkipAndLimit(cursor, request);\r\n\r\n return cursor;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E extends Document>(base: FindCursor<E> | Collection<E>, request: CrudRequest): Promise<GetManyResult<WithId<E>>> {\r\n const cursor = 'find' in base ? base.find() : base as FindCursor<WithId<E>>;\r\n\r\n const filter = this.adaptFilter<E>(cursor, request);\r\n\r\n const total = await this.getCount<E>(base, cursor, filter);\r\n\r\n this.adaptProjection(cursor, request);\r\n this.adaptSort(cursor, request);\r\n\r\n const [skip, limit] = this.adaptSkipAndLimit(cursor, request);\r\n\r\n const data = await cursor.toArray();\r\n\r\n return createGetManyResult(data, total, skip, limit);\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E extends Document>(base: FindCursor<E> | Collection<E>, request: CrudRequest): Promise<WithId<E> | null> {\r\n const cursor = 'find' in base ? base.find() : base as FindCursor<WithId<E>>;\r\n\r\n this.adaptFilter(cursor, request);\r\n this.adaptProjection(cursor, request);\r\n this.adaptSort(cursor, request);\r\n this.adaptSkipAndLimit(cursor, request);\r\n\r\n return await cursor.next();\r\n }\r\n\r\n /**\r\n * Fetches the count from a cursor or a collection\r\n *\r\n * @param base The cursor or collection\r\n * @param cursor The actual cursor\r\n * @param filter The filter\r\n */\r\n protected async getCount<E extends Document>(base: FindCursor<E> | Collection<E>, cursor: FindCursor<WithId<E>>, filter: Filter<E>): Promise<number> {\r\n if (this.options.disableCount)\r\n return 0;\r\n\r\n if ('countDocuments' in base && typeof base.countDocuments === 'function')\r\n return await base.countDocuments(filter);\r\n\r\n if ('count' in base && typeof cursor.count === 'function')\r\n return await cursor.count();\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Adapts the query select list into a projection\r\n *\r\n * @param cursor The cursor\r\n * @param crudRequest The request\r\n */\r\n protected adaptProjection<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): void {\r\n if (crudRequest.select.length === 0)\r\n return;\r\n\r\n cursor.project(this.buildProjection(crudRequest));\r\n }\r\n\r\n /**\r\n * Adapts the query order into a sort order\r\n *\r\n * @param cursor The cursor\r\n * @param crudRequest The request\r\n */\r\n protected adaptSort<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): void {\r\n if (crudRequest.order.length === 0)\r\n return;\r\n\r\n cursor.sort(this.buildSort(crudRequest));\r\n }\r\n\r\n /**\r\n * Adapts the query offset and limit into the cursor skip and limit\r\n *\r\n * @param cursor The cursor\r\n * @param crudRequest The request\r\n */\r\n protected adaptSkipAndLimit<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): [number, number?] {\r\n const skip = this.buildSkip(crudRequest);\r\n const limit = crudRequest.limit;\r\n\r\n if (skip)\r\n cursor.skip(skip);\r\n\r\n if (limit)\r\n cursor.limit(limit);\r\n\r\n return [skip, limit];\r\n }\r\n\r\n /**\r\n * Adapts the query where conditions into a cursor filter\r\n *\r\n * @param cursor The cursor\r\n * @param crudRequest The request\r\n */\r\n protected adaptFilter<E>(cursor: FindCursor<WithId<E>>, crudRequest: CrudRequest): Filter<E> {\r\n const filter = this.buildFilter<E>(crudRequest);\r\n\r\n cursor.filter(filter);\r\n\r\n return filter;\r\n }\r\n\r\n}\r\n","import type { HydratedDocument, Query } from 'mongoose';\r\nimport { QueryAdapter } from '../../models/query-adapter';\r\nimport { CrudRequest } from '../../models/crud-request';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { BaseMongoQueryAdapter } from './base-mongo.query-adapter';\r\nimport { createGetManyResult } from '../../utils/objects';\r\n\r\nexport interface MongooseQueryAdapterOptions {\r\n /**\r\n * Whether you want to disable the fetching the total count in `getMany()`\r\n */\r\n disableCount?: boolean;\r\n}\r\n\r\ntype MongooseQuery = Query<any, any>;\r\n\r\nexport class MongooseQueryAdapter extends BaseMongoQueryAdapter implements QueryAdapter<Query<any, any>, HydratedDocument<any>> {\r\n\r\n constructor(\r\n private readonly options: MongooseQueryAdapterOptions = {},\r\n ) {\r\n super();\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build<E extends HydratedDocument<any>, Q extends Query<any, E>>(baseQuery: Q, request: CrudRequest): Q {\r\n const query = baseQuery.clone();\r\n\r\n this.adaptFilter(query, request);\r\n this.adaptProjection(query, request);\r\n this.adaptSort(query, request);\r\n this.adaptSkipAndLimit(query, request);\r\n\r\n return query;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E extends HydratedDocument<any>>(baseQuery: Query<any, E>, request: CrudRequest): Promise<GetManyResult<E>> {\r\n const query = baseQuery.clone();\r\n\r\n this.adaptFilter(query, request);\r\n\r\n const countQuery = query.clone();\r\n\r\n this.adaptProjection(query, request);\r\n this.adaptSort(query, request);\r\n\r\n const [skip, limit] = this.adaptSkipAndLimit(query, request);\r\n\r\n const total = await this.getCount(countQuery);\r\n const data = await query.exec();\r\n\r\n return createGetManyResult(data, total, skip, limit);\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E extends HydratedDocument<any>>(baseQuery: Query<any, E>, request: CrudRequest): Promise<E | null> {\r\n const query = baseQuery.clone();\r\n\r\n this.adaptFilter(query, request);\r\n this.adaptProjection(query, request);\r\n this.adaptSort(query, request);\r\n\r\n const entities = await query.limit(1).exec();\r\n\r\n if (entities.length === 0)\r\n return null;\r\n\r\n return entities[0];\r\n }\r\n\r\n /**\r\n * Fetches the count from a query\r\n *\r\n * @param query The query\r\n */\r\n protected async getCount(query: MongooseQuery): Promise<number> {\r\n if (this.options.disableCount)\r\n return 0;\r\n\r\n return query.countDocuments();\r\n }\r\n\r\n /**\r\n * Adapts the request select list into a projection\r\n *\r\n * @param query The query\r\n * @param crudRequest The request\r\n */\r\n protected adaptProjection(query: MongooseQuery, crudRequest: CrudRequest): void {\r\n if (crudRequest.select.length === 0)\r\n return;\r\n\r\n query.projection(this.buildProjection(crudRequest));\r\n }\r\n\r\n /**\r\n * Adapts the request order into a sort order\r\n *\r\n * @param query The query\r\n * @param crudRequest The request\r\n */\r\n protected adaptSort(query: MongooseQuery, crudRequest: CrudRequest): void {\r\n if (crudRequest.order.length === 0)\r\n return;\r\n\r\n query.sort(this.buildSort(crudRequest));\r\n }\r\n\r\n /**\r\n * Adapts the request offset and limit into the cursor skip and limit\r\n *\r\n * @param query The query\r\n * @param crudRequest The request\r\n */\r\n protected adaptSkipAndLimit(query: MongooseQuery, crudRequest: CrudRequest): [number, number?] {\r\n const skip = this.buildSkip(crudRequest);\r\n const limit = crudRequest.limit;\r\n\r\n if (skip)\r\n query.skip(skip);\r\n\r\n if (limit)\r\n query.limit(limit);\r\n\r\n return [skip, limit];\r\n }\r\n\r\n /**\r\n * Adapts the request where conditions into a query where\r\n *\r\n * @param query The query\r\n * @param crudRequest The request\r\n */\r\n protected adaptFilter(query: MongooseQuery, crudRequest: CrudRequest): void {\r\n query.where(this.buildFilter(crudRequest));\r\n }\r\n\r\n}\r\n"],"mappings":"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","names":["mongodb_exports","__export","MongoDBQueryAdapter","MongooseQueryAdapter","__toCommonJS","ensureString","fieldName","data","__name","ensureArray","minLength","getOffset","offset","limit","page","__name","escapeRegex","str","__name","BaseMongoQueryAdapter","__name","crudRequest","obj","item","getOffset","where","operator","value","arr","ensureArray","escapeRegex","ensureString","createGetManyResult","data","total","offset","limit","count","actualLimit","page","pageCount","__name","MongoDBQueryAdapter","BaseMongoQueryAdapter","options","__name","base","request","cursor","filter","total","skip","limit","data","createGetManyResult","crudRequest","MongooseQueryAdapter","BaseMongoQueryAdapter","options","__name","baseQuery","request","query","countQuery","skip","limit","total","data","createGetManyResult","entities","crudRequest"]}
@@ -0,0 +1,2 @@
1
+ var N=Object.defineProperty;var u=(i,n)=>N(i,"name",{value:n,configurable:!0});function s(i,n){if(typeof n=="string")return n;throw new Error(`${i} must be a string`)}u(s,"ensureString");function l(i,n,t=0){if(!Array.isArray(n)||n.length<t)throw new Error(`${i} must be an array with at least ${t} items`);return n}u(l,"ensureArray");function y(i,n,t){return i??(n&&t?n*(t-1):0)}u(y,"getOffset");function a(i){return i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}u(a,"escapeRegex");var d=class{static{u(this,"BaseMongoQueryAdapter")}buildProjection(n){return n.select.reduce((t,e)=>(t[e.field.join(".")]=!0,t),{})}buildSort(n){return n.order.map(t=>[t.field.join("."),t.order==="DESC"?-1:1])}buildSkip(n){return y(n.offset,n.limit,n.page)}buildFilter(n){return this.mapFilter(n.where)}mapFilter(n){return n.and&&n.and.length>0?{$and:n.and.map(t=>this.mapFilter(t))}:n.or&&n.or.length>0?{$or:n.or.map(t=>this.mapFilter(t))}:n.field?{[n.field.join(".")]:this.mapCondition(n.operator,n.value)}:{}}mapCondition(n,t){switch(n){case"eq":return t;case"neq":return{$ne:t};case"gt":return{$gt:t};case"gte":return{$gte:t};case"lt":return{$lt:t};case"lte":return{$lte:t};case"in":return{$in:t};case"not_in":return{$nin:t};case"is_null":return{$eq:null};case"not_null":return{$ne:null};case"between":let e=l("BETWEEN operator",t,2);return{$gte:e[0],$lte:e[1]};case"contains":return{$regex:a(s("CONTAINS operator",t))};case"not_contains":return{$not:{$regex:a(s("CONTAINS operator",t))}};case"starts":return{$regex:"^"+a(s("STARTS operator",t))};case"ends":return{$regex:a(s("ENDS operator",t))+"$"};case"eq_lower":return{$regex:"^"+a(s("EQ LOWER operator",t))+"$",$options:"i"};case"neq_lower":return{$not:{$regex:"^"+a(s("NEQ LOWER operator",t))+"$",$options:"i"}};case"contains_lower":return{$regex:a(s("CONTAINS LOWER operator",t)),$options:"i"};case"not_contains_lower":return{$not:{$regex:a(s("NOT CONTAINS LOWER operator",t)),$options:"i"}};case"starts_lower":return{$regex:"^"+a(s("STARTS LOWER operator",t)),$options:"i"};case"ends_lower":return{$regex:a(s("ENDS LOWER operator",t))+"$",$options:"i"};case"in_lower":return{$in:l("IN LOWER operator",t,1).map((r,o)=>({$regex:"^"+a(s(`IN LOWER [${o}] operator`,r))+"$",$options:"i"}))};case"not_in_lower":return{$nin:l("NOT IN LOWER operator",t,1).map((r,o)=>({$regex:"^"+a(s(`NOT IN LOWER [${o}] operator`,r))+"$",$options:"i"}))}}throw new Error(`Unsupported operator ${n}.`)}};function m(i,n,t,e){let r=i.length,o=e??n,p=o>0?Math.floor(t/o)+1:1,c=o>0?Math.ceil(n/o):0;return{data:i,count:r,total:n,page:p,pageCount:c}}u(m,"createGetManyResult");var g=class extends d{constructor(t={}){super();this.options=t}static{u(this,"MongoDBQueryAdapter")}build(t,e){let r="find"in t?t.find():t;return this.adaptFilter(r,e),this.adaptProjection(r,e),this.adaptSort(r,e),this.adaptSkipAndLimit(r,e),r}async getMany(t,e){let r="find"in t?t.find():t,o=this.adaptFilter(r,e),p=await this.getCount(t,r,o);this.adaptProjection(r,e),this.adaptSort(r,e);let[c,f]=this.adaptSkipAndLimit(r,e),E=await r.toArray();return m(E,p,c,f)}async getOne(t,e){let r="find"in t?t.find():t;return this.adaptFilter(r,e),this.adaptProjection(r,e),this.adaptSort(r,e),this.adaptSkipAndLimit(r,e),await r.next()}async getCount(t,e,r){return this.options.disableCount?0:"countDocuments"in t&&typeof t.countDocuments=="function"?await t.countDocuments(r):"count"in t&&typeof e.count=="function"?await e.count():0}adaptProjection(t,e){e.select.length!==0&&t.project(this.buildProjection(e))}adaptSort(t,e){e.order.length!==0&&t.sort(this.buildSort(e))}adaptSkipAndLimit(t,e){let r=this.buildSkip(e),o=e.limit;return r&&t.skip(r),o&&t.limit(o),[r,o]}adaptFilter(t,e){let r=this.buildFilter(e);return t.filter(r),r}};var T=class extends d{constructor(t={}){super();this.options=t}static{u(this,"MongooseQueryAdapter")}build(t,e){let r=t.clone();return this.adaptFilter(r,e),this.adaptProjection(r,e),this.adaptSort(r,e),this.adaptSkipAndLimit(r,e),r}async getMany(t,e){let r=t.clone();this.adaptFilter(r,e);let o=r.clone();this.adaptProjection(r,e),this.adaptSort(r,e);let[p,c]=this.adaptSkipAndLimit(r,e),f=await this.getCount(o),E=await r.exec();return m(E,f,p,c)}async getOne(t,e){let r=t.clone();this.adaptFilter(r,e),this.adaptProjection(r,e),this.adaptSort(r,e);let o=await r.limit(1).exec();return o.length===0?null:o[0]}async getCount(t){return this.options.disableCount?0:t.countDocuments()}adaptProjection(t,e){e.select.length!==0&&t.projection(this.buildProjection(e))}adaptSort(t,e){e.order.length!==0&&t.sort(this.buildSort(e))}adaptSkipAndLimit(t,e){let r=this.buildSkip(e),o=e.limit;return r&&t.skip(r),o&&t.limit(o),[r,o]}adaptFilter(t,e){t.where(this.buildFilter(e))}};export{g as MongoDBQueryAdapter,T as MongooseQueryAdapter};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/functions.ts","../../../src/adapters/mongodb/base-mongo.query-adapter.ts","../../../src/utils/objects.ts","../../../src/adapters/mongodb/mongodb.query-adapter.ts","../../../src/adapters/mongodb/mongoose.query-adapter.ts"],"sourcesContent":["export function ensurePrimitive(fieldName: string, data: any): number | string | boolean | Date {\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number or boolean`);\r\n}\r\n\r\nexport function ensurePrimitiveOrNull(fieldName: string, data: any): number | string | boolean | Date | undefined | null {\r\n if (data === null || data === undefined)\r\n return data;\r\n\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number, boolean or null`);\r\n}\r\n\r\nexport function ensureString(fieldName: string, data: any): string {\r\n if (typeof data === 'string')\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string`);\r\n}\r\n\r\nexport function ensureArray<T>(fieldName: string, data: T[] | any, minLength: number = 0): T[] {\r\n if (!Array.isArray(data) || data.length < minLength)\r\n throw new Error(`${fieldName} must be an array with at least ${minLength} items`);\r\n\r\n return data;\r\n}\r\n\r\nexport function ensureEmpty(fieldName: string, data: any) {\r\n if (isValid(data) && data !== true)\r\n throw new Error(`${fieldName} must be true, null or undefined`);\r\n}\r\n\r\nexport function isValid<T>(value: T | undefined | null): value is T {\r\n return value !== null && value !== undefined;\r\n}\r\n\r\nexport function getOffset(offset: number | undefined, limit?: number, page?: number): number {\r\n return offset ?? (limit && page ? limit * (page - 1) : 0);\r\n}\r\n\r\nexport interface Type<T> extends Function { new (... args: any[]): T; }\r\n\r\nexport function createInstance<T extends object>(clazzOrInstance: T | Type<T> | undefined): T | undefined {\r\n if (typeof clazzOrInstance === 'function')\r\n return new clazzOrInstance();\r\n\r\n if (typeof clazzOrInstance === 'object')\r\n return clazzOrInstance as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n","import type { Condition, Filter } from 'mongodb';\r\nimport { CrudRequest } from '../../models/crud-request';\r\nimport { CrudRequestWhere, CrudRequestWhereOperator, CrudRequestWhereValueType } from '../../models/crud-request-where';\r\nimport { ensureArray, ensureString, escapeRegex, getOffset } from '../../utils/functions';\r\n\r\nexport abstract class BaseMongoQueryAdapter {\r\n\r\n /**\r\n * Adapts the query select list into a MongoDB projection\r\n *\r\n * @param crudRequest The crud request\r\n */\r\n public buildProjection(crudRequest: CrudRequest): Record<string, true> {\r\n return crudRequest.select.reduce<Record<string, true>>((obj, item) => {\r\n obj[item.field.join('.')] = true;\r\n\r\n return obj;\r\n }, {});\r\n }\r\n\r\n /**\r\n * Adapts the query order into a MongoDB sort order\r\n *\r\n * @param crudRequest The crud request\r\n */\r\n public buildSort(crudRequest: CrudRequest): [string, -1 | 1][] {\r\n return crudRequest.order.map<[string, -1 | 1]>(\r\n item => [item.field.join('.'), item.order === 'DESC' ? -1 : 1],\r\n );\r\n }\r\n\r\n /**\r\n * Adapts the query offset, page and limit into the MongoDB skip\r\n *\r\n * @param crudRequest The crud request\r\n */\r\n public buildSkip(crudRequest: CrudRequest): number {\r\n return getOffset(crudRequest.offset, crudRequest.limit, crudRequest.page);\r\n }\r\n\r\n /**\r\n * Adapts the query where conditions into a MongoDB filter\r\n *\r\n * @param crudRequest The crud request\r\n */\r\n public buildFilter<E>(crudRequest: CrudRequest): Filter<E> {\r\n return this.mapFilter<E>(crudRequest.where);\r\n }\r\n\r\n /**\r\n * Maps the where condition into a cursor filter\r\n *\r\n * @param where The where condition\r\n */\r\n protected mapFilter<E>(where: CrudRequestWhere): Filter<E> {\r\n if (where.and && where.and.length > 0) {\r\n return { $and: where.and.map(item => this.mapFilter(item)) };\r\n }\r\n\r\n if (where.or && where.or.length > 0) {\r\n return { $or: where.or.map(item => this.mapFilter(item)) };\r\n }\r\n\r\n if (where.field) {\r\n return { [where.field.join('.') as any]: this.mapCondition(where.operator, where.value) };\r\n }\r\n\r\n return {};\r\n }\r\n\r\n /**\r\n * Maps the query operator into a cursor condition operator\r\n *\r\n * @param operator The condition operator\r\n * @param value The condition value\r\n */\r\n protected mapCondition(\r\n operator: CrudRequestWhereOperator,\r\n value: CrudRequestWhereValueType | CrudRequestWhereValueType[],\r\n ): Condition<any> {\r\n switch (operator) {\r\n case CrudRequestWhereOperator.EQ:\r\n return value;\r\n\r\n case CrudRequestWhereOperator.NEQ:\r\n return { $ne: value };\r\n\r\n case CrudRequestWhereOperator.GT:\r\n return { $gt: value };\r\n\r\n case CrudRequestWhereOperator.GTE:\r\n return { $gte: value };\r\n\r\n case CrudRequestWhereOperator.LT:\r\n return { $lt: value };\r\n\r\n case CrudRequestWhereOperator.LTE:\r\n return { $lte: value };\r\n\r\n case CrudRequestWhereOperator.IN:\r\n return { $in: value };\r\n\r\n case CrudRequestWhereOperator.NOT_IN:\r\n return { $nin: value };\r\n\r\n case CrudRequestWhereOperator.IS_NULL:\r\n return { $eq: null };\r\n\r\n case CrudRequestWhereOperator.NOT_NULL:\r\n return { $ne: null };\r\n\r\n case CrudRequestWhereOperator.BETWEEN:\r\n const arr = ensureArray('BETWEEN operator', value, 2);\r\n\r\n return { $gte: arr[0], $lte: arr[1] };\r\n\r\n case CrudRequestWhereOperator.CONTAINS:\r\n return { $regex: escapeRegex(ensureString('CONTAINS operator', value)) };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS:\r\n return { $not: { $regex: escapeRegex(ensureString('CONTAINS operator', value)) } };\r\n\r\n case CrudRequestWhereOperator.STARTS:\r\n return { $regex: '^' + escapeRegex(ensureString('STARTS operator', value)) };\r\n\r\n case CrudRequestWhereOperator.ENDS:\r\n return { $regex: escapeRegex(ensureString('ENDS operator', value)) + '$' };\r\n\r\n case CrudRequestWhereOperator.EQ_LOWER:\r\n return { $regex: '^' + escapeRegex(ensureString('EQ LOWER operator', value)) + '$', $options: 'i' };\r\n\r\n case CrudRequestWhereOperator.NEQ_LOWER:\r\n return { $not: { $regex: '^' + escapeRegex(ensureString('NEQ LOWER operator', value)) + '$', $options: 'i' } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS_LOWER:\r\n return { $regex: escapeRegex(ensureString('CONTAINS LOWER operator', value)), $options: 'i' };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS_LOWER:\r\n return { $not: { $regex: escapeRegex(ensureString('NOT CONTAINS LOWER operator', value)), $options: 'i' } };\r\n\r\n case CrudRequestWhereOperator.STARTS_LOWER:\r\n return { $regex: '^' + escapeRegex(ensureString('STARTS LOWER operator', value)), $options: 'i' };\r\n\r\n case CrudRequestWhereOperator.ENDS_LOWER:\r\n return { $regex: escapeRegex(ensureString('ENDS LOWER operator', value)) + '$', $options: 'i' };\r\n\r\n case CrudRequestWhereOperator.IN_LOWER:\r\n return {\r\n $in: ensureArray('IN LOWER operator', value, 1).map((item, i) => (\r\n { $regex: '^' + escapeRegex(ensureString(`IN LOWER [${i}] operator`, item)) + '$', $options: 'i' }\r\n )),\r\n };\r\n\r\n case CrudRequestWhereOperator.NOT_IN_LOWER:\r\n return {\r\n $nin: ensureArray('NOT IN LOWER operator', value, 1).map((item, i) => (\r\n { $regex: '^' + escapeRegex(ensureString(`NOT IN LOWER [${i}] operator`, item)) + '$', $options: 'i' }\r\n )),\r\n };\r\n }\r\n\r\n throw new Error(`Unsupported operator ${operator}.`);\r\n }\r\n\r\n}\r\n","import { GetManyResult } from '../models/get-many-result';\r\nimport { CrudRequest } from '../models/crud-request';\r\n\r\n/**\r\n * Creates a CrudRequest object, filling required missing properties with empty values\r\n */\r\nexport function createCrudRequest(crudRequest?: Partial<CrudRequest>): CrudRequest {\r\n return {\r\n select: [],\r\n relations: [],\r\n order: [],\r\n where: { and: [] },\r\n ...crudRequest,\r\n };\r\n}\r\n\r\n/**\r\n * Creates a GetManyResult object\r\n *\r\n * @param data The entity list to be returned\r\n * @param total The total amount of entities in the database\r\n * @param offset The offset used for querying\r\n * @param limit The limit used for querying\r\n */\r\nexport function createGetManyResult<T>(data: T[], total: number, offset: number, limit?: number): GetManyResult<T> {\r\n const count = data.length;\r\n const actualLimit = limit ?? total;\r\n const page = actualLimit > 0 ? Math.floor(offset / actualLimit) + 1 : 1;\r\n const pageCount = actualLimit > 0 ? Math.ceil(total / actualLimit) : 0;\r\n\r\n return {\r\n data,\r\n count,\r\n total,\r\n page,\r\n pageCount,\r\n };\r\n}\r\n","import type { Collection, Document, Filter, FindCursor, WithId } from 'mongodb';\r\nimport { QueryAdapter } from '../../models/query-adapter';\r\nimport { CrudRequest } from '../../models/crud-request';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { BaseMongoQueryAdapter } from './base-mongo.query-adapter';\r\nimport { createGetManyResult } from '../../utils/objects';\r\n\r\nexport interface MongoQueryAdapterOptions {\r\n /**\r\n * Whether you want to disable the fetching the total in `getMany()`\r\n */\r\n disableCount?: boolean;\r\n}\r\n\r\nexport class MongoDBQueryAdapter extends BaseMongoQueryAdapter implements QueryAdapter<FindCursor | Collection, Document> {\r\n\r\n constructor(\r\n private readonly options: MongoQueryAdapterOptions = {},\r\n ) {\r\n super();\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build<E extends Document>(base: FindCursor<WithId<E>> | Collection<E>, request: CrudRequest): FindCursor<WithId<E>> {\r\n const cursor = 'find' in base ? base.find() : base;\r\n\r\n this.adaptFilter(cursor, request);\r\n this.adaptProjection(cursor, request);\r\n this.adaptSort(cursor, request);\r\n this.adaptSkipAndLimit(cursor, request);\r\n\r\n return cursor;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E extends Document>(base: FindCursor<E> | Collection<E>, request: CrudRequest): Promise<GetManyResult<WithId<E>>> {\r\n const cursor = 'find' in base ? base.find() : base as FindCursor<WithId<E>>;\r\n\r\n const filter = this.adaptFilter<E>(cursor, request);\r\n\r\n const total = await this.getCount<E>(base, cursor, filter);\r\n\r\n this.adaptProjection(cursor, request);\r\n this.adaptSort(cursor, request);\r\n\r\n const [skip, limit] = this.adaptSkipAndLimit(cursor, request);\r\n\r\n const data = await cursor.toArray();\r\n\r\n return createGetManyResult(data, total, skip, limit);\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E extends Document>(base: FindCursor<E> | Collection<E>, request: CrudRequest): Promise<WithId<E> | null> {\r\n const cursor = 'find' in base ? base.find() : base as FindCursor<WithId<E>>;\r\n\r\n this.adaptFilter(cursor, request);\r\n this.adaptProjection(cursor, request);\r\n this.adaptSort(cursor, request);\r\n this.adaptSkipAndLimit(cursor, request);\r\n\r\n return await cursor.next();\r\n }\r\n\r\n /**\r\n * Fetches the count from a cursor or a collection\r\n *\r\n * @param base The cursor or collection\r\n * @param cursor The actual cursor\r\n * @param filter The filter\r\n */\r\n protected async getCount<E extends Document>(base: FindCursor<E> | Collection<E>, cursor: FindCursor<WithId<E>>, filter: Filter<E>): Promise<number> {\r\n if (this.options.disableCount)\r\n return 0;\r\n\r\n if ('countDocuments' in base && typeof base.countDocuments === 'function')\r\n return await base.countDocuments(filter);\r\n\r\n if ('count' in base && typeof cursor.count === 'function')\r\n return await cursor.count();\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Adapts the query select list into a projection\r\n *\r\n * @param cursor The cursor\r\n * @param crudRequest The request\r\n */\r\n protected adaptProjection<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): void {\r\n if (crudRequest.select.length === 0)\r\n return;\r\n\r\n cursor.project(this.buildProjection(crudRequest));\r\n }\r\n\r\n /**\r\n * Adapts the query order into a sort order\r\n *\r\n * @param cursor The cursor\r\n * @param crudRequest The request\r\n */\r\n protected adaptSort<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): void {\r\n if (crudRequest.order.length === 0)\r\n return;\r\n\r\n cursor.sort(this.buildSort(crudRequest));\r\n }\r\n\r\n /**\r\n * Adapts the query offset and limit into the cursor skip and limit\r\n *\r\n * @param cursor The cursor\r\n * @param crudRequest The request\r\n */\r\n protected adaptSkipAndLimit<E>(cursor: FindCursor<E>, crudRequest: CrudRequest): [number, number?] {\r\n const skip = this.buildSkip(crudRequest);\r\n const limit = crudRequest.limit;\r\n\r\n if (skip)\r\n cursor.skip(skip);\r\n\r\n if (limit)\r\n cursor.limit(limit);\r\n\r\n return [skip, limit];\r\n }\r\n\r\n /**\r\n * Adapts the query where conditions into a cursor filter\r\n *\r\n * @param cursor The cursor\r\n * @param crudRequest The request\r\n */\r\n protected adaptFilter<E>(cursor: FindCursor<WithId<E>>, crudRequest: CrudRequest): Filter<E> {\r\n const filter = this.buildFilter<E>(crudRequest);\r\n\r\n cursor.filter(filter);\r\n\r\n return filter;\r\n }\r\n\r\n}\r\n","import type { HydratedDocument, Query } from 'mongoose';\r\nimport { QueryAdapter } from '../../models/query-adapter';\r\nimport { CrudRequest } from '../../models/crud-request';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { BaseMongoQueryAdapter } from './base-mongo.query-adapter';\r\nimport { createGetManyResult } from '../../utils/objects';\r\n\r\nexport interface MongooseQueryAdapterOptions {\r\n /**\r\n * Whether you want to disable the fetching the total count in `getMany()`\r\n */\r\n disableCount?: boolean;\r\n}\r\n\r\ntype MongooseQuery = Query<any, any>;\r\n\r\nexport class MongooseQueryAdapter extends BaseMongoQueryAdapter implements QueryAdapter<Query<any, any>, HydratedDocument<any>> {\r\n\r\n constructor(\r\n private readonly options: MongooseQueryAdapterOptions = {},\r\n ) {\r\n super();\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build<E extends HydratedDocument<any>, Q extends Query<any, E>>(baseQuery: Q, request: CrudRequest): Q {\r\n const query = baseQuery.clone();\r\n\r\n this.adaptFilter(query, request);\r\n this.adaptProjection(query, request);\r\n this.adaptSort(query, request);\r\n this.adaptSkipAndLimit(query, request);\r\n\r\n return query;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E extends HydratedDocument<any>>(baseQuery: Query<any, E>, request: CrudRequest): Promise<GetManyResult<E>> {\r\n const query = baseQuery.clone();\r\n\r\n this.adaptFilter(query, request);\r\n\r\n const countQuery = query.clone();\r\n\r\n this.adaptProjection(query, request);\r\n this.adaptSort(query, request);\r\n\r\n const [skip, limit] = this.adaptSkipAndLimit(query, request);\r\n\r\n const total = await this.getCount(countQuery);\r\n const data = await query.exec();\r\n\r\n return createGetManyResult(data, total, skip, limit);\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E extends HydratedDocument<any>>(baseQuery: Query<any, E>, request: CrudRequest): Promise<E | null> {\r\n const query = baseQuery.clone();\r\n\r\n this.adaptFilter(query, request);\r\n this.adaptProjection(query, request);\r\n this.adaptSort(query, request);\r\n\r\n const entities = await query.limit(1).exec();\r\n\r\n if (entities.length === 0)\r\n return null;\r\n\r\n return entities[0];\r\n }\r\n\r\n /**\r\n * Fetches the count from a query\r\n *\r\n * @param query The query\r\n */\r\n protected async getCount(query: MongooseQuery): Promise<number> {\r\n if (this.options.disableCount)\r\n return 0;\r\n\r\n return query.countDocuments();\r\n }\r\n\r\n /**\r\n * Adapts the request select list into a projection\r\n *\r\n * @param query The query\r\n * @param crudRequest The request\r\n */\r\n protected adaptProjection(query: MongooseQuery, crudRequest: CrudRequest): void {\r\n if (crudRequest.select.length === 0)\r\n return;\r\n\r\n query.projection(this.buildProjection(crudRequest));\r\n }\r\n\r\n /**\r\n * Adapts the request order into a sort order\r\n *\r\n * @param query The query\r\n * @param crudRequest The request\r\n */\r\n protected adaptSort(query: MongooseQuery, crudRequest: CrudRequest): void {\r\n if (crudRequest.order.length === 0)\r\n return;\r\n\r\n query.sort(this.buildSort(crudRequest));\r\n }\r\n\r\n /**\r\n * Adapts the request offset and limit into the cursor skip and limit\r\n *\r\n * @param query The query\r\n * @param crudRequest The request\r\n */\r\n protected adaptSkipAndLimit(query: MongooseQuery, crudRequest: CrudRequest): [number, number?] {\r\n const skip = this.buildSkip(crudRequest);\r\n const limit = crudRequest.limit;\r\n\r\n if (skip)\r\n query.skip(skip);\r\n\r\n if (limit)\r\n query.limit(limit);\r\n\r\n return [skip, limit];\r\n }\r\n\r\n /**\r\n * Adapts the request where conditions into a query where\r\n *\r\n * @param query The query\r\n * @param crudRequest The request\r\n */\r\n protected adaptFilter(query: MongooseQuery, crudRequest: CrudRequest): void {\r\n query.where(this.buildFilter(crudRequest));\r\n }\r\n\r\n}\r\n"],"mappings":"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","names":["ensureString","fieldName","data","__name","ensureArray","minLength","getOffset","offset","limit","page","__name","escapeRegex","str","__name","BaseMongoQueryAdapter","__name","crudRequest","obj","item","getOffset","where","operator","value","arr","ensureArray","escapeRegex","ensureString","i","createGetManyResult","data","total","offset","limit","count","actualLimit","page","pageCount","__name","MongoDBQueryAdapter","BaseMongoQueryAdapter","options","__name","base","request","cursor","filter","total","skip","limit","data","createGetManyResult","crudRequest","MongooseQueryAdapter","BaseMongoQueryAdapter","options","__name","baseQuery","request","query","countQuery","skip","limit","total","data","createGetManyResult","entities","crudRequest"]}