@hasna/connectors 1.4.2 → 1.4.4

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.
Files changed (168) hide show
  1. package/bin/index.js +145 -98
  2. package/bin/mcp.js +1 -1
  3. package/bin/serve.js +144 -93
  4. package/connectors/clickbank/README.md +2 -2
  5. package/connectors/split-in-batches/CLAUDE.md +1 -1
  6. package/connectors/split-in-batches/README.md +1 -1
  7. package/connectors/split-in-batches/src/api/client.test.ts +16 -17
  8. package/connectors/split-in-batches/src/api/client.ts +4 -3
  9. package/connectors/split-in-batches/src/cli/index.ts +1 -1
  10. package/connectors/spreadsheet-file/.env.example +1 -1
  11. package/connectors/spreadsheet-file/CLAUDE.md +2 -2
  12. package/connectors/spreadsheet-file/README.md +3 -3
  13. package/connectors/spreadsheet-file/src/api/client.test.ts +8 -9
  14. package/connectors/spreadsheet-file/src/api/client.ts +4 -3
  15. package/connectors/spreadsheet-file/src/cli/index.ts +1 -1
  16. package/connectors/sse-trigger/.env.example +1 -1
  17. package/connectors/sse-trigger/CLAUDE.md +2 -2
  18. package/connectors/sse-trigger/README.md +1 -1
  19. package/connectors/sse-trigger/src/api/client.test.ts +12 -8
  20. package/connectors/sse-trigger/src/api/client.ts +4 -3
  21. package/connectors/sse-trigger/src/api/index.ts +1 -1
  22. package/connectors/sse-trigger/src/cli/index.ts +1 -1
  23. package/connectors/sse-trigger/src/index.ts +1 -1
  24. package/connectors/stability-api-platform/AGENTS.md +1 -1
  25. package/connectors/stability-api-platform/CLAUDE.md +1 -1
  26. package/connectors/stability-api-platform/README.md +2 -2
  27. package/connectors/stability-api-platform/src/api/client.test.ts +17 -12
  28. package/connectors/stability-api-platform/src/api/client.ts +4 -3
  29. package/connectors/stability-api-platform/src/api/index.ts +0 -1
  30. package/connectors/stability-api-platform/src/cli/index.ts +1 -1
  31. package/connectors/stability-api-platform/src/index.ts +0 -1
  32. package/connectors/stop-and-error/.env.example +1 -1
  33. package/connectors/stop-and-error/CLAUDE.md +1 -1
  34. package/connectors/stop-and-error/README.md +1 -1
  35. package/connectors/stop-and-error/src/api/client.test.ts +12 -8
  36. package/connectors/stop-and-error/src/api/client.ts +4 -3
  37. package/connectors/stop-and-error/src/cli/index.ts +2 -2
  38. package/connectors/stripe-financial-connections/.env.example +1 -1
  39. package/connectors/stripe-financial-connections/CLAUDE.md +2 -2
  40. package/connectors/stripe-financial-connections/src/api/client.test.ts +34 -0
  41. package/connectors/stripe-financial-connections/src/api/client.ts +4 -3
  42. package/connectors/stripe-financial-connections/src/cli/index.ts +1 -1
  43. package/connectors/sucuri-api-platform/.env.example +1 -1
  44. package/connectors/sucuri-api-platform/CLAUDE.md +1 -1
  45. package/connectors/sucuri-api-platform/README.md +2 -2
  46. package/connectors/sucuri-api-platform/src/api/client.test.ts +9 -7
  47. package/connectors/sucuri-api-platform/src/api/client.ts +4 -3
  48. package/connectors/sucuri-api-platform/src/api/index.ts +1 -1
  49. package/connectors/sucuri-api-platform/src/cli/index.ts +1 -1
  50. package/connectors/sucuri-api-platform/src/index.ts +1 -1
  51. package/connectors/tettra-api-platform/CLAUDE.md +1 -1
  52. package/connectors/tettra-api-platform/README.md +2 -2
  53. package/connectors/tettra-api-platform/src/api/client.test.ts +7 -8
  54. package/connectors/tettra-api-platform/src/api/client.ts +4 -3
  55. package/connectors/tettra-api-platform/src/api/index.ts +1 -1
  56. package/connectors/tettra-api-platform/src/cli/index.ts +1 -1
  57. package/connectors/tettra-api-platform/src/index.ts +1 -1
  58. package/connectors/together-api-platform/.env.example +1 -1
  59. package/connectors/together-api-platform/CLAUDE.md +1 -1
  60. package/connectors/together-api-platform/README.md +1 -1
  61. package/connectors/together-api-platform/src/api/client.test.ts +11 -7
  62. package/connectors/together-api-platform/src/api/client.ts +4 -4
  63. package/connectors/together-api-platform/src/api/index.ts +1 -1
  64. package/connectors/together-api-platform/src/cli/index.ts +1 -1
  65. package/connectors/together-api-platform/src/index.ts +1 -1
  66. package/connectors/travo-real-estate/CLAUDE.md +1 -1
  67. package/connectors/travo-real-estate/README.md +1 -1
  68. package/connectors/travo-real-estate/src/api/client.test.ts +20 -16
  69. package/connectors/travo-real-estate/src/api/client.ts +4 -3
  70. package/connectors/travo-real-estate/src/utils/config.ts +2 -4
  71. package/connectors/tray-api-platform/CLAUDE.md +1 -1
  72. package/connectors/tray-api-platform/src/api/client.test.ts +17 -13
  73. package/connectors/tray-api-platform/src/api/client.ts +4 -3
  74. package/connectors/tray-api-platform/src/api/index.ts +1 -1
  75. package/connectors/tray-api-platform/src/cli/index.ts +1 -1
  76. package/connectors/tray-api-platform/src/index.ts +0 -1
  77. package/connectors/turso-api-platform/CLAUDE.md +1 -1
  78. package/connectors/turso-api-platform/README.md +2 -2
  79. package/connectors/turso-api-platform/src/api/client.test.ts +17 -13
  80. package/connectors/turso-api-platform/src/api/client.ts +4 -3
  81. package/connectors/turso-api-platform/src/cli/index.ts +2 -2
  82. package/connectors/twilio-api-platform/CLAUDE.md +1 -1
  83. package/connectors/twilio-api-platform/src/api/client.test.ts +11 -11
  84. package/connectors/twilio-api-platform/src/api/client.ts +4 -3
  85. package/connectors/twilio-api-platform/src/api/index.ts +1 -1
  86. package/connectors/twilio-api-platform/src/cli/index.ts +1 -1
  87. package/connectors/twilio-api-platform/src/index.ts +1 -1
  88. package/connectors/tyk-api-platform/.env.example +1 -1
  89. package/connectors/tyk-api-platform/CLAUDE.md +2 -2
  90. package/connectors/tyk-api-platform/README.md +1 -1
  91. package/connectors/tyk-api-platform/src/api/client.test.ts +14 -15
  92. package/connectors/tyk-api-platform/src/api/client.ts +4 -3
  93. package/connectors/tyk-api-platform/src/api/index.ts +1 -1
  94. package/connectors/tyk-api-platform/src/cli/index.ts +1 -1
  95. package/connectors/tyk-api-platform/src/index.ts +1 -1
  96. package/connectors/vector-legal/.env.example +1 -1
  97. package/connectors/vector-legal/AGENTS.md +1 -1
  98. package/connectors/vector-legal/CLAUDE.md +1 -1
  99. package/connectors/vector-legal/README.md +1 -1
  100. package/connectors/vector-legal/src/api/client.test.ts +9 -5
  101. package/connectors/vector-legal/src/api/client.ts +4 -3
  102. package/connectors/vector-legal/src/api/index.ts +1 -1
  103. package/connectors/vector-legal/src/cli/index.ts +2 -2
  104. package/connectors/vector-legal/src/index.ts +0 -1
  105. package/connectors/vector-legal-api/CLAUDE.md +1 -1
  106. package/connectors/vector-legal-api/README.md +2 -2
  107. package/connectors/vector-legal-api/src/api/client.test.ts +12 -7
  108. package/connectors/vector-legal-api/src/api/client.ts +4 -3
  109. package/connectors/vector-legal-api/src/api/index.ts +1 -1
  110. package/connectors/vector-legal-api/src/cli/index.ts +1 -1
  111. package/connectors/vector-legal-api/src/index.ts +1 -2
  112. package/connectors/velum-data-quality/.env.example +1 -1
  113. package/connectors/velum-data-quality/CLAUDE.md +1 -1
  114. package/connectors/velum-data-quality/src/api/client.test.ts +15 -16
  115. package/connectors/velum-data-quality/src/api/client.ts +4 -3
  116. package/connectors/velum-data-quality/src/api/index.ts +1 -1
  117. package/connectors/velum-data-quality/src/cli/index.ts +1 -1
  118. package/connectors/velum-data-quality/src/index.ts +0 -1
  119. package/connectors/vercel-api-platform/.env.example +1 -1
  120. package/connectors/vercel-api-platform/CLAUDE.md +2 -2
  121. package/connectors/vercel-api-platform/README.md +2 -2
  122. package/connectors/vercel-api-platform/src/api/client.test.ts +27 -6
  123. package/connectors/vercel-api-platform/src/api/client.ts +4 -3
  124. package/connectors/vercel-api-platform/src/api/index.ts +1 -1
  125. package/connectors/vercel-api-platform/src/cli/index.ts +2 -2
  126. package/connectors/vercel-api-platform/src/index.ts +0 -1
  127. package/connectors/veriphone/README.md +2 -2
  128. package/connectors/wave-accounting/CLAUDE.md +1 -1
  129. package/connectors/wave-accounting/src/utils/auth.ts +1 -1
  130. package/connectors/weaviate-api-platform/CLAUDE.md +1 -1
  131. package/connectors/weaviate-api-platform/src/api/client.test.ts +32 -7
  132. package/connectors/weaviate-api-platform/src/api/client.ts +4 -3
  133. package/connectors/weaviate-api-platform/src/api/index.ts +1 -1
  134. package/connectors/weaviate-api-platform/src/cli/index.ts +1 -1
  135. package/connectors/weaviate-api-platform/src/index.ts +1 -1
  136. package/connectors/workflow-trigger/.env.example +1 -1
  137. package/connectors/workflow-trigger/CLAUDE.md +1 -1
  138. package/connectors/workflow-trigger/README.md +1 -1
  139. package/connectors/workflow-trigger/src/api/client.test.ts +10 -6
  140. package/connectors/workflow-trigger/src/api/client.ts +4 -3
  141. package/connectors/workflow-trigger/src/cli/index.ts +1 -1
  142. package/connectors/write-binary-file/CLAUDE.md +1 -1
  143. package/connectors/write-binary-file/README.md +1 -1
  144. package/connectors/write-binary-file/src/api/client.test.ts +16 -12
  145. package/connectors/write-binary-file/src/api/client.ts +4 -3
  146. package/connectors/write-binary-file/src/api/index.ts +1 -1
  147. package/connectors/write-binary-file/src/index.ts +1 -1
  148. package/connectors/wubookratechecker/src/api/client.test.ts +34 -0
  149. package/connectors/wubookratechecker/src/api/client.ts +3 -1
  150. package/connectors/wubookratechecker/src/api/index.ts +1 -1
  151. package/connectors/wubookratechecker/src/types/index.ts +1 -1
  152. package/connectors/xai-api-platform/.env.example +1 -1
  153. package/connectors/xai-api-platform/CLAUDE.md +1 -1
  154. package/connectors/xai-api-platform/README.md +1 -1
  155. package/connectors/xai-api-platform/src/api/client.test.ts +33 -8
  156. package/connectors/xai-api-platform/src/api/client.ts +4 -3
  157. package/connectors/xai-api-platform/src/api/index.ts +1 -1
  158. package/connectors/xai-api-platform/src/index.ts +1 -1
  159. package/connectors/xai-api-platform/src/utils/config.ts +2 -3
  160. package/connectors/zapier-api-platform/CLAUDE.md +1 -1
  161. package/connectors/zapier-api-platform/README.md +1 -1
  162. package/connectors/zapier-api-platform/src/api/client.test.ts +19 -14
  163. package/connectors/zapier-api-platform/src/api/client.ts +4 -3
  164. package/connectors/zapier-api-platform/src/api/index.ts +1 -1
  165. package/connectors/zapier-api-platform/src/cli/index.ts +1 -1
  166. package/connectors/zapier-api-platform/src/index.ts +1 -1
  167. package/dist/index.js +1 -1
  168. package/package.json +1 -1
