@reactionary/unomi 0.10.11
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/capabilities/analytics.capability.js +154 -0
- package/capabilities/personalization-profile.capability.js +70 -0
- package/core/client.js +43 -0
- package/core/initialize.js +42 -0
- package/core/initialize.types.js +7 -0
- package/core/session-keys.js +6 -0
- package/factories/index.js +1 -0
- package/factories/personalization-profile/personalization-profile.factory.js +18 -0
- package/index.js +8 -0
- package/package.json +21 -0
- package/schema/capabilities.schema.js +20 -0
- package/schema/configuration.schema.js +12 -0
- package/src/capabilities/analytics.capability.d.ts +15 -0
- package/src/capabilities/personalization-profile.capability.d.ts +12 -0
- package/src/core/client.d.ts +12 -0
- package/src/core/initialize.d.ts +5 -0
- package/src/core/initialize.types.d.ts +31 -0
- package/src/core/session-keys.d.ts +2 -0
- package/src/factories/index.d.ts +1 -0
- package/src/factories/personalization-profile/personalization-profile.factory.d.ts +18 -0
- package/src/index.d.ts +8 -0
- package/src/schema/capabilities.schema.d.ts +31 -0
- package/src/schema/configuration.schema.d.ts +10 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import {
|
|
12
|
+
AnalyticsCapability,
|
|
13
|
+
AnalyticsMutationSchema,
|
|
14
|
+
AnalyticsResultSchema
|
|
15
|
+
} from "@reactionary/core";
|
|
16
|
+
import { Reactionary } from "@reactionary/core";
|
|
17
|
+
import { UnomiAPI } from "../core/client.js";
|
|
18
|
+
class UnomiAnalyticsCapability extends AnalyticsCapability {
|
|
19
|
+
constructor(cache, context, config) {
|
|
20
|
+
super(cache, context);
|
|
21
|
+
this.config = config;
|
|
22
|
+
this.api = new UnomiAPI(config, context);
|
|
23
|
+
}
|
|
24
|
+
config;
|
|
25
|
+
api;
|
|
26
|
+
async track(event) {
|
|
27
|
+
return super.track(event);
|
|
28
|
+
}
|
|
29
|
+
async processProductSummaryView(event) {
|
|
30
|
+
const events = event.products.map((product) => ({
|
|
31
|
+
eventType: "product_view",
|
|
32
|
+
scope: this.config.scope,
|
|
33
|
+
target: {
|
|
34
|
+
itemId: product.key,
|
|
35
|
+
itemType: "product"
|
|
36
|
+
}
|
|
37
|
+
}));
|
|
38
|
+
try {
|
|
39
|
+
await this.postEvents(events);
|
|
40
|
+
return this.accepted();
|
|
41
|
+
} catch {
|
|
42
|
+
return this.rejected();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async processProductSummaryClick(event) {
|
|
46
|
+
const events = [
|
|
47
|
+
{
|
|
48
|
+
eventType: "selectItem",
|
|
49
|
+
scope: this.config.scope,
|
|
50
|
+
targetProperties: {
|
|
51
|
+
productId: event.product.key,
|
|
52
|
+
sku: event.product.key,
|
|
53
|
+
index: event.position
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
try {
|
|
58
|
+
await this.postEvents(events);
|
|
59
|
+
return this.accepted();
|
|
60
|
+
} catch {
|
|
61
|
+
return this.rejected();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async processProductDetailsView(event) {
|
|
65
|
+
const events = [
|
|
66
|
+
{
|
|
67
|
+
eventType: "product_view",
|
|
68
|
+
scope: this.config.scope,
|
|
69
|
+
target: {
|
|
70
|
+
itemId: event.product.key,
|
|
71
|
+
itemType: "product"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
try {
|
|
76
|
+
await this.postEvents(events);
|
|
77
|
+
return this.accepted();
|
|
78
|
+
} catch {
|
|
79
|
+
return this.rejected();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async processProductAddToCart(event) {
|
|
83
|
+
const events = [
|
|
84
|
+
{
|
|
85
|
+
eventType: "addToCart",
|
|
86
|
+
scope: this.config.scope,
|
|
87
|
+
target: {
|
|
88
|
+
itemId: event.product.key,
|
|
89
|
+
itemType: "product",
|
|
90
|
+
customItemType: "product",
|
|
91
|
+
properties: {
|
|
92
|
+
price: 1,
|
|
93
|
+
currency: this.context.languageContext.currencyCode ?? "USD",
|
|
94
|
+
productName: "-"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
try {
|
|
100
|
+
await this.postEvents(events);
|
|
101
|
+
return this.accepted();
|
|
102
|
+
} catch (e) {
|
|
103
|
+
console.error("Error posting addToCart event to Unomi:", e);
|
|
104
|
+
return this.rejected();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async processPurchase(event) {
|
|
108
|
+
const events = [
|
|
109
|
+
{
|
|
110
|
+
eventType: "purchaseComplete",
|
|
111
|
+
scope: this.config.scope,
|
|
112
|
+
targetProperties: {
|
|
113
|
+
totalAmount: event.order.price.grandTotal.value,
|
|
114
|
+
currency: event.order.price.grandTotal.currency,
|
|
115
|
+
itemCount: event.order.items.length
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
];
|
|
119
|
+
try {
|
|
120
|
+
await this.postEvents(events);
|
|
121
|
+
return this.accepted();
|
|
122
|
+
} catch {
|
|
123
|
+
return this.rejected();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async postEvents(events) {
|
|
127
|
+
const profileId = this.context.session.marketingContext.identifier.key;
|
|
128
|
+
const source = {
|
|
129
|
+
itemType: "page",
|
|
130
|
+
scope: this.config.scope,
|
|
131
|
+
itemId: "backend"
|
|
132
|
+
};
|
|
133
|
+
const payload = {
|
|
134
|
+
source,
|
|
135
|
+
profileId,
|
|
136
|
+
events
|
|
137
|
+
};
|
|
138
|
+
const s = JSON.stringify(payload, null, 2);
|
|
139
|
+
console.dir(payload, { depth: null });
|
|
140
|
+
const response = await this.api.postEvent(payload);
|
|
141
|
+
if (!response.ok) {
|
|
142
|
+
throw new Error(`Unomi event request failed with status ${response.status}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
__decorateClass([
|
|
147
|
+
Reactionary({
|
|
148
|
+
inputSchema: AnalyticsMutationSchema,
|
|
149
|
+
outputSchema: AnalyticsResultSchema
|
|
150
|
+
})
|
|
151
|
+
], UnomiAnalyticsCapability.prototype, "track", 1);
|
|
152
|
+
export {
|
|
153
|
+
UnomiAnalyticsCapability
|
|
154
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import {
|
|
12
|
+
PersonalizationProfileCapability,
|
|
13
|
+
PersonalizationProfileQueryGetProfileSchema,
|
|
14
|
+
PersonalizationProfileSchema,
|
|
15
|
+
Reactionary,
|
|
16
|
+
error,
|
|
17
|
+
success
|
|
18
|
+
} from "@reactionary/core";
|
|
19
|
+
import {
|
|
20
|
+
} from "../factories/personalization-profile/personalization-profile.factory.js";
|
|
21
|
+
import { UnomiAPI } from "../core/client.js";
|
|
22
|
+
import { SESSION_KEY_PERSONALIZATION_ID, SESSION_KEY_UNOMI_SESSION_ID } from "../core/session-keys.js";
|
|
23
|
+
class UnomiPersonalizationProfileCapability extends PersonalizationProfileCapability {
|
|
24
|
+
constructor(config, cache, context, factory) {
|
|
25
|
+
super(cache, context);
|
|
26
|
+
this.config = config;
|
|
27
|
+
this.factory = factory;
|
|
28
|
+
this.api = new UnomiAPI(config, context);
|
|
29
|
+
}
|
|
30
|
+
config;
|
|
31
|
+
factory;
|
|
32
|
+
api;
|
|
33
|
+
async getPersonalizationProfile(payload) {
|
|
34
|
+
const newId = globalThis.crypto.randomUUID();
|
|
35
|
+
const profileId = payload.personalizationProfileIdentifier?.key ?? newId;
|
|
36
|
+
const response = await this.api.getProfile(profileId);
|
|
37
|
+
if (response.status === 404) {
|
|
38
|
+
return error({ type: "NotFound", identifier: { key: profileId } });
|
|
39
|
+
}
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
throw new Error(`Unomi profile request failed with status ${response.status}`);
|
|
42
|
+
}
|
|
43
|
+
if (response.status === 204) {
|
|
44
|
+
return success(this.factory.parsePersonalizationProfile(this.context, {
|
|
45
|
+
profileId
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
const profile = await response.json();
|
|
49
|
+
return success(this.factory.parsePersonalizationProfile(this.context, {
|
|
50
|
+
...profile,
|
|
51
|
+
profileId
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
async hash(value) {
|
|
55
|
+
const digest = await globalThis.crypto.subtle.digest(
|
|
56
|
+
"SHA-256",
|
|
57
|
+
new TextEncoder().encode(value)
|
|
58
|
+
);
|
|
59
|
+
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
__decorateClass([
|
|
63
|
+
Reactionary({
|
|
64
|
+
inputSchema: PersonalizationProfileQueryGetProfileSchema,
|
|
65
|
+
outputSchema: PersonalizationProfileSchema
|
|
66
|
+
})
|
|
67
|
+
], UnomiPersonalizationProfileCapability.prototype, "getPersonalizationProfile", 1);
|
|
68
|
+
export {
|
|
69
|
+
UnomiPersonalizationProfileCapability
|
|
70
|
+
};
|
package/core/client.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
class UnomiAPI {
|
|
2
|
+
constructor(config, _context) {
|
|
3
|
+
this.config = config;
|
|
4
|
+
this._context = _context;
|
|
5
|
+
}
|
|
6
|
+
config;
|
|
7
|
+
_context;
|
|
8
|
+
async getProfile(profileId) {
|
|
9
|
+
return fetch(this.getProfileUrl(profileId), {
|
|
10
|
+
headers: this.getHeaders()
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async postEvent(body) {
|
|
14
|
+
return fetch(this.getEventsUrl(), {
|
|
15
|
+
method: "POST",
|
|
16
|
+
headers: {
|
|
17
|
+
...this.getHeaders(),
|
|
18
|
+
"content-type": "application/json"
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify(body)
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
getProfileUrl(profileId) {
|
|
24
|
+
const baseUrl = this.config.apiUrl.replace(/\/$/, "");
|
|
25
|
+
const profilePath = this.config.profilePath.replace(/^\/|\/$/g, "");
|
|
26
|
+
return `${baseUrl}/${profilePath}/${encodeURIComponent(profileId)}`;
|
|
27
|
+
}
|
|
28
|
+
getEventsUrl() {
|
|
29
|
+
return `${this.config.apiUrl.replace(/\/$/, "")}/cxs/context.json`;
|
|
30
|
+
}
|
|
31
|
+
getHeaders() {
|
|
32
|
+
const headers = { accept: "application/json" };
|
|
33
|
+
if (this.config.apiKey) {
|
|
34
|
+
headers["authorization"] = `Bearer ${this.config.apiKey}`;
|
|
35
|
+
} else if (this.config.username && this.config.password) {
|
|
36
|
+
headers["authorization"] = `Basic ${btoa(`${this.config.username}:${this.config.password}`)}`;
|
|
37
|
+
}
|
|
38
|
+
return headers;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
UnomiAPI
|
|
43
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PersonalizationProfileSchema
|
|
3
|
+
} from "@reactionary/core";
|
|
4
|
+
import { UnomiPersonalizationProfileCapability } from "../capabilities/personalization-profile.capability.js";
|
|
5
|
+
import { UnomiAnalyticsCapability } from "../capabilities/analytics.capability.js";
|
|
6
|
+
import { UnomiPersonalizationProfileFactory } from "../factories/personalization-profile/personalization-profile.factory.js";
|
|
7
|
+
import {
|
|
8
|
+
UnomiCapabilitiesSchema
|
|
9
|
+
} from "../schema/capabilities.schema.js";
|
|
10
|
+
import { UnomiConfigurationSchema } from "../schema/configuration.schema.js";
|
|
11
|
+
import { resolveCapabilityWithFactory } from "./initialize.types.js";
|
|
12
|
+
function withUnomiCapabilities(configuration, capabilities) {
|
|
13
|
+
return (cache, context) => {
|
|
14
|
+
const config = UnomiConfigurationSchema.parse(configuration);
|
|
15
|
+
const caps = UnomiCapabilitiesSchema.parse(capabilities);
|
|
16
|
+
const client = {};
|
|
17
|
+
const personalizationProfile = capabilities.personalizationProfile;
|
|
18
|
+
const analytics = capabilities.analytics;
|
|
19
|
+
if (caps.analytics?.enabled) {
|
|
20
|
+
client.analytics = analytics?.capability?.({ config }) ?? new UnomiAnalyticsCapability(cache, context, config);
|
|
21
|
+
}
|
|
22
|
+
if (caps.personalizationProfile?.enabled) {
|
|
23
|
+
client.personalizationProfile = resolveCapabilityWithFactory(
|
|
24
|
+
personalizationProfile,
|
|
25
|
+
{
|
|
26
|
+
factory: new UnomiPersonalizationProfileFactory(PersonalizationProfileSchema),
|
|
27
|
+
capability: (args) => new UnomiPersonalizationProfileCapability(
|
|
28
|
+
config,
|
|
29
|
+
cache,
|
|
30
|
+
context,
|
|
31
|
+
args.factory
|
|
32
|
+
)
|
|
33
|
+
},
|
|
34
|
+
(factory) => ({ config, factory })
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
return client;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
withUnomiCapabilities
|
|
42
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./personalization-profile/personalization-profile.factory.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class UnomiPersonalizationProfileFactory {
|
|
2
|
+
personalizationProfileSchema;
|
|
3
|
+
constructor(personalizationProfileSchema) {
|
|
4
|
+
this.personalizationProfileSchema = personalizationProfileSchema;
|
|
5
|
+
}
|
|
6
|
+
parsePersonalizationProfile(_context, data) {
|
|
7
|
+
const segments = (data.segments ?? []).map((segment) => typeof segment === "string" ? segment : segment.name ?? segment.id).filter((segment) => Boolean(segment));
|
|
8
|
+
const blurb = typeof data.properties?.["description"] === "string" ? data.properties["description"] : "";
|
|
9
|
+
return this.personalizationProfileSchema.parse({
|
|
10
|
+
identifier: { key: data.profileId },
|
|
11
|
+
segments,
|
|
12
|
+
blurb
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
UnomiPersonalizationProfileFactory
|
|
18
|
+
};
|
package/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./schema/configuration.schema.js";
|
|
2
|
+
export * from "./schema/capabilities.schema.js";
|
|
3
|
+
export * from "./core/client.js";
|
|
4
|
+
export * from "./core/initialize.js";
|
|
5
|
+
export * from "./core/initialize.types.js";
|
|
6
|
+
export * from "./factories/index.js";
|
|
7
|
+
export * from "./capabilities/personalization-profile.capability.js";
|
|
8
|
+
export * from "./capabilities/analytics.capability.js";
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reactionary/unomi",
|
|
3
|
+
"version": "0.10.11",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"types": "./src/index.d.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Solteq/reactionary.git"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@reactionary/core": "0.10.11",
|
|
13
|
+
"zod": "4.1.9"
|
|
14
|
+
},
|
|
15
|
+
"private": false,
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"vitest": "^4.0.9"
|
|
19
|
+
},
|
|
20
|
+
"sideEffects": false
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CapabilitiesSchema } from "@reactionary/core";
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
const OverridableCapabilitySchema = z.looseObject({
|
|
4
|
+
enabled: z.boolean(),
|
|
5
|
+
factory: z.unknown().optional(),
|
|
6
|
+
capability: z.unknown().optional()
|
|
7
|
+
});
|
|
8
|
+
const UnomiCapabilitiesSchema = CapabilitiesSchema.pick({
|
|
9
|
+
analytics: true,
|
|
10
|
+
personalizationProfile: true
|
|
11
|
+
}).extend({
|
|
12
|
+
analytics: z.looseObject({
|
|
13
|
+
enabled: z.boolean(),
|
|
14
|
+
capability: z.unknown().optional()
|
|
15
|
+
}).optional(),
|
|
16
|
+
personalizationProfile: OverridableCapabilitySchema.optional()
|
|
17
|
+
}).partial();
|
|
18
|
+
export {
|
|
19
|
+
UnomiCapabilitiesSchema
|
|
20
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
const UnomiConfigurationSchema = z.looseObject({
|
|
3
|
+
apiUrl: z.string().url(),
|
|
4
|
+
username: z.string().optional(),
|
|
5
|
+
password: z.string().optional(),
|
|
6
|
+
apiKey: z.string().optional(),
|
|
7
|
+
profilePath: z.string().default("/cxs/profiles"),
|
|
8
|
+
scope: z.string().default("default")
|
|
9
|
+
});
|
|
10
|
+
export {
|
|
11
|
+
UnomiConfigurationSchema
|
|
12
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AnalyticsCapability, type AnalyticsMutation, type AnalyticsMutationProductAddToCartEvent, type AnalyticsMutationProductDetailsViewEvent, type AnalyticsMutationProductSummaryClickEvent, type AnalyticsMutationProductSummaryViewEvent, type AnalyticsMutationPurchaseEvent, type AnalyticsResult, type Cache, type RequestContext } from '@reactionary/core';
|
|
2
|
+
import { UnomiAPI } from '../core/client.js';
|
|
3
|
+
import type { UnomiConfiguration } from '../schema/configuration.schema.js';
|
|
4
|
+
export declare class UnomiAnalyticsCapability extends AnalyticsCapability {
|
|
5
|
+
protected readonly config: UnomiConfiguration;
|
|
6
|
+
protected readonly api: UnomiAPI;
|
|
7
|
+
constructor(cache: Cache, context: RequestContext, config: UnomiConfiguration);
|
|
8
|
+
track(event: AnalyticsMutation): Promise<AnalyticsResult>;
|
|
9
|
+
protected processProductSummaryView(event: AnalyticsMutationProductSummaryViewEvent): Promise<AnalyticsResult>;
|
|
10
|
+
protected processProductSummaryClick(event: AnalyticsMutationProductSummaryClickEvent): Promise<AnalyticsResult>;
|
|
11
|
+
protected processProductDetailsView(event: AnalyticsMutationProductDetailsViewEvent): Promise<AnalyticsResult>;
|
|
12
|
+
protected processProductAddToCart(event: AnalyticsMutationProductAddToCartEvent): Promise<AnalyticsResult>;
|
|
13
|
+
protected processPurchase(event: AnalyticsMutationPurchaseEvent): Promise<AnalyticsResult>;
|
|
14
|
+
protected postEvents(events: Array<unknown>): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PersonalizationProfileCapability, type Cache, type NotFoundError, type PersonalizationProfileFactory, type PersonalizationProfileFactoryOutput, type PersonalizationProfileFactoryWithOutput, type PersonalizationProfileQueryGetProfile, type RequestContext, type Result } from '@reactionary/core';
|
|
2
|
+
import { type UnomiPersonalizationProfileFactory } from '../factories/personalization-profile/personalization-profile.factory.js';
|
|
3
|
+
import type { UnomiConfiguration } from '../schema/configuration.schema.js';
|
|
4
|
+
import { UnomiAPI } from '../core/client.js';
|
|
5
|
+
export declare class UnomiPersonalizationProfileCapability<TFactory extends PersonalizationProfileFactory = UnomiPersonalizationProfileFactory> extends PersonalizationProfileCapability<PersonalizationProfileFactoryOutput<TFactory>> {
|
|
6
|
+
protected readonly config: UnomiConfiguration;
|
|
7
|
+
protected readonly factory: PersonalizationProfileFactoryWithOutput<TFactory>;
|
|
8
|
+
protected readonly api: UnomiAPI;
|
|
9
|
+
constructor(config: UnomiConfiguration, cache: Cache, context: RequestContext, factory: PersonalizationProfileFactoryWithOutput<TFactory>);
|
|
10
|
+
getPersonalizationProfile(payload: PersonalizationProfileQueryGetProfile): Promise<Result<PersonalizationProfileFactoryOutput<TFactory>, NotFoundError>>;
|
|
11
|
+
protected hash(value: string): Promise<string>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RequestContext } from '@reactionary/core';
|
|
2
|
+
import type { UnomiConfiguration } from '../schema/configuration.schema.js';
|
|
3
|
+
export declare class UnomiAPI {
|
|
4
|
+
protected readonly config: UnomiConfiguration;
|
|
5
|
+
protected readonly _context: RequestContext;
|
|
6
|
+
constructor(config: UnomiConfiguration, _context: RequestContext);
|
|
7
|
+
getProfile(profileId: string): Promise<Response>;
|
|
8
|
+
postEvent(body: Record<string, unknown>): Promise<Response>;
|
|
9
|
+
protected getProfileUrl(profileId: string): string;
|
|
10
|
+
protected getEventsUrl(): string;
|
|
11
|
+
protected getHeaders(): Record<string, string>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Cache, type RequestContext } from '@reactionary/core';
|
|
2
|
+
import { type UnomiCapabilities } from '../schema/capabilities.schema.js';
|
|
3
|
+
import { type UnomiConfiguration } from '../schema/configuration.schema.js';
|
|
4
|
+
import { type UnomiClientFromCapabilities } from './initialize.types.js';
|
|
5
|
+
export declare function withUnomiCapabilities<T extends UnomiCapabilities>(configuration: UnomiConfiguration, capabilities: T): (cache: Cache, context: RequestContext) => UnomiClientFromCapabilities<T>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { PersonalizationProfileFactory } from '@reactionary/core';
|
|
2
|
+
import type { AnalyticsCapability } from '@reactionary/core';
|
|
3
|
+
import type { UnomiCapabilities } from '../schema/capabilities.schema.js';
|
|
4
|
+
import type { UnomiPersonalizationProfileFactory } from '../factories/personalization-profile/personalization-profile.factory.js';
|
|
5
|
+
import type { UnomiPersonalizationProfileCapability } from '../capabilities/personalization-profile.capability.js';
|
|
6
|
+
type ExtractFactory<TCapability> = TCapability extends {
|
|
7
|
+
enabled: true;
|
|
8
|
+
factory?: infer TFactory;
|
|
9
|
+
} ? TFactory extends PersonalizationProfileFactory ? TFactory : UnomiPersonalizationProfileFactory : UnomiPersonalizationProfileFactory;
|
|
10
|
+
type ExtractCapability<TCapability> = TCapability extends {
|
|
11
|
+
enabled: true;
|
|
12
|
+
capability?: infer TCapabilityFactory;
|
|
13
|
+
} ? TCapabilityFactory extends (...args: never[]) => infer TResolvedCapability ? TResolvedCapability : UnomiPersonalizationProfileCapability : UnomiPersonalizationProfileCapability;
|
|
14
|
+
export type UnomiClientFromCapabilities<T extends UnomiCapabilities> = (T['analytics'] extends {
|
|
15
|
+
enabled: true;
|
|
16
|
+
} ? {
|
|
17
|
+
analytics: AnalyticsCapability;
|
|
18
|
+
} : Record<string, never>) & (T['personalizationProfile'] extends {
|
|
19
|
+
enabled: true;
|
|
20
|
+
} ? {
|
|
21
|
+
personalizationProfile: ExtractCapability<T['personalizationProfile']>;
|
|
22
|
+
} : Record<string, never>);
|
|
23
|
+
export declare function resolveCapabilityWithFactory<TFactory, TResolvedCapability, TArgs>(capability: {
|
|
24
|
+
factory?: TFactory;
|
|
25
|
+
capability?: (args: TArgs) => TResolvedCapability;
|
|
26
|
+
} | undefined, defaults: {
|
|
27
|
+
factory: TFactory;
|
|
28
|
+
capability: (args: TArgs) => TResolvedCapability;
|
|
29
|
+
}, buildArgs: (factory: TFactory) => TArgs): TResolvedCapability;
|
|
30
|
+
export type UnomiPersonalizationProfileFactoryFor<T extends UnomiCapabilities> = ExtractFactory<T['personalizationProfile']>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './personalization-profile/personalization-profile.factory.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AnyPersonalizationProfileSchema, PersonalizationProfileFactory, PersonalizationProfileSchema, RequestContext } from '@reactionary/core';
|
|
2
|
+
import type * as z from 'zod';
|
|
3
|
+
export interface UnomiProfileResponse {
|
|
4
|
+
itemId?: string;
|
|
5
|
+
profileId?: string;
|
|
6
|
+
properties?: Record<string, unknown>;
|
|
7
|
+
segments?: Array<string | {
|
|
8
|
+
id?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export declare class UnomiPersonalizationProfileFactory<TPersonalizationProfileSchema extends AnyPersonalizationProfileSchema = typeof PersonalizationProfileSchema> implements PersonalizationProfileFactory<TPersonalizationProfileSchema> {
|
|
13
|
+
readonly personalizationProfileSchema: TPersonalizationProfileSchema;
|
|
14
|
+
constructor(personalizationProfileSchema: TPersonalizationProfileSchema);
|
|
15
|
+
parsePersonalizationProfile(_context: RequestContext, data: UnomiProfileResponse & {
|
|
16
|
+
profileId: string;
|
|
17
|
+
}): z.output<TPersonalizationProfileSchema>;
|
|
18
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './schema/configuration.schema.js';
|
|
2
|
+
export * from './schema/capabilities.schema.js';
|
|
3
|
+
export * from './core/client.js';
|
|
4
|
+
export * from './core/initialize.js';
|
|
5
|
+
export * from './core/initialize.types.js';
|
|
6
|
+
export * from './factories/index.js';
|
|
7
|
+
export * from './capabilities/personalization-profile.capability.js';
|
|
8
|
+
export * from './capabilities/analytics.capability.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AnalyticsCapability, PersonalizationProfileCapability } from '@reactionary/core';
|
|
2
|
+
import * as z from 'zod';
|
|
3
|
+
import type { UnomiConfiguration } from './configuration.schema.js';
|
|
4
|
+
import type { UnomiPersonalizationProfileFactory } from '../factories/personalization-profile/personalization-profile.factory.js';
|
|
5
|
+
export declare const UnomiCapabilitiesSchema: z.ZodObject<{
|
|
6
|
+
analytics: z.ZodOptional<z.ZodOptional<z.ZodObject<{
|
|
7
|
+
enabled: z.ZodBoolean;
|
|
8
|
+
capability: z.ZodOptional<z.ZodUnknown>;
|
|
9
|
+
}, z.core.$loose>>>;
|
|
10
|
+
personalizationProfile: z.ZodOptional<z.ZodOptional<z.ZodObject<{
|
|
11
|
+
enabled: z.ZodBoolean;
|
|
12
|
+
factory: z.ZodOptional<z.ZodUnknown>;
|
|
13
|
+
capability: z.ZodOptional<z.ZodUnknown>;
|
|
14
|
+
}, z.core.$loose>>>;
|
|
15
|
+
}, z.core.$loose>;
|
|
16
|
+
export type UnomiCapabilities = z.infer<typeof UnomiCapabilitiesSchema>;
|
|
17
|
+
export interface UnomiCapabilityFactoryArgs {
|
|
18
|
+
config: UnomiConfiguration;
|
|
19
|
+
}
|
|
20
|
+
export interface UnomiFactoryCapabilityArgs<TFactory> extends UnomiCapabilityFactoryArgs {
|
|
21
|
+
factory: TFactory;
|
|
22
|
+
}
|
|
23
|
+
export interface UnomiPersonalizationProfileCapabilityConfig {
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
factory?: UnomiPersonalizationProfileFactory;
|
|
26
|
+
capability?: (args: UnomiFactoryCapabilityArgs<UnomiPersonalizationProfileFactory>) => PersonalizationProfileCapability;
|
|
27
|
+
}
|
|
28
|
+
export interface UnomiAnalyticsCapabilityConfig {
|
|
29
|
+
enabled: boolean;
|
|
30
|
+
capability?: (args: UnomiCapabilityFactoryArgs) => AnalyticsCapability;
|
|
31
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
export declare const UnomiConfigurationSchema: z.ZodObject<{
|
|
3
|
+
apiUrl: z.ZodString;
|
|
4
|
+
username: z.ZodOptional<z.ZodString>;
|
|
5
|
+
password: z.ZodOptional<z.ZodString>;
|
|
6
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
7
|
+
profilePath: z.ZodDefault<z.ZodString>;
|
|
8
|
+
scope: z.ZodDefault<z.ZodString>;
|
|
9
|
+
}, z.core.$loose>;
|
|
10
|
+
export type UnomiConfiguration = z.infer<typeof UnomiConfigurationSchema>;
|