@croct/sdk 0.10.0 → 0.11.0-alpha

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 (122) hide show
  1. package/activeRecord.js +32 -36
  2. package/cache/fallbackCache.js +15 -32
  3. package/cache/inMemoryCache.js +9 -10
  4. package/cache/index.js +1 -1
  5. package/cache/localStorageCache.js +24 -25
  6. package/channel/beaconSocketChannel.d.ts +1 -1
  7. package/channel/beaconSocketChannel.js +49 -79
  8. package/channel/channel.d.ts +1 -1
  9. package/channel/encodedChannel.js +8 -10
  10. package/channel/guaranteedChannel.d.ts +4 -4
  11. package/channel/guaranteedChannel.js +41 -43
  12. package/channel/index.js +1 -1
  13. package/channel/queuedChannel.js +35 -64
  14. package/channel/retryChannel.d.ts +1 -1
  15. package/channel/retryChannel.js +44 -77
  16. package/channel/sandboxChannel.js +17 -18
  17. package/channel/socketChannel.d.ts +4 -4
  18. package/channel/socketChannel.js +77 -79
  19. package/cid/cachedAssigner.js +15 -27
  20. package/cid/fixedAssigner.js +5 -6
  21. package/cid/index.js +1 -1
  22. package/cid/remoteAssigner.js +23 -36
  23. package/constants.d.ts +3 -2
  24. package/constants.js +6 -5
  25. package/container.d.ts +13 -6
  26. package/container.js +152 -168
  27. package/contentFetcher.d.ts +59 -0
  28. package/contentFetcher.js +129 -0
  29. package/context.d.ts +3 -3
  30. package/context.js +36 -38
  31. package/error.js +2 -2
  32. package/evaluator.d.ts +33 -24
  33. package/evaluator.js +126 -117
  34. package/eventManager.d.ts +1 -1
  35. package/eventManager.js +14 -15
  36. package/facade/contentFetcherFacade.d.ts +27 -0
  37. package/facade/contentFetcherFacade.js +40 -0
  38. package/facade/evaluatorFacade.d.ts +13 -3
  39. package/facade/evaluatorFacade.js +57 -72
  40. package/facade/sdkFacade.d.ts +10 -3
  41. package/facade/sdkFacade.js +129 -141
  42. package/facade/sessionFacade.js +6 -7
  43. package/facade/sessionPatch.js +9 -13
  44. package/facade/trackerFacade.js +32 -38
  45. package/facade/userFacade.js +10 -11
  46. package/facade/userPatch.js +9 -13
  47. package/index.js +2 -2
  48. package/logging/consoleLogger.js +18 -35
  49. package/logging/index.js +1 -1
  50. package/logging/namespacedLogger.js +14 -15
  51. package/logging/nullLogger.js +10 -13
  52. package/namespacedStorage.js +30 -47
  53. package/package.json +13 -16
  54. package/patch.d.ts +1 -1
  55. package/queue/capacityRestrictedQueue.js +17 -18
  56. package/queue/inMemoryQueue.js +22 -28
  57. package/queue/index.js +1 -1
  58. package/queue/monitoredQueue.d.ts +2 -2
  59. package/queue/monitoredQueue.js +39 -40
  60. package/queue/persistentQueue.js +33 -38
  61. package/retry/arbitraryPolicy.js +8 -10
  62. package/retry/backoffPolicy.d.ts +1 -1
  63. package/retry/backoffPolicy.js +11 -13
  64. package/retry/index.js +1 -1
  65. package/retry/maxAttemptsPolicy.js +7 -8
  66. package/retry/neverPolicy.js +6 -9
  67. package/schema/attributeSchema.js +1 -1
  68. package/schema/contentFetcherSchemas.d.ts +2 -0
  69. package/schema/contentFetcherSchemas.js +22 -0
  70. package/schema/contentSchemas.js +1 -1
  71. package/schema/contextSchemas.js +1 -1
  72. package/schema/ecommerceSchemas.js +1 -1
  73. package/schema/evaluatorSchemas.d.ts +2 -0
  74. package/schema/{evaluationSchemas.js → evaluatorSchemas.js} +3 -3
  75. package/schema/eventSchemas.js +5 -7
  76. package/schema/index.d.ts +2 -1
  77. package/schema/index.js +3 -2
  78. package/schema/loggerSchema.js +1 -1
  79. package/schema/operationSchemas.js +8 -8
  80. package/schema/sdkFacadeSchemas.js +9 -6
  81. package/schema/sdkSchemas.js +8 -5
  82. package/schema/tokenSchema.js +5 -4
  83. package/schema/userSchema.js +2 -2
  84. package/sdk.d.ts +9 -3
  85. package/sdk.js +81 -127
  86. package/sdkEvents.d.ts +3 -3
  87. package/sourceLocation.d.ts +3 -3
  88. package/sourceLocation.js +13 -14
  89. package/tab.d.ts +5 -5
  90. package/tab.js +50 -80
  91. package/token/cachedTokenStore.js +9 -10
  92. package/token/inMemoryTokenStore.js +7 -8
  93. package/token/index.js +1 -1
  94. package/token/replicatedTokenStore.js +7 -8
  95. package/token/token.d.ts +9 -5
  96. package/token/token.js +63 -57
  97. package/tracker.d.ts +4 -4
  98. package/tracker.js +145 -122
  99. package/trackingEvents.d.ts +36 -36
  100. package/trackingEvents.js +12 -6
  101. package/transformer.js +1 -1
  102. package/utilityTypes.d.ts +2 -2
  103. package/uuid.js +9 -7
  104. package/validation/arrayType.d.ts +2 -2
  105. package/validation/arrayType.js +29 -27
  106. package/validation/booleanType.js +11 -15
  107. package/validation/functionType.js +11 -15
  108. package/validation/index.js +1 -1
  109. package/validation/jsonType.d.ts +2 -2
  110. package/validation/jsonType.js +61 -80
  111. package/validation/mixedSchema.js +4 -7
  112. package/validation/nullType.js +11 -15
  113. package/validation/numberType.d.ts +1 -1
  114. package/validation/numberType.js +23 -22
  115. package/validation/objectType.d.ts +1 -1
  116. package/validation/objectType.js +61 -72
  117. package/validation/schema.js +6 -10
  118. package/validation/stringType.d.ts +1 -1
  119. package/validation/stringType.js +36 -47
  120. package/validation/unionType.js +27 -77
  121. package/validation/violation.js +1 -2
  122. package/schema/evaluationSchemas.d.ts +0 -2
