1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
import type { Opt } from '@jet/environment';
import { DEFAULT_STOREFRONT_CODE } from '~/constants/storefront';
import type {
NormalizedLocale,
NormalizedStorefront,
NormalizedLanguage,
} from '@jet-app/app-store/api/locale';
import type { Locale } from '@jet-app/app-store/foundation/dependencies/locale/locale';
import { TEXT_DIRECTION } from '@amp/web-app-components/src/constants';
import { getLocAttributes } from '@amp/web-apps-localization';
import { regions } from '~/utils/storefront-data';
import { getJet } from '~/jet/svelte';
export type NormalizedLocaleWithDefault = NormalizedLocale & {
isDefaultLanguage: boolean;
};
type LanguageDetails = {
languages: NormalizedLanguage[];
defaultLanguage: NormalizedLanguage;
};
export function normalizeStorefront(storefront: Opt<string>): {
storefront: NormalizedStorefront;
languages: NormalizedLanguage[];
defaultLanguage: NormalizedLanguage;
} {
const storefronts: Record<NormalizedStorefront, LanguageDetails> = {};
for (const { locales } of regions) {
for (const { id, language, isDefault } of locales) {
if (isDefault) {
storefronts[id as NormalizedStorefront] = {
languages: [],
defaultLanguage: language as NormalizedLanguage,
};
}
if (id in storefronts) {
storefronts[id as NormalizedStorefront].languages.push(
language as NormalizedLanguage,
);
}
}
}
const normalizedStorefront = (storefront || '').toLowerCase();
const chosenStorefront =
normalizedStorefront in storefronts
? (normalizedStorefront as NormalizedStorefront)
: DEFAULT_STOREFRONT_CODE;
return {
storefront: chosenStorefront,
...storefronts[chosenStorefront],
};
}
export function normalizeLanguage(
language: string,
languages: NormalizedLanguage[],
defaultLanguage: NormalizedLanguage,
): { language: NormalizedLanguage; isDefaultLanguage: boolean } {
function annotateReturn(language: NormalizedLanguage): {
language: NormalizedLanguage;
isDefaultLanguage: boolean;
} {
return {
language,
isDefaultLanguage: language === defaultLanguage,
};
}
// Prefer an exact match (ex. en-US matches en-US)
const exactMatch = findMatch(language, languages, (a, b) => a === b);
if (exactMatch) {
return annotateReturn(exactMatch);
}
// Try partial match (ex. fr-CA or fr matches fr-FR)
const partialMatch = findMatch(
language,
languages,
(a, b) => a.split('-')[0] === b.split('-')[0],
);
if (partialMatch) {
return annotateReturn(partialMatch);
}
// The only remaining choice is the storefront default
return annotateReturn(defaultLanguage);
}
function findMatch<T extends string>(
needle: string,
haystack: T[],
matches: (a: string, b: string) => boolean,
): Opt<T> {
return haystack.find((possibility) =>
matches(possibility.toLowerCase(), needle.toLowerCase()),
);
}
/**
* Gets the current Locale instance from the Svelte context.
*
* @return the active {@linkcode NormalizedLocale}
*/
export function getLocale(): NormalizedLocale {
let locale: Locale | undefined;
try {
const { objectGraph } = getJet();
locale = objectGraph.locale;
} catch {
throw new Error('`getLocale` called before `Jet.load`');
}
return {
storefront: locale.activeStorefront,
language: locale.activeLanguage,
};
}
/**
* Returns whether or not the document is in RTL mode, first based on the document's direction,
* with a fallback to the storefronts default writing direction.
*/
export function isRtl() {
const { storefront } = getLocale();
const { dir } = getLocAttributes(storefront);
return (
(typeof document !== 'undefined' &&
document.dir === TEXT_DIRECTION.RTL) ||
dir === TEXT_DIRECTION.RTL
);
}
|