Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 40 additions & 29 deletions packages/plugins/google-discovery/src/sdk/invoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,34 @@ const replacePathParameters = (input: {
pathTemplate: string;
args: Record<string, unknown>;
parameters: readonly GoogleDiscoveryParameter[];
}): string =>
input.pathTemplate.replaceAll(/\{([^}]+)\}/g, (_, name: string) => {
const parameter = input.parameters.find(
(entry) => entry.location === "path" && entry.name === name,
);
const values = stringValuesFromParameter(input.args[name], false);
if (values.length === 0) {
if (parameter?.required) {
throw new Error(`Missing required path parameter: ${name}`);
}): Effect.Effect<string, GoogleDiscoveryInvocationError> =>
Effect.gen(function* () {
let output = "";
let cursor = 0;
const pathParameterPattern = /\{([^}]+)\}/g;

for (const match of input.pathTemplate.matchAll(pathParameterPattern)) {
const name = match[1]!;
output += input.pathTemplate.slice(cursor, match.index);
cursor = match.index + match[0].length;

const parameter = input.parameters.find(
(entry) => entry.location === "path" && entry.name === name,
);
const values = stringValuesFromParameter(input.args[name], false);
if (values.length === 0) {
if (parameter?.required) {
return yield* new GoogleDiscoveryInvocationError({
message: `Missing required path parameter: ${name}`,
statusCode: Option.none(),
});
}
continue;
}
return "";
output += encodeURIComponent(values[0]!);
}
return encodeURIComponent(values[0]!);

return output + input.pathTemplate.slice(cursor);
});

const resolveBaseUrl = (source: GoogleDiscoveryStoredSourceData): string =>
Expand Down Expand Up @@ -87,7 +102,7 @@ const performRequest = Effect.fn("GoogleDiscovery.invoke")(function* (input: {
}) {
const client = yield* HttpClient.HttpClient;

const resolvedPath = replacePathParameters({
const resolvedPath = yield* replacePathParameters({
pathTemplate: input.pathTemplate,
args: input.args,
parameters: input.parameters,
Expand Down Expand Up @@ -138,7 +153,7 @@ const performRequest = Effect.fn("GoogleDiscovery.invoke")(function* (input: {
Effect.mapError(
(err) =>
new GoogleDiscoveryInvocationError({
message: `HTTP request failed: ${err.message}`,
message: "HTTP request failed",
statusCode: Option.none(),
cause: err,
}),
Expand All @@ -147,9 +162,9 @@ const performRequest = Effect.fn("GoogleDiscovery.invoke")(function* (input: {

const contentType = response.headers["content-type"] ?? null;
const mapBodyError = Effect.mapError(
(err: { readonly message?: string }) =>
(err) =>
new GoogleDiscoveryInvocationError({
message: `Failed to read response body: ${err.message ?? String(err)}`,
message: "Failed to read response body",
statusCode: Option.some(response.status),
cause: err,
}),
Expand Down Expand Up @@ -191,31 +206,27 @@ export const invokeGoogleDiscoveryTool = (input: {
Effect.gen(function* () {
const entry = yield* input.ctx.storage.getBinding(input.toolId, input.toolScope);
if (!entry) {
return yield* Effect.fail(
new GoogleDiscoveryInvocationError({
message: `No Google Discovery operation found for tool "${input.toolId}"`,
statusCode: Option.none(),
}),
);
return yield* new GoogleDiscoveryInvocationError({
message: `No Google Discovery operation found for tool "${input.toolId}"`,
statusCode: Option.none(),
});
}
const stored = yield* input.ctx.storage.getSource(entry.namespace, input.toolScope);
if (!stored) {
return yield* Effect.fail(
new GoogleDiscoveryInvocationError({
message: `No Google Discovery source found for "${entry.namespace}"`,
statusCode: Option.none(),
}),
);
return yield* new GoogleDiscoveryInvocationError({
message: `No Google Discovery source found for "${entry.namespace}"`,
statusCode: Option.none(),
});
}
const source = stored.config;

const authHeader =
source.auth.kind === "oauth2"
? `Bearer ${yield* input.ctx.connections.accessToken(source.auth.connectionId).pipe(
Effect.mapError(
(err) =>
() =>
new GoogleDiscoveryOAuthError({
message: "message" in err ? (err as { message: string }).message : String(err),
message: "Failed to resolve Google Discovery OAuth access token",
}),
),
)}`
Expand Down
Loading