@plentymarkets/shop-core 1.13.9 → 1.14.0
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/module.json +1 -1
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/getAllTranslationsMock.d.ts +21 -0
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/getAllTranslationsMock.js +21 -0
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceMock.d.ts +2 -0
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceMock.js +24 -0
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceTranslatedMock.d.ts +2 -0
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceTranslatedMock.js +33 -0
- package/dist/runtime/composables/localization/helpers/extractKeysWithValuesHelper.d.ts +17 -0
- package/dist/runtime/composables/localization/helpers/extractKeysWithValuesHelper.js +40 -0
- package/dist/runtime/composables/localization/{helpers.d.ts → helpers/loadKeysHelper.d.ts} +2 -3
- package/dist/runtime/composables/localization/helpers/loadKeysHelper.js +70 -0
- package/dist/runtime/composables/localization/helpers/messageHelper.d.ts +11 -0
- package/dist/runtime/composables/localization/helpers/messageHelper.js +17 -0
- package/dist/runtime/composables/localization/helpers/transformationHelper.d.ts +13 -0
- package/dist/runtime/composables/localization/helpers/transformationHelper.js +34 -0
- package/dist/runtime/composables/localization/useEditorLocalizationKeys.js +2 -1
- package/dist/runtime/composables/localization/useEditorLocalizationLocales.d.ts +10 -10
- package/dist/runtime/composables/localization/useEditorLocalizationLocales.js +16 -7
- package/dist/runtime/utils/cookieBarHelper.js +12 -5
- package/package.json +2 -2
- package/dist/runtime/composables/localization/helpers.js +0 -157
package/dist/module.json
CHANGED
package/dist/runtime/composables/localization/helpers/__tests__/mocks/getAllTranslationsMock.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const GetAllTranslationsMock: {
|
|
2
|
+
events: never[];
|
|
3
|
+
data: {
|
|
4
|
+
de: {
|
|
5
|
+
welcome: string;
|
|
6
|
+
auth: {
|
|
7
|
+
login: {
|
|
8
|
+
createAccount: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
en: {
|
|
13
|
+
welcome: string;
|
|
14
|
+
auth: {
|
|
15
|
+
login: {
|
|
16
|
+
createAccount: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
};
|
package/dist/runtime/composables/localization/helpers/__tests__/mocks/getAllTranslationsMock.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const GetAllTranslationsMock = {
|
|
2
|
+
"events": [],
|
|
3
|
+
"data": {
|
|
4
|
+
"de": {
|
|
5
|
+
"welcome": "Willkommen vom Backend",
|
|
6
|
+
"auth": {
|
|
7
|
+
"login": {
|
|
8
|
+
"createAccount": "Sie haben noch kein Konto? Erstellen Sie jetzt Ihr Konto!"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"en": {
|
|
13
|
+
"welcome": "Overridden welcome value",
|
|
14
|
+
"auth": {
|
|
15
|
+
"login": {
|
|
16
|
+
"createAccount": "Don't have an account? Sign up now!"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
export const i18nInstanceMock = {
|
|
3
|
+
availableLocales: ["en", "de"],
|
|
4
|
+
loadLocaleMessages: vi.fn(),
|
|
5
|
+
getLocaleMessage: vi.fn((locale) => {
|
|
6
|
+
if (locale === "en") {
|
|
7
|
+
return {
|
|
8
|
+
welcome: "Welcome",
|
|
9
|
+
"nested.key": "Nested value",
|
|
10
|
+
"translated.shouldBeSkipped": "Skip this"
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (locale === "de") {
|
|
14
|
+
return {
|
|
15
|
+
welcome: "Willkommen",
|
|
16
|
+
"nested.key": "Verschachtelter Wert",
|
|
17
|
+
"translated.shouldBeSkipped": "\xDCberspringe"
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return {};
|
|
21
|
+
}),
|
|
22
|
+
te: vi.fn(),
|
|
23
|
+
t: vi.fn()
|
|
24
|
+
};
|
package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceTranslatedMock.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
export const i18nInstanceTranslatedMock = {
|
|
3
|
+
availableLocales: ["en", "de"],
|
|
4
|
+
loadLocaleMessages: vi.fn(),
|
|
5
|
+
getLocaleMessage: vi.fn((locale) => {
|
|
6
|
+
if (locale === "en") {
|
|
7
|
+
return {
|
|
8
|
+
welcome: "Welcome",
|
|
9
|
+
"nested.key": "Nested value",
|
|
10
|
+
translated: {
|
|
11
|
+
"welcome": "Overridden welcome value",
|
|
12
|
+
"another.override": "Another override",
|
|
13
|
+
"nested.translated.key": "Nested translated value"
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (locale === "de") {
|
|
18
|
+
return {
|
|
19
|
+
welcome: "Willkommen",
|
|
20
|
+
"nested.key": "Verschachtelter Wert",
|
|
21
|
+
translated: {
|
|
22
|
+
"welcome": "\xDCberschriebener Wert f\xFCr welcome",
|
|
23
|
+
"another.override": "Weitere \xDCberschreibung",
|
|
24
|
+
"nested.translated.key": "Verschachtelter \xFCbersetzter Wert",
|
|
25
|
+
"key.thatdoesnotexist": "Dieser Schl\xFCssel existiert nur in der \xDCbersetzung"
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return {};
|
|
30
|
+
}),
|
|
31
|
+
te: vi.fn(),
|
|
32
|
+
t: vi.fn()
|
|
33
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { LocalizationMessage } from "~/src/module";
|
|
2
|
+
/**
|
|
3
|
+
* Get translation value from compiled message or string
|
|
4
|
+
* @param value
|
|
5
|
+
*/
|
|
6
|
+
export declare const getTranslationValue: (value: unknown) => string | null;
|
|
7
|
+
/**
|
|
8
|
+
* Check if value is a nested object (not array or compiled message)
|
|
9
|
+
* @param value
|
|
10
|
+
*/
|
|
11
|
+
export declare const isNestedObject: (value: unknown) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Recursively extract keys with values from nested objects
|
|
14
|
+
* @param obj
|
|
15
|
+
* @param prefix
|
|
16
|
+
*/
|
|
17
|
+
export declare const extractKeysWithValues: (obj: Record<string, unknown>, prefix?: string) => Record<string, LocalizationMessage>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { isCompiledMessage } from "./messageHelper.js";
|
|
2
|
+
export const getTranslationValue = (value) => {
|
|
3
|
+
if (isCompiledMessage(value) && value) {
|
|
4
|
+
const data = value;
|
|
5
|
+
return data?.loc?.source ?? data?.b?.s ?? "";
|
|
6
|
+
}
|
|
7
|
+
if (typeof value === "string") {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
};
|
|
12
|
+
export const isNestedObject = (value) => {
|
|
13
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && !isCompiledMessage(value);
|
|
14
|
+
};
|
|
15
|
+
export const extractKeysWithValues = (obj, prefix = "") => {
|
|
16
|
+
const result = {};
|
|
17
|
+
for (const key in obj) {
|
|
18
|
+
let fullKey = prefix ? `${prefix}.${key}` : key;
|
|
19
|
+
if (fullKey.endsWith(".body.static")) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (fullKey.endsWith(".loc.source")) {
|
|
23
|
+
fullKey = fullKey.substring(0, fullKey.length - ".loc.source".length);
|
|
24
|
+
}
|
|
25
|
+
const value = obj[key];
|
|
26
|
+
if (isNestedObject(value)) {
|
|
27
|
+
Object.assign(result, extractKeysWithValues(value, fullKey));
|
|
28
|
+
} else {
|
|
29
|
+
const translationValue = getTranslationValue(value);
|
|
30
|
+
if (translationValue)
|
|
31
|
+
result[fullKey] = {
|
|
32
|
+
value: translationValue,
|
|
33
|
+
default: translationValue,
|
|
34
|
+
input: translationValue,
|
|
35
|
+
isDeployed: true
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { LocalizationMessage, I18nInstance } from '
|
|
2
|
-
export declare const unflattenTranslations: (flat: Record<string, string>) => Record<string, any>;
|
|
1
|
+
import type { LocalizationMessage, I18nInstance } from '../../../types/index.js';
|
|
3
2
|
/**
|
|
4
3
|
* Load default keys from i18n messages (PWA)
|
|
5
4
|
* @param keysMap
|
|
@@ -8,7 +7,7 @@ export declare const unflattenTranslations: (flat: Record<string, string>) => Re
|
|
|
8
7
|
export declare const loadDefaultKeys: (keysMap: Map<string, Record<string, LocalizationMessage>>, $i18n: I18nInstance) => Promise<void>;
|
|
9
8
|
/**
|
|
10
9
|
* Load translated keys from i18n messages (Module Overrides)
|
|
11
|
-
* @param keysMap
|
|
10
|
+
* @param keysMap requires to have default keys already loaded with loadDefaultKeys()
|
|
12
11
|
* @param $i18n
|
|
13
12
|
*/
|
|
14
13
|
export declare const loadTranslatedKeys: (keysMap: Map<string, Record<string, LocalizationMessage>>, $i18n: I18nInstance) => void;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useRuntimeConfig } from "nuxt/app";
|
|
2
|
+
import { useSdk } from "../../useSdk.js";
|
|
3
|
+
import { flattenTranslations } from "./transformationHelper.js";
|
|
4
|
+
import { createEmptyMessage } from "./messageHelper.js";
|
|
5
|
+
import { extractKeysWithValues } from "./extractKeysWithValuesHelper.js";
|
|
6
|
+
export const loadDefaultKeys = async (keysMap, $i18n) => {
|
|
7
|
+
for (const locale of $i18n.availableLocales) {
|
|
8
|
+
await $i18n.loadLocaleMessages(locale);
|
|
9
|
+
const messages = $i18n.getLocaleMessage(locale);
|
|
10
|
+
const keysWithValues = extractKeysWithValues(messages);
|
|
11
|
+
for (const [key, value] of Object.entries(keysWithValues)) {
|
|
12
|
+
if (key.startsWith("translated.")) continue;
|
|
13
|
+
if (!keysMap.has(key)) {
|
|
14
|
+
keysMap.set(key, createEmptyMessage($i18n.availableLocales));
|
|
15
|
+
}
|
|
16
|
+
const translations = keysMap.get(key);
|
|
17
|
+
translations[locale] = value;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export const loadTranslatedKeys = (keysMap, $i18n) => {
|
|
22
|
+
for (const locale of $i18n.availableLocales) {
|
|
23
|
+
const messages = $i18n.getLocaleMessage(locale);
|
|
24
|
+
const translatedMessages = messages["translated"];
|
|
25
|
+
if (!translatedMessages) continue;
|
|
26
|
+
const keysWithValues = extractKeysWithValues(translatedMessages);
|
|
27
|
+
for (const [key, value] of Object.entries(keysWithValues)) {
|
|
28
|
+
if (!keysMap.has(key)) {
|
|
29
|
+
keysMap.set(key, createEmptyMessage($i18n.availableLocales));
|
|
30
|
+
}
|
|
31
|
+
const translations = keysMap.get(key);
|
|
32
|
+
if (translations[locale]) {
|
|
33
|
+
translations[locale].value = value.value;
|
|
34
|
+
translations[locale].input = value.input;
|
|
35
|
+
} else {
|
|
36
|
+
translations[locale] = value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
export const loadKeysFromBackend = async (keysMap, $i18n, backendLanguages) => {
|
|
42
|
+
try {
|
|
43
|
+
const config = useRuntimeConfig().public.shopCore;
|
|
44
|
+
const configId = config?.configId;
|
|
45
|
+
if (!configId) return;
|
|
46
|
+
const { data } = await useSdk().plentysystems.getAllTranslations({ configId });
|
|
47
|
+
const flattened = flattenTranslations(data);
|
|
48
|
+
for (const [lang, translations] of Object.entries(flattened)) {
|
|
49
|
+
if (backendLanguages && Object.keys(translations).length > 0) backendLanguages.add(lang);
|
|
50
|
+
for (const [key, value] of Object.entries(translations)) {
|
|
51
|
+
if (!keysMap.has(key)) {
|
|
52
|
+
keysMap.set(key, createEmptyMessage($i18n.availableLocales));
|
|
53
|
+
}
|
|
54
|
+
const localeTranslations = keysMap.get(key);
|
|
55
|
+
if (localeTranslations[lang]) {
|
|
56
|
+
localeTranslations[lang].isDeployed = localeTranslations[lang].value === value;
|
|
57
|
+
localeTranslations[lang].value = value;
|
|
58
|
+
localeTranslations[lang].input = value;
|
|
59
|
+
} else {
|
|
60
|
+
localeTranslations[lang] = {
|
|
61
|
+
value,
|
|
62
|
+
input: value,
|
|
63
|
+
isDeployed: false
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
} catch {
|
|
69
|
+
}
|
|
70
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if value is a compiled message
|
|
3
|
+
* for production and dev builds of vue-i18n
|
|
4
|
+
* @param value
|
|
5
|
+
*/
|
|
6
|
+
export declare const isCompiledMessage: (value: unknown) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Create an empty message object for all locales
|
|
9
|
+
* @param availableLocales
|
|
10
|
+
*/
|
|
11
|
+
export declare const createEmptyMessage: (availableLocales: string[]) => {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const isCompiledMessage = (value) => {
|
|
2
|
+
return typeof value === "object" && value !== null && ("loc" in value && typeof value.loc === "object" && value.loc !== null && "source" in value.loc && typeof value.loc.source === "string" || "b" in value && typeof value.b === "object" && value.b !== null && "s" in value.b && typeof value.b.s === "string");
|
|
3
|
+
};
|
|
4
|
+
export const createEmptyMessage = (availableLocales) => {
|
|
5
|
+
let data = {};
|
|
6
|
+
for (const locale of availableLocales) {
|
|
7
|
+
data = {
|
|
8
|
+
...data,
|
|
9
|
+
[locale]: {
|
|
10
|
+
value: "",
|
|
11
|
+
input: "",
|
|
12
|
+
isDeployed: true
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return data;
|
|
17
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TranslationObject } from "@plentymarkets/shop-api";
|
|
2
|
+
/**
|
|
3
|
+
* Flatten nested translation objects into dot notation
|
|
4
|
+
* e.g. { module: { key: 'value' } } => { 'module.key': 'value' }
|
|
5
|
+
* @param data
|
|
6
|
+
*/
|
|
7
|
+
export declare const flattenTranslations: (data: Record<string, TranslationObject>) => Record<string, Record<string, string>>;
|
|
8
|
+
/**
|
|
9
|
+
* Unflatten dot notation into nested objects
|
|
10
|
+
* e.g. { 'module.key': 'value' } => { module: { key: 'value' } }
|
|
11
|
+
* @param flat
|
|
12
|
+
*/
|
|
13
|
+
export declare const unflattenTranslations: (flat: Record<string, string>) => Record<string, any>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const flattenTranslations = (data) => {
|
|
2
|
+
const result = {};
|
|
3
|
+
function flattenObject(obj, prefix = "") {
|
|
4
|
+
const flattened = {};
|
|
5
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
6
|
+
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
7
|
+
if (typeof value === "string") {
|
|
8
|
+
flattened[newKey] = value;
|
|
9
|
+
} else {
|
|
10
|
+
Object.assign(flattened, flattenObject(value, newKey));
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return flattened;
|
|
14
|
+
}
|
|
15
|
+
for (const [lang, modules] of Object.entries(data)) {
|
|
16
|
+
result[lang] = flattenObject(modules);
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
export const unflattenTranslations = (flat) => {
|
|
21
|
+
const result = {};
|
|
22
|
+
for (const [key, value] of Object.entries(flat)) {
|
|
23
|
+
const parts = key.split(".");
|
|
24
|
+
let current = result;
|
|
25
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
26
|
+
const part = parts[i];
|
|
27
|
+
if (!current[part]) current[part] = {};
|
|
28
|
+
current = current[part];
|
|
29
|
+
}
|
|
30
|
+
const lastPart = parts[parts.length - 1];
|
|
31
|
+
current[lastPart] = value;
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { useState, useNuxtApp, useRuntimeConfig } from "nuxt/app";
|
|
2
2
|
import { toRefs } from "vue";
|
|
3
|
-
import { loadDefaultKeys, loadTranslatedKeys, loadKeysFromBackend
|
|
3
|
+
import { loadDefaultKeys, loadTranslatedKeys, loadKeysFromBackend } from "./helpers/loadKeysHelper.js";
|
|
4
4
|
import { useSdk, useNotification, useEditorLocalizationLocales } from "#imports";
|
|
5
5
|
import { allLanguages } from "./useEditorLocalizationLocales.js";
|
|
6
|
+
import { unflattenTranslations } from "./helpers/transformationHelper.js";
|
|
6
7
|
export const useEditorLocalizationKeys = () => {
|
|
7
8
|
const state = useState("useEditorLocalizationKeys", () => ({
|
|
8
9
|
keys: [],
|
|
@@ -9,15 +9,15 @@ export declare const allLanguages: {
|
|
|
9
9
|
nl: string;
|
|
10
10
|
pl: string;
|
|
11
11
|
pt: string;
|
|
12
|
-
|
|
12
|
+
nn: string;
|
|
13
13
|
ro: string;
|
|
14
14
|
da: string;
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
se: string;
|
|
16
|
+
cz: string;
|
|
17
17
|
ru: string;
|
|
18
18
|
sk: string;
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
cn: string;
|
|
20
|
+
vn: string;
|
|
21
21
|
};
|
|
22
22
|
export declare const useEditorLocalizationLocales: () => {
|
|
23
23
|
allLanguages: {
|
|
@@ -31,15 +31,15 @@ export declare const useEditorLocalizationLocales: () => {
|
|
|
31
31
|
nl: string;
|
|
32
32
|
pl: string;
|
|
33
33
|
pt: string;
|
|
34
|
-
|
|
34
|
+
nn: string;
|
|
35
35
|
ro: string;
|
|
36
36
|
da: string;
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
se: string;
|
|
38
|
+
cz: string;
|
|
39
39
|
ru: string;
|
|
40
40
|
sk: string;
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
cn: string;
|
|
42
|
+
vn: string;
|
|
43
43
|
};
|
|
44
44
|
selectLocale: (locale: string) => void;
|
|
45
45
|
removeLocale: (locale: string) => void;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useState } from "#app";
|
|
2
2
|
import { toRefs } from "vue";
|
|
3
3
|
export const allLanguages = {
|
|
4
|
-
de: "German
|
|
5
|
-
en: "English
|
|
4
|
+
de: "German",
|
|
5
|
+
en: "English",
|
|
6
6
|
bg: "Bulgarian",
|
|
7
7
|
fr: "French",
|
|
8
8
|
it: "Italian",
|
|
@@ -11,15 +11,24 @@ export const allLanguages = {
|
|
|
11
11
|
nl: "Dutch",
|
|
12
12
|
pl: "Polish",
|
|
13
13
|
pt: "Portuguese",
|
|
14
|
-
|
|
14
|
+
nn: "Norwegian",
|
|
15
15
|
ro: "Romanian",
|
|
16
16
|
da: "Danish",
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
se: "Swedish",
|
|
18
|
+
cz: "Czech",
|
|
19
19
|
ru: "Russian",
|
|
20
20
|
sk: "Slovak",
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
cn: "Chinese",
|
|
22
|
+
vn: "Vietnamese"
|
|
23
|
+
/*
|
|
24
|
+
fi: 'Finnish',
|
|
25
|
+
ga: 'Irish',
|
|
26
|
+
lt: 'Lithuanian',
|
|
27
|
+
lv: 'Latvian',
|
|
28
|
+
et: 'Estonian',
|
|
29
|
+
hr: 'Croatian',
|
|
30
|
+
hu: 'Hungarian',
|
|
31
|
+
*/
|
|
23
32
|
};
|
|
24
33
|
export const useEditorLocalizationLocales = () => {
|
|
25
34
|
const state = useState("useEditorLocalizationLocales", () => ({
|
|
@@ -2,11 +2,18 @@ const convertToDays = (daysInString) => {
|
|
|
2
2
|
return Number.parseInt(daysInString.split(" ")[0]);
|
|
3
3
|
};
|
|
4
4
|
const getMinimumLifeSpan = (cookieJsonFromConfig) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
let minimum = 999999;
|
|
6
|
+
cookieJsonFromConfig.forEach((group) => {
|
|
7
|
+
const accepted = group.cookies.filter((cookie) => {
|
|
8
|
+
return cookie.accepted;
|
|
9
|
+
});
|
|
10
|
+
accepted.forEach((cookie) => {
|
|
11
|
+
if (cookie.Lifespan && minimum > convertToDays(cookie.Lifespan)) {
|
|
12
|
+
minimum = convertToDays(cookie.Lifespan);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
return 60 * 60 * 24 * minimum;
|
|
10
17
|
};
|
|
11
18
|
export const cookieBarHelper = () => {
|
|
12
19
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plentymarkets/shop-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Core module for PlentyONE Shop",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"test:types": "vue-tsc --noEmit"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@plentymarkets/shop-api": "^0.
|
|
48
|
+
"@plentymarkets/shop-api": "^0.147.0",
|
|
49
49
|
"@vue-storefront/sdk": "^3.4.1",
|
|
50
50
|
"cookie": "^1.0.2",
|
|
51
51
|
"js-sha256": "^0.11.0",
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { useRuntimeConfig } from "nuxt/app";
|
|
2
|
-
import { useSdk } from "#imports";
|
|
3
|
-
function flattenTranslations(data) {
|
|
4
|
-
const result = {};
|
|
5
|
-
function flattenObject(obj, prefix = "") {
|
|
6
|
-
const flattened = {};
|
|
7
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
8
|
-
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
9
|
-
if (typeof value === "string") {
|
|
10
|
-
flattened[newKey] = value;
|
|
11
|
-
} else {
|
|
12
|
-
Object.assign(flattened, flattenObject(value, newKey));
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return flattened;
|
|
16
|
-
}
|
|
17
|
-
for (const [lang, modules] of Object.entries(data)) {
|
|
18
|
-
result[lang] = flattenObject(modules);
|
|
19
|
-
}
|
|
20
|
-
return result;
|
|
21
|
-
}
|
|
22
|
-
export const unflattenTranslations = (flat) => {
|
|
23
|
-
const result = {};
|
|
24
|
-
for (const [key, value] of Object.entries(flat)) {
|
|
25
|
-
const parts = key.split(".");
|
|
26
|
-
let current = result;
|
|
27
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
28
|
-
const part = parts[i];
|
|
29
|
-
if (!current[part]) current[part] = {};
|
|
30
|
-
current = current[part];
|
|
31
|
-
}
|
|
32
|
-
const lastPart = parts[parts.length - 1];
|
|
33
|
-
current[lastPart] = value;
|
|
34
|
-
}
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
const isCompiledMessage = (value) => {
|
|
38
|
-
return typeof value === "object" && value !== null && ("loc" in value && typeof value.loc === "object" && value.loc !== null && "source" in value.loc && typeof value.loc.source === "string" || "b" in value && typeof value.b === "object" && value.b !== null && "s" in value.b && typeof value.b.s === "string");
|
|
39
|
-
};
|
|
40
|
-
const createEmptyMessage = (availableLocales) => {
|
|
41
|
-
let data = {};
|
|
42
|
-
for (const locale of availableLocales) {
|
|
43
|
-
data = {
|
|
44
|
-
...data,
|
|
45
|
-
[locale]: {
|
|
46
|
-
value: "",
|
|
47
|
-
input: "",
|
|
48
|
-
isDeployed: true
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
return data;
|
|
53
|
-
};
|
|
54
|
-
const getTranslationValue = (value) => {
|
|
55
|
-
if (isCompiledMessage(value) && value) {
|
|
56
|
-
const data = value;
|
|
57
|
-
return data?.loc?.source ?? data?.b?.s ?? "";
|
|
58
|
-
}
|
|
59
|
-
if (typeof value === "string") {
|
|
60
|
-
return value;
|
|
61
|
-
}
|
|
62
|
-
return null;
|
|
63
|
-
};
|
|
64
|
-
const isNestedObject = (value) => {
|
|
65
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) && !isCompiledMessage(value);
|
|
66
|
-
};
|
|
67
|
-
const extractKeysWithValues = (obj, prefix = "") => {
|
|
68
|
-
const result = {};
|
|
69
|
-
for (const key in obj) {
|
|
70
|
-
let fullKey = prefix ? `${prefix}.${key}` : key;
|
|
71
|
-
if (fullKey.endsWith(".body.static")) {
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
if (fullKey.endsWith(".loc.source")) {
|
|
75
|
-
fullKey = fullKey.substring(0, fullKey.length - ".loc.source".length);
|
|
76
|
-
}
|
|
77
|
-
const value = obj[key];
|
|
78
|
-
if (isNestedObject(value)) {
|
|
79
|
-
Object.assign(result, extractKeysWithValues(value, fullKey));
|
|
80
|
-
} else {
|
|
81
|
-
const translationValue = getTranslationValue(value);
|
|
82
|
-
if (translationValue)
|
|
83
|
-
result[fullKey] = {
|
|
84
|
-
value: translationValue,
|
|
85
|
-
default: translationValue,
|
|
86
|
-
input: translationValue,
|
|
87
|
-
isDeployed: true
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return result;
|
|
92
|
-
};
|
|
93
|
-
export const loadDefaultKeys = async (keysMap, $i18n) => {
|
|
94
|
-
for (const locale of $i18n.availableLocales) {
|
|
95
|
-
await $i18n.loadLocaleMessages(locale);
|
|
96
|
-
const messages = $i18n.getLocaleMessage(locale);
|
|
97
|
-
const keysWithValues = extractKeysWithValues(messages);
|
|
98
|
-
for (const [key, value] of Object.entries(keysWithValues)) {
|
|
99
|
-
if (key.startsWith("translated.")) continue;
|
|
100
|
-
if (!keysMap.has(key)) {
|
|
101
|
-
keysMap.set(key, createEmptyMessage($i18n.availableLocales));
|
|
102
|
-
}
|
|
103
|
-
const translations = keysMap.get(key);
|
|
104
|
-
translations[locale] = value;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
export const loadTranslatedKeys = (keysMap, $i18n) => {
|
|
109
|
-
for (const locale of $i18n.availableLocales) {
|
|
110
|
-
const messages = $i18n.getLocaleMessage(locale);
|
|
111
|
-
const translatedMessages = messages["translated"];
|
|
112
|
-
if (!translatedMessages) continue;
|
|
113
|
-
const keysWithValues = extractKeysWithValues(translatedMessages);
|
|
114
|
-
for (const [key, value] of Object.entries(keysWithValues)) {
|
|
115
|
-
if (!keysMap.has(key)) {
|
|
116
|
-
keysMap.set(key, createEmptyMessage($i18n.availableLocales));
|
|
117
|
-
}
|
|
118
|
-
const translations = keysMap.get(key);
|
|
119
|
-
if (translations[locale]) {
|
|
120
|
-
translations[locale].value = value.value;
|
|
121
|
-
translations[locale].input = value.input;
|
|
122
|
-
} else {
|
|
123
|
-
translations[locale] = value;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
export const loadKeysFromBackend = async (keysMap, $i18n, backendLanguages) => {
|
|
129
|
-
try {
|
|
130
|
-
const config = useRuntimeConfig().public.shopCore;
|
|
131
|
-
const configId = config?.configId;
|
|
132
|
-
if (!configId) return;
|
|
133
|
-
const { data } = await useSdk().plentysystems.getAllTranslations({ configId });
|
|
134
|
-
const flattened = flattenTranslations(data);
|
|
135
|
-
for (const [lang, translations] of Object.entries(flattened)) {
|
|
136
|
-
if (backendLanguages && Object.keys(translations).length > 0) backendLanguages.add(lang);
|
|
137
|
-
for (const [key, value] of Object.entries(translations)) {
|
|
138
|
-
if (!keysMap.has(key)) {
|
|
139
|
-
keysMap.set(key, createEmptyMessage($i18n.availableLocales));
|
|
140
|
-
}
|
|
141
|
-
const localeTranslations = keysMap.get(key);
|
|
142
|
-
if (localeTranslations[lang]) {
|
|
143
|
-
localeTranslations[lang].isDeployed = localeTranslations[lang].value === value;
|
|
144
|
-
localeTranslations[lang].value = value;
|
|
145
|
-
localeTranslations[lang].input = value;
|
|
146
|
-
} else {
|
|
147
|
-
localeTranslations[lang] = {
|
|
148
|
-
value,
|
|
149
|
-
input: value,
|
|
150
|
-
isDeployed: false
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
} catch {
|
|
156
|
-
}
|
|
157
|
-
};
|