@s2-dev/streamstore 0.3.14 → 0.4.2
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/README.md +115 -2
- package/bin/mcp-server.js +50283 -0
- package/bin/mcp-server.js.map +347 -0
- package/funcs/accountCreateBasin.d.ts +2 -1
- package/funcs/accountCreateBasin.d.ts.map +1 -1
- package/funcs/accountCreateBasin.js +11 -6
- package/funcs/accountCreateBasin.js.map +1 -1
- package/funcs/accountDeleteBasin.d.ts +2 -1
- package/funcs/accountDeleteBasin.d.ts.map +1 -1
- package/funcs/accountDeleteBasin.js +11 -6
- package/funcs/accountDeleteBasin.js.map +1 -1
- package/funcs/accountGetBasinConfig.d.ts +2 -1
- package/funcs/accountGetBasinConfig.d.ts.map +1 -1
- package/funcs/accountGetBasinConfig.js +11 -6
- package/funcs/accountGetBasinConfig.js.map +1 -1
- package/funcs/accountListBasins.d.ts +2 -1
- package/funcs/accountListBasins.d.ts.map +1 -1
- package/funcs/accountListBasins.js +19 -6
- package/funcs/accountListBasins.js.map +1 -1
- package/funcs/accountReconfigureBasin.d.ts +2 -1
- package/funcs/accountReconfigureBasin.d.ts.map +1 -1
- package/funcs/accountReconfigureBasin.js +11 -6
- package/funcs/accountReconfigureBasin.js.map +1 -1
- package/funcs/basinCreateStream.d.ts +2 -1
- package/funcs/basinCreateStream.d.ts.map +1 -1
- package/funcs/basinCreateStream.js +11 -6
- package/funcs/basinCreateStream.js.map +1 -1
- package/funcs/basinDeleteStream.d.ts +2 -1
- package/funcs/basinDeleteStream.d.ts.map +1 -1
- package/funcs/basinDeleteStream.js +11 -6
- package/funcs/basinDeleteStream.js.map +1 -1
- package/funcs/basinGetStreamConfig.d.ts +2 -1
- package/funcs/basinGetStreamConfig.d.ts.map +1 -1
- package/funcs/basinGetStreamConfig.js +11 -6
- package/funcs/basinGetStreamConfig.js.map +1 -1
- package/funcs/basinListStreams.d.ts +2 -1
- package/funcs/basinListStreams.d.ts.map +1 -1
- package/funcs/basinListStreams.js +19 -6
- package/funcs/basinListStreams.js.map +1 -1
- package/funcs/basinReconfigureStream.d.ts +2 -1
- package/funcs/basinReconfigureStream.d.ts.map +1 -1
- package/funcs/basinReconfigureStream.js +11 -6
- package/funcs/basinReconfigureStream.js.map +1 -1
- package/funcs/streamAppend.d.ts +2 -1
- package/funcs/streamAppend.d.ts.map +1 -1
- package/funcs/streamAppend.js +11 -6
- package/funcs/streamAppend.js.map +1 -1
- package/funcs/streamCheckTail.d.ts +2 -1
- package/funcs/streamCheckTail.d.ts.map +1 -1
- package/funcs/streamCheckTail.js +11 -6
- package/funcs/streamCheckTail.js.map +1 -1
- package/funcs/streamRead.d.ts +2 -1
- package/funcs/streamRead.d.ts.map +1 -1
- package/funcs/streamRead.js +11 -6
- package/funcs/streamRead.js.map +1 -1
- package/hooks/types.d.ts +1 -0
- package/hooks/types.d.ts.map +1 -1
- package/index.extras.d.ts +38 -15
- package/index.extras.d.ts.map +1 -1
- package/index.extras.js +91 -46
- package/index.extras.js.map +1 -1
- package/jsr.json +1 -1
- package/lib/config.d.ts +6 -6
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +3 -3
- package/lib/config.js.map +1 -1
- package/lib/files.js.map +1 -1
- package/lib/primitives.d.ts +3 -0
- package/lib/primitives.d.ts.map +1 -1
- package/lib/primitives.js +7 -0
- package/lib/primitives.js.map +1 -1
- package/lib/sdks.d.ts +1 -1
- package/lib/sdks.d.ts.map +1 -1
- package/lib/security.d.ts.map +1 -1
- package/lib/security.js.map +1 -1
- package/mcp-server/build.d.mts.map +1 -0
- package/mcp-server/build.mjs +14 -0
- package/mcp-server/build.mjs.map +1 -0
- package/mcp-server/cli/start/command.d.ts +2 -0
- package/mcp-server/cli/start/command.d.ts.map +1 -0
- package/mcp-server/cli/start/command.js +129 -0
- package/mcp-server/cli/start/command.js.map +1 -0
- package/mcp-server/cli/start/impl.d.ts +17 -0
- package/mcp-server/cli/start/impl.d.ts.map +1 -0
- package/mcp-server/cli/start/impl.js +102 -0
- package/mcp-server/cli/start/impl.js.map +1 -0
- package/mcp-server/cli.d.ts +6 -0
- package/mcp-server/cli.d.ts.map +1 -0
- package/mcp-server/cli.js +10 -0
- package/mcp-server/cli.js.map +1 -0
- package/mcp-server/console-logger.d.ts +7 -0
- package/mcp-server/console-logger.d.ts.map +1 -0
- package/mcp-server/console-logger.js +59 -0
- package/mcp-server/console-logger.js.map +1 -0
- package/mcp-server/mcp-server.d.ts +2 -0
- package/mcp-server/mcp-server.d.ts.map +1 -0
- package/mcp-server/mcp-server.js +29 -0
- package/mcp-server/mcp-server.js.map +1 -0
- package/mcp-server/resources.d.ts +27 -0
- package/mcp-server/resources.d.ts.map +1 -0
- package/mcp-server/resources.js +51 -0
- package/mcp-server/resources.js.map +1 -0
- package/mcp-server/scopes.d.ts +3 -0
- package/mcp-server/scopes.d.ts.map +1 -0
- package/mcp-server/scopes.js +11 -0
- package/mcp-server/scopes.js.map +1 -0
- package/mcp-server/server.d.ts +12 -0
- package/mcp-server/server.d.ts.map +1 -0
- package/mcp-server/server.js +51 -0
- package/mcp-server/server.js.map +1 -0
- package/mcp-server/shared.d.ts +7 -0
- package/mcp-server/shared.d.ts.map +1 -0
- package/mcp-server/shared.js +98 -0
- package/mcp-server/shared.js.map +1 -0
- package/mcp-server/tools/accountCreateBasin.d.ts +8 -0
- package/mcp-server/tools/accountCreateBasin.d.ts.map +1 -0
- package/mcp-server/tools/accountCreateBasin.js +63 -0
- package/mcp-server/tools/accountCreateBasin.js.map +1 -0
- package/mcp-server/tools/accountDeleteBasin.d.ts +8 -0
- package/mcp-server/tools/accountDeleteBasin.d.ts.map +1 -0
- package/mcp-server/tools/accountDeleteBasin.js +62 -0
- package/mcp-server/tools/accountDeleteBasin.js.map +1 -0
- package/mcp-server/tools/accountGetBasinConfig.d.ts +8 -0
- package/mcp-server/tools/accountGetBasinConfig.d.ts.map +1 -0
- package/mcp-server/tools/accountGetBasinConfig.js +63 -0
- package/mcp-server/tools/accountGetBasinConfig.js.map +1 -0
- package/mcp-server/tools/accountListBasins.d.ts +8 -0
- package/mcp-server/tools/accountListBasins.d.ts.map +1 -0
- package/mcp-server/tools/accountListBasins.js +63 -0
- package/mcp-server/tools/accountListBasins.js.map +1 -0
- package/mcp-server/tools/accountReconfigureBasin.d.ts +8 -0
- package/mcp-server/tools/accountReconfigureBasin.d.ts.map +1 -0
- package/mcp-server/tools/accountReconfigureBasin.js +63 -0
- package/mcp-server/tools/accountReconfigureBasin.js.map +1 -0
- package/mcp-server/tools/basinCreateStream.d.ts +8 -0
- package/mcp-server/tools/basinCreateStream.d.ts.map +1 -0
- package/mcp-server/tools/basinCreateStream.js +63 -0
- package/mcp-server/tools/basinCreateStream.js.map +1 -0
- package/mcp-server/tools/basinDeleteStream.d.ts +8 -0
- package/mcp-server/tools/basinDeleteStream.d.ts.map +1 -0
- package/mcp-server/tools/basinDeleteStream.js +62 -0
- package/mcp-server/tools/basinDeleteStream.js.map +1 -0
- package/mcp-server/tools/basinGetStreamConfig.d.ts +8 -0
- package/mcp-server/tools/basinGetStreamConfig.d.ts.map +1 -0
- package/mcp-server/tools/basinGetStreamConfig.js +63 -0
- package/mcp-server/tools/basinGetStreamConfig.js.map +1 -0
- package/mcp-server/tools/basinListStreams.d.ts +8 -0
- package/mcp-server/tools/basinListStreams.d.ts.map +1 -0
- package/mcp-server/tools/basinListStreams.js +63 -0
- package/mcp-server/tools/basinListStreams.js.map +1 -0
- package/mcp-server/tools/basinReconfigureStream.d.ts +8 -0
- package/mcp-server/tools/basinReconfigureStream.d.ts.map +1 -0
- package/mcp-server/tools/basinReconfigureStream.js +63 -0
- package/mcp-server/tools/basinReconfigureStream.js.map +1 -0
- package/mcp-server/tools/streamAppend.d.ts +8 -0
- package/mcp-server/tools/streamAppend.d.ts.map +1 -0
- package/mcp-server/tools/streamAppend.js +65 -0
- package/mcp-server/tools/streamAppend.js.map +1 -0
- package/mcp-server/tools/streamCheckTail.d.ts +8 -0
- package/mcp-server/tools/streamCheckTail.d.ts.map +1 -0
- package/mcp-server/tools/streamCheckTail.js +65 -0
- package/mcp-server/tools/streamCheckTail.js.map +1 -0
- package/mcp-server/tools/streamRead.d.ts +8 -0
- package/mcp-server/tools/streamRead.d.ts.map +1 -0
- package/mcp-server/tools/streamRead.js +65 -0
- package/mcp-server/tools/streamRead.js.map +1 -0
- package/mcp-server/tools.d.ts +25 -0
- package/mcp-server/tools.d.ts.map +1 -0
- package/mcp-server/tools.js +74 -0
- package/mcp-server/tools.js.map +1 -0
- package/models/components/endpoints.d.ts +67 -0
- package/models/components/endpoints.d.ts.map +1 -0
- package/models/components/endpoints.js +126 -0
- package/models/components/endpoints.js.map +1 -0
- package/package.json +16 -2
- package/src/funcs/accountCreateBasin.ts +38 -7
- package/src/funcs/accountDeleteBasin.ts +39 -7
- package/src/funcs/accountGetBasinConfig.ts +38 -7
- package/src/funcs/accountListBasins.ts +49 -7
- package/src/funcs/accountReconfigureBasin.ts +38 -7
- package/src/funcs/basinCreateStream.ts +38 -7
- package/src/funcs/basinDeleteStream.ts +39 -7
- package/src/funcs/basinGetStreamConfig.ts +38 -7
- package/src/funcs/basinListStreams.ts +49 -7
- package/src/funcs/basinReconfigureStream.ts +38 -7
- package/src/funcs/streamAppend.ts +38 -7
- package/src/funcs/streamCheckTail.ts +38 -7
- package/src/funcs/streamRead.ts +38 -7
- package/src/hooks/types.ts +1 -0
- package/src/index.extras.ts +113 -49
- package/src/lib/config.ts +6 -7
- package/src/lib/files.ts +1 -1
- package/src/lib/primitives.ts +14 -0
- package/src/lib/sdks.ts +1 -1
- package/src/lib/security.ts +0 -1
- package/src/mcp-server/cli/start/command.ts +98 -0
- package/src/mcp-server/cli/start/impl.ts +131 -0
- package/src/mcp-server/cli.ts +13 -0
- package/src/mcp-server/console-logger.ts +71 -0
- package/src/mcp-server/mcp-server.ts +26 -0
- package/src/mcp-server/resources.ts +96 -0
- package/src/mcp-server/scopes.ts +10 -0
- package/src/mcp-server/server.ts +60 -0
- package/src/mcp-server/shared.ts +75 -0
- package/src/mcp-server/tools/accountCreateBasin.ts +36 -0
- package/src/mcp-server/tools/accountDeleteBasin.ts +34 -0
- package/src/mcp-server/tools/accountGetBasinConfig.ts +36 -0
- package/src/mcp-server/tools/accountListBasins.ts +36 -0
- package/src/mcp-server/tools/accountReconfigureBasin.ts +36 -0
- package/src/mcp-server/tools/basinCreateStream.ts +36 -0
- package/src/mcp-server/tools/basinDeleteStream.ts +34 -0
- package/src/mcp-server/tools/basinGetStreamConfig.ts +36 -0
- package/src/mcp-server/tools/basinListStreams.ts +36 -0
- package/src/mcp-server/tools/basinReconfigureStream.ts +36 -0
- package/src/mcp-server/tools/streamAppend.ts +38 -0
- package/src/mcp-server/tools/streamCheckTail.ts +38 -0
- package/src/mcp-server/tools/streamRead.ts +38 -0
- package/src/mcp-server/tools.ts +116 -0
- package/src/models/components/endpoints.ts +159 -0
- package/src/types/async.ts +68 -0
- package/types/async.d.ts +23 -0
- package/types/async.d.ts.map +1 -0
- package/types/async.js +44 -0
- package/types/async.js.map +1 -0
package/src/index.extras.ts
CHANGED
|
@@ -75,8 +75,29 @@ export type S2ClientConfig = {
|
|
|
75
75
|
httpClient?: HTTPClient;
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Override the client level configuration for a specific operation.
|
|
80
|
+
*
|
|
81
|
+
* @remarks
|
|
82
|
+
* Only `authToken` can be overridden for now.
|
|
83
|
+
*/
|
|
84
|
+
export type S2OperationConfig = {
|
|
85
|
+
authToken?: string;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Retry policy for appends.
|
|
90
|
+
*/
|
|
78
91
|
export enum AppendRetryPolicy {
|
|
92
|
+
/**
|
|
93
|
+
* Retry all eligible failures encountered during an append.
|
|
94
|
+
* This could result in append batches being duplicated on the stream.
|
|
95
|
+
*/
|
|
79
96
|
All,
|
|
97
|
+
/**
|
|
98
|
+
* Retry only failures with no side effects.
|
|
99
|
+
* Will not attempt to retry failures where it cannot be concluded whether an append may become durable, in order to prevent duplicates.
|
|
100
|
+
*/
|
|
80
101
|
NoSideEffects,
|
|
81
102
|
}
|
|
82
103
|
|
|
@@ -92,12 +113,9 @@ const defaultS2ClientConfig: S2ClientConfig = {
|
|
|
92
113
|
|
|
93
114
|
export class S2Client {
|
|
94
115
|
private config: S2ClientConfig;
|
|
95
|
-
private _account?: S2Account;
|
|
116
|
+
private _account?: S2Account;
|
|
96
117
|
|
|
97
118
|
get account(): S2Account {
|
|
98
|
-
// this.httpClient.addHook("beforeRequest", (request) => {
|
|
99
|
-
// if (this.config.userAgent) request.headers.set("User-Agent", this.config.userAgent);
|
|
100
|
-
// });
|
|
101
119
|
return (this._account ??= new S2Account(this.config));
|
|
102
120
|
}
|
|
103
121
|
|
|
@@ -117,12 +135,11 @@ class S2Account {
|
|
|
117
135
|
private readonly accountURLSuffx = "/v1alpha";
|
|
118
136
|
|
|
119
137
|
constructor(config: S2ClientConfig) {
|
|
120
|
-
|
|
121
|
-
config.
|
|
138
|
+
config.httpClient?.addHook("beforeRequest", (request) => {
|
|
139
|
+
if (config.userAgent !== undefined) {
|
|
122
140
|
request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
126
143
|
this._account = new InnerAccount({
|
|
127
144
|
...(config.authToken !== undefined && { bearerAuth: config.authToken }),
|
|
128
145
|
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout }),
|
|
@@ -131,57 +148,67 @@ class S2Account {
|
|
|
131
148
|
this.config = config;
|
|
132
149
|
}
|
|
133
150
|
|
|
134
|
-
get URL(): string
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
151
|
+
get URL(): string {
|
|
152
|
+
return `https://${ClientKind.toAuthority({ kind: "Account" }, this.config.endpoints ?? S2Endpoints.forCloud(S2Cloud.Aws))}${this.accountURLSuffx}`;
|
|
153
|
+
}
|
|
138
154
|
|
|
139
155
|
basin(basinName: string): S2Basin {
|
|
140
156
|
return new S2Basin(basinName, this.config);
|
|
141
157
|
}
|
|
142
158
|
|
|
159
|
+
private overrideConfig(config?: S2OperationConfig) {
|
|
160
|
+
this.config.httpClient?.addHook("beforeRequest", (request) => {
|
|
161
|
+
if (config?.authToken !== undefined) {
|
|
162
|
+
request.headers.set("Authorization", `Bearer ${config.authToken}`);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
143
167
|
async listBasins(
|
|
144
|
-
request?: ListBasinsRequest
|
|
168
|
+
request?: ListBasinsRequest,
|
|
169
|
+
opConfig?: S2OperationConfig,
|
|
145
170
|
): Promise<PageIterator<ListBasinsResponse, { cursor: string }>> {
|
|
146
|
-
|
|
171
|
+
this.overrideConfig(opConfig);
|
|
147
172
|
return retryWithExponentialBackoff(
|
|
148
|
-
() => this._account.listBasins(request ?? {},
|
|
173
|
+
() => this._account.listBasins(request ?? {}, {
|
|
174
|
+
serverURL: this.URL,
|
|
175
|
+
}),
|
|
149
176
|
this.config.maxRetries,
|
|
150
177
|
this.config.initialBackoffMs,
|
|
151
178
|
this.config.maxBackoffMs
|
|
152
179
|
);
|
|
153
180
|
}
|
|
154
181
|
|
|
155
|
-
async getBasinConfig(basin: string): Promise<BasinConfig | undefined> {
|
|
182
|
+
async getBasinConfig(basin: string, opConfig?: S2OperationConfig): Promise<BasinConfig | undefined> {
|
|
183
|
+
this.overrideConfig(opConfig);
|
|
156
184
|
const _request: GetBasinConfigRequest = { basin };
|
|
157
|
-
const url = this.URL;
|
|
158
185
|
return retryWithExponentialBackoff(
|
|
159
|
-
() => this._account.getBasinConfig(_request,
|
|
186
|
+
() => this._account.getBasinConfig(_request, { serverURL: this.URL }),
|
|
160
187
|
this.config.maxRetries,
|
|
161
188
|
this.config.initialBackoffMs,
|
|
162
189
|
this.config.maxBackoffMs
|
|
163
190
|
);
|
|
164
191
|
}
|
|
165
192
|
|
|
166
|
-
async createBasin(basin: string, request?: CreateBasinRequest): Promise<BasinInfo | undefined> {
|
|
193
|
+
async createBasin(basin: string, request?: CreateBasinRequest, opConfig?: S2OperationConfig): Promise<BasinInfo | undefined> {
|
|
194
|
+
this.overrideConfig(opConfig);
|
|
167
195
|
const _request: CreateBasinRequestInner = {
|
|
168
196
|
basin,
|
|
169
197
|
s2RequestToken: genS2RequestToken(),
|
|
170
198
|
createBasinRequest: request ?? {},
|
|
171
199
|
};
|
|
172
|
-
const url = this.URL;
|
|
173
200
|
return retryWithExponentialBackoff(
|
|
174
|
-
() => this._account.createBasin(_request,
|
|
201
|
+
() => this._account.createBasin(_request, { serverURL: this.URL }),
|
|
175
202
|
this.config.maxRetries,
|
|
176
203
|
this.config.initialBackoffMs,
|
|
177
204
|
this.config.maxBackoffMs
|
|
178
205
|
);
|
|
179
206
|
}
|
|
180
207
|
|
|
181
|
-
async deleteBasin(basin: string, if_exists?: boolean): Promise<void> {
|
|
182
|
-
|
|
208
|
+
async deleteBasin(basin: string, if_exists?: boolean, opConfig?: S2OperationConfig): Promise<void> {
|
|
209
|
+
this.overrideConfig(opConfig);
|
|
183
210
|
const response = await retryWithExponentialBackoff(
|
|
184
|
-
() => accountDeleteBasin(this._account, { basin },
|
|
211
|
+
() => accountDeleteBasin(this._account, { basin }, { serverURL: this.URL }),
|
|
185
212
|
this.config.maxRetries,
|
|
186
213
|
this.config.initialBackoffMs,
|
|
187
214
|
this.config.maxBackoffMs
|
|
@@ -191,11 +218,11 @@ class S2Account {
|
|
|
191
218
|
return;
|
|
192
219
|
}
|
|
193
220
|
|
|
194
|
-
async reconfigureBasin(basin: string, config: BasinConfig): Promise<BasinConfig | undefined> {
|
|
195
|
-
|
|
221
|
+
async reconfigureBasin(basin: string, config: BasinConfig, opConfig?: S2OperationConfig): Promise<BasinConfig | undefined> {
|
|
222
|
+
this.overrideConfig(opConfig);
|
|
196
223
|
const _request: ReconfigureBasinRequest = { basin, basinConfig: config };
|
|
197
224
|
return retryWithExponentialBackoff(
|
|
198
|
-
() => this._account.reconfigureBasin(_request,
|
|
225
|
+
() => this._account.reconfigureBasin(_request, { serverURL: this.URL }),
|
|
199
226
|
this.config.maxRetries,
|
|
200
227
|
this.config.initialBackoffMs,
|
|
201
228
|
this.config.maxBackoffMs
|
|
@@ -209,21 +236,25 @@ class S2Basin {
|
|
|
209
236
|
private basinName: string;
|
|
210
237
|
private config: S2ClientConfig;
|
|
211
238
|
private clientKind: ClientKind;
|
|
212
|
-
private readonly basinURLSuffx = "/v1alpha";
|
|
239
|
+
private readonly basinURLSuffx = "/v1alpha";
|
|
213
240
|
|
|
214
241
|
private get URL(): string {
|
|
215
242
|
return `https://${ClientKind.toAuthority(this.clientKind, this.config.endpoints ?? S2Endpoints.forCloud(S2Cloud.Aws))}${this.basinURLSuffx}`;
|
|
216
243
|
}
|
|
217
244
|
|
|
218
245
|
constructor(basinName: string, config: S2ClientConfig) {
|
|
219
|
-
|
|
220
|
-
config.
|
|
246
|
+
config.httpClient?.addHook("beforeRequest", (request) => {
|
|
247
|
+
if (config.userAgent !== undefined) {
|
|
221
248
|
request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
|
|
222
|
-
}
|
|
223
|
-
|
|
249
|
+
}
|
|
250
|
+
if (config.endpoints?.basin?.kind === "Direct") {
|
|
251
|
+
request.headers.set("s2-basin", basinName);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
224
254
|
this._basin = new InnerBasin({
|
|
225
255
|
...(config.authToken !== undefined && { bearerAuth: config.authToken }),
|
|
226
|
-
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout })
|
|
256
|
+
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout }),
|
|
257
|
+
...(config.httpClient !== undefined && { httpClient: config.httpClient }),
|
|
227
258
|
});
|
|
228
259
|
this.config = config;
|
|
229
260
|
this.clientKind = { kind: "Basin" as const, basin: basinName };
|
|
@@ -234,18 +265,32 @@ class S2Basin {
|
|
|
234
265
|
return (this._stream ??= new Stream(this.basinName, streamName, this.config));
|
|
235
266
|
}
|
|
236
267
|
|
|
268
|
+
private overrideConfig(config?: S2OperationConfig) {
|
|
269
|
+
this.config.httpClient?.addHook("beforeRequest", (request) => {
|
|
270
|
+
if (config?.authToken !== undefined) {
|
|
271
|
+
request.headers.set("Authorization", `Bearer ${config.authToken}`);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
237
276
|
async listStreams(
|
|
238
|
-
request
|
|
277
|
+
request?: ListStreamsRequest,
|
|
278
|
+
opConfig?: S2OperationConfig,
|
|
239
279
|
): Promise<PageIterator<ListStreamsResponse, { cursor: string }>> {
|
|
280
|
+
this.overrideConfig(opConfig);
|
|
240
281
|
return retryWithExponentialBackoff(
|
|
241
|
-
() => this._basin.listStreams(request, { serverURL: this.URL }),
|
|
282
|
+
() => this._basin.listStreams(request ?? {}, { serverURL: this.URL }),
|
|
242
283
|
this.config.maxRetries,
|
|
243
284
|
this.config.initialBackoffMs,
|
|
244
285
|
this.config.maxBackoffMs
|
|
245
286
|
);
|
|
246
287
|
}
|
|
247
288
|
|
|
248
|
-
async getStreamConfig(
|
|
289
|
+
async getStreamConfig(
|
|
290
|
+
stream: string,
|
|
291
|
+
opConfig?: S2OperationConfig
|
|
292
|
+
): Promise<StreamConfig | undefined> {
|
|
293
|
+
this.overrideConfig(opConfig);
|
|
249
294
|
return retryWithExponentialBackoff(
|
|
250
295
|
() => this._basin.getStreamConfig({ stream }, { serverURL: this.URL }),
|
|
251
296
|
this.config.maxRetries,
|
|
@@ -254,7 +299,8 @@ class S2Basin {
|
|
|
254
299
|
);
|
|
255
300
|
}
|
|
256
301
|
|
|
257
|
-
async createStream(stream: string, request?: CreateStreamRequest): Promise<StreamInfo | undefined> {
|
|
302
|
+
async createStream(stream: string, request?: CreateStreamRequest, opConfig?: S2OperationConfig): Promise<StreamInfo | undefined> {
|
|
303
|
+
this.overrideConfig(opConfig);
|
|
258
304
|
const _request: CreateStreamRequestInner = {
|
|
259
305
|
stream,
|
|
260
306
|
s2RequestToken: genS2RequestToken(),
|
|
@@ -268,7 +314,8 @@ class S2Basin {
|
|
|
268
314
|
);
|
|
269
315
|
}
|
|
270
316
|
|
|
271
|
-
async deleteStream(stream: string, if_exists?: boolean): Promise<void | undefined> {
|
|
317
|
+
async deleteStream(stream: string, if_exists?: boolean, opConfig?: S2OperationConfig): Promise<void | undefined> {
|
|
318
|
+
this.overrideConfig(opConfig);
|
|
272
319
|
const response = await retryWithExponentialBackoff(
|
|
273
320
|
() => basinDeleteStream(this._basin, { stream }, { serverURL: this.URL }),
|
|
274
321
|
this.config.maxRetries,
|
|
@@ -280,7 +327,8 @@ class S2Basin {
|
|
|
280
327
|
return;
|
|
281
328
|
}
|
|
282
329
|
|
|
283
|
-
async reconfigureStream(stream: string, config: StreamConfig): Promise<StreamConfig> {
|
|
330
|
+
async reconfigureStream(stream: string, config: StreamConfig, opConfig?: S2OperationConfig): Promise<StreamConfig> {
|
|
331
|
+
this.overrideConfig(opConfig);
|
|
284
332
|
return retryWithExponentialBackoff(
|
|
285
333
|
() => this._basin.reconfigureStream({ stream, streamConfig: config }, { serverURL: this.URL }),
|
|
286
334
|
this.config.maxRetries,
|
|
@@ -301,28 +349,42 @@ class Stream {
|
|
|
301
349
|
return `https://${ClientKind.toAuthority(this.clientKind, this.config.endpoints ?? S2Endpoints.forCloud(S2Cloud.Aws))}${this.basinURLSuffx}`;
|
|
302
350
|
}
|
|
303
351
|
|
|
352
|
+
private overrideConfig(config?: S2OperationConfig) {
|
|
353
|
+
this.config.httpClient?.addHook("beforeRequest", (request) => {
|
|
354
|
+
if (config?.authToken !== undefined) {
|
|
355
|
+
request.headers.set("Authorization", `Bearer ${config.authToken}`);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
|
|
304
360
|
constructor(basinName: string, streamName: string, config: S2ClientConfig) {
|
|
305
361
|
this.config = config;
|
|
306
362
|
this.clientKind = { kind: "Basin" as const, basin: basinName };
|
|
307
363
|
this.streamName = streamName;
|
|
308
|
-
|
|
309
|
-
config.
|
|
364
|
+
config.httpClient?.addHook("beforeRequest", (request) => {
|
|
365
|
+
if (config.userAgent !== undefined) {
|
|
310
366
|
request.headers.set("user-agent", config.userAgent ?? "s2-sdk-typescript");
|
|
311
|
-
}
|
|
312
|
-
|
|
367
|
+
}
|
|
368
|
+
if (config.endpoints?.basin?.kind === "Direct") {
|
|
369
|
+
request.headers.set("s2-basin", basinName);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
313
372
|
this._stream = new InnerStream({
|
|
314
373
|
...(config.authToken !== undefined && { bearerAuth: config.authToken }),
|
|
315
|
-
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout })
|
|
374
|
+
...(config.requestTimeout !== undefined && { timeoutMs: config.requestTimeout }),
|
|
375
|
+
...(config.httpClient !== undefined && { httpClient: config.httpClient })
|
|
316
376
|
});
|
|
317
377
|
}
|
|
318
378
|
|
|
319
|
-
async checkTail(): Promise<CheckTailResponse> {
|
|
379
|
+
async checkTail(opConfig?: S2OperationConfig): Promise<CheckTailResponse> {
|
|
380
|
+
this.overrideConfig(opConfig);
|
|
320
381
|
return (
|
|
321
382
|
await this._stream.checkTail({ stream: this.streamName }, { serverURL: this.basinURL })
|
|
322
383
|
);
|
|
323
384
|
}
|
|
324
385
|
|
|
325
|
-
async append(request: AppendRequest): Promise<AppendOutput> {
|
|
386
|
+
async append(request: AppendRequest, opConfig?: S2OperationConfig): Promise<AppendOutput> {
|
|
387
|
+
this.overrideConfig(opConfig);
|
|
326
388
|
switch (this.config.appedRetryPolicy) {
|
|
327
389
|
case AppendRetryPolicy.All:
|
|
328
390
|
case undefined:
|
|
@@ -343,13 +405,15 @@ class Stream {
|
|
|
343
405
|
}
|
|
344
406
|
}
|
|
345
407
|
|
|
346
|
-
async read(request: ReadRequest): Promise<Output> {
|
|
408
|
+
async read(request: ReadRequest, opConfig?: S2OperationConfig): Promise<Output> {
|
|
409
|
+
this.overrideConfig(opConfig);
|
|
347
410
|
return (
|
|
348
411
|
await this._stream.read({ ...request, stream: this.streamName }, { serverURL: this.basinURL }) as Output
|
|
349
412
|
);
|
|
350
413
|
}
|
|
351
414
|
|
|
352
|
-
async *readStream(request: ReadRequest): AsyncGenerator<ReadResponse, void, undefined> {
|
|
415
|
+
async *readStream(request: ReadRequest, opConfig?: S2OperationConfig): AsyncGenerator<ReadResponse, void, undefined> {
|
|
416
|
+
this.overrideConfig(opConfig);
|
|
353
417
|
let currentRequest: ReadRequest = { ...request };
|
|
354
418
|
let initialBackoffMs = this.config.initialBackoffMs ?? 100;
|
|
355
419
|
const maxBackoffMs = 5000;
|
package/src/lib/config.ts
CHANGED
|
@@ -15,17 +15,17 @@ export const ServerList = [
|
|
|
15
15
|
] as const;
|
|
16
16
|
|
|
17
17
|
export type SDKOptions = {
|
|
18
|
-
bearerAuth?: string | (() => Promise<string>);
|
|
18
|
+
bearerAuth?: string | (() => Promise<string>) | undefined;
|
|
19
19
|
|
|
20
20
|
httpClient?: HTTPClient;
|
|
21
21
|
/**
|
|
22
22
|
* Allows overriding the default server used by the SDK
|
|
23
23
|
*/
|
|
24
|
-
serverIdx?: number;
|
|
24
|
+
serverIdx?: number | undefined;
|
|
25
25
|
/**
|
|
26
26
|
* Allows overriding the default server URL used by the SDK
|
|
27
27
|
*/
|
|
28
|
-
serverURL?: string;
|
|
28
|
+
serverURL?: string | undefined;
|
|
29
29
|
/**
|
|
30
30
|
* Allows overriding the default retry config used by the SDK
|
|
31
31
|
*/
|
|
@@ -54,8 +54,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
|
|
|
54
54
|
export const SDK_METADATA = {
|
|
55
55
|
language: "typescript",
|
|
56
56
|
openapiDocVersion: "1.0.0",
|
|
57
|
-
sdkVersion: "0.
|
|
58
|
-
genVersion: "2.
|
|
59
|
-
userAgent:
|
|
60
|
-
"speakeasy-sdk/typescript 0.3.14 2.506.0 1.0.0 @s2-dev/streamstore",
|
|
57
|
+
sdkVersion: "0.4.2",
|
|
58
|
+
genVersion: "2.529.2",
|
|
59
|
+
userAgent: "speakeasy-sdk/typescript 0.4.2 2.529.2 1.0.0 @s2-dev/streamstore",
|
|
61
60
|
} as const;
|
package/src/lib/files.ts
CHANGED
package/src/lib/primitives.ts
CHANGED
|
@@ -134,3 +134,17 @@ export function compactMap<T>(
|
|
|
134
134
|
|
|
135
135
|
return out;
|
|
136
136
|
}
|
|
137
|
+
|
|
138
|
+
export function allRequired<V extends Record<string, unknown>>(
|
|
139
|
+
v: V,
|
|
140
|
+
):
|
|
141
|
+
| {
|
|
142
|
+
[K in keyof V]: NonNullable<V[K]>;
|
|
143
|
+
}
|
|
144
|
+
| undefined {
|
|
145
|
+
if (Object.values(v).every((x) => x == null)) {
|
|
146
|
+
return void 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return v as ReturnType<typeof allRequired<V>>;
|
|
150
|
+
}
|
package/src/lib/sdks.ts
CHANGED
|
@@ -79,7 +79,7 @@ export class ClientSDK {
|
|
|
79
79
|
readonly #httpClient: HTTPClient;
|
|
80
80
|
readonly #hooks: SDKHooks;
|
|
81
81
|
readonly #logger?: Logger | undefined;
|
|
82
|
-
|
|
82
|
+
public readonly _baseURL: URL | null;
|
|
83
83
|
public readonly _options: SDKOptions & { hooks?: SDKHooks };
|
|
84
84
|
|
|
85
85
|
constructor(options: SDKOptions = {}) {
|
package/src/lib/security.ts
CHANGED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { buildCommand } from "@stricli/core";
|
|
6
|
+
import { numberParser } from "@stricli/core";
|
|
7
|
+
import * as z from "zod";
|
|
8
|
+
import { consoleLoggerLevels } from "../../console-logger.js";
|
|
9
|
+
import { mcpScopes } from "../../scopes.js";
|
|
10
|
+
|
|
11
|
+
export const startCommand = buildCommand({
|
|
12
|
+
loader: async () => {
|
|
13
|
+
const { main } = await import("./impl.js");
|
|
14
|
+
return main;
|
|
15
|
+
},
|
|
16
|
+
parameters: {
|
|
17
|
+
flags: {
|
|
18
|
+
transport: {
|
|
19
|
+
kind: "enum",
|
|
20
|
+
brief: "The transport to use for communicating with the server",
|
|
21
|
+
default: "stdio",
|
|
22
|
+
values: ["stdio", "sse"],
|
|
23
|
+
},
|
|
24
|
+
port: {
|
|
25
|
+
kind: "parsed",
|
|
26
|
+
brief: "The port to use when the SSE transport is enabled",
|
|
27
|
+
default: "2718",
|
|
28
|
+
parse: (val: string) =>
|
|
29
|
+
z.coerce.number().int().gte(0).lt(65536).parse(val),
|
|
30
|
+
},
|
|
31
|
+
...(mcpScopes.length
|
|
32
|
+
? {
|
|
33
|
+
scope: {
|
|
34
|
+
kind: "enum",
|
|
35
|
+
brief:
|
|
36
|
+
"Mount tools/resources that match given scope (repeatable flag)",
|
|
37
|
+
values: mcpScopes,
|
|
38
|
+
variadic: true,
|
|
39
|
+
optional: true,
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
: {}),
|
|
43
|
+
"bearer-auth": {
|
|
44
|
+
kind: "parsed",
|
|
45
|
+
brief: "Sets the bearerAuth auth field for the API",
|
|
46
|
+
optional: true,
|
|
47
|
+
parse: (value) => {
|
|
48
|
+
return z.string().parse(value);
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
"server-url": {
|
|
52
|
+
kind: "parsed",
|
|
53
|
+
brief: "Overrides the default server URL used by the SDK",
|
|
54
|
+
optional: true,
|
|
55
|
+
parse: (value) => new URL(value).toString(),
|
|
56
|
+
},
|
|
57
|
+
"server-index": {
|
|
58
|
+
kind: "parsed",
|
|
59
|
+
brief: "Selects a predefined server used by the SDK",
|
|
60
|
+
optional: true,
|
|
61
|
+
parse: numberParser,
|
|
62
|
+
},
|
|
63
|
+
"log-level": {
|
|
64
|
+
kind: "enum",
|
|
65
|
+
brief: "The log level to use for the server",
|
|
66
|
+
default: "info",
|
|
67
|
+
values: consoleLoggerLevels,
|
|
68
|
+
},
|
|
69
|
+
env: {
|
|
70
|
+
kind: "parsed",
|
|
71
|
+
brief: "Environment variables made available to the server",
|
|
72
|
+
optional: true,
|
|
73
|
+
variadic: true,
|
|
74
|
+
parse: (val: string) => {
|
|
75
|
+
const sepIdx = val.indexOf("=");
|
|
76
|
+
if (sepIdx === -1) {
|
|
77
|
+
throw new Error("Invalid environment variable format");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const key = val.slice(0, sepIdx);
|
|
81
|
+
const value = val.slice(sepIdx + 1);
|
|
82
|
+
|
|
83
|
+
return [
|
|
84
|
+
z.string().nonempty({
|
|
85
|
+
message: "Environment variable key must be a non-empty string",
|
|
86
|
+
}).parse(key),
|
|
87
|
+
z.string().nonempty({
|
|
88
|
+
message: "Environment variable value must be a non-empty string",
|
|
89
|
+
}).parse(value),
|
|
90
|
+
] satisfies [string, string];
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
docs: {
|
|
96
|
+
brief: "Run the Model Context Protocol server",
|
|
97
|
+
},
|
|
98
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
6
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
+
import express from "express";
|
|
8
|
+
import { SDKOptions } from "../../../lib/config.js";
|
|
9
|
+
import { LocalContext } from "../../cli.js";
|
|
10
|
+
import {
|
|
11
|
+
ConsoleLoggerLevel,
|
|
12
|
+
createConsoleLogger,
|
|
13
|
+
} from "../../console-logger.js";
|
|
14
|
+
import { MCPScope } from "../../scopes.js";
|
|
15
|
+
import { createMCPServer } from "../../server.js";
|
|
16
|
+
|
|
17
|
+
interface StartCommandFlags {
|
|
18
|
+
readonly transport: "stdio" | "sse";
|
|
19
|
+
readonly port: number;
|
|
20
|
+
readonly scope?: MCPScope[];
|
|
21
|
+
readonly "bearer-auth"?: string | undefined;
|
|
22
|
+
readonly "server-url"?: string;
|
|
23
|
+
readonly "server-index"?: SDKOptions["serverIdx"];
|
|
24
|
+
readonly "log-level": ConsoleLoggerLevel;
|
|
25
|
+
readonly env?: [string, string][];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function main(this: LocalContext, flags: StartCommandFlags) {
|
|
29
|
+
flags.env?.forEach(([key, value]) => {
|
|
30
|
+
process.env[key] = value;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
switch (flags.transport) {
|
|
34
|
+
case "stdio":
|
|
35
|
+
await startStdio(flags);
|
|
36
|
+
break;
|
|
37
|
+
case "sse":
|
|
38
|
+
await startSSE(flags);
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
throw new Error(`Invalid transport: ${flags.transport}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function startStdio(flags: StartCommandFlags) {
|
|
46
|
+
const logger = createConsoleLogger(flags["log-level"]);
|
|
47
|
+
const transport = new StdioServerTransport();
|
|
48
|
+
const server = createMCPServer({
|
|
49
|
+
logger,
|
|
50
|
+
scopes: flags.scope,
|
|
51
|
+
...{ bearerAuth: flags["bearer-auth"] },
|
|
52
|
+
serverURL: flags["server-url"],
|
|
53
|
+
serverIdx: flags["server-index"],
|
|
54
|
+
});
|
|
55
|
+
await server.connect(transport);
|
|
56
|
+
|
|
57
|
+
const abort = async () => {
|
|
58
|
+
await server.close();
|
|
59
|
+
process.exit(0);
|
|
60
|
+
};
|
|
61
|
+
process.on("SIGTERM", abort);
|
|
62
|
+
process.on("SIGINT", abort);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function startSSE(flags: StartCommandFlags) {
|
|
66
|
+
const logger = createConsoleLogger(flags["log-level"]);
|
|
67
|
+
const app = express();
|
|
68
|
+
const mcpServer = createMCPServer({
|
|
69
|
+
logger,
|
|
70
|
+
scopes: flags.scope,
|
|
71
|
+
...{ bearerAuth: flags["bearer-auth"] },
|
|
72
|
+
serverURL: flags["server-url"],
|
|
73
|
+
serverIdx: flags["server-index"],
|
|
74
|
+
});
|
|
75
|
+
let transport: SSEServerTransport | undefined;
|
|
76
|
+
const controller = new AbortController();
|
|
77
|
+
|
|
78
|
+
app.get("/sse", async (_req, res) => {
|
|
79
|
+
transport = new SSEServerTransport("/message", res);
|
|
80
|
+
|
|
81
|
+
await mcpServer.connect(transport);
|
|
82
|
+
|
|
83
|
+
mcpServer.server.onclose = async () => {
|
|
84
|
+
res.end();
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
app.post("/message", async (req, res) => {
|
|
89
|
+
if (!transport) {
|
|
90
|
+
throw new Error("Server transport not initialized");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
await transport.handlePostMessage(req, res);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const httpServer = app.listen(flags.port, "0.0.0.0", () => {
|
|
97
|
+
const ha = httpServer.address();
|
|
98
|
+
const host = typeof ha === "string" ? ha : `${ha?.address}:${ha?.port}`;
|
|
99
|
+
logger.info("MCP HTTP server started", { host });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
let closing = false;
|
|
103
|
+
controller.signal.addEventListener("abort", async () => {
|
|
104
|
+
if (closing) {
|
|
105
|
+
logger.info("Received second signal. Forcing shutdown.");
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
closing = true;
|
|
109
|
+
|
|
110
|
+
logger.info("Shutting down MCP server");
|
|
111
|
+
|
|
112
|
+
await mcpServer.close();
|
|
113
|
+
|
|
114
|
+
logger.info("Shutting down HTTP server");
|
|
115
|
+
|
|
116
|
+
const timer = setTimeout(() => {
|
|
117
|
+
logger.info("Forcing shutdown");
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}, 5000);
|
|
120
|
+
|
|
121
|
+
httpServer.close(() => {
|
|
122
|
+
clearTimeout(timer);
|
|
123
|
+
logger.info("Graceful shutdown complete");
|
|
124
|
+
process.exit(0);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const abort = () => controller.abort();
|
|
129
|
+
process.on("SIGTERM", abort);
|
|
130
|
+
process.on("SIGINT", abort);
|
|
131
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CommandContext, StricliProcess } from "@stricli/core";
|
|
6
|
+
|
|
7
|
+
export interface LocalContext extends CommandContext {
|
|
8
|
+
readonly process: StricliProcess;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function buildContext(process: NodeJS.Process): LocalContext {
|
|
12
|
+
return { process: process as StricliProcess };
|
|
13
|
+
}
|