// @flow import type { QueryCondition, EqCondition, } from './query-condition.js.flow' import type { SortNotation } from './sort-notation.js.flow' import type { DocumentPath } from './document-path.js.flow' export type SetOperator = { [field: DocumentPath]: any } export type IncOperator = { [field: DocumentPath]: number } export type MinOperator = { [field: DocumentPath]: any } export type MaxOperator = { [field: DocumentPath]: any } export type MulOperator = { [field: DocumentPath]: number } export type AddToSetOperator = { [field: DocumentPath]: any | { $each: Array } } export type RegularAddToSetOperator = { [field: DocumentPath]: { $each: Array } } export type PopOperator = { [field: DocumentPath]: 1 | - 1 } export type UnsetOperator = { [field: DocumentPath]: '' } export type PullOperator = { +[field: DocumentPath]: QueryCondition | EqCondition } export type RegularPullOperator = { +[field: DocumentPath]: QueryCondition } export type PushModifier = { $each: Array, $slice?: number, $sort?: SortNotation, $position?: number, } export type PushOperator = { [field: DocumentPath]: any | PushModifier } export type RegularPushOperator = { [field: DocumentPath]: PushModifier } type TypeSpecification = true | { $type: 'timestamp' | 'date' } export type CurrentDateOperator = { [field: DocumentPath]: TypeSpecification } export type BitOperator = { [field: DocumentPath]: { and?: number, or?: number, xor?: number, } } /** * RenameOperator * a bit different operator from MongoDB's $rename operator * https://docs.mongodb.com/manual/reference/operator/update/rename/ * * The values are not 'DotNotationString's but field names. * The following sample object in mongodb * { $rename: { "name.first": "name.fname" } } * * will be the following object in power-assign. * * { $rename: { "name.first": "fname" } } * * See that the value doesn't contain "name". * When this operator is passed to MongoDB via phenyl-mongodb, * new field names will be automatically corrected to fit the MongoDB's spec. */ export type RenameOperator = { [field: DocumentPath]: string } /** * New operator which construct instances of the given path * Notice: * * Once RestoreOperator is JSON.stringify-ed, the fields with Class will be removed. * To avoid this, you can choose two alternatives. * * 1) Implement static method toJSON() to Classes * class Foo { * static toJSON() { return '' } * } * * 2) Use updateOperationToJSON() function exported from oad-utils * import { updateOperationToJSON } from 'oad-utils/jsnext' * const operation: UpdateOperation = { $restore: { foo: Foo } } * JSON.stringify(updateOperationToJSON(operation)) // {"$restore":{"foo":""}} */ export type RestoreOperator = { [field: DocumentPath]: '' | Class<*> } export type RegularUpdateOperation = $Shape<{ $set: SetOperator, $inc: IncOperator, $min: MinOperator, $max: MaxOperator, $mul: MulOperator, $addToSet: RegularAddToSetOperator, $pop: PopOperator, $pull: RegularPullOperator, $push: RegularPushOperator, $currentDate: CurrentDateOperator, $bit: BitOperator, $unset: UnsetOperator, $restore: RestoreOperator, $rename: RenameOperator, }> export type UpdateOperation = $Shape<{ $set: SetOperator, $inc: IncOperator, $min: MinOperator, $max: MaxOperator, $mul: MulOperator, $addToSet: AddToSetOperator, $pop: PopOperator, $pull: RegularPullOperator, $push: PushOperator, $currentDate: CurrentDateOperator, $bit: BitOperator, $unset: UnsetOperator, $restore: RestoreOperator, $rename: RenameOperator, }> export type UpdateOperatorName = '$set' | '$inc' | '$min' | '$max' | '$mul' | '$addToSet' | '$pop' | '$pull' | '$push' | '$currentDate' | '$bit' | '$unset' | '$restore' | '$rename' export type UpdateOperator = SetOperator | IncOperator | MinOperator | MaxOperator | MulOperator | AddToSetOperator | PopOperator | PullOperator | PushOperator | CurrentDateOperator | BitOperator | UnsetOperator | RenameOperator | RestoreOperator | RenameOperator