package/context.js CHANGED
@@ -1,70 +1,69 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Context = void 0;
4
- var token_1 = require("./token");
5
- var tab_1 = require("./tab");
6
- var uuid_1 = require("./uuid");
4
+ const token_1 = require("./token");
5
+ const tab_1 = require("./tab");
6
+ const uuid_1 = require("./uuid");
7
7
  function tokenEquals(left, right) {
8
8
  return left === right || (left !== null && right !== null && left.toString() === right.toString());
9
9
  }
10
- var Context = /** @class */ (function () {
11
- function Context(tab, tokenStore, eventDispatcher) {
10
+ class Context {
11
+ constructor(tab, tokenStore, eventDispatcher) {
12
12
  this.tab = tab;
13
13
  this.tokenStore = tokenStore;
14
14
  this.eventDispatcher = eventDispatcher;
15
15
  this.lastToken = tokenStore.getToken();
16
16
  this.syncToken = this.syncToken.bind(this);
17
17
  }
18
- Context.load = function (_a) {
19
- var cache = _a.cache, tokenScope = _a.tokenScope, eventDispatcher = _a.eventDispatcher, urlSanitizer = _a.urlSanitizer;
20
- var tabId = cache.tabId.get();
21
- var newTab = false;
18
+ static load({ cache, tokenScope, eventDispatcher, urlSanitizer }) {
19
+ let tabId = cache.tabId.get();
20
+ let newTab = false;
22
21
  if (tabId === null) {
23
22
  tabId = (0, uuid_1.uuid4)(true);
24
23
  newTab = true;
25
24
  }
26
- var tab = new tab_1.Tab(tabId, newTab, urlSanitizer);
25
+ const tab = new tab_1.Tab(tabId, newTab, urlSanitizer);
27
26
  cache.tabId.clear();
28
- tab.addListener('unload', function () { return cache.tabId.put(tab.id); });
27
+ tab.addListener('unload', () => cache.tabId.put(tab.id));
29
28
  switch (tokenScope) {
30
29
  case 'isolated':
31
30
  return new Context(tab, new token_1.InMemoryTokenStore(), eventDispatcher);
32
31
  case 'global': {
33
- var context = new Context(tab, new token_1.CachedTokenStore(cache.browserToken), eventDispatcher);
32
+ const context = new Context(tab, new token_1.CachedTokenStore(cache.browserToken), eventDispatcher);
34
33
  cache.browserToken.addListener(context.syncToken);
35
34
  return context;
36
35
  }
37
36
  case 'contextual': {
38
- var primaryStorage_1 = new token_1.CachedTokenStore(cache.tabToken);
39
- var secondaryStorage_1 = new token_1.CachedTokenStore(cache.browserToken);
37
+ const primaryStorage = new token_1.CachedTokenStore(cache.tabToken);
38
+ const secondaryStorage = new token_1.CachedTokenStore(cache.browserToken);
40
39
  if (tab.isNew) {
41
- primaryStorage_1.setToken(secondaryStorage_1.getToken());
40
+ primaryStorage.setToken(secondaryStorage.getToken());
42
41
  }
43
- tab.addListener('visibilityChange', function (event) {
42
+ tab.addListener('visibilityChange', event => {
44
43
  if (event.detail.visible) {
45
- secondaryStorage_1.setToken(primaryStorage_1.getToken());
44
+ secondaryStorage.setToken(primaryStorage.getToken());
46
45
  }
47
46
  });
48
- return new Context(tab, new token_1.ReplicatedTokenStore(primaryStorage_1, secondaryStorage_1), eventDispatcher);
47
+ return new Context(tab, new token_1.ReplicatedTokenStore(primaryStorage, secondaryStorage), eventDispatcher);
49
48
  }
50
49
  }
51
- };
52
- Context.prototype.getTab = function () {
50
+ }
51
+ getTab() {
53
52
  return this.tab;
54
- };
55
- Context.prototype.isAnonymous = function () {
56
- var token = this.getToken();
53
+ }
54
+ isAnonymous() {
55
+ const token = this.getToken();
57
56
  return token == null || token.isAnonymous();
58
- };
59
- Context.prototype.getUser = function () {
60
- var token = this.getToken();
57
+ }
58
+ getUser() {
59
+ const token = this.getToken();
61
60
  return token == null ? null : token.getSubject();
62
- };
63
- Context.prototype.getToken = function () {
61
+ }
62
+ getToken() {
64
63
  return this.tokenStore.getToken();
65
- };
66
- Context.prototype.setToken = function (token) {
67
- var oldToken = this.lastToken;
64
+ }
65
+ setToken(token) {
66
+ const oldToken = this.lastToken;
68
67
  this.lastToken = token;
69
68
  this.tokenStore.setToken(token);
70
69
  if (!tokenEquals(oldToken, token)) {
@@ -73,10 +72,10 @@ var Context = /** @class */ (function () {
73
72
  newToken: token,
74
73
  });
75
74
  }
76
- };
77
- Context.prototype.syncToken = function () {
78
- var newToken = this.tokenStore.getToken();
79
- var oldToken = this.lastToken;
75
+ }
76
+ syncToken() {
77
+ const newToken = this.tokenStore.getToken();
78
+ const oldToken = this.lastToken;
80
79
  if (!tokenEquals(oldToken, newToken)) {
81
80
  this.lastToken = newToken;
82
81
  this.eventDispatcher.dispatch('tokenChanged', {
@@ -84,7 +83,6 @@ var Context = /** @class */ (function () {
84
83
  newToken: newToken,
85
84
  });
86
85
  }
87
- };
88
- return Context;
89
- }());
86
+ }
87
+ }
90
88
  exports.Context = Context;
package/error.js CHANGED
@@ -11,7 +11,7 @@ function extractMessage(error) {
11
11
  return 'unknown error';
12
12
  }
13
13
  function formatMessage(error) {
14
- var message = extractMessage(error);
14
+ const message = extractMessage(error);
15
15
  if (message.length === 0) {
16
16
  return message;
17
17
  }
@@ -19,7 +19,7 @@ function formatMessage(error) {
19
19
  }
20
20
  exports.formatMessage = formatMessage;
21
21
  function formatCause(error) {
22
- var message = formatMessage(error);
22
+ const message = formatMessage(error);
23
23
  if (message.length === 0) {
24
24
  return message;
25
25
  }
package/evaluator.d.ts CHANGED
@@ -1,45 +1,47 @@
1
1
  import { JsonObject, JsonValue } from '@croct/json';
2
- import { TokenProvider } from './token';
2
+ import { Token } from './token';
3
3
  import { Location } from './sourceLocation';
4
- import { CidAssigner } from './cid';
5
- export declare type Configuration = {
6
- appId: string;
7
- endpointUrl?: string;
8
- tokenProvider: TokenProvider;
9
- cidAssigner: CidAssigner;
10
- };
11
- export declare type Campaign = {
4
+ export type Campaign = {
12
5
  name?: string;
13
6
  source?: string;
14
7
  medium?: string;
15
8
  term?: string;
16
9
  content?: string;
17
10
  };
18
- export declare type Page = {
19
- title: string;
11
+ export type Page = {
20
12
  url: string;
13
+ title?: string;
21
14
  referrer?: string;
22
15
  };
23
- export declare type EvaluationContext = {
24
- timezone?: string;
16
+ export type EvaluationContext = {
17
+ timeZone?: string;
25
18
  campaign?: Campaign;
26
19
  page?: Page;
27
20
  attributes?: JsonObject;
28
21
  };
29
- export declare type EvaluationOptions = {
22
+ type AllowedFetchOptions = Exclude<keyof RequestInit, 'method' | 'body' | 'headers' | 'signal'>;
23
+ type ExtraFetchOptions<T extends keyof RequestInit = AllowedFetchOptions> = Pick<RequestInit, T> & {
24
+ [key in Exclude<keyof RequestInit, T>]?: never;
25
+ } & Record<string, any>;
26
+ export type EvaluationOptions = {
27
+ clientId?: string;
28
+ clientIp?: string;
29
+ userAgent?: string;
30
+ userToken?: Token | string;
30
31
  timeout?: number;
31
32
  context?: EvaluationContext;
33
+ extra?: ExtraFetchOptions;
32
34
  };
33
35
  export declare enum EvaluationErrorType {
34
36
  TIMEOUT = "https://croct.help/api/evaluation#timeout",
35
37
  UNEXPECTED_ERROR = "https://croct.help/api/evaluation#unexpected-error",
36
- INVALID_EXPRESSION = "https://croct.help/api/evaluation#invalid-expression",
37
- TOO_COMPLEX_EXPRESSION = "https://croct.help/api/evaluation#too-complex-expression",
38
+ INVALID_QUERY = "https://croct.help/api/evaluation#invalid-query",
39
+ TOO_COMPLEX_QUERY = "https://croct.help/api/evaluation#too-complex-query",
38
40
  EVALUATION_FAILED = "https://croct.help/api/evaluation#evaluation-failed",
39
41
  UNALLOWED_RESULT = "https://croct.help/api/evaluation#unallowed-result",
40
42
  UNSERIALIZABLE_RESULT = "https://croct.help/api/evaluation#unserializable-result"
41
43
  }
42
- export declare type ErrorResponse = {
44
+ export type ErrorResponse = {
43
45
  type: EvaluationErrorType;
44
46
  title: string;
45
47
  status: number;
@@ -49,21 +51,28 @@ export declare class EvaluationError<T extends ErrorResponse = ErrorResponse> ex
49
51
  readonly response: T;
50
52
  constructor(response: T);
51
53
  }
52
- declare type ExpressionErrorDetail = {
54
+ type QueryErrorDetail = {
53
55
  cause: string;
54
56
  location: Location;
55
57
  };
56
- export declare type ExpressionErrorResponse = ErrorResponse & {
57
- errors: ExpressionErrorDetail[];
58
+ export type QueryErrorResponse = ErrorResponse & {
59
+ errors: QueryErrorDetail[];
58
60
  };
59
- export declare class ExpressionError extends EvaluationError<ExpressionErrorResponse> {
60
- constructor(response: ExpressionErrorResponse);
61
+ export declare class QueryError extends EvaluationError<QueryErrorResponse> {
62
+ constructor(response: QueryErrorResponse);
61
63
  }
64
+ export type Configuration = {
65
+ appId?: string;
66
+ apiKey?: string;
67
+ endpointUrl?: string;
68
+ };
62
69
  export declare class Evaluator {
63
- static readonly MAX_EXPRESSION_LENGTH: number;
70
+ static readonly MAX_QUERY_LENGTH: number;
64
71
  private readonly configuration;
72
+ private readonly endpoint;
65
73
  constructor(configuration: Configuration);
66
- evaluate(expression: string, options?: EvaluationOptions): Promise<JsonValue>;
74
+ evaluate(query: string, options?: EvaluationOptions): Promise<JsonValue>;
67
75
  private fetch;
76
+ toJSON(): never;
68
77
  }
69
78
  export {};
package/evaluator.js CHANGED
@@ -1,138 +1,147 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Evaluator = exports.ExpressionError = exports.EvaluationError = exports.EvaluationErrorType = void 0;
4
- var tslib_1 = require("tslib");
5
- var constants_1 = require("./constants");
6
- var error_1 = require("./error");
7
- var sourceLocation_1 = require("./sourceLocation");
3
+ exports.Evaluator = exports.QueryError = exports.EvaluationError = exports.EvaluationErrorType = void 0;
4
+ const constants_1 = require("./constants");
5
+ const error_1 = require("./error");
6
+ const sourceLocation_1 = require("./sourceLocation");
8
7
  var EvaluationErrorType;
9
8
  (function (EvaluationErrorType) {
10
9
  EvaluationErrorType["TIMEOUT"] = "https://croct.help/api/evaluation#timeout";
11
10
  EvaluationErrorType["UNEXPECTED_ERROR"] = "https://croct.help/api/evaluation#unexpected-error";
12
- EvaluationErrorType["INVALID_EXPRESSION"] = "https://croct.help/api/evaluation#invalid-expression";
13
- EvaluationErrorType["TOO_COMPLEX_EXPRESSION"] = "https://croct.help/api/evaluation#too-complex-expression";
11
+ EvaluationErrorType["INVALID_QUERY"] = "https://croct.help/api/evaluation#invalid-query";
12
+ EvaluationErrorType["TOO_COMPLEX_QUERY"] = "https://croct.help/api/evaluation#too-complex-query";
14
13
  EvaluationErrorType["EVALUATION_FAILED"] = "https://croct.help/api/evaluation#evaluation-failed";
15
14
  EvaluationErrorType["UNALLOWED_RESULT"] = "https://croct.help/api/evaluation#unallowed-result";
16
15
  EvaluationErrorType["UNSERIALIZABLE_RESULT"] = "https://croct.help/api/evaluation#unserializable-result";
17
16
  })(EvaluationErrorType = exports.EvaluationErrorType || (exports.EvaluationErrorType = {}));
18
- var EvaluationError = /** @class */ (function (_super) {
19
- tslib_1.__extends(EvaluationError, _super);
20
- function EvaluationError(response) {
21
- var _this = _super.call(this, response.title) || this;
22
- _this.response = response;
23
- Object.setPrototypeOf(_this, EvaluationError.prototype);
24
- return _this;
17
+ class EvaluationError extends Error {
18
+ constructor(response) {
19
+ super(response.title);
20
+ this.response = response;
21
+ Object.setPrototypeOf(this, EvaluationError.prototype);
25
22
  }
26
- return EvaluationError;
27
- }(Error));
23
+ }
28
24
  exports.EvaluationError = EvaluationError;
29
- var ExpressionError = /** @class */ (function (_super) {
30
- tslib_1.__extends(ExpressionError, _super);
31
- function ExpressionError(response) {
32
- var _this = _super.call(this, response) || this;
33
- Object.setPrototypeOf(_this, ExpressionError.prototype);
34
- return _this;
25
+ class QueryError extends EvaluationError {
26
+ constructor(response) {
27
+ super(response);
28
+ Object.setPrototypeOf(this, QueryError.prototype);
35
29
  }
36
- return ExpressionError;
37
- }(EvaluationError));
38
- exports.ExpressionError = ExpressionError;
39
- var Evaluator = /** @class */ (function () {
40
- function Evaluator(configuration) {
41
- var _a;
42
- this.configuration = tslib_1.__assign(tslib_1.__assign({}, configuration), { endpointUrl: (_a = configuration.endpointUrl) !== null && _a !== void 0 ? _a : constants_1.EVALUATION_ENDPOINT_URL });
30
+ }
31
+ exports.QueryError = QueryError;
32
+ class Evaluator {
33
+ constructor(configuration) {
34
+ if ((configuration.appId === undefined) === (configuration.apiKey === undefined)) {
35
+ throw new Error('Either the application ID or the API key must be provided.');
36
+ }
37
+ const { endpointUrl, apiKey } = configuration;
38
+ // eslint-disable-next-line prefer-template -- Better readability
39
+ this.endpoint = (endpointUrl !== null && endpointUrl !== void 0 ? endpointUrl : constants_1.EVALUATION_ENDPOINT_URL).replace(/\/+$/, '')
40
+ + (apiKey === undefined ? '/client' : '/external')
41
+ + '/web/evaluate';
42
+ this.configuration = configuration;
43
43
  }
44
- Evaluator.prototype.evaluate = function (expression, options) {
45
- if (options === void 0) { options = {}; }
46
- return tslib_1.__awaiter(this, void 0, void 0, function () {
47
- var length, response, endpoint;
48
- var _this = this;
49
- return tslib_1.__generator(this, function (_a) {
50
- length = (0, sourceLocation_1.getLength)(expression);
51
- if (length > Evaluator.MAX_EXPRESSION_LENGTH) {
52
- response = {
53
- title: 'The expression is too complex.',
54
- status: 422,
55
- type: EvaluationErrorType.TOO_COMPLEX_EXPRESSION,
56
- detail: "The expression must be at most ".concat(Evaluator.MAX_EXPRESSION_LENGTH, " characters long, ")
57
- + "but it is ".concat(length, " characters long."),
58
- errors: [{
59
- cause: 'The expression is longer than expected.',
60
- location: (0, sourceLocation_1.getLocation)(expression, 0, Math.max(length - 1, 0)),
61
- }],
44
+ evaluate(query, options = {}) {
45
+ const length = (0, sourceLocation_1.getLength)(query);
46
+ if (length > Evaluator.MAX_QUERY_LENGTH) {
47
+ const response = {
48
+ title: 'The query is too complex.',
49
+ status: 422,
50
+ type: EvaluationErrorType.TOO_COMPLEX_QUERY,
51
+ detail: `The query must be at most ${Evaluator.MAX_QUERY_LENGTH} characters long, `
52
+ + `but it is ${length} characters long.`,
53
+ errors: [{
54
+ cause: 'The query is longer than expected.',
55
+ location: (0, sourceLocation_1.getLocation)(query, 0, Math.max(length - 1, 0)),
56
+ }],
57
+ };
58
+ return Promise.reject(new QueryError(response));
59
+ }
60
+ const body = {
61
+ query: query,
62
+ };
63
+ if (options.context !== undefined) {
64
+ body.context = options.context;
65
+ }
66
+ return new Promise((resolve, reject) => {
67
+ const abortController = new AbortController();
68
+ if (options.timeout !== undefined) {
69
+ setTimeout(() => {
70
+ const response = {
71
+ title: 'Maximum evaluation timeout reached before evaluation could complete.',
72
+ type: EvaluationErrorType.TIMEOUT,
73
+ detail: `The evaluation took more than ${options.timeout}ms to complete.`,
74
+ status: 408, // Request Timeout
62
75
  };
63
- return [2 /*return*/, Promise.reject(new ExpressionError(response))];
76
+ abortController.abort();
77
+ reject(new EvaluationError(response));
78
+ }, options.timeout);
79
+ }
80
+ const promise = this.fetch(body, abortController.signal, options);
81
+ promise.then(response => response.json()
82
+ .then(data => {
83
+ if (response.ok) {
84
+ return resolve(data);
64
85
  }
65
- endpoint = new URL(this.configuration.endpointUrl);
66
- endpoint.searchParams.append('expression', expression);
67
- if (options.context !== undefined) {
68
- endpoint.searchParams.append('context', JSON.stringify(options.context));
86
+ const errorResponse = data;
87
+ switch (errorResponse.type) {
88
+ case EvaluationErrorType.INVALID_QUERY:
89
+ case EvaluationErrorType.EVALUATION_FAILED:
90
+ case EvaluationErrorType.TOO_COMPLEX_QUERY:
91
+ reject(new QueryError(errorResponse));
92
+ break;
93
+ default:
94
+ reject(new EvaluationError(errorResponse));
95
+ break;
69
96
  }
70
- return [2 /*return*/, new Promise(function (resolve, reject) {
71
- if (options.timeout !== undefined) {
72
- window.setTimeout(function () {
73
- var response = {
74
- title: 'Maximum evaluation timeout reached before evaluation could complete.',
75
- type: EvaluationErrorType.TIMEOUT,
76
- detail: "The evaluation took more than ".concat(options.timeout, "ms to complete."),
77
- status: 408, // Request Timeout
78
- };
79
- reject(new EvaluationError(response));
80
- }, options.timeout);
81
- }
82
- var promise = _this.fetch(endpoint.toString());
83
- promise.then(function (response) {
84
- if (response.ok) {
85
- response.json().then(resolve);
86
- return;
87
- }
88
- response.json().then(function (result) {
89
- var errorResponse = result;
90
- switch (errorResponse.type) {
91
- case EvaluationErrorType.INVALID_EXPRESSION:
92
- case EvaluationErrorType.EVALUATION_FAILED:
93
- case EvaluationErrorType.TOO_COMPLEX_EXPRESSION:
94
- reject(new ExpressionError(errorResponse));
95
- break;
96
- default:
97
- reject(new EvaluationError(errorResponse));
98
- break;
99
- }
100
- });
101
- }, function (error) {
102
- var errorResponse = {
103
- title: (0, error_1.formatMessage)(error),
104
- type: EvaluationErrorType.UNEXPECTED_ERROR,
105
- detail: 'Please try again or contact Croct support if the error persists.',
106
- status: 500, // Internal Server Error
107
- };
108
- reject(new EvaluationError(errorResponse));
109
- });
110
- })];
111
- });
112
- });
113
- };
114
- Evaluator.prototype.fetch = function (endpoint) {
115
- return tslib_1.__awaiter(this, void 0, void 0, function () {
116
- var _a, tokenProvider, cidAssigner, appId, token, cid, headers;
117
- return tslib_1.__generator(this, function (_b) {
118
- switch (_b.label) {
119
- case 0:
120
- _a = this.configuration, tokenProvider = _a.tokenProvider, cidAssigner = _a.cidAssigner, appId = _a.appId;
121
- token = tokenProvider.getToken();
122
- return [4 /*yield*/, cidAssigner.assignCid()];
123
- case 1:
124
- cid = _b.sent();
125
- headers = tslib_1.__assign({ 'X-App-Id': appId, 'X-Client-Id': cid }, (token !== null && { 'X-Token': token.toString() }));
126
- return [2 /*return*/, window.fetch(endpoint.toString(), {
127
- method: 'GET',
128
- headers: headers,
129
- credentials: 'include',
130
- })];
97
+ }))
98
+ .catch(error => {
99
+ if (!abortController.signal.aborted) {
100
+ reject(new EvaluationError({
101
+ title: (0, error_1.formatMessage)(error),
102
+ type: EvaluationErrorType.UNEXPECTED_ERROR,
103
+ detail: 'Please try again or contact Croct support if the error persists.',
104
+ status: 500, // Internal Server Error
105
+ }));
131
106
  }
132
107
  });
133
108
  });
134
- };
135
- Evaluator.MAX_EXPRESSION_LENGTH = constants_1.MAX_EXPRESSION_LENGTH;
136
- return Evaluator;
137
- }());
109
+ }
110
+ fetch(body, signal, options) {
111
+ const { appId, apiKey } = this.configuration;
112
+ const { clientId, clientIp, userAgent, userToken } = options;
113
+ const headers = new Headers();
114
+ if (apiKey !== undefined) {
115
+ headers.set('X-Api-Key', apiKey);
116
+ }
117
+ else if (appId !== undefined) {
118
+ headers.set('X-App-Id', appId);
119
+ }
120
+ if (clientId !== undefined) {
121
+ headers.set('X-Client-Id', clientId);
122
+ }
123
+ if (clientIp !== undefined) {
124
+ headers.set('X-Client-Ip', clientIp);
125
+ }
126
+ if (userToken !== undefined) {
127
+ headers.set('X-Token', userToken.toString());
128
+ }
129
+ if (userAgent !== undefined) {
130
+ headers.set('User-Agent', userAgent);
131
+ }
132
+ return fetch(this.endpoint, {
133
+ credentials: 'omit',
134
+ ...options.extra,
135
+ method: 'POST',
136
+ headers: headers,
137
+ signal: signal,
138
+ body: JSON.stringify(body),
139
+ });
140
+ }
141
+ toJSON() {
142
+ // Prevent sensitive configuration from being serialized
143
+ throw new Error('Unserializable value.');
144
+ }
145
+ }
138
146
  exports.Evaluator = Evaluator;
147
+ Evaluator.MAX_QUERY_LENGTH = constants_1.MAX_QUERY_LENGTH;
package/eventManager.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export interface EventListener<T> {
2
2
  (event: T): void;
3
3
  }
4
- export declare type EventMap = Record<string, Record<string, any>>;
4
+ export type EventMap = Record<string, Record<string, any>>;
5
5
  export interface EventDispatcher<TEvents extends EventMap> {
6
6
  dispatch<T extends keyof TEvents>(eventName: T, event: TEvents[T]): void;
7
7
  }
package/eventManager.js CHANGED
@@ -1,32 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SynchronousEventManager = void 0;
4
- var SynchronousEventManager = /** @class */ (function () {
5
- function SynchronousEventManager() {
4
+ class SynchronousEventManager {
5
+ constructor() {
6
6
  this.listeners = {};
7
7
  }
8
- SynchronousEventManager.prototype.addListener = function (type, listener) {
8
+ addListener(type, listener) {
9
9
  var _a;
10
- var listeners = (_a = this.listeners[type]) !== null && _a !== void 0 ? _a : [];
10
+ const listeners = (_a = this.listeners[type]) !== null && _a !== void 0 ? _a : [];
11
11
  listeners.push(listener);
12
12
  this.listeners[type] = listeners;
13
- };
14
- SynchronousEventManager.prototype.removeListener = function (eventName, listener) {
15
- var listeners = this.listeners[eventName];
13
+ }
14
+ removeListener(eventName, listener) {
15
+ const listeners = this.listeners[eventName];
16
16
  if (listeners === undefined) {
17
17
  return;
18
18
  }
19
- var index = listeners.indexOf(listener);
19
+ const index = listeners.indexOf(listener);
20
20
  if (index >= 0) {
21
21
  listeners.splice(index, 1);
22
22
  }
23
- };
24
- SynchronousEventManager.prototype.dispatch = function (eventName, event) {
25
- var listeners = this.listeners[eventName];
23
+ }
24
+ dispatch(eventName, event) {
25
+ const listeners = this.listeners[eventName];
26
26
  if (listeners !== undefined) {
27
- listeners.forEach(function (listener) { return listener(event); });
27
+ listeners.forEach(listener => listener(event));
28
28
  }
29
- };
30
- return SynchronousEventManager;
31
- }());
29
+ }
30
+ }
32
31
  exports.SynchronousEventManager = SynchronousEventManager;
@@ -0,0 +1,27 @@
1
+ import { JsonObject } from '@croct/json';
2
+ import { ContentFetcher, FetchResponse } from '../contentFetcher';
3
+ import { ContextFactory } from './evaluatorFacade';
4
+ import { TokenProvider } from '../token';
5
+ import { CidAssigner } from '../cid';
6
+ export type FetchOptions = {
7
+ version?: `${number}` | number;
8
+ preferredLocale?: string;
9
+ timeout?: number;
10
+ attributes?: JsonObject;
11
+ };
12
+ export type Configuration = {
13
+ contentFetcher: ContentFetcher;
14
+ contextFactory: ContextFactory;
15
+ previewTokenProvider: TokenProvider;
16
+ userTokenProvider: TokenProvider;
17
+ cidAssigner: CidAssigner;
18
+ };
19
+ export declare class ContentFetcherFacade {
20
+ private readonly fetcher;
21
+ private readonly contextFactory;
22
+ private readonly previewTokenProvider;
23
+ private readonly userTokenProvider;
24
+ private readonly cidAssigner;
25
+ constructor(configuration: Configuration);
26
+ fetch<P extends JsonObject>(slotId: string, options?: FetchOptions): Promise<FetchResponse<P>>;
27
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContentFetcherFacade = void 0;
4
+ const error_1 = require("../error");
5
+ const schema_1 = require("../schema");
6
+ function validate(options) {
7
+ try {
8
+ schema_1.fetchOptionsSchema.validate(options);
9
+ }
10
+ catch (violation) {
11
+ throw new Error(`Invalid options: ${(0, error_1.formatCause)(violation)}`);
12
+ }
13
+ }
14
+ class ContentFetcherFacade {
15
+ constructor(configuration) {
16
+ this.fetcher = configuration.contentFetcher;
17
+ this.previewTokenProvider = configuration.previewTokenProvider;
18
+ this.userTokenProvider = configuration.userTokenProvider;
19
+ this.cidAssigner = configuration.cidAssigner;
20
+ this.contextFactory = configuration.contextFactory;
21
+ }
22
+ async fetch(slotId, options = {}) {
23
+ var _a, _b;
24
+ if (typeof slotId !== 'string' || slotId.length === 0) {
25
+ throw new Error('The slot ID must be a non-empty string.');
26
+ }
27
+ validate(options);
28
+ return this.fetcher.fetch(slotId, {
29
+ static: false,
30
+ clientId: await this.cidAssigner.assignCid(),
31
+ userToken: (_a = this.userTokenProvider.getToken()) !== null && _a !== void 0 ? _a : undefined,
32
+ previewToken: (_b = this.previewTokenProvider.getToken()) !== null && _b !== void 0 ? _b : undefined,
33
+ version: options.version,
34
+ preferredLocale: options.preferredLocale,
35
+ context: this.contextFactory.createContext(options.attributes),
36
+ timeout: options.timeout,
37
+ });
38
+ }
39
+ }
40
+ exports.ContentFetcherFacade = ContentFetcherFacade;