Skip to content

Commit

Permalink
fix(typescript): Simplify runtime detection (#5578)
Browse files Browse the repository at this point in the history
Simplify runtime detection
  • Loading branch information
Swimburger authored Jan 11, 2025
1 parent 2256c53 commit 48260d9
Show file tree
Hide file tree
Showing 269 changed files with 5,168 additions and 4,896 deletions.
5 changes: 5 additions & 0 deletions generators/typescript/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.46.7] - 2025-01-09

- Fix: Simplify runtime detection to reduce the chance of using an unsupported API like `process.`
Detect Edge Runtime by Vercel.

## [0.46.6] - 2025-01-09

- Fix: Update `@types/node` to `18+`, required for the generated `Node18UniversalStreamWrapper` test.
Expand Down
2 changes: 1 addition & 1 deletion generators/typescript/sdk/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.46.6
0.46.7
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { RUNTIME } from "../../runtime";
import { makeRequest } from "../makeRequest";

describe("Test makeRequest", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { RUNTIME } from "../../runtime";
import { requestWithRetries } from "../requestWithRetries";

describe("requestWithRetries", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,104 +8,104 @@ interface BunGlobal {
version: string;
}

declare const Deno: DenoGlobal;
declare const Bun: BunGlobal;

/**
* A constant that indicates whether the environment the code is running is a Web Browser.
*/
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";

/**
* A constant that indicates whether the environment the code is running is a Web Worker.
*/
const isWebWorker =
typeof self === "object" &&
// @ts-ignore
typeof self?.importScripts === "function" &&
(self.constructor?.name === "DedicatedWorkerGlobalScope" ||
self.constructor?.name === "ServiceWorkerGlobalScope" ||
self.constructor?.name === "SharedWorkerGlobalScope");

/**
* A constant that indicates whether the environment the code is running is Deno.
*/
const isDeno =
typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined";

/**
* A constant that indicates whether the environment the code is running is Bun.sh.
*/
const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined";

/**
* A constant that indicates whether the environment the code is running is Node.JS.
*/
const isNode =
typeof process !== "undefined" &&
Boolean(process.version) &&
Boolean(process.versions?.node) &&
// Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions
!isDeno &&
!isBun;

/**
* A constant that indicates whether the environment the code is running is in React-Native.
* https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js
*/
const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative";

/**
* A constant that indicates whether the environment the code is running is Cloudflare.
* https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent
*/
const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?.userAgent === "Cloudflare-Workers";
declare const Deno: DenoGlobal | undefined;
declare const Bun: BunGlobal | undefined;
declare const EdgeRuntime: string | undefined;

/**
* A constant that indicates which environment and version the SDK is running in.
*/
export const RUNTIME: Runtime = evaluateRuntime();

export interface Runtime {
type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd";
type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd" | "edge-runtime";
version?: string;
parsedVersion?: number;
}

function evaluateRuntime(): Runtime {
/**
* A constant that indicates whether the environment the code is running is a Web Browser.
*/
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
if (isBrowser) {
return {
type: "browser",
version: window.navigator.userAgent
};
}

/**
* A constant that indicates whether the environment the code is running is Cloudflare.
* https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent
*/
const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?.userAgent === "Cloudflare-Workers";
if (isCloudflare) {
return {
type: "workerd"
};
}

/**
* A constant that indicates whether the environment the code is running is Edge Runtime.
* https://vercel.com/docs/functions/runtimes/edge-runtime#check-if-you're-running-on-the-edge-runtime
*/
const isEdgeRuntime = typeof EdgeRuntime === "string";
if (isEdgeRuntime) {
return {
type: "edge-runtime"
};
}

/**
* A constant that indicates whether the environment the code is running is a Web Worker.
*/
const isWebWorker =
typeof self === "object" &&
// @ts-ignore
typeof self?.importScripts === "function" &&
(self.constructor?.name === "DedicatedWorkerGlobalScope" ||
self.constructor?.name === "ServiceWorkerGlobalScope" ||
self.constructor?.name === "SharedWorkerGlobalScope");
if (isWebWorker) {
return {
type: "web-worker"
};
}

/**
* A constant that indicates whether the environment the code is running is Deno.
* FYI Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions
*/
const isDeno =
typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined";
if (isDeno) {
return {
type: "deno",
version: Deno.version.deno
};
}

/**
* A constant that indicates whether the environment the code is running is Bun.sh.
*/
const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined";
if (isBun) {
return {
type: "bun",
version: Bun.version
};
}

/**
* A constant that indicates whether the environment the code is running is Node.JS.
*/
const isNode =
typeof process !== "undefined" &&
"version" in process &&
!!process.version &&
"versions" in process &&
!!process.versions?.node;
if (isNode) {
return {
type: "node",
Expand All @@ -114,6 +114,11 @@ function evaluateRuntime(): Runtime {
};
}

/**
* A constant that indicates whether the environment the code is running is in React-Native.
* https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js
*/
const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative";
if (isReactNative) {
return {
type: "react-native"
Expand Down
111 changes: 58 additions & 53 deletions seed/ts-sdk/alias-extends/src/core/runtime/runtime.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 48260d9

Please sign in to comment.