quidproquo-web 0.0.263 → 0.1.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 (63) hide show
  1. package/lib/commonjs/actions/api/ApiActionType.d.ts +3 -0
  2. package/lib/commonjs/actions/api/ApiActionType.js +7 -0
  3. package/lib/commonjs/actions/api/ApiRequestActionRequester.d.ts +3 -0
  4. package/lib/commonjs/actions/api/ApiRequestActionRequester.js +18 -0
  5. package/lib/commonjs/actions/api/ApiRequestActionRequesterTypes.d.ts +18 -0
  6. package/lib/commonjs/actions/api/ApiRequestActionRequesterTypes.js +2 -0
  7. package/lib/commonjs/actions/api/index.d.ts +3 -0
  8. package/lib/commonjs/{request → actions/api}/index.js +3 -1
  9. package/lib/commonjs/actions/index.d.ts +2 -0
  10. package/lib/commonjs/actions/index.js +2 -0
  11. package/lib/commonjs/actions/window/WindowActionType.d.ts +3 -0
  12. package/lib/commonjs/actions/window/WindowActionType.js +7 -0
  13. package/lib/commonjs/actions/window/WindowGetLocationActionRequester.d.ts +2 -0
  14. package/lib/commonjs/actions/window/WindowGetLocationActionRequester.js +7 -0
  15. package/lib/commonjs/actions/window/WindowGetLocationActionRequesterTypes.d.ts +19 -0
  16. package/lib/commonjs/actions/window/WindowGetLocationActionRequesterTypes.js +2 -0
  17. package/lib/commonjs/actions/window/index.d.ts +3 -0
  18. package/lib/commonjs/{auth → actions/window}/index.js +3 -1
  19. package/lib/commonjs/index.d.ts +0 -2
  20. package/lib/commonjs/index.js +0 -2
  21. package/lib/commonjs/tools/index.d.ts +1 -0
  22. package/lib/commonjs/tools/index.js +1 -0
  23. package/lib/commonjs/tools/timeAgo.d.ts +11 -0
  24. package/lib/commonjs/tools/timeAgo.js +54 -0
  25. package/lib/esm/actions/api/ApiActionType.d.ts +3 -0
  26. package/lib/esm/actions/api/ApiActionType.js +4 -0
  27. package/lib/esm/actions/api/ApiRequestActionRequester.d.ts +3 -0
  28. package/lib/esm/actions/api/ApiRequestActionRequester.js +15 -0
  29. package/lib/esm/actions/api/ApiRequestActionRequesterTypes.d.ts +18 -0
  30. package/lib/esm/actions/api/ApiRequestActionRequesterTypes.js +1 -0
  31. package/lib/esm/actions/api/index.d.ts +3 -0
  32. package/lib/esm/actions/api/index.js +3 -0
  33. package/lib/esm/actions/index.d.ts +2 -0
  34. package/lib/esm/actions/index.js +2 -0
  35. package/lib/esm/actions/window/WindowActionType.d.ts +3 -0
  36. package/lib/esm/actions/window/WindowActionType.js +4 -0
  37. package/lib/esm/actions/window/WindowGetLocationActionRequester.d.ts +2 -0
  38. package/lib/esm/actions/window/WindowGetLocationActionRequester.js +4 -0
  39. package/lib/esm/actions/window/WindowGetLocationActionRequesterTypes.d.ts +19 -0
  40. package/lib/esm/actions/window/WindowGetLocationActionRequesterTypes.js +1 -0
  41. package/lib/esm/actions/window/index.d.ts +3 -0
  42. package/lib/esm/actions/window/index.js +3 -0
  43. package/lib/esm/index.d.ts +0 -2
  44. package/lib/esm/index.js +0 -2
  45. package/lib/esm/tools/index.d.ts +1 -0
  46. package/lib/esm/tools/index.js +1 -0
  47. package/lib/esm/tools/timeAgo.d.ts +11 -0
  48. package/lib/esm/tools/timeAgo.js +49 -0
  49. package/package.json +4 -4
  50. package/lib/commonjs/auth/exchangeOauth2TokenForAccessToken.d.ts +0 -6
  51. package/lib/commonjs/auth/exchangeOauth2TokenForAccessToken.js +0 -26
  52. package/lib/commonjs/auth/index.d.ts +0 -1
  53. package/lib/commonjs/request/index.d.ts +0 -1
  54. package/lib/commonjs/request/preformNetworkRequest.d.ts +0 -2
  55. package/lib/commonjs/request/preformNetworkRequest.js +0 -155
  56. package/lib/esm/auth/exchangeOauth2TokenForAccessToken.d.ts +0 -6
  57. package/lib/esm/auth/exchangeOauth2TokenForAccessToken.js +0 -12
  58. package/lib/esm/auth/index.d.ts +0 -1
  59. package/lib/esm/auth/index.js +0 -1
  60. package/lib/esm/request/index.d.ts +0 -1
  61. package/lib/esm/request/index.js +0 -1
  62. package/lib/esm/request/preformNetworkRequest.d.ts +0 -2
  63. package/lib/esm/request/preformNetworkRequest.js +0 -141
