feat(smartenv): add Bun and Deno OS detection support and update test runtime compatibility

This commit is contained in:
2026-05-01 11:03:45 +00:00
parent 8514c4def0
commit 1c609cc638
14 changed files with 4366 additions and 5894 deletions
+36 -19
View File
@@ -1,6 +1,18 @@
import * as plugins from './smartenv.plugins.js';
import * as interfaces from './interfaces/index.js';
type TSmartenvGlobalThis = typeof globalThis & {
Deno?: {
version?: {
deno?: string;
};
};
Bun?: {
version?: string;
};
importScripts?: (urlArg: string) => void;
};
// interfaces
export interface IEnvObject {
name: string;
@@ -30,10 +42,10 @@ export class Smartenv {
}
}
public async getSafeNodeModule<T = any>(moduleNameArg: string, runAfterFunc?: (moduleArg: T) => Promise<any>): Promise<T> {
public async getSafeNodeModule<T = any>(moduleNameArg: string, runAfterFunc?: (moduleArg: T) => Promise<any>): Promise<T | undefined> {
if (!this.isNode && !this.isDeno && !this.isBun) {
console.error(`You tried to load a server module in a wrong context: ${moduleNameArg}. This does not throw.`);
return;
return undefined;
}
// tslint:disable-next-line: function-constructor
const returnValue: T = await (new Function(`return import('${moduleNameArg}')`)() as Promise<T>);
@@ -57,8 +69,9 @@ export class Smartenv {
}
const done = plugins.smartpromise.defer();
if (globalThis.importScripts) {
globalThis.importScripts(urlArg);
const smartenvGlobal = globalThis as TSmartenvGlobalThis;
if (smartenvGlobal.importScripts) {
smartenvGlobal.importScripts(urlArg);
done.resolve();
} else {
const script = document.createElement('script');
@@ -73,15 +86,17 @@ export class Smartenv {
}
public get runtimeEnv(): interfaces.TRuntimeType {
const smartenvGlobal = globalThis as TSmartenvGlobalThis;
// Check Deno first (most distinctive)
if (typeof globalThis.Deno !== 'undefined' &&
typeof (globalThis as any).Deno?.version !== 'undefined') {
if (typeof smartenvGlobal.Deno !== 'undefined' &&
typeof smartenvGlobal.Deno.version !== 'undefined') {
return 'deno';
}
// Check Bun second (most distinctive)
if (typeof globalThis.Bun !== 'undefined' &&
typeof (globalThis as any).Bun?.version !== 'undefined') {
if (typeof smartenvGlobal.Bun !== 'undefined' &&
typeof smartenvGlobal.Bun.version !== 'undefined') {
return 'bun';
}
@@ -135,14 +150,16 @@ export class Smartenv {
public get denoVersion(): string {
if (this.isDeno) {
return (globalThis as any).Deno.version.deno;
const smartenvGlobal = globalThis as TSmartenvGlobalThis;
return smartenvGlobal.Deno?.version?.deno ?? 'undefined';
}
return 'undefined';
}
public get bunVersion(): string {
if (this.isBun) {
return (globalThis as any).Bun.version;
const smartenvGlobal = globalThis as TSmartenvGlobalThis;
return smartenvGlobal.Bun?.version ?? 'undefined';
}
return 'undefined';
}
@@ -212,27 +229,27 @@ export class Smartenv {
}
public async isMacAsync(): Promise<boolean> {
if (this.isNode) {
const os = await this.getSafeNodeModule('os');
return os.platform() === 'darwin';
if (this.isNode || this.isDeno || this.isBun) {
const os = await this.getSafeNodeModule<typeof import('node:os')>(this.isDeno ? 'node:os' : 'os');
return os?.platform() === 'darwin';
} else {
return false;
}
}
public async isWindowsAsync(): Promise<boolean> {
if (this.isNode) {
const os = await this.getSafeNodeModule('os');
return os.platform() === 'win32';
if (this.isNode || this.isDeno || this.isBun) {
const os = await this.getSafeNodeModule<typeof import('node:os')>(this.isDeno ? 'node:os' : 'os');
return os?.platform() === 'win32';
} else {
return false;
}
}
public async isLinuxAsync(): Promise<boolean> {
if (this.isNode) {
const os = await this.getSafeNodeModule('os');
return os.platform() === 'linux';
if (this.isNode || this.isDeno || this.isBun) {
const os = await this.getSafeNodeModule<typeof import('node:os')>(this.isDeno ? 'node:os' : 'os');
return os?.platform() === 'linux';
} else {
return false;
}