@@ -15,7 +15,7 @@ Copy `.env.example` to `.env` and set your API key:
15
15
  ```bash
16
16
  SPLIT_IN_BATCHES_API_KEY=your_api_key_here
17
17
  # Optional:
18
- # SPLIT_IN_BATCHES_BASE_URL=https://api.split-in-batches.com/v1
18
+ # SPLIT_IN_BATCHES_BASE_URL=configured.example.com/v1
19
19
  ```
20
20
 
21
21
  Or use the CLI profile/config commands:
@@ -1,5 +1,5 @@
1
1
  import { describe, test, expect, mock, beforeEach, afterEach } from 'bun:test';
2
- import { ConnectorClient, DEFAULT_BASE_URL } from './client';
2
+ import { ConnectorClient } from './client';
3
3
  import { BatchesApi } from './batches';
4
4
  import { Connector } from './index';
5
5
  import { ConnectorApiError } from '../types';
@@ -16,12 +16,11 @@ describe('ConnectorClient', () => {
16
16
  });
17
17
 
18
18
  test('requires apiKey', () => {
19
- expect(() => new ConnectorClient({ apiKey: '' })).toThrow('API key is required');
19
+ expect(() => new ConnectorClient({ apiKey: '', baseUrl: 'https://configured.example.com/v1' })).toThrow('API key is required');
20
20
  });
