@upstash/qstash
Advanced tools
Comparing version 0.0.0-ci.37e98361f195772c282401708a329852dd7208c9-20241004163351 to 0.0.0-ci.3ad108b4d11889f11171a5f189ef4d368a06438b-20241219161150
@@ -1,2 +0,2 @@ | ||
import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js'; | ||
import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-CdYtp0E1.js'; | ||
import 'neverthrow'; | ||
@@ -30,2 +30,6 @@ | ||
* @returns | ||
* | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
@@ -32,0 +36,0 @@ declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => ((...args: PagesHandlerArgs | WorkersHandlerArgs) => Promise<Response>); |
import * as h3 from 'h3'; | ||
import { H3Event } from 'h3'; | ||
import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js'; | ||
import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-CdYtp0E1.js'; | ||
import 'neverthrow'; | ||
@@ -12,2 +12,7 @@ | ||
declare const verifySignatureH3: (handler: (event: H3Event) => Promise<unknown>, config?: VerifySignatureConfig) => h3.EventHandler<h3.EventHandlerRequest, Promise<unknown>>; | ||
/** | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => h3.EventHandler<h3.EventHandlerRequest, Promise<Response | { | ||
@@ -14,0 +19,0 @@ status: number; |
import { Context } from 'hono'; | ||
import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js'; | ||
import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-CdYtp0E1.js'; | ||
import 'neverthrow'; | ||
@@ -20,2 +20,6 @@ | ||
* @returns | ||
* | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
@@ -22,0 +26,0 @@ declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => ((context: Context<{ |
@@ -1,3 +0,3 @@ | ||
import { R as RateLimit, C as ChatRateLimit, S as Step, F as FailureFunctionPayload } from './client-DEZq0-qk.js'; | ||
export { A as AddEndpointsRequest, $ as AnalyticsConfig, a0 as AnalyticsSetup, B as BodyInit, y as Chat, D as ChatCompletion, I as ChatCompletionChunk, z as ChatCompletionMessage, T as ChatRequest, f as Client, n as CreateScheduleRequest, p as Endpoint, t as Event, u as EventPayload, E as EventsRequest, v as GetEventsPayload, G as GetEventsResponse, H as HTTPMethods, w as HeadersInit, M as Message, k as MessagePayload, l as Messages, O as OpenAIChatModel, N as PromptChatRequest, _ as ProviderReturnType, P as PublishBatchRequest, e as PublishJsonRequest, d as PublishRequest, j as PublishResponse, g as PublishToApiResponse, i as PublishToUrlGroupsResponse, h as PublishToUrlResponse, Q as QueueRequest, c as Receiver, a as ReceiverConfig, q as RemoveEndpointsRequest, x as RequestOptions, m as Schedule, o as Schedules, b as SignatureError, s as State, K as StreamDisabled, J as StreamEnabled, L as StreamParameter, U as UrlGroup, r as UrlGroups, V as VerifyRequest, W as WithCursor, X as custom, Y as openai, a1 as setupAnalytics, Z as upstash } from './client-DEZq0-qk.js'; | ||
import { R as RateLimit, C as ChatRateLimit, S as Step, F as FailureFunctionPayload, L as LLMOwner, B as BaseProvider, E as EmailOwner, P as ProviderInfo } from './client-CdYtp0E1.js'; | ||
export { A as AddEndpointsRequest, y as BodyInit, I as Chat, K as ChatCompletion, N as ChatCompletionChunk, J as ChatCompletionMessage, _ as ChatRequest, h as Client, p as CreateScheduleRequest, r as Endpoint, v as Event, w as EventPayload, g as EventsRequest, x as GetEventsPayload, G as GetEventsResponse, H as HTTPMethods, z as HeadersInit, M as Message, m as MessagePayload, n as Messages, Y as OpenAIChatModel, Z as PromptChatRequest, d as PublishBatchRequest, f as PublishJsonRequest, e as PublishRequest, l as PublishResponse, i as PublishToApiResponse, k as PublishToUrlGroupsResponse, j as PublishToUrlResponse, Q as QueueRequest, c as Receiver, a as ReceiverConfig, s as RemoveEndpointsRequest, D as RequestOptions, o as Schedule, q as Schedules, b as SignatureError, u as State, T as StreamDisabled, O as StreamEnabled, X as StreamParameter, U as UrlGroup, t as UrlGroups, V as VerifyRequest, W as WithCursor, a1 as anthropic, a2 as custom, a0 as openai, $ as upstash } from './client-CdYtp0E1.js'; | ||
import 'neverthrow'; | ||
@@ -9,3 +9,4 @@ | ||
declare class QstashError extends Error { | ||
constructor(message: string); | ||
readonly status?: number; | ||
constructor(message: string, status?: number); | ||
} | ||
@@ -68,2 +69,26 @@ declare class QstashRatelimitError extends QstashError { | ||
export { ChatRateLimit, QStashWorkflowAbort, QStashWorkflowError, QstashChatRatelimitError, QstashDailyRatelimitError, QstashError, QstashRatelimitError, RateLimit, decodeBase64, formatWorkflowError }; | ||
type AnalyticsConfig = { | ||
name: "helicone"; | ||
token: string; | ||
}; | ||
type AnalyticsSetup = { | ||
baseURL?: string; | ||
defaultHeaders?: Record<string, string | undefined>; | ||
}; | ||
declare const setupAnalytics: (analytics: AnalyticsConfig | undefined, providerApiKey: string, providerBaseUrl?: string, provider?: LLMOwner) => AnalyticsSetup; | ||
declare class EmailProvider extends BaseProvider<"email", EmailOwner> { | ||
readonly apiKind = "email"; | ||
readonly batch: boolean; | ||
readonly method = "POST"; | ||
constructor(baseUrl: string, token: string, owner: EmailOwner, batch: boolean); | ||
getRoute(): string[]; | ||
getHeaders(_options: unknown): Record<string, string>; | ||
onFinish(providerInfo: ProviderInfo, _options: unknown): ProviderInfo; | ||
} | ||
declare const resend: ({ token, batch, }: { | ||
token: string; | ||
batch?: boolean; | ||
}) => EmailProvider; | ||
export { ChatRateLimit, QStashWorkflowAbort, QStashWorkflowError, QstashChatRatelimitError, QstashDailyRatelimitError, QstashError, QstashRatelimitError, RateLimit, decodeBase64, formatWorkflowError, resend, setupAnalytics }; |
427
index.js
@@ -46,2 +46,3 @@ "use strict"; | ||
UrlGroups: () => UrlGroups, | ||
anthropic: () => anthropic, | ||
custom: () => custom, | ||
@@ -51,2 +52,3 @@ decodeBase64: () => decodeBase64, | ||
openai: () => openai, | ||
resend: () => resend, | ||
setupAnalytics: () => setupAnalytics, | ||
@@ -83,7 +85,10 @@ upstash: () => upstash | ||
async verify(request) { | ||
const isValid = await this.verifyWithKey(this.currentSigningKey, request); | ||
if (isValid) { | ||
return true; | ||
let payload; | ||
try { | ||
payload = await this.verifyWithKey(this.currentSigningKey, request); | ||
} catch { | ||
payload = await this.verifyWithKey(this.nextSigningKey, request); | ||
} | ||
return this.verifyWithKey(this.nextSigningKey, request); | ||
this.verifyBodyAndUrl(payload, request); | ||
return true; | ||
} | ||
@@ -100,3 +105,6 @@ /** | ||
}); | ||
const p = jwt.payload; | ||
return jwt.payload; | ||
} | ||
verifyBodyAndUrl(payload, request) { | ||
const p = payload; | ||
if (request.url !== void 0 && p.sub !== request.url) { | ||
@@ -110,3 +118,2 @@ throw new SignatureError(`invalid subject: ${p.sub}, want: ${request.url}`); | ||
} | ||
return true; | ||
} | ||
@@ -173,6 +180,9 @@ }; | ||
// src/client/error.ts | ||
var RATELIMIT_STATUS = 429; | ||
var QstashError = class extends Error { | ||
constructor(message) { | ||
status; | ||
constructor(message, status) { | ||
super(message); | ||
this.name = "QstashError"; | ||
this.status = status; | ||
} | ||
@@ -185,3 +195,3 @@ }; | ||
constructor(args) { | ||
super(`Exceeded burst rate limit. ${JSON.stringify(args)} `); | ||
super(`Exceeded burst rate limit. ${JSON.stringify(args)}`, RATELIMIT_STATUS); | ||
this.name = "QstashRatelimitError"; | ||
@@ -201,3 +211,4 @@ this.limit = args.limit; | ||
constructor(args) { | ||
super(`Exceeded chat rate limit. ${JSON.stringify(args)} `); | ||
super(`Exceeded chat rate limit. ${JSON.stringify(args)}`, RATELIMIT_STATUS); | ||
this.name = "QstashChatRatelimitError"; | ||
this.limitRequests = args["limit-requests"]; | ||
@@ -216,7 +227,7 @@ this.limitTokens = args["limit-tokens"]; | ||
constructor(args) { | ||
super(`Exceeded daily rate limit. ${JSON.stringify(args)} `); | ||
super(`Exceeded daily rate limit. ${JSON.stringify(args)}`, RATELIMIT_STATUS); | ||
this.name = "QstashDailyRatelimitError"; | ||
this.limit = args.limit; | ||
this.remaining = args.remaining; | ||
this.reset = args.reset; | ||
this.name = "QstashChatRatelimitError"; | ||
} | ||
@@ -258,2 +269,3 @@ }; | ||
retry; | ||
headers; | ||
constructor(config) { | ||
@@ -267,5 +279,6 @@ this.baseUrl = config.baseUrl.replace(/\/$/, ""); | ||
} : { | ||
attempts: config.retry?.retries ? config.retry.retries + 1 : 5, | ||
attempts: config.retry?.retries ?? 5, | ||
backoff: config.retry?.backoff ?? ((retryCount) => Math.exp(retryCount) * 50) | ||
}; | ||
this.headers = config.headers; | ||
} | ||
@@ -313,3 +326,3 @@ async request(request) { | ||
let error = void 0; | ||
for (let index = 0; index < this.retry.attempts; index++) { | ||
for (let index = 0; index <= this.retry.attempts; index++) { | ||
try { | ||
@@ -320,3 +333,5 @@ response = await fetch(url.toString(), requestOptions); | ||
error = error_; | ||
await new Promise((r) => setTimeout(r, this.retry.backoff(index))); | ||
if (index < this.retry.attempts) { | ||
await new Promise((r) => setTimeout(r, this.retry.backoff(index))); | ||
} | ||
} | ||
@@ -380,3 +395,6 @@ } | ||
const body = await response.text(); | ||
throw new QstashError(body.length > 0 ? body : `Error: status=${response.status}`); | ||
throw new QstashError( | ||
body.length > 0 ? body : `Error: status=${response.status}`, | ||
response.status | ||
); | ||
} | ||
@@ -419,33 +437,2 @@ } | ||
}; | ||
var upstash = () => { | ||
return { | ||
owner: "upstash", | ||
baseUrl: "https://qstash.upstash.io/llm", | ||
token: "", | ||
organization: void 0 | ||
}; | ||
}; | ||
var openai = ({ | ||
token, | ||
organization | ||
}) => { | ||
return { | ||
token, | ||
owner: "openai", | ||
baseUrl: "https://api.openai.com", | ||
organization | ||
}; | ||
}; | ||
var custom = ({ | ||
baseUrl, | ||
token | ||
}) => { | ||
const trimmedBaseUrl = baseUrl.replace(/\/(v1\/)?chat\/completions$/, ""); | ||
return { | ||
token, | ||
owner: "custom", | ||
baseUrl: trimmedBaseUrl, | ||
organization: void 0 | ||
}; | ||
}; | ||
@@ -526,3 +513,2 @@ // src/client/llm/chat.ts | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/require-await | ||
createThirdParty = async (request) => { | ||
@@ -588,59 +574,2 @@ const { baseUrl, token, owner, organization } = request.provider; | ||
// src/client/llm/utils.ts | ||
function appendLLMOptionsIfNeeded(request, headers, http) { | ||
if (!request.api) | ||
return; | ||
const provider = request.api.provider; | ||
const analytics = request.api.analytics; | ||
if (provider?.owner === "upstash") { | ||
handleUpstashProvider(request, headers, http, analytics); | ||
return; | ||
} | ||
if (!("provider" in request.api)) | ||
return; | ||
const { baseUrl, token } = validateProviderConfig(provider); | ||
const analyticsConfig = analytics ? setupAnalytics({ name: analytics.name, token: analytics.token }, token, baseUrl, "custom") : void 0; | ||
if (analyticsConfig) { | ||
setAnalyticsHeaders(headers, analyticsConfig); | ||
request.url = analyticsConfig.baseURL; | ||
} else { | ||
request.url = `${baseUrl}/v1/chat/completions`; | ||
headers.set("Authorization", `Bearer ${token}`); | ||
} | ||
} | ||
function handleUpstashProvider(request, headers, http, analytics) { | ||
if (analytics) { | ||
const analyticsConfig = setupAnalytics( | ||
{ name: analytics.name, token: analytics.token }, | ||
//@ts-expect-error hacky way to get bearer token | ||
String(http.authorization).split("Bearer ")[1], | ||
request.api?.provider?.baseUrl, | ||
"upstash" | ||
); | ||
setAnalyticsHeaders(headers, analyticsConfig); | ||
request.url = analyticsConfig.baseURL; | ||
} else { | ||
request.api = { name: "llm" }; | ||
} | ||
} | ||
function validateProviderConfig(provider) { | ||
if (!provider?.baseUrl) | ||
throw new Error("baseUrl cannot be empty or undefined!"); | ||
if (!provider.token) | ||
throw new Error("token cannot be empty or undefined!"); | ||
return { baseUrl: provider.baseUrl, token: provider.token }; | ||
} | ||
function setAnalyticsHeaders(headers, analyticsConfig) { | ||
headers.set("Helicone-Auth", analyticsConfig.defaultHeaders?.["Helicone-Auth"] ?? ""); | ||
headers.set("Authorization", analyticsConfig.defaultHeaders?.Authorization ?? ""); | ||
if (analyticsConfig.defaultHeaders?.["Helicone-Target-Url"]) { | ||
headers.set("Helicone-Target-Url", analyticsConfig.defaultHeaders["Helicone-Target-Url"]); | ||
} | ||
} | ||
function ensureCallbackPresent(request) { | ||
if (request.api?.name === "llm" && !request.callback) { | ||
throw new TypeError("Callback cannot be undefined when using LLM"); | ||
} | ||
} | ||
// src/client/messages.ts | ||
@@ -694,2 +623,166 @@ var Messages = class { | ||
// src/client/api/base.ts | ||
var BaseProvider = class { | ||
baseUrl; | ||
token; | ||
owner; | ||
constructor(baseUrl, token, owner) { | ||
this.baseUrl = baseUrl; | ||
this.token = token; | ||
this.owner = owner; | ||
} | ||
getUrl() { | ||
return `${this.baseUrl}/${this.getRoute().join("/")}`; | ||
} | ||
}; | ||
// src/client/api/llm.ts | ||
var LLMProvider = class extends BaseProvider { | ||
apiKind = "llm"; | ||
organization; | ||
method = "POST"; | ||
constructor(baseUrl, token, owner, organization) { | ||
super(baseUrl, token, owner); | ||
this.organization = organization; | ||
} | ||
getRoute() { | ||
return this.owner === "anthropic" ? ["v1", "messages"] : ["v1", "chat", "completions"]; | ||
} | ||
getHeaders(options) { | ||
if (this.owner === "upstash" && !options.analytics) { | ||
return { "content-type": "application/json" }; | ||
} | ||
const header = this.owner === "anthropic" ? "x-api-key" : "authorization"; | ||
const headerValue = this.owner === "anthropic" ? this.token : `Bearer ${this.token}`; | ||
const headers = { | ||
[header]: headerValue, | ||
"content-type": "application/json" | ||
}; | ||
if (this.owner === "openai" && this.organization) { | ||
headers["OpenAI-Organization"] = this.organization; | ||
} | ||
if (this.owner === "anthropic") { | ||
headers["anthropic-version"] = "2023-06-01"; | ||
} | ||
return headers; | ||
} | ||
/** | ||
* Checks if callback exists and adds analytics in place if it's set. | ||
* | ||
* @param request | ||
* @param options | ||
*/ | ||
onFinish(providerInfo, options) { | ||
if (options.analytics) { | ||
return updateWithAnalytics(providerInfo, options.analytics); | ||
} | ||
return providerInfo; | ||
} | ||
}; | ||
var upstash = () => { | ||
return new LLMProvider("https://qstash.upstash.io/llm", "", "upstash"); | ||
}; | ||
var openai = ({ | ||
token, | ||
organization | ||
}) => { | ||
return new LLMProvider("https://api.openai.com", token, "openai", organization); | ||
}; | ||
var anthropic = ({ token }) => { | ||
return new LLMProvider("https://api.anthropic.com", token, "anthropic"); | ||
}; | ||
var custom = ({ | ||
baseUrl, | ||
token | ||
}) => { | ||
const trimmedBaseUrl = baseUrl.replace(/\/(v1\/)?chat\/completions$/, ""); | ||
return new LLMProvider(trimmedBaseUrl, token, "custom"); | ||
}; | ||
// src/client/api/utils.ts | ||
var getProviderInfo = (api, upstashToken) => { | ||
const { name, provider, ...parameters } = api; | ||
const finalProvider = provider ?? upstash(); | ||
if (finalProvider.owner === "upstash" && !finalProvider.token) { | ||
finalProvider.token = upstashToken; | ||
} | ||
if (!finalProvider.baseUrl) | ||
throw new TypeError("baseUrl cannot be empty or undefined!"); | ||
if (!finalProvider.token) | ||
throw new TypeError("token cannot be empty or undefined!"); | ||
if (finalProvider.apiKind !== name) { | ||
throw new TypeError( | ||
`Unexpected api name. Expected '${finalProvider.apiKind}', received ${name}` | ||
); | ||
} | ||
const providerInfo = { | ||
url: finalProvider.getUrl(), | ||
baseUrl: finalProvider.baseUrl, | ||
route: finalProvider.getRoute(), | ||
appendHeaders: finalProvider.getHeaders(parameters), | ||
owner: finalProvider.owner, | ||
method: finalProvider.method | ||
}; | ||
return finalProvider.onFinish(providerInfo, parameters); | ||
}; | ||
var safeJoinHeaders = (headers, record) => { | ||
const joinedHeaders = new Headers(record); | ||
for (const [header, value] of headers.entries()) { | ||
joinedHeaders.set(header, value); | ||
} | ||
return joinedHeaders; | ||
}; | ||
var processApi = (request, headers, upstashToken) => { | ||
if (!request.api) { | ||
request.headers = headers; | ||
return request; | ||
} | ||
const { url, appendHeaders, owner, method } = getProviderInfo(request.api, upstashToken); | ||
if (request.api.name === "llm") { | ||
const callback = request.callback; | ||
if (!callback) { | ||
throw new TypeError("Callback cannot be undefined when using LLM api."); | ||
} | ||
return { | ||
...request, | ||
method: request.method ?? method, | ||
headers: safeJoinHeaders(headers, appendHeaders), | ||
...owner === "upstash" && !request.api.analytics ? { api: { name: "llm" }, url: void 0, callback } : { url, api: void 0 } | ||
}; | ||
} else { | ||
return { | ||
...request, | ||
method: request.method ?? method, | ||
headers: safeJoinHeaders(headers, appendHeaders), | ||
url, | ||
api: void 0 | ||
}; | ||
} | ||
}; | ||
function updateWithAnalytics(providerInfo, analytics) { | ||
switch (analytics.name) { | ||
case "helicone": { | ||
providerInfo.appendHeaders["Helicone-Auth"] = `Bearer ${analytics.token}`; | ||
if (providerInfo.owner === "upstash") { | ||
updateProviderInfo(providerInfo, "https://qstash.helicone.ai", [ | ||
"llm", | ||
...providerInfo.route | ||
]); | ||
} else { | ||
providerInfo.appendHeaders["Helicone-Target-Url"] = providerInfo.baseUrl; | ||
updateProviderInfo(providerInfo, "https://gateway.helicone.ai", providerInfo.route); | ||
} | ||
return providerInfo; | ||
} | ||
default: { | ||
throw new Error("Unknown analytics provider"); | ||
} | ||
} | ||
} | ||
function updateProviderInfo(providerInfo, baseUrl, route) { | ||
providerInfo.baseUrl = baseUrl; | ||
providerInfo.route = route; | ||
providerInfo.url = `${baseUrl}/${route.join("/")}`; | ||
} | ||
// src/client/utils.ts | ||
@@ -711,2 +804,12 @@ var isIgnoredHeader = (header) => { | ||
} | ||
function wrapWithGlobalHeaders(headers, globalHeaders) { | ||
if (!globalHeaders) { | ||
return headers; | ||
} | ||
const finalHeaders = new Headers(globalHeaders); | ||
headers.forEach((value, key) => { | ||
finalHeaders.set(key, value); | ||
}); | ||
return finalHeaders; | ||
} | ||
function processHeaders(request) { | ||
@@ -728,3 +831,3 @@ const headers = prefixHeaders(new Headers(request.headers)); | ||
} | ||
if (request.contentBasedDeduplication !== void 0) { | ||
if (request.contentBasedDeduplication) { | ||
headers.set("Upstash-Content-Based-Deduplication", "true"); | ||
@@ -751,3 +854,12 @@ } | ||
function getRequestPath(request) { | ||
return request.url ?? request.urlGroup ?? request.topic ?? `api/${request.api?.name}`; | ||
const nonApiPath = request.url ?? request.urlGroup ?? request.topic; | ||
if (nonApiPath) | ||
return nonApiPath; | ||
if (request.api?.name === "llm") | ||
return `api/llm`; | ||
if (request.api?.name === "email") { | ||
const providerInfo = getProviderInfo(request.api, "not-needed"); | ||
return providerInfo.baseUrl; | ||
} | ||
throw new QstashError(`Failed to infer request path for ${JSON.stringify(request)}`); | ||
} | ||
@@ -760,6 +872,14 @@ function decodeBase64(base64) { | ||
} catch (error) { | ||
console.warn( | ||
`Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}` | ||
); | ||
return atob(base64); | ||
try { | ||
const result = atob(base64); | ||
console.warn( | ||
`Upstash QStash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}` | ||
); | ||
return result; | ||
} catch (error2) { | ||
console.warn( | ||
`Upstash QStash: Failed to decode base64 "${base64}" with atob. Returning it as it is. ${error2}` | ||
); | ||
return base64; | ||
} | ||
} | ||
@@ -839,3 +959,6 @@ } | ||
} | ||
const headers = processHeaders(request); | ||
const headers = wrapWithGlobalHeaders( | ||
processHeaders(request), | ||
this.http.headers | ||
); | ||
const destination = getRequestPath(request); | ||
@@ -856,8 +979,7 @@ const response = await this.http.request({ | ||
headers.set("Content-Type", "application/json"); | ||
ensureCallbackPresent(request); | ||
appendLLMOptionsIfNeeded(request, headers, this.http); | ||
const upstashToken = String(this.http.authorization).split("Bearer ")[1]; | ||
const nonApiRequest = processApi(request, headers, upstashToken); | ||
const response = await this.enqueue({ | ||
...request, | ||
body: JSON.stringify(request.body), | ||
headers | ||
...nonApiRequest, | ||
body: JSON.stringify(nonApiRequest.body) | ||
}); | ||
@@ -941,5 +1063,8 @@ return response; | ||
} | ||
if (request.queueName !== void 0) { | ||
headers.set("Upstash-Queue-Name", request.queueName); | ||
} | ||
return await this.http.request({ | ||
method: "POST", | ||
headers, | ||
headers: wrapWithGlobalHeaders(headers, this.http.headers), | ||
path: ["v2", "schedules", request.destination], | ||
@@ -1101,3 +1226,5 @@ body: request.body | ||
baseUrl: config.baseUrl ? config.baseUrl.replace(/\/$/, "") : "https://qstash.upstash.io", | ||
authorization: `Bearer ${config.token}` | ||
authorization: `Bearer ${config.token}`, | ||
//@ts-expect-error caused by undici and bunjs type overlap | ||
headers: prefixHeaders(new Headers(config.headers)) | ||
}); | ||
@@ -1152,2 +1279,6 @@ this.token = config.token; | ||
* cancel workflows. | ||
* | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use @upstash/workflow instead https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
@@ -1174,3 +1305,6 @@ get workflow() { | ||
async publish(request) { | ||
const headers = processHeaders(request); | ||
const headers = wrapWithGlobalHeaders( | ||
processHeaders(request), | ||
this.http.headers | ||
); | ||
const response = await this.http.request({ | ||
@@ -1191,8 +1325,7 @@ path: ["v2", "publish", getRequestPath(request)], | ||
headers.set("Content-Type", "application/json"); | ||
ensureCallbackPresent(request); | ||
appendLLMOptionsIfNeeded(request, headers, this.http); | ||
const upstashToken = String(this.http.authorization).split("Bearer ")[1]; | ||
const nonApiRequest = processApi(request, headers, upstashToken); | ||
const response = await this.publish({ | ||
...request, | ||
headers, | ||
body: JSON.stringify(request.body) | ||
...nonApiRequest, | ||
body: JSON.stringify(nonApiRequest.body) | ||
}); | ||
@@ -1207,3 +1340,3 @@ return response; | ||
for (const message of request) { | ||
const headers = processHeaders(message); | ||
const headers = wrapWithGlobalHeaders(processHeaders(message), this.http.headers); | ||
const headerEntries = Object.fromEntries(headers.entries()); | ||
@@ -1232,12 +1365,12 @@ messages.push({ | ||
async batchJSON(request) { | ||
for (const message of request) { | ||
const batchPayload = request.map((message) => { | ||
if ("body" in message) { | ||
message.body = JSON.stringify(message.body); | ||
} | ||
message.headers = new Headers(message.headers); | ||
ensureCallbackPresent(message); | ||
appendLLMOptionsIfNeeded(message, message.headers, this.http); | ||
message.headers.set("Content-Type", "application/json"); | ||
} | ||
const response = await this.batch(request); | ||
const upstashToken = String(this.http.authorization).split("Bearer ")[1]; | ||
const nonApiMessage = processApi(message, new Headers(message.headers), upstashToken); | ||
nonApiMessage.headers.set("Content-Type", "application/json"); | ||
return nonApiMessage; | ||
}); | ||
const response = await this.batch(batchPayload); | ||
return response; | ||
@@ -1297,2 +1430,30 @@ } | ||
}; | ||
// src/client/api/email.ts | ||
var EmailProvider = class extends BaseProvider { | ||
apiKind = "email"; | ||
batch; | ||
method = "POST"; | ||
constructor(baseUrl, token, owner, batch) { | ||
super(baseUrl, token, owner); | ||
this.batch = batch; | ||
} | ||
getRoute() { | ||
return this.batch ? ["emails", "batch"] : ["emails"]; | ||
} | ||
getHeaders(_options) { | ||
return { | ||
authorization: `Bearer ${this.token}` | ||
}; | ||
} | ||
onFinish(providerInfo, _options) { | ||
return providerInfo; | ||
} | ||
}; | ||
var resend = ({ | ||
token, | ||
batch = false | ||
}) => { | ||
return new EmailProvider("https://api.resend.com", token, "resend", batch); | ||
}; | ||
// Annotate the CommonJS export names for ESM import in node: | ||
@@ -1313,2 +1474,3 @@ 0 && (module.exports = { | ||
UrlGroups, | ||
anthropic, | ||
custom, | ||
@@ -1318,4 +1480,5 @@ decodeBase64, | ||
openai, | ||
resend, | ||
setupAnalytics, | ||
upstash | ||
}); |
import { NextApiHandler } from 'next'; | ||
import { NextRequest, NextFetchEvent, NextResponse } from 'next/server'; | ||
import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js'; | ||
import { NextRequest, NextFetchEvent } from 'next/server'; | ||
import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-CdYtp0E1.js'; | ||
import 'neverthrow'; | ||
@@ -23,4 +23,4 @@ | ||
declare function verifySignature(handler: NextApiHandler, config?: VerifySignatureConfig): NextApiHandler; | ||
declare function verifySignatureEdge(handler: (request: NextRequest, nfe?: NextFetchEvent) => NextResponse | Promise<NextResponse>, config?: VerifySignatureConfig): (request: NextRequest, nfe: NextFetchEvent) => Promise<NextResponse<unknown>>; | ||
type VerifySignatureAppRouterResponse = NextResponse | Promise<NextResponse> | Response | Promise<Response>; | ||
declare function verifySignatureEdge(handler: (request: NextRequest, nfe?: NextFetchEvent) => Response | Promise<Response>, config?: VerifySignatureConfig): (request: NextRequest, nfe: NextFetchEvent) => Promise<Response>; | ||
type VerifySignatureAppRouterResponse = Response | Promise<Response>; | ||
declare function verifySignatureAppRouter(handler: ((request: Request, params?: unknown) => VerifySignatureAppRouterResponse) | ((request: NextRequest, params?: unknown) => VerifySignatureAppRouterResponse), config?: VerifySignatureConfig): (request: NextRequest | Request, params?: unknown) => Promise<Response>; | ||
@@ -35,6 +35,15 @@ /** | ||
* @returns | ||
* | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<NextResponse, TInitialPayload>, "onStepFinish">) => ((request: Request) => Promise<NextResponse>); | ||
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => ((request: Request) => Promise<Response>); | ||
/** | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
declare const servePagesRouter: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => NextApiHandler; | ||
export { type VerifySignatureConfig, serve, servePagesRouter, verifySignature, verifySignatureAppRouter, verifySignatureEdge }; |
import * as h3 from 'h3'; | ||
/** | ||
* @deprecated Use import { verifySignatureH3 } from "@upstash/qstash/h3" instead | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
@@ -6,0 +8,0 @@ declare const verifySignatureNuxt: (handler: (event: h3.H3Event<h3.EventHandlerRequest>) => Promise<unknown>, config?: { |
17
nuxt.js
@@ -386,7 +386,10 @@ "use strict"; | ||
async verify(request) { | ||
const isValid = await this.verifyWithKey(this.currentSigningKey, request); | ||
if (isValid) { | ||
return true; | ||
let payload; | ||
try { | ||
payload = await this.verifyWithKey(this.currentSigningKey, request); | ||
} catch { | ||
payload = await this.verifyWithKey(this.nextSigningKey, request); | ||
} | ||
return this.verifyWithKey(this.nextSigningKey, request); | ||
this.verifyBodyAndUrl(payload, request); | ||
return true; | ||
} | ||
@@ -403,3 +406,6 @@ /** | ||
}); | ||
const p = jwt.payload; | ||
return jwt.payload; | ||
} | ||
verifyBodyAndUrl(payload, request) { | ||
const p = payload; | ||
if (request.url !== void 0 && p.sub !== request.url) { | ||
@@ -413,3 +419,2 @@ throw new SignatureError(`invalid subject: ${p.sub}, want: ${request.url}`); | ||
} | ||
return true; | ||
} | ||
@@ -416,0 +421,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
{ "version": "v0.0.0-ci.37e98361f195772c282401708a329852dd7208c9-20241004163351", "name": "@upstash/qstash", "description": "Official Typescript client for QStash", "author": "Andreas Thomas <dev@chronark.com>", "license": "MIT", "homepage": "https://github.com/upstash/sdk-qstash-ts#readme", "repository": { "type": "git", "url": "git+https://github.com/upstash/sdk-qstash-ts.git" }, "bugs": { "url": "https://github.com/upstash/sdk-qstash-ts/issues" }, "main": "./index.js", "module": "./index.mjs", "types": "./index.d.ts", "files": [ "./*" ], "exports": { ".": { "import": "./index.mjs", "require": "./index.js" }, "./dist/nextjs": { "import": "./nextjs.mjs", "require": "./nextjs.js" }, "./nextjs": { "import": "./nextjs.mjs", "require": "./nextjs.js" }, "./h3": { "import": "./h3.mjs", "require": "./h3.js" }, "./nuxt": { "import": "./nuxt.mjs", "require": "./nuxt.js" }, "./svelte": { "import": "./svelte.mjs", "require": "./svelte.js" }, "./solidjs": { "import": "./solidjs.mjs", "require": "./solidjs.js" }, "./workflow": { "import": "./workflow.mjs", "require": "./workflow.js" }, "./hono": { "import": "./hono.mjs", "require": "./hono.js" }, "./cloudflare": { "import": "./cloudflare.mjs", "require": "./cloudflare.js" } }, "keywords": [ "qstash", "queue", "events", "serverless", "upstash" ], "scripts": { "build": "tsup && cp README.md ./dist/ && cp package.json ./dist/ && cp LICENSE ./dist/", "test": "bun test src", "fmt": "prettier --write .", "lint": "tsc && eslint \"{src,platforms}/**/*.{js,ts,tsx}\" --quiet --fix", "check-exports": "bun run build && cd dist && attw -P", "prepare": "husky" }, "devDependencies": { "@commitlint/cli": "^19.2.2", "@commitlint/config-conventional": "^19.2.2", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.10.0", "@solidjs/start": "^1.0.6", "@sveltejs/kit": "^2.5.18", "@types/bun": "^1.1.1", "@types/crypto-js": "^4.2.0", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", "ai": "^3.1.28", "bun-types": "^1.1.7", "eslint": "^9.10.0", "eslint-plugin-unicorn": "^51.0.1", "h3": "^1.12.0", "hono": "^4.5.8", "husky": "^9.0.10", "next": "^14.0.2", "prettier": "^3.2.5", "tsup": "latest", "typescript": "^5.4.5", "undici-types": "^6.16.0", "vitest": "latest" }, "dependencies": { "neverthrow": "^7.0.1", "crypto-js": ">=4.2.0", "jose": "^5.2.3" } } | ||
{ "version": "v0.0.0-ci.3ad108b4d11889f11171a5f189ef4d368a06438b-20241219161150", "name": "@upstash/qstash", "description": "Official Typescript client for QStash", "author": "Andreas Thomas <dev@chronark.com>", "license": "MIT", "homepage": "https://github.com/upstash/sdk-qstash-ts#readme", "repository": { "type": "git", "url": "git+https://github.com/upstash/sdk-qstash-ts.git" }, "bugs": { "url": "https://github.com/upstash/sdk-qstash-ts/issues" }, "main": "./index.js", "module": "./index.mjs", "types": "./index.d.ts", "files": [ "./*" ], "exports": { ".": { "import": "./index.mjs", "require": "./index.js" }, "./dist/nextjs": { "import": "./nextjs.mjs", "require": "./nextjs.js" }, "./nextjs": { "import": "./nextjs.mjs", "require": "./nextjs.js" }, "./h3": { "import": "./h3.mjs", "require": "./h3.js" }, "./nuxt": { "import": "./nuxt.mjs", "require": "./nuxt.js" }, "./svelte": { "import": "./svelte.mjs", "require": "./svelte.js" }, "./solidjs": { "import": "./solidjs.mjs", "require": "./solidjs.js" }, "./workflow": { "import": "./workflow.mjs", "require": "./workflow.js" }, "./hono": { "import": "./hono.mjs", "require": "./hono.js" }, "./cloudflare": { "import": "./cloudflare.mjs", "require": "./cloudflare.js" } }, "keywords": [ "qstash", "queue", "events", "serverless", "upstash" ], "scripts": { "build": "tsup && cp README.md ./dist/ && cp package.json ./dist/ && cp LICENSE ./dist/", "test": "bun test src", "fmt": "prettier --write .", "lint": "tsc && eslint \"{src,platforms}/**/*.{js,ts,tsx}\" --quiet --fix", "check-exports": "bun run build && cd dist && attw -P", "prepare": "husky" }, "devDependencies": { "@commitlint/cli": "^19.2.2", "@commitlint/config-conventional": "^19.2.2", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.10.0", "@solidjs/start": "^1.0.6", "@sveltejs/kit": "^2.5.18", "@types/bun": "^1.1.1", "@types/crypto-js": "^4.2.0", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", "ai": "^3.1.28", "bun-types": "^1.1.7", "eslint": "^9.10.0", "eslint-plugin-unicorn": "^51.0.1", "h3": "^1.12.0", "hono": "^4.5.8", "husky": "^9.0.10", "next": "^14.0.2", "prettier": "^3.2.5", "tsup": "latest", "typescript": "^5.4.5", "undici-types": "^6.16.0", "vitest": "latest" }, "dependencies": { "neverthrow": "^7.0.1", "crypto-js": ">=4.2.0", "jose": "^5.2.3" } } |
import { APIHandler, APIEvent } from '@solidjs/start/server'; | ||
import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js'; | ||
import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-CdYtp0E1.js'; | ||
import 'neverthrow'; | ||
@@ -19,2 +19,6 @@ | ||
* @returns | ||
* | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
@@ -21,0 +25,0 @@ declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => (event: APIEvent) => Promise<Response>; |
import { RequestHandler } from '@sveltejs/kit'; | ||
import { a2 as RouteFunction, a3 as WorkflowServeOptions } from './client-DEZq0-qk.js'; | ||
import { a3 as RouteFunction, a4 as WorkflowServeOptions } from './client-CdYtp0E1.js'; | ||
import 'neverthrow'; | ||
@@ -19,2 +19,6 @@ | ||
* @returns | ||
* | ||
* @deprecated as of version 2.7.17. Will be removed in qstash-js 3.0.0. | ||
* Please use https://github.com/upstash/workflow-js | ||
* Migration Guide: https://upstash.com/docs/workflow/migration | ||
*/ | ||
@@ -21,0 +25,0 @@ declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish"> & { |
@@ -1,2 +0,2 @@ | ||
export { af as AsyncStepFunction, a8 as DisabledWorkflowContext, F as FailureFunctionPayload, ai as FinishCondition, ak as LogLevel, ah as ParallelCallState, ad as RawStep, aj as RequiredExceptFields, a2 as RouteFunction, S as Step, ag as StepFunction, ac as StepType, ab as StepTypes, ae as SyncStepFunction, a4 as Workflow, a9 as WorkflowClient, a7 as WorkflowContext, am as WorkflowLogger, al as WorkflowLoggerOptions, aa as WorkflowReceiver, a3 as WorkflowServeOptions, a5 as processOptions, a6 as serve } from './client-DEZq0-qk.js'; | ||
export { ag as AsyncStepFunction, a9 as DisabledWorkflowContext, F as FailureFunctionPayload, aj as FinishCondition, al as LogLevel, ai as ParallelCallState, ae as RawStep, ak as RequiredExceptFields, a3 as RouteFunction, S as Step, ah as StepFunction, ad as StepType, ac as StepTypes, af as SyncStepFunction, a5 as Workflow, aa as WorkflowClient, a8 as WorkflowContext, an as WorkflowLogger, am as WorkflowLoggerOptions, ab as WorkflowReceiver, a4 as WorkflowServeOptions, a6 as processOptions, a7 as serve } from './client-CdYtp0E1.js'; | ||
import 'neverthrow'; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
923323
27221
10