From 18e7b168e982c3582d817ef1815403abf0f7c496 Mon Sep 17 00:00:00 2001 From: Duncan Beevers Date: Tue, 28 May 2024 18:21:01 -0700 Subject: [PATCH] fixup! feat: Support updates with readonly array values Closes #828 --- src/__tests__/model.test.ts | 12 +++++++---- src/model.ts | 4 ++-- src/mongodbTypes.ts | 42 ++++++++++++++++++++++++------------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/__tests__/model.test.ts b/src/__tests__/model.test.ts index 614e15594..2d20c7b2c 100644 --- a/src/__tests__/model.test.ts +++ b/src/__tests__/model.test.ts @@ -239,7 +239,7 @@ describe('model', () => { describe('bulkWrite', () => { test('simple schema', async () => { - const operations: PaprBulkWriteOperation[] = [ + const operations = [ { insertOne: { document: { @@ -283,7 +283,9 @@ describe('model', () => { filter: { foo: 'foo' }, }, }, - ]; + ] as const; + + expectType[]>(operations); await simpleModel.bulkWrite(operations); @@ -293,7 +295,7 @@ describe('model', () => { }); test('schema with defaults', async () => { - const operations: PaprBulkWriteOperation[] = [ + const operations = [ { insertOne: { document: { @@ -367,7 +369,9 @@ describe('model', () => { upsert: true, }, }, - ]; + ] as const; + + expectType[]>(operations); await simpleModel.bulkWrite(operations); diff --git a/src/model.ts b/src/model.ts index 9a4a4b90c..2512f822d 100644 --- a/src/model.ts +++ b/src/model.ts @@ -57,7 +57,7 @@ export interface Model Promise; bulkWrite: ( - operations: PaprBulkWriteOperation[], + operations: readonly PaprBulkWriteOperation[], options?: BulkWriteOptions ) => Promise; @@ -376,7 +376,7 @@ export function build[], + operations: readonly PaprBulkWriteOperation[], options?: BulkWriteOptions ): Promise { if (operations.length === 0) { diff --git a/src/mongodbTypes.ts b/src/mongodbTypes.ts index 7ba9c4768..86ca8b49d 100644 --- a/src/mongodbTypes.ts +++ b/src/mongodbTypes.ts @@ -42,7 +42,7 @@ import { DocumentForInsert, NestedPaths, PropertyType } from './utils'; // We've adopted these types in this repository and made some improvements to them. // See: https://github.com/plexinc/papr/issues/410 -// These buik operation types need our own `PaprFilter` and `PaprUpdateFilter` in their definition +// These bulk operation types need our own `PaprFilter` and `PaprUpdateFilter` in their definition export type PaprBulkWriteOperation> = | { // @ts-expect-error Type expects a Document extended type, but Document is too generic @@ -171,7 +171,7 @@ export type PaprAllProperties = { * } */ export type PaprArrayElementsProperties = { - [Property in `${KeysOfAType, any[]>}.$${ + [Property in `${KeysOfAType, readonly any[]>}.$${ | '' | `[${string}]`}`]?: ArrayElement< PropertyType @@ -204,6 +204,18 @@ export type PaprMatchKeysAndValues = PaprAllProperties & PaprArrayElementsProperties & PaprArrayNestedProperties; +type DeepReadonly = TSchema extends (infer Member)[] + ? DeepReadonlyArray + : TSchema extends object + ? DeepReadonlyObject + : TSchema; + +interface DeepReadonlyArray extends ReadonlyArray> {} + +type DeepReadonlyObject = { + readonly [Prop in keyof TSchema]: DeepReadonly; +}; + export interface PaprUpdateFilter { $currentDate?: OnlyFieldsOfType< TSchema, @@ -213,21 +225,21 @@ export interface PaprUpdateFilter { $type: 'date' | 'timestamp'; } >; - $inc?: OnlyFieldsOfType; - $min?: PaprMatchKeysAndValues; - $max?: PaprMatchKeysAndValues; - $mul?: OnlyFieldsOfType; + $inc?: OnlyFieldsOfType, NumericType | undefined>; + $min?: PaprMatchKeysAndValues>; + $max?: PaprMatchKeysAndValues>; + $mul?: OnlyFieldsOfType, NumericType | undefined>; $rename?: Record; - $set?: PaprMatchKeysAndValues; - $setOnInsert?: PaprMatchKeysAndValues; - $unset?: OnlyFieldsOfType; - $addToSet?: SetFields; - $pop?: OnlyFieldsOfType; - $pull?: PullOperator; - $push?: PushOperator; - $pullAll?: PullAllOperator; + $set?: PaprMatchKeysAndValues>; + $setOnInsert?: PaprMatchKeysAndValues>; + $unset?: OnlyFieldsOfType, any, '' | 1 | true>; + $addToSet?: SetFields>; + $pop?: OnlyFieldsOfType, readonly any[], -1 | 1>; + $pull?: PullOperator>; + $push?: PushOperator>; + $pullAll?: PullAllOperator>; $bit?: OnlyFieldsOfType< - TSchema, + DeepReadonly, NumericType | undefined, | { and: IntegerType;