@getuserfeedback/adapters 0.2.1
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/dist/gtm/index.d.ts +52 -0
- package/dist/gtm/index.d.ts.map +1 -0
- package/dist/gtm/index.js +165 -0
- package/package.json +44 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type InitOptions, type Scope } from "@getuserfeedback/protocol";
|
|
2
|
+
export declare const GTM_CONSENT_TYPES: readonly [
|
|
3
|
+
"functionality_storage",
|
|
4
|
+
"security_storage",
|
|
5
|
+
"analytics_storage",
|
|
6
|
+
"personalization_storage",
|
|
7
|
+
"ad_storage",
|
|
8
|
+
"ad_user_data",
|
|
9
|
+
"ad_personalization"
|
|
10
|
+
];
|
|
11
|
+
export type GtmConsentType = (typeof GTM_CONSENT_TYPES)[number];
|
|
12
|
+
export type GtmConsentValue = "granted" | "denied";
|
|
13
|
+
export type GtmAnalyticsMeasurementMode = "inherit-analytics-storage" | "granted" | "denied";
|
|
14
|
+
export type GtmScopeMapping = {
|
|
15
|
+
scope: Scope;
|
|
16
|
+
consentType: GtmConsentType;
|
|
17
|
+
};
|
|
18
|
+
export type GtmConsentState = Partial<Record<GtmConsentType, GtmConsentValue>>;
|
|
19
|
+
export type GtmTemplateInput = {
|
|
20
|
+
apiKey: string;
|
|
21
|
+
consentState?: GtmConsentState;
|
|
22
|
+
scopeMappings?: ReadonlyArray<GtmScopeMapping>;
|
|
23
|
+
analyticsMeasurementMode?: GtmAnalyticsMeasurementMode;
|
|
24
|
+
colorScheme?: unknown;
|
|
25
|
+
disableTelemetry?: boolean;
|
|
26
|
+
enableDebug?: InitOptions["enableDebug"];
|
|
27
|
+
capabilities?: InitOptions["capabilities"];
|
|
28
|
+
runtimeEndpoints?: InitOptions["runtimeEndpoints"];
|
|
29
|
+
clientMeta?: InitOptions["clientMeta"];
|
|
30
|
+
};
|
|
31
|
+
type GtmTemplateScopeOption = {
|
|
32
|
+
label: string;
|
|
33
|
+
scope: Scope;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
type GtmTemplateMappingOption = {
|
|
37
|
+
consentType: GtmConsentType;
|
|
38
|
+
label: string;
|
|
39
|
+
};
|
|
40
|
+
export declare const DEFAULT_GTM_SCOPE_MAPPINGS: ReadonlyArray<GtmScopeMapping>;
|
|
41
|
+
export declare const GTM_TEMPLATE_SCOPE_OPTIONS: ReadonlyArray<GtmTemplateScopeOption>;
|
|
42
|
+
export declare const GTM_TEMPLATE_MAPPING_OPTIONS: ReadonlyArray<GtmTemplateMappingOption>;
|
|
43
|
+
export declare function isGtmConsentType(value: unknown): value is GtmConsentType;
|
|
44
|
+
export declare function normalizeGtmThemeInput(input: unknown): InitOptions["colorScheme"] | undefined;
|
|
45
|
+
export declare function resolveDefaultConsentFromGtm(input: {
|
|
46
|
+
consentState?: GtmConsentState;
|
|
47
|
+
scopeMappings?: ReadonlyArray<GtmScopeMapping>;
|
|
48
|
+
analyticsMeasurementMode?: GtmAnalyticsMeasurementMode;
|
|
49
|
+
}): InitOptions["defaultConsent"] | undefined;
|
|
50
|
+
export declare function buildInitOptionsFromGtmTemplate(input: GtmTemplateInput): InitOptions;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gtm/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,WAAW,EAEhB,KAAK,KAAK,EACV,MAAM,2BAA2B,CAAC;AAEnC,eAAO,MAAM,iBAAiB,EAAE,SAAS;IACxC,uBAAuB;IACvB,kBAAkB;IAClB,mBAAmB;IACnB,yBAAyB;IACzB,YAAY;IACZ,cAAc;IACd,oBAAoB;CASpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEnD,MAAM,MAAM,2BAA2B,GACpC,2BAA2B,GAC3B,SAAS,GACT,QAAQ,CAAC;AAEZ,MAAM,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,cAAc,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,CAAC;AAE/E,MAAM,MAAM,gBAAgB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,aAAa,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/C,wBAAwB,CAAC,EAAE,2BAA2B,CAAC;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IAC3C,gBAAgB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACnD,UAAU,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;CACvC,CAAC;AAMF,KAAK,sBAAsB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC/B,WAAW,EAAE,cAAc,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACd,CAAC;AAUF,eAAO,MAAM,0BAA0B,EAAE,aAAa,CAAC,eAAe,CA6BrE,CAAC;AA4BF,eAAO,MAAM,0BAA0B,EAAE,aAAa,CAAC,sBAAsB,CAKzE,CAAC;AAEL,eAAO,MAAM,4BAA4B,EAAE,aAAa,CAAC,wBAAwB,CAI7E,CAAC;AAEL,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAKxE;AAED,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,OAAO,GACZ,WAAW,CAAC,aAAa,CAAC,GAAG,SAAS,CA2CxC;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IACnD,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,aAAa,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/C,wBAAwB,CAAC,EAAE,2BAA2B,CAAC;CACvD,GAAG,WAAW,CAAC,gBAAgB,CAAC,GAAG,SAAS,CA0B5C;AAED,wBAAgB,+BAA+B,CAC9C,KAAK,EAAE,gBAAgB,GACrB,WAAW,CA8Bb"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { DEFAULT_AUTO_DETECT_COLOR_SCHEME_ATTRS, listScopes, } from "@getuserfeedback/protocol";
|
|
2
|
+
export const GTM_CONSENT_TYPES = [
|
|
3
|
+
"functionality_storage",
|
|
4
|
+
"security_storage",
|
|
5
|
+
"analytics_storage",
|
|
6
|
+
"personalization_storage",
|
|
7
|
+
"ad_storage",
|
|
8
|
+
"ad_user_data",
|
|
9
|
+
"ad_personalization",
|
|
10
|
+
];
|
|
11
|
+
const essentialScopes = new Set([
|
|
12
|
+
"functionality.storage",
|
|
13
|
+
"security.storage",
|
|
14
|
+
]);
|
|
15
|
+
const isProtocolConsentScope = (scope) => !essentialScopes.has(scope);
|
|
16
|
+
export const DEFAULT_GTM_SCOPE_MAPPINGS = [
|
|
17
|
+
{
|
|
18
|
+
scope: "functionality.storage",
|
|
19
|
+
consentType: "functionality_storage",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
scope: "security.storage",
|
|
23
|
+
consentType: "security_storage",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
scope: "analytics.storage",
|
|
27
|
+
consentType: "analytics_storage",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
scope: "personalization.storage",
|
|
31
|
+
consentType: "personalization_storage",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
scope: "ads.storage",
|
|
35
|
+
consentType: "ad_storage",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
scope: "ads.user_data",
|
|
39
|
+
consentType: "ad_user_data",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
scope: "ads.personalization",
|
|
43
|
+
consentType: "ad_personalization",
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
const toTitleCase = (value) => value
|
|
47
|
+
.split(/[_\-.]/g)
|
|
48
|
+
.filter((part) => part.length > 0)
|
|
49
|
+
.map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`)
|
|
50
|
+
.join(" ");
|
|
51
|
+
const uniqueScopes = (scopes) => {
|
|
52
|
+
const deduped = new Set();
|
|
53
|
+
for (const scope of scopes) {
|
|
54
|
+
if (!isProtocolConsentScope(scope)) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
deduped.add(scope);
|
|
58
|
+
}
|
|
59
|
+
return [...deduped];
|
|
60
|
+
};
|
|
61
|
+
const normalizeAttrList = (value) => value
|
|
62
|
+
.split(",")
|
|
63
|
+
.map((entry) => entry.trim())
|
|
64
|
+
.filter((entry) => entry.length > 0);
|
|
65
|
+
export const GTM_TEMPLATE_SCOPE_OPTIONS = listScopes().map((scopeMeta) => ({
|
|
66
|
+
label: toTitleCase(scopeMeta.id),
|
|
67
|
+
scope: scopeMeta.id,
|
|
68
|
+
description: scopeMeta.description,
|
|
69
|
+
}));
|
|
70
|
+
export const GTM_TEMPLATE_MAPPING_OPTIONS = GTM_CONSENT_TYPES.map((consentType) => ({
|
|
71
|
+
consentType,
|
|
72
|
+
label: toTitleCase(consentType),
|
|
73
|
+
}));
|
|
74
|
+
export function isGtmConsentType(value) {
|
|
75
|
+
if (typeof value !== "string") {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return GTM_CONSENT_TYPES.some((consentType) => consentType === value);
|
|
79
|
+
}
|
|
80
|
+
export function normalizeGtmThemeInput(input) {
|
|
81
|
+
if (input === undefined || input === null) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
if (Array.isArray(input)) {
|
|
85
|
+
const attrs = input
|
|
86
|
+
.filter((value) => typeof value === "string")
|
|
87
|
+
.map((value) => value.trim())
|
|
88
|
+
.filter((value) => value.length > 0);
|
|
89
|
+
if (attrs.length === 0) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
return { autoDetectColorScheme: attrs };
|
|
93
|
+
}
|
|
94
|
+
if (typeof input !== "string") {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const normalized = input.trim().toLowerCase();
|
|
98
|
+
if (normalized.length === 0) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
if (normalized === "light" ||
|
|
102
|
+
normalized === "dark" ||
|
|
103
|
+
normalized === "system") {
|
|
104
|
+
return normalized;
|
|
105
|
+
}
|
|
106
|
+
if (normalized === "auto") {
|
|
107
|
+
return {
|
|
108
|
+
autoDetectColorScheme: [...DEFAULT_AUTO_DETECT_COLOR_SCHEME_ATTRS],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const attrs = normalizeAttrList(input);
|
|
112
|
+
if (attrs.length === 0) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
autoDetectColorScheme: attrs,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export function resolveDefaultConsentFromGtm(input) {
|
|
120
|
+
const consentState = input.consentState;
|
|
121
|
+
if (!consentState) {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
const mappings = input.scopeMappings ?? DEFAULT_GTM_SCOPE_MAPPINGS;
|
|
125
|
+
const grantedScopes = uniqueScopes(mappings.flatMap((mapping) => consentState[mapping.consentType] === "granted" ? [mapping.scope] : []));
|
|
126
|
+
const analyticsMeasurementMode = input.analyticsMeasurementMode ?? "inherit-analytics-storage";
|
|
127
|
+
if (analyticsMeasurementMode === "granted") {
|
|
128
|
+
grantedScopes.push("analytics.measurement");
|
|
129
|
+
}
|
|
130
|
+
if (analyticsMeasurementMode === "inherit-analytics-storage" &&
|
|
131
|
+
consentState.analytics_storage === "granted") {
|
|
132
|
+
grantedScopes.push("analytics.measurement");
|
|
133
|
+
}
|
|
134
|
+
return uniqueScopes(grantedScopes);
|
|
135
|
+
}
|
|
136
|
+
export function buildInitOptionsFromGtmTemplate(input) {
|
|
137
|
+
const colorScheme = normalizeGtmThemeInput(input.colorScheme);
|
|
138
|
+
const defaultConsent = resolveDefaultConsentFromGtm({
|
|
139
|
+
consentState: input.consentState,
|
|
140
|
+
scopeMappings: input.scopeMappings,
|
|
141
|
+
analyticsMeasurementMode: input.analyticsMeasurementMode,
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
apiKey: input.apiKey,
|
|
145
|
+
...(colorScheme !== undefined ? { colorScheme } : {}),
|
|
146
|
+
...(input.disableTelemetry !== undefined
|
|
147
|
+
? { disableTelemetry: input.disableTelemetry }
|
|
148
|
+
: {}),
|
|
149
|
+
...(input.enableDebug !== undefined
|
|
150
|
+
? { enableDebug: input.enableDebug }
|
|
151
|
+
: {}),
|
|
152
|
+
...(defaultConsent !== undefined ? { defaultConsent } : {}),
|
|
153
|
+
clientMeta: {
|
|
154
|
+
...(input.clientMeta ?? {}),
|
|
155
|
+
loader: "gtm",
|
|
156
|
+
transport: input.clientMeta?.transport ?? "tag-manager",
|
|
157
|
+
},
|
|
158
|
+
...(input.capabilities !== undefined
|
|
159
|
+
? { capabilities: input.capabilities }
|
|
160
|
+
: {}),
|
|
161
|
+
...(input.runtimeEndpoints !== undefined
|
|
162
|
+
? { runtimeEndpoints: input.runtimeEndpoints }
|
|
163
|
+
: {}),
|
|
164
|
+
};
|
|
165
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@getuserfeedback/adapters",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "getuserfeedback integration adapters",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"getuserfeedback",
|
|
7
|
+
"widget",
|
|
8
|
+
"adapters",
|
|
9
|
+
"gtm"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
"./gtm": {
|
|
22
|
+
"types": "./dist/gtm/index.d.ts",
|
|
23
|
+
"import": "./dist/gtm/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"prepack": "node scripts/prepack.cjs",
|
|
28
|
+
"postpack": "node scripts/postpack.cjs",
|
|
29
|
+
"lint": "ultracite check .",
|
|
30
|
+
"build": "bun x rimraf dist tsconfig.tsbuildinfo && tsc -b tsconfig.json",
|
|
31
|
+
"typecheck": "tsc -b tsconfig.json",
|
|
32
|
+
"test": "bun test --dots",
|
|
33
|
+
"pack:verify": "node ../../scripts/pack-and-verify.cjs --expect-dependency @getuserfeedback/protocol:../protocol/package.json",
|
|
34
|
+
"publish:dry-run": "node ../../scripts/publish-package.cjs . --expect-dependency @getuserfeedback/protocol:../protocol/package.json -- --dry-run",
|
|
35
|
+
"publish:npm": "node ../../scripts/publish-package.cjs . --expect-dependency @getuserfeedback/protocol:../protocol/package.json"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@getuserfeedback/protocol": "^0.2.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"rimraf": "^6.0.0",
|
|
42
|
+
"typescript": "^5.8.3"
|
|
43
|
+
}
|
|
44
|
+
}
|