From 37db1273c91c6952def550d7e43153b381f29a4a Mon Sep 17 00:00:00 2001
From: Alistair Smith <hi@alistair.sh>
Date: Wed, 21 Sep 2022 04:30:46 +0100
Subject: [PATCH] feat: only use https import in node

---
 env.d.ts              |  5 +++
 gen-docs.mts          | 42 -------------------------
 package.json          |  2 ++
 src/rest/client.ts    | 10 +++---
 src/util/constants.ts | 10 ------
 tsup.config.ts        | 73 ++++++++++++++-----------------------------
 6 files changed, 36 insertions(+), 106 deletions(-)
 create mode 100644 env.d.ts
 delete mode 100644 gen-docs.mts

diff --git a/env.d.ts b/env.d.ts
new file mode 100644
index 00000000..c6a2be3d
--- /dev/null
+++ b/env.d.ts
@@ -0,0 +1,5 @@
+// Variables defined in tsup.config.ts
+// Used to build specific code for specific runtimes
+// while doing deadcode elimination
+
+declare const TSUP_IS_NODE: boolean;
diff --git a/gen-docs.mts b/gen-docs.mts
deleted file mode 100644
index 0cef418b..00000000
--- a/gen-docs.mts
+++ /dev/null
@@ -1,42 +0,0 @@
-import ts from 'typescript';
-import {createReadStream} from 'node:fs';
-import {json} from 'node:stream/consumers';
-
-const tsconfig = (await json(createReadStream('./tsconfig.json'))) as {
-	compilerOptions: ts.CompilerOptions;
-};
-
-const program = ts.createProgram(['./src/index.ts'], {
-	...ts.getDefaultCompilerOptions(),
-	...tsconfig.compilerOptions,
-	moduleResolution: ts.ModuleResolutionKind.NodeNext,
-	module: ts.ModuleKind.NodeNext,
-});
-
-const printer = ts.createPrinter();
-const hop = program.getSourceFile('./src/hop.ts');
-
-if (!hop) {
-	throw new Error('Could not find Hop class file!');
-}
-
-const node = hop.forEachChild(node => {
-	if (ts.isClassDeclaration(node)) {
-		return node;
-	}
-});
-
-if (!node) {
-	throw new Error('Could not find Hop class!');
-}
-
-const members = node.members.filter(ts.isPropertyDeclaration);
-
-const identifiers = members
-	.map(member => member.name)
-	.filter(Boolean)
-	.filter(ts.isIdentifier);
-
-for (const identifier of identifiers) {
-	console.log(printer.printNode(ts.EmitHint.IdentifierName, identifier, hop));
-}
diff --git a/package.json b/package.json
index fc7b692b..bd4b56b2 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,8 @@
 	"module": "./dist/index.js",
 	"exports": {
 		".": {
+			"node": "./dist/node/index.js",
+			"browser": "./dist/index.js",
 			"import": "./dist/index.js",
 			"require": "./dist/index.cjs"
 		},
diff --git a/src/rest/client.ts b/src/rest/client.ts
index 37b5739b..d41ea688 100644
--- a/src/rest/client.ts
+++ b/src/rest/client.ts
@@ -1,6 +1,6 @@
 import {fetch, Headers, Request} from '../util/fetch.js';
 import {ExtractRouteParams} from '../util/index.js';
-import {IS_BROWSER, IS_NODE} from '../util/constants.js';
+import {IS_BROWSER} from '../util/constants.js';
 import {createURLBuilder} from '../util/urls.js';
 import {APIResponse, Endpoints, ErroredAPIResponse} from './endpoints.js';
 import {getIdPrefix, Id, Method} from './types/index.js';
@@ -136,9 +136,11 @@ export class APIClient {
 	}
 
 	private async executeRequest<T>(request: Request): Promise<T> {
-		if (IS_NODE && !this.agent) {
-			const https = await import('https');
-			this.agent = new https.Agent({keepAlive: true});
+		if (TSUP_IS_NODE) {
+			if (!this.agent) {
+				const https = await import('https');
+				this.agent = new https.Agent({keepAlive: true});
+			}
 		}
 
 		const response = await fetch(request, {
diff --git a/src/util/constants.ts b/src/util/constants.ts
index 70adca30..041fb405 100644
--- a/src/util/constants.ts
+++ b/src/util/constants.ts
@@ -13,14 +13,4 @@ export const DEFAULT_BASE_URL = 'https://api.hop.io';
  */
 export const IS_BROWSER = typeof window !== 'undefined';
 
-/**
- * If we are in Node.js.
- */
-export const IS_NODE =
-	typeof process !== 'undefined' &&
-	process.versions != null &&
-	process.versions.node != null &&
-	typeof Bun === 'undefined' &&
-	typeof Deno === 'undefined';
-
 export const SUPPORTS_INTL = typeof Intl !== 'undefined';
diff --git a/tsup.config.ts b/tsup.config.ts
index 49acf9d1..23798748 100644
--- a/tsup.config.ts
+++ b/tsup.config.ts
@@ -1,62 +1,35 @@
-import {defineConfig} from 'tsup';
+import {defineConfig, type Options} from 'tsup';
 
-import glob from 'glob';
-import fs from 'fs';
-
-const utils = glob.sync('./src/utils/*');
-
-/**
- * Generate a package.json file for a util
- *
- * @param {string} utilName The name of the util to be exported
- * @returns A package.json config
- */
-function pkg(utilName: string) {
-	return JSON.stringify(
-		{
-			main: `../../dist/utils/${utilName}/index.js`,
-			module: `../../dist/utils/${utilName}/index.mjs`,
-			types: `../../dist/utils/${utilName}/index.d.ts`,
-		},
-		null,
-		4,
-	);
-}
-
-export default defineConfig({
-	entry: ['src/index.ts', 'src/utils/*/index.ts'],
+const commonBuild: Options = {
 	splitting: true,
 	clean: true,
-	minify: false,
 	sourcemap: true,
 	dts: true,
 	format: ['cjs', 'esm'],
+	minifySyntax: true,
+	minifyWhitespace: true,
 	target: 'esnext',
-	define: {
-		TSUP_DEBUG: 'false',
+	banner: {
+		js: `/* Copyright ${new Date().getFullYear()} Hop, Inc */`,
 	},
-	onSuccess: async () => {
-		if (!fs.existsSync('./utils')) {
-			fs.mkdirSync('./utils');
-		}
-
-		for (const util of utils) {
-			const utilName = util.split('/').pop();
+};
 
-			if (!utilName) {
-				continue;
-			}
-
-			const directory = `./utils/${utilName}`;
-
-			if (!fs.existsSync(directory)) {
-				fs.mkdirSync(directory);
-			}
+const define = ({node = false} = {}) => ({
+	TSUP_IS_NODE: JSON.stringify(node),
+});
 
-			fs.writeFileSync(`${directory}/package.json`, pkg(utilName), 'utf-8');
-		}
+export default defineConfig([
+	{
+		...commonBuild,
+		entry: ['src/index.ts', 'src/utils/*/index.ts'],
+		define: define(),
 	},
-	banner: {
-		js: `/* Copyright ${new Date().getFullYear()} Hop, Inc */`,
+	{
+		...commonBuild,
+		entry: ['src/index.ts'],
+		outDir: 'dist/node',
+		define: define({
+			node: true,
+		}),
 	},
-});
+]);