feat: init @affine/env (#1243)

This commit is contained in:
Himself65
2023-03-01 19:26:55 -06:00
committed by GitHub
parent 71a0951c77
commit 1abab690af
19 changed files with 338 additions and 137 deletions
+146
View File
@@ -0,0 +1,146 @@
import { assertEquals } from '@blocksuite/global/utils';
import getConfig from 'next/config';
import { z } from 'zod';
import { getUaHelper } from './ua-helper';
type BrowserBase = {
isBrowser: true;
isServer: false;
isDebug: boolean;
// browser special properties
isLinux: boolean;
isMacOs: boolean;
isSafari: boolean;
isWindows: boolean;
isFireFox: boolean;
isMobile: boolean;
isChrome: boolean;
};
type NonChromeBrowser = BrowserBase & {
isChrome: false;
};
type ChromeBrowser = BrowserBase & {
isSafari: false;
isFireFox: false;
isChrome: true;
chromeVersion: number;
};
type Browser = NonChromeBrowser | ChromeBrowser;
type Server = {
isBrowser: false;
isServer: true;
isDebug: boolean;
};
export type Environment = Browser | Server;
let environment: Environment | null = null;
export function getEnvironment() {
if (environment) {
return environment;
}
const isDebug = process.env.NODE_ENV === 'development';
if (typeof window === 'undefined') {
environment = {
isBrowser: false,
isServer: true,
isDebug,
} satisfies Server;
} else {
const uaHelper = getUaHelper();
environment = {
isBrowser: true,
isServer: false,
isDebug,
isLinux: uaHelper.isLinux,
isMacOs: uaHelper.isMacOs,
isSafari: uaHelper.isSafari,
isWindows: uaHelper.isWindows,
isFireFox: uaHelper.isFireFox,
isMobile: uaHelper.isMobile,
isChrome: uaHelper.isChrome,
} as Browser;
if (environment.isChrome === true) {
assertEquals(environment.isSafari, false);
assertEquals(environment.isFireFox, false);
environment = {
...environment,
isSafari: false,
isFireFox: false,
isChrome: true,
chromeVersion: uaHelper.getChromeVersion(),
} satisfies ChromeBrowser;
}
}
globalThis.environment = environment;
return environment;
}
export const publicRuntimeConfigSchema = z.object({
PROJECT_NAME: z.string(),
BUILD_DATE: z.string(),
gitVersion: z.string(),
hash: z.string(),
serverAPI: z.string(),
editorVersion: z.string(),
enableIndexedDBProvider: z.boolean(),
enableBroadCastChannelProvider: z.boolean(),
prefetchWorkspace: z.boolean(),
// expose internal api to globalThis, **development only**
exposeInternal: z.boolean(),
});
export type PublicRuntimeConfig = z.infer<typeof publicRuntimeConfigSchema>;
const { publicRuntimeConfig: config } = getConfig() as {
publicRuntimeConfig: PublicRuntimeConfig;
};
publicRuntimeConfigSchema.parse(config);
function printBuildInfo() {
console.group('Build info');
console.log('Project:', config.PROJECT_NAME);
console.log(
'Build date:',
config.BUILD_DATE ? new Date(config.BUILD_DATE).toLocaleString() : 'Unknown'
);
console.log('Editor Version:', config.editorVersion);
console.log('Version:', config.gitVersion);
console.log(
'AFFiNE is an open source project, you can view its source code on GitHub!'
);
console.log(`https://github.com/toeverything/AFFiNE/tree/${config.hash}`);
console.groupEnd();
}
declare global {
// eslint-disable-next-line no-var
var environment: Environment;
// eslint-disable-next-line no-var
var $AFFINE_SETUP: boolean | undefined;
// eslint-disable-next-line no-var
var editorVersion: string | undefined;
}
export function setupGlobal() {
if (globalThis.$AFFINE_SETUP) {
return;
}
globalThis.environment = getEnvironment();
if (getEnvironment().isBrowser) {
printBuildInfo();
globalThis.editorVersion = config.editorVersion;
}
globalThis.$AFFINE_SETUP = true;
}
export { config };
+88
View File
@@ -0,0 +1,88 @@
import { assertExists } from '@blocksuite/global/utils';
export function getUaHelper() {
let uaHelper = null;
(function (navigator) {
const getUa = () => {
const ua = navigator.userAgent;
const uas = ua.toLowerCase();
const mobile = /iPhone|iPad|iPod|Android/i.test(ua);
const android =
(mobile &&
(uas.indexOf('android') > -1 || uas.indexOf('linux') > -1)) ||
uas.indexOf('adr') > -1;
const ios = mobile && !android && /Mac OS/i.test(ua);
const iphone = ios && uas.indexOf('iphone') > -1;
const ipad = ios && !iphone;
const wx = /MicroMessenger/i.test(ua);
const chrome = /CriOS/i.test(ua) || /Chrome/i.test(ua);
const tiktok = mobile && /aweme/i.test(ua);
const weibo = mobile && /Weibo/i.test(ua);
const safari =
ios &&
!chrome &&
!wx &&
!weibo &&
!tiktok &&
/Safari|Macintosh/i.test(ua);
const firefox = /Firefox/.test(ua);
const win = /windows|win32|win64|wow32|wow64/.test(uas);
const linux = /linux/.test(uas);
return {
ua,
mobile,
android,
ios,
wx,
chrome,
iphone,
ipad,
safari,
tiktok,
weibo,
win,
linux,
firefox,
};
};
class UaHelper {
private uaMap;
public isLinux = false;
public isMacOs = false;
public isSafari = false;
public isWindows = false;
public isFireFox = false;
public isMobile = false;
public isChrome = false;
getChromeVersion = (): number => {
const raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
assertExists(raw);
return parseInt(raw[2], 10);
};
constructor() {
this.uaMap = getUa();
this.initUaFlags();
}
public checkUseragent(isUseragent: keyof ReturnType<typeof getUa>) {
return Boolean(this.uaMap[isUseragent]);
}
private initUaFlags() {
this.isLinux = this.checkUseragent('linux');
this.isMacOs = this.checkUseragent('ios');
this.isSafari = this.checkUseragent('safari');
this.isWindows = this.checkUseragent('win');
this.isFireFox = this.checkUseragent('firefox');
this.isMobile = this.checkUseragent('mobile');
this.isChrome = this.checkUseragent('chrome');
}
}
uaHelper = new UaHelper();
})(navigator);
return uaHelper;
}