@hasna/connectors 1.4.2 → 1.4.3
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/bin/index.js +1 -5
- package/bin/mcp.js +1 -1
- package/bin/serve.js +1 -1
- package/connectors/clickbank/README.md +2 -2
- package/connectors/split-in-batches/CLAUDE.md +1 -1
- package/connectors/split-in-batches/README.md +1 -1
- package/connectors/split-in-batches/src/api/client.test.ts +16 -17
- package/connectors/split-in-batches/src/api/client.ts +4 -3
- package/connectors/split-in-batches/src/cli/index.ts +1 -1
- package/connectors/spreadsheet-file/.env.example +1 -1
- package/connectors/spreadsheet-file/CLAUDE.md +2 -2
- package/connectors/spreadsheet-file/README.md +3 -3
- package/connectors/spreadsheet-file/src/api/client.test.ts +8 -9
- package/connectors/spreadsheet-file/src/api/client.ts +4 -3
- package/connectors/spreadsheet-file/src/cli/index.ts +1 -1
- package/connectors/sse-trigger/.env.example +1 -1
- package/connectors/sse-trigger/CLAUDE.md +2 -2
- package/connectors/sse-trigger/README.md +1 -1
- package/connectors/sse-trigger/src/api/client.test.ts +12 -8
- package/connectors/sse-trigger/src/api/client.ts +4 -3
- package/connectors/sse-trigger/src/api/index.ts +1 -1
- package/connectors/sse-trigger/src/cli/index.ts +1 -1
- package/connectors/sse-trigger/src/index.ts +1 -1
- package/connectors/stability-api-platform/AGENTS.md +1 -1
- package/connectors/stability-api-platform/CLAUDE.md +1 -1
- package/connectors/stability-api-platform/README.md +2 -2
- package/connectors/stability-api-platform/src/api/client.test.ts +17 -12
- package/connectors/stability-api-platform/src/api/client.ts +4 -3
- package/connectors/stability-api-platform/src/api/index.ts +0 -1
- package/connectors/stability-api-platform/src/cli/index.ts +1 -1
- package/connectors/stability-api-platform/src/index.ts +0 -1
- package/connectors/stop-and-error/.env.example +1 -1
- package/connectors/stop-and-error/CLAUDE.md +1 -1
- package/connectors/stop-and-error/README.md +1 -1
- package/connectors/stop-and-error/src/api/client.test.ts +12 -8
- package/connectors/stop-and-error/src/api/client.ts +4 -3
- package/connectors/stop-and-error/src/cli/index.ts +2 -2
- package/connectors/stripe-financial-connections/.env.example +1 -1
- package/connectors/stripe-financial-connections/CLAUDE.md +2 -2
- package/connectors/stripe-financial-connections/src/api/client.test.ts +34 -0
- package/connectors/stripe-financial-connections/src/api/client.ts +4 -3
- package/connectors/stripe-financial-connections/src/cli/index.ts +1 -1
- package/connectors/sucuri-api-platform/.env.example +1 -1
- package/connectors/sucuri-api-platform/CLAUDE.md +1 -1
- package/connectors/sucuri-api-platform/README.md +2 -2
- package/connectors/sucuri-api-platform/src/api/client.test.ts +9 -7
- package/connectors/sucuri-api-platform/src/api/client.ts +4 -3
- package/connectors/sucuri-api-platform/src/api/index.ts +1 -1
- package/connectors/sucuri-api-platform/src/cli/index.ts +1 -1
- package/connectors/sucuri-api-platform/src/index.ts +1 -1
- package/connectors/tettra-api-platform/CLAUDE.md +1 -1
- package/connectors/tettra-api-platform/README.md +2 -2
- package/connectors/tettra-api-platform/src/api/client.test.ts +7 -8
- package/connectors/tettra-api-platform/src/api/client.ts +4 -3
- package/connectors/tettra-api-platform/src/api/index.ts +1 -1
- package/connectors/tettra-api-platform/src/cli/index.ts +1 -1
- package/connectors/tettra-api-platform/src/index.ts +1 -1
- package/connectors/together-api-platform/.env.example +1 -1
- package/connectors/together-api-platform/CLAUDE.md +1 -1
- package/connectors/together-api-platform/README.md +1 -1
- package/connectors/together-api-platform/src/api/client.test.ts +11 -7
- package/connectors/together-api-platform/src/api/client.ts +4 -4
- package/connectors/together-api-platform/src/api/index.ts +1 -1
- package/connectors/together-api-platform/src/cli/index.ts +1 -1
- package/connectors/together-api-platform/src/index.ts +1 -1
- package/connectors/travo-real-estate/CLAUDE.md +1 -1
- package/connectors/travo-real-estate/README.md +1 -1
- package/connectors/travo-real-estate/src/api/client.test.ts +20 -16
- package/connectors/travo-real-estate/src/api/client.ts +4 -3
- package/connectors/travo-real-estate/src/utils/config.ts +2 -4
- package/connectors/tray-api-platform/CLAUDE.md +1 -1
- package/connectors/tray-api-platform/src/api/client.test.ts +17 -13
- package/connectors/tray-api-platform/src/api/client.ts +4 -3
- package/connectors/tray-api-platform/src/api/index.ts +1 -1
- package/connectors/tray-api-platform/src/cli/index.ts +1 -1
- package/connectors/tray-api-platform/src/index.ts +0 -1
- package/connectors/turso-api-platform/CLAUDE.md +1 -1
- package/connectors/turso-api-platform/README.md +2 -2
- package/connectors/turso-api-platform/src/api/client.test.ts +17 -13
- package/connectors/turso-api-platform/src/api/client.ts +4 -3
- package/connectors/turso-api-platform/src/cli/index.ts +2 -2
- package/connectors/twilio-api-platform/CLAUDE.md +1 -1
- package/connectors/twilio-api-platform/src/api/client.test.ts +11 -11
- package/connectors/twilio-api-platform/src/api/client.ts +4 -3
- package/connectors/twilio-api-platform/src/api/index.ts +1 -1
- package/connectors/twilio-api-platform/src/cli/index.ts +1 -1
- package/connectors/twilio-api-platform/src/index.ts +1 -1
- package/connectors/tyk-api-platform/.env.example +1 -1
- package/connectors/tyk-api-platform/CLAUDE.md +2 -2
- package/connectors/tyk-api-platform/README.md +1 -1
- package/connectors/tyk-api-platform/src/api/client.test.ts +14 -15
- package/connectors/tyk-api-platform/src/api/client.ts +4 -3
- package/connectors/tyk-api-platform/src/api/index.ts +1 -1
- package/connectors/tyk-api-platform/src/cli/index.ts +1 -1
- package/connectors/tyk-api-platform/src/index.ts +1 -1
- package/connectors/vector-legal/.env.example +1 -1
- package/connectors/vector-legal/AGENTS.md +1 -1
- package/connectors/vector-legal/CLAUDE.md +1 -1
- package/connectors/vector-legal/README.md +1 -1
- package/connectors/vector-legal/src/api/client.test.ts +9 -5
- package/connectors/vector-legal/src/api/client.ts +4 -3
- package/connectors/vector-legal/src/api/index.ts +1 -1
- package/connectors/vector-legal/src/cli/index.ts +2 -2
- package/connectors/vector-legal/src/index.ts +0 -1
- package/connectors/vector-legal-api/CLAUDE.md +1 -1
- package/connectors/vector-legal-api/README.md +2 -2
- package/connectors/vector-legal-api/src/api/client.test.ts +12 -7
- package/connectors/vector-legal-api/src/api/client.ts +4 -3
- package/connectors/vector-legal-api/src/api/index.ts +1 -1
- package/connectors/vector-legal-api/src/cli/index.ts +1 -1
- package/connectors/vector-legal-api/src/index.ts +1 -2
- package/connectors/velum-data-quality/.env.example +1 -1
- package/connectors/velum-data-quality/CLAUDE.md +1 -1
- package/connectors/velum-data-quality/src/api/client.test.ts +15 -16
- package/connectors/velum-data-quality/src/api/client.ts +4 -3
- package/connectors/velum-data-quality/src/api/index.ts +1 -1
- package/connectors/velum-data-quality/src/cli/index.ts +1 -1
- package/connectors/velum-data-quality/src/index.ts +0 -1
- package/connectors/vercel-api-platform/.env.example +1 -1
- package/connectors/vercel-api-platform/CLAUDE.md +2 -2
- package/connectors/vercel-api-platform/README.md +2 -2
- package/connectors/vercel-api-platform/src/api/client.test.ts +27 -6
- package/connectors/vercel-api-platform/src/api/client.ts +4 -3
- package/connectors/vercel-api-platform/src/api/index.ts +1 -1
- package/connectors/vercel-api-platform/src/cli/index.ts +2 -2
- package/connectors/vercel-api-platform/src/index.ts +0 -1
- package/connectors/veriphone/README.md +2 -2
- package/connectors/wave-accounting/CLAUDE.md +1 -1
- package/connectors/wave-accounting/src/utils/auth.ts +1 -1
- package/connectors/weaviate-api-platform/CLAUDE.md +1 -1
- package/connectors/weaviate-api-platform/src/api/client.test.ts +32 -7
- package/connectors/weaviate-api-platform/src/api/client.ts +4 -3
- package/connectors/weaviate-api-platform/src/api/index.ts +1 -1
- package/connectors/weaviate-api-platform/src/cli/index.ts +1 -1
- package/connectors/weaviate-api-platform/src/index.ts +1 -1
- package/connectors/workflow-trigger/.env.example +1 -1
- package/connectors/workflow-trigger/CLAUDE.md +1 -1
- package/connectors/workflow-trigger/README.md +1 -1
- package/connectors/workflow-trigger/src/api/client.test.ts +10 -6
- package/connectors/workflow-trigger/src/api/client.ts +4 -3
- package/connectors/workflow-trigger/src/cli/index.ts +1 -1
- package/connectors/write-binary-file/CLAUDE.md +1 -1
- package/connectors/write-binary-file/README.md +1 -1
- package/connectors/write-binary-file/src/api/client.test.ts +16 -12
- package/connectors/write-binary-file/src/api/client.ts +4 -3
- package/connectors/write-binary-file/src/api/index.ts +1 -1
- package/connectors/write-binary-file/src/index.ts +1 -1
- package/connectors/wubookratechecker/src/api/client.test.ts +34 -0
- package/connectors/wubookratechecker/src/api/client.ts +3 -1
- package/connectors/wubookratechecker/src/api/index.ts +1 -1
- package/connectors/wubookratechecker/src/types/index.ts +1 -1
- package/connectors/xai-api-platform/.env.example +1 -1
- package/connectors/xai-api-platform/CLAUDE.md +1 -1
- package/connectors/xai-api-platform/README.md +1 -1
- package/connectors/xai-api-platform/src/api/client.test.ts +33 -8
- package/connectors/xai-api-platform/src/api/client.ts +4 -3
- package/connectors/xai-api-platform/src/api/index.ts +1 -1
- package/connectors/xai-api-platform/src/index.ts +1 -1
- package/connectors/xai-api-platform/src/utils/config.ts +2 -3
- package/connectors/zapier-api-platform/CLAUDE.md +1 -1
- package/connectors/zapier-api-platform/README.md +1 -1
- package/connectors/zapier-api-platform/src/api/client.test.ts +19 -14
- package/connectors/zapier-api-platform/src/api/client.ts +4 -3
- package/connectors/zapier-api-platform/src/api/index.ts +1 -1
- package/connectors/zapier-api-platform/src/cli/index.ts +1 -1
- package/connectors/zapier-api-platform/src/index.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -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('
|
|
194
|
+
info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
|
|
195
195
|
});
|
|
196
196
|
|
|
197
197
|
configCmd
|
|
@@ -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
|
|
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://
|
|
18
|
+
export STOP_AND_ERROR_BASE_URL=https://configured.example.com/v1
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Or use the CLI:
|
|
@@ -51,11 +51,11 @@ afterEach(() => {
|
|
|
51
51
|
describe('StopAndErrorClient', () => {
|
|
52
52
|
const mockConfig = {
|
|
53
53
|
apiKey: 'test-api-key-12345',
|
|
54
|
-
baseUrl: 'https://
|
|
54
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
test('throws when api key is missing', () => {
|
|
58
|
-
expect(() => new StopAndErrorClient({ apiKey: '' })).toThrow('API key is required');
|
|
58
|
+
expect(() => new StopAndErrorClient({ apiKey: '', baseUrl: 'https://configured.example.com/v1' })).toThrow('API key is required');
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
test('getApiKeyPreview masks long keys', () => {
|
|
@@ -65,7 +65,7 @@ describe('StopAndErrorClient', () => {
|
|
|
65
65
|
|
|
66
66
|
test('listErrors GET /errors with bearer auth', async () => {
|
|
67
67
|
const recorded = installFetch((req) => {
|
|
68
|
-
expect(req.url).toBe('https://
|
|
68
|
+
expect(req.url).toBe('https://configured.example.com/v1/errors?limit=10');
|
|
69
69
|
expect(req.method).toBe('GET');
|
|
70
70
|
expect(req.headers.authorization).toBe('Bearer test-api-key-12345');
|
|
71
71
|
return { data: [{ id: 'err_1', message: 'boom' }] };
|
|
@@ -78,7 +78,7 @@ describe('StopAndErrorClient', () => {
|
|
|
78
78
|
|
|
79
79
|
test('getError GET /errors/{id}', async () => {
|
|
80
80
|
const recorded = installFetch((req) => {
|
|
81
|
-
expect(req.url).toBe('https://
|
|
81
|
+
expect(req.url).toBe('https://configured.example.com/v1/errors/err_42');
|
|
82
82
|
expect(req.method).toBe('GET');
|
|
83
83
|
return { id: 'err_42', message: 'failed node' };
|
|
84
84
|
});
|
|
@@ -90,7 +90,7 @@ describe('StopAndErrorClient', () => {
|
|
|
90
90
|
|
|
91
91
|
test('createError POST /errors with body', async () => {
|
|
92
92
|
const recorded = installFetch((req) => {
|
|
93
|
-
expect(req.url).toBe('https://
|
|
93
|
+
expect(req.url).toBe('https://configured.example.com/v1/errors');
|
|
94
94
|
expect(req.method).toBe('POST');
|
|
95
95
|
expect(req.headers.authorization).toBe('Bearer test-api-key-12345');
|
|
96
96
|
const body = JSON.parse(req.body!);
|
|
@@ -106,7 +106,7 @@ describe('StopAndErrorClient', () => {
|
|
|
106
106
|
|
|
107
107
|
test('listEvents GET /events', async () => {
|
|
108
108
|
const recorded = installFetch((req) => {
|
|
109
|
-
expect(req.url).toBe('https://
|
|
109
|
+
expect(req.url).toBe('https://configured.example.com/v1/events?errorId=err_1');
|
|
110
110
|
expect(req.method).toBe('GET');
|
|
111
111
|
return { data: [{ id: 'evt_1', type: 'error.created' }] };
|
|
112
112
|
});
|
|
@@ -118,7 +118,7 @@ describe('StopAndErrorClient', () => {
|
|
|
118
118
|
|
|
119
119
|
test('search POST /search with query body', async () => {
|
|
120
120
|
const recorded = installFetch((req) => {
|
|
121
|
-
expect(req.url).toBe('https://
|
|
121
|
+
expect(req.url).toBe('https://configured.example.com/v1/search');
|
|
122
122
|
expect(req.method).toBe('POST');
|
|
123
123
|
const body = JSON.parse(req.body!);
|
|
124
124
|
expect(body.query).toBe('timeout');
|
|
@@ -147,7 +147,7 @@ describe('StopAndErrorClient', () => {
|
|
|
147
147
|
|
|
148
148
|
test('rawRequest supports custom path and method', async () => {
|
|
149
149
|
const recorded = installFetch((req) => {
|
|
150
|
-
expect(req.url).toBe('https://
|
|
150
|
+
expect(req.url).toBe('https://configured.example.com/v1/custom?foo=bar');
|
|
151
151
|
expect(req.method).toBe('PUT');
|
|
152
152
|
return { ok: true };
|
|
153
153
|
});
|
|
@@ -155,4 +155,8 @@ describe('StopAndErrorClient', () => {
|
|
|
155
155
|
await connector.rawRequest({ method: 'PUT', path: '/custom', params: { foo: 'bar' } });
|
|
156
156
|
expect(recorded).toHaveLength(1);
|
|
157
157
|
});
|
|
158
|
+
|
|
159
|
+
test('refuses to send without a configured base URL (no default endpoint)', () => {
|
|
160
|
+
expect(() => new StopAndErrorClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
|
|
161
|
+
});
|
|
158
162
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { StopAndErrorConfig } from '../types';
|
|
2
2
|
import { StopAndErrorApiError } from '../types';
|
|
3
3
|
|
|
4
|
-
const DEFAULT_BASE_URL = 'https://api.stop-and-error.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>;
|
|
@@ -19,7 +17,10 @@ export class StopAndErrorClient {
|
|
|
19
17
|
throw new Error('API key is required');
|
|
20
18
|
}
|
|
21
19
|
this.apiKey = config.apiKey;
|
|
22
|
-
|
|
20
|
+
if (!config.baseUrl) {
|
|
21
|
+
throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
|
|
22
|
+
}
|
|
23
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
|
|
@@ -167,7 +167,7 @@ configCmd
|
|
|
167
167
|
console.log(chalk.bold(`Active Profile: ${getCurrentProfile()}`));
|
|
168
168
|
info(`Config directory: ${getConfigDir()}`);
|
|
169
169
|
info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
|
|
170
|
-
info(`Base URL: ${getBaseUrl() || chalk.gray('
|
|
170
|
+
info(`Base URL: ${getBaseUrl() || chalk.gray('none configured')}`);
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
configCmd
|
|
@@ -187,7 +187,7 @@ statusCmd.action(() => {
|
|
|
187
187
|
console.log(chalk.bold('StopAndError Connector Status'));
|
|
188
188
|
info(`Profile: ${getCurrentProfile()}`);
|
|
189
189
|
info(`API Key: ${apiKey ? client!.getApiKeyPreview() : chalk.gray('not set')}`);
|
|
190
|
-
info(`Base URL: ${getBaseUrl() || '
|
|
190
|
+
info(`Base URL: ${getBaseUrl() || 'none configured'}`);
|
|
191
191
|
});
|
|
192
192
|
|
|
193
193
|
const errorsCmd = program.command('errors').description('Workflow error operations');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Stripe Financial Connections API credentials
|
|
2
2
|
STRIPE_FINANCIAL_CONNECTIONS_API_KEY=your-api-key-here
|
|
3
3
|
|
|
4
|
-
# Optional: override API base URL (default
|
|
4
|
+
# Optional: override API base URL (no default - must be configured)
|
|
5
5
|
# STRIPE_FINANCIAL_CONNECTIONS_BASE_URL=https://api.stripefinancialconnections.com/v1
|
|
@@ -54,7 +54,7 @@ connect-stripe-financial-connections raw --path /items --method GET
|
|
|
54
54
|
|
|
55
55
|
## Authentication
|
|
56
56
|
|
|
57
|
-
Bearer Token authentication. API base URL
|
|
57
|
+
Bearer Token authentication. API base URL has no default (must be configured).
|
|
58
58
|
|
|
59
59
|
## Data Storage
|
|
60
60
|
|
|
@@ -70,7 +70,7 @@ Profile JSON structure:
|
|
|
70
70
|
```json
|
|
71
71
|
{
|
|
72
72
|
"apiKey": "your-api-key",
|
|
73
|
-
"baseUrl": "
|
|
73
|
+
"baseUrl": "configured.example.com/v1"
|
|
74
74
|
}
|
|
75
75
|
```
|
|
76
76
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from 'bun:test';
|
|
2
|
+
import { StripeFinancialConnectionsClient } from './client';
|
|
3
|
+
|
|
4
|
+
const realFetch = globalThis.fetch;
|
|
5
|
+
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
globalThis.fetch = realFetch;
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('StripeFinancialConnectionsClient transport', () => {
|
|
11
|
+
test('refuses to send without a configured base URL (no default endpoint)', () => {
|
|
12
|
+
expect(() => new StripeFinancialConnectionsClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('sends the API key only to the configured base URL', async () => {
|
|
16
|
+
const recorded: string[] = [];
|
|
17
|
+
globalThis.fetch = (async (input: string | URL | Request, init?: RequestInit) => {
|
|
18
|
+
recorded.push(typeof input === 'string' ? input : input.toString());
|
|
19
|
+
return {
|
|
20
|
+
ok: true,
|
|
21
|
+
status: 200,
|
|
22
|
+
statusText: 'OK',
|
|
23
|
+
headers: new Headers({ 'content-type': 'application/json' }),
|
|
24
|
+
async text() { return JSON.stringify({ ok: true }); },
|
|
25
|
+
async json() { return { ok: true }; },
|
|
26
|
+
} as Response;
|
|
27
|
+
}) as typeof fetch;
|
|
28
|
+
const client = new StripeFinancialConnectionsClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
|
|
29
|
+
await client.request('/ping');
|
|
30
|
+
expect(recorded).toHaveLength(1);
|
|
31
|
+
expect(recorded[0].startsWith('https://configured.example.com/v1/')).toBe(true);
|
|
32
|
+
expect(recorded[0]).not.toContain('api.stripefinancialconnections.com');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { StripeFinancialConnectionsConfig, OutputFormat } from '../types';
|
|
2
2
|
import { StripeFinancialConnectionsApiError } from '../types';
|
|
3
3
|
|
|
4
|
-
export const DEFAULT_BASE_URL = 'https://api.stripefinancialconnections.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>;
|
|
@@ -20,7 +18,10 @@ export class StripeFinancialConnectionsClient {
|
|
|
20
18
|
throw new Error('API key is required');
|
|
21
19
|
}
|
|
22
20
|
this.apiKey = config.apiKey;
|
|
23
|
-
|
|
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;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
|
|
@@ -178,7 +178,7 @@ configCmd
|
|
|
178
178
|
console.log(chalk.bold(`Active Profile: ${getCurrentProfile()}`));
|
|
179
179
|
info(`Config directory: ${getConfigDir()}`);
|
|
180
180
|
info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
|
|
181
|
-
info(`Base URL: ${baseUrl || chalk.gray('
|
|
181
|
+
info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
|
|
182
182
|
});
|
|
183
183
|
|
|
184
184
|
configCmd
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Sucuri API Platform credentials (placeholder values only)
|
|
2
2
|
SUCURI_API_PLATFORM_API_KEY=your-api-key-here
|
|
3
3
|
|
|
4
|
-
# Optional: override the API base URL (default
|
|
4
|
+
# Optional: override the API base URL (no default - must be configured)
|
|
5
5
|
# SUCURI_API_PLATFORM_BASE_URL=https://api.sucuriapiplatform.com/v1
|
|
@@ -27,7 +27,7 @@ bun run dev raw request --path /items --method GET
|
|
|
27
27
|
|
|
28
28
|
## API Details
|
|
29
29
|
|
|
30
|
-
- **Base URL**:
|
|
30
|
+
- **Base URL**: no default (must be configured) (override via `SUCURI_API_PLATFORM_BASE_URL` or profile `baseUrl`)
|
|
31
31
|
- **Auth**: Bearer token (`Authorization: Bearer <api_key>`)
|
|
32
32
|
- **Endpoints**:
|
|
33
33
|
- `GET /items` — list items
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hasna/connect-sucuri-api-platform
|
|
2
2
|
|
|
3
|
-
TypeScript connector and CLI for the [Sucuri API Platform](
|
|
3
|
+
TypeScript connector and CLI for the [Sucuri API Platform](configured.example.com/v1).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ bun add @hasna/connect-sucuri-api-platform
|
|
|
13
13
|
```bash
|
|
14
14
|
export SUCURI_API_PLATFORM_API_KEY=your-api-key
|
|
15
15
|
# optional
|
|
16
|
-
export SUCURI_API_PLATFORM_BASE_URL=https://
|
|
16
|
+
export SUCURI_API_PLATFORM_BASE_URL=https://configured.example.com/v1
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Or use the CLI profile/config commands:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { describe, test, expect, mock, beforeEach, afterEach } from 'bun:test';
|
|
2
|
-
import { ConnectorClient
|
|
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://
|
|
8
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
describe('constructor', () => {
|
|
@@ -18,14 +18,16 @@ describe('ConnectorClient', () => {
|
|
|
18
18
|
expect(client).toBeInstanceOf(ConnectorClient);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
test('strips trailing slash from base URL', () => {
|
|
27
26
|
const client = new ConnectorClient({
|
|
28
27
|
apiKey: 'token',
|
|
28
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
29
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
30
|
+
baseUrl: 'https://configured.example.com/v1',
|
|
29
31
|
baseUrl: 'https://custom.example.com/v1/',
|
|
30
32
|
});
|
|
31
33
|
expect(client.getBaseUrl()).toBe('https://custom.example.com/v1');
|
|
@@ -72,7 +74,7 @@ describe('ConnectorClient', () => {
|
|
|
72
74
|
|
|
73
75
|
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
74
76
|
const [url, options] = (global.fetch as ReturnType<typeof mock>).mock.calls[0];
|
|
75
|
-
expect(url).toBe('https://
|
|
77
|
+
expect(url).toBe('https://configured.example.com/v1/items');
|
|
76
78
|
expect(options.method).toBe('GET');
|
|
77
79
|
expect(options.headers.Authorization).toBe('Bearer test-api-key-12345');
|
|
78
80
|
expect(options.headers.Accept).toBe('application/json');
|
|
@@ -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.sucuriapiplatform.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('Sucuri API Platform API key is required');
|
|
24
22
|
}
|
|
25
23
|
this.apiKey = key;
|
|
26
|
-
|
|
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?: Record<string, string | number | boolean | undefined>): string {
|
|
@@ -49,7 +49,7 @@ export class Connector {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export { ConnectorClient
|
|
52
|
+
export { ConnectorClient } from './client';
|
|
53
53
|
export { ItemsApi } from './items';
|
|
54
54
|
export { EventsApi } from './events';
|
|
55
55
|
export { SearchApi } from './search';
|
|
@@ -187,7 +187,7 @@ configCmd
|
|
|
187
187
|
console.log(chalk.bold(`Active Profile: ${profileName}`));
|
|
188
188
|
info(`Config directory: ${getConfigDir()}`);
|
|
189
189
|
info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
|
|
190
|
-
info(`Base URL: ${baseUrl || chalk.gray('
|
|
190
|
+
info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
|
|
191
191
|
});
|
|
192
192
|
|
|
193
193
|
configCmd
|
|
@@ -4,7 +4,7 @@ Tettra Api Platform connector — knowledge items, events, and search API.
|
|
|
4
4
|
|
|
5
5
|
## API Details
|
|
6
6
|
|
|
7
|
-
- **Base URL**:
|
|
7
|
+
- **Base URL**: no default (must be configured) (override via `TETTRA_API_PLATFORM_BASE_URL`)
|
|
8
8
|
- **Auth**: Bearer token (`Authorization: Bearer <api_key>`)
|
|
9
9
|
- **Endpoints**: `GET /items`, `POST /items`, `GET /items/:itemId`, `GET /events`, `POST /search`
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hasna/connect-tettra-api-platform
|
|
2
2
|
|
|
3
|
-
TypeScript connector and CLI for the [Tettra Api Platform](
|
|
3
|
+
TypeScript connector and CLI for the [Tettra Api Platform](configured.example.com/v1) API.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ bun install
|
|
|
13
13
|
```bash
|
|
14
14
|
export TETTRA_API_PLATFORM_API_KEY=your-api-key
|
|
15
15
|
# optional
|
|
16
|
-
export TETTRA_API_PLATFORM_BASE_URL=https://
|
|
16
|
+
export TETTRA_API_PLATFORM_BASE_URL=https://configured.example.com/v1
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Or use the CLI profile:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterEach, describe, expect, test } from 'bun:test';
|
|
2
|
-
import { ConnectorClient
|
|
2
|
+
import { ConnectorClient } from './client';
|
|
3
3
|
import { ItemsApi } from './items';
|
|
4
4
|
import { ConnectorApiError } from '../types';
|
|
5
5
|
|
|
@@ -51,9 +51,8 @@ describe('ConnectorClient', () => {
|
|
|
51
51
|
expect(() => new ConnectorClient({})).toThrow('API key or token is required');
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
expect(client.getBaseUrl()).toBe(DEFAULT_BASE_URL);
|
|
54
|
+
test('refuses to send without a configured base URL (no default endpoint)', () => {
|
|
55
|
+
expect(() => new ConnectorClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
|
|
57
56
|
});
|
|
58
57
|
|
|
59
58
|
test('uses custom base URL when provided', () => {
|
|
@@ -99,21 +98,21 @@ describe('ConnectorClient', () => {
|
|
|
99
98
|
describe('ItemsApi', () => {
|
|
100
99
|
test('listItems calls GET /items on default base URL', async () => {
|
|
101
100
|
const recorded = installFetch(() => [{ id: '1' }]);
|
|
102
|
-
const client = new ConnectorClient({ apiKey: 'key' });
|
|
101
|
+
const client = new ConnectorClient({ apiKey: 'key', baseUrl: 'https://configured.example.com/v1' });
|
|
103
102
|
const items = new ItemsApi(client);
|
|
104
103
|
const result = await items.list();
|
|
105
104
|
|
|
106
|
-
expect(recorded[0].url).toBe(
|
|
105
|
+
expect(recorded[0].url).toBe(`https://configured.example.com/v1/items`);
|
|
107
106
|
expect(recorded[0].headers.Authorization).toBe('Bearer key');
|
|
108
107
|
expect(result).toEqual([{ id: '1' }]);
|
|
109
108
|
});
|
|
110
109
|
|
|
111
110
|
test('getItem calls GET /items/:itemId with encoded id', async () => {
|
|
112
111
|
const recorded = installFetch(() => ({ id: 'abc/def' }));
|
|
113
|
-
const client = new ConnectorClient({ apiKey: 'key' });
|
|
112
|
+
const client = new ConnectorClient({ apiKey: 'key', baseUrl: 'https://configured.example.com/v1' });
|
|
114
113
|
const items = new ItemsApi(client);
|
|
115
114
|
await items.get('abc/def');
|
|
116
115
|
|
|
117
|
-
expect(recorded[0].url).toBe(
|
|
116
|
+
expect(recorded[0].url).toBe(`https://configured.example.com/v1/items/abc%2Fdef`);
|
|
118
117
|
});
|
|
119
118
|
});
|
|
@@ -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.tettraapiplatform.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>;
|
|
@@ -22,7 +20,10 @@ export class ConnectorClient {
|
|
|
22
20
|
throw new Error('API key or token is required');
|
|
23
21
|
}
|
|
24
22
|
this.apiKey = key;
|
|
25
|
-
|
|
23
|
+
if (!config.baseUrl) {
|
|
24
|
+
throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
|
|
25
|
+
}
|
|
26
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, '');
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
getBaseUrl(): string {
|
|
@@ -45,7 +45,7 @@ export class Connector {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export { ConnectorClient
|
|
48
|
+
export { ConnectorClient } from './client';
|
|
49
49
|
export { ItemsApi } from './items';
|
|
50
50
|
export { EventsApi } from './events';
|
|
51
51
|
export { SearchApi } from './search';
|
|
@@ -192,7 +192,7 @@ configCmd
|
|
|
192
192
|
console.log(chalk.bold(`Active Profile: ${profileName}`));
|
|
193
193
|
info(`Config directory: ${getConfigDir()}`);
|
|
194
194
|
info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
|
|
195
|
-
info(`Base URL: ${baseUrl || chalk.gray('
|
|
195
|
+
info(`Base URL: ${baseUrl || chalk.gray('none configured')}`);
|
|
196
196
|
});
|
|
197
197
|
|
|
198
198
|
configCmd
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Together Api Platform API credentials
|
|
2
2
|
TOGETHER_API_PLATFORM_API_KEY=your-api-key-here
|
|
3
3
|
|
|
4
|
-
# Optional: override API base URL (default
|
|
4
|
+
# Optional: override API base URL (no default - must be configured)
|
|
5
5
|
# TOGETHER_API_PLATFORM_BASE_URL=https://api.togetherapiplatform.com/v1
|
|
@@ -8,7 +8,7 @@ connect-together-api-platform is a TypeScript connector for the Together Api Pla
|
|
|
8
8
|
|
|
9
9
|
## API Reference
|
|
10
10
|
|
|
11
|
-
- **Base URL**:
|
|
11
|
+
- **Base URL**: no default (must be configured)
|
|
12
12
|
- **Auth**: Bearer token (`Authorization: Bearer <api_key>`)
|
|
13
13
|
- **API Docs**: https://www.ycombinator.com/companies/together-api-platform
|
|
14
14
|
|
|
@@ -21,7 +21,7 @@ bun install
|
|
|
21
21
|
```bash
|
|
22
22
|
export TOGETHER_API_PLATFORM_API_KEY=your-api-key
|
|
23
23
|
# optional
|
|
24
|
-
export TOGETHER_API_PLATFORM_BASE_URL=https://
|
|
24
|
+
export TOGETHER_API_PLATFORM_BASE_URL=https://configured.example.com/v1
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
Or use the CLI profile/config commands:
|
|
@@ -44,26 +44,26 @@ afterEach(() => {
|
|
|
44
44
|
describe('TogetherApiPlatformClient', () => {
|
|
45
45
|
test('listItems calls GET /v1/items with Bearer auth', async () => {
|
|
46
46
|
const recorded = installFetch(() => ({}));
|
|
47
|
-
const client = new TogetherApiPlatformClient({ apiKey: 'together-api-platform-key' });
|
|
47
|
+
const client = new TogetherApiPlatformClient({ apiKey: 'together-api-platform-key', baseUrl: 'https://configured.example.com/v1' });
|
|
48
48
|
await client.listItems();
|
|
49
|
-
expect(recorded[0].url).toBe('https://
|
|
49
|
+
expect(recorded[0].url).toBe('https://configured.example.com/v1/items');
|
|
50
50
|
expect(recorded[0].method).toBe('GET');
|
|
51
51
|
expect(authHeader(recorded)).toBe('Bearer together-api-platform-key');
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
test('getItem calls GET /v1/items/:itemId', async () => {
|
|
55
55
|
const recorded = installFetch(() => ({}));
|
|
56
|
-
const client = new TogetherApiPlatformClient({ apiKey: 'together-api-platform-key' });
|
|
56
|
+
const client = new TogetherApiPlatformClient({ apiKey: 'together-api-platform-key', baseUrl: 'https://configured.example.com/v1' });
|
|
57
57
|
await client.getItem('item-1');
|
|
58
|
-
expect(recorded[0].url).toBe('https://
|
|
58
|
+
expect(recorded[0].url).toBe('https://configured.example.com/v1/items/item-1');
|
|
59
59
|
expect(authHeader(recorded)).toBe('Bearer together-api-platform-key');
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
test('search posts to /v1/search', async () => {
|
|
63
63
|
const recorded = installFetch(() => ({}));
|
|
64
|
-
const client = new TogetherApiPlatformClient({ apiKey: 'test-key' });
|
|
64
|
+
const client = new TogetherApiPlatformClient({ apiKey: 'test-key', baseUrl: 'https://configured.example.com/v1' });
|
|
65
65
|
await client.search({ q: 'hello' });
|
|
66
|
-
expect(recorded[0].url).toBe('https://
|
|
66
|
+
expect(recorded[0].url).toBe('https://configured.example.com/v1/search');
|
|
67
67
|
expect(recorded[0].method).toBe('POST');
|
|
68
68
|
});
|
|
69
69
|
|
|
@@ -78,6 +78,10 @@ describe('TogetherApiPlatformClient', () => {
|
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
test('requires API key', () => {
|
|
81
|
-
expect(() => new TogetherApiPlatformClient({ apiKey: '' })).toThrow('API key is required');
|
|
81
|
+
expect(() => new TogetherApiPlatformClient({ apiKey: '', baseUrl: 'https://configured.example.com/v1' })).toThrow('API key is required');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('refuses to send without a configured base URL (no default endpoint)', () => {
|
|
85
|
+
expect(() => new TogetherApiPlatformClient({ apiKey: 'test-key' })).toThrow(/baseUrl/);
|
|
82
86
|
});
|
|
83
87
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { TogetherApiPlatformConfig } from '../types';
|
|
2
2
|
import { TogetherApiPlatformApiError } from '../types';
|
|
3
3
|
|
|
4
|
-
const DEFAULT_BASE_URL = 'https://api.togetherapiplatform.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>;
|
|
@@ -19,7 +17,10 @@ export class TogetherApiPlatformClient {
|
|
|
19
17
|
throw new Error('API key is required');
|
|
20
18
|
}
|
|
21
19
|
this.apiKey = config.apiKey;
|
|
22
|
-
|
|
20
|
+
if (!config.baseUrl) {
|
|
21
|
+
throw new Error('baseUrl is required: no default endpoint is configured; set baseUrl (profile, config, or the connector BASE_URL environment variable)');
|
|
22
|
+
}
|
|
23
|
+
this.baseUrl = config.baseUrl;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
|
|
@@ -140,4 +141,3 @@ export class TogetherApiPlatformClient {
|
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
export { DEFAULT_BASE_URL };
|