@borrowbetter/swsdk 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,121 @@
1
+ 'use strict';
2
+
3
+ var ky = require('ky');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var ky__default = /*#__PURE__*/_interopDefault(ky);
8
+
9
+ // src/index.ts
10
+
11
+ // src/connect.ts
12
+ var ConnectAPI = class {
13
+ constructor(clients) {
14
+ this.clients = clients;
15
+ }
16
+ /**
17
+ * Connect a user that has already been pre-verified by phone number/SMS.
18
+ * Requires Spinwheel Support approval to enable.
19
+ *
20
+ * @see https://docs.spinwheel.io/reference/connect-preverified-phone-number
21
+ */
22
+ async preverifiedPhone(input) {
23
+ return this.clients.client.post("v1/users/connect/preverified/phoneNumber", { json: input }).json();
24
+ }
25
+ /**
26
+ * Connect a user using a network token obtained from user verification.
27
+ *
28
+ * @see https://docs.spinwheel.io/reference/create-network-user
29
+ */
30
+ async networkToken(input) {
31
+ return this.clients.client.post("v1/users/connect/network", { json: input }).json();
32
+ }
33
+ };
34
+
35
+ // src/debt-profile.ts
36
+ var DebtProfileAPI = class {
37
+ constructor(clients) {
38
+ this.clients = clients;
39
+ }
40
+ /**
41
+ * Trigger a credit pull for a user's debt profile.
42
+ *
43
+ * This is an async operation — the credit pull happens in the background.
44
+ * Poll `userManagement.get(userId)` to retrieve results once complete.
45
+ *
46
+ * Note: Your implementation must display the Spinwheel End User Agreement:
47
+ * "By continuing you agree to the Spinwheel End User Agreement. Further,
48
+ * you are providing written instructions to Spinwheel Solutions, Inc.
49
+ * authorizing it to obtain your credit profile from any consumer reporting agency."
50
+ *
51
+ * @see https://docs.spinwheel.io/reference/fetch-debt-profile
52
+ */
53
+ async fetch(userId, options) {
54
+ const { liabilityType, ...json } = options;
55
+ const searchParams = new URLSearchParams();
56
+ if (liabilityType) {
57
+ searchParams.set("liabilityType", liabilityType);
58
+ }
59
+ await this.clients.client.post(`v1/users/${userId}/debtProfile`, {
60
+ searchParams,
61
+ json
62
+ });
63
+ }
64
+ };
65
+
66
+ // src/user-management.ts
67
+ var UserManagementAPI = class {
68
+ constructor(clients) {
69
+ this.clients = clients;
70
+ }
71
+ /**
72
+ * Retrieve a user's full hydrated profile with unmasked account number and SSN.
73
+ *
74
+ * @param input - Either `userId` (Spinwheel's ID) or `extUserId` (your external ID)
75
+ * @see https://docs.spinwheel.io/reference/get-user-profile
76
+ */
77
+ async get(input) {
78
+ const searchParams = new URLSearchParams(input);
79
+ searchParams.append("unmask", "accountNumber");
80
+ searchParams.append("unmask", "ssn");
81
+ return this.clients.secureClient.get("v1/users", { searchParams }).json();
82
+ }
83
+ };
84
+
85
+ // src/index.ts
86
+ var BASE_URLS = {
87
+ production: {
88
+ standard: "https://api.spinwheel.io",
89
+ secure: "https://secure-api.spinwheel.io"
90
+ },
91
+ sandbox: {
92
+ standard: "https://sandbox-api.spinwheel.io",
93
+ secure: "https://secure-sandbox-api.spinwheel.io"
94
+ }
95
+ };
96
+ var SpinwheelSDK = class {
97
+ constructor(config) {
98
+ const urls = config.sandbox ? BASE_URLS.sandbox : BASE_URLS.production;
99
+ const clients = {
100
+ client: ky__default.default.create({
101
+ prefixUrl: urls.standard,
102
+ headers: {
103
+ Authorization: `Bearer ${config.apiKey}`
104
+ }
105
+ }),
106
+ secureClient: ky__default.default.create({
107
+ prefixUrl: urls.secure,
108
+ headers: {
109
+ Authorization: `Bearer ${config.apiKey}`
110
+ }
111
+ })
112
+ };
113
+ this.connect = new ConnectAPI(clients);
114
+ this.debtProfile = new DebtProfileAPI(clients);
115
+ this.userManagement = new UserManagementAPI(clients);
116
+ }
117
+ };
118
+
119
+ exports.SpinwheelSDK = SpinwheelSDK;
120
+ //# sourceMappingURL=index.js.map
121
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connect.ts","../src/debt-profile.ts","../src/user-management.ts","../src/index.ts"],"names":["ky"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n\tConnectNetworkTokenInput,\n\tConnectNetworkTokenResponse,\n\tConnectPreverifiedPhoneInput,\n\tConnectPreverifiedPhoneResponse,\n\tSpinwheelClients,\n} from \"./types\";\n\n/**\n * Connect API — Discover > Connect\n *\n * Handles user connection flows (preverified phone, network tokens).\n */\nexport class ConnectAPI {\n\tconstructor(private clients: SpinwheelClients) {}\n\n\t/**\n\t * Connect a user that has already been pre-verified by phone number/SMS.\n\t * Requires Spinwheel Support approval to enable.\n\t *\n\t * @see https://docs.spinwheel.io/reference/connect-preverified-phone-number\n\t */\n\tasync preverifiedPhone(\n\t\tinput: ConnectPreverifiedPhoneInput,\n\t): Promise<ConnectPreverifiedPhoneResponse> {\n\t\treturn this.clients.client\n\t\t\t.post(\"v1/users/connect/preverified/phoneNumber\", { json: input })\n\t\t\t.json<ConnectPreverifiedPhoneResponse>();\n\t}\n\n\t/**\n\t * Connect a user using a network token obtained from user verification.\n\t *\n\t * @see https://docs.spinwheel.io/reference/create-network-user\n\t */\n\tasync networkToken(\n\t\tinput: ConnectNetworkTokenInput,\n\t): Promise<ConnectNetworkTokenResponse> {\n\t\treturn this.clients.client\n\t\t\t.post(\"v1/users/connect/network\", { json: input })\n\t\t\t.json<ConnectNetworkTokenResponse>();\n\t}\n}\n","import type { FetchDebtProfileOptions, SpinwheelClients } from \"./types\";\n\n/**\n * Debt Profile API — Discover > Debt Profile\n *\n * Triggers asynchronous credit pulls. After calling `fetch`, use\n * `userManagement.get()` to retrieve the resulting hydrated user data.\n */\nexport class DebtProfileAPI {\n\tconstructor(private clients: SpinwheelClients) {}\n\n\t/**\n\t * Trigger a credit pull for a user's debt profile.\n\t *\n\t * This is an async operation — the credit pull happens in the background.\n\t * Poll `userManagement.get(userId)` to retrieve results once complete.\n\t *\n\t * Note: Your implementation must display the Spinwheel End User Agreement:\n\t * \"By continuing you agree to the Spinwheel End User Agreement. Further,\n\t * you are providing written instructions to Spinwheel Solutions, Inc.\n\t * authorizing it to obtain your credit profile from any consumer reporting agency.\"\n\t *\n\t * @see https://docs.spinwheel.io/reference/fetch-debt-profile\n\t */\n\tasync fetch(userId: string, options: FetchDebtProfileOptions): Promise<void> {\n\t\tconst { liabilityType, ...json } = options;\n\t\tconst searchParams = new URLSearchParams();\n\n\t\tif (liabilityType) {\n\t\t\tsearchParams.set(\"liabilityType\", liabilityType);\n\t\t}\n\n\t\tawait this.clients.client.post(`v1/users/${userId}/debtProfile`, {\n\t\t\tsearchParams,\n\t\t\tjson,\n\t\t});\n\t}\n}\n","import type { GetUserResponse, SpinwheelClients } from \"./types\";\n\ntype GetUserInput = { userId: string } | { extUserId: string };\n\n/**\n * User Management API — Optimize > User Management\n *\n * Handles user profile retrieval with unmasked sensitive fields.\n * Always uses the secure API endpoint.\n */\nexport class UserManagementAPI {\n\tconstructor(private clients: SpinwheelClients) {}\n\n\t/**\n\t * Retrieve a user's full hydrated profile with unmasked account number and SSN.\n\t *\n\t * @param input - Either `userId` (Spinwheel's ID) or `extUserId` (your external ID)\n\t * @see https://docs.spinwheel.io/reference/get-user-profile\n\t */\n\tasync get(input: GetUserInput): Promise<GetUserResponse> {\n\t\tconst searchParams = new URLSearchParams(input);\n\t\tsearchParams.append(\"unmask\", \"accountNumber\");\n\t\tsearchParams.append(\"unmask\", \"ssn\");\n\n\t\treturn this.clients.secureClient\n\t\t\t.get(\"v1/users\", { searchParams })\n\t\t\t.json<GetUserResponse>();\n\t}\n}\n","import ky from \"ky\";\nimport { ConnectAPI } from \"./connect\";\nimport { DebtProfileAPI } from \"./debt-profile\";\nimport type { SpinwheelClients, SpinwheelConfig } from \"./types\";\nimport { UserManagementAPI } from \"./user-management\";\n\nexport type { SpinwheelConfig } from \"./types\";\nexport type * from \"./types\";\n\nconst BASE_URLS = {\n\tproduction: {\n\t\tstandard: \"https://api.spinwheel.io\",\n\t\tsecure: \"https://secure-api.spinwheel.io\",\n\t},\n\tsandbox: {\n\t\tstandard: \"https://sandbox-api.spinwheel.io\",\n\t\tsecure: \"https://secure-sandbox-api.spinwheel.io\",\n\t},\n} as const;\n\n/**\n * Spinwheel SDK\n *\n * Domain-based client for the Spinwheel credit data and debt profile API.\n *\n * @example\n * ```typescript\n * const spinwheel = new SpinwheelSDK({\n * apiKey: \"your-api-key\",\n * sandbox: true,\n * });\n *\n * // Connect a user\n * const { data } = await spinwheel.connect.preverifiedPhone({\n * phoneNumber: \"+14155552671\",\n * dateOfBirth: \"1990-01-15\",\n * extUserId: \"your-user-id\",\n * audit: {\n * verificationDate: \"2025-01-01\",\n * userConsentDate: \"2025-01-01\",\n * verificationType: \"SMS\",\n * },\n * });\n *\n * // Trigger a credit pull\n * await spinwheel.debtProfile.fetch(data.userId, {\n * creditReport: { sourceBureau: \"TransUnion\", type: \"1_BUREAU.FULL\" },\n * creditScore: { sourceBureau: \"TransUnion\", model: \"VANTAGE_SCORE_3_0\" },\n * });\n *\n * // Retrieve hydrated profile\n * const profile = await spinwheel.userManagement.get({ userId: data.userId });\n * ```\n */\nexport class SpinwheelSDK {\n\treadonly connect: ConnectAPI;\n\treadonly debtProfile: DebtProfileAPI;\n\treadonly userManagement: UserManagementAPI;\n\n\tconstructor(config: SpinwheelConfig) {\n\t\tconst urls = config.sandbox ? BASE_URLS.sandbox : BASE_URLS.production;\n\n\t\tconst clients: SpinwheelClients = {\n\t\t\tclient: ky.create({\n\t\t\t\tprefixUrl: urls.standard,\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.apiKey}`,\n\t\t\t\t},\n\t\t\t}),\n\t\t\tsecureClient: ky.create({\n\t\t\t\tprefixUrl: urls.secure,\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.apiKey}`,\n\t\t\t\t},\n\t\t\t}),\n\t\t};\n\n\t\tthis.connect = new ConnectAPI(clients);\n\t\tthis.debtProfile = new DebtProfileAPI(clients);\n\t\tthis.userManagement = new UserManagementAPI(clients);\n\t}\n}\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,115 @@
1
+ import ky from 'ky';
2
+
3
+ // src/index.ts
4
+
5
+ // src/connect.ts
6
+ var ConnectAPI = class {
7
+ constructor(clients) {
8
+ this.clients = clients;
9
+ }
10
+ /**
11
+ * Connect a user that has already been pre-verified by phone number/SMS.
12
+ * Requires Spinwheel Support approval to enable.
13
+ *
14
+ * @see https://docs.spinwheel.io/reference/connect-preverified-phone-number
15
+ */
16
+ async preverifiedPhone(input) {
17
+ return this.clients.client.post("v1/users/connect/preverified/phoneNumber", { json: input }).json();
18
+ }
19
+ /**
20
+ * Connect a user using a network token obtained from user verification.
21
+ *
22
+ * @see https://docs.spinwheel.io/reference/create-network-user
23
+ */
24
+ async networkToken(input) {
25
+ return this.clients.client.post("v1/users/connect/network", { json: input }).json();
26
+ }
27
+ };
28
+
29
+ // src/debt-profile.ts
30
+ var DebtProfileAPI = class {
31
+ constructor(clients) {
32
+ this.clients = clients;
33
+ }
34
+ /**
35
+ * Trigger a credit pull for a user's debt profile.
36
+ *
37
+ * This is an async operation — the credit pull happens in the background.
38
+ * Poll `userManagement.get(userId)` to retrieve results once complete.
39
+ *
40
+ * Note: Your implementation must display the Spinwheel End User Agreement:
41
+ * "By continuing you agree to the Spinwheel End User Agreement. Further,
42
+ * you are providing written instructions to Spinwheel Solutions, Inc.
43
+ * authorizing it to obtain your credit profile from any consumer reporting agency."
44
+ *
45
+ * @see https://docs.spinwheel.io/reference/fetch-debt-profile
46
+ */
47
+ async fetch(userId, options) {
48
+ const { liabilityType, ...json } = options;
49
+ const searchParams = new URLSearchParams();
50
+ if (liabilityType) {
51
+ searchParams.set("liabilityType", liabilityType);
52
+ }
53
+ await this.clients.client.post(`v1/users/${userId}/debtProfile`, {
54
+ searchParams,
55
+ json
56
+ });
57
+ }
58
+ };
59
+
60
+ // src/user-management.ts
61
+ var UserManagementAPI = class {
62
+ constructor(clients) {
63
+ this.clients = clients;
64
+ }
65
+ /**
66
+ * Retrieve a user's full hydrated profile with unmasked account number and SSN.
67
+ *
68
+ * @param input - Either `userId` (Spinwheel's ID) or `extUserId` (your external ID)
69
+ * @see https://docs.spinwheel.io/reference/get-user-profile
70
+ */
71
+ async get(input) {
72
+ const searchParams = new URLSearchParams(input);
73
+ searchParams.append("unmask", "accountNumber");
74
+ searchParams.append("unmask", "ssn");
75
+ return this.clients.secureClient.get("v1/users", { searchParams }).json();
76
+ }
77
+ };
78
+
79
+ // src/index.ts
80
+ var BASE_URLS = {
81
+ production: {
82
+ standard: "https://api.spinwheel.io",
83
+ secure: "https://secure-api.spinwheel.io"
84
+ },
85
+ sandbox: {
86
+ standard: "https://sandbox-api.spinwheel.io",
87
+ secure: "https://secure-sandbox-api.spinwheel.io"
88
+ }
89
+ };
90
+ var SpinwheelSDK = class {
91
+ constructor(config) {
92
+ const urls = config.sandbox ? BASE_URLS.sandbox : BASE_URLS.production;
93
+ const clients = {
94
+ client: ky.create({
95
+ prefixUrl: urls.standard,
96
+ headers: {
97
+ Authorization: `Bearer ${config.apiKey}`
98
+ }
99
+ }),
100
+ secureClient: ky.create({
101
+ prefixUrl: urls.secure,
102
+ headers: {
103
+ Authorization: `Bearer ${config.apiKey}`
104
+ }
105
+ })
106
+ };
107
+ this.connect = new ConnectAPI(clients);
108
+ this.debtProfile = new DebtProfileAPI(clients);
109
+ this.userManagement = new UserManagementAPI(clients);
110
+ }
111
+ };
112
+
113
+ export { SpinwheelSDK };
114
+ //# sourceMappingURL=index.mjs.map
115
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connect.ts","../src/debt-profile.ts","../src/user-management.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type {\n\tConnectNetworkTokenInput,\n\tConnectNetworkTokenResponse,\n\tConnectPreverifiedPhoneInput,\n\tConnectPreverifiedPhoneResponse,\n\tSpinwheelClients,\n} from \"./types\";\n\n/**\n * Connect API — Discover > Connect\n *\n * Handles user connection flows (preverified phone, network tokens).\n */\nexport class ConnectAPI {\n\tconstructor(private clients: SpinwheelClients) {}\n\n\t/**\n\t * Connect a user that has already been pre-verified by phone number/SMS.\n\t * Requires Spinwheel Support approval to enable.\n\t *\n\t * @see https://docs.spinwheel.io/reference/connect-preverified-phone-number\n\t */\n\tasync preverifiedPhone(\n\t\tinput: ConnectPreverifiedPhoneInput,\n\t): Promise<ConnectPreverifiedPhoneResponse> {\n\t\treturn this.clients.client\n\t\t\t.post(\"v1/users/connect/preverified/phoneNumber\", { json: input })\n\t\t\t.json<ConnectPreverifiedPhoneResponse>();\n\t}\n\n\t/**\n\t * Connect a user using a network token obtained from user verification.\n\t *\n\t * @see https://docs.spinwheel.io/reference/create-network-user\n\t */\n\tasync networkToken(\n\t\tinput: ConnectNetworkTokenInput,\n\t): Promise<ConnectNetworkTokenResponse> {\n\t\treturn this.clients.client\n\t\t\t.post(\"v1/users/connect/network\", { json: input })\n\t\t\t.json<ConnectNetworkTokenResponse>();\n\t}\n}\n","import type { FetchDebtProfileOptions, SpinwheelClients } from \"./types\";\n\n/**\n * Debt Profile API — Discover > Debt Profile\n *\n * Triggers asynchronous credit pulls. After calling `fetch`, use\n * `userManagement.get()` to retrieve the resulting hydrated user data.\n */\nexport class DebtProfileAPI {\n\tconstructor(private clients: SpinwheelClients) {}\n\n\t/**\n\t * Trigger a credit pull for a user's debt profile.\n\t *\n\t * This is an async operation — the credit pull happens in the background.\n\t * Poll `userManagement.get(userId)` to retrieve results once complete.\n\t *\n\t * Note: Your implementation must display the Spinwheel End User Agreement:\n\t * \"By continuing you agree to the Spinwheel End User Agreement. Further,\n\t * you are providing written instructions to Spinwheel Solutions, Inc.\n\t * authorizing it to obtain your credit profile from any consumer reporting agency.\"\n\t *\n\t * @see https://docs.spinwheel.io/reference/fetch-debt-profile\n\t */\n\tasync fetch(userId: string, options: FetchDebtProfileOptions): Promise<void> {\n\t\tconst { liabilityType, ...json } = options;\n\t\tconst searchParams = new URLSearchParams();\n\n\t\tif (liabilityType) {\n\t\t\tsearchParams.set(\"liabilityType\", liabilityType);\n\t\t}\n\n\t\tawait this.clients.client.post(`v1/users/${userId}/debtProfile`, {\n\t\t\tsearchParams,\n\t\t\tjson,\n\t\t});\n\t}\n}\n","import type { GetUserResponse, SpinwheelClients } from \"./types\";\n\ntype GetUserInput = { userId: string } | { extUserId: string };\n\n/**\n * User Management API — Optimize > User Management\n *\n * Handles user profile retrieval with unmasked sensitive fields.\n * Always uses the secure API endpoint.\n */\nexport class UserManagementAPI {\n\tconstructor(private clients: SpinwheelClients) {}\n\n\t/**\n\t * Retrieve a user's full hydrated profile with unmasked account number and SSN.\n\t *\n\t * @param input - Either `userId` (Spinwheel's ID) or `extUserId` (your external ID)\n\t * @see https://docs.spinwheel.io/reference/get-user-profile\n\t */\n\tasync get(input: GetUserInput): Promise<GetUserResponse> {\n\t\tconst searchParams = new URLSearchParams(input);\n\t\tsearchParams.append(\"unmask\", \"accountNumber\");\n\t\tsearchParams.append(\"unmask\", \"ssn\");\n\n\t\treturn this.clients.secureClient\n\t\t\t.get(\"v1/users\", { searchParams })\n\t\t\t.json<GetUserResponse>();\n\t}\n}\n","import ky from \"ky\";\nimport { ConnectAPI } from \"./connect\";\nimport { DebtProfileAPI } from \"./debt-profile\";\nimport type { SpinwheelClients, SpinwheelConfig } from \"./types\";\nimport { UserManagementAPI } from \"./user-management\";\n\nexport type { SpinwheelConfig } from \"./types\";\nexport type * from \"./types\";\n\nconst BASE_URLS = {\n\tproduction: {\n\t\tstandard: \"https://api.spinwheel.io\",\n\t\tsecure: \"https://secure-api.spinwheel.io\",\n\t},\n\tsandbox: {\n\t\tstandard: \"https://sandbox-api.spinwheel.io\",\n\t\tsecure: \"https://secure-sandbox-api.spinwheel.io\",\n\t},\n} as const;\n\n/**\n * Spinwheel SDK\n *\n * Domain-based client for the Spinwheel credit data and debt profile API.\n *\n * @example\n * ```typescript\n * const spinwheel = new SpinwheelSDK({\n * apiKey: \"your-api-key\",\n * sandbox: true,\n * });\n *\n * // Connect a user\n * const { data } = await spinwheel.connect.preverifiedPhone({\n * phoneNumber: \"+14155552671\",\n * dateOfBirth: \"1990-01-15\",\n * extUserId: \"your-user-id\",\n * audit: {\n * verificationDate: \"2025-01-01\",\n * userConsentDate: \"2025-01-01\",\n * verificationType: \"SMS\",\n * },\n * });\n *\n * // Trigger a credit pull\n * await spinwheel.debtProfile.fetch(data.userId, {\n * creditReport: { sourceBureau: \"TransUnion\", type: \"1_BUREAU.FULL\" },\n * creditScore: { sourceBureau: \"TransUnion\", model: \"VANTAGE_SCORE_3_0\" },\n * });\n *\n * // Retrieve hydrated profile\n * const profile = await spinwheel.userManagement.get({ userId: data.userId });\n * ```\n */\nexport class SpinwheelSDK {\n\treadonly connect: ConnectAPI;\n\treadonly debtProfile: DebtProfileAPI;\n\treadonly userManagement: UserManagementAPI;\n\n\tconstructor(config: SpinwheelConfig) {\n\t\tconst urls = config.sandbox ? BASE_URLS.sandbox : BASE_URLS.production;\n\n\t\tconst clients: SpinwheelClients = {\n\t\t\tclient: ky.create({\n\t\t\t\tprefixUrl: urls.standard,\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.apiKey}`,\n\t\t\t\t},\n\t\t\t}),\n\t\t\tsecureClient: ky.create({\n\t\t\t\tprefixUrl: urls.secure,\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.apiKey}`,\n\t\t\t\t},\n\t\t\t}),\n\t\t};\n\n\t\tthis.connect = new ConnectAPI(clients);\n\t\tthis.debtProfile = new DebtProfileAPI(clients);\n\t\tthis.userManagement = new UserManagementAPI(clients);\n\t}\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@borrowbetter/swsdk",
3
+ "version": "0.1.1",
4
+ "description": "Spinwheel credit data and debt profile SDK",
5
+ "license": "MIT",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "dev": "tsup --watch",
22
+ "typecheck": "tsc --noEmit",
23
+ "smoke": "tsx scripts/smoke.ts",
24
+ "prepublishOnly": "npm run build",
25
+ "lint": "biome check",
26
+ "format": "biome check --write --unsafe",
27
+ "format:check": "biome ci"
28
+ },
29
+ "dependencies": {
30
+ "ky": "^1.7.2"
31
+ },
32
+ "devDependencies": {
33
+ "@biomejs/biome": "^2.4.4",
34
+ "dotenv-flow": "^4.1.0",
35
+ "tsup": "^8.0.0",
36
+ "tsx": "^4.21.0",
37
+ "typescript": "^5.4.0"
38
+ },
39
+ "engines": {
40
+ "node": ">=18"
41
+ }
42
+ }