UNPKG

7.3 kBPlain TextView Raw
1import {IncomingMessage, ServerResponse} from "http";
2import * as UrlParser from 'url';
3
4const SUB_DIR = /^(\/(\w\w(_\w\w)?))(?:\/|$)/;
5const SUB_DOMAIN_PIPE_REGEX = /(?:^|_)(\w\w(?:_\w\w)?)_(?:b\-[mt]\-)?[0-9a-f]{24,25}_pipe/i;
6const SUB_DOMAIN_REGEX = /^(?:www\.)?(\w\w(?:_\w\w)?)\./i;
7
8export interface ExtendedRequest extends IncomingMessage {
9 originalUrl?: string;
10 bablic?:{
11 locale: string;
12 proxied?: boolean;
13 }
14}
15
16export interface ExtendedResponse extends ServerResponse {
17 locals?: any;
18}
19
20export type Middleware = (req: IncomingMessage, res: ServerResponse, next: () => void) => void;
21
22export interface KeywordMapper {
23 [locale: string]:{
24 [keyword:string]: string
25 }
26}
27
28function getLocaleFromFolder(folderLocale, locales) {
29 var index = locales.indexOf(folderLocale);
30 if (index > -1)
31 return locales[index];
32 folderLocale = folderLocale.substr(0, 2);
33 for (var i = 0; i < locales.length; i++) {
34 if (locales[i].substr(0, 2) == folderLocale)
35 return locales[i];
36 }
37 return '';
38}
39
40
41export function getLocaleByURL(parsedUrl, locale_detection, localeConfigs, cookieLocale, siteDefaultLocale, detectedLocale, isProxy, explicitLocale, subDirBase, folders, locales) {
42 switch (locale_detection) {
43 case 'querystring':
44 if (parsedUrl.query && typeof(parsedUrl.query) == 'object')
45 return parsedUrl.query.locale;
46 var matches = /locale=([^&]+)/.exec(parsedUrl.query || '');
47 if (matches && matches.length == 2 && matches[1])
48 return matches[1];
49 return cookieLocale || detectedLocale || siteDefaultLocale;
50 case "subdomain":
51 var regex = isProxy ? SUB_DOMAIN_PIPE_REGEX : SUB_DOMAIN_REGEX;
52 var matches = regex.exec(parsedUrl.hostname);
53 if (matches && matches.length > 1 && matches[1])
54 return matches[1];
55 return siteDefaultLocale;
56 case "subdir":
57 var pathname = parsedUrl.pathname;
58 if (subDirBase)
59 pathname = pathname.replace(subDirBase, '');
60 var match = SUB_DIR.exec(pathname);
61 if (match) {
62 if (folders && locales && folders[match[2]])
63 return getLocaleFromFolder(folders[match[2]], locales) || siteDefaultLocale;
64 return match[2];
65 }
66 if (explicitLocale)
67 return explicitLocale;
68 if (cookieLocale)
69 return cookieLocale;
70 return detectedLocale || siteDefaultLocale;
71 case "tld":
72 var matches = /\.(\w\w)$/.exec(parsedUrl.hostname);
73 if (matches && matches.length > 1 && matches[1])
74 return matches[1];
75 return null;
76 case "custom":
77 var parseDomainRule = function (str) {
78 return RegExp((str + '').replace(/([.?+^$[\]\\(){}|-])/g, "\\$1").replace(/\*/g, '.*'), 'i');
79 };
80
81 for (var locale in localeConfigs) {
82 var urlPattern = localeConfigs[locale];
83 if (urlPattern && parseDomainRule(urlPattern).test(parsedUrl.href))
84 return locale;
85 }
86 return explicitLocale || siteDefaultLocale;
87 case "hash":
88 var matches = /^#!locale=(\w\w(?:_\w\w)?)$/.exec(parsedUrl.hash || '');
89 if (matches && matches.length > 1 && matches[1])
90 return matches[1];
91 return cookieLocale || detectedLocale || siteDefaultLocale;
92 default:
93 return cookieLocale;
94 }
95}
96export interface SiteMeta{
97 localeDetection: string;
98 original: string;
99 customUrls: {
100 [locale:string]:string
101 };
102 default: string;
103 autoDetect: boolean;
104 localeKeys: string[];
105 timestamp: number;
106 includeQueryString: boolean;
107 includeHash: boolean;
108 singlePageApp: boolean;
109 qsParams: string[],
110 domain: string;
111 mountSubs: string[];
112}
113
114export interface BablicLinkOptions {
115 subDir?: boolean;
116 subDirBase?: string;
117 subDirOptional?: boolean;
118 returnFull?: boolean;
119 folders?:{[locale:string]:string}
120}
121
122export function getLink(locale: string, parsed: UrlParser.Url, meta: SiteMeta, options?: BablicLinkOptions) {
123 options = options || {};
124 let protocol = parsed.protocol || '';
125 let hostname = parsed.hostname;
126 let pathname = parsed.pathname || '/';
127 let search = parsed.search || '';
128 let hash = parsed.hash || '';
129
130 let returnFull = options.returnFull;
131 let localeDetection = meta.localeDetection;
132 let original = meta.original;
133 if(options.subDir)
134 localeDetection = 'subdir';
135 if(localeDetection == 'custom' && !(meta.customUrls && meta.customUrls[locale]))
136 localeDetection = 'querystring';
137
138 switch(localeDetection){
139 case 'custom':
140 let customUrl = meta.customUrls[locale];
141 let confDomain = customUrl.indexOf('/') > -1 ? customUrl.substr(0,customUrl.indexOf('/')) : customUrl;
142 return protocol + '//' + confDomain + pathname + search + hash;
143
144 case 'querystring':
145 if (/[?&]locale=([^&]+)/.test(search))
146 search = search.replace(/([?&]locale=)([^&]+)/, '$1' + locale);
147 else {
148 if (search)
149 search = search + '&locale=' + locale;
150 else
151 search = '?locale=' + locale;
152 }
153 if(returnFull)
154 return protocol + '//' + hostname + pathname + search + hash;
155
156 return pathname + search + hash;
157
158 case 'subdir':
159 if(options.subDirBase)
160 pathname = pathname.replace(options.subDirBase,'');
161 let match = SUB_DIR.exec(pathname);
162 if (match) {
163 pathname = pathname.substr(match[1].length);
164 if (pathname.length == 0)
165 pathname = '/';
166 }
167 let prefix = '';
168 if(options.folders)
169 prefix = '/' + getFolder(locale,options.folders);
170 else if(locale != original)
171 prefix = '/' + locale;
172 if(options.subDirBase && (!options.subDirOptional || locale != original))
173 prefix = options.subDirBase + prefix;
174 if(returnFull)
175 return protocol + '//' + hostname + prefix + pathname + search + hash;
176 return prefix + pathname + search + hash;
177 case 'hash':
178 if(returnFull)
179 return protocol + '//' + hostname + pathname + search + '#locale=' + locale;
180 return '#locale_' + locale;
181 }
182 return `javascript:bablic.setLanguage("${locale}");`;
183}
184
185
186function getFolder(locale: string,folders:{[locale:string]:string}) :string{
187 for(let folder in folders){
188 if(folders[folder] == locale)
189 return folder;
190 }
191 locale = locale.substr(0,2);
192 for(let folder in folders){
193 if(folders[folder].substr(0,2) == locale)
194 return folder;
195 }
196 return locale;
197}