@croct/plug 0.10.2 → 0.11.0-alpha.2
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/constants.d.ts +2 -0
- package/constants.js +3 -1
- package/eap.d.ts +4 -4
- package/index.js +1 -1
- package/package.json +15 -18
- package/playground.d.ts +3 -3
- package/playground.js +46 -49
- package/plug.d.ts +20 -8
- package/plug.js +186 -262
- package/plugin.d.ts +2 -1
- package/preview.d.ts +22 -0
- package/preview.js +128 -0
- package/sdk/evaluation.d.ts +1 -1
- package/sdk/evaluation.js +2 -2
- package/sdk/index.d.ts +4 -4
- package/sdk/json.d.ts +1 -1
- package/sdk/json.js +1 -1
- package/sdk/token.d.ts +1 -1
- package/sdk/tracking.d.ts +1 -1
- package/sdk/validation.js +1 -1
- package/slot.d.ts +21 -0
- package/{fetch.js → slot.js} +0 -0
- package/fetch.d.ts +0 -12
package/constants.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export declare const CDN_URL = "https://cdn.croct.io/js/v1/lib/plug.js";
|
|
2
2
|
export declare const PLAYGROUND_ORIGIN = "https://play.croct.com";
|
|
3
3
|
export declare const PLAYGROUND_CONNECT_URL = "https://play.croct.com/connect.html";
|
|
4
|
+
export declare const PREVIEW_WIDGET_ORIGIN = "https://cdn.croct.io";
|
|
5
|
+
export declare const PREVIEW_WIDGET_URL = "https://cdn.croct.io/js/v1/lib/plug/widget-0.11.0-alpha.2.html";
|
package/constants.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PLAYGROUND_CONNECT_URL = exports.PLAYGROUND_ORIGIN = exports.CDN_URL = void 0;
|
|
3
|
+
exports.PREVIEW_WIDGET_URL = exports.PREVIEW_WIDGET_ORIGIN = exports.PLAYGROUND_CONNECT_URL = exports.PLAYGROUND_ORIGIN = exports.CDN_URL = void 0;
|
|
4
4
|
exports.CDN_URL = 'https://cdn.croct.io/js/v1/lib/plug.js';
|
|
5
5
|
exports.PLAYGROUND_ORIGIN = 'https://play.croct.com';
|
|
6
6
|
exports.PLAYGROUND_CONNECT_URL = 'https://play.croct.com/connect.html';
|
|
7
|
+
exports.PREVIEW_WIDGET_ORIGIN = 'https://cdn.croct.io';
|
|
8
|
+
exports.PREVIEW_WIDGET_URL = 'https://cdn.croct.io/js/v1/lib/plug/widget-0.11.0-alpha.2.html';
|
package/eap.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { Plug } from './plug';
|
|
1
|
+
import { VersionedSlotId } from './slot';
|
|
2
|
+
import { JsonObject } from './sdk/json';
|
|
3
|
+
import { LegacyFetchResponse, Plug } from './plug';
|
|
4
4
|
export interface EapFeatures {
|
|
5
|
-
fetch<P extends
|
|
5
|
+
fetch<P extends JsonObject, I extends VersionedSlotId>(this: Plug, slotId: I): Promise<LegacyFetchResponse<I, P>>;
|
|
6
6
|
}
|
|
7
7
|
interface EapHooks extends EapFeatures {
|
|
8
8
|
initialize(this: Plug): void;
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
const plug_1 = require("./plug");
|
|
4
4
|
/* eslint-disable-next-line import/no-default-export -- Should be default export */
|
|
5
5
|
exports.default = new plug_1.GlobalPlug();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@croct/plug",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-alpha.2",
|
|
4
4
|
"description": "A fully-featured devkit for building natively personalized applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -34,27 +34,24 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@croct/json": "^1.1.0",
|
|
37
|
-
"@croct/sdk": "^0.
|
|
37
|
+
"@croct/sdk": "^0.11.0-alpha",
|
|
38
38
|
"tslib": "^2.2.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@rollup/plugin-
|
|
46
|
-
"@rollup/plugin-
|
|
47
|
-
"@
|
|
48
|
-
"@rollup/plugin-typescript": "^8.2.1",
|
|
49
|
-
"@types/jest": "^26.0.23",
|
|
41
|
+
"@croct/eslint-plugin": "^0.6.3",
|
|
42
|
+
"@rollup/plugin-commonjs": "^23.0.2",
|
|
43
|
+
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
44
|
+
"@rollup/plugin-replace": "^5.0.1",
|
|
45
|
+
"@rollup/plugin-terser": "^0.1.0",
|
|
46
|
+
"@rollup/plugin-typescript": "^9.0.2",
|
|
47
|
+
"@types/jest": "^29.2.2",
|
|
50
48
|
"@typescript-eslint/parser": "^5.30.0",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"jest": "^
|
|
54
|
-
"rollup": "^
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"typescript": "^4.2.4"
|
|
49
|
+
"eslint": "^8.27.0",
|
|
50
|
+
"jest": "^29.3.1",
|
|
51
|
+
"jest-environment-jsdom": "^29.3.1",
|
|
52
|
+
"rollup": "^3.3.0",
|
|
53
|
+
"ts-jest": "^29.0.3",
|
|
54
|
+
"typescript": "^4.9.3"
|
|
58
55
|
},
|
|
59
56
|
"browserslist": [
|
|
60
57
|
"last 1 version"
|
package/playground.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Campaign, Page } from '@croct/sdk/evaluator';
|
|
|
4
4
|
import { Plugin, PluginFactory } from './plugin';
|
|
5
5
|
import { Logger, SdkEventSubscriber, Tab } from './sdk';
|
|
6
6
|
import { TokenProvider } from './sdk/token';
|
|
7
|
-
export
|
|
7
|
+
export type Configuration = {
|
|
8
8
|
appId: string;
|
|
9
9
|
connectionId?: string;
|
|
10
10
|
sdkVersion: string;
|
|
@@ -16,7 +16,7 @@ export declare type Configuration = {
|
|
|
16
16
|
tokenProvider: TokenProvider;
|
|
17
17
|
logger: Logger;
|
|
18
18
|
};
|
|
19
|
-
export
|
|
19
|
+
export type SyncPayload = {
|
|
20
20
|
appId: string;
|
|
21
21
|
connectionId: string;
|
|
22
22
|
sdkVersion: string;
|
|
@@ -48,7 +48,7 @@ export declare class PlaygroundPlugin implements Plugin {
|
|
|
48
48
|
private syncToken;
|
|
49
49
|
private createContext;
|
|
50
50
|
}
|
|
51
|
-
export
|
|
51
|
+
export type Options = {
|
|
52
52
|
connectionId?: string;
|
|
53
53
|
};
|
|
54
54
|
export declare const factory: PluginFactory<Options>;
|
package/playground.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.factory = exports.PlaygroundPlugin = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
const error_1 = require("@croct/sdk/error");
|
|
5
|
+
const evaluatorFacade_1 = require("@croct/sdk/facade/evaluatorFacade");
|
|
6
|
+
const constants_1 = require("./constants");
|
|
7
|
+
const CONNECTION_PARAMETER = '__cplay';
|
|
8
|
+
class PlaygroundPlugin {
|
|
9
|
+
constructor(configuration) {
|
|
10
10
|
this.sdkVersion = configuration.sdkVersion;
|
|
11
11
|
this.appId = configuration.appId;
|
|
12
12
|
this.connectionId = configuration.connectionId;
|
|
@@ -18,31 +18,30 @@ var PlaygroundPlugin = /** @class */ (function () {
|
|
|
18
18
|
this.tokenProvider = configuration.tokenProvider;
|
|
19
19
|
this.logger = configuration.logger;
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var connectionId = this.resolveConnectionId();
|
|
21
|
+
enable() {
|
|
22
|
+
const connectionId = this.resolveConnectionId();
|
|
24
23
|
if (connectionId === null) {
|
|
25
24
|
return;
|
|
26
25
|
}
|
|
27
|
-
this.syncListener =
|
|
26
|
+
this.syncListener = () => this.cidAssigner
|
|
28
27
|
.assignCid()
|
|
29
|
-
.then(
|
|
30
|
-
|
|
28
|
+
.then(cid => {
|
|
29
|
+
this.syncToken(connectionId, cid);
|
|
31
30
|
})
|
|
32
|
-
.catch(
|
|
33
|
-
|
|
34
|
-
});
|
|
31
|
+
.catch(error => {
|
|
32
|
+
this.logger.warn(`Sync failed: ${(0, error_1.formatCause)(error)}`);
|
|
33
|
+
});
|
|
35
34
|
this.eventSubscriber.addListener('tokenChanged', this.syncListener);
|
|
36
35
|
this.tab.addListener('urlChange', this.syncListener);
|
|
37
36
|
return this.syncListener();
|
|
38
|
-
}
|
|
39
|
-
|
|
37
|
+
}
|
|
38
|
+
resolveConnectionId() {
|
|
40
39
|
if (this.connectionId !== undefined) {
|
|
41
40
|
this.logger.debug('Connection ID passed in configuration');
|
|
42
41
|
return this.connectionId;
|
|
43
42
|
}
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
const url = new URL(this.tab.url);
|
|
44
|
+
let connectionId = url.searchParams.get(CONNECTION_PARAMETER);
|
|
46
45
|
if (connectionId === null || connectionId === '') {
|
|
47
46
|
this.logger.debug('No connection ID found in URL');
|
|
48
47
|
connectionId = this.storage.getItem('connectionId');
|
|
@@ -54,17 +53,16 @@ var PlaygroundPlugin = /** @class */ (function () {
|
|
|
54
53
|
this.logger.debug('Connection ID found in URL');
|
|
55
54
|
this.storage.setItem('connectionId', connectionId);
|
|
56
55
|
return connectionId;
|
|
57
|
-
}
|
|
58
|
-
|
|
56
|
+
}
|
|
57
|
+
disable() {
|
|
59
58
|
if (this.syncListener !== undefined) {
|
|
60
59
|
this.eventSubscriber.removeListener('tokenChanged', this.syncListener);
|
|
61
60
|
this.tab.removeListener('urlChange', this.syncListener);
|
|
62
61
|
delete this.syncListener;
|
|
63
62
|
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
var iframe = document.createElement('iframe');
|
|
63
|
+
}
|
|
64
|
+
syncToken(connectionId, cid) {
|
|
65
|
+
const iframe = document.createElement('iframe');
|
|
68
66
|
iframe.setAttribute('src', constants_1.PLAYGROUND_CONNECT_URL);
|
|
69
67
|
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
|
70
68
|
iframe.style.visibility = 'hidden';
|
|
@@ -72,17 +70,17 @@ var PlaygroundPlugin = /** @class */ (function () {
|
|
|
72
70
|
iframe.style.border = '0';
|
|
73
71
|
iframe.style.width = '0';
|
|
74
72
|
iframe.style.height = '0';
|
|
75
|
-
|
|
76
|
-
iframe.onload =
|
|
73
|
+
const context = this.createContext();
|
|
74
|
+
iframe.onload = () => {
|
|
77
75
|
var _a, _b;
|
|
78
76
|
if (iframe.contentWindow === null) {
|
|
79
77
|
if (document.body.contains(iframe)) {
|
|
80
78
|
document.body.removeChild(iframe);
|
|
81
79
|
}
|
|
82
|
-
|
|
80
|
+
this.logger.warn('Sync handshake failed');
|
|
83
81
|
return;
|
|
84
82
|
}
|
|
85
|
-
|
|
83
|
+
const listener = (event) => {
|
|
86
84
|
if (event.origin !== constants_1.PLAYGROUND_ORIGIN || event.data !== connectionId) {
|
|
87
85
|
return;
|
|
88
86
|
}
|
|
@@ -90,24 +88,24 @@ var PlaygroundPlugin = /** @class */ (function () {
|
|
|
90
88
|
if (document.body.contains(iframe)) {
|
|
91
89
|
document.body.removeChild(iframe);
|
|
92
90
|
}
|
|
93
|
-
|
|
91
|
+
this.logger.debug('Sync completed');
|
|
94
92
|
};
|
|
95
93
|
window.addEventListener('message', listener);
|
|
96
|
-
|
|
97
|
-
appId:
|
|
94
|
+
const payload = {
|
|
95
|
+
appId: this.appId,
|
|
98
96
|
connectionId: connectionId,
|
|
99
|
-
sdkVersion:
|
|
100
|
-
tabId:
|
|
97
|
+
sdkVersion: this.sdkVersion,
|
|
98
|
+
tabId: this.tab.id,
|
|
101
99
|
cid: cid,
|
|
102
|
-
token: (_b = (_a =
|
|
100
|
+
token: (_b = (_a = this.tokenProvider
|
|
103
101
|
.getToken()) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : null,
|
|
104
102
|
context: context,
|
|
105
103
|
};
|
|
106
104
|
iframe.contentWindow.postMessage(payload, constants_1.PLAYGROUND_ORIGIN);
|
|
107
|
-
|
|
105
|
+
this.logger.debug('Waiting for sync acknowledgment...');
|
|
108
106
|
};
|
|
109
107
|
this.logger.debug('Sync started');
|
|
110
|
-
|
|
108
|
+
const connect = () => {
|
|
111
109
|
document.body.appendChild(iframe);
|
|
112
110
|
};
|
|
113
111
|
if (document.body === null) {
|
|
@@ -116,33 +114,32 @@ var PlaygroundPlugin = /** @class */ (function () {
|
|
|
116
114
|
else {
|
|
117
115
|
connect();
|
|
118
116
|
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
}
|
|
118
|
+
createContext() {
|
|
119
|
+
const { page, campaign, timeZone } = this.contextFactory.createContext();
|
|
120
|
+
const context = {};
|
|
123
121
|
if (page !== undefined) {
|
|
124
122
|
context.page = page;
|
|
125
123
|
}
|
|
126
124
|
if (campaign !== undefined) {
|
|
127
125
|
context.campaign = campaign;
|
|
128
126
|
}
|
|
129
|
-
if (
|
|
130
|
-
context.
|
|
127
|
+
if (timeZone !== undefined) {
|
|
128
|
+
context.timeZone = timeZone;
|
|
131
129
|
}
|
|
132
130
|
return context;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
}());
|
|
131
|
+
}
|
|
132
|
+
}
|
|
136
133
|
exports.PlaygroundPlugin = PlaygroundPlugin;
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
const factory = (props) => {
|
|
135
|
+
const { sdk, options } = props;
|
|
139
136
|
return new PlaygroundPlugin({
|
|
140
137
|
sdkVersion: sdk.version,
|
|
141
138
|
appId: sdk.appId,
|
|
142
139
|
connectionId: options.connectionId,
|
|
143
140
|
tab: sdk.tab,
|
|
144
141
|
storage: sdk.getTabStorage(),
|
|
145
|
-
tokenProvider: sdk.
|
|
142
|
+
tokenProvider: sdk.userTokenStore,
|
|
146
143
|
cidAssigner: sdk.cidAssigner,
|
|
147
144
|
contextFactory: new evaluatorFacade_1.TabContextFactory(sdk.tab),
|
|
148
145
|
eventSubscriber: sdk.eventManager,
|
package/plug.d.ts
CHANGED
|
@@ -1,20 +1,34 @@
|
|
|
1
1
|
import { SessionFacade } from '@croct/sdk/facade/sessionFacade';
|
|
2
2
|
import { UserFacade } from '@croct/sdk/facade/userFacade';
|
|
3
3
|
import { TrackerFacade } from '@croct/sdk/facade/trackerFacade';
|
|
4
|
-
import {
|
|
4
|
+
import { EvaluationOptions, EvaluatorFacade } from '@croct/sdk/facade/evaluatorFacade';
|
|
5
5
|
import { Configuration as SdkFacadeConfiguration } from '@croct/sdk/facade/sdkFacade';
|
|
6
6
|
import { Optional } from '@croct/sdk/utilityTypes';
|
|
7
7
|
import { ExternalTrackingEvent as ExternalEvent, ExternalTrackingEventPayload as ExternalEventPayload, ExternalTrackingEventType as ExternalEventType } from '@croct/sdk/trackingEvents';
|
|
8
|
+
import { FetchOptions as BaseFetchOptions } from '@croct/sdk/facade/contentFetcherFacade';
|
|
8
9
|
import { PluginFactory } from './plugin';
|
|
9
10
|
import { EapFeatures } from './eap';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
11
|
+
import { VersionedSlotId, SlotContent } from './slot';
|
|
12
|
+
import { JsonValue, JsonObject } from './sdk/json';
|
|
12
13
|
export interface PluginConfigurations {
|
|
13
14
|
[key: string]: any;
|
|
14
15
|
}
|
|
15
|
-
export
|
|
16
|
+
export type Configuration = Optional<SdkFacadeConfiguration, 'appId'> & {
|
|
16
17
|
plugins?: PluginConfigurations;
|
|
17
18
|
};
|
|
19
|
+
export type FetchOptions = Omit<BaseFetchOptions, 'version'>;
|
|
20
|
+
export type FetchResponse<I extends VersionedSlotId, C extends JsonObject = JsonObject> = {
|
|
21
|
+
content: SlotContent<I, C>;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export type LegacyFetchResponse<I extends VersionedSlotId, C extends JsonObject = JsonObject> = FetchResponse<I, C> & {
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated Use `content` instead.
|
|
29
|
+
*/
|
|
30
|
+
payload: SlotContent<I, C>;
|
|
31
|
+
};
|
|
18
32
|
export interface Plug extends EapFeatures {
|
|
19
33
|
readonly tracker: TrackerFacade;
|
|
20
34
|
readonly user: UserFacade;
|
|
@@ -31,6 +45,7 @@ export interface Plug extends EapFeatures {
|
|
|
31
45
|
unsetToken(): void;
|
|
32
46
|
track<T extends ExternalEventType>(type: T, payload: ExternalEventPayload<T>): Promise<ExternalEvent<T>>;
|
|
33
47
|
evaluate<T extends JsonValue>(expression: string, options?: EvaluationOptions): Promise<T>;
|
|
48
|
+
fetch<P extends JsonObject, I extends VersionedSlotId>(slotId: I, options?: FetchOptions): Promise<LegacyFetchResponse<I, P>>;
|
|
34
49
|
unplug(): Promise<void>;
|
|
35
50
|
}
|
|
36
51
|
export declare class GlobalPlug implements Plug {
|
|
@@ -59,10 +74,7 @@ export declare class GlobalPlug implements Plug {
|
|
|
59
74
|
track<T extends ExternalEventType>(type: T, payload: ExternalEventPayload<T>): Promise<ExternalEvent<T>>;
|
|
60
75
|
evaluate<T extends JsonValue>(expression: string, options?: EvaluationOptions): Promise<T>;
|
|
61
76
|
test(expression: string, options?: EvaluationOptions): Promise<boolean>;
|
|
62
|
-
|
|
63
|
-
* This API is unstable and subject to change in future releases.
|
|
64
|
-
*/
|
|
65
|
-
fetch<P extends NullableJsonObject, I extends SlotId = SlotId>(slotId: I, options?: FetchOptions): Promise<FetchResponse<I, P>>;
|
|
77
|
+
get fetch(): Plug['fetch'];
|
|
66
78
|
unplug(): Promise<void>;
|
|
67
79
|
private eap;
|
|
68
80
|
}
|
package/plug.js
CHANGED
|
@@ -1,87 +1,92 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GlobalPlug = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
const sdkFacade_1 = require("@croct/sdk/facade/sdkFacade");
|
|
5
|
+
const error_1 = require("@croct/sdk/error");
|
|
6
|
+
const validation_1 = require("@croct/sdk/validation");
|
|
7
|
+
const token_1 = require("@croct/sdk/token");
|
|
8
|
+
const sdk_1 = require("@croct/sdk");
|
|
9
|
+
const constants_1 = require("./constants");
|
|
10
|
+
const playground_1 = require("./playground");
|
|
11
|
+
const preview_1 = require("./preview");
|
|
12
|
+
const PLUGIN_NAMESPACE = 'Plugin';
|
|
13
13
|
function detectAppId() {
|
|
14
|
-
|
|
14
|
+
const script = window.document.querySelector(`script[src^='${constants_1.CDN_URL}']`);
|
|
15
15
|
if (!(script instanceof HTMLScriptElement)) {
|
|
16
16
|
return null;
|
|
17
17
|
}
|
|
18
18
|
return (new URL(script.src)).searchParams.get('appId');
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
class GlobalPlug {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.pluginFactories = {
|
|
23
|
+
playground: playground_1.factory,
|
|
24
|
+
preview: preview_1.factory,
|
|
25
|
+
};
|
|
24
26
|
this.plugins = {};
|
|
25
|
-
this.ready = new Promise(
|
|
26
|
-
|
|
27
|
+
this.ready = new Promise(resolve => {
|
|
28
|
+
this.initialize = resolve;
|
|
27
29
|
});
|
|
28
30
|
}
|
|
29
|
-
|
|
31
|
+
extend(name, plugin) {
|
|
30
32
|
if (this.pluginFactories[name] !== undefined) {
|
|
31
|
-
throw new Error(
|
|
33
|
+
throw new Error(`Another plugin is already registered with name "${name}".`);
|
|
32
34
|
}
|
|
33
35
|
this.pluginFactories[name] = plugin;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
var
|
|
37
|
-
var _this = this;
|
|
38
|
-
var _b, _c, _d, _e;
|
|
39
|
-
if (configuration === void 0) { configuration = {}; }
|
|
36
|
+
}
|
|
37
|
+
plug(configuration = {}) {
|
|
38
|
+
var _a, _b, _c, _d;
|
|
40
39
|
if (this.instance !== undefined) {
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
const logger = this.instance.getLogger();
|
|
41
|
+
logger.info('Croct is already plugged in.');
|
|
43
42
|
return;
|
|
44
43
|
}
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const detectedAppId = detectAppId();
|
|
45
|
+
const configuredAppId = (_a = configuration.appId) !== null && _a !== void 0 ? _a : null;
|
|
47
46
|
if (detectedAppId !== null && configuredAppId !== null && detectedAppId !== configuredAppId) {
|
|
48
47
|
throw new Error('The specified app ID and the auto-detected app ID are conflicting. '
|
|
49
48
|
+ 'There is no need to specify an app ID when using an application-specific tag. '
|
|
50
49
|
+ 'Please try again omitting the "appId" option.');
|
|
51
50
|
}
|
|
52
|
-
|
|
51
|
+
const appId = detectedAppId !== null && detectedAppId !== void 0 ? detectedAppId : configuredAppId;
|
|
53
52
|
if (appId === null) {
|
|
54
53
|
throw new Error('The app ID must be specified when it cannot be auto-detected. '
|
|
55
54
|
+ 'Please try again specifying the "appId" option.');
|
|
56
55
|
}
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
const { plugins, test, ...sdkConfiguration } = configuration;
|
|
57
|
+
const sdk = sdkFacade_1.SdkFacade.init({
|
|
58
|
+
...sdkConfiguration,
|
|
59
|
+
appId: appId,
|
|
60
|
+
test: test !== null && test !== void 0 ? test : (typeof process === 'object' && (((_b = process.env) === null || _b === void 0 ? void 0 : _b.CROCT_TEST_MODE) !== undefined
|
|
59
61
|
? process.env.CROCT_TEST_MODE === 'true'
|
|
60
|
-
: ((
|
|
62
|
+
: ((_c = process.env) === null || _c === void 0 ? void 0 : _c.NODE_ENV) === 'test')),
|
|
63
|
+
});
|
|
61
64
|
this.instance = sdk;
|
|
62
|
-
|
|
65
|
+
const logger = this.instance.getLogger();
|
|
63
66
|
if (detectedAppId === configuredAppId) {
|
|
64
67
|
logger.warn('It is strongly recommended omitting the "appId" option when using '
|
|
65
68
|
+ 'the application-specific tag as it is detected automatically.');
|
|
66
69
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
const pending = [];
|
|
71
|
+
const defaultEnabledPlugins = Object.fromEntries(Object.keys(this.pluginFactories)
|
|
72
|
+
.map(name => [name, true]));
|
|
73
|
+
for (const [name, options] of Object.entries({ ...defaultEnabledPlugins, ...plugins })) {
|
|
74
|
+
logger.debug(`Initializing plugin "${name}"...`);
|
|
75
|
+
const factory = this.pluginFactories[name];
|
|
71
76
|
if (factory === undefined) {
|
|
72
|
-
logger.error(
|
|
73
|
-
|
|
77
|
+
logger.error(`Plugin "${name}" is not registered.`);
|
|
78
|
+
continue;
|
|
74
79
|
}
|
|
75
80
|
if (typeof options !== 'boolean' && (options === null || typeof options !== 'object')) {
|
|
76
|
-
logger.error(
|
|
77
|
-
+
|
|
78
|
-
|
|
81
|
+
logger.error(`Invalid options for plugin "${name}", `
|
|
82
|
+
+ `expected either boolean or object but got ${(0, validation_1.describe)(options)}`);
|
|
83
|
+
continue;
|
|
79
84
|
}
|
|
80
85
|
if (options === false) {
|
|
81
|
-
logger.warn(
|
|
82
|
-
|
|
86
|
+
logger.warn(`Plugin "${name}" is declared but not enabled`);
|
|
87
|
+
continue;
|
|
83
88
|
}
|
|
84
|
-
|
|
89
|
+
const args = {
|
|
85
90
|
options: options === true ? {} : options,
|
|
86
91
|
sdk: {
|
|
87
92
|
version: sdk_1.VERSION,
|
|
@@ -91,266 +96,185 @@ var GlobalPlug = /** @class */ (function () {
|
|
|
91
96
|
user: sdk.user,
|
|
92
97
|
session: sdk.session,
|
|
93
98
|
tab: sdk.context.getTab(),
|
|
94
|
-
|
|
99
|
+
userTokenStore: {
|
|
95
100
|
getToken: sdk.getToken.bind(sdk),
|
|
96
101
|
setToken: sdk.setToken.bind(sdk),
|
|
97
102
|
},
|
|
103
|
+
previewTokenStore: sdk.previewTokenStore,
|
|
98
104
|
cidAssigner: sdk.cidAssigner,
|
|
99
105
|
eventManager: sdk.eventManager,
|
|
100
|
-
getLogger:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
namespace[_i] = arguments[_i];
|
|
104
|
-
}
|
|
105
|
-
return sdk.getLogger.apply(sdk, tslib_1.__spreadArray([PLUGIN_NAMESPACE, name_1], tslib_1.__read(namespace), false));
|
|
106
|
-
},
|
|
107
|
-
getTabStorage: function () {
|
|
108
|
-
var namespace = [];
|
|
109
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
110
|
-
namespace[_i] = arguments[_i];
|
|
111
|
-
}
|
|
112
|
-
return (sdk.getTabStorage.apply(sdk, tslib_1.__spreadArray([PLUGIN_NAMESPACE, name_1], tslib_1.__read(namespace), false)));
|
|
113
|
-
},
|
|
114
|
-
getBrowserStorage: function () {
|
|
115
|
-
var namespace = [];
|
|
116
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
117
|
-
namespace[_i] = arguments[_i];
|
|
118
|
-
}
|
|
119
|
-
return (sdk.getBrowserStorage.apply(sdk, tslib_1.__spreadArray([PLUGIN_NAMESPACE, name_1], tslib_1.__read(namespace), false)));
|
|
120
|
-
},
|
|
106
|
+
getLogger: (...namespace) => sdk.getLogger(PLUGIN_NAMESPACE, name, ...namespace),
|
|
107
|
+
getTabStorage: (...namespace) => (sdk.getTabStorage(PLUGIN_NAMESPACE, name, ...namespace)),
|
|
108
|
+
getBrowserStorage: (...namespace) => (sdk.getBrowserStorage(PLUGIN_NAMESPACE, name, ...namespace)),
|
|
121
109
|
},
|
|
122
110
|
};
|
|
123
|
-
|
|
111
|
+
let plugin;
|
|
124
112
|
try {
|
|
125
113
|
plugin = factory(args);
|
|
126
114
|
}
|
|
127
115
|
catch (error) {
|
|
128
|
-
logger.error(
|
|
129
|
-
|
|
116
|
+
logger.error(`Failed to initialize plugin "${name}": ${(0, error_1.formatCause)(error)}`);
|
|
117
|
+
continue;
|
|
130
118
|
}
|
|
131
|
-
logger.debug(
|
|
119
|
+
logger.debug(`Plugin "${name}" initialized`);
|
|
132
120
|
if (typeof plugin !== 'object') {
|
|
133
|
-
|
|
121
|
+
continue;
|
|
134
122
|
}
|
|
135
|
-
|
|
136
|
-
|
|
123
|
+
this.plugins[name] = plugin;
|
|
124
|
+
const promise = plugin.enable();
|
|
137
125
|
if (!(promise instanceof Promise)) {
|
|
138
|
-
logger.debug(
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
pending.push(promise.then(function () { return logger.debug("Plugin \"".concat(name_1, "\" enabled")); })
|
|
142
|
-
.catch(function (error) { return logger.error("Failed to enable plugin \"".concat(name_1, "\": ").concat((0, error_1.formatCause)(error))); }));
|
|
143
|
-
};
|
|
144
|
-
var this_1 = this;
|
|
145
|
-
try {
|
|
146
|
-
for (var _f = tslib_1.__values(Object.entries(tslib_1.__assign({ playground: true }, plugins))), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
147
|
-
var _h = tslib_1.__read(_g.value, 2), name_1 = _h[0], options = _h[1];
|
|
148
|
-
_loop_1(name_1, options);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
152
|
-
finally {
|
|
153
|
-
try {
|
|
154
|
-
if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
|
|
126
|
+
logger.debug(`Plugin "${name}" enabled`);
|
|
127
|
+
continue;
|
|
155
128
|
}
|
|
156
|
-
|
|
129
|
+
pending.push(promise.then(() => logger.debug(`Plugin "${name}" enabled`))
|
|
130
|
+
.catch(error => logger.error(`Failed to enable plugin "${name}": ${(0, error_1.formatCause)(error)}`)));
|
|
157
131
|
}
|
|
158
|
-
|
|
132
|
+
const initializeEap = (_d = window.croctEap) === null || _d === void 0 ? void 0 : _d.initialize;
|
|
159
133
|
if (typeof initializeEap === 'function') {
|
|
160
134
|
initializeEap.call(this);
|
|
161
135
|
}
|
|
162
|
-
Promise.all(pending)
|
|
163
|
-
|
|
136
|
+
Promise.all(pending)
|
|
137
|
+
.then(() => {
|
|
138
|
+
this.initialize();
|
|
164
139
|
logger.debug('Initialization complete');
|
|
165
140
|
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return this.instance;
|
|
198
|
-
},
|
|
199
|
-
enumerable: false,
|
|
200
|
-
configurable: true
|
|
201
|
-
});
|
|
202
|
-
Object.defineProperty(GlobalPlug.prototype, "tracker", {
|
|
203
|
-
get: function () {
|
|
204
|
-
return this.sdk.tracker;
|
|
205
|
-
},
|
|
206
|
-
enumerable: false,
|
|
207
|
-
configurable: true
|
|
208
|
-
});
|
|
209
|
-
Object.defineProperty(GlobalPlug.prototype, "evaluator", {
|
|
210
|
-
get: function () {
|
|
211
|
-
return this.sdk.evaluator;
|
|
212
|
-
},
|
|
213
|
-
enumerable: false,
|
|
214
|
-
configurable: true
|
|
215
|
-
});
|
|
216
|
-
Object.defineProperty(GlobalPlug.prototype, "user", {
|
|
217
|
-
get: function () {
|
|
218
|
-
return this.sdk.user;
|
|
219
|
-
},
|
|
220
|
-
enumerable: false,
|
|
221
|
-
configurable: true
|
|
222
|
-
});
|
|
223
|
-
Object.defineProperty(GlobalPlug.prototype, "session", {
|
|
224
|
-
get: function () {
|
|
225
|
-
return this.sdk.session;
|
|
226
|
-
},
|
|
227
|
-
enumerable: false,
|
|
228
|
-
configurable: true
|
|
229
|
-
});
|
|
230
|
-
GlobalPlug.prototype.isAnonymous = function () {
|
|
141
|
+
}
|
|
142
|
+
get initialized() {
|
|
143
|
+
return this.instance !== undefined;
|
|
144
|
+
}
|
|
145
|
+
get plugged() {
|
|
146
|
+
return this.ready.then(() => this);
|
|
147
|
+
}
|
|
148
|
+
get flushed() {
|
|
149
|
+
return this.tracker
|
|
150
|
+
.flushed
|
|
151
|
+
.then(() => this);
|
|
152
|
+
}
|
|
153
|
+
get sdk() {
|
|
154
|
+
if (this.instance === undefined) {
|
|
155
|
+
throw new Error('Croct is not plugged in.');
|
|
156
|
+
}
|
|
157
|
+
return this.instance;
|
|
158
|
+
}
|
|
159
|
+
get tracker() {
|
|
160
|
+
return this.sdk.tracker;
|
|
161
|
+
}
|
|
162
|
+
get evaluator() {
|
|
163
|
+
return this.sdk.evaluator;
|
|
164
|
+
}
|
|
165
|
+
get user() {
|
|
166
|
+
return this.sdk.user;
|
|
167
|
+
}
|
|
168
|
+
get session() {
|
|
169
|
+
return this.sdk.session;
|
|
170
|
+
}
|
|
171
|
+
isAnonymous() {
|
|
231
172
|
return this.sdk
|
|
232
173
|
.context
|
|
233
174
|
.isAnonymous();
|
|
234
|
-
}
|
|
235
|
-
|
|
175
|
+
}
|
|
176
|
+
getUserId() {
|
|
236
177
|
return this.sdk
|
|
237
178
|
.context
|
|
238
179
|
.getUser();
|
|
239
|
-
}
|
|
240
|
-
|
|
180
|
+
}
|
|
181
|
+
identify(userId) {
|
|
241
182
|
if (typeof userId !== 'string') {
|
|
242
183
|
throw new Error('The user ID must be a string. Read more on https://croct.help/plug-js/id-conversion');
|
|
243
184
|
}
|
|
244
185
|
this.sdk.identify(userId);
|
|
245
|
-
}
|
|
246
|
-
|
|
186
|
+
}
|
|
187
|
+
anonymize() {
|
|
247
188
|
this.sdk.anonymize();
|
|
248
|
-
}
|
|
249
|
-
|
|
189
|
+
}
|
|
190
|
+
setToken(token) {
|
|
250
191
|
this.sdk.setToken(token_1.Token.parse(token));
|
|
251
|
-
}
|
|
252
|
-
|
|
192
|
+
}
|
|
193
|
+
unsetToken() {
|
|
253
194
|
this.sdk.unsetToken();
|
|
254
|
-
}
|
|
255
|
-
|
|
195
|
+
}
|
|
196
|
+
track(type, payload) {
|
|
256
197
|
return this.sdk
|
|
257
198
|
.tracker
|
|
258
199
|
.track(type, payload);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
if (options === void 0) { options = {}; }
|
|
200
|
+
}
|
|
201
|
+
evaluate(expression, options = {}) {
|
|
262
202
|
return this.sdk
|
|
263
203
|
.evaluator
|
|
264
204
|
.evaluate(expression, options);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (options === void 0) { options = {}; }
|
|
205
|
+
}
|
|
206
|
+
test(expression, options = {}) {
|
|
268
207
|
return this.evaluate(expression, options)
|
|
269
|
-
.then(
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
finally { if (e_2) throw e_2.error; }
|
|
317
|
-
}
|
|
318
|
-
// Reset
|
|
319
|
-
delete this.instance;
|
|
320
|
-
this.plugins = {};
|
|
321
|
-
this.ready = new Promise(function (resolve) {
|
|
322
|
-
_this.initialize = resolve;
|
|
323
|
-
});
|
|
324
|
-
return [4 /*yield*/, Promise.all(pending)];
|
|
325
|
-
case 1:
|
|
326
|
-
_f.sent();
|
|
327
|
-
_f.label = 2;
|
|
328
|
-
case 2:
|
|
329
|
-
_f.trys.push([2, , 4, 5]);
|
|
330
|
-
return [4 /*yield*/, instance.close()];
|
|
331
|
-
case 3:
|
|
332
|
-
_f.sent();
|
|
333
|
-
return [3 /*break*/, 5];
|
|
334
|
-
case 4:
|
|
335
|
-
logger.info('🔌 Croct has been unplugged.');
|
|
336
|
-
return [7 /*endfinally*/];
|
|
337
|
-
case 5: return [2 /*return*/];
|
|
338
|
-
}
|
|
339
|
-
});
|
|
208
|
+
.then(result => result === true);
|
|
209
|
+
}
|
|
210
|
+
get fetch() {
|
|
211
|
+
return this.eap('fetch', (slotId, options = {}) => {
|
|
212
|
+
const [id, version] = slotId.split('@');
|
|
213
|
+
const logger = this.sdk.getLogger();
|
|
214
|
+
return this.sdk
|
|
215
|
+
.contentFetcher
|
|
216
|
+
.fetch(id, {
|
|
217
|
+
...options,
|
|
218
|
+
version: version === 'latest' ? undefined : version,
|
|
219
|
+
})
|
|
220
|
+
.then(response => ({
|
|
221
|
+
get payload() {
|
|
222
|
+
logger.warn('Accessing the "payload" property of the fetch response is deprecated'
|
|
223
|
+
+ ' and will be removed in a future version. Use the "content" property instead.');
|
|
224
|
+
return response.content;
|
|
225
|
+
},
|
|
226
|
+
content: response.content,
|
|
227
|
+
}));
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
async unplug() {
|
|
231
|
+
if (this.instance === undefined) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const { instance, plugins } = this;
|
|
235
|
+
const logger = this.sdk.getLogger();
|
|
236
|
+
const pending = [];
|
|
237
|
+
for (const [pluginName, controller] of Object.entries(plugins)) {
|
|
238
|
+
if (typeof controller.disable !== 'function') {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
logger.debug(`Disabling plugin "${pluginName}"...`);
|
|
242
|
+
const promise = controller.disable();
|
|
243
|
+
if (!(promise instanceof Promise)) {
|
|
244
|
+
logger.debug(`Plugin "${pluginName}" disabled`);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
pending.push(promise.then(() => logger.debug(`Plugin "${pluginName}" disabled`))
|
|
248
|
+
.catch(error => logger.error(`Failed to disable "${pluginName}": ${(0, error_1.formatCause)(error)}`)));
|
|
249
|
+
}
|
|
250
|
+
// Reset
|
|
251
|
+
delete this.instance;
|
|
252
|
+
this.plugins = {};
|
|
253
|
+
this.ready = new Promise(resolve => {
|
|
254
|
+
this.initialize = resolve;
|
|
340
255
|
});
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
256
|
+
await Promise.all(pending);
|
|
257
|
+
try {
|
|
258
|
+
await instance.close();
|
|
259
|
+
}
|
|
260
|
+
finally {
|
|
261
|
+
logger.info('🔌 Croct has been unplugged.');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
eap(feature, api) {
|
|
265
|
+
const eap = window.croctEap;
|
|
266
|
+
const method = typeof eap === 'object' ? eap[feature] : undefined;
|
|
346
267
|
if (typeof method !== 'function') {
|
|
347
|
-
|
|
348
|
-
+ 'Early-Access Program (EAP). Please contact your Customer Success Manager or email eap@croct.com '
|
|
349
|
-
+ 'to check your account eligibility.');
|
|
268
|
+
return api;
|
|
350
269
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
270
|
+
return method.bind(new Proxy(this, {
|
|
271
|
+
get: (plug, property) => {
|
|
272
|
+
if (property === feature) {
|
|
273
|
+
return api;
|
|
274
|
+
}
|
|
275
|
+
return plug[property];
|
|
276
|
+
},
|
|
277
|
+
}));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
356
280
|
exports.GlobalPlug = GlobalPlug;
|
package/plugin.d.ts
CHANGED
|
@@ -10,7 +10,8 @@ export interface PluginSdk {
|
|
|
10
10
|
readonly user: UserFacade;
|
|
11
11
|
readonly session: SessionFacade;
|
|
12
12
|
readonly tab: Tab;
|
|
13
|
-
readonly
|
|
13
|
+
readonly userTokenStore: TokenStore;
|
|
14
|
+
readonly previewTokenStore: TokenStore;
|
|
14
15
|
readonly cidAssigner: CidAssigner;
|
|
15
16
|
readonly eventManager: SdkEventManager;
|
|
16
17
|
getLogger(...namespace: string[]): Logger;
|
package/preview.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Logger } from './sdk';
|
|
2
|
+
import { Plugin, PluginFactory } from './plugin';
|
|
3
|
+
import { TokenStore } from './sdk/token';
|
|
4
|
+
export type Configuration = {
|
|
5
|
+
tokenStore: TokenStore;
|
|
6
|
+
logger: Logger;
|
|
7
|
+
};
|
|
8
|
+
export declare class PreviewPlugin implements Plugin {
|
|
9
|
+
private static readonly PREVIEW_PARAMS;
|
|
10
|
+
private readonly tokenStore;
|
|
11
|
+
private readonly logger;
|
|
12
|
+
private readonly widgetId;
|
|
13
|
+
constructor(configuration: Configuration);
|
|
14
|
+
enable(): void;
|
|
15
|
+
disable(): void;
|
|
16
|
+
private updateToken;
|
|
17
|
+
private getWidgetUrl;
|
|
18
|
+
private getWidgetParams;
|
|
19
|
+
private insertWidget;
|
|
20
|
+
private createWidget;
|
|
21
|
+
}
|
|
22
|
+
export declare const factory: PluginFactory;
|
package/preview.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.factory = exports.PreviewPlugin = void 0;
|
|
4
|
+
const error_1 = require("@croct/sdk/error");
|
|
5
|
+
const uuid_1 = require("@croct/sdk/uuid");
|
|
6
|
+
const token_1 = require("./sdk/token");
|
|
7
|
+
const constants_1 = require("./constants");
|
|
8
|
+
const PREVIEW_PARAMETER = 'croct-preview';
|
|
9
|
+
const PREVIEW_EXIT = 'exit';
|
|
10
|
+
class PreviewPlugin {
|
|
11
|
+
constructor(configuration) {
|
|
12
|
+
this.widgetId = `croct-preview:${(0, uuid_1.uuid4)()}`;
|
|
13
|
+
this.tokenStore = configuration.tokenStore;
|
|
14
|
+
this.logger = configuration.logger;
|
|
15
|
+
}
|
|
16
|
+
enable() {
|
|
17
|
+
const url = new URL(window.location.href);
|
|
18
|
+
const previewData = url.searchParams.get(PREVIEW_PARAMETER);
|
|
19
|
+
if (previewData !== null) {
|
|
20
|
+
this.updateToken(previewData);
|
|
21
|
+
// Remove the token from the URL
|
|
22
|
+
url.searchParams.delete(PREVIEW_PARAMETER);
|
|
23
|
+
window.history.replaceState({}, '', url.toString());
|
|
24
|
+
}
|
|
25
|
+
const token = this.tokenStore.getToken();
|
|
26
|
+
if (token !== null) {
|
|
27
|
+
this.insertWidget(this.getWidgetUrl(token));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
disable() {
|
|
31
|
+
var _a;
|
|
32
|
+
(_a = document.getElementById(this.widgetId)) === null || _a === void 0 ? void 0 : _a.remove();
|
|
33
|
+
}
|
|
34
|
+
updateToken(data) {
|
|
35
|
+
if (data === PREVIEW_EXIT) {
|
|
36
|
+
this.logger.debug('Exiting preview mode.');
|
|
37
|
+
this.tokenStore.setToken(null);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
let token = token_1.Token.parse(data);
|
|
42
|
+
const { exp } = token.getPayload();
|
|
43
|
+
if (exp !== undefined && exp <= Date.now() / 1000) {
|
|
44
|
+
this.logger.debug('Preview token expired.');
|
|
45
|
+
token = null;
|
|
46
|
+
}
|
|
47
|
+
this.tokenStore.setToken(token);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
this.tokenStore.setToken(null);
|
|
51
|
+
this.logger.warn(`Invalid preview token: ${(0, error_1.formatCause)(error)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
getWidgetUrl(token) {
|
|
55
|
+
const params = this.getWidgetParams(token);
|
|
56
|
+
let queryString = params.toString();
|
|
57
|
+
if (queryString !== '') {
|
|
58
|
+
queryString = `?${queryString}`;
|
|
59
|
+
}
|
|
60
|
+
return `${constants_1.PREVIEW_WIDGET_URL}${queryString}`;
|
|
61
|
+
}
|
|
62
|
+
getWidgetParams(token) {
|
|
63
|
+
const { metadata = {} } = token.getPayload();
|
|
64
|
+
const params = new URLSearchParams();
|
|
65
|
+
if (metadata === null || typeof metadata !== 'object' || Array.isArray(metadata)) {
|
|
66
|
+
return params;
|
|
67
|
+
}
|
|
68
|
+
for (const [key, param] of Object.entries(PreviewPlugin.PREVIEW_PARAMS)) {
|
|
69
|
+
const value = metadata[key];
|
|
70
|
+
if (typeof value === 'string') {
|
|
71
|
+
params.set(param, value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return params;
|
|
75
|
+
}
|
|
76
|
+
insertWidget(url) {
|
|
77
|
+
const widget = this.createWidget(url);
|
|
78
|
+
window.addEventListener('message', event => {
|
|
79
|
+
if (event.origin !== constants_1.PREVIEW_WIDGET_ORIGIN) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
switch (event.data.type) {
|
|
83
|
+
case 'croct:preview:leave': {
|
|
84
|
+
this.tokenStore.setToken(null);
|
|
85
|
+
const exitUrl = new URL(window.location.href);
|
|
86
|
+
exitUrl.searchParams.set(PREVIEW_PARAMETER, PREVIEW_EXIT);
|
|
87
|
+
window.location.replace(exitUrl.toString());
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case 'croct:preview:resize':
|
|
91
|
+
widget.style.width = `${event.data.width}px`;
|
|
92
|
+
widget.style.height = `${event.data.height}px`;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
document.body.prepend(widget);
|
|
97
|
+
}
|
|
98
|
+
createWidget(url) {
|
|
99
|
+
const widget = document.createElement('iframe');
|
|
100
|
+
widget.setAttribute('id', this.widgetId);
|
|
101
|
+
widget.setAttribute('src', url);
|
|
102
|
+
widget.setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
|
103
|
+
widget.style.position = 'fixed';
|
|
104
|
+
widget.style.width = '0px';
|
|
105
|
+
widget.style.height = '0px';
|
|
106
|
+
widget.style.right = '0';
|
|
107
|
+
widget.style.bottom = '0';
|
|
108
|
+
widget.style.border = '0';
|
|
109
|
+
widget.style.overflow = 'hidden';
|
|
110
|
+
widget.style.zIndex = '2147483647';
|
|
111
|
+
return widget;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.PreviewPlugin = PreviewPlugin;
|
|
115
|
+
PreviewPlugin.PREVIEW_PARAMS = {
|
|
116
|
+
experienceName: 'experience',
|
|
117
|
+
experimentName: 'experiment',
|
|
118
|
+
audienceName: 'audience',
|
|
119
|
+
variantName: 'variant',
|
|
120
|
+
};
|
|
121
|
+
const factory = (props) => {
|
|
122
|
+
const { sdk } = props;
|
|
123
|
+
return new PreviewPlugin({
|
|
124
|
+
tokenStore: props.sdk.previewTokenStore,
|
|
125
|
+
logger: sdk.getLogger(),
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
exports.factory = factory;
|
package/sdk/evaluation.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { EvaluatorFacade, EvaluationOptions } from '@croct/sdk/facade/evaluatorFacade';
|
|
2
|
-
export { EvaluationError, EvaluationErrorType,
|
|
2
|
+
export { EvaluationError, EvaluationErrorType, QueryError } from '@croct/sdk/evaluator';
|
package/sdk/evaluation.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.QueryError = exports.EvaluationErrorType = exports.EvaluationError = exports.EvaluatorFacade = void 0;
|
|
4
4
|
var evaluatorFacade_1 = require("@croct/sdk/facade/evaluatorFacade");
|
|
5
5
|
Object.defineProperty(exports, "EvaluatorFacade", { enumerable: true, get: function () { return evaluatorFacade_1.EvaluatorFacade; } });
|
|
6
6
|
var evaluator_1 = require("@croct/sdk/evaluator");
|
|
7
7
|
Object.defineProperty(exports, "EvaluationError", { enumerable: true, get: function () { return evaluator_1.EvaluationError; } });
|
|
8
8
|
Object.defineProperty(exports, "EvaluationErrorType", { enumerable: true, get: function () { return evaluator_1.EvaluationErrorType; } });
|
|
9
|
-
Object.defineProperty(exports, "
|
|
9
|
+
Object.defineProperty(exports, "QueryError", { enumerable: true, get: function () { return evaluator_1.QueryError; } });
|
package/sdk/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { UserFacade } from '@croct/sdk/facade/userFacade';
|
|
|
6
6
|
export { Tab } from '@croct/sdk/tab';
|
|
7
7
|
export { CidAssigner } from '@croct/sdk/cid';
|
|
8
8
|
export { SdkEventType, SdkEvent } from '@croct/sdk/sdkEvents';
|
|
9
|
-
export
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
export
|
|
9
|
+
export type SdkEventListener<T extends SdkEventType> = EventListener<SdkEventMap[T]>;
|
|
10
|
+
export type SdkEventDispatcher = EventDispatcher<Record<string, Record<string, any>>>;
|
|
11
|
+
export type SdkEventSubscriber = EventSubscriber<SdkEventMap>;
|
|
12
|
+
export type SdkEventManager = EventManager<SdkEventMap, Record<string, Record<string, any>>>;
|
package/sdk/json.d.ts
CHANGED
package/sdk/json.js
CHANGED
package/sdk/token.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Token,
|
|
1
|
+
export { Token, TokenPayload, Headers, TokenProvider, TokenStore } from '@croct/sdk/token';
|
package/sdk/tracking.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ import { TrackingEvent, TrackingEventType } from '@croct/sdk/trackingEvents';
|
|
|
3
3
|
export { TrackerFacade } from '@croct/sdk/facade/trackerFacade';
|
|
4
4
|
export { EventListener } from '@croct/sdk/tracker';
|
|
5
5
|
export { TrackingEvent, TrackingEventType, ExternalTrackingEvent, ExternalTrackingEventPayload, ExternalTrackingEventType, } from '@croct/sdk/trackingEvents';
|
|
6
|
-
export
|
|
6
|
+
export type EventInfo<T extends TrackingEventType> = SdkEventInfo<TrackingEvent<T>>;
|
package/sdk/validation.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
4
|
tslib_1.__exportStar(require("@croct/sdk/validation"), exports);
|
|
5
5
|
tslib_1.__exportStar(require("@croct/sdk/error"), exports);
|
package/slot.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { JsonObject } from '@croct/json';
|
|
2
|
+
export interface SlotMap {
|
|
3
|
+
}
|
|
4
|
+
type LatestSlotVersionMap = {
|
|
5
|
+
[K in keyof SlotMap]: {
|
|
6
|
+
latest: SlotMap[K];
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export interface VersionedSlotMap extends LatestSlotVersionMap {
|
|
10
|
+
}
|
|
11
|
+
type LatestAlias = 'latest';
|
|
12
|
+
export type SlotId = keyof VersionedSlotMap extends never ? string : keyof VersionedSlotMap;
|
|
13
|
+
export type SlotVersion<I extends SlotId = SlotId> = LatestAlias | (I extends keyof VersionedSlotMap ? keyof VersionedSlotMap[I] : never);
|
|
14
|
+
export type VersionedSlotId<I extends SlotId = SlotId> = I | {
|
|
15
|
+
[K in SlotId]: `${K}@${SlotVersion<K> & string}`;
|
|
16
|
+
}[I];
|
|
17
|
+
type VersionedSlotContent<I extends SlotId, V extends string = LatestAlias, C extends JsonObject = JsonObject> = I extends keyof VersionedSlotMap ? (V extends keyof VersionedSlotMap[I] ? VersionedSlotMap[I][V] : C) : C;
|
|
18
|
+
export type ExtractSlotVersion<I extends string> = I extends `${string}@${infer V}` ? (LatestAlias extends V ? LatestAlias : (V extends `${number}` ? V : never)) : LatestAlias;
|
|
19
|
+
export type ExtractSlotId<I extends string> = I extends `${infer V}@${string}` ? V : I;
|
|
20
|
+
export type SlotContent<I extends VersionedSlotId, C extends JsonObject = JsonObject> = VersionedSlotContent<ExtractSlotId<I>, ExtractSlotVersion<I>, C>;
|
|
21
|
+
export {};
|
package/{fetch.js → slot.js}
RENAMED
|
File without changes
|
package/fetch.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { NullableJsonObject, JsonObject } from './sdk/json';
|
|
2
|
-
export interface SlotMap {
|
|
3
|
-
}
|
|
4
|
-
export declare type FetchOptions = {
|
|
5
|
-
timeout?: number;
|
|
6
|
-
attributes?: JsonObject;
|
|
7
|
-
};
|
|
8
|
-
export declare type SlotId = keyof SlotMap extends never ? string : keyof SlotMap;
|
|
9
|
-
export declare type SlotContent<I extends SlotId> = I extends keyof SlotMap ? SlotMap[I] : NullableJsonObject;
|
|
10
|
-
export declare type FetchResponse<I extends SlotId, P extends NullableJsonObject = NullableJsonObject> = {
|
|
11
|
-
payload: SlotContent<I> & P;
|
|
12
|
-
};
|