utils.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { AssetType } from '@vendure/common/lib/generated-types';
  2. import { ID } from '@vendure/common/lib/shared-types';
  3. import { Observable, Observer } from 'rxjs';
  4. /**
  5. * Takes a predicate function and returns a negated version.
  6. */
  7. export function not(predicate: (...args: any[]) => boolean) {
  8. return (...args: any[]) => !predicate(...args);
  9. }
  10. /**
  11. * Returns a predicate function which returns true if the item is found in the set,
  12. * as determined by a === equality check on the given compareBy property.
  13. */
  14. export function foundIn<T>(set: T[], compareBy: keyof T) {
  15. return (item: T) => set.some(t => t[compareBy] === item[compareBy]);
  16. }
  17. /**
  18. * Identity function which asserts to the type system that a promise which can resolve to T or undefined
  19. * does in fact resolve to T.
  20. * Used when performing a "find" operation on an entity which we are sure exists, as in the case that we
  21. * just successfully created or updated it.
  22. */
  23. export function assertFound<T>(promise: Promise<T | undefined>): Promise<T> {
  24. return promise as Promise<T>;
  25. }
  26. /**
  27. * Compare ID values for equality, taking into account the fact that they may not be of matching types
  28. * (string or number).
  29. */
  30. export function idsAreEqual(id1?: ID, id2?: ID): boolean {
  31. if (id1 === undefined || id2 === undefined) {
  32. return false;
  33. }
  34. return id1.toString() === id2.toString();
  35. }
  36. /**
  37. * Returns the AssetType based on the mime type.
  38. */
  39. export function getAssetType(mimeType: string): AssetType {
  40. const type = mimeType.split('/')[0];
  41. switch (type) {
  42. case 'image':
  43. return AssetType.IMAGE;
  44. case 'video':
  45. return AssetType.VIDEO;
  46. default:
  47. return AssetType.BINARY;
  48. }
  49. }
  50. /**
  51. * A simple normalization for email addresses. Lowercases the whole address,
  52. * even though technically the local part (before the '@') is case-sensitive
  53. * per the spec. In practice, however, it seems safe to treat emails as
  54. * case-insensitive to allow for users who might vary the usage of
  55. * upper/lower case. See more discussion here: https://ux.stackexchange.com/a/16849
  56. */
  57. export function normalizeEmailAddress(input: string): string {
  58. return input.trim().toLowerCase();
  59. }
  60. /**
  61. * Converts a value that may be wrapped into a Promise or Observable into a Promise-wrapped
  62. * value.
  63. */
  64. export async function awaitPromiseOrObservable<T>(value: T | Promise<T> | Observable<T>): Promise<T> {
  65. let result = await value;
  66. if (result instanceof Observable) {
  67. result = await result.toPromise();
  68. }
  69. return result;
  70. }
  71. /**
  72. * @description
  73. * Returns an observable which executes the given async work function and completes with
  74. * the returned value. This is useful in methods which need to return
  75. * an Observable but also want to work with async (Promise-returning) code.
  76. *
  77. * @example
  78. * ```TypeScript
  79. * \@Controller()
  80. * export class MyWorkerController {
  81. *
  82. * \@MessagePattern('test')
  83. * handleTest() {
  84. * return asyncObservable(async observer => {
  85. * const value = await this.connection.fetchSomething();
  86. * return value;
  87. * });
  88. * }
  89. * }
  90. * ```
  91. */
  92. export function asyncObservable<T>(work: (observer: Observer<T>) => Promise<T | void>): Observable<T> {
  93. return new Observable<T>(subscriber => {
  94. (async () => {
  95. try {
  96. const result = await work(subscriber);
  97. if (result) {
  98. subscriber.next(result);
  99. }
  100. subscriber.complete();
  101. } catch (e) {
  102. subscriber.error(e);
  103. }
  104. })();
  105. });
  106. }