21
21
 
22
- test('uses default base URL', () => {
23
- const client = new ConnectorClient({ apiKey: 'test-key' });
24
- expect(client.getBaseUrl()).toBe(DEFAULT_BASE_URL);
22
+ test('refuses to send without a configured base URL (no default endpoint)', () => {
23
+ expect(() => new ConnectorClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
25
24
  });
26
25
 
27
26
  test('uses custom base URL and strips trailing slash', () => {
@@ -33,24 +32,24 @@ describe('ConnectorClient', () => {
33
32
  });
34
33
 
35
34
  test('buildUrl constructs batches list endpoint', () => {
36
- const client = new ConnectorClient({ apiKey: 'test-key' });
37
- expect(client.buildUrl('/batches')).toBe(`${DEFAULT_BASE_URL}/batches`);
35
+ const client = new ConnectorClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
36
+ expect(client.buildUrl('/batches')).toBe(`https://configured.example.com/v1/batches`);
38
37
  });
39
38
 
40
39
  test('buildUrl appends query parameters', () => {
41
- const client = new ConnectorClient({ apiKey: 'test-key' });
40
+ const client = new ConnectorClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
42
41
  const url = client.buildUrl('/batches', { limit: 10, offset: 0 });
43
- expect(url).toBe(`${DEFAULT_BASE_URL}/batches?limit=10&offset=0`);
42
+ expect(url).toBe(`https://configured.example.com/v1/batches?limit=10&offset=0`);
44
43
  });
45
44
 
46
45
  test('encodePathSegment encodes special characters', () => {
47
- const client = new ConnectorClient({ apiKey: 'test-key' });
46
+ const client = new ConnectorClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
48
47
  expect(client.encodePathSegment('item/1')).toBe('item%2F1');
49
48
  expect(client.encodePathSegment('batch id')).toBe('batch%20id');
50
49
  });
51
50
 
52
51
  test('request sends Bearer authorization header', async () => {
53
- const client = new ConnectorClient({ apiKey: 'split-in-batches-key' });
52
+ const client = new ConnectorClient({ apiKey: 'split-in-batches-key', baseUrl: 'https://configured.example.com/v1' });
54
53
  let capturedHeaders: Headers | undefined;
55
54
 
56
55
  globalThis.fetch = mock((_url, init) => {
@@ -66,7 +65,7 @@ describe('ConnectorClient', () => {
66
65
  });
67
66
 
68
67
  test('get batch builds encoded URL', async () => {
69
- const client = new ConnectorClient({ apiKey: 'test-key' });
68
+ const client = new ConnectorClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
70
69
  let capturedUrl = '';
71
70
 
72
71
  globalThis.fetch = mock((url) => {
@@ -79,11 +78,11 @@ describe('ConnectorClient', () => {
79
78
  const batches = new BatchesApi(client);
80
79
  await batches.get('item/1');
81
80
 
82
- expect(capturedUrl).toBe(`${DEFAULT_BASE_URL}/batches/item%2F1`);
81
+ expect(capturedUrl).toBe(`https://configured.example.com/v1/batches/item%2F1`);
83
82
  });
84
83
 
85
84
  test('post sends JSON body', async () => {
86
- const client = new ConnectorClient({ apiKey: 'test-key' });
85
+ const client = new ConnectorClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
87
86
  let capturedInit: RequestInit | undefined;
88
87
 
89
88
  globalThis.fetch = mock((_url, init) => {
@@ -100,7 +99,7 @@ describe('ConnectorClient', () => {
100
99
  });
101
100
 
102
101
  test('throws ConnectorApiError on HTTP error', async () => {
103
- const client = new ConnectorClient({ apiKey: 'test-key' });
102
+ const client = new ConnectorClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
104
103
 
105
104
  globalThis.fetch = mock(() =>
106
105
  Promise.resolve(
@@ -112,7 +111,7 @@ describe('ConnectorClient', () => {
112
111
  });
113
112
 
114
113
  test('getApiKeyPreview masks long keys', () => {
115
- const client = new ConnectorClient({ apiKey: 'abcdef1234567890' });
114
+ const client = new ConnectorClient({ apiKey: 'abcdef1234567890', baseUrl: 'https://configured.example.com/v1' });
116
115
  expect(client.getApiKeyPreview()).toBe('abcdef...7890');
117
116
  });
118
117
  });
@@ -128,7 +127,7 @@ describe('Connector', () => {
128
127
  });
129
128
 
130
129
  test('exposes API modules', () => {
131
- const connector = new Connector({ apiKey: 'test-key' });
130
+ const connector = new Connector({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
132
131
  expect(connector.batches).toBeDefined();
133
132
  expect(connector.events).toBeDefined();
134
133
  expect(connector.search).toBeDefined();
@@ -1,8 +1,6 @@
1
1
  import type { ConnectorConfig } from '../types';
2
2
  import { ConnectorApiError, parseApiError } from '../types';
3
3
 
4
- export const DEFAULT_BASE_URL = 'https://api.split-in-batches.com/v1';
5
-
6
4
  export interface RequestOptions {
7
5
  method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
8
6
  params?: Record<string, string | number | boolean | undefined>;
@@ -20,7 +18,10 @@ export class ConnectorClient {
20
18
  throw new Error('API key is required');
21
19
  }
22
20
  this.apiKey = config.apiKey;
23
- this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, '');
21
+ if (!config.baseUrl) {
22
+ throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
23
+ }
24
+ this.baseUrl = config.baseUrl.replace(/\/$/, '');
24
25
  }
25
26
 
26
27
  buildUrl(
@@ -201,7 +201,7 @@ configCmd
201
201
  console.log(chalk.bold(`Active Profile: ${profileName}`));
202
202
  info(`Config directory: ${getConfigDir()}`);
203
203
  info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
204
- info(`Base URL: ${baseUrl || chalk.gray('default (https://api.split-in-batches.com/v1)')}`);
204
+ info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
205
205
  });
206
206
 
207
207
  configCmd
@@ -1,5 +1,5 @@
1
1
  # SpreadsheetFile API credentials (Bearer token)
2
2
  SPREADSHEET_FILE_API_KEY=your-api-key-here
3
3
 
4
- # Optional: override API base URL (default: https://api.spreadsheet-file.com/v1)
4
+ # Optional: override API base URL (no default - must be configured)
5
5
  # SPREADSHEET_FILE_BASE_URL=https://api.spreadsheet-file.com/v1
@@ -33,7 +33,7 @@ Environment variables:
33
33
 
34
34
  ## API Details
35
35
 
36
- - **Base URL**: `https://api.spreadsheet-file.com/v1`
36
+ - **Base URL**: no default (must be configured)
37
37
  - **Auth**: `Authorization: Bearer <api_key>`
38
38
  - **Endpoints**:
39
39
  - `GET /files` - List files
@@ -75,7 +75,7 @@ Profile JSON structure:
75
75
  ```json
76
76
  {
77
77
  "apiKey": "your-api-key",
78
- "baseUrl": "https://api.spreadsheet-file.com/v1"
78
+ "baseUrl": "configured.example.com/v1"
79
79
  }
80
80
  ```
81
81
 
@@ -1,6 +1,6 @@
1
1
  # connect-spreadsheet-file
2
2
 
3
- TypeScript connector for the [SpreadsheetFile API](https://api.spreadsheet-file.com/v1) — spreadsheet workflow node operations.
3
+ TypeScript connector for the [SpreadsheetFile API](configured.example.com/v1) — spreadsheet workflow node operations.
4
4
 
5
5
  ## Features
6
6
 
@@ -26,7 +26,7 @@ Set credentials via environment variables or CLI profile:
26
26
  ```bash
27
27
  export SPREADSHEET_FILE_API_KEY=your-api-key
28
28
  # optional
29
- export SPREADSHEET_FILE_BASE_URL=https://api.spreadsheet-file.com/v1
29
+ export SPREADSHEET_FILE_BASE_URL=https://configured.example.com/v1
30
30
  ```
31
31
 
32
32
  Or use the CLI:
@@ -71,7 +71,7 @@ const file = await client.files.get('file-id');
71
71
 
72
72
  ## API
73
73
 
74
- - Base URL: `https://api.spreadsheet-file.com/v1`
74
+ - Base URL: `configured.example.com/v1`
75
75
  - Auth: `Authorization: Bearer <api_key>`
76
76
 
77
77
  ## License
@@ -1,11 +1,11 @@
1
1
  import { describe, test, expect, mock, beforeEach, afterEach } from 'bun:test';
2
- import { ConnectorClient, DEFAULT_BASE_URL } from './client';
2
+ import { ConnectorClient } from './client';
3
3
  import { ConnectorApiError } from '../types';
4
4
 
5
5
  describe('ConnectorClient', () => {
6
6
  const mockConfig = {
7
7
  apiKey: 'test-api-key-12345',
8
- baseUrl: 'https://api.spreadsheet-file.com/v1',
8
+ baseUrl: 'https://configured.example.com/v1',
9
9
  };
10
10
 
11
11
  describe('constructor', () => {
@@ -18,10 +18,9 @@ describe('ConnectorClient', () => {
18
18
  expect(client).toBeInstanceOf(ConnectorClient);
19
19
  });
20
20
 
21
- test('uses default base URL when not provided', () => {
22
- const client = new ConnectorClient({ apiKey: 'test-key' });
23
- expect(client.getBaseUrl()).toBe(DEFAULT_BASE_URL);
24
- });
21
+ test('refuses to send without a configured base URL (no default endpoint)', () => {
22
+ expect(() => new ConnectorClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
23
+ });
25
24
  });
26
25
 
27
26
  describe('getApiKeyPreview', () => {
@@ -31,7 +30,7 @@ describe('ConnectorClient', () => {
31
30
  });
32
31
 
33
32
  test('returns *** for short keys', () => {
34
- const client = new ConnectorClient({ apiKey: 'short' });
33
+ const client = new ConnectorClient({ apiKey: 'short', baseUrl: 'https://configured.example.com/v1' });
35
34
  expect(client.getApiKeyPreview()).toBe('***');
36
35
  });
37
36
  });
@@ -64,7 +63,7 @@ describe('ConnectorClient', () => {
64
63
 
65
64
  expect(global.fetch).toHaveBeenCalledTimes(1);
66
65
  const [url, options] = (global.fetch as ReturnType<typeof mock>).mock.calls[0];
67
- expect(url).toBe('https://api.spreadsheet-file.com/v1/files');
66
+ expect(url).toBe('https://configured.example.com/v1/files');
68
67
  expect(options.method).toBe('GET');
69
68
  expect(options.headers.Authorization).toBe('Bearer test-api-key-12345');
70
69
  expect(options.headers.Accept).toBe('application/json');
@@ -101,7 +100,7 @@ describe('ConnectorClient', () => {
101
100
  await client.get('/files/file%2Fwith%2Fslash');
102
101
 
103
102
  const [url] = (global.fetch as ReturnType<typeof mock>).mock.calls[0];
104
- expect(url).toBe('https://api.spreadsheet-file.com/v1/files/file%2Fwith%2Fslash');
103
+ expect(url).toBe('https://configured.example.com/v1/files/file%2Fwith%2Fslash');
105
104
  });
106
105
 
107
106
  test('post() makes POST request with JSON body', async () => {
@@ -1,8 +1,6 @@
1
1
  import type { ConnectorConfig, OutputFormat } from '../types';
2
2
  import { ConnectorApiError, parseApiError } from '../types';
3
3
 
4
- export const DEFAULT_BASE_URL = 'https://api.spreadsheet-file.com/v1';
5
-
6
4
  export interface RequestOptions {
7
5
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
8
6
  params?: Record<string, string | number | boolean | undefined>;
@@ -23,7 +21,10 @@ export class ConnectorClient {
23
21
  throw new Error('SpreadsheetFile API key is required');
24
22
  }
25
23
  this.apiKey = key;
26
- this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
24
+ if (!config.baseUrl) {
25
+ throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
26
+ }
27
+ this.baseUrl = config.baseUrl;
27
28
  }
28
29
 
29
30
  private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
@@ -199,7 +199,7 @@ configCmd
199
199
  console.log(chalk.bold(`Active Profile: ${profileName}`));
200
200
  info(`Config directory: ${getConfigDir()}`);
201
201
  info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
202
- info(`Base URL: ${baseUrl || chalk.gray('https://api.spreadsheet-file.com/v1 (default)')}`);
202
+ info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
203
203
  });
204
204
 
205
205
  configCmd
@@ -1,5 +1,5 @@
1
1
  # SseTrigger API credentials
2
2
  SSE_TRIGGER_API_KEY=your-api-key-here
3
3
 
4
- # Optional: override API base URL (default https://api.sse-trigger.com/v1)
4
+ # Optional: override API base URL (no default - must be configured)
5
5
  # SSE_TRIGGER_BASE_URL=https://api.sse-trigger.com/v1
@@ -24,7 +24,7 @@ bun run dev raw request --path /streams
24
24
 
25
25
  ## API Details
26
26
 
27
- - **Base URL**: `https://api.sse-trigger.com/v1`
27
+ - **Base URL**: no default (must be configured)
28
28
  - **Auth**: Bearer token (`Authorization: Bearer <api_key>`)
29
29
  - **Endpoints**:
30
30
  - `GET /streams` — list streams
@@ -54,7 +54,7 @@ Profile JSON:
54
54
  ```json
55
55
  {
56
56
  "apiKey": "your-key",
57
- "baseUrl": "https://api.sse-trigger.com/v1"
57
+ "baseUrl": "configured.example.com/v1"
58
58
  }
59
59
  ```
60
60
 
@@ -24,7 +24,7 @@ bun run dev streams list
24
24
  | Variable | Description |
25
25
  |----------|-------------|
26
26
  | `SSE_TRIGGER_API_KEY` | API key (overrides profile) |
27
- | `SSE_TRIGGER_BASE_URL` | Override base URL (default `https://api.sse-trigger.com/v1`) |
27
+ | `SSE_TRIGGER_BASE_URL` | Override base URL (no default - must be configured) |
28
28
 
29
29
  ## CLI Commands
30
30
 
@@ -1,6 +1,6 @@
1
1
  import { afterEach, describe, expect, test } from 'bun:test';
2
+ import { SseTriggerClient } from './client';
2
3
  import { SseTrigger } from './index';
3
- import { DEFAULT_BASE_URL } from './client';
4
4
 
5
5
  const realFetch = globalThis.fetch;
6
6
 
@@ -42,26 +42,26 @@ afterEach(() => {
42
42
  describe('SseTriggerClient', () => {
43
43
  test('listStreams sends Bearer auth to /streams', async () => {
44
44
  const recorded = installFetch(() => ({ streams: [] }));
45
- const client = new SseTrigger({ apiKey: 'sse-trigger-key' });
45
+ const client = new SseTrigger({ apiKey: 'sse-trigger-key', baseUrl: 'https://configured.example.com/v1' });
46
46
  await client.listStreams();
47
- expect(recorded[0].url).toBe(`${DEFAULT_BASE_URL}/streams`);
47
+ expect(recorded[0].url).toBe(`https://configured.example.com/v1/streams`);
48
48
  expect(recorded[0].method).toBe('GET');
49
49
  expect(new Headers(recorded[0].headers).get('Authorization')).toBe('Bearer sse-trigger-key');
50
50
  });
51
51
 
52
52
  test('getStream encodes stream id in URL path', async () => {
53
53
  const recorded = installFetch(() => ({ id: 'item-1' }));
54
- const client = new SseTrigger({ apiKey: 'sse-trigger-key' });
54
+ const client = new SseTrigger({ apiKey: 'sse-trigger-key', baseUrl: 'https://configured.example.com/v1' });
55
55
  await client.getStream('item-1');
56
- expect(recorded[0].url).toBe(`${DEFAULT_BASE_URL}/streams/item-1`);
56
+ expect(recorded[0].url).toBe(`https://configured.example.com/v1/streams/item-1`);
57
57
  expect(new Headers(recorded[0].headers).get('Authorization')).toBe('Bearer sse-trigger-key');
58
58
  });
59
59
 
60
60
  test('createStream POSTs JSON body to /streams', async () => {
61
61
  const recorded = installFetch(() => ({ id: 'new-stream' }));
62
- const client = new SseTrigger({ apiKey: 'sse-trigger-key' });
62
+ const client = new SseTrigger({ apiKey: 'sse-trigger-key', baseUrl: 'https://configured.example.com/v1' });
63
63
  await client.createStream({ name: 'workflow' });
64
- expect(recorded[0].url).toBe(`${DEFAULT_BASE_URL}/streams`);
64
+ expect(recorded[0].url).toBe(`https://configured.example.com/v1/streams`);
65
65
  expect(recorded[0].method).toBe('POST');
66
66
  expect(JSON.parse(recorded[0].body ?? '{}')).toEqual({ name: 'workflow' });
67
67
  });
@@ -74,6 +74,10 @@ describe('SseTriggerClient', () => {
74
74
  });
75
75
 
76
76
  test('requires API key', () => {
77
- expect(() => new SseTrigger({ apiKey: '' })).toThrow('API key is required');
77
+ expect(() => new SseTrigger({ apiKey: '', baseUrl: 'https://configured.example.com/v1' })).toThrow('API key is required');
78
+ });
79
+
80
+ test('refuses to send without a configured base URL (no default endpoint)', () => {
81
+ expect(() => new SseTriggerClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
78
82
  });
79
83
  });
@@ -1,8 +1,6 @@
1
1
  import type { SseTriggerConfig } from '../types';
2
2
  import { SseTriggerApiError, parseApiError } from '../types';
3
3
 
4
- export const DEFAULT_BASE_URL = 'https://api.sse-trigger.com/v1';
5
-
6
4
  export interface RequestOptions {
7
5
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
8
6
  params?: Record<string, string | number | boolean | undefined>;
@@ -21,7 +19,10 @@ export class SseTriggerClient {
21
19
  throw new Error('API key is required');
22
20
  }
23
21
  this.apiKey = config.apiKey;
24
- this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, '');
22
+ if (!config.baseUrl) {
23
+ throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
24
+ }
25
+ this.baseUrl = config.baseUrl.replace(/\/$/, '');
25
26
  }
26
27
 
27
28
  private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
@@ -63,7 +63,7 @@ export class SseTrigger {
63
63
  }
64
64
  }
65
65
 
66
- export { SseTriggerClient, DEFAULT_BASE_URL } from './client';
66
+ export { SseTriggerClient } from './client';
67
67
  export { StreamsApi } from './streams';
68
68
  export { EventsApi } from './events';
69
69
  export { SearchApi } from './search';
@@ -173,7 +173,7 @@ configCmd.command('show').description('Show current configuration').action(() =>
173
173
  console.log(chalk.bold(`Active Profile: ${profileName}`));
174
174
  info(`Config directory: ${getConfigDir()}`);
175
175
  info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
176
- info(`Base URL: ${baseUrl || chalk.gray('default (https://api.sse-trigger.com/v1)')}`);
176
+ info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
177
177
  });
178
178
 
179
179
  configCmd.command('clear').description('Clear configuration for active profile').action(() => {
@@ -1,6 +1,6 @@
1
1
  export { SseTrigger } from './api';
2
2
  export * from './types';
3
- export { SseTriggerClient, DEFAULT_BASE_URL } from './api';
3
+ export { SseTriggerClient } from './api';
4
4
 
5
5
  export {
6
6
  getApiKey,
@@ -8,7 +8,7 @@ Bearer API key (`STABILITY_API_PLATFORM_API_KEY`). Dashboard auth type: apikey/b
8
8
 
9
9
  ## Endpoints
10
10
 
11
- Base URL: `https://api.stabilityapiplatform.com/v1`
11
+ Base URL: no default (must be configured)
12
12
 
13
13
  Operations: list/create/get items, list events, search, raw request.
14
14
 
@@ -1,6 +1,6 @@
1
1
  # CLAUDE.md
2
2
 
3
- Stability Api Platform connector — Bearer token REST client for `https://api.stabilityapiplatform.com/v1`.
3
+ Stability Api Platform connector — Bearer token REST client for `configured.example.com/v1`.
4
4
 
5
5
  ## Commands
6
6
 
@@ -1,6 +1,6 @@
1
1
  # connect-stability-api-platform
2
2
 
3
- TypeScript connector for the [Stability Api Platform](https://api.stabilityapiplatform.com) REST API — items, events, search, and raw API access.
3
+ TypeScript connector for the [Stability Api Platform](configured.example.com/v1) REST API — items, events, search, and raw API access.
4
4
 
5
5
  ## Install
6
6
 
@@ -32,7 +32,7 @@ const items = await client.listItems();
32
32
  | Variable | Description |
33
33
  |----------|-------------|
34
34
  | `STABILITY_API_PLATFORM_API_KEY` | Bearer API key |
35
- | `STABILITY_API_PLATFORM_BASE_URL` | Optional base URL override (default `https://api.stabilityapiplatform.com/v1`) |
35
+ | `STABILITY_API_PLATFORM_BASE_URL` | Optional base URL override (no default - must be configured) |
36
36
 
37
37
  ## Configuration
38
38
 
@@ -1,5 +1,6 @@
1
1
  import { afterEach, describe, expect, test } from 'bun:test';
2
- import { StabilityApiPlatform, DEFAULT_BASE_URL } from './index';
2
+ import { ConnectorClient } from './client';
3
+ import { StabilityApiPlatform } from './index';
3
4
 
4
5
  const realFetch = globalThis.fetch;
5
6
 
@@ -45,60 +46,60 @@ afterEach(() => {
45
46
 
46
47
  describe('StabilityApiPlatform client', () => {
47
48
  test('requires api key', () => {
48
- expect(() => new StabilityApiPlatform({ apiKey: '' })).toThrow('API key is required');
49
+ expect(() => new StabilityApiPlatform({ apiKey: '', baseUrl: 'https://configured.example.com/v1' })).toThrow('API key is required');
49
50
  });
50
51
 
51
52
  test('listItems sends bearer auth to /v1/items', async () => {
52
53
  const recorded = installFetch();
53
- const client = new StabilityApiPlatform({ apiKey: 'stability-api-platform-key' });
54
+ const client = new StabilityApiPlatform({ apiKey: 'stability-api-platform-key', baseUrl: 'https://configured.example.com/v1' });
54
55
 
55
56
  await client.listItems();
56
57
 
57
58
  expect(recorded).toHaveLength(1);
58
- expect(recorded[0].url).toBe(`${DEFAULT_BASE_URL}/items`);
59
+ expect(recorded[0].url).toBe(`https://configured.example.com/v1/items`);
59
60
  expect(recorded[0].method).toBe('GET');
60
61
  expect(recorded[0].headers.get('Authorization')).toBe('Bearer stability-api-platform-key');
61
62
  });
62
63
 
63
64
  test('getItem encodes item id in URL path', async () => {
64
65
  const recorded = installFetch();
65
- const client = new StabilityApiPlatform({ apiKey: 'stability-api-platform-key' });
66
+ const client = new StabilityApiPlatform({ apiKey: 'stability-api-platform-key', baseUrl: 'https://configured.example.com/v1' });
66
67
 
67
68
  await client.getItem('item-1');
68
69
 
69
70
  expect(recorded).toHaveLength(1);
70
- expect(recorded[0].url).toBe(`${DEFAULT_BASE_URL}/items/item-1`);
71
+ expect(recorded[0].url).toBe(`https://configured.example.com/v1/items/item-1`);
71
72
  expect(recorded[0].headers.get('Authorization')).toBe('Bearer stability-api-platform-key');
72
73
  });
73
74
 
74
75
  test('createItem POSTs JSON body to /items', async () => {
75
76
  const recorded = installFetch();
76
- const client = new StabilityApiPlatform({ apiKey: 'test-key' });
77
+ const client = new StabilityApiPlatform({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
77
78
 
78
79
  await client.createItem({ name: 'widget' });
79
80
 
80
- expect(recorded[0].url).toBe(`${DEFAULT_BASE_URL}/items`);
81
+ expect(recorded[0].url).toBe(`https://configured.example.com/v1/items`);
81
82
  expect(recorded[0].method).toBe('POST');
82
83
  expect(JSON.parse(recorded[0].body!)).toEqual({ name: 'widget' });
83
84
  });
84
85
 
85
86
  test('listEvents GETs /events', async () => {
86
87
  const recorded = installFetch();
87
- const client = new StabilityApiPlatform({ apiKey: 'test-key' });
88
+ const client = new StabilityApiPlatform({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
88
89
 
89
90
  await client.listEvents({ limit: 5 });
90
91
 
91
- expect(recorded[0].url).toBe(`${DEFAULT_BASE_URL}/events?limit=5`);
92
+ expect(recorded[0].url).toBe(`https://configured.example.com/v1/events?limit=5`);
92
93
  expect(recorded[0].method).toBe('GET');
93
94
  });
94
95
 
95
96
  test('search POSTs to /search', async () => {
96
97
  const recorded = installFetch();
97
- const client = new StabilityApiPlatform({ apiKey: 'test-key' });
98
+ const client = new StabilityApiPlatform({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
98
99
 
99
100
  await client.search({ q: 'hello' });
100
101
 
101
- expect(recorded[0].url).toBe(`${DEFAULT_BASE_URL}/search`);
102
+ expect(recorded[0].url).toBe(`https://configured.example.com/v1/search`);
102
103
  expect(recorded[0].method).toBe('POST');
103
104
  expect(JSON.parse(recorded[0].body!)).toEqual({ q: 'hello' });
104
105
  });
@@ -121,4 +122,8 @@ describe('StabilityApiPlatform client', () => {
121
122
 
122
123
  if (original) process.env.STABILITY_API_PLATFORM_API_KEY = original;
123
124
  });
125
+
126
+ test('refuses to send without a configured base URL (no default endpoint)', () => {
127
+ expect(() => new ConnectorClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
128
+ });
124
129
  });
@@ -1,8 +1,6 @@
1
1
  import type { ConnectorConfig, ListQueryParams, RawRequestOptions } from '../types';
2
2
  import { ConnectorApiError } from '../types';
3
3
 
4
- export const DEFAULT_BASE_URL = 'https://api.stabilityapiplatform.com/v1';
5
-
6
4
  export interface RequestOptions {
7
5
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
8
6
  params?: ListQueryParams;
@@ -23,7 +21,10 @@ export class ConnectorClient {
23
21
  throw new Error('API key is required');
24
22
  }
25
23
  this.apiKey = config.apiKey;
26
- this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
24
+ if (!config.baseUrl) {
25
+ throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
26
+ }
27
+ this.baseUrl = config.baseUrl.replace(/\/+$/, '');
27
28
  }
28
29
 
29
30
  private buildUrl(path: string, params?: ListQueryParams): string {
@@ -55,6 +55,5 @@ export class StabilityApiPlatform {
55
55
  export {
56
56
  ConnectorClient,
57
57
  StabilityApiPlatformClient,
58
- DEFAULT_BASE_URL,
59
58
  encodePathSegment,
60
59
  } from './client';
@@ -191,7 +191,7 @@ configCmd
191
191
  console.log(chalk.bold(`Active Profile: ${profileName}`));
192
192
  info(`Config directory: ${getConfigDir()}`);
193
193
  info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
194
- info(`Base URL: ${baseUrl || chalk.gray('https://api.stabilityapiplatform.com/v1 (default)')}`);
194
+ info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
195
195
  });
196
196
 
197
197
  configCmd
@@ -3,7 +3,6 @@ export * from './types';
3
3
  export {
4
4
  ConnectorClient,
5
5
  StabilityApiPlatformClient,
6
- DEFAULT_BASE_URL,
7
6
  encodePathSegment,
8
7
  } from './api';
9
8
  export {
@@ -2,5 +2,5 @@
2
2
 
3
3
  STOP_AND_ERROR_API_KEY=your-api-key-here
4
4
 
5
- # Optional: Override API base URL (default https://api.stop-and-error.com/v1)
5
+ # Optional: Override API base URL (no default - must be configured)
6
6
  # STOP_AND_ERROR_BASE_URL=https://api.stop-and-error.com/v1
@@ -31,7 +31,7 @@ Credentials can be set via:
31
31
  - Profile configuration: `stop-and-error config set-key <key>`
32
32
 
33
33
  Optional base URL override:
34
- - `STOP_AND_ERROR_BASE_URL` (default `https://api.stop-and-error.com/v1`)
34
+ - `STOP_AND_ERROR_BASE_URL` (no default - must be configured)
35
35
 
36
36
  ## API Endpoints
37
37
 
@@ -15,7 +15,7 @@ Set credentials via environment variables or CLI profile:
15
15
  ```bash
16
16
  export STOP_AND_ERROR_API_KEY=your-api-key
17
17
  # optional
18
- export STOP_AND_ERROR_BASE_URL=https://api.stop-and-error.com/v1
18
+ export STOP_AND_ERROR_BASE_URL=https://configured.example.com/v1
19
19
  ```
20
20
 
21
21
  Or use the CLI: