detect-platform.mjs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
  2. import { VERSION } from "../version.mjs";
  3. export const isRunningInBrowser = () => {
  4. return (
  5. // @ts-ignore
  6. typeof window !== 'undefined' &&
  7. // @ts-ignore
  8. typeof window.document !== 'undefined' &&
  9. // @ts-ignore
  10. typeof navigator !== 'undefined');
  11. };
  12. /**
  13. * Note this does not detect 'browser'; for that, use getBrowserInfo().
  14. */
  15. function getDetectedPlatform() {
  16. if (typeof Deno !== 'undefined' && Deno.build != null) {
  17. return 'deno';
  18. }
  19. if (typeof EdgeRuntime !== 'undefined') {
  20. return 'edge';
  21. }
  22. if (Object.prototype.toString.call(typeof globalThis.process !== 'undefined' ? globalThis.process : 0) === '[object process]') {
  23. return 'node';
  24. }
  25. return 'unknown';
  26. }
  27. const getPlatformProperties = () => {
  28. const detectedPlatform = getDetectedPlatform();
  29. if (detectedPlatform === 'deno') {
  30. return {
  31. 'X-Stainless-Lang': 'js',
  32. 'X-Stainless-Package-Version': VERSION,
  33. 'X-Stainless-OS': normalizePlatform(Deno.build.os),
  34. 'X-Stainless-Arch': normalizeArch(Deno.build.arch),
  35. 'X-Stainless-Runtime': 'deno',
  36. 'X-Stainless-Runtime-Version': typeof Deno.version === 'string' ? Deno.version : Deno.version?.deno ?? 'unknown',
  37. };
  38. }
  39. if (typeof EdgeRuntime !== 'undefined') {
  40. return {
  41. 'X-Stainless-Lang': 'js',
  42. 'X-Stainless-Package-Version': VERSION,
  43. 'X-Stainless-OS': 'Unknown',
  44. 'X-Stainless-Arch': `other:${EdgeRuntime}`,
  45. 'X-Stainless-Runtime': 'edge',
  46. 'X-Stainless-Runtime-Version': globalThis.process.version,
  47. };
  48. }
  49. // Check if Node.js
  50. if (detectedPlatform === 'node') {
  51. return {
  52. 'X-Stainless-Lang': 'js',
  53. 'X-Stainless-Package-Version': VERSION,
  54. 'X-Stainless-OS': normalizePlatform(globalThis.process.platform ?? 'unknown'),
  55. 'X-Stainless-Arch': normalizeArch(globalThis.process.arch ?? 'unknown'),
  56. 'X-Stainless-Runtime': 'node',
  57. 'X-Stainless-Runtime-Version': globalThis.process.version ?? 'unknown',
  58. };
  59. }
  60. const browserInfo = getBrowserInfo();
  61. if (browserInfo) {
  62. return {
  63. 'X-Stainless-Lang': 'js',
  64. 'X-Stainless-Package-Version': VERSION,
  65. 'X-Stainless-OS': 'Unknown',
  66. 'X-Stainless-Arch': 'unknown',
  67. 'X-Stainless-Runtime': `browser:${browserInfo.browser}`,
  68. 'X-Stainless-Runtime-Version': browserInfo.version,
  69. };
  70. }
  71. // TODO add support for Cloudflare workers, etc.
  72. return {
  73. 'X-Stainless-Lang': 'js',
  74. 'X-Stainless-Package-Version': VERSION,
  75. 'X-Stainless-OS': 'Unknown',
  76. 'X-Stainless-Arch': 'unknown',
  77. 'X-Stainless-Runtime': 'unknown',
  78. 'X-Stainless-Runtime-Version': 'unknown',
  79. };
  80. };
  81. // Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts
  82. function getBrowserInfo() {
  83. if (typeof navigator === 'undefined' || !navigator) {
  84. return null;
  85. }
  86. // NOTE: The order matters here!
  87. const browserPatterns = [
  88. { key: 'edge', pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
  89. { key: 'ie', pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
  90. { key: 'ie', pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
  91. { key: 'chrome', pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
  92. { key: 'firefox', pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
  93. { key: 'safari', pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ },
  94. ];
  95. // Find the FIRST matching browser
  96. for (const { key, pattern } of browserPatterns) {
  97. const match = pattern.exec(navigator.userAgent);
  98. if (match) {
  99. const major = match[1] || 0;
  100. const minor = match[2] || 0;
  101. const patch = match[3] || 0;
  102. return { browser: key, version: `${major}.${minor}.${patch}` };
  103. }
  104. }
  105. return null;
  106. }
  107. const normalizeArch = (arch) => {
  108. // Node docs:
  109. // - https://nodejs.org/api/process.html#processarch
  110. // Deno docs:
  111. // - https://doc.deno.land/deno/stable/~/Deno.build
  112. if (arch === 'x32')
  113. return 'x32';
  114. if (arch === 'x86_64' || arch === 'x64')
  115. return 'x64';
  116. if (arch === 'arm')
  117. return 'arm';
  118. if (arch === 'aarch64' || arch === 'arm64')
  119. return 'arm64';
  120. if (arch)
  121. return `other:${arch}`;
  122. return 'unknown';
  123. };
  124. const normalizePlatform = (platform) => {
  125. // Node platforms:
  126. // - https://nodejs.org/api/process.html#processplatform
  127. // Deno platforms:
  128. // - https://doc.deno.land/deno/stable/~/Deno.build
  129. // - https://github.com/denoland/deno/issues/14799
  130. platform = platform.toLowerCase();
  131. // NOTE: this iOS check is untested and may not work
  132. // Node does not work natively on IOS, there is a fork at
  133. // https://github.com/nodejs-mobile/nodejs-mobile
  134. // however it is unknown at the time of writing how to detect if it is running
  135. if (platform.includes('ios'))
  136. return 'iOS';
  137. if (platform === 'android')
  138. return 'Android';
  139. if (platform === 'darwin')
  140. return 'MacOS';
  141. if (platform === 'win32')
  142. return 'Windows';
  143. if (platform === 'freebsd')
  144. return 'FreeBSD';
  145. if (platform === 'openbsd')
  146. return 'OpenBSD';
  147. if (platform === 'linux')
  148. return 'Linux';
  149. if (platform)
  150. return `Other:${platform}`;
  151. return 'Unknown';
  152. };
  153. let _platformHeaders;
  154. export const getPlatformHeaders = () => {
  155. return (_platformHeaders ?? (_platformHeaders = getPlatformProperties()));
  156. };
  157. //# sourceMappingURL=detect-platform.mjs.map