@posthog/core 1.27.9 → 1.28.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/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/logs/index.d.ts +94 -4
- package/dist/logs/index.d.ts.map +1 -1
- package/dist/logs/index.js +149 -4
- package/dist/logs/index.mjs +150 -5
- package/dist/logs/logs-utils.d.ts +2 -1
- package/dist/logs/logs-utils.d.ts.map +1 -1
- package/dist/logs/types.d.ts +140 -8
- package/dist/logs/types.d.ts.map +1 -1
- package/dist/posthog-core-stateless.d.ts +34 -0
- package/dist/posthog-core-stateless.d.ts.map +1 -1
- package/dist/posthog-core-stateless.js +46 -0
- package/dist/posthog-core-stateless.mjs +46 -0
- package/dist/posthog-core.d.ts.map +1 -1
- package/dist/posthog-core.js +2 -0
- package/dist/posthog-core.mjs +2 -0
- package/dist/surveys/events.d.ts +22 -0
- package/dist/surveys/events.d.ts.map +1 -0
- package/dist/surveys/events.js +95 -0
- package/dist/surveys/events.mjs +43 -0
- package/dist/surveys/index.d.ts +4 -0
- package/dist/surveys/index.d.ts.map +1 -0
- package/dist/surveys/index.js +83 -0
- package/dist/surveys/index.mjs +4 -0
- package/dist/surveys/translations.d.ts +38 -0
- package/dist/surveys/translations.d.ts.map +1 -0
- package/dist/surveys/translations.js +207 -0
- package/dist/surveys/translations.mjs +158 -0
- package/dist/testing/test-utils.d.ts.map +1 -1
- package/dist/testing/test-utils.js +1 -0
- package/dist/testing/test-utils.mjs +1 -0
- package/dist/types.d.ts +31 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +3 -0
- package/dist/utils/logger.mjs +3 -0
- package/package.json +26 -2
- package/src/index.ts +12 -1
- package/src/logs/index.spec.ts +891 -17
- package/src/logs/index.ts +341 -11
- package/src/logs/logs-utils.spec.ts +2 -1
- package/src/logs/logs-utils.ts +1 -1
- package/src/logs/types.ts +150 -25
- package/src/posthog-core-stateless.ts +80 -0
- package/src/posthog-core.ts +6 -0
- package/src/surveys/events.spec.ts +52 -0
- package/src/surveys/events.ts +80 -0
- package/src/surveys/index.ts +18 -0
- package/src/surveys/translations.spec.ts +205 -0
- package/src/surveys/translations.ts +244 -0
- package/src/testing/test-utils.ts +1 -0
- package/src/types.ts +38 -2
- package/src/utils/logger.ts +6 -2
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
getSurveyInteractionProperty: ()=>external_events_js_namespaceObject.getSurveyInteractionProperty,
|
|
28
|
+
getSurveyOldResponseKey: ()=>external_events_js_namespaceObject.getSurveyOldResponseKey,
|
|
29
|
+
getBaseLanguage: ()=>external_translations_js_namespaceObject.getBaseLanguage,
|
|
30
|
+
getSurveyResponseValue: ()=>external_events_js_namespaceObject.getSurveyResponseValue,
|
|
31
|
+
SURVEY_LANGUAGE_PROPERTY: ()=>external_events_js_namespaceObject.SURVEY_LANGUAGE_PROPERTY,
|
|
32
|
+
detectSurveyLanguage: ()=>external_translations_js_namespaceObject.detectSurveyLanguage,
|
|
33
|
+
applySurveyTranslation: ()=>external_translations_js_namespaceObject.applySurveyTranslation,
|
|
34
|
+
getValidationError: ()=>external_validation_js_namespaceObject.getValidationError,
|
|
35
|
+
getLanguageFromStoredPersonProperties: ()=>external_translations_js_namespaceObject.getLanguageFromStoredPersonProperties,
|
|
36
|
+
buildSurveyResponseProperties: ()=>external_events_js_namespaceObject.buildSurveyResponseProperties,
|
|
37
|
+
getRequirementsHint: ()=>external_validation_js_namespaceObject.getRequirementsHint,
|
|
38
|
+
findBestTranslationMatch: ()=>external_translations_js_namespaceObject.findBestTranslationMatch,
|
|
39
|
+
normalizeLanguageCode: ()=>external_translations_js_namespaceObject.normalizeLanguageCode,
|
|
40
|
+
getSurveyResponseKey: ()=>external_events_js_namespaceObject.getSurveyResponseKey,
|
|
41
|
+
getLengthFromRules: ()=>external_validation_js_namespaceObject.getLengthFromRules,
|
|
42
|
+
surveyHasResponses: ()=>external_events_js_namespaceObject.surveyHasResponses
|
|
43
|
+
});
|
|
44
|
+
const external_validation_js_namespaceObject = require("./validation.js");
|
|
45
|
+
const external_events_js_namespaceObject = require("./events.js");
|
|
46
|
+
const external_translations_js_namespaceObject = require("./translations.js");
|
|
47
|
+
exports.SURVEY_LANGUAGE_PROPERTY = __webpack_exports__.SURVEY_LANGUAGE_PROPERTY;
|
|
48
|
+
exports.applySurveyTranslation = __webpack_exports__.applySurveyTranslation;
|
|
49
|
+
exports.buildSurveyResponseProperties = __webpack_exports__.buildSurveyResponseProperties;
|
|
50
|
+
exports.detectSurveyLanguage = __webpack_exports__.detectSurveyLanguage;
|
|
51
|
+
exports.findBestTranslationMatch = __webpack_exports__.findBestTranslationMatch;
|
|
52
|
+
exports.getBaseLanguage = __webpack_exports__.getBaseLanguage;
|
|
53
|
+
exports.getLanguageFromStoredPersonProperties = __webpack_exports__.getLanguageFromStoredPersonProperties;
|
|
54
|
+
exports.getLengthFromRules = __webpack_exports__.getLengthFromRules;
|
|
55
|
+
exports.getRequirementsHint = __webpack_exports__.getRequirementsHint;
|
|
56
|
+
exports.getSurveyInteractionProperty = __webpack_exports__.getSurveyInteractionProperty;
|
|
57
|
+
exports.getSurveyOldResponseKey = __webpack_exports__.getSurveyOldResponseKey;
|
|
58
|
+
exports.getSurveyResponseKey = __webpack_exports__.getSurveyResponseKey;
|
|
59
|
+
exports.getSurveyResponseValue = __webpack_exports__.getSurveyResponseValue;
|
|
60
|
+
exports.getValidationError = __webpack_exports__.getValidationError;
|
|
61
|
+
exports.normalizeLanguageCode = __webpack_exports__.normalizeLanguageCode;
|
|
62
|
+
exports.surveyHasResponses = __webpack_exports__.surveyHasResponses;
|
|
63
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
64
|
+
"SURVEY_LANGUAGE_PROPERTY",
|
|
65
|
+
"applySurveyTranslation",
|
|
66
|
+
"buildSurveyResponseProperties",
|
|
67
|
+
"detectSurveyLanguage",
|
|
68
|
+
"findBestTranslationMatch",
|
|
69
|
+
"getBaseLanguage",
|
|
70
|
+
"getLanguageFromStoredPersonProperties",
|
|
71
|
+
"getLengthFromRules",
|
|
72
|
+
"getRequirementsHint",
|
|
73
|
+
"getSurveyInteractionProperty",
|
|
74
|
+
"getSurveyOldResponseKey",
|
|
75
|
+
"getSurveyResponseKey",
|
|
76
|
+
"getSurveyResponseValue",
|
|
77
|
+
"getValidationError",
|
|
78
|
+
"normalizeLanguageCode",
|
|
79
|
+
"surveyHasResponses"
|
|
80
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
81
|
+
Object.defineProperty(exports, '__esModule', {
|
|
82
|
+
value: true
|
|
83
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { getLengthFromRules, getRequirementsHint, getValidationError } from "./validation.mjs";
|
|
2
|
+
import { SURVEY_LANGUAGE_PROPERTY, buildSurveyResponseProperties, getSurveyInteractionProperty, getSurveyOldResponseKey, getSurveyResponseKey, getSurveyResponseValue, surveyHasResponses } from "./events.mjs";
|
|
3
|
+
import { applySurveyTranslation, detectSurveyLanguage, findBestTranslationMatch, getBaseLanguage, getLanguageFromStoredPersonProperties, normalizeLanguageCode } from "./translations.mjs";
|
|
4
|
+
export { SURVEY_LANGUAGE_PROPERTY, applySurveyTranslation, buildSurveyResponseProperties, detectSurveyLanguage, findBestTranslationMatch, getBaseLanguage, getLanguageFromStoredPersonProperties, getLengthFromRules, getRequirementsHint, getSurveyInteractionProperty, getSurveyOldResponseKey, getSurveyResponseKey, getSurveyResponseValue, getValidationError, normalizeLanguageCode, surveyHasResponses };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SurveyQuestionTranslation, SurveyTranslation } from '../types';
|
|
2
|
+
export type DetectSurveyLanguageOptions = {
|
|
3
|
+
overrideLanguage?: unknown;
|
|
4
|
+
storedPersonProperties?: unknown;
|
|
5
|
+
locale?: unknown;
|
|
6
|
+
};
|
|
7
|
+
export declare function getLanguageFromStoredPersonProperties(storedPersonProperties: unknown): string | null;
|
|
8
|
+
export declare function detectSurveyLanguage({ overrideLanguage, storedPersonProperties, locale, }: DetectSurveyLanguageOptions): string | null;
|
|
9
|
+
export declare function normalizeLanguageCode(languageCode: string): string;
|
|
10
|
+
export declare function getBaseLanguage(languageCode: string): string;
|
|
11
|
+
export declare function findBestTranslationMatch(translations: Record<string, unknown> | undefined, targetLanguage: string): string | null;
|
|
12
|
+
type TranslatableSurveyAppearance = {
|
|
13
|
+
thankYouMessageHeader?: string;
|
|
14
|
+
thankYouMessageDescription?: string | null;
|
|
15
|
+
thankYouMessageCloseButtonText?: string;
|
|
16
|
+
};
|
|
17
|
+
type TranslatableSurveyQuestion = {
|
|
18
|
+
question: string;
|
|
19
|
+
description?: string | null;
|
|
20
|
+
buttonText?: string;
|
|
21
|
+
link?: string | null;
|
|
22
|
+
lowerBoundLabel?: string;
|
|
23
|
+
upperBoundLabel?: string;
|
|
24
|
+
choices?: string[];
|
|
25
|
+
translations?: Record<string, SurveyQuestionTranslation>;
|
|
26
|
+
};
|
|
27
|
+
type TranslatableSurvey<TQuestion extends TranslatableSurveyQuestion = TranslatableSurveyQuestion> = {
|
|
28
|
+
name: string;
|
|
29
|
+
translations?: Record<string, SurveyTranslation>;
|
|
30
|
+
appearance?: TranslatableSurveyAppearance | null;
|
|
31
|
+
questions: TQuestion[];
|
|
32
|
+
};
|
|
33
|
+
export declare function applySurveyTranslation<TQuestion extends TranslatableSurveyQuestion, TSurvey extends TranslatableSurvey<TQuestion>>(survey: TSurvey, targetLanguage: string): {
|
|
34
|
+
survey: TSurvey;
|
|
35
|
+
matchedKey: string | null;
|
|
36
|
+
};
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=translations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../src/surveys/translations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAKvE,MAAM,MAAM,2BAA2B,GAAG;IACxC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAMD,wBAAgB,qCAAqC,CAAC,sBAAsB,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAUpG;AAED,wBAAgB,oBAAoB,CAAC,EACnC,gBAAgB,EAChB,sBAAsB,EACtB,MAAM,GACP,EAAE,2BAA2B,GAAG,MAAM,GAAG,IAAI,CAqB7C;AAED,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACjD,cAAc,EAAE,MAAM,GACrB,MAAM,GAAG,IAAI,CAuBf;AAgBD,KAAK,4BAA4B,GAAG;IAClC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C,8BAA8B,CAAC,EAAE,MAAM,CAAA;CACxC,CAAA;AAED,KAAK,0BAA0B,GAAG;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAA;CACzD,CAAA;AAED,KAAK,kBAAkB,CAAC,SAAS,SAAS,0BAA0B,GAAG,0BAA0B,IAAI;IACnG,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IAChD,UAAU,CAAC,EAAE,4BAA4B,GAAG,IAAI,CAAA;IAChD,SAAS,EAAE,SAAS,EAAE,CAAA;CACvB,CAAA;AA0DD,wBAAgB,sBAAsB,CACpC,SAAS,SAAS,0BAA0B,EAC5C,OAAO,SAAS,kBAAkB,CAAC,SAAS,CAAC,EAC7C,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAwDzF"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
normalizeLanguageCode: ()=>normalizeLanguageCode,
|
|
28
|
+
getBaseLanguage: ()=>getBaseLanguage,
|
|
29
|
+
detectSurveyLanguage: ()=>detectSurveyLanguage,
|
|
30
|
+
applySurveyTranslation: ()=>applySurveyTranslation,
|
|
31
|
+
findBestTranslationMatch: ()=>findBestTranslationMatch,
|
|
32
|
+
getLanguageFromStoredPersonProperties: ()=>getLanguageFromStoredPersonProperties
|
|
33
|
+
});
|
|
34
|
+
const index_js_namespaceObject = require("../utils/index.js");
|
|
35
|
+
const logger = (0, index_js_namespaceObject.createLogger)('[SurveyTranslations]');
|
|
36
|
+
function getTrimmedLanguage(value) {
|
|
37
|
+
return 'string' == typeof value && value.trim() ? value.trim() : null;
|
|
38
|
+
}
|
|
39
|
+
function getLanguageFromStoredPersonProperties(storedPersonProperties) {
|
|
40
|
+
if (!storedPersonProperties || 'object' != typeof storedPersonProperties || !('language' in storedPersonProperties)) return null;
|
|
41
|
+
return getTrimmedLanguage(storedPersonProperties.language);
|
|
42
|
+
}
|
|
43
|
+
function detectSurveyLanguage({ overrideLanguage, storedPersonProperties, locale }) {
|
|
44
|
+
const explicitLanguage = getTrimmedLanguage(overrideLanguage);
|
|
45
|
+
if (explicitLanguage) {
|
|
46
|
+
logger.info(`Using override display language: ${explicitLanguage}`);
|
|
47
|
+
return explicitLanguage;
|
|
48
|
+
}
|
|
49
|
+
const personLanguage = getLanguageFromStoredPersonProperties(storedPersonProperties);
|
|
50
|
+
if (personLanguage) {
|
|
51
|
+
logger.info(`Using person property language: ${personLanguage}`);
|
|
52
|
+
return personLanguage;
|
|
53
|
+
}
|
|
54
|
+
const detectedLocale = getTrimmedLanguage(locale);
|
|
55
|
+
if (detectedLocale) {
|
|
56
|
+
logger.info(`Using detected locale: ${detectedLocale}`);
|
|
57
|
+
return detectedLocale;
|
|
58
|
+
}
|
|
59
|
+
logger.info('No user language detected');
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
function normalizeLanguageCode(languageCode) {
|
|
63
|
+
return languageCode.toLowerCase();
|
|
64
|
+
}
|
|
65
|
+
function getBaseLanguage(languageCode) {
|
|
66
|
+
return languageCode.split('-')[0];
|
|
67
|
+
}
|
|
68
|
+
function findBestTranslationMatch(translations, targetLanguage) {
|
|
69
|
+
if (!translations || !targetLanguage) return null;
|
|
70
|
+
const normalizedTarget = normalizeLanguageCode(targetLanguage);
|
|
71
|
+
const exactMatch = Object.keys(translations).find((key)=>normalizeLanguageCode(key) === normalizedTarget);
|
|
72
|
+
if (exactMatch) {
|
|
73
|
+
logger.debug(`Found exact translation match: ${exactMatch}`);
|
|
74
|
+
return exactMatch;
|
|
75
|
+
}
|
|
76
|
+
if (normalizedTarget.includes('-')) {
|
|
77
|
+
const baseLanguage = getBaseLanguage(normalizedTarget);
|
|
78
|
+
const baseMatch = Object.keys(translations).find((key)=>normalizeLanguageCode(key) === baseLanguage);
|
|
79
|
+
if (baseMatch) {
|
|
80
|
+
logger.debug(`Found base language translation match: ${baseMatch} (from ${targetLanguage})`);
|
|
81
|
+
return baseMatch;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
function isTranslatedChoices(questionTranslation) {
|
|
87
|
+
return (0, index_js_namespaceObject.isArray)(questionTranslation.choices);
|
|
88
|
+
}
|
|
89
|
+
function hasThankYouTranslation(translation) {
|
|
90
|
+
return !(0, index_js_namespaceObject.isUndefined)(translation.thankYouMessageHeader) || !(0, index_js_namespaceObject.isUndefined)(translation.thankYouMessageDescription) || !(0, index_js_namespaceObject.isUndefined)(translation.thankYouMessageCloseButtonText);
|
|
91
|
+
}
|
|
92
|
+
function mergeQuestionTranslation(question, targetLanguage) {
|
|
93
|
+
const translationKey = findBestTranslationMatch(question.translations, targetLanguage);
|
|
94
|
+
if (!translationKey) return {
|
|
95
|
+
question,
|
|
96
|
+
matchedKey: null,
|
|
97
|
+
hasChanges: false
|
|
98
|
+
};
|
|
99
|
+
const questionTranslation = question.translations?.[translationKey];
|
|
100
|
+
if (!questionTranslation) return {
|
|
101
|
+
question,
|
|
102
|
+
matchedKey: null,
|
|
103
|
+
hasChanges: false
|
|
104
|
+
};
|
|
105
|
+
const translated = {
|
|
106
|
+
...question
|
|
107
|
+
};
|
|
108
|
+
let hasChanges = false;
|
|
109
|
+
if (!(0, index_js_namespaceObject.isUndefined)(questionTranslation.question)) {
|
|
110
|
+
translated.question = questionTranslation.question;
|
|
111
|
+
hasChanges = true;
|
|
112
|
+
}
|
|
113
|
+
if (!(0, index_js_namespaceObject.isUndefined)(questionTranslation.description)) {
|
|
114
|
+
translated.description = questionTranslation.description;
|
|
115
|
+
hasChanges = true;
|
|
116
|
+
}
|
|
117
|
+
if (!(0, index_js_namespaceObject.isUndefined)(questionTranslation.buttonText)) {
|
|
118
|
+
translated.buttonText = questionTranslation.buttonText;
|
|
119
|
+
hasChanges = true;
|
|
120
|
+
}
|
|
121
|
+
if ('link' in translated && !(0, index_js_namespaceObject.isUndefined)(questionTranslation.link)) {
|
|
122
|
+
translated.link = questionTranslation.link;
|
|
123
|
+
hasChanges = true;
|
|
124
|
+
}
|
|
125
|
+
if ('lowerBoundLabel' in translated && !(0, index_js_namespaceObject.isUndefined)(questionTranslation.lowerBoundLabel)) {
|
|
126
|
+
translated.lowerBoundLabel = questionTranslation.lowerBoundLabel;
|
|
127
|
+
hasChanges = true;
|
|
128
|
+
}
|
|
129
|
+
if ('upperBoundLabel' in translated && !(0, index_js_namespaceObject.isUndefined)(questionTranslation.upperBoundLabel)) {
|
|
130
|
+
translated.upperBoundLabel = questionTranslation.upperBoundLabel;
|
|
131
|
+
hasChanges = true;
|
|
132
|
+
}
|
|
133
|
+
if ('choices' in translated && isTranslatedChoices(questionTranslation)) {
|
|
134
|
+
translated.choices = questionTranslation.choices;
|
|
135
|
+
hasChanges = true;
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
question: hasChanges ? translated : question,
|
|
139
|
+
matchedKey: hasChanges ? translationKey : null,
|
|
140
|
+
hasChanges
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function applySurveyTranslation(survey, targetLanguage) {
|
|
144
|
+
const translationKey = findBestTranslationMatch(survey.translations, targetLanguage);
|
|
145
|
+
const translated = {
|
|
146
|
+
...survey
|
|
147
|
+
};
|
|
148
|
+
let hasTranslation = false;
|
|
149
|
+
if (translationKey) {
|
|
150
|
+
const translation = survey.translations?.[translationKey];
|
|
151
|
+
if (translation) {
|
|
152
|
+
logger.info(`Applying survey-level translation for language: ${translationKey}`);
|
|
153
|
+
if (!(0, index_js_namespaceObject.isUndefined)(translation.name)) {
|
|
154
|
+
translated.name = translation.name;
|
|
155
|
+
hasTranslation = true;
|
|
156
|
+
}
|
|
157
|
+
if (translated.appearance) {
|
|
158
|
+
translated.appearance = {
|
|
159
|
+
...translated.appearance
|
|
160
|
+
};
|
|
161
|
+
if (!(0, index_js_namespaceObject.isUndefined)(translation.thankYouMessageHeader)) {
|
|
162
|
+
translated.appearance.thankYouMessageHeader = translation.thankYouMessageHeader;
|
|
163
|
+
hasTranslation = true;
|
|
164
|
+
}
|
|
165
|
+
if (!(0, index_js_namespaceObject.isUndefined)(translation.thankYouMessageDescription)) {
|
|
166
|
+
translated.appearance.thankYouMessageDescription = translation.thankYouMessageDescription;
|
|
167
|
+
hasTranslation = true;
|
|
168
|
+
}
|
|
169
|
+
if (!(0, index_js_namespaceObject.isUndefined)(translation.thankYouMessageCloseButtonText)) {
|
|
170
|
+
translated.appearance.thankYouMessageCloseButtonText = translation.thankYouMessageCloseButtonText;
|
|
171
|
+
hasTranslation = true;
|
|
172
|
+
}
|
|
173
|
+
} else if (hasThankYouTranslation(translation)) hasTranslation = true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const translatedResults = survey.questions.map((question)=>mergeQuestionTranslation(question, targetLanguage));
|
|
177
|
+
const translatedQuestions = translatedResults.map((result)=>result.question);
|
|
178
|
+
const anyQuestionTranslated = translatedResults.some((result)=>result.hasChanges);
|
|
179
|
+
let questionMatchedKey = null;
|
|
180
|
+
if (!translationKey) questionMatchedKey = translatedResults.find((result)=>result.matchedKey)?.matchedKey || null;
|
|
181
|
+
if (anyQuestionTranslated) {
|
|
182
|
+
translated.questions = translatedQuestions;
|
|
183
|
+
hasTranslation = true;
|
|
184
|
+
logger.info(`Applied question-level translations for language: ${targetLanguage}`);
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
survey: translated,
|
|
188
|
+
matchedKey: hasTranslation ? translationKey || questionMatchedKey : null
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
exports.applySurveyTranslation = __webpack_exports__.applySurveyTranslation;
|
|
192
|
+
exports.detectSurveyLanguage = __webpack_exports__.detectSurveyLanguage;
|
|
193
|
+
exports.findBestTranslationMatch = __webpack_exports__.findBestTranslationMatch;
|
|
194
|
+
exports.getBaseLanguage = __webpack_exports__.getBaseLanguage;
|
|
195
|
+
exports.getLanguageFromStoredPersonProperties = __webpack_exports__.getLanguageFromStoredPersonProperties;
|
|
196
|
+
exports.normalizeLanguageCode = __webpack_exports__.normalizeLanguageCode;
|
|
197
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
198
|
+
"applySurveyTranslation",
|
|
199
|
+
"detectSurveyLanguage",
|
|
200
|
+
"findBestTranslationMatch",
|
|
201
|
+
"getBaseLanguage",
|
|
202
|
+
"getLanguageFromStoredPersonProperties",
|
|
203
|
+
"normalizeLanguageCode"
|
|
204
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
205
|
+
Object.defineProperty(exports, '__esModule', {
|
|
206
|
+
value: true
|
|
207
|
+
});
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { createLogger, isArray, isUndefined } from "../utils/index.mjs";
|
|
2
|
+
const logger = createLogger('[SurveyTranslations]');
|
|
3
|
+
function getTrimmedLanguage(value) {
|
|
4
|
+
return 'string' == typeof value && value.trim() ? value.trim() : null;
|
|
5
|
+
}
|
|
6
|
+
function getLanguageFromStoredPersonProperties(storedPersonProperties) {
|
|
7
|
+
if (!storedPersonProperties || 'object' != typeof storedPersonProperties || !('language' in storedPersonProperties)) return null;
|
|
8
|
+
return getTrimmedLanguage(storedPersonProperties.language);
|
|
9
|
+
}
|
|
10
|
+
function detectSurveyLanguage({ overrideLanguage, storedPersonProperties, locale }) {
|
|
11
|
+
const explicitLanguage = getTrimmedLanguage(overrideLanguage);
|
|
12
|
+
if (explicitLanguage) {
|
|
13
|
+
logger.info(`Using override display language: ${explicitLanguage}`);
|
|
14
|
+
return explicitLanguage;
|
|
15
|
+
}
|
|
16
|
+
const personLanguage = getLanguageFromStoredPersonProperties(storedPersonProperties);
|
|
17
|
+
if (personLanguage) {
|
|
18
|
+
logger.info(`Using person property language: ${personLanguage}`);
|
|
19
|
+
return personLanguage;
|
|
20
|
+
}
|
|
21
|
+
const detectedLocale = getTrimmedLanguage(locale);
|
|
22
|
+
if (detectedLocale) {
|
|
23
|
+
logger.info(`Using detected locale: ${detectedLocale}`);
|
|
24
|
+
return detectedLocale;
|
|
25
|
+
}
|
|
26
|
+
logger.info('No user language detected');
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
function normalizeLanguageCode(languageCode) {
|
|
30
|
+
return languageCode.toLowerCase();
|
|
31
|
+
}
|
|
32
|
+
function getBaseLanguage(languageCode) {
|
|
33
|
+
return languageCode.split('-')[0];
|
|
34
|
+
}
|
|
35
|
+
function findBestTranslationMatch(translations, targetLanguage) {
|
|
36
|
+
if (!translations || !targetLanguage) return null;
|
|
37
|
+
const normalizedTarget = normalizeLanguageCode(targetLanguage);
|
|
38
|
+
const exactMatch = Object.keys(translations).find((key)=>normalizeLanguageCode(key) === normalizedTarget);
|
|
39
|
+
if (exactMatch) {
|
|
40
|
+
logger.debug(`Found exact translation match: ${exactMatch}`);
|
|
41
|
+
return exactMatch;
|
|
42
|
+
}
|
|
43
|
+
if (normalizedTarget.includes('-')) {
|
|
44
|
+
const baseLanguage = getBaseLanguage(normalizedTarget);
|
|
45
|
+
const baseMatch = Object.keys(translations).find((key)=>normalizeLanguageCode(key) === baseLanguage);
|
|
46
|
+
if (baseMatch) {
|
|
47
|
+
logger.debug(`Found base language translation match: ${baseMatch} (from ${targetLanguage})`);
|
|
48
|
+
return baseMatch;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
function isTranslatedChoices(questionTranslation) {
|
|
54
|
+
return isArray(questionTranslation.choices);
|
|
55
|
+
}
|
|
56
|
+
function hasThankYouTranslation(translation) {
|
|
57
|
+
return !isUndefined(translation.thankYouMessageHeader) || !isUndefined(translation.thankYouMessageDescription) || !isUndefined(translation.thankYouMessageCloseButtonText);
|
|
58
|
+
}
|
|
59
|
+
function mergeQuestionTranslation(question, targetLanguage) {
|
|
60
|
+
const translationKey = findBestTranslationMatch(question.translations, targetLanguage);
|
|
61
|
+
if (!translationKey) return {
|
|
62
|
+
question,
|
|
63
|
+
matchedKey: null,
|
|
64
|
+
hasChanges: false
|
|
65
|
+
};
|
|
66
|
+
const questionTranslation = question.translations?.[translationKey];
|
|
67
|
+
if (!questionTranslation) return {
|
|
68
|
+
question,
|
|
69
|
+
matchedKey: null,
|
|
70
|
+
hasChanges: false
|
|
71
|
+
};
|
|
72
|
+
const translated = {
|
|
73
|
+
...question
|
|
74
|
+
};
|
|
75
|
+
let hasChanges = false;
|
|
76
|
+
if (!isUndefined(questionTranslation.question)) {
|
|
77
|
+
translated.question = questionTranslation.question;
|
|
78
|
+
hasChanges = true;
|
|
79
|
+
}
|
|
80
|
+
if (!isUndefined(questionTranslation.description)) {
|
|
81
|
+
translated.description = questionTranslation.description;
|
|
82
|
+
hasChanges = true;
|
|
83
|
+
}
|
|
84
|
+
if (!isUndefined(questionTranslation.buttonText)) {
|
|
85
|
+
translated.buttonText = questionTranslation.buttonText;
|
|
86
|
+
hasChanges = true;
|
|
87
|
+
}
|
|
88
|
+
if ('link' in translated && !isUndefined(questionTranslation.link)) {
|
|
89
|
+
translated.link = questionTranslation.link;
|
|
90
|
+
hasChanges = true;
|
|
91
|
+
}
|
|
92
|
+
if ('lowerBoundLabel' in translated && !isUndefined(questionTranslation.lowerBoundLabel)) {
|
|
93
|
+
translated.lowerBoundLabel = questionTranslation.lowerBoundLabel;
|
|
94
|
+
hasChanges = true;
|
|
95
|
+
}
|
|
96
|
+
if ('upperBoundLabel' in translated && !isUndefined(questionTranslation.upperBoundLabel)) {
|
|
97
|
+
translated.upperBoundLabel = questionTranslation.upperBoundLabel;
|
|
98
|
+
hasChanges = true;
|
|
99
|
+
}
|
|
100
|
+
if ('choices' in translated && isTranslatedChoices(questionTranslation)) {
|
|
101
|
+
translated.choices = questionTranslation.choices;
|
|
102
|
+
hasChanges = true;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
question: hasChanges ? translated : question,
|
|
106
|
+
matchedKey: hasChanges ? translationKey : null,
|
|
107
|
+
hasChanges
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function applySurveyTranslation(survey, targetLanguage) {
|
|
111
|
+
const translationKey = findBestTranslationMatch(survey.translations, targetLanguage);
|
|
112
|
+
const translated = {
|
|
113
|
+
...survey
|
|
114
|
+
};
|
|
115
|
+
let hasTranslation = false;
|
|
116
|
+
if (translationKey) {
|
|
117
|
+
const translation = survey.translations?.[translationKey];
|
|
118
|
+
if (translation) {
|
|
119
|
+
logger.info(`Applying survey-level translation for language: ${translationKey}`);
|
|
120
|
+
if (!isUndefined(translation.name)) {
|
|
121
|
+
translated.name = translation.name;
|
|
122
|
+
hasTranslation = true;
|
|
123
|
+
}
|
|
124
|
+
if (translated.appearance) {
|
|
125
|
+
translated.appearance = {
|
|
126
|
+
...translated.appearance
|
|
127
|
+
};
|
|
128
|
+
if (!isUndefined(translation.thankYouMessageHeader)) {
|
|
129
|
+
translated.appearance.thankYouMessageHeader = translation.thankYouMessageHeader;
|
|
130
|
+
hasTranslation = true;
|
|
131
|
+
}
|
|
132
|
+
if (!isUndefined(translation.thankYouMessageDescription)) {
|
|
133
|
+
translated.appearance.thankYouMessageDescription = translation.thankYouMessageDescription;
|
|
134
|
+
hasTranslation = true;
|
|
135
|
+
}
|
|
136
|
+
if (!isUndefined(translation.thankYouMessageCloseButtonText)) {
|
|
137
|
+
translated.appearance.thankYouMessageCloseButtonText = translation.thankYouMessageCloseButtonText;
|
|
138
|
+
hasTranslation = true;
|
|
139
|
+
}
|
|
140
|
+
} else if (hasThankYouTranslation(translation)) hasTranslation = true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const translatedResults = survey.questions.map((question)=>mergeQuestionTranslation(question, targetLanguage));
|
|
144
|
+
const translatedQuestions = translatedResults.map((result)=>result.question);
|
|
145
|
+
const anyQuestionTranslated = translatedResults.some((result)=>result.hasChanges);
|
|
146
|
+
let questionMatchedKey = null;
|
|
147
|
+
if (!translationKey) questionMatchedKey = translatedResults.find((result)=>result.matchedKey)?.matchedKey || null;
|
|
148
|
+
if (anyQuestionTranslated) {
|
|
149
|
+
translated.questions = translatedQuestions;
|
|
150
|
+
hasTranslation = true;
|
|
151
|
+
logger.info(`Applied question-level translations for language: ${targetLanguage}`);
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
survey: translated,
|
|
155
|
+
matchedKey: hasTranslation ? translationKey || questionMatchedKey : null
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
export { applySurveyTranslation, detectSurveyLanguage, findBestTranslationMatch, getBaseLanguage, getLanguageFromStoredPersonProperties, normalizeLanguageCode };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/testing/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEhC,eAAO,MAAM,IAAI,GAAU,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CAElD,CAAA;AAED,eAAO,MAAM,eAAe,QAAa,OAAO,CAAC,IAAI,CAQpD,CAAA;AAED,eAAO,MAAM,SAAS,GAAI,UAAU,GAAG,KAAG,GAIzC,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,CAAC,OAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAM5E,CAAA;AAED,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,KAAG,OAAO,CAAC,IAAI,CAI9C,CAAA;AAED,eAAO,MAAM,gBAAgB,QAAO,
|
|
1
|
+
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/testing/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEhC,eAAO,MAAM,IAAI,GAAU,GAAG,MAAM,KAAG,OAAO,CAAC,IAAI,CAElD,CAAA;AAED,eAAO,MAAM,eAAe,QAAa,OAAO,CAAC,IAAI,CAQpD,CAAA;AAED,eAAO,MAAM,SAAS,GAAI,UAAU,GAAG,KAAG,GAIzC,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,CAAC,OAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAM5E,CAAA;AAED,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,KAAG,OAAO,CAAC,IAAI,CAI9C,CAAA;AAED,eAAO,MAAM,gBAAgB,QAAO,MASnC,CAAA"}
|
|
@@ -60,6 +60,7 @@ const delay = (ms)=>new Promise((resolve)=>{
|
|
|
60
60
|
setTimeout(resolve, ms);
|
|
61
61
|
});
|
|
62
62
|
const createMockLogger = ()=>({
|
|
63
|
+
debug: jest.fn((...args)=>console.debug(...args)),
|
|
63
64
|
info: jest.fn((...args)=>console.log(...args)),
|
|
64
65
|
warn: jest.fn((...args)=>console.warn(...args)),
|
|
65
66
|
error: jest.fn((...args)=>console.error(...args)),
|
|
@@ -27,6 +27,7 @@ const delay = (ms)=>new Promise((resolve)=>{
|
|
|
27
27
|
setTimeout(resolve, ms);
|
|
28
28
|
});
|
|
29
29
|
const createMockLogger = ()=>({
|
|
30
|
+
debug: jest.fn((...args)=>console.debug(...args)),
|
|
30
31
|
info: jest.fn((...args)=>console.log(...args)),
|
|
31
32
|
warn: jest.fn((...args)=>console.warn(...args)),
|
|
32
33
|
error: jest.fn((...args)=>console.error(...args)),
|
package/dist/types.d.ts
CHANGED
|
@@ -318,6 +318,15 @@ export type PostHogRemoteConfig = {
|
|
|
318
318
|
capturePerformance?: boolean | {
|
|
319
319
|
[key: string]: JsonType;
|
|
320
320
|
};
|
|
321
|
+
/**
|
|
322
|
+
* Logs feature remote config. When a map, `captureConsoleLogs` (boolean)
|
|
323
|
+
* is the local opt-in flag for `console.*` autocapture (read by the JS
|
|
324
|
+
* SDK's `PostHogLogs` extension to decide whether to load the autocapture
|
|
325
|
+
* bundle).
|
|
326
|
+
*/
|
|
327
|
+
logs?: boolean | {
|
|
328
|
+
[key: string]: JsonType;
|
|
329
|
+
};
|
|
321
330
|
};
|
|
322
331
|
export type FeatureFlagValue = string | boolean;
|
|
323
332
|
/**
|
|
@@ -534,23 +543,39 @@ export interface SurveyValidationRule {
|
|
|
534
543
|
value?: number;
|
|
535
544
|
errorMessage?: string;
|
|
536
545
|
}
|
|
546
|
+
export interface SurveyTranslation {
|
|
547
|
+
name?: string;
|
|
548
|
+
thankYouMessageHeader?: string;
|
|
549
|
+
thankYouMessageDescription?: string;
|
|
550
|
+
thankYouMessageCloseButtonText?: string;
|
|
551
|
+
}
|
|
552
|
+
export interface SurveyQuestionTranslation {
|
|
553
|
+
question?: string;
|
|
554
|
+
description?: string | null;
|
|
555
|
+
buttonText?: string;
|
|
556
|
+
link?: string | null;
|
|
557
|
+
lowerBoundLabel?: string;
|
|
558
|
+
upperBoundLabel?: string;
|
|
559
|
+
choices?: string[];
|
|
560
|
+
}
|
|
537
561
|
type SurveyQuestionBase = {
|
|
538
562
|
question: string;
|
|
539
563
|
id: string;
|
|
540
|
-
description?: string;
|
|
564
|
+
description?: string | null;
|
|
541
565
|
descriptionContentType?: SurveyQuestionDescriptionContentType;
|
|
542
566
|
optional?: boolean;
|
|
543
567
|
buttonText?: string;
|
|
544
568
|
originalQuestionIndex: number;
|
|
545
569
|
branching?: NextQuestionBranching | EndBranching | ResponseBasedBranching | SpecificQuestionBranching;
|
|
546
570
|
validation?: SurveyValidationRule[];
|
|
571
|
+
translations?: Record<string, SurveyQuestionTranslation>;
|
|
547
572
|
};
|
|
548
573
|
export type BasicSurveyQuestion = SurveyQuestionBase & {
|
|
549
574
|
type: SurveyQuestionType.Open;
|
|
550
575
|
};
|
|
551
576
|
export type LinkSurveyQuestion = SurveyQuestionBase & {
|
|
552
577
|
type: SurveyQuestionType.Link;
|
|
553
|
-
link?: string;
|
|
578
|
+
link?: string | null;
|
|
554
579
|
};
|
|
555
580
|
export type RatingSurveyQuestion = SurveyQuestionBase & {
|
|
556
581
|
type: SurveyQuestionType.Rating;
|
|
@@ -601,6 +626,8 @@ export type SpecificQuestionBranching = {
|
|
|
601
626
|
export type SurveyResponse = {
|
|
602
627
|
surveys: Survey[];
|
|
603
628
|
};
|
|
629
|
+
export type SurveyResponseValue = string | number | string[] | null;
|
|
630
|
+
export type SurveyResponses = Record<string, SurveyResponseValue>;
|
|
604
631
|
export type SurveyCallback = (surveys: Survey[]) => void;
|
|
605
632
|
export declare enum SurveyMatchType {
|
|
606
633
|
Regex = "regex",
|
|
@@ -638,6 +665,7 @@ export type Survey = {
|
|
|
638
665
|
name: string;
|
|
639
666
|
description?: string;
|
|
640
667
|
type: SurveyType;
|
|
668
|
+
translations?: Record<string, SurveyTranslation>;
|
|
641
669
|
feature_flag_keys?: {
|
|
642
670
|
key: string;
|
|
643
671
|
value?: string;
|
|
@@ -696,6 +724,7 @@ export type ActionStepType = {
|
|
|
696
724
|
url_matching?: ActionStepStringMatching;
|
|
697
725
|
};
|
|
698
726
|
export type Logger = {
|
|
727
|
+
debug: (...args: any[]) => void;
|
|
699
728
|
info: (...args: any[]) => void;
|
|
700
729
|
warn: (...args: any[]) => void;
|
|
701
730
|
error: (...args: any[]) => void;
|