@croct/sdk 0.17.8 → 0.17.10
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.
- package/activeRecord.cjs +135 -0
- package/apiKey.cjs +178 -0
- package/base64Url.cjs +41 -0
- package/cache/cache.cjs +34 -0
- package/cache/cookieCache.cjs +85 -0
- package/cache/fallbackCache.cjs +47 -0
- package/cache/inMemoryCache.cjs +41 -0
- package/cache/index.cjs +37 -0
- package/cache/localStorageCache.cjs +81 -0
- package/channel/channel.cjs +48 -0
- package/channel/encodedChannel.cjs +39 -0
- package/channel/guaranteedChannel.cjs +105 -0
- package/channel/httpBeaconChannel.cjs +111 -0
- package/channel/index.cjs +46 -0
- package/channel/queuedChannel.cjs +122 -0
- package/channel/retryChannel.cjs +87 -0
- package/channel/sandboxChannel.cjs +63 -0
- package/cid/assigner.cjs +16 -0
- package/cid/cachedAssigner.cjs +66 -0
- package/cid/fixedAssigner.cjs +35 -0
- package/cid/index.cjs +37 -0
- package/cid/remoteAssigner.cjs +65 -0
- package/constants.cjs +37 -0
- package/constants.cjs.map +1 -1
- package/constants.d.ts +2 -2
- package/constants.js +1 -1
- package/constants.js.map +1 -1
- package/container.cjs +305 -0
- package/contentFetcher.cjs +193 -0
- package/context.cjs +114 -0
- package/error.cjs +52 -0
- package/evaluator.cjs +219 -0
- package/eventManager.cjs +53 -0
- package/eventSubjectProcessor.cjs +84 -0
- package/facade/contentFetcherFacade.cjs +61 -0
- package/facade/evaluatorFacade.cjs +94 -0
- package/facade/index.cjs +52 -0
- package/facade/sdkFacade.cjs +229 -0
- package/facade/sessionFacade.cjs +36 -0
- package/facade/sessionPatch.cjs +48 -0
- package/facade/trackerFacade.cjs +87 -0
- package/facade/userFacade.cjs +43 -0
- package/facade/userPatch.cjs +48 -0
- package/help.cjs +45 -0
- package/index.cjs +33 -0
- package/logging/consoleLogger.cjs +50 -0
- package/logging/filteredLogger.cjs +62 -0
- package/logging/index.cjs +40 -0
- package/logging/logger.cjs +16 -0
- package/logging/namespacedLogger.cjs +48 -0
- package/logging/nullLogger.cjs +37 -0
- package/namespacedStorage.cjs +77 -0
- package/package.json +29 -28
- package/patch.cjs +16 -0
- package/queue/capacityRestrictedQueue.cjs +57 -0
- package/queue/inMemoryQueue.cjs +58 -0
- package/queue/index.cjs +40 -0
- package/queue/monitoredQueue.cjs +141 -0
- package/queue/persistentQueue.cjs +78 -0
- package/queue/queue.cjs +16 -0
- package/retry/arbitraryPolicy.cjs +41 -0
- package/retry/backoffPolicy.cjs +81 -0
- package/retry/index.cjs +40 -0
- package/retry/maxAttemptsPolicy.cjs +45 -0
- package/retry/neverPolicy.cjs +35 -0
- package/retry/policy.cjs +16 -0
- package/schema/attributeSchema.cjs +32 -0
- package/schema/contentFetcherSchemas.cjs +49 -0
- package/schema/contentSchemas.cjs +70 -0
- package/schema/contextSchemas.cjs +31 -0
- package/schema/ecommerceSchemas.cjs +209 -0
- package/schema/evaluatorSchemas.cjs +64 -0
- package/schema/eventSchemas.cjs +162 -0
- package/schema/index.cjs +42 -0
- package/schema/loggerSchema.cjs +38 -0
- package/schema/operationSchemas.cjs +122 -0
- package/schema/sdkFacadeSchemas.cjs +82 -0
- package/schema/sdkSchemas.cjs +110 -0
- package/schema/tokenSchema.cjs +68 -0
- package/schema/userSchema.cjs +202 -0
- package/sdk.cjs +134 -0
- package/sdkEvents.cjs +16 -0
- package/sourceLocation.cjs +92 -0
- package/tab.cjs +122 -0
- package/token/cachedTokenStore.cjs +51 -0
- package/token/inMemoryTokenStore.cjs +38 -0
- package/token/index.cjs +37 -0
- package/token/replicatedTokenStore.cjs +40 -0
- package/token/token.cjs +239 -0
- package/tracker.cjs +358 -0
- package/trackingEvents.cjs +94 -0
- package/transformer.cjs +30 -0
- package/utilityTypes.cjs +16 -0
- package/uuid.cjs +55 -0
- package/validation/arrayType.cjs +75 -0
- package/validation/booleanType.cjs +46 -0
- package/validation/functionType.cjs +46 -0
- package/validation/index.cjs +66 -0
- package/validation/jsonType.cjs +142 -0
- package/validation/mixedSchema.cjs +31 -0
- package/validation/nullType.cjs +46 -0
- package/validation/numberType.cjs +69 -0
- package/validation/objectType.cjs +114 -0
- package/validation/schema.cjs +34 -0
- package/validation/stringType.cjs +106 -0
- package/validation/unionType.cjs +67 -0
- package/validation/violation.cjs +47 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var contentFetcher_exports = {};
|
|
19
|
+
__export(contentFetcher_exports, {
|
|
20
|
+
ContentError: () => ContentError,
|
|
21
|
+
ContentErrorType: () => ContentErrorType,
|
|
22
|
+
ContentFetcher: () => ContentFetcher
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(contentFetcher_exports);
|
|
25
|
+
var import_constants = require("./constants");
|
|
26
|
+
var import_error = require("./error");
|
|
27
|
+
var import_logging = require("./logging");
|
|
28
|
+
var import_help = require("./help");
|
|
29
|
+
var ContentErrorType = /* @__PURE__ */ ((ContentErrorType2) => {
|
|
30
|
+
ContentErrorType2["TIMEOUT"] = "https://croct.help/api/content#timeout";
|
|
31
|
+
ContentErrorType2["UNEXPECTED_ERROR"] = "https://croct.help/api/content#unexpected-error";
|
|
32
|
+
return ContentErrorType2;
|
|
33
|
+
})(ContentErrorType || {});
|
|
34
|
+
class ContentError extends Error {
|
|
35
|
+
constructor(response) {
|
|
36
|
+
super(response.title);
|
|
37
|
+
this.response = response;
|
|
38
|
+
Object.setPrototypeOf(this, ContentError.prototype);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
class ContentFetcher {
|
|
42
|
+
constructor(configuration) {
|
|
43
|
+
if (configuration.appId === void 0 === (configuration.apiKey === void 0)) {
|
|
44
|
+
throw new Error("Either the application ID or the API key must be provided.");
|
|
45
|
+
}
|
|
46
|
+
const { baseEndpointUrl } = configuration;
|
|
47
|
+
const apiKey = typeof configuration.apiKey === "object" ? configuration.apiKey.getIdentifier() : configuration.apiKey;
|
|
48
|
+
const baseEndpoint = (baseEndpointUrl ?? import_constants.BASE_ENDPOINT_URL).replace(/\/+$/, "") + (apiKey === void 0 ? "/client" : "/external") + "/web";
|
|
49
|
+
this.dynamicEndpoint = `${baseEndpoint}/content`;
|
|
50
|
+
this.staticEndpoint = `${baseEndpoint}/static-content`;
|
|
51
|
+
this.logger = configuration.logger ?? new import_logging.NullLogger();
|
|
52
|
+
this.configuration = {
|
|
53
|
+
appId: configuration.appId,
|
|
54
|
+
apiKey,
|
|
55
|
+
defaultTimeout: configuration.defaultTimeout,
|
|
56
|
+
defaultPreferredLocale: configuration.defaultPreferredLocale
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
fetch(slotId, options = {}) {
|
|
60
|
+
if (options.static === true && this.configuration.apiKey === void 0) {
|
|
61
|
+
throw new Error("The API key must be provided to fetch static content.");
|
|
62
|
+
}
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
const abortController = new AbortController();
|
|
65
|
+
const timeout = options.timeout ?? this.configuration.defaultTimeout;
|
|
66
|
+
let timer;
|
|
67
|
+
if (timeout !== void 0) {
|
|
68
|
+
timer = setTimeout(
|
|
69
|
+
() => {
|
|
70
|
+
const response = {
|
|
71
|
+
title: `Content could not be loaded in time for slot '${slotId}'.`,
|
|
72
|
+
type: "https://croct.help/api/content#timeout" /* TIMEOUT */,
|
|
73
|
+
detail: `The content took more than ${timeout}ms to load.`,
|
|
74
|
+
status: 408
|
|
75
|
+
// Request Timeout
|
|
76
|
+
};
|
|
77
|
+
abortController.abort();
|
|
78
|
+
this.logHelp(response.status);
|
|
79
|
+
reject(new ContentError(response));
|
|
80
|
+
},
|
|
81
|
+
timeout
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
this.load(slotId, abortController.signal, options).finally(() => clearTimeout(timer)).then((response) => {
|
|
85
|
+
const region = response.headers.get("X-Croct-Region");
|
|
86
|
+
const timing = response.headers.get("X-Croct-Timing");
|
|
87
|
+
this.logger.debug(`Content for slot '${slotId}' processed by region ${region} in ${timing}.`);
|
|
88
|
+
return response.json().then((body) => {
|
|
89
|
+
if (response.ok) {
|
|
90
|
+
return resolve(body);
|
|
91
|
+
}
|
|
92
|
+
this.logHelp(response.status);
|
|
93
|
+
reject(new ContentError(body));
|
|
94
|
+
}).catch((error) => {
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
throw new Error(`Error ${response.status} - ${response.statusText}`);
|
|
97
|
+
}
|
|
98
|
+
throw error;
|
|
99
|
+
});
|
|
100
|
+
}).catch((error) => {
|
|
101
|
+
if (!abortController.signal.aborted) {
|
|
102
|
+
reject(
|
|
103
|
+
new ContentError({
|
|
104
|
+
title: (0, import_error.formatMessage)(error),
|
|
105
|
+
type: "https://croct.help/api/content#unexpected-error" /* UNEXPECTED_ERROR */,
|
|
106
|
+
detail: "Please try again or contact Croct support if the error persists.",
|
|
107
|
+
status: 500
|
|
108
|
+
// Internal Server Error
|
|
109
|
+
})
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
load(slotId, signal, options) {
|
|
116
|
+
const { apiKey, appId } = this.configuration;
|
|
117
|
+
const headers = {
|
|
118
|
+
"Content-Type": "application/json"
|
|
119
|
+
};
|
|
120
|
+
headers["X-Client-Library"] = import_constants.CLIENT_LIBRARY;
|
|
121
|
+
if (appId !== void 0) {
|
|
122
|
+
headers["X-App-Id"] = appId;
|
|
123
|
+
}
|
|
124
|
+
if (apiKey !== void 0) {
|
|
125
|
+
headers["X-Api-Key"] = apiKey;
|
|
126
|
+
}
|
|
127
|
+
const payload = {
|
|
128
|
+
slotId
|
|
129
|
+
};
|
|
130
|
+
if (options.version !== void 0) {
|
|
131
|
+
payload.version = `${options.version}`;
|
|
132
|
+
}
|
|
133
|
+
const preferredLocale = options.preferredLocale ?? this.configuration.defaultPreferredLocale;
|
|
134
|
+
if (preferredLocale !== void 0) {
|
|
135
|
+
payload.preferredLocale = preferredLocale;
|
|
136
|
+
}
|
|
137
|
+
const dynamic = ContentFetcher.isDynamicContent(options);
|
|
138
|
+
if (dynamic) {
|
|
139
|
+
if (options.clientId !== void 0) {
|
|
140
|
+
headers["X-Client-Id"] = options.clientId;
|
|
141
|
+
}
|
|
142
|
+
if (options.clientIp !== void 0) {
|
|
143
|
+
headers["X-Client-Ip"] = options.clientIp;
|
|
144
|
+
}
|
|
145
|
+
if (options.userToken !== void 0) {
|
|
146
|
+
headers["X-Token"] = options.userToken.toString();
|
|
147
|
+
}
|
|
148
|
+
if (options.clientAgent !== void 0) {
|
|
149
|
+
headers["X-Client-Agent"] = options.clientAgent;
|
|
150
|
+
}
|
|
151
|
+
if (options.context !== void 0) {
|
|
152
|
+
payload.context = options.context;
|
|
153
|
+
}
|
|
154
|
+
if (options.previewToken !== void 0) {
|
|
155
|
+
payload.previewToken = `${options.previewToken}`;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return fetch(dynamic ? this.dynamicEndpoint : this.staticEndpoint, {
|
|
159
|
+
// Set the request mode to 'cors' when running in the browser.
|
|
160
|
+
// By default, the request mode is computed based on the referrer policy
|
|
161
|
+
// and response-tainting rules applied to the script that ultimately
|
|
162
|
+
// initiated the fetch, make this prone to errors due to unrelated
|
|
163
|
+
// configurations on the page.
|
|
164
|
+
// https://fetch.spec.whatwg.org/#origin-header
|
|
165
|
+
mode: typeof window === "undefined" ? void 0 : "cors",
|
|
166
|
+
credentials: "omit",
|
|
167
|
+
...options.extra,
|
|
168
|
+
method: "POST",
|
|
169
|
+
headers,
|
|
170
|
+
signal,
|
|
171
|
+
body: JSON.stringify(payload)
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
logHelp(statusCode) {
|
|
175
|
+
const help = import_help.Help.forStatusCode(statusCode);
|
|
176
|
+
if (help !== void 0) {
|
|
177
|
+
this.logger.error(help);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
static isDynamicContent(options) {
|
|
181
|
+
return options.static !== true;
|
|
182
|
+
}
|
|
183
|
+
toJSON() {
|
|
184
|
+
throw new Error("Unserializable value.");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
188
|
+
0 && (module.exports = {
|
|
189
|
+
ContentError,
|
|
190
|
+
ContentErrorType,
|
|
191
|
+
ContentFetcher
|
|
192
|
+
});
|
|
193
|
+
//# sourceMappingURL=contentFetcher.cjs.map
|
package/context.cjs
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var context_exports = {};
|
|
19
|
+
__export(context_exports, {
|
|
20
|
+
Context: () => Context
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(context_exports);
|
|
23
|
+
var import_token = require("./token");
|
|
24
|
+
var import_tab = require("./tab");
|
|
25
|
+
var import_uuid = require("./uuid");
|
|
26
|
+
var import_cache = require("./cache");
|
|
27
|
+
function tokenEquals(left, right) {
|
|
28
|
+
return left === right || left !== null && right !== null && left.toString() === right.toString();
|
|
29
|
+
}
|
|
30
|
+
class Context {
|
|
31
|
+
constructor(tab, tokenStore, eventDispatcher) {
|
|
32
|
+
this.tab = tab;
|
|
33
|
+
this.tokenStore = tokenStore;
|
|
34
|
+
this.eventDispatcher = eventDispatcher;
|
|
35
|
+
this.lastToken = tokenStore.getToken();
|
|
36
|
+
this.syncToken = this.syncToken.bind(this);
|
|
37
|
+
}
|
|
38
|
+
static load({ cache, tokenScope, eventDispatcher, urlSanitizer }) {
|
|
39
|
+
let tabId = cache.tabId.get();
|
|
40
|
+
let newTab = false;
|
|
41
|
+
if (tabId === null) {
|
|
42
|
+
tabId = (0, import_uuid.uuid4)(true);
|
|
43
|
+
newTab = true;
|
|
44
|
+
}
|
|
45
|
+
const tab = new import_tab.Tab(tabId, newTab, urlSanitizer);
|
|
46
|
+
cache.tabId.clear();
|
|
47
|
+
tab.addListener("unload", () => cache.tabId.put(tab.id));
|
|
48
|
+
switch (tokenScope) {
|
|
49
|
+
case "isolated":
|
|
50
|
+
return new Context(tab, new import_token.InMemoryTokenStore(), eventDispatcher);
|
|
51
|
+
case "global": {
|
|
52
|
+
const context = new Context(tab, new import_token.CachedTokenStore(cache.browserToken), eventDispatcher);
|
|
53
|
+
if (import_cache.ObservableCache.isObservable(cache.browserToken)) {
|
|
54
|
+
cache.browserToken.addListener(context.syncToken);
|
|
55
|
+
}
|
|
56
|
+
return context;
|
|
57
|
+
}
|
|
58
|
+
case "contextual": {
|
|
59
|
+
const primaryStorage = new import_token.CachedTokenStore(cache.tabToken);
|
|
60
|
+
const secondaryStorage = new import_token.CachedTokenStore(cache.browserToken);
|
|
61
|
+
if (tab.isNew) {
|
|
62
|
+
primaryStorage.setToken(secondaryStorage.getToken());
|
|
63
|
+
}
|
|
64
|
+
tab.addListener("visibilityChange", (event) => {
|
|
65
|
+
if (event.detail.visible) {
|
|
66
|
+
secondaryStorage.setToken(primaryStorage.getToken());
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return new Context(tab, new import_token.ReplicatedTokenStore(primaryStorage, secondaryStorage), eventDispatcher);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
getTab() {
|
|
74
|
+
return this.tab;
|
|
75
|
+
}
|
|
76
|
+
isAnonymous() {
|
|
77
|
+
const token = this.getToken();
|
|
78
|
+
return token == null || token.isAnonymous();
|
|
79
|
+
}
|
|
80
|
+
getUser() {
|
|
81
|
+
const token = this.getToken();
|
|
82
|
+
return token == null ? null : token.getSubject();
|
|
83
|
+
}
|
|
84
|
+
getToken() {
|
|
85
|
+
return this.tokenStore.getToken();
|
|
86
|
+
}
|
|
87
|
+
setToken(token) {
|
|
88
|
+
const oldToken = this.lastToken;
|
|
89
|
+
this.lastToken = token;
|
|
90
|
+
this.tokenStore.setToken(token);
|
|
91
|
+
if (!tokenEquals(oldToken, token)) {
|
|
92
|
+
this.eventDispatcher.dispatch("tokenChanged", {
|
|
93
|
+
oldToken,
|
|
94
|
+
newToken: token
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
syncToken() {
|
|
99
|
+
const newToken = this.tokenStore.getToken();
|
|
100
|
+
const oldToken = this.lastToken;
|
|
101
|
+
if (!tokenEquals(oldToken, newToken)) {
|
|
102
|
+
this.lastToken = newToken;
|
|
103
|
+
this.eventDispatcher.dispatch("tokenChanged", {
|
|
104
|
+
oldToken,
|
|
105
|
+
newToken
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
111
|
+
0 && (module.exports = {
|
|
112
|
+
Context
|
|
113
|
+
});
|
|
114
|
+
//# sourceMappingURL=context.cjs.map
|
package/error.cjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var error_exports = {};
|
|
19
|
+
__export(error_exports, {
|
|
20
|
+
formatCause: () => formatCause,
|
|
21
|
+
formatMessage: () => formatMessage
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(error_exports);
|
|
24
|
+
function extractMessage(error) {
|
|
25
|
+
if (error instanceof Error) {
|
|
26
|
+
return error.message;
|
|
27
|
+
}
|
|
28
|
+
if (typeof error === "string" && error !== "") {
|
|
29
|
+
return error;
|
|
30
|
+
}
|
|
31
|
+
return "unknown error";
|
|
32
|
+
}
|
|
33
|
+
function formatMessage(error) {
|
|
34
|
+
const message = extractMessage(error);
|
|
35
|
+
if (message.length === 0) {
|
|
36
|
+
return message;
|
|
37
|
+
}
|
|
38
|
+
return message.charAt(0).toUpperCase() + message.slice(1);
|
|
39
|
+
}
|
|
40
|
+
function formatCause(error) {
|
|
41
|
+
const message = formatMessage(error);
|
|
42
|
+
if (message.length === 0) {
|
|
43
|
+
return message;
|
|
44
|
+
}
|
|
45
|
+
return message.charAt(0).toLowerCase() + message.slice(1);
|
|
46
|
+
}
|
|
47
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
48
|
+
0 && (module.exports = {
|
|
49
|
+
formatCause,
|
|
50
|
+
formatMessage
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=error.cjs.map
|
package/evaluator.cjs
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var evaluator_exports = {};
|
|
19
|
+
__export(evaluator_exports, {
|
|
20
|
+
EvaluationError: () => EvaluationError,
|
|
21
|
+
EvaluationErrorType: () => EvaluationErrorType,
|
|
22
|
+
Evaluator: () => Evaluator,
|
|
23
|
+
QueryError: () => QueryError
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(evaluator_exports);
|
|
26
|
+
var import_constants = require("./constants");
|
|
27
|
+
var import_error = require("./error");
|
|
28
|
+
var import_sourceLocation = require("./sourceLocation");
|
|
29
|
+
var import_logging = require("./logging");
|
|
30
|
+
var import_help = require("./help");
|
|
31
|
+
var EvaluationErrorType = /* @__PURE__ */ ((EvaluationErrorType2) => {
|
|
32
|
+
EvaluationErrorType2["TIMEOUT"] = "https://croct.help/api/evaluation#timeout";
|
|
33
|
+
EvaluationErrorType2["UNEXPECTED_ERROR"] = "https://croct.help/api/evaluation#unexpected-error";
|
|
34
|
+
EvaluationErrorType2["INVALID_QUERY"] = "https://croct.help/api/evaluation#invalid-query";
|
|
35
|
+
EvaluationErrorType2["TOO_COMPLEX_QUERY"] = "https://croct.help/api/evaluation#too-complex-query";
|
|
36
|
+
EvaluationErrorType2["EVALUATION_FAILED"] = "https://croct.help/api/evaluation#evaluation-failed";
|
|
37
|
+
EvaluationErrorType2["UNALLOWED_RESULT"] = "https://croct.help/api/evaluation#unallowed-result";
|
|
38
|
+
EvaluationErrorType2["UNSERIALIZABLE_RESULT"] = "https://croct.help/api/evaluation#unserializable-result";
|
|
39
|
+
return EvaluationErrorType2;
|
|
40
|
+
})(EvaluationErrorType || {});
|
|
41
|
+
class EvaluationError extends Error {
|
|
42
|
+
constructor(response) {
|
|
43
|
+
super(response.title);
|
|
44
|
+
this.response = response;
|
|
45
|
+
Object.setPrototypeOf(this, EvaluationError.prototype);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
class QueryError extends EvaluationError {
|
|
49
|
+
constructor(response) {
|
|
50
|
+
super(response);
|
|
51
|
+
Object.setPrototypeOf(this, QueryError.prototype);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const _Evaluator = class _Evaluator {
|
|
55
|
+
constructor(configuration) {
|
|
56
|
+
if (configuration.appId === void 0 === (configuration.apiKey === void 0)) {
|
|
57
|
+
throw new Error("Either the application ID or the API key must be provided.");
|
|
58
|
+
}
|
|
59
|
+
const { baseEndpointUrl } = configuration;
|
|
60
|
+
const apiKey = typeof configuration.apiKey === "object" ? configuration.apiKey.getIdentifier() : configuration.apiKey;
|
|
61
|
+
this.endpoint = (baseEndpointUrl ?? import_constants.BASE_ENDPOINT_URL).replace(/\/+$/, "") + (apiKey === void 0 ? "/client" : "/external") + "/web/evaluate";
|
|
62
|
+
this.logger = configuration.logger ?? new import_logging.NullLogger();
|
|
63
|
+
this.configuration = {
|
|
64
|
+
appId: configuration.appId,
|
|
65
|
+
apiKey,
|
|
66
|
+
defaultTimeout: configuration.defaultTimeout
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
evaluate(query, options = {}) {
|
|
70
|
+
const length = (0, import_sourceLocation.getLength)(query);
|
|
71
|
+
const reference = query.length > 20 ? `${query.slice(0, 20)}...` : query;
|
|
72
|
+
if (length > _Evaluator.MAX_QUERY_LENGTH) {
|
|
73
|
+
const response = {
|
|
74
|
+
title: "The query is too complex.",
|
|
75
|
+
status: 422,
|
|
76
|
+
// Unprocessable Entity
|
|
77
|
+
type: "https://croct.help/api/evaluation#too-complex-query" /* TOO_COMPLEX_QUERY */,
|
|
78
|
+
detail: `The query "${reference}" must be at most ${_Evaluator.MAX_QUERY_LENGTH} characters long, but it is ${length} characters long.`,
|
|
79
|
+
errors: [{
|
|
80
|
+
cause: "The query is longer than expected.",
|
|
81
|
+
location: (0, import_sourceLocation.getLocation)(query, 0, Math.max(length - 1, 0))
|
|
82
|
+
}]
|
|
83
|
+
};
|
|
84
|
+
return Promise.reject(new QueryError(response));
|
|
85
|
+
}
|
|
86
|
+
const payload = {
|
|
87
|
+
query
|
|
88
|
+
};
|
|
89
|
+
if (options.context !== void 0) {
|
|
90
|
+
payload.context = options.context;
|
|
91
|
+
}
|
|
92
|
+
return new Promise((resolve, reject) => {
|
|
93
|
+
const abortController = new AbortController();
|
|
94
|
+
const timeout = options.timeout ?? this.configuration.defaultTimeout;
|
|
95
|
+
let timer;
|
|
96
|
+
if (timeout !== void 0) {
|
|
97
|
+
timer = setTimeout(
|
|
98
|
+
() => {
|
|
99
|
+
const response = {
|
|
100
|
+
title: `Evaluation could not be completed in time for query "${reference}".`,
|
|
101
|
+
type: "https://croct.help/api/evaluation#timeout" /* TIMEOUT */,
|
|
102
|
+
detail: `The evaluation took more than ${timeout}ms to complete.`,
|
|
103
|
+
status: 408
|
|
104
|
+
// Request Timeout
|
|
105
|
+
};
|
|
106
|
+
abortController.abort();
|
|
107
|
+
this.logHelp(response.status);
|
|
108
|
+
reject(new EvaluationError(response));
|
|
109
|
+
},
|
|
110
|
+
timeout
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
this.fetch(payload, abortController.signal, options).finally(() => clearTimeout(timer)).then(
|
|
114
|
+
(response) => {
|
|
115
|
+
const region = response.headers.get("X-Croct-Region");
|
|
116
|
+
const timing = response.headers.get("X-Croct-Timing");
|
|
117
|
+
this.logger.debug(
|
|
118
|
+
`Evaluation of the query "${reference}" processed by region ${region} in ${timing}.`
|
|
119
|
+
);
|
|
120
|
+
return response.json().then((body) => {
|
|
121
|
+
if (response.ok) {
|
|
122
|
+
return resolve(body);
|
|
123
|
+
}
|
|
124
|
+
this.logHelp(response.status);
|
|
125
|
+
const problem = body;
|
|
126
|
+
switch (problem.type) {
|
|
127
|
+
case "https://croct.help/api/evaluation#invalid-query" /* INVALID_QUERY */:
|
|
128
|
+
case "https://croct.help/api/evaluation#evaluation-failed" /* EVALUATION_FAILED */:
|
|
129
|
+
case "https://croct.help/api/evaluation#too-complex-query" /* TOO_COMPLEX_QUERY */:
|
|
130
|
+
reject(new QueryError(problem));
|
|
131
|
+
break;
|
|
132
|
+
default:
|
|
133
|
+
reject(new EvaluationError(problem));
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}).catch((error) => {
|
|
137
|
+
if (!response.ok) {
|
|
138
|
+
throw new Error(`Error ${response.status} - ${response.statusText}`);
|
|
139
|
+
}
|
|
140
|
+
throw error;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
).catch(
|
|
144
|
+
(error) => {
|
|
145
|
+
if (!abortController.signal.aborted) {
|
|
146
|
+
reject(
|
|
147
|
+
new EvaluationError({
|
|
148
|
+
title: (0, import_error.formatMessage)(error),
|
|
149
|
+
type: "https://croct.help/api/evaluation#unexpected-error" /* UNEXPECTED_ERROR */,
|
|
150
|
+
detail: "Please try again or contact Croct support if the error persists.",
|
|
151
|
+
status: 500
|
|
152
|
+
// Internal Server Error
|
|
153
|
+
})
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
fetch(body, signal, options) {
|
|
161
|
+
const { appId, apiKey } = this.configuration;
|
|
162
|
+
const { clientId, clientIp, userToken, clientAgent } = options;
|
|
163
|
+
const headers = {
|
|
164
|
+
"Content-Type": "application/json"
|
|
165
|
+
};
|
|
166
|
+
headers["X-Client-Library"] = import_constants.CLIENT_LIBRARY;
|
|
167
|
+
if (apiKey !== void 0) {
|
|
168
|
+
headers["X-Api-Key"] = apiKey;
|
|
169
|
+
} else if (appId !== void 0) {
|
|
170
|
+
headers["X-App-Id"] = appId;
|
|
171
|
+
}
|
|
172
|
+
if (clientId !== void 0) {
|
|
173
|
+
headers["X-Client-Id"] = clientId;
|
|
174
|
+
}
|
|
175
|
+
if (clientIp !== void 0) {
|
|
176
|
+
headers["X-Client-Ip"] = clientIp;
|
|
177
|
+
}
|
|
178
|
+
if (userToken !== void 0) {
|
|
179
|
+
headers["X-Token"] = userToken.toString();
|
|
180
|
+
}
|
|
181
|
+
if (clientAgent !== void 0) {
|
|
182
|
+
headers["X-Client-Agent"] = clientAgent;
|
|
183
|
+
}
|
|
184
|
+
return fetch(this.endpoint, {
|
|
185
|
+
// Set the request mode to 'cors' when running in the browser.
|
|
186
|
+
// By default, the request mode is computed based on the referrer policy
|
|
187
|
+
// and response-tainting rules applied to the script that ultimately
|
|
188
|
+
// initiated the fetch, make this prone to errors due to unrelated
|
|
189
|
+
// configurations on the page.
|
|
190
|
+
// https://fetch.spec.whatwg.org/#origin-header
|
|
191
|
+
mode: typeof window === "undefined" ? void 0 : "cors",
|
|
192
|
+
credentials: "omit",
|
|
193
|
+
...options.extra,
|
|
194
|
+
method: "POST",
|
|
195
|
+
headers,
|
|
196
|
+
signal,
|
|
197
|
+
body: JSON.stringify(body)
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
logHelp(statusCode) {
|
|
201
|
+
const help = import_help.Help.forStatusCode(statusCode);
|
|
202
|
+
if (help !== void 0) {
|
|
203
|
+
this.logger.error(help);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
toJSON() {
|
|
207
|
+
throw new Error("Unserializable value.");
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
_Evaluator.MAX_QUERY_LENGTH = import_constants.MAX_QUERY_LENGTH;
|
|
211
|
+
let Evaluator = _Evaluator;
|
|
212
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
213
|
+
0 && (module.exports = {
|
|
214
|
+
EvaluationError,
|
|
215
|
+
EvaluationErrorType,
|
|
216
|
+
Evaluator,
|
|
217
|
+
QueryError
|
|
218
|
+
});
|
|
219
|
+
//# sourceMappingURL=evaluator.cjs.map
|
package/eventManager.cjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var eventManager_exports = {};
|
|
19
|
+
__export(eventManager_exports, {
|
|
20
|
+
SynchronousEventManager: () => SynchronousEventManager
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(eventManager_exports);
|
|
23
|
+
class SynchronousEventManager {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.listeners = {};
|
|
26
|
+
}
|
|
27
|
+
addListener(type, listener) {
|
|
28
|
+
const listeners = this.listeners[type] ?? [];
|
|
29
|
+
listeners.push(listener);
|
|
30
|
+
this.listeners[type] = listeners;
|
|
31
|
+
}
|
|
32
|
+
removeListener(eventName, listener) {
|
|
33
|
+
const listeners = this.listeners[eventName];
|
|
34
|
+
if (listeners === void 0) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const index = listeners.indexOf(listener);
|
|
38
|
+
if (index >= 0) {
|
|
39
|
+
listeners.splice(index, 1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
dispatch(eventName, event) {
|
|
43
|
+
const listeners = this.listeners[eventName];
|
|
44
|
+
if (listeners !== void 0) {
|
|
45
|
+
listeners.forEach((listener) => listener(event));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
50
|
+
0 && (module.exports = {
|
|
51
|
+
SynchronousEventManager
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=eventManager.cjs.map
|