@@ -0,0 +1,3 @@
1
+ export declare enum ApiActionType {
2
+ Request = "@quidproquo-web/Api/Request"
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiActionType = void 0;
4
+ var ApiActionType;
5
+ (function (ApiActionType) {
6
+ ApiActionType["Request"] = "@quidproquo-web/Api/Request";
7
+ })(ApiActionType || (exports.ApiActionType = ApiActionType = {}));
@@ -0,0 +1,3 @@
1
+ import { HTTPMethod } from 'quidproquo-core';
2
+ import { ApiRequestActionRequester, ApiRequestOptions } from './ApiRequestActionRequesterTypes';
3
+ export declare function askApiRequest<T, R>(service: string, method: HTTPMethod, endpoint: string, options?: ApiRequestOptions<T>): ApiRequestActionRequester<T, R>;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.askApiRequest = askApiRequest;
4
+ const ApiActionType_1 = require("./ApiActionType");
5
+ function* askApiRequest(service, method, endpoint, options) {
6
+ return yield {
7
+ type: ApiActionType_1.ApiActionType.Request,
8
+ payload: {
9
+ service,
10
+ endpoint,
11
+ method,
12
+ body: options === null || options === void 0 ? void 0 : options.body,
13
+ headers: options === null || options === void 0 ? void 0 : options.headers,
14
+ params: options === null || options === void 0 ? void 0 : options.params,
15
+ responseType: (options === null || options === void 0 ? void 0 : options.responseType) || 'json',
16
+ },
17
+ };
18
+ }
@@ -0,0 +1,18 @@
1
+ import { Action, ActionProcessor, ActionRequester, HTTPMethod, HTTPNetworkResponse, HTTPRequestOptions, ResponseType } from 'quidproquo-core';
2
+ import { ApiActionType } from './ApiActionType';
3
+ export type ApiRequestOptions<T> = Omit<HTTPRequestOptions<T>, 'basePath'>;
4
+ export interface ApiRequestActionPayload<T> {
5
+ service: string;
6
+ endpoint: string;
7
+ method: HTTPMethod;
8
+ body?: T;
9
+ params?: Record<string, string>;
10
+ headers?: Record<string, string>;
11
+ responseType: ResponseType;
12
+ }
13
+ export interface ApiRequestAction<T> extends Action<ApiRequestActionPayload<T>> {
14
+ type: ApiActionType.Request;
15
+ payload: ApiRequestActionPayload<T>;
16
+ }
17
+ export type ApiRequestActionProcessor<T, R> = ActionProcessor<ApiRequestAction<T>, HTTPNetworkResponse<R>>;
18
+ export type ApiRequestActionRequester<T, R> = ActionRequester<ApiRequestAction<T>, HTTPNetworkResponse<R>>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ export * from './ApiActionType';
2
+ export * from './ApiRequestActionRequester';
3
+ export * from './ApiRequestActionRequesterTypes';
@@ -14,4 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./preformNetworkRequest"), exports);
17
+ __exportStar(require("./ApiActionType"), exports);
18
+ __exportStar(require("./ApiRequestActionRequester"), exports);
19
+ __exportStar(require("./ApiRequestActionRequesterTypes"), exports);
@@ -1 +1,3 @@
1
+ export * from './api';
1
2
  export * from './queryParams';
3
+ export * from './window';
@@ -14,4 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./api"), exports);
17
18
  __exportStar(require("./queryParams"), exports);
19
+ __exportStar(require("./window"), exports);
@@ -0,0 +1,3 @@
1
+ export declare enum WindowActionType {
2
+ GetLocation = "@quidproquo-web/Window/GetLocation"
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WindowActionType = void 0;
4
+ var WindowActionType;
5
+ (function (WindowActionType) {
6
+ WindowActionType["GetLocation"] = "@quidproquo-web/Window/GetLocation";
7
+ })(WindowActionType || (exports.WindowActionType = WindowActionType = {}));
@@ -0,0 +1,2 @@
1
+ import { WindowGetLocationActionRequester } from './WindowGetLocationActionRequesterTypes';
2
+ export declare function askWindowGetLocation(): WindowGetLocationActionRequester;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.askWindowGetLocation = askWindowGetLocation;
4
+ const WindowActionType_1 = require("./WindowActionType");
5
+ function* askWindowGetLocation() {
6
+ return yield { type: WindowActionType_1.WindowActionType.GetLocation };
7
+ }
@@ -0,0 +1,19 @@
1
+ import { Action, ActionProcessor, ActionRequester } from 'quidproquo-core';
2
+ import { WindowActionType } from './WindowActionType';
3
+ export type WindowLocation = {
4
+ href: string;
5
+ origin: string;
6
+ protocol: string;
7
+ host: string;
8
+ hostname: string;
9
+ port: string;
10
+ pathname: string;
11
+ search: string;
12
+ hash: string;
13
+ };
14
+ export type WindowGetLocationActionPayload = undefined;
15
+ export interface WindowGetLocationAction extends Action<WindowGetLocationActionPayload> {
16
+ type: WindowActionType.GetLocation;
17
+ }
18
+ export type WindowGetLocationActionProcessor = ActionProcessor<WindowGetLocationAction, WindowLocation>;
19
+ export type WindowGetLocationActionRequester = ActionRequester<WindowGetLocationAction, WindowLocation>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ export * from './WindowActionType';
2
+ export * from './WindowGetLocationActionRequester';
3
+ export * from './WindowGetLocationActionRequesterTypes';
@@ -14,4 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./exchangeOauth2TokenForAccessToken"), exports);
17
+ __exportStar(require("./WindowActionType"), exports);
18
+ __exportStar(require("./WindowGetLocationActionRequester"), exports);
19
+ __exportStar(require("./WindowGetLocationActionRequesterTypes"), exports);
@@ -1,5 +1,3 @@
1
1
  export * from './actions';
2
- export * from './auth';
3
- export * from './request';
4
2
  export * from './services';
5
3
  export * from './tools';
@@ -15,7 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./actions"), exports);
18
- __exportStar(require("./auth"), exports);
19
- __exportStar(require("./request"), exports);
20
18
  __exportStar(require("./services"), exports);
21
19
  __exportStar(require("./tools"), exports);
@@ -1 +1,2 @@
1
+ export * from './timeAgo';
1
2
  export * from './uniqueBy';
@@ -14,4 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./timeAgo"), exports);
17
18
  __exportStar(require("./uniqueBy"), exports);
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Formats the distance between `date` and `now` as a relative phrase
3
+ * (e.g. "5 minutes ago", "in 2 hours") using the native Intl.RelativeTimeFormat.
4
+ * Past dates are negative, future dates are positive.
5
+ */
6
+ export declare const formatTimeAgo: (date: Date, now?: Date, locale?: string | string[]) => string;
7
+ /**
8
+ * How long until the relative phrase could next change, so callers can
9
+ * re-render no more often than necessary.
10
+ */
11
+ export declare const getTimeAgoUpdateIntervalMs: (date: Date, now?: Date) => number;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTimeAgoUpdateIntervalMs = exports.formatTimeAgo = void 0;
4
+ // Each amount is "how many of this unit make up one of the next unit".
5
+ const DIVISIONS = [
6
+ { amount: 60, unit: 'seconds' },
7
+ { amount: 60, unit: 'minutes' },
8
+ { amount: 24, unit: 'hours' },
9
+ { amount: 7, unit: 'days' },
10
+ { amount: 4.34524, unit: 'weeks' },
11
+ { amount: 12, unit: 'months' },
12
+ { amount: Number.POSITIVE_INFINITY, unit: 'years' },
13
+ ];
14
+ /**
15
+ * Formats the distance between `date` and `now` as a relative phrase
16
+ * (e.g. "5 minutes ago", "in 2 hours") using the native Intl.RelativeTimeFormat.
17
+ * Past dates are negative, future dates are positive.
18
+ */
19
+ const formatTimeAgo = (date, now = new Date(), locale) => {
20
+ // An invalid date (e.g. new Date('')) has a NaN time, which Intl.RelativeTimeFormat
21
+ // rejects — guard so callers never have to.
22
+ if (Number.isNaN(date.getTime())) {
23
+ return '';
24
+ }
25
+ const formatter = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
26
+ // Seconds between the two dates; negative for the past.
27
+ let duration = (date.getTime() - now.getTime()) / 1000;
28
+ for (const division of DIVISIONS) {
29
+ if (Math.abs(duration) < division.amount) {
30
+ return formatter.format(Math.round(duration), division.unit);
31
+ }
32
+ duration /= division.amount;
33
+ }
34
+ return formatter.format(Math.round(duration), 'years');
35
+ };
36
+ exports.formatTimeAgo = formatTimeAgo;
37
+ /**
38
+ * How long until the relative phrase could next change, so callers can
39
+ * re-render no more often than necessary.
40
+ */
41
+ const getTimeAgoUpdateIntervalMs = (date, now = new Date()) => {
42
+ const seconds = Math.abs((date.getTime() - now.getTime()) / 1000);
43
+ if (seconds < 60) {
44
+ return 1000; // seconds tick over
45
+ }
46
+ if (seconds < 60 * 60) {
47
+ return 60 * 1000; // minutes tick over
48
+ }
49
+ if (seconds < 60 * 60 * 24) {
50
+ return 60 * 60 * 1000; // hours tick over
51
+ }
52
+ return 60 * 60 * 24 * 1000; // days or coarser
53
+ };
54
+ exports.getTimeAgoUpdateIntervalMs = getTimeAgoUpdateIntervalMs;
@@ -0,0 +1,3 @@
1
+ export declare enum ApiActionType {
2
+ Request = "@quidproquo-web/Api/Request"
3
+ }
@@ -0,0 +1,4 @@
1
+ export var ApiActionType;
2
+ (function (ApiActionType) {
3
+ ApiActionType["Request"] = "@quidproquo-web/Api/Request";
4
+ })(ApiActionType || (ApiActionType = {}));
@@ -0,0 +1,3 @@
1
+ import { HTTPMethod } from 'quidproquo-core';
2
+ import { ApiRequestActionRequester, ApiRequestOptions } from './ApiRequestActionRequesterTypes';
3
+ export declare function askApiRequest<T, R>(service: string, method: HTTPMethod, endpoint: string, options?: ApiRequestOptions<T>): ApiRequestActionRequester<T, R>;
@@ -0,0 +1,15 @@
1
+ import { ApiActionType } from './ApiActionType';
2
+ export function* askApiRequest(service, method, endpoint, options) {
3
+ return yield {
4
+ type: ApiActionType.Request,
5
+ payload: {
6
+ service,
7
+ endpoint,
8
+ method,
9
+ body: options?.body,
10
+ headers: options?.headers,
11
+ params: options?.params,
12
+ responseType: options?.responseType || 'json',
13
+ },
14
+ };
15
+ }
@@ -0,0 +1,18 @@
1
+ import { Action, ActionProcessor, ActionRequester, HTTPMethod, HTTPNetworkResponse, HTTPRequestOptions, ResponseType } from 'quidproquo-core';
2
+ import { ApiActionType } from './ApiActionType';
3
+ export type ApiRequestOptions<T> = Omit<HTTPRequestOptions<T>, 'basePath'>;
4
+ export interface ApiRequestActionPayload<T> {
5
+ service: string;
6
+ endpoint: string;
7
+ method: HTTPMethod;
8
+ body?: T;
9
+ params?: Record<string, string>;
10
+ headers?: Record<string, string>;
11
+ responseType: ResponseType;
12
+ }
13
+ export interface ApiRequestAction<T> extends Action<ApiRequestActionPayload<T>> {
14
+ type: ApiActionType.Request;
15
+ payload: ApiRequestActionPayload<T>;
16
+ }
17
+ export type ApiRequestActionProcessor<T, R> = ActionProcessor<ApiRequestAction<T>, HTTPNetworkResponse<R>>;
18
+ export type ApiRequestActionRequester<T, R> = ActionRequester<ApiRequestAction<T>, HTTPNetworkResponse<R>>;
@@ -0,0 +1,3 @@
1
+ export * from './ApiActionType';
2
+ export * from './ApiRequestActionRequester';
3
+ export * from './ApiRequestActionRequesterTypes';
@@ -0,0 +1,3 @@
1
+ export * from './ApiActionType';
2
+ export * from './ApiRequestActionRequester';
3
+ export * from './ApiRequestActionRequesterTypes';
@@ -1 +1,3 @@
1
+ export * from './api';
1
2
  export * from './queryParams';
3
+ export * from './window';
@@ -1 +1,3 @@
1
+ export * from './api';
1
2
  export * from './queryParams';
3
+ export * from './window';
@@ -0,0 +1,3 @@
1
+ export declare enum WindowActionType {
2
+ GetLocation = "@quidproquo-web/Window/GetLocation"
3
+ }
@@ -0,0 +1,4 @@
1
+ export var WindowActionType;
2
+ (function (WindowActionType) {
3
+ WindowActionType["GetLocation"] = "@quidproquo-web/Window/GetLocation";
4
+ })(WindowActionType || (WindowActionType = {}));
@@ -0,0 +1,2 @@
1
+ import { WindowGetLocationActionRequester } from './WindowGetLocationActionRequesterTypes';
2
+ export declare function askWindowGetLocation(): WindowGetLocationActionRequester;
@@ -0,0 +1,4 @@
1
+ import { WindowActionType } from './WindowActionType';
2
+ export function* askWindowGetLocation() {
3
+ return yield { type: WindowActionType.GetLocation };
4
+ }
@@ -0,0 +1,19 @@
1
+ import { Action, ActionProcessor, ActionRequester } from 'quidproquo-core';
2
+ import { WindowActionType } from './WindowActionType';
3
+ export type WindowLocation = {
4
+ href: string;
5
+ origin: string;
6
+ protocol: string;
7
+ host: string;
8
+ hostname: string;
9
+ port: string;
10
+ pathname: string;
11
+ search: string;
12
+ hash: string;
13
+ };
14
+ export type WindowGetLocationActionPayload = undefined;
15
+ export interface WindowGetLocationAction extends Action<WindowGetLocationActionPayload> {
16
+ type: WindowActionType.GetLocation;
17
+ }
18
+ export type WindowGetLocationActionProcessor = ActionProcessor<WindowGetLocationAction, WindowLocation>;
19
+ export type WindowGetLocationActionRequester = ActionRequester<WindowGetLocationAction, WindowLocation>;
@@ -0,0 +1,3 @@
1
+ export * from './WindowActionType';
2
+ export * from './WindowGetLocationActionRequester';
3
+ export * from './WindowGetLocationActionRequesterTypes';
@@ -0,0 +1,3 @@
1
+ export * from './WindowActionType';
2
+ export * from './WindowGetLocationActionRequester';
3
+ export * from './WindowGetLocationActionRequesterTypes';
@@ -1,5 +1,3 @@
1
1
  export * from './actions';
2
- export * from './auth';
3
- export * from './request';
4
2
  export * from './services';
5
3
  export * from './tools';
package/lib/esm/index.js CHANGED
@@ -1,5 +1,3 @@
1
1
  export * from './actions';
2
- export * from './auth';
3
- export * from './request';
4
2
  export * from './services';
5
3
  export * from './tools';
@@ -1 +1,2 @@
1
+ export * from './timeAgo';
1
2
  export * from './uniqueBy';
@@ -1 +1,2 @@
1
+ export * from './timeAgo';
1
2
  export * from './uniqueBy';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Formats the distance between `date` and `now` as a relative phrase
3
+ * (e.g. "5 minutes ago", "in 2 hours") using the native Intl.RelativeTimeFormat.
4
+ * Past dates are negative, future dates are positive.
5
+ */
6
+ export declare const formatTimeAgo: (date: Date, now?: Date, locale?: string | string[]) => string;
7
+ /**
8
+ * How long until the relative phrase could next change, so callers can
9
+ * re-render no more often than necessary.
10
+ */
11
+ export declare const getTimeAgoUpdateIntervalMs: (date: Date, now?: Date) => number;
@@ -0,0 +1,49 @@
1
+ // Each amount is "how many of this unit make up one of the next unit".
2
+ const DIVISIONS = [
3
+ { amount: 60, unit: 'seconds' },
4
+ { amount: 60, unit: 'minutes' },
5
+ { amount: 24, unit: 'hours' },
6
+ { amount: 7, unit: 'days' },
7
+ { amount: 4.34524, unit: 'weeks' },
8
+ { amount: 12, unit: 'months' },
9
+ { amount: Number.POSITIVE_INFINITY, unit: 'years' },
10
+ ];
11
+ /**
12
+ * Formats the distance between `date` and `now` as a relative phrase
13
+ * (e.g. "5 minutes ago", "in 2 hours") using the native Intl.RelativeTimeFormat.
14
+ * Past dates are negative, future dates are positive.
15
+ */
16
+ export const formatTimeAgo = (date, now = new Date(), locale) => {
17
+ // An invalid date (e.g. new Date('')) has a NaN time, which Intl.RelativeTimeFormat
18
+ // rejects — guard so callers never have to.
19
+ if (Number.isNaN(date.getTime())) {
20
+ return '';
21
+ }
22
+ const formatter = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
23
+ // Seconds between the two dates; negative for the past.
24
+ let duration = (date.getTime() - now.getTime()) / 1000;
25
+ for (const division of DIVISIONS) {
26
+ if (Math.abs(duration) < division.amount) {
27
+ return formatter.format(Math.round(duration), division.unit);
28
+ }
29
+ duration /= division.amount;
30
+ }
31
+ return formatter.format(Math.round(duration), 'years');
32
+ };
33
+ /**
34
+ * How long until the relative phrase could next change, so callers can
35
+ * re-render no more often than necessary.
36
+ */
37
+ export const getTimeAgoUpdateIntervalMs = (date, now = new Date()) => {
38
+ const seconds = Math.abs((date.getTime() - now.getTime()) / 1000);
39
+ if (seconds < 60) {
40
+ return 1000; // seconds tick over
41
+ }
42
+ if (seconds < 60 * 60) {
43
+ return 60 * 1000; // minutes tick over
44
+ }
45
+ if (seconds < 60 * 60 * 24) {
46
+ return 60 * 60 * 1000; // hours tick over
47
+ }
48
+ return 60 * 60 * 24 * 1000; // days or coarser
49
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-web",
3
- "version": "0.0.263",
3
+ "version": "0.1.0",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -32,9 +32,9 @@
32
32
  },
33
33
  "homepage": "https://github.com/joe-coady/quidproquo#readme",
34
34
  "devDependencies": {
35
- "quidproquo-core": "0.0.263",
36
- "quidproquo-tsconfig": "0.0.263",
37
- "quidproquo-webserver": "0.0.263",
35
+ "quidproquo-core": "0.1.0",
36
+ "quidproquo-tsconfig": "0.1.0",
37
+ "quidproquo-webserver": "0.1.0",
38
38
  "typescript": "^5.8.2"
39
39
  }
40
40
  }
@@ -1,6 +0,0 @@
1
- export declare function exchangeOauth2TokenForAccessToken(code: string, authDomain: string): Promise<string | undefined>;
2
- declare global {
3
- interface Window {
4
- exchangeOauth2TokenForAccessToken: any;
5
- }
6
- }
@@ -1,26 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.exchangeOauth2TokenForAccessToken = exchangeOauth2TokenForAccessToken;
13
- const request_1 = require("../request");
14
- function exchangeOauth2TokenForAccessToken(code, authDomain) {
15
- return __awaiter(this, void 0, void 0, function* () {
16
- const oAuth2Url = `https://${authDomain}/oauth2/token/${code}`;
17
- const result = yield (0, request_1.preformNetworkRequest)({
18
- method: 'POST',
19
- url: oAuth2Url,
20
- responseType: 'json',
21
- });
22
- console.log('result: ', result);
23
- return result.data.accessToken;
24
- });
25
- }
26
- window.exchangeOauth2TokenForAccessToken = exchangeOauth2TokenForAccessToken;
@@ -1 +0,0 @@
1
- export * from './exchangeOauth2TokenForAccessToken';
@@ -1 +0,0 @@
1
- export * from './preformNetworkRequest';
@@ -1,2 +0,0 @@
1
- import { HTTPNetworkResponse, NetworkRequestActionPayload } from 'quidproquo-core';
2
- export declare const preformNetworkRequest: <R>(payload: NetworkRequestActionPayload<any>) => Promise<HTTPNetworkResponse<R>>;
@@ -1,155 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.preformNetworkRequest = void 0;
16
- const axios_1 = __importDefault(require("axios"));
17
- const mime_types_1 = require("mime-types");
18
- const getAxiosResponseType = (responseType) => {
19
- if (responseType === 'binary') {
20
- return 'arraybuffer';
21
- }
22
- return 'json';
23
- };
24
- const transformResponse = (payload, response) => {
25
- var _a, _b;
26
- if (payload.responseType === 'binary') {
27
- const headers = response.headers || {};
28
- const mimeType = headers['content-type'] || 'application/octet-stream';
29
- const filename = ((_b = (_a = headers['content-disposition']) === null || _a === void 0 ? void 0 : _a.match(/filename="([^"]+)"/)) === null || _b === void 0 ? void 0 : _b[1]) || `file.${(0, mime_types_1.extension)(mimeType)}`;
30
- return Object.assign(Object.assign({}, response), { data: {
31
- base64Data: Buffer.from(response.data).toString('base64'),
32
- mimetype: mimeType,
33
- filename,
34
- } });
35
- }
36
- return response;
37
- };
38
- const axiosInstance = axios_1.default.create({
39
- timeout: 25000,
40
- headers: {
41
- // Fixes: https://github.com/axios/axios/issues/5346
42
- 'Accept-Encoding': 'gzip,deflate,compress',
43
- },
44
- validateStatus: () => true,
45
- });
46
- const processNetworkRequestGet = (payload) => __awaiter(void 0, void 0, void 0, function* () {
47
- const response = yield axiosInstance.get(payload.url, {
48
- baseURL: payload.basePath,
49
- headers: payload.headers,
50
- params: payload.params,
51
- responseType: getAxiosResponseType(payload.responseType),
52
- });
53
- return transformResponse(payload, response);
54
- });
55
- const processNetworkRequestPost = (payload) => __awaiter(void 0, void 0, void 0, function* () {
56
- const response = yield axiosInstance.post(payload.url, payload.body, {
57
- baseURL: payload.basePath,
58
- headers: payload.headers,
59
- params: payload.params,
60
- responseType: getAxiosResponseType(payload.responseType),
61
- });
62
- return transformResponse(payload, response);
63
- });
64
- const processNetworkRequestDelete = (payload) => __awaiter(void 0, void 0, void 0, function* () {
65
- const response = yield axiosInstance.delete(payload.url, {
66
- baseURL: payload.basePath,
67
- headers: payload.headers,
68
- params: payload.params,
69
- responseType: getAxiosResponseType(payload.responseType),
70
- });
71
- return transformResponse(payload, response);
72
- });
73
- const processNetworkRequestHead = (payload) => __awaiter(void 0, void 0, void 0, function* () {
74
- const response = yield axiosInstance.head(payload.url, {
75
- baseURL: payload.basePath,
76
- headers: payload.headers,
77
- params: payload.params,
78
- responseType: getAxiosResponseType(payload.responseType),
79
- });
80
- return transformResponse(payload, response);
81
- });
82
- const processNetworkRequestOptions = (payload) => __awaiter(void 0, void 0, void 0, function* () {
83
- const response = yield axiosInstance.options(payload.url, {
84
- baseURL: payload.basePath,
85
- headers: payload.headers,
86
- params: payload.params,
87
- responseType: getAxiosResponseType(payload.responseType),
88
- });
89
- return transformResponse(payload, response);
90
- });
91
- const processNetworkRequestPut = (payload) => __awaiter(void 0, void 0, void 0, function* () {
92
- const response = yield axiosInstance.put(payload.url, payload.body, {
93
- baseURL: payload.basePath,
94
- headers: payload.headers,
95
- params: payload.params,
96
- responseType: getAxiosResponseType(payload.responseType),
97
- });
98
- return transformResponse(payload, response);
99
- });
100
- const processNetworkRequestPatch = (payload) => __awaiter(void 0, void 0, void 0, function* () {
101
- const response = yield axiosInstance.patch(payload.url, payload.body, {
102
- baseURL: payload.basePath,
103
- headers: payload.headers,
104
- params: payload.params,
105
- responseType: getAxiosResponseType(payload.responseType),
106
- });
107
- return transformResponse(payload, response);
108
- });
109
- const processNetworkRequestConnect = (payload) => __awaiter(void 0, void 0, void 0, function* () {
110
- throw new Error('Function not implemented.');
111
- });
112
- const requestMethodMap = {
113
- GET: processNetworkRequestGet,
114
- POST: processNetworkRequestPost,
115
- DELETE: processNetworkRequestDelete,
116
- HEAD: processNetworkRequestHead,
117
- OPTIONS: processNetworkRequestOptions,
118
- PUT: processNetworkRequestPut,
119
- PATCH: processNetworkRequestPatch,
120
- CONNECT: processNetworkRequestConnect,
121
- };
122
- const convertAxiosHeadersToRecord = (headers) => {
123
- const record = {};
124
- Object.keys(headers).forEach((key) => {
125
- record[key] = headers[key];
126
- });
127
- return record;
128
- };
129
- const preformNetworkRequest = (payload) => __awaiter(void 0, void 0, void 0, function* () {
130
- const requestMethod = requestMethodMap[payload.method];
131
- if (!requestMethod) {
132
- throw new Error(`Request not implemented [payload.method]`);
133
- }
134
- try {
135
- const response = yield requestMethod(payload);
136
- const httpNetworkResponse = {
137
- headers: convertAxiosHeadersToRecord(response.headers),
138
- status: response.status,
139
- statusText: response.statusText,
140
- data: response.data,
141
- };
142
- return httpNetworkResponse;
143
- }
144
- catch (err) {
145
- console.log(err);
146
- const errorResponse = {
147
- headers: {},
148
- status: 500,
149
- statusText: 'Internal Server Error',
150
- data: err.stack,
151
- };
152
- return errorResponse;
153
- }
154
- });
155
- exports.preformNetworkRequest = preformNetworkRequest;
@@ -1,6 +0,0 @@
1
- export declare function exchangeOauth2TokenForAccessToken(code: string, authDomain: string): Promise<string | undefined>;
2
- declare global {
3
- interface Window {
4
- exchangeOauth2TokenForAccessToken: any;
5
- }
6
- }
@@ -1,12 +0,0 @@
1
- import { preformNetworkRequest } from '../request';
2
- export async function exchangeOauth2TokenForAccessToken(code, authDomain) {
3
- const oAuth2Url = `https://${authDomain}/oauth2/token/${code}`;
4
- const result = await preformNetworkRequest({
5
- method: 'POST',
6
- url: oAuth2Url,
7
- responseType: 'json',
8
- });
9
- console.log('result: ', result);
10
- return result.data.accessToken;
11
- }
12
- window.exchangeOauth2TokenForAccessToken = exchangeOauth2TokenForAccessToken;
@@ -1 +0,0 @@
1
- export * from './exchangeOauth2TokenForAccessToken';
@@ -1 +0,0 @@
1
- export * from './exchangeOauth2TokenForAccessToken';
@@ -1 +0,0 @@
1
- export * from './preformNetworkRequest';
@@ -1 +0,0 @@
1
- export * from './preformNetworkRequest';
@@ -1,2 +0,0 @@
1
- import { HTTPNetworkResponse, NetworkRequestActionPayload } from 'quidproquo-core';
2
- export declare const preformNetworkRequest: <R>(payload: NetworkRequestActionPayload<any>) => Promise<HTTPNetworkResponse<R>>;
@@ -1,141 +0,0 @@
1
- import axios from 'axios';
2
- import { extension } from 'mime-types';
3
- const getAxiosResponseType = (responseType) => {
4
- if (responseType === 'binary') {
5
- return 'arraybuffer';
6
- }
7
- return 'json';
8
- };
9
- const transformResponse = (payload, response) => {
10
- if (payload.responseType === 'binary') {
11
- const headers = response.headers || {};
12
- const mimeType = headers['content-type'] || 'application/octet-stream';
13
- const filename = headers['content-disposition']?.match(/filename="([^"]+)"/)?.[1] || `file.${extension(mimeType)}`;
14
- return {
15
- ...response,
16
- data: {
17
- base64Data: Buffer.from(response.data).toString('base64'),
18
- mimetype: mimeType,
19
- filename,
20
- },
21
- };
22
- }
23
- return response;
24
- };
25
- const axiosInstance = axios.create({
26
- timeout: 25000,
27
- headers: {
28
- // Fixes: https://github.com/axios/axios/issues/5346
29
- 'Accept-Encoding': 'gzip,deflate,compress',
30
- },
31
- validateStatus: () => true,
32
- });
33
- const processNetworkRequestGet = async (payload) => {
34
- const response = await axiosInstance.get(payload.url, {
35
- baseURL: payload.basePath,
36
- headers: payload.headers,
37
- params: payload.params,
38
- responseType: getAxiosResponseType(payload.responseType),
39
- });
40
- return transformResponse(payload, response);
41
- };
42
- const processNetworkRequestPost = async (payload) => {
43
- const response = await axiosInstance.post(payload.url, payload.body, {
44
- baseURL: payload.basePath,
45
- headers: payload.headers,
46
- params: payload.params,
47
- responseType: getAxiosResponseType(payload.responseType),
48
- });
49
- return transformResponse(payload, response);
50
- };
51
- const processNetworkRequestDelete = async (payload) => {
52
- const response = await axiosInstance.delete(payload.url, {
53
- baseURL: payload.basePath,
54
- headers: payload.headers,
55
- params: payload.params,
56
- responseType: getAxiosResponseType(payload.responseType),
57
- });
58
- return transformResponse(payload, response);
59
- };
60
- const processNetworkRequestHead = async (payload) => {
61
- const response = await axiosInstance.head(payload.url, {
62
- baseURL: payload.basePath,
63
- headers: payload.headers,
64
- params: payload.params,
65
- responseType: getAxiosResponseType(payload.responseType),
66
- });
67
- return transformResponse(payload, response);
68
- };
69
- const processNetworkRequestOptions = async (payload) => {
70
- const response = await axiosInstance.options(payload.url, {
71
- baseURL: payload.basePath,
72
- headers: payload.headers,
73
- params: payload.params,
74
- responseType: getAxiosResponseType(payload.responseType),
75
- });
76
- return transformResponse(payload, response);
77
- };
78
- const processNetworkRequestPut = async (payload) => {
79
- const response = await axiosInstance.put(payload.url, payload.body, {
80
- baseURL: payload.basePath,
81
- headers: payload.headers,
82
- params: payload.params,
83
- responseType: getAxiosResponseType(payload.responseType),
84
- });
85
- return transformResponse(payload, response);
86
- };
87
- const processNetworkRequestPatch = async (payload) => {
88
- const response = await axiosInstance.patch(payload.url, payload.body, {
89
- baseURL: payload.basePath,
90
- headers: payload.headers,
91
- params: payload.params,
92
- responseType: getAxiosResponseType(payload.responseType),
93
- });
94
- return transformResponse(payload, response);
95
- };
96
- const processNetworkRequestConnect = async (payload) => {
97
- throw new Error('Function not implemented.');
98
- };
99
- const requestMethodMap = {
100
- GET: processNetworkRequestGet,
101
- POST: processNetworkRequestPost,
102
- DELETE: processNetworkRequestDelete,
103
- HEAD: processNetworkRequestHead,
104
- OPTIONS: processNetworkRequestOptions,
105
- PUT: processNetworkRequestPut,
106
- PATCH: processNetworkRequestPatch,
107
- CONNECT: processNetworkRequestConnect,
108
- };
109
- const convertAxiosHeadersToRecord = (headers) => {
110
- const record = {};
111
- Object.keys(headers).forEach((key) => {
112
- record[key] = headers[key];
113
- });
114
- return record;
115
- };
116
- export const preformNetworkRequest = async (payload) => {
117
- const requestMethod = requestMethodMap[payload.method];
118
- if (!requestMethod) {
119
- throw new Error(`Request not implemented [payload.method]`);
120
- }
121
- try {
122
- const response = await requestMethod(payload);
123
- const httpNetworkResponse = {
124
- headers: convertAxiosHeadersToRecord(response.headers),
125
- status: response.status,
126
- statusText: response.statusText,
127
- data: response.data,
128
- };
129
- return httpNetworkResponse;
130
- }
131
- catch (err) {
132
- console.log(err);
133
- const errorResponse = {
134
- headers: {},
135
- status: 500,
136
- statusText: 'Internal Server Error',
137
- data: err.stack,
138
- };
139
- return errorResponse;
140
- }
141
- };