common.ts 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /*
  2. * Common types and interfaces
  3. */
  4. import type { Types } from 'mongoose';
  5. import { isValidObjectId } from '../utils/objectid-utils';
  6. type ObjectId = Types.ObjectId;
  7. // Foreign key field
  8. export type Ref<T> = string | ObjectId | T & { _id: string | ObjectId };
  9. export type Populated<T, K extends keyof T> = {
  10. [P in keyof T]: P extends K
  11. ? T[P] extends null
  12. ? null
  13. : T[P] extends Ref<infer R>
  14. ? R
  15. : T[P]
  16. : T[P];
  17. };
  18. export type Nullable<T> = T | null | undefined;
  19. export const isRef = <T>(obj: unknown): obj is Ref<T> => {
  20. return obj != null
  21. && (
  22. (typeof obj === 'string' && isValidObjectId(obj))
  23. || (typeof obj === 'object' && '_bsontype' in obj && obj._bsontype === 'ObjectID')
  24. || (typeof obj === 'object' && '_id' in obj)
  25. );
  26. };
  27. export const isPopulated = <T>(ref: Ref<T>): ref is T & { _id: string | ObjectId } => {
  28. return ref != null
  29. && typeof ref !== 'string'
  30. && !('_bsontype' in ref && ref._bsontype === 'ObjectID');
  31. };
  32. export const getIdForRef = <T>(ref: Ref<T>): string | ObjectId => {
  33. return isPopulated(ref)
  34. ? ref._id
  35. : ref;
  36. };
  37. export const getIdStringForRef = <T>(ref: Ref<T>): string => {
  38. return getIdForRef(ref).toString();
  39. };