Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 59669b0273 | |||
| 1c609cc638 |
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"@git.zone/cli": {
|
||||
"projectType": "npm",
|
||||
"module": {
|
||||
"githost": "code.foss.global",
|
||||
"gitscope": "push.rocks",
|
||||
"gitrepo": "smartenv",
|
||||
"description": "A module for storing and accessing environment details across different platforms.",
|
||||
"npmPackagename": "@push.rocks/smartenv",
|
||||
"license": "MIT",
|
||||
"projectDomain": "push.rocks"
|
||||
},
|
||||
"release": {
|
||||
"registries": [
|
||||
"https://verdaccio.lossless.digital",
|
||||
"https://registry.npmjs.org"
|
||||
],
|
||||
"accessLevel": "public"
|
||||
}
|
||||
},
|
||||
"@git.zone/tsdoc": {
|
||||
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
||||
},
|
||||
"@ship.zone/szci": {
|
||||
"npmGlobalTools": [],
|
||||
"npmRegistryUrl": "registry.npmjs.org"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-05-01 - 6.1.0 - feat(smartenv)
|
||||
add Bun and Deno OS detection support and update test runtime compatibility
|
||||
|
||||
- extends async OS detection helpers to work in Bun and Deno by loading the appropriate os module for each runtime
|
||||
- improves runtime-specific typings and safe global access for Deno, Bun, and importScripts usage
|
||||
- updates tests to export tap.start(), rename the browser test target to chromium, and clean up console output for newer test tooling
|
||||
- refreshes build and test tooling configuration and package metadata for the current release workflow
|
||||
|
||||
## 2025-11-01 - 6.0.0 - BREAKING CHANGE(Smartenv)
|
||||
Add Deno and Bun runtime detection, introduce getSafeModuleFor API, update docs and tests, and make isNode semantics Node-only (breaking change)
|
||||
|
||||
|
||||
+1
-2
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Task Venture Capital GmbH
|
||||
Copyright (c) 2026 Task Venture Capital GmbH
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
+14
-6
@@ -1,9 +1,5 @@
|
||||
{
|
||||
"npmci": {
|
||||
"npmGlobalTools": [],
|
||||
"npmAccessLevel": "public"
|
||||
},
|
||||
"gitzone": {
|
||||
"@git.zone/cli": {
|
||||
"projectType": "npm",
|
||||
"module": {
|
||||
"githost": "code.foss.global",
|
||||
@@ -12,6 +8,7 @@
|
||||
"description": "A module for storing and accessing environment details across different platforms.",
|
||||
"npmPackagename": "@push.rocks/smartenv",
|
||||
"license": "MIT",
|
||||
"projectDomain": "push.rocks",
|
||||
"keywords": [
|
||||
"environment detection",
|
||||
"cross-platform",
|
||||
@@ -24,9 +21,20 @@
|
||||
"typescript",
|
||||
"async"
|
||||
]
|
||||
},
|
||||
"release": {
|
||||
"registries": [
|
||||
"https://verdaccio.lossless.digital",
|
||||
"https://registry.npmjs.org"
|
||||
],
|
||||
"accessLevel": "public"
|
||||
}
|
||||
},
|
||||
"tsdoc": {
|
||||
"@git.zone/tsdoc": {
|
||||
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
||||
},
|
||||
"@ship.zone/szci": {
|
||||
"npmGlobalTools": [],
|
||||
"npmRegistryUrl": "registry.npmjs.org"
|
||||
}
|
||||
}
|
||||
+13
-11
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "@push.rocks/smartenv",
|
||||
"version": "6.0.0",
|
||||
"version": "6.1.0",
|
||||
"description": "A module for storing and accessing environment details across different platforms.",
|
||||
"main": "dist_ts/index.js",
|
||||
"typings": "dist_ts/index.d.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "(tstest test/ --web)",
|
||||
"build": "(tsbuild --web --allowimplicitany && tsbundle npm)",
|
||||
"testbrowser": "(npm test) && (node testbrowser.js)",
|
||||
"test": "tstest test/ --verbose",
|
||||
"build": "tsbuild --web && tsbundle npm",
|
||||
"testbrowser": "pnpm test && node testbrowser.js",
|
||||
"buildDocs": "tsdoc"
|
||||
},
|
||||
"repository": {
|
||||
@@ -34,14 +34,14 @@
|
||||
},
|
||||
"homepage": "https://code.foss.global/push.rocks/smartenv",
|
||||
"dependencies": {
|
||||
"@push.rocks/smartpromise": "^4.0.2"
|
||||
"@push.rocks/smartpromise": "^4.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@git.zone/tsbuild": "^2.6.8",
|
||||
"@git.zone/tsbundle": "^2.0.15",
|
||||
"@git.zone/tsrun": "^1.6.2",
|
||||
"@git.zone/tstest": "^2.7.0",
|
||||
"@types/node": "^22.0.0"
|
||||
"@git.zone/tsbuild": "^4.4.0",
|
||||
"@git.zone/tsbundle": "^2.10.1",
|
||||
"@git.zone/tsrun": "^2.0.3",
|
||||
"@git.zone/tstest": "^3.6.3",
|
||||
"@types/node": "^25.6.0"
|
||||
},
|
||||
"private": false,
|
||||
"files": [
|
||||
@@ -53,11 +53,13 @@
|
||||
"dist_ts_web/**/*",
|
||||
"assets/**/*",
|
||||
"cli.js",
|
||||
".smartconfig.json",
|
||||
"license",
|
||||
"npmextra.json",
|
||||
"readme.md"
|
||||
],
|
||||
"browserslist": [
|
||||
"last 1 chrome versions"
|
||||
],
|
||||
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
|
||||
"packageManager": "pnpm@10.28.2"
|
||||
}
|
||||
|
||||
Generated
+2068
-3043
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -13,7 +13,7 @@ tap.test('should detect Bun runtime correctly', async () => {
|
||||
expect(testEnv.isNode).toBeFalse();
|
||||
expect(testEnv.isDeno).toBeFalse();
|
||||
expect(testEnv.isBrowser).toBeFalse();
|
||||
console.log(' Bun runtime detected correctly');
|
||||
console.log('Bun runtime detected correctly');
|
||||
});
|
||||
|
||||
tap.test('should get Bun version', async () => {
|
||||
@@ -31,27 +31,27 @@ tap.test('should load modules for Bun', async () => {
|
||||
const pathModule = await testEnv.getSafeModuleFor('bun', 'path');
|
||||
expect(pathModule).not.toBeUndefined();
|
||||
expect(typeof pathModule.join).toEqual('function');
|
||||
console.log(' Successfully loaded module for Bun');
|
||||
console.log('Successfully loaded module for Bun');
|
||||
});
|
||||
|
||||
tap.test('should load modules for server runtimes', async () => {
|
||||
const pathModule = await testEnv.getSafeModuleFor('server', 'path');
|
||||
expect(pathModule).not.toBeUndefined();
|
||||
expect(typeof pathModule.join).toEqual('function');
|
||||
console.log(' Successfully loaded module with server target');
|
||||
console.log('Successfully loaded module with server target');
|
||||
});
|
||||
|
||||
tap.test('should load modules for array of runtimes', async () => {
|
||||
const pathModule = await testEnv.getSafeModuleFor(['bun', 'node'], 'path');
|
||||
expect(pathModule).not.toBeUndefined();
|
||||
expect(typeof pathModule.join).toEqual('function');
|
||||
console.log(' Successfully loaded module with array target');
|
||||
console.log('Successfully loaded module with array target');
|
||||
});
|
||||
|
||||
tap.test('should not load modules for wrong runtime', async () => {
|
||||
const result = await testEnv.getSafeModuleFor('node', 'path');
|
||||
expect(result).toBeUndefined();
|
||||
console.log(' Correctly rejected Node.js-only module in Bun');
|
||||
console.log('Correctly rejected Node.js-only module in Bun');
|
||||
});
|
||||
|
||||
tap.test('should detect OS', async () => {
|
||||
@@ -78,4 +78,4 @@ tap.test('should detect CI environment if present', async () => {
|
||||
console.log('CI detection: ' + testEnv.isCI);
|
||||
});
|
||||
|
||||
tap.start();
|
||||
export default tap.start();
|
||||
|
||||
@@ -13,7 +13,7 @@ tap.test('should detect browser runtime correctly', async () => {
|
||||
expect(testEnv.isNode).toBeFalse();
|
||||
expect(testEnv.isDeno).toBeFalse();
|
||||
expect(testEnv.isBun).toBeFalse();
|
||||
console.log(' Browser runtime detected correctly');
|
||||
console.log('Browser runtime detected correctly');
|
||||
});
|
||||
|
||||
tap.test('should get user agent', async () => {
|
||||
@@ -31,18 +31,18 @@ tap.test('should not get server runtime versions', async () => {
|
||||
expect(testEnv.nodeVersion).toEqual('undefined');
|
||||
expect(testEnv.denoVersion).toEqual('undefined');
|
||||
expect(testEnv.bunVersion).toEqual('undefined');
|
||||
console.log(' Server runtime versions correctly return undefined in browser');
|
||||
console.log('Server runtime versions correctly return undefined in browser');
|
||||
});
|
||||
|
||||
tap.test('should not load server modules', async () => {
|
||||
const result = await testEnv.getSafeModuleFor('server', 'path');
|
||||
expect(result).toBeUndefined();
|
||||
console.log(' Correctly rejected server module in browser');
|
||||
console.log('Correctly rejected server module in browser');
|
||||
});
|
||||
|
||||
tap.test('should not detect as CI', async () => {
|
||||
expect(testEnv.isCI).toBeFalse();
|
||||
console.log(' CI detection correctly false in browser');
|
||||
console.log('CI detection correctly false in browser');
|
||||
});
|
||||
|
||||
tap.test('OS detection should return false in browser', async () => {
|
||||
@@ -52,7 +52,7 @@ tap.test('OS detection should return false in browser', async () => {
|
||||
expect(resultMac).toBeFalse();
|
||||
expect(resultLinux).toBeFalse();
|
||||
expect(resultWindows).toBeFalse();
|
||||
console.log(' OS detection correctly returns false in browser');
|
||||
console.log('OS detection correctly returns false in browser');
|
||||
});
|
||||
|
||||
tap.start();
|
||||
export default tap.start();
|
||||
+5
-5
@@ -13,7 +13,7 @@ tap.test('should detect Deno runtime correctly', async () => {
|
||||
expect(testEnv.isNode).toBeFalse();
|
||||
expect(testEnv.isBun).toBeFalse();
|
||||
expect(testEnv.isBrowser).toBeFalse();
|
||||
console.log(' Deno runtime detected correctly');
|
||||
console.log('Deno runtime detected correctly');
|
||||
});
|
||||
|
||||
tap.test('should get Deno version', async () => {
|
||||
@@ -32,7 +32,7 @@ tap.test('should load modules for Deno', async () => {
|
||||
const pathModule = await testEnv.getSafeModuleFor('deno', 'node:path');
|
||||
expect(pathModule).not.toBeUndefined();
|
||||
expect(typeof pathModule.join).toEqual('function');
|
||||
console.log(' Successfully loaded module for Deno');
|
||||
console.log('Successfully loaded module for Deno');
|
||||
});
|
||||
|
||||
tap.test('should load modules for server runtimes', async () => {
|
||||
@@ -40,13 +40,13 @@ tap.test('should load modules for server runtimes', async () => {
|
||||
const pathModule = await testEnv.getSafeModuleFor('server', 'node:path');
|
||||
expect(pathModule).not.toBeUndefined();
|
||||
expect(typeof pathModule.join).toEqual('function');
|
||||
console.log(' Successfully loaded module with server target');
|
||||
console.log('Successfully loaded module with server target');
|
||||
});
|
||||
|
||||
tap.test('should not load modules for wrong runtime', async () => {
|
||||
const result = await testEnv.getSafeModuleFor('node', 'node:path');
|
||||
expect(result).toBeUndefined();
|
||||
console.log(' Correctly rejected Node.js-only module in Deno');
|
||||
console.log('Correctly rejected Node.js-only module in Deno');
|
||||
});
|
||||
|
||||
tap.test('should detect CI environment if present', async () => {
|
||||
@@ -56,4 +56,4 @@ tap.test('should detect CI environment if present', async () => {
|
||||
console.log('CI detection in Deno: ' + isCI);
|
||||
});
|
||||
|
||||
tap.start();
|
||||
export default tap.start();
|
||||
|
||||
+1
-1
@@ -78,4 +78,4 @@ tap.test('should state wether we are in CI', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
tap.start();
|
||||
export default tap.start();
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smartenv',
|
||||
version: '6.0.0',
|
||||
version: '6.1.0',
|
||||
description: 'A module for storing and accessing environment details across different platforms.'
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+4
-4
@@ -5,10 +5,10 @@
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"noImplicitAny": true,
|
||||
"esModuleInterop": true,
|
||||
"verbatimModuleSyntax": true
|
||||
"verbatimModuleSyntax": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": [
|
||||
"dist_*/**/*.d.ts"
|
||||
]
|
||||
"exclude": ["dist_*/**/*.d.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user