@jitsu/js 1.9.18-canary.1269.20250403142744 → 1.9.18-canary.1288.20250415192732
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/.turbo/turbo-build.log +67 -0
- package/.turbo/turbo-clean.log +5 -0
- package/.turbo/turbo-test.log +2884 -0
- package/__tests__/node/method-queue.test.ts +66 -0
- package/__tests__/node/nodejs.test.ts +306 -0
- package/__tests__/playwright/cases/anonymous-id-bug.html +26 -0
- package/__tests__/playwright/cases/basic.html +32 -0
- package/__tests__/playwright/cases/callbacks.html +21 -0
- package/__tests__/playwright/cases/cookie-names.html +22 -0
- package/__tests__/playwright/cases/disable-user-ids.html +23 -0
- package/__tests__/playwright/cases/dont-send.html +22 -0
- package/__tests__/playwright/cases/ip-policy.html +22 -0
- package/__tests__/playwright/cases/reset.html +32 -0
- package/__tests__/playwright/cases/segment-reference.html +64 -0
- package/__tests__/playwright/cases/url-bug.html +20 -0
- package/__tests__/playwright/integration.test.ts +640 -0
- package/__tests__/simple-syrup.ts +136 -0
- package/dist/jitsu.cjs.js +4 -8
- package/dist/jitsu.es.js +4 -8
- package/dist/web/p.js.txt +4 -8
- package/jest.config.js +13 -0
- package/package/README.md +9 -0
- package/package/dist/analytics-plugin.d.ts +28 -0
- package/package/dist/browser.d.ts +10 -0
- package/package/dist/index.d.ts +28 -0
- package/package/dist/jitsu.cjs.js +2100 -0
- package/package/dist/jitsu.d.ts +78 -0
- package/package/dist/jitsu.es.js +2090 -0
- package/package/dist/method-queue.d.ts +19 -0
- package/package/dist/script-loader.d.ts +8 -0
- package/package/dist/tlds.d.ts +3 -0
- package/package/dist/version.d.ts +3 -0
- package/package/dist/web/p.js.txt +2219 -0
- package/package/package.json +56 -0
- package/package.json +3 -7
- package/playwrite.config.ts +91 -0
- package/rollup.config.js +32 -0
- package/src/analytics-plugin.ts +989 -0
- package/src/browser.ts +163 -0
- package/src/destination-plugins/ga4.ts +138 -0
- package/src/destination-plugins/gtm.ts +142 -0
- package/src/destination-plugins/index.ts +61 -0
- package/src/destination-plugins/logrocket.ts +85 -0
- package/src/destination-plugins/tag.ts +85 -0
- package/src/index.ts +255 -0
- package/src/method-queue.ts +70 -0
- package/src/script-loader.ts +76 -0
- package/src/tlds.ts +27 -0
- package/src/version.ts +6 -0
- package/tsconfig.json +23 -0
- package/tsconfig.test.json +15 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import Analytics from "analytics";
|
|
2
|
+
import { jitsuAnalyticsPlugin, emptyRuntime, isInBrowser, windowRuntime, uuid } from "./analytics-plugin";
|
|
3
|
+
import {
|
|
4
|
+
Callback,
|
|
5
|
+
DispatchedEvent,
|
|
6
|
+
ID,
|
|
7
|
+
JSONObject,
|
|
8
|
+
Options,
|
|
9
|
+
AnalyticsInterface,
|
|
10
|
+
JitsuOptions,
|
|
11
|
+
PersistentStorage,
|
|
12
|
+
RuntimeFacade,
|
|
13
|
+
DynamicJitsuOptions,
|
|
14
|
+
} from "@jitsu/protocols/analytics";
|
|
15
|
+
|
|
16
|
+
export default function parse(input) {
|
|
17
|
+
let value = input;
|
|
18
|
+
if (input?.indexOf("%7B%22") === 0) {
|
|
19
|
+
value = decodeURIComponent(input);
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
value = JSON.parse(value);
|
|
23
|
+
if (value === "true") return true;
|
|
24
|
+
if (value === "false") return false;
|
|
25
|
+
if (typeof value === "object") return value;
|
|
26
|
+
if (parseFloat(value) === value) {
|
|
27
|
+
value = parseFloat(value);
|
|
28
|
+
}
|
|
29
|
+
} catch (e) {}
|
|
30
|
+
if (value === null || value === "") {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const emptyAnalytics: AnalyticsInterface = {
|
|
37
|
+
setAnonymousId: () => {},
|
|
38
|
+
track: () => Promise.resolve(),
|
|
39
|
+
page: () => Promise.resolve(),
|
|
40
|
+
user: () => ({}),
|
|
41
|
+
identify: () => Promise.resolve({}),
|
|
42
|
+
group: () => Promise.resolve({}),
|
|
43
|
+
reset: () => Promise.resolve({}),
|
|
44
|
+
configure: () => {},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function createUnderlyingAnalyticsInstance(
|
|
48
|
+
opts: JitsuOptions,
|
|
49
|
+
rt: RuntimeFacade,
|
|
50
|
+
plugins: any[] = []
|
|
51
|
+
): AnalyticsInterface {
|
|
52
|
+
const storageCache: any = {};
|
|
53
|
+
|
|
54
|
+
// AnalyticsInstance's storage is async somewhere inside. So if we make 'page' call right after 'identify' call
|
|
55
|
+
// 'page' call will load traits from storage before 'identify' call had a change to save them.
|
|
56
|
+
// to avoid that we use in-memory cache for storage
|
|
57
|
+
const cachingStorageWrapper = (persistentStorage: PersistentStorage) => ({
|
|
58
|
+
setItem(key: string, val: any) {
|
|
59
|
+
if (opts.privacy?.dontSend || opts.privacy?.disableUserIds) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (opts.debug) {
|
|
63
|
+
console.log(`[JITSU DEBUG] Caching storage setItem: ${key}=${val}`);
|
|
64
|
+
}
|
|
65
|
+
storageCache[key] = val;
|
|
66
|
+
persistentStorage.setItem(key, val);
|
|
67
|
+
},
|
|
68
|
+
getItem(key: string) {
|
|
69
|
+
if (opts.privacy?.dontSend || opts.privacy?.disableUserIds) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const value = storageCache[key] || persistentStorage.getItem(key);
|
|
73
|
+
if (opts.debug) {
|
|
74
|
+
console.log(
|
|
75
|
+
`[JITSU DEBUG] Caching storage getItem: ${key}=${value}. Evicted from cache: ${!storageCache[key]}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
},
|
|
80
|
+
reset() {
|
|
81
|
+
for (const key of [...Object.keys(storageCache)]) {
|
|
82
|
+
delete storageCache[key];
|
|
83
|
+
}
|
|
84
|
+
persistentStorage.reset();
|
|
85
|
+
},
|
|
86
|
+
removeItem(key: string) {
|
|
87
|
+
if (opts.debug) {
|
|
88
|
+
console.log(`[JITSU DEBUG] Caching storage removeItem: ${key}`);
|
|
89
|
+
}
|
|
90
|
+
delete storageCache[key];
|
|
91
|
+
persistentStorage.removeItem(key);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
const storage = cachingStorageWrapper(rt.store());
|
|
95
|
+
|
|
96
|
+
const analytics = Analytics({
|
|
97
|
+
debug: !!opts.debug,
|
|
98
|
+
storage,
|
|
99
|
+
plugins: [jitsuAnalyticsPlugin(opts, storage), ...plugins],
|
|
100
|
+
} as any);
|
|
101
|
+
|
|
102
|
+
const a = {
|
|
103
|
+
...analytics,
|
|
104
|
+
page: (...args) => {
|
|
105
|
+
if (args.length === 2 && typeof args[0] === "string" && typeof args[1] === "object") {
|
|
106
|
+
return analytics.page({
|
|
107
|
+
name: args[0],
|
|
108
|
+
...args[1],
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
return (analytics.page as any)(...args);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
identify: (...args) => {
|
|
115
|
+
if (args[0] && typeof args[0] !== "object" && typeof args[0] !== "string") {
|
|
116
|
+
//fix the quirk of analytics.js: if you pass number as first argument, it will be converted to string
|
|
117
|
+
args[0] = args[0] + "";
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
//analytics.js sets userId and traits asynchronously, so if
|
|
121
|
+
//we want them to be available immediately after identify call in subsequent page() calls,
|
|
122
|
+
//we need to put them into storage manually
|
|
123
|
+
const storage = (analytics as any).storage;
|
|
124
|
+
const storageWrapper = cachingStorageWrapper(storage);
|
|
125
|
+
if (typeof args[0] === "string") {
|
|
126
|
+
//first argument is user id
|
|
127
|
+
storageWrapper.setItem("__user_id", args[0]);
|
|
128
|
+
} else if (typeof args[0] === "object") {
|
|
129
|
+
//first argument is traits
|
|
130
|
+
storageWrapper.setItem("__user_traits", args[0]);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (args.length === 2 && typeof args[1] === "object") {
|
|
134
|
+
//first argument is user id, second is traits
|
|
135
|
+
storageWrapper.setItem("__user_traits", args[1]);
|
|
136
|
+
}
|
|
137
|
+
return (analytics.identify as any)(...args);
|
|
138
|
+
},
|
|
139
|
+
setAnonymousId: (id: string) => {
|
|
140
|
+
if (opts.debug) {
|
|
141
|
+
console.log("[JITSU DEBUG] Setting anonymous id to " + id);
|
|
142
|
+
}
|
|
143
|
+
//Workaround for analytics.js bug. Underlying setAnonymousId doesn't set the id immediately,
|
|
144
|
+
//so we got to it manually here. See https://github.com/jitsucom/jitsu/issues/1060
|
|
145
|
+
storage.setItem("__anon_id", id);
|
|
146
|
+
const userState = analytics.user();
|
|
147
|
+
if (userState) {
|
|
148
|
+
userState.anonymousId = id;
|
|
149
|
+
}
|
|
150
|
+
(analytics as any).setAnonymousId(id);
|
|
151
|
+
},
|
|
152
|
+
async reset() {
|
|
153
|
+
if (opts.debug) {
|
|
154
|
+
console.log("[JITSU DEBUG] Called reset(). Storage state", JSON.stringify(analytics.user()));
|
|
155
|
+
}
|
|
156
|
+
storage.reset();
|
|
157
|
+
await analytics.reset();
|
|
158
|
+
this.setAnonymousId(uuid());
|
|
159
|
+
if (opts.debug) {
|
|
160
|
+
console.log("[JITSU DEBUG] User state after reset", JSON.stringify(analytics.user()));
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
async configure(options: DynamicJitsuOptions) {
|
|
164
|
+
if (opts.debug) {
|
|
165
|
+
console.log("[JITSU DEBUG] Update Jitsu config with", JSON.stringify(options));
|
|
166
|
+
}
|
|
167
|
+
if (options.privacy?.disableUserIds || options.privacy?.dontSend) {
|
|
168
|
+
storage.reset();
|
|
169
|
+
}
|
|
170
|
+
for (const plugin of Object.values(analytics.plugins)) {
|
|
171
|
+
if (typeof plugin["configure"] === "function") {
|
|
172
|
+
plugin["configure"](options);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
async group(
|
|
177
|
+
groupId?: ID,
|
|
178
|
+
traits?: JSONObject | null,
|
|
179
|
+
options?: Options,
|
|
180
|
+
callback?: Callback
|
|
181
|
+
): Promise<DispatchedEvent> {
|
|
182
|
+
const results: any[] = [];
|
|
183
|
+
for (const plugin of Object.values(analytics.plugins)) {
|
|
184
|
+
if (plugin["group"]) {
|
|
185
|
+
results.push(await plugin["group"](groupId, traits, options, callback));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
//It's incorrect at many levels. First, it's not a dispatched event. Second, we take a first result
|
|
189
|
+
//However, since returned values are used for debugging purposes only, it's ok
|
|
190
|
+
return results[0];
|
|
191
|
+
},
|
|
192
|
+
} as AnalyticsInterface;
|
|
193
|
+
if (opts.privacy?.disableUserIds || opts.privacy?.dontSend) {
|
|
194
|
+
storage.reset();
|
|
195
|
+
}
|
|
196
|
+
return a;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Fix common mistakes in jitsu configuration
|
|
201
|
+
* @param opts
|
|
202
|
+
*/
|
|
203
|
+
function fixOptions(opts: JitsuOptions): JitsuOptions {
|
|
204
|
+
return {
|
|
205
|
+
...opts,
|
|
206
|
+
host:
|
|
207
|
+
(opts.host ?? "").indexOf("https://") !== 0 && (opts.host ?? "").indexOf("http://") !== 0
|
|
208
|
+
? `https://${opts.host}`
|
|
209
|
+
: opts.host,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function jitsuAnalytics(_opts: JitsuOptions): AnalyticsInterface {
|
|
214
|
+
const opts = fixOptions(_opts);
|
|
215
|
+
const inBrowser = isInBrowser();
|
|
216
|
+
const rt = opts.runtime || (inBrowser ? windowRuntime(opts) : emptyRuntime(opts));
|
|
217
|
+
return createUnderlyingAnalyticsInstance(opts, rt);
|
|
218
|
+
|
|
219
|
+
// if (inBrowser) {
|
|
220
|
+
// const fetch = opts.fetch || globalThis.fetch;
|
|
221
|
+
// if (!fetch) {
|
|
222
|
+
// throw new Error(
|
|
223
|
+
// "Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope"
|
|
224
|
+
// );
|
|
225
|
+
// }
|
|
226
|
+
// const url = `${opts.host}/api/s/cfg`;
|
|
227
|
+
// const authHeader = {};
|
|
228
|
+
// const debugHeader = opts.debug ? { "X-Enable-Debug": "true" } : {};
|
|
229
|
+
// fetch(url)
|
|
230
|
+
// .then(res => res.json())
|
|
231
|
+
// .then(res => {
|
|
232
|
+
// result.loaded(createUnderlyingAnalyticsInstance(opts, rt, []));
|
|
233
|
+
// })
|
|
234
|
+
// .catch(e => {
|
|
235
|
+
// console.warn(`[JITSU] error getting device-destinations from ${url}`, e);
|
|
236
|
+
// result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
|
|
237
|
+
// });
|
|
238
|
+
// } else {
|
|
239
|
+
// result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
|
|
240
|
+
// }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export {
|
|
244
|
+
Callback,
|
|
245
|
+
DispatchedEvent,
|
|
246
|
+
ID,
|
|
247
|
+
JSONObject,
|
|
248
|
+
Options,
|
|
249
|
+
AnalyticsInterface,
|
|
250
|
+
JitsuOptions,
|
|
251
|
+
PersistentStorage,
|
|
252
|
+
RuntimeFacade,
|
|
253
|
+
DynamicJitsuOptions,
|
|
254
|
+
};
|
|
255
|
+
export * from "./analytics-plugin";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export type InterfaceWrapper<T> = {
|
|
2
|
+
get(): WithAsyncMethods<T>;
|
|
3
|
+
loaded(instance: T);
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
type MethodCall<M> = {
|
|
7
|
+
method: keyof M;
|
|
8
|
+
args: any[];
|
|
9
|
+
resolve?: (value: any) => void;
|
|
10
|
+
reject?: (reason: any) => void;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type WithAsyncMethods<T> = {
|
|
14
|
+
[K in keyof T]: T[K] extends (...args: infer A) => infer R
|
|
15
|
+
? (...args: A) => R extends Promise<any> ? R : Promise<R>
|
|
16
|
+
: T[K];
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This function creates a wrapper around an interface that allows to call methods on it, but all methods will go to queue. Once actual instance
|
|
21
|
+
* implementation becomes available, all queued methods will be called on it.
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
|
+
* @param methods of methods that should be wrapped. Per each method of you should specify if it should be wrapped. You'll need to mark all
|
|
25
|
+
* methods for type safety. If method is not wrapped, it will throw an error when called.
|
|
26
|
+
*/
|
|
27
|
+
export function delayMethodExec<T>(methods: Record<keyof T, boolean>): InterfaceWrapper<T> {
|
|
28
|
+
const queue: Array<MethodCall<T>> = [];
|
|
29
|
+
|
|
30
|
+
let instance: Partial<T> = {};
|
|
31
|
+
for (const [_method, enabled] of Object.entries(methods)) {
|
|
32
|
+
const method = _method as keyof T;
|
|
33
|
+
if (enabled) {
|
|
34
|
+
instance[method] = ((...args) => {
|
|
35
|
+
queue.push({ method, args });
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
queue[queue.length - 1].resolve = resolve;
|
|
38
|
+
queue[queue.length - 1].reject = reject;
|
|
39
|
+
});
|
|
40
|
+
}) as any;
|
|
41
|
+
} else {
|
|
42
|
+
instance[method] = (() => {
|
|
43
|
+
throw new Error(`Method ${_method} is not implemented`);
|
|
44
|
+
}) as any;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
get() {
|
|
50
|
+
return instance as WithAsyncMethods<T>;
|
|
51
|
+
},
|
|
52
|
+
loaded(newInstance: T) {
|
|
53
|
+
for (const { method, args, resolve, reject } of queue) {
|
|
54
|
+
try {
|
|
55
|
+
const result = (newInstance[method] as any)(...args);
|
|
56
|
+
if (typeof result.then === "function") {
|
|
57
|
+
result.then(resolve).catch(reject);
|
|
58
|
+
} else {
|
|
59
|
+
resolve(result);
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {
|
|
62
|
+
reject(e);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const method of Object.keys(methods)) {
|
|
66
|
+
instance[method] = newInstance[method];
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
function findScript(src: string): HTMLScriptElement | undefined {
|
|
2
|
+
const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
|
|
3
|
+
return scripts.find(s => s.src === src);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type ScriptOptions = {
|
|
7
|
+
attributes?: Record<string, string>;
|
|
8
|
+
www?: boolean;
|
|
9
|
+
js?: boolean;
|
|
10
|
+
min?: boolean;
|
|
11
|
+
query?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function buildScriptSrc(src: string, options?: ScriptOptions): string {
|
|
15
|
+
let result = src;
|
|
16
|
+
if (!result.startsWith("http")) {
|
|
17
|
+
result = `https://${options?.www ? "www." : ""}${result}`;
|
|
18
|
+
}
|
|
19
|
+
if (options?.min) {
|
|
20
|
+
result = result + ".min.js";
|
|
21
|
+
} else if (options?.js) {
|
|
22
|
+
result = result + ".js";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (options?.query) {
|
|
26
|
+
result += "?" + options.query;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function loadScript(src: string, options?: ScriptOptions): Promise<HTMLScriptElement> {
|
|
32
|
+
const found = findScript(src);
|
|
33
|
+
|
|
34
|
+
if (found !== undefined) {
|
|
35
|
+
const status = found?.getAttribute("status");
|
|
36
|
+
|
|
37
|
+
if (status === "loaded") {
|
|
38
|
+
return Promise.resolve(found);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (status === "loading") {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
found.addEventListener("load", () => resolve(found));
|
|
44
|
+
found.addEventListener("error", err => reject(err));
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const script = window.document.createElement("script");
|
|
51
|
+
|
|
52
|
+
script.type = "text/javascript";
|
|
53
|
+
script.src = buildScriptSrc(src, options);
|
|
54
|
+
script.async = true;
|
|
55
|
+
|
|
56
|
+
script.setAttribute("status", "loading");
|
|
57
|
+
for (const [k, v] of Object.entries(options?.attributes ?? {})) {
|
|
58
|
+
script.setAttribute(k, v);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
script.onload = (): void => {
|
|
62
|
+
script.onerror = script.onload = null;
|
|
63
|
+
script.setAttribute("status", "loaded");
|
|
64
|
+
resolve(script);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
script.onerror = (): void => {
|
|
68
|
+
script.onerror = script.onload = null;
|
|
69
|
+
script.setAttribute("status", "error");
|
|
70
|
+
reject(new Error(`Failed to load ${src}`));
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const tag = window.document.getElementsByTagName("script")[0];
|
|
74
|
+
tag.parentElement?.insertBefore(script, tag);
|
|
75
|
+
});
|
|
76
|
+
}
|
package/src/tlds.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const publicSuffixes =
|
|
2
|
+
"myshopify.com,ac,com.ac,edu.ac,gov.ac,net.ac,mil.ac,org.ac,ad,nom.ad,ae,co.ae,net.ae,org.ae,sch.ae,ac.ae,gov.ae,mil.ae,aero,af,gov.af,com.af,org.af,net.af,edu.af,ag,com.ag,org.ag,net.ag,co.ag,nom.ag,ai,off.ai,com.ai,net.ai,org.ai,al,com.al,edu.al,gov.al,mil.al,net.al,org.al,am,co.am,com.am,commune.am,net.am,org.am,ao,ed.ao,gv.ao,og.ao,co.ao,pb.ao,it.ao,aq,ar,bet.ar,com.ar,coop.ar,edu.ar,gob.ar,gov.ar,int.ar,mil.ar,musica.ar,mutual.ar,net.ar,org.ar,senasa.ar,tur.ar,arpa,e164.arpa,in-addr.arpa,ip6.arpa,iris.arpa,uri.arpa,urn.arpa,as,gov.as,asia,at,ac.at,co.at,gv.at,or.at,sth.ac.at,au,com.au,net.au,org.au,edu.au,gov.au,asn.au,id.au,act.au,nsw.au,nt.au,qld.au,sa.au,tas.au,vic.au,wa.au,aw,com.aw,ax,az,com.az,net.az,int.az,gov.az,org.az,edu.az,info.az,pp.az,mil.az,name.az,pro.az,biz.az,ba,com.ba,edu.ba,gov.ba,mil.ba,net.ba,org.ba,bb,biz.bb,co.bb,com.bb,edu.bb,gov.bb,info.bb,net.bb,org.bb,store.bb,tv.bb,bd,be,ac.be,bf,gov.bf,bg,a.bg,b.bg,c.bg,d.bg,e.bg,f.bg,g.bg,h.bg,i.bg,j.bg,k.bg,l.bg,m.bg,n.bg,o.bg,p.bg,q.bg,r.bg,s.bg,t.bg,u.bg,v.bg,w.bg,x.bg,y.bg,z.bg,0.bg,1.bg,2.bg,3.bg,4.bg,5.bg,6.bg,7.bg,8.bg,9.bg,bh,com.bh,edu.bh,net.bh,org.bh,gov.bh,bi,co.bi,com.bi,edu.bi,or.bi,org.bi,biz,bj,africa.bj,agro.bj,architectes.bj,assur.bj,avocats.bj,co.bj,com.bj,eco.bj,econo.bj,edu.bj,info.bj,loisirs.bj,money.bj,net.bj,org.bj,ote.bj,resto.bj,restaurant.bj,tourism.bj,univ.bj,bm,com.bm,edu.bm,gov.bm,net.bm,org.bm,bn,com.bn,edu.bn,gov.bn,net.bn,org.bn,bo,com.bo,edu.bo,gob.bo,int.bo,org.bo,net.bo,mil.bo,tv.bo,web.bo,br,9guacu.br,abc.br,adm.br,adv.br,agr.br,aju.br,am.br,anani.br,aparecida.br,app.br,arq.br,art.br,ato.br,b.br,barueri.br,belem.br,bhz.br,bib.br,bio.br,blog.br,bmd.br,boavista.br,bsb.br,campinagrande.br,campinas.br,caxias.br,cim.br,cng.br,cnt.br,com.br,contagem.br,coop.br,coz.br,cri.br,cuiaba.br,curitiba.br,def.br,des.br,det.br,dev.br,ecn.br,eco.br,edu.br,emp.br,enf.br,eng.br,esp.br,etc.br,eti.br,far.br,feira.br,flog.br,floripa.br,fm.br,fnd.br,fortal.br,fot.br,foz.br,fst.br,g12.br,geo.br,ggf.br,goiania.br,gov.br,gru.br,imb.br,ind.br,inf.br,jab.br,jampa.br,jdf.br,joinville.br,jor.br,jus.br,leg.br,lel.br,log.br,londrina.br,macapa.br,maceio.br,manaus.br,maringa.br,mat.br,med.br,mil.br,morena.br,mp.br,mus.br,natal.br,net.br,niteroi.br,nom.br,not.br,ntr.br,odo.br,ong.br,org.br,osasco.br,palmas.br,poa.br,ppg.br,pro.br,psc.br,psi.br,pvh.br,qsl.br,radio.br,rec.br,recife.br,rep.br,ribeirao.br,rio.br,riobranco.br,riopreto.br,salvador.br,sampa.br,santamaria.br,santoandre.br,saobernardo.br,saogonca.br,seg.br,sjc.br,slg.br,slz.br,sorocaba.br,srv.br,taxi.br,tc.br,tec.br,teo.br,the.br,tmp.br,trd.br,tur.br,tv.br,udi.br,vet.br,vix.br,vlog.br,wiki.br,zlg.br,bs,com.bs,net.bs,org.bs,edu.bs,gov.bs,bt,com.bt,edu.bt,gov.bt,net.bt,org.bt,bv,bw,co.bw,org.bw,by,gov.by,mil.by,com.by,of.by,bz,com.bz,net.bz,org.bz,edu.bz,gov.bz,ca,ab.ca,bc.ca,mb.ca,nb.ca,nf.ca,nl.ca,ns.ca,nt.ca,nu.ca,on.ca,pe.ca,qc.ca,sk.ca,yk.ca,gc.ca,cat,cc,cd,gov.cd,cf,cg,ch,ci,org.ci,or.ci,com.ci,co.ci,edu.ci,ed.ci,ac.ci,net.ci,go.ci,asso.ci,aéroport.ci,int.ci,presse.ci,md.ci,gouv.ci,ck,cl,co.cl,gob.cl,gov.cl,mil.cl,cm,co.cm,com.cm,gov.cm,net.cm,cn,ac.cn,com.cn,edu.cn,gov.cn,net.cn,org.cn,mil.cn,co,arts.co,com.co,edu.co,firm.co,gov.co,info.co,int.co,mil.co,net.co,nom.co,org.co,rec.co,web.co,com,coop,cr,ac.cr,co.cr,ed.cr,fi.cr,go.cr,or.cr,sa.cr,cu,com.cu,edu.cu,org.cu,net.cu,gov.cu,inf.cu,cv,com.cv,edu.cv,int.cv,nome.cv,org.cv,cw,com.cw,edu.cw,net.cw,org.cw,cx,gov.cx,cy,ac.cy,biz.cy,com.cy,ekloges.cy,gov.cy,ltd.cy,mil.cy,net.cy,org.cy,press.cy,pro.cy,tm.cy,cz,de,dj,dk,dm,com.dm,net.dm,org.dm,edu.dm,gov.dm,do,art.do,com.do,edu.do,gob.do,gov.do,mil.do,net.do,org.do,sld.do,web.do,dz,art.dz,asso.dz,com.dz,edu.dz,gov.dz,org.dz,net.dz,pol.dz,soc.dz,tm.dz,ec,com.ec,info.ec,net.ec,fin.ec,k12.ec,med.ec,pro.ec,org.ec,edu.ec,gov.ec,gob.ec,mil.ec,edu,ee,edu.ee,gov.ee,riik.ee,lib.ee,med.ee,com.ee,pri.ee,aip.ee,org.ee,fie.ee,eg,com.eg,edu.eg,eun.eg,gov.eg,mil.eg,name.eg,net.eg,org.eg,sci.eg,er,es,com.es,nom.es,org.es,gob.es,edu.es,et,com.et,gov.et,org.et,edu.et,biz.et,name.et,info.et,net.et,eu,fi,aland.fi,fj,ac.fj,biz.fj,com.fj,gov.fj,info.fj,mil.fj,name.fj,net.fj,org.fj,pro.fj,fk,com.fm,edu.fm,net.fm,org.fm,fm,fo,fr,asso.fr,com.fr,gouv.fr,nom.fr,prd.fr,tm.fr,aeroport.fr,avocat.fr,avoues.fr,cci.fr,chambagri.fr,chirurgiens-dentistes.fr,experts-comptables.fr,geometre-expert.fr,greta.fr,huissier-justice.fr,medecin.fr,notaires.fr,pharmacien.fr,port.fr,veterinaire.fr,ga,gb,edu.gd,gov.gd,gd,ge,com.ge,edu.ge,gov.ge,org.ge,mil.ge,net.ge,pvt.ge,gf,gg,co.gg,net.gg,org.gg,gh,com.gh,edu.gh,gov.gh,org.gh,mil.gh,gi,com.gi,ltd.gi,gov.gi,mod.gi,edu.gi,org.gi,gl,co.gl,com.gl,edu.gl,net.gl,org.gl,gm,gn,ac.gn,com.gn,edu.gn,gov.gn,org.gn,net.gn,gov,gp,com.gp,net.gp,mobi.gp,edu.gp,org.gp,asso.gp,gq,gr,com.gr,edu.gr,net.gr,org.gr,gov.gr,gs,gt,com.gt,edu.gt,gob.gt,ind.gt,mil.gt,net.gt,org.gt,gu,com.gu,edu.gu,gov.gu,guam.gu,info.gu,net.gu,org.gu,web.gu,gw,gy,co.gy,com.gy,edu.gy,gov.gy,net.gy,org.gy,hk,com.hk,edu.hk,gov.hk,idv.hk,net.hk,org.hk,hm,hn,com.hn,edu.hn,org.hn,net.hn,mil.hn,gob.hn,hr,iz.hr,from.hr,name.hr,com.hr,ht,com.ht,shop.ht,firm.ht,info.ht,adult.ht,net.ht,pro.ht,org.ht,med.ht,art.ht,coop.ht,pol.ht,asso.ht,edu.ht,rel.ht,gouv.ht,perso.ht,hu,co.hu,info.hu,org.hu,priv.hu,sport.hu,tm.hu,2000.hu,agrar.hu,bolt.hu,casino.hu,city.hu,erotica.hu,erotika.hu,film.hu,forum.hu,games.hu,hotel.hu,ingatlan.hu,jogasz.hu,konyvelo.hu,lakas.hu,media.hu,news.hu,reklam.hu,sex.hu,shop.hu,suli.hu,szex.hu,tozsde.hu,utazas.hu,video.hu,id,ac.id,biz.id,co.id,desa.id,go.id,mil.id,my.id,net.id,or.id,ponpes.id,sch.id,web.id,ie,gov.ie,il,ac.il,co.il,gov.il,idf.il,k12.il,muni.il,net.il,org.il,im,ac.im,co.im,com.im,ltd.co.im,net.im,org.im,plc.co.im,tt.im,tv.im,in,5g.in,6g.in,ac.in,ai.in,am.in,bihar.in,biz.in,business.in,ca.in,cn.in,co.in,com.in,coop.in,cs.in,delhi.in,dr.in,edu.in,er.in,firm.in,gen.in,gov.in,gujarat.in,ind.in,info.in,int.in,internet.in,io.in,me.in,mil.in,net.in,nic.in,org.in,pg.in,post.in,pro.in,res.in,travel.in,tv.in,uk.in,up.in,us.in,info,int,eu.int,io,com.io,iq,gov.iq,edu.iq,mil.iq,com.iq,org.iq,net.iq,ir,ac.ir,co.ir,gov.ir,id.ir,net.ir,org.ir,sch.ir,is,net.is,com.is,edu.is,gov.is,org.is,int.is,it,gov.it,edu.it,je,co.je,net.je,org.je,jm,jo,com.jo,org.jo,net.jo,edu.jo,sch.jo,gov.jo,mil.jo,name.jo,jobs,jp,ac.jp,ad.jp,co.jp,ed.jp,go.jp,gr.jp,lg.jp,ne.jp,or.jp,ke,ac.ke,co.ke,go.ke,info.ke,me.ke,mobi.ke,ne.ke,or.ke,sc.ke,kg,org.kg,net.kg,com.kg,edu.kg,gov.kg,mil.kg,kh,ki,edu.ki,biz.ki,net.ki,org.ki,gov.ki,info.ki,com.ki,km,org.km,nom.km,gov.km,prd.km,tm.km,edu.km,mil.km,ass.km,com.km,kn,net.kn,org.kn,edu.kn,gov.kn,kp,com.kp,edu.kp,gov.kp,org.kp,rep.kp,tra.kp,kr,ac.kr,co.kr,es.kr,go.kr,hs.kr,kg.kr,mil.kr,ms.kr,ne.kr,or.kr,pe.kr,re.kr,sc.kr,kw,com.kw,edu.kw,emb.kw,gov.kw,ind.kw,net.kw,org.kw,ky,com.ky,edu.ky,net.ky,org.ky,kz,org.kz,edu.kz,net.kz,gov.kz,mil.kz,com.kz,la,int.la,net.la,info.la,edu.la,gov.la,per.la,com.la,org.la,lb,com.lb,edu.lb,gov.lb,net.lb,org.lb,lc,com.lc,net.lc,co.lc,org.lc,edu.lc,gov.lc,li,lk,gov.lk,sch.lk,net.lk,int.lk,com.lk,org.lk,edu.lk,ngo.lk,soc.lk,web.lk,ltd.lk,assn.lk,grp.lk,hotel.lk,ac.lk,lr,com.lr,edu.lr,gov.lr,org.lr,net.lr,ls,ac.ls,biz.ls,co.ls,edu.ls,gov.ls,info.ls,net.ls,org.ls,sc.ls,lt,gov.lt,lu,lv,com.lv,edu.lv,gov.lv,org.lv,mil.lv,id.lv,net.lv,asn.lv,conf.lv,ly,com.ly,net.ly,gov.ly,plc.ly,edu.ly,sch.ly,med.ly,org.ly,id.ly,ma,co.ma,net.ma,gov.ma,org.ma,ac.ma,press.ma,mc,tm.mc,asso.mc,md,me,co.me,net.me,org.me,edu.me,ac.me,gov.me,its.me,priv.me,mg,org.mg,nom.mg,gov.mg,prd.mg,tm.mg,edu.mg,mil.mg,com.mg,co.mg,mh,mil,mk,com.mk,org.mk,net.mk,edu.mk,gov.mk,inf.mk,name.mk,ml,com.ml,edu.ml,gouv.ml,gov.ml,net.ml,org.ml,presse.ml,mm,mn,gov.mn,edu.mn,org.mn,mo,com.mo,net.mo,org.mo,edu.mo,gov.mo,mobi,mp,mq,mr,gov.mr,ms,com.ms,edu.ms,gov.ms,net.ms,org.ms,mt,com.mt,edu.mt,net.mt,org.mt,mu,com.mu,net.mu,org.mu,gov.mu,ac.mu,co.mu,or.mu,museum,mv,aero.mv,biz.mv,com.mv,coop.mv,edu.mv,gov.mv,info.mv,int.mv,mil.mv,museum.mv,name.mv,net.mv,org.mv,pro.mv,mw,ac.mw,biz.mw,co.mw,com.mw,coop.mw,edu.mw,gov.mw,int.mw,museum.mw,net.mw,org.mw,mx,com.mx,org.mx,gob.mx,edu.mx,net.mx,my,biz.my,com.my,edu.my,gov.my,mil.my,name.my,net.my,org.my,mz,ac.mz,adv.mz,co.mz,edu.mz,gov.mz,mil.mz,net.mz,org.mz,na,info.na,pro.na,name.na,school.na,or.na,dr.na,us.na,mx.na,ca.na,in.na,cc.na,tv.na,ws.na,mobi.na,co.na,com.na,org.na,name,nc,asso.nc,nom.nc,ne,net,nf,com.nf,net.nf,per.nf,rec.nf,web.nf,arts.nf,firm.nf,info.nf,other.nf,store.nf,ng,com.ng,edu.ng,gov.ng,i.ng,mil.ng,mobi.ng,name.ng,net.ng,org.ng,sch.ng,ni,ac.ni,biz.ni,co.ni,com.ni,edu.ni,gob.ni,in.ni,info.ni,int.ni,mil.ni,net.ni,nom.ni,org.ni,web.ni,nl,no,fhs.no,vgs.no,fylkesbibl.no,folkebibl.no,museum.no,idrett.no,priv.no,mil.no,stat.no,dep.no,kommune.no,herad.no,np,nr,biz.nr,info.nr,gov.nr,edu.nr,org.nr,net.nr,com.nr,nu,nz,ac.nz,co.nz,cri.nz,geek.nz,gen.nz,govt.nz,health.nz,iwi.nz,kiwi.nz,maori.nz,mil.nz,māori.nz,net.nz,org.nz,parliament.nz,school.nz,om,co.om,com.om,edu.om,gov.om,med.om,museum.om,net.om,org.om,pro.om,onion,org,pa,ac.pa,gob.pa,com.pa,org.pa,sld.pa,edu.pa,net.pa,ing.pa,abo.pa,med.pa,nom.pa,pe,edu.pe,gob.pe,nom.pe,mil.pe,org.pe,com.pe,net.pe,pf,com.pf,org.pf,edu.pf,pg,ph,com.ph,net.ph,org.ph,gov.ph,edu.ph,ngo.ph,mil.ph,i.ph,pk,com.pk,net.pk,edu.pk,org.pk,fam.pk,biz.pk,web.pk,gov.pk,gob.pk,gok.pk,gon.pk,gop.pk,gos.pk,info.pk,pl,com.pl,net.pl,org.pl,aid.pl,agro.pl,atm.pl,auto.pl,biz.pl,edu.pl,gmina.pl,gsm.pl,info.pl,mail.pl,miasta.pl,media.pl,mil.pl,nieruchomosci.pl,nom.pl,pc.pl,powiat.pl,priv.pl,realestate.pl,rel.pl,sex.pl,shop.pl,sklep.pl,sos.pl,szkola.pl,targi.pl,tm.pl,tourism.pl,travel.pl,turystyka.pl,pm,pn,gov.pn,co.pn,org.pn,edu.pn,net.pn,post,pr,com.pr,net.pr,org.pr,gov.pr,edu.pr,isla.pr,pro.pr,biz.pr,info.pr,name.pr,est.pr,prof.pr,ac.pr,pro,aaa.pro,aca.pro,acct.pro,avocat.pro,bar.pro,cpa.pro,eng.pro,jur.pro,law.pro,med.pro,recht.pro,ps,edu.ps,gov.ps,sec.ps,plo.ps,com.ps,org.ps,net.ps,pt,net.pt,gov.pt,org.pt,edu.pt,int.pt,publ.pt,com.pt,nome.pt,pw,co.pw,ne.pw,or.pw,ed.pw,go.pw,belau.pw,py,com.py,coop.py,edu.py,gov.py,mil.py,net.py,org.py,qa,com.qa,edu.qa,gov.qa,mil.qa,name.qa,net.qa,org.qa,sch.qa,re,asso.re,com.re,nom.re,ro,arts.ro,com.ro,firm.ro,info.ro,nom.ro,nt.ro,org.ro,rec.ro,store.ro,tm.ro,www.ro,rs,ac.rs,co.rs,edu.rs,gov.rs,in.rs,org.rs,ru,rw,ac.rw,co.rw,coop.rw,gov.rw,mil.rw,net.rw,org.rw,sa,com.sa,net.sa,org.sa,gov.sa,med.sa,pub.sa,edu.sa,sch.sa,sb,com.sb,edu.sb,gov.sb,net.sb,org.sb,sc,com.sc,gov.sc,net.sc,org.sc,edu.sc,sd,com.sd,net.sd,org.sd,edu.sd,med.sd,tv.sd,gov.sd,info.sd,se,a.se,ac.se,b.se,bd.se,brand.se,c.se,d.se,e.se,f.se,fh.se,fhsk.se,fhv.se,g.se,h.se,i.se,k.se,komforb.se,kommunalforbund.se,komvux.se,l.se,lanbib.se,m.se,n.se,naturbruksgymn.se,o.se,org.se,p.se,parti.se,pp.se,press.se,r.se,s.se,t.se,tm.se,u.se,w.se,x.se,y.se,z.se,sg,com.sg,net.sg,org.sg,gov.sg,edu.sg,per.sg,sh,com.sh,net.sh,gov.sh,org.sh,mil.sh,si,sj,sk,sl,com.sl,net.sl,edu.sl,gov.sl,org.sl,sm,sn,art.sn,com.sn,edu.sn,gouv.sn,org.sn,perso.sn,univ.sn,so,com.so,edu.so,gov.so,me.so,net.so,org.so,sr,ss,biz.ss,com.ss,edu.ss,gov.ss,me.ss,net.ss,org.ss,sch.ss,st,co.st,com.st,consulado.st,edu.st,embaixada.st,mil.st,net.st,org.st,principe.st,saotome.st,store.st,su,sv,com.sv,edu.sv,gob.sv,org.sv,red.sv,sx,gov.sx,sy,edu.sy,gov.sy,net.sy,mil.sy,com.sy,org.sy,sz,co.sz,ac.sz,org.sz,tc,td,tel,tf,tg,th,ac.th,co.th,go.th,in.th,mi.th,net.th,or.th,tj,ac.tj,biz.tj,co.tj,com.tj,edu.tj,go.tj,gov.tj,int.tj,mil.tj,name.tj,net.tj,nic.tj,org.tj,test.tj,web.tj,tk,tl,gov.tl,tm,com.tm,co.tm,org.tm,net.tm,nom.tm,gov.tm,mil.tm,edu.tm,tn,com.tn,ens.tn,fin.tn,gov.tn,ind.tn,info.tn,intl.tn,mincom.tn,nat.tn,net.tn,org.tn,perso.tn,tourism.tn,to,com.to,gov.to,net.to,org.to,edu.to,mil.to,tr,av.tr,bbs.tr,bel.tr,biz.tr,com.tr,dr.tr,edu.tr,gen.tr,gov.tr,info.tr,mil.tr,k12.tr,kep.tr,name.tr,net.tr,org.tr,pol.tr,tel.tr,tsk.tr,tv.tr,web.tr,nc.tr,tt,co.tt,com.tt,org.tt,net.tt,biz.tt,info.tt,pro.tt,int.tt,coop.tt,jobs.tt,mobi.tt,travel.tt,museum.tt,aero.tt,name.tt,gov.tt,edu.tt,tv,tw,edu.tw,gov.tw,mil.tw,com.tw,net.tw,org.tw,idv.tw,game.tw,ebiz.tw,club.tw,tz,ac.tz,co.tz,go.tz,hotel.tz,info.tz,me.tz,mil.tz,mobi.tz,ne.tz,or.tz,sc.tz,tv.tz,ua,com.ua,edu.ua,gov.ua,in.ua,net.ua,org.ua,ug,co.ug,or.ug,ac.ug,sc.ug,go.ug,ne.ug,com.ug,org.ug,uk,ac.uk,co.uk,gov.uk,ltd.uk,me.uk,net.uk,nhs.uk,org.uk,plc.uk,police.uk,us,dni.us,fed.us,isa.us,kids.us,nsn.us,ak.us,al.us,ar.us,as.us,az.us,ca.us,co.us,ct.us,dc.us,de.us,fl.us,ga.us,gu.us,hi.us,ia.us,id.us,il.us,in.us,ks.us,ky.us,la.us,ma.us,md.us,me.us,mi.us,mn.us,mo.us,ms.us,mt.us,nc.us,nd.us,ne.us,nh.us,nj.us,nm.us,nv.us,ny.us,oh.us,ok.us,or.us,pa.us,pr.us,ri.us,sc.us,sd.us,tn.us,tx.us,ut.us,vi.us,vt.us,va.us,wa.us,wi.us,wv.us,wy.us,uy,com.uy,edu.uy,gub.uy,mil.uy,net.uy,org.uy,uz,co.uz,com.uz,net.uz,org.uz,va,vc,com.vc,net.vc,org.vc,gov.vc,mil.vc,edu.vc,ve,arts.ve,bib.ve,co.ve,com.ve,e12.ve,edu.ve,firm.ve,gob.ve,gov.ve,info.ve,int.ve,mil.ve,net.ve,nom.ve,org.ve,rar.ve,rec.ve,store.ve,tec.ve,web.ve,vg,vi,co.vi,com.vi,k12.vi,net.vi,org.vi,vn,ac.vn,ai.vn,biz.vn,com.vn,edu.vn,gov.vn,health.vn,id.vn,info.vn,int.vn,io.vn,name.vn,net.vn,org.vn,pro.vn,vu,com.vu,edu.vu,net.vu,org.vu,wf,ws,com.ws,net.ws,org.ws,gov.ws,edu.ws,yt,ye,com.ye,edu.ye,gov.ye,net.ye,mil.ye,org.ye,ac.za,agric.za,alt.za,co.za,edu.za,gov.za,grondar.za,law.za,mil.za,net.za,ngo.za,nic.za,nis.za,nom.za,org.za,school.za,tm.za,web.za,zm,ac.zm,biz.zm,co.zm,com.zm,edu.zm,gov.zm,info.zm,mil.zm,net.zm,org.zm,sch.zm,zw,ac.zw,co.zw,gov.zw,mil.zw,org.zw".split(
|
|
3
|
+
","
|
|
4
|
+
);
|
|
5
|
+
|
|
6
|
+
//convert to Map
|
|
7
|
+
const _publicSuffixesMap: Record<string, boolean> = {};
|
|
8
|
+
publicSuffixes.forEach(tld => {
|
|
9
|
+
_publicSuffixesMap[tld] = true;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const publicSuffixesMap = _publicSuffixesMap;
|
|
13
|
+
|
|
14
|
+
export function getTopLevelDomain(hostname: string) {
|
|
15
|
+
const [domain] = hostname.split(":");
|
|
16
|
+
const parts = domain.split(".");
|
|
17
|
+
if (parts[parts.length - 1] === "localhost" || parts.length < 2) {
|
|
18
|
+
return parts[parts.length - 1];
|
|
19
|
+
} else {
|
|
20
|
+
const d = parts[parts.length - 2] + "." + parts[parts.length - 1];
|
|
21
|
+
if (parts.length > 2 && publicSuffixesMap[d]) {
|
|
22
|
+
return parts[parts.length - 3] + "." + d;
|
|
23
|
+
} else {
|
|
24
|
+
return d;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/version.ts
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"rootDir": ".",
|
|
4
|
+
"outDir": "./compiled",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"moduleResolution": "Node",
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"target": "ES2015",
|
|
10
|
+
"lib": ["es2020", "dom"],
|
|
11
|
+
//this makes typescript igore @types/node during compilation
|
|
12
|
+
"types": []
|
|
13
|
+
},
|
|
14
|
+
"include": ["./src", "./__tests__"],
|
|
15
|
+
"exclude": [
|
|
16
|
+
"__tests__",
|
|
17
|
+
"node_modules",
|
|
18
|
+
"dist",
|
|
19
|
+
"test_projects",
|
|
20
|
+
"test",
|
|
21
|
+
"templates"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"rootDir": ".",
|
|
4
|
+
"outDir": "./compiled",
|
|
5
|
+
"declaration": false,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"moduleResolution": "Node",
|
|
8
|
+
"target": "ES2015",
|
|
9
|
+
"lib": ["es2017", "dom"]
|
|
10
|
+
//this makes typescript igore @types/node during compilation
|
|
11
|
+
// "types": []
|
|
12
|
+
},
|
|
13
|
+
"include": ["./src", "./__tests__"],
|
|
14
|
+
"exclude": ["__tests__", "node_modules", "dist", "test_projects", "test", "templates"]
|
|
15
|
+
}
|