@vercel/schedules 0.0.0-alpha.11 → 0.0.0-alpha.12

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 CHANGED
@@ -82,7 +82,9 @@ export const POST = handleSchedule(async (metadata) => {
82
82
  });
83
83
  ```
84
84
 
85
- The handler receives only metadata about the current firing, including `executionId` from the CloudEvent `ce-id` header and `scheduledAt` from the required `ce-vssscheduledat` header. `scheduledAt` is a `Date` representing the scheduled run time; the parser does not use `ce-time` as a fallback. The handler returns a `200` response when the callback completes successfully. Static schedules do not accept a configured payload; dynamic Queue schedules created or updated through the SDK still support `payload`.
85
+ The handler receives metadata about the current firing as its first argument, including `executionId` from the CloudEvent `ce-id` header and `scheduledAt` from the required `ce-vssscheduledat` header. `scheduledAt` is a `Date` representing the scheduled run time; the parser does not use `ce-time` as a fallback. The original `Request` is passed as the second argument so you can read additional headers or other request details. The handler returns a `200` response when the callback completes successfully. Static schedules do not accept a configured payload; dynamic Queue schedules created or updated through the SDK still support `payload`.
86
+
87
+ `handleSchedule` and `parseScheduleEvent` implement the [schedule function dispatch protocol](https://github.com/vercel/schedules/blob/main/docs/schedule-dispatch-protocol.md). Frameworks and libraries can implement schedule target functions without depending on this package by following that document.
86
88
 
87
89
  For a custom client:
88
90
 
package/dist/index.cjs CHANGED
@@ -272,7 +272,7 @@ function handleSchedule(handler) {
272
272
  );
273
273
  }
274
274
  try {
275
- await handler(metadata);
275
+ await handler(metadata, request);
276
276
  return new Response(null, { status: 200 });
277
277
  } catch (e2) {
278
278
  return Response.json(
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/schedules/schedules/packages/schedules/dist/index.cjs","../src/api-client.ts","../src/constants.ts","../src/schedules.ts","../src/default-client.ts","../src/schedule-event.ts"],"names":[],"mappings":"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","file":"/home/runner/work/schedules/schedules/packages/schedules/dist/index.cjs","sourcesContent":[null,"import { getVercelOidcToken } from '@vercel/oidc';\nimport { DEFAULT_SCHEDULES_BASE_URL } from './constants';\n\nexport interface SchedulesApiClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: typeof fetch;\n}\n\nfunction trimTrailingSlashes(path: string): string {\n let end = path.length;\n while (end > 0 && path[end - 1] === '/') {\n end--;\n }\n return path.slice(0, end);\n}\n\nexport class SchedulesApiError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = 'SchedulesApiError';\n this.status = status;\n }\n}\n\nexport class SchedulesApiClient {\n private readonly baseUrl?: URL;\n private readonly token?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly configurationError?: Error;\n\n constructor(options: SchedulesApiClientOptions = {}) {\n this.token = options.token;\n this.fetchImpl = options.fetch ?? fetch;\n\n const envBaseUrl = process.env.VERCEL_SCHEDULE_BASE_URL;\n const devApiVersion = process.env.VERCEL_SCHEDULE_DEV_API_VERSION;\n let advertisedBaseUrl: URL | undefined;\n try {\n advertisedBaseUrl = new URL(envBaseUrl ?? '');\n } catch {\n // An independent explicit endpoint does not need the injected URL.\n }\n\n const explicitBaseUrl =\n options.baseUrl === undefined ? undefined : new URL(options.baseUrl);\n const localSelected =\n process.env.NODE_ENV === 'development' &&\n process.env.VERCEL_DEPLOYMENT_ID === undefined &&\n devApiVersion !== undefined &&\n (explicitBaseUrl === undefined ||\n (advertisedBaseUrl !== undefined &&\n explicitBaseUrl.origin === advertisedBaseUrl.origin &&\n trimTrailingSlashes(explicitBaseUrl.pathname) ===\n trimTrailingSlashes(advertisedBaseUrl.pathname)));\n\n if (localSelected) {\n try {\n if (devApiVersion !== '1') {\n throw new Error(\n 'Unsupported VERCEL_SCHEDULE_DEV_API_VERSION. This SDK supports local Schedules API version \"1\".',\n );\n }\n if (\n !advertisedBaseUrl ||\n !['http:', 'https:'].includes(advertisedBaseUrl.protocol) ||\n advertisedBaseUrl.username ||\n advertisedBaseUrl.password ||\n advertisedBaseUrl.search ||\n advertisedBaseUrl.hash\n ) {\n throw new Error(\n 'Local Schedules requires VERCEL_SCHEDULE_BASE_URL to be an absolute HTTP(S) URL without credentials, a query, or a fragment.',\n );\n }\n this.token = options.token ?? process.env.VERCEL_SCHEDULE_TOKEN;\n if (!this.token?.trim()) {\n throw new Error(\n 'Local Schedules requires VERCEL_SCHEDULE_TOKEN or an explicit token option.',\n );\n }\n } catch (err) {\n // Defer only selected-local configuration errors so the default\n // singleton does not prevent importing independent clients.\n this.configurationError =\n err instanceof Error ? err : new Error(String(err));\n return;\n }\n }\n\n this.baseUrl = new URL(\n options.baseUrl ?? envBaseUrl ?? DEFAULT_SCHEDULES_BASE_URL,\n );\n this.baseUrl.pathname = `${trimTrailingSlashes(this.baseUrl.pathname)}/`;\n }\n\n protected async getToken(): Promise<string> {\n if (this.configurationError) {\n throw this.configurationError;\n }\n if (this.token) {\n return this.token;\n }\n\n try {\n return await getVercelOidcToken();\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n const isDev = process.env.NODE_ENV === 'development';\n\n throw new Error(\n isDev\n ? 'Failed to get OIDC token for local development.\\n\\n' +\n 'To fix this, pull your environment variables with Vercel CLI:\\n' +\n ' `vercel env pull`\\n\\n' +\n `Cause: ${cause}`\n : 'Failed to get OIDC token. This usually means the function is running ' +\n 'outside of a Vercel Function environment.\\n\\n' +\n 'To fix this, either:\\n' +\n ' - Deploy to Vercel (OIDC tokens are provisioned automatically)\\n' +\n ' - Provide a token explicitly: `new Schedules({ token: \"...\" })`\\n\\n' +\n `Cause: ${cause}`,\n );\n }\n }\n\n protected async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n });\n\n if (body !== undefined) {\n headers.set('Content-Type', 'application/json');\n }\n\n const response = await this.fetchImpl(\n new URL(path.replace(/^\\/+/, ''), this.baseUrl),\n {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new SchedulesApiError(response.status, text || response.statusText);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return (await response.json()) as T;\n }\n}\n","export const DEFAULT_SCHEDULES_BASE_URL = 'https://vercel-schedules.com';\n","import { SchedulesApiClient } from './api-client';\nimport type {\n CreateScheduleParams,\n CreateScheduleResponse,\n InvokeScheduleParams,\n ListSchedulesParams,\n ListSchedulesResponse,\n Schedule,\n ScheduleIdentifier,\n UpdateScheduleParams,\n UpdateScheduleResponse,\n} from './types';\n\nfunction schedulePath(name: string, namespace?: string, suffix = ''): string {\n const searchParams = new URLSearchParams();\n\n if (namespace !== undefined) {\n searchParams.set('namespace', namespace);\n }\n\n const query = searchParams.toString();\n const path = `/v1/schedules/${encodeURIComponent(name)}${suffix}`;\n\n return query ? `${path}?${query}` : path;\n}\n\nexport class SchedulesClient extends SchedulesApiClient {\n create({\n target,\n ...params\n }: CreateScheduleParams): Promise<CreateScheduleResponse> {\n return this.request('POST', '/v1/schedules', {\n ...params,\n target: {\n type: 'queue',\n topic: target.topic,\n },\n });\n }\n\n list(params: ListSchedulesParams = {}): Promise<ListSchedulesResponse> {\n const searchParams = new URLSearchParams();\n\n if (params.namespace !== undefined) {\n searchParams.set('namespace', params.namespace);\n }\n if (params.cursor !== undefined) {\n searchParams.set('cursor', params.cursor);\n }\n if (params.limit !== undefined) {\n searchParams.set('limit', String(params.limit));\n }\n\n const query = searchParams.toString();\n const path = query ? `/v1/schedules?${query}` : '/v1/schedules';\n\n return this.request('GET', path);\n }\n\n get({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('GET', schedulePath(name, namespace));\n }\n\n update({\n name,\n namespace,\n target,\n ...params\n }: UpdateScheduleParams): Promise<UpdateScheduleResponse> {\n return this.request('PATCH', schedulePath(name, namespace), {\n ...params,\n ...(target === undefined\n ? {}\n : {\n target: {\n type: 'queue',\n topic: target.topic,\n },\n }),\n });\n }\n\n async delete({ name, namespace }: ScheduleIdentifier): Promise<void> {\n await this.request('DELETE', schedulePath(name, namespace));\n }\n\n enable({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('POST', schedulePath(name, namespace, '/enable'));\n }\n\n disable({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('POST', schedulePath(name, namespace, '/disable'));\n }\n\n async invoke({ name, namespace }: InvokeScheduleParams): Promise<void> {\n await this.request('POST', schedulePath(name, namespace, '/invoke'));\n }\n}\n","import { SchedulesClient } from './schedules';\n\nexport const schedules = new SchedulesClient();\n","/** CloudEvent type used for schedule function dispatches. */\nexport const SCHEDULE_CLOUD_EVENT_TYPE = 'com.vercel.schedule.v1beta';\nexport const CLOUD_EVENT_SPEC_VERSION_HEADER = 'ce-specversion';\nexport const CLOUD_EVENT_TYPE_HEADER = 'ce-type';\nexport const CLOUD_EVENT_SOURCE_HEADER = 'ce-source';\nexport const CLOUD_EVENT_ID_HEADER = 'ce-id';\nexport const SCHEDULE_SCHEDULED_AT_HEADER = 'ce-vssscheduledat';\nexport const SCHEDULE_ID_HEADER = 'ce-vssscheduleid';\nexport const SCHEDULE_NAME_HEADER = 'ce-vssschedulename';\nexport const SCHEDULE_NAMESPACE_HEADER = 'ce-vssnamespace';\nexport const SCHEDULE_SOURCE_HEADER = 'ce-vssschedulesource';\n\nexport interface ScheduleMetadata {\n /** Unique identifier of the schedule. */\n scheduleId: string;\n /** Unique identifier for this schedule occurrence. */\n executionId: string;\n /** Schedule name, unique within its project and namespace. */\n name: string;\n /** Namespace the schedule belongs to. */\n namespace: string;\n /**\n * Nominal scheduled time for this occurrence, based on the schedule expression.\n * Does not account for jitter. The dispatch may arrive later within the jitter window.\n */\n scheduledAt: Date;\n /** How the schedule was defined, such as `static`. */\n source: string;\n}\n\nexport type ScheduleHandler = (\n metadata: ScheduleMetadata,\n) => void | Promise<void>;\n\nexport class ScheduleEventParseError extends Error {\n cause?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = 'ScheduleEventParseError';\n if (options && 'cause' in options) {\n this.cause = options.cause;\n }\n }\n}\n\nfunction requiredHeader(request: Request, name: string): string {\n const value = request.headers.get(name);\n if (!value) {\n throw new ScheduleEventParseError(\n `Request is missing the ${name} header; it does not look like a schedule dispatch`,\n );\n }\n return value;\n}\n\n/** Parses schedule metadata from a binary-mode schedule CloudEvent. */\nexport async function parseScheduleEvent(\n request: Request,\n): Promise<ScheduleMetadata> {\n if (request.method !== 'POST') {\n throw new ScheduleEventParseError(\n `Schedule dispatches are POST requests, received ${request.method}`,\n );\n }\n\n const specVersion = requiredHeader(request, CLOUD_EVENT_SPEC_VERSION_HEADER);\n if (specVersion !== '1.0') {\n throw new ScheduleEventParseError(\n `Unsupported CloudEvent spec version: ${specVersion}`,\n );\n }\n\n const eventType = requiredHeader(request, CLOUD_EVENT_TYPE_HEADER);\n if (eventType !== SCHEDULE_CLOUD_EVENT_TYPE) {\n throw new ScheduleEventParseError(\n `Unsupported schedule CloudEvent type: ${eventType}`,\n );\n }\n\n requiredHeader(request, CLOUD_EVENT_SOURCE_HEADER);\n const executionId = requiredHeader(request, CLOUD_EVENT_ID_HEADER);\n const scheduledAtValue = requiredHeader(\n request,\n SCHEDULE_SCHEDULED_AT_HEADER,\n );\n const metadata: ScheduleMetadata = {\n scheduleId: requiredHeader(request, SCHEDULE_ID_HEADER),\n executionId,\n name: requiredHeader(request, SCHEDULE_NAME_HEADER),\n namespace: requiredHeader(request, SCHEDULE_NAMESPACE_HEADER),\n scheduledAt: new Date(scheduledAtValue),\n source: requiredHeader(request, SCHEDULE_SOURCE_HEADER),\n };\n\n if (Number.isNaN(metadata.scheduledAt.getTime())) {\n throw new ScheduleEventParseError(\n `Schedule scheduledAt is not a valid timestamp: ${scheduledAtValue}`,\n );\n }\n\n return metadata;\n}\n\n/**\n * Creates a web-standard route handler for schedule dispatches.\n *\n * ```ts\n * export const POST = handleSchedule(async (metadata) => {\n * console.log(metadata.name, metadata.scheduledAt);\n * });\n * ```\n */\nexport function handleSchedule(\n handler: ScheduleHandler,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let metadata: ScheduleMetadata;\n try {\n metadata = await parseScheduleEvent(request);\n } catch (error) {\n if (error instanceof ScheduleEventParseError) {\n return Response.json({ error: error.message }, { status: 400 });\n }\n return Response.json(\n { error: 'Failed to parse schedule dispatch' },\n { status: 500 },\n );\n }\n\n try {\n await handler(metadata);\n return new Response(null, { status: 200 });\n } catch {\n return Response.json(\n { error: 'Schedule handler failed' },\n { status: 500 },\n );\n }\n };\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/schedules/schedules/packages/schedules/dist/index.cjs","../src/api-client.ts","../src/constants.ts","../src/schedules.ts","../src/default-client.ts","../src/schedule-event.ts"],"names":[],"mappings":"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","file":"/home/runner/work/schedules/schedules/packages/schedules/dist/index.cjs","sourcesContent":[null,"import { getVercelOidcToken } from '@vercel/oidc';\nimport { DEFAULT_SCHEDULES_BASE_URL } from './constants';\n\nexport interface SchedulesApiClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: typeof fetch;\n}\n\nfunction trimTrailingSlashes(path: string): string {\n let end = path.length;\n while (end > 0 && path[end - 1] === '/') {\n end--;\n }\n return path.slice(0, end);\n}\n\nexport class SchedulesApiError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = 'SchedulesApiError';\n this.status = status;\n }\n}\n\nexport class SchedulesApiClient {\n private readonly baseUrl?: URL;\n private readonly token?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly configurationError?: Error;\n\n constructor(options: SchedulesApiClientOptions = {}) {\n this.token = options.token;\n this.fetchImpl = options.fetch ?? fetch;\n\n const envBaseUrl = process.env.VERCEL_SCHEDULE_BASE_URL;\n const devApiVersion = process.env.VERCEL_SCHEDULE_DEV_API_VERSION;\n let advertisedBaseUrl: URL | undefined;\n try {\n advertisedBaseUrl = new URL(envBaseUrl ?? '');\n } catch {\n // An independent explicit endpoint does not need the injected URL.\n }\n\n const explicitBaseUrl =\n options.baseUrl === undefined ? undefined : new URL(options.baseUrl);\n const localSelected =\n process.env.NODE_ENV === 'development' &&\n process.env.VERCEL_DEPLOYMENT_ID === undefined &&\n devApiVersion !== undefined &&\n (explicitBaseUrl === undefined ||\n (advertisedBaseUrl !== undefined &&\n explicitBaseUrl.origin === advertisedBaseUrl.origin &&\n trimTrailingSlashes(explicitBaseUrl.pathname) ===\n trimTrailingSlashes(advertisedBaseUrl.pathname)));\n\n if (localSelected) {\n try {\n if (devApiVersion !== '1') {\n throw new Error(\n 'Unsupported VERCEL_SCHEDULE_DEV_API_VERSION. This SDK supports local Schedules API version \"1\".',\n );\n }\n if (\n !advertisedBaseUrl ||\n !['http:', 'https:'].includes(advertisedBaseUrl.protocol) ||\n advertisedBaseUrl.username ||\n advertisedBaseUrl.password ||\n advertisedBaseUrl.search ||\n advertisedBaseUrl.hash\n ) {\n throw new Error(\n 'Local Schedules requires VERCEL_SCHEDULE_BASE_URL to be an absolute HTTP(S) URL without credentials, a query, or a fragment.',\n );\n }\n this.token = options.token ?? process.env.VERCEL_SCHEDULE_TOKEN;\n if (!this.token?.trim()) {\n throw new Error(\n 'Local Schedules requires VERCEL_SCHEDULE_TOKEN or an explicit token option.',\n );\n }\n } catch (err) {\n // Defer only selected-local configuration errors so the default\n // singleton does not prevent importing independent clients.\n this.configurationError =\n err instanceof Error ? err : new Error(String(err));\n return;\n }\n }\n\n this.baseUrl = new URL(\n options.baseUrl ?? envBaseUrl ?? DEFAULT_SCHEDULES_BASE_URL,\n );\n this.baseUrl.pathname = `${trimTrailingSlashes(this.baseUrl.pathname)}/`;\n }\n\n protected async getToken(): Promise<string> {\n if (this.configurationError) {\n throw this.configurationError;\n }\n if (this.token) {\n return this.token;\n }\n\n try {\n return await getVercelOidcToken();\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n const isDev = process.env.NODE_ENV === 'development';\n\n throw new Error(\n isDev\n ? 'Failed to get OIDC token for local development.\\n\\n' +\n 'To fix this, pull your environment variables with Vercel CLI:\\n' +\n ' `vercel env pull`\\n\\n' +\n `Cause: ${cause}`\n : 'Failed to get OIDC token. This usually means the function is running ' +\n 'outside of a Vercel Function environment.\\n\\n' +\n 'To fix this, either:\\n' +\n ' - Deploy to Vercel (OIDC tokens are provisioned automatically)\\n' +\n ' - Provide a token explicitly: `new Schedules({ token: \"...\" })`\\n\\n' +\n `Cause: ${cause}`,\n );\n }\n }\n\n protected async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n });\n\n if (body !== undefined) {\n headers.set('Content-Type', 'application/json');\n }\n\n const response = await this.fetchImpl(\n new URL(path.replace(/^\\/+/, ''), this.baseUrl),\n {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new SchedulesApiError(response.status, text || response.statusText);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return (await response.json()) as T;\n }\n}\n","export const DEFAULT_SCHEDULES_BASE_URL = 'https://vercel-schedules.com';\n","import { SchedulesApiClient } from './api-client';\nimport type {\n CreateScheduleParams,\n CreateScheduleResponse,\n InvokeScheduleParams,\n ListSchedulesParams,\n ListSchedulesResponse,\n Schedule,\n ScheduleIdentifier,\n UpdateScheduleParams,\n UpdateScheduleResponse,\n} from './types';\n\nfunction schedulePath(name: string, namespace?: string, suffix = ''): string {\n const searchParams = new URLSearchParams();\n\n if (namespace !== undefined) {\n searchParams.set('namespace', namespace);\n }\n\n const query = searchParams.toString();\n const path = `/v1/schedules/${encodeURIComponent(name)}${suffix}`;\n\n return query ? `${path}?${query}` : path;\n}\n\nexport class SchedulesClient extends SchedulesApiClient {\n create({\n target,\n ...params\n }: CreateScheduleParams): Promise<CreateScheduleResponse> {\n return this.request('POST', '/v1/schedules', {\n ...params,\n target: {\n type: 'queue',\n topic: target.topic,\n },\n });\n }\n\n list(params: ListSchedulesParams = {}): Promise<ListSchedulesResponse> {\n const searchParams = new URLSearchParams();\n\n if (params.namespace !== undefined) {\n searchParams.set('namespace', params.namespace);\n }\n if (params.cursor !== undefined) {\n searchParams.set('cursor', params.cursor);\n }\n if (params.limit !== undefined) {\n searchParams.set('limit', String(params.limit));\n }\n\n const query = searchParams.toString();\n const path = query ? `/v1/schedules?${query}` : '/v1/schedules';\n\n return this.request('GET', path);\n }\n\n get({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('GET', schedulePath(name, namespace));\n }\n\n update({\n name,\n namespace,\n target,\n ...params\n }: UpdateScheduleParams): Promise<UpdateScheduleResponse> {\n return this.request('PATCH', schedulePath(name, namespace), {\n ...params,\n ...(target === undefined\n ? {}\n : {\n target: {\n type: 'queue',\n topic: target.topic,\n },\n }),\n });\n }\n\n async delete({ name, namespace }: ScheduleIdentifier): Promise<void> {\n await this.request('DELETE', schedulePath(name, namespace));\n }\n\n enable({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('POST', schedulePath(name, namespace, '/enable'));\n }\n\n disable({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('POST', schedulePath(name, namespace, '/disable'));\n }\n\n async invoke({ name, namespace }: InvokeScheduleParams): Promise<void> {\n await this.request('POST', schedulePath(name, namespace, '/invoke'));\n }\n}\n","import { SchedulesClient } from './schedules';\n\nexport const schedules = new SchedulesClient();\n","/** CloudEvent type used for schedule function dispatches. */\nexport const SCHEDULE_CLOUD_EVENT_TYPE = 'com.vercel.schedule.v1beta';\nexport const CLOUD_EVENT_SPEC_VERSION_HEADER = 'ce-specversion';\nexport const CLOUD_EVENT_TYPE_HEADER = 'ce-type';\nexport const CLOUD_EVENT_SOURCE_HEADER = 'ce-source';\nexport const CLOUD_EVENT_ID_HEADER = 'ce-id';\nexport const SCHEDULE_SCHEDULED_AT_HEADER = 'ce-vssscheduledat';\nexport const SCHEDULE_ID_HEADER = 'ce-vssscheduleid';\nexport const SCHEDULE_NAME_HEADER = 'ce-vssschedulename';\nexport const SCHEDULE_NAMESPACE_HEADER = 'ce-vssnamespace';\nexport const SCHEDULE_SOURCE_HEADER = 'ce-vssschedulesource';\n\nexport interface ScheduleMetadata {\n /** Unique identifier of the schedule. */\n scheduleId: string;\n /** Unique identifier for this schedule occurrence. */\n executionId: string;\n /** Schedule name, unique within its project and namespace. */\n name: string;\n /** Namespace the schedule belongs to. */\n namespace: string;\n /**\n * Nominal scheduled time for this occurrence, based on the schedule expression.\n * Does not account for jitter. The dispatch may arrive later within the jitter window.\n */\n scheduledAt: Date;\n /** How the schedule was defined, such as `static`. */\n source: string;\n}\n\nexport type ScheduleHandler = (\n metadata: ScheduleMetadata,\n request: Request,\n) => void | Promise<void>;\n\nexport class ScheduleEventParseError extends Error {\n cause?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = 'ScheduleEventParseError';\n if (options && 'cause' in options) {\n this.cause = options.cause;\n }\n }\n}\n\nfunction requiredHeader(request: Request, name: string): string {\n const value = request.headers.get(name);\n if (!value) {\n throw new ScheduleEventParseError(\n `Request is missing the ${name} header; it does not look like a schedule dispatch`,\n );\n }\n return value;\n}\n\n/** Parses schedule metadata from a binary-mode schedule CloudEvent. */\nexport async function parseScheduleEvent(\n request: Request,\n): Promise<ScheduleMetadata> {\n if (request.method !== 'POST') {\n throw new ScheduleEventParseError(\n `Schedule dispatches are POST requests, received ${request.method}`,\n );\n }\n\n const specVersion = requiredHeader(request, CLOUD_EVENT_SPEC_VERSION_HEADER);\n if (specVersion !== '1.0') {\n throw new ScheduleEventParseError(\n `Unsupported CloudEvent spec version: ${specVersion}`,\n );\n }\n\n const eventType = requiredHeader(request, CLOUD_EVENT_TYPE_HEADER);\n if (eventType !== SCHEDULE_CLOUD_EVENT_TYPE) {\n throw new ScheduleEventParseError(\n `Unsupported schedule CloudEvent type: ${eventType}`,\n );\n }\n\n requiredHeader(request, CLOUD_EVENT_SOURCE_HEADER);\n const executionId = requiredHeader(request, CLOUD_EVENT_ID_HEADER);\n const scheduledAtValue = requiredHeader(\n request,\n SCHEDULE_SCHEDULED_AT_HEADER,\n );\n const metadata: ScheduleMetadata = {\n scheduleId: requiredHeader(request, SCHEDULE_ID_HEADER),\n executionId,\n name: requiredHeader(request, SCHEDULE_NAME_HEADER),\n namespace: requiredHeader(request, SCHEDULE_NAMESPACE_HEADER),\n scheduledAt: new Date(scheduledAtValue),\n source: requiredHeader(request, SCHEDULE_SOURCE_HEADER),\n };\n\n if (Number.isNaN(metadata.scheduledAt.getTime())) {\n throw new ScheduleEventParseError(\n `Schedule scheduledAt is not a valid timestamp: ${scheduledAtValue}`,\n );\n }\n\n return metadata;\n}\n\n/**\n * Creates a web-standard route handler for schedule dispatches.\n *\n * ```ts\n * export const POST = handleSchedule(async (metadata, request) => {\n * console.log(metadata.name, metadata.scheduledAt);\n * });\n * ```\n */\nexport function handleSchedule(\n handler: ScheduleHandler,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let metadata: ScheduleMetadata;\n try {\n metadata = await parseScheduleEvent(request);\n } catch (error) {\n if (error instanceof ScheduleEventParseError) {\n return Response.json({ error: error.message }, { status: 400 });\n }\n return Response.json(\n { error: 'Failed to parse schedule dispatch' },\n { status: 500 },\n );\n }\n\n try {\n await handler(metadata, request);\n return new Response(null, { status: 200 });\n } catch {\n return Response.json(\n { error: 'Schedule handler failed' },\n { status: 500 },\n );\n }\n };\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -135,7 +135,7 @@ interface ScheduleMetadata {
135
135
  /** How the schedule was defined, such as `static`. */
136
136
  source: string;
137
137
  }
138
- type ScheduleHandler = (metadata: ScheduleMetadata) => void | Promise<void>;
138
+ type ScheduleHandler = (metadata: ScheduleMetadata, request: Request) => void | Promise<void>;
139
139
  declare class ScheduleEventParseError extends Error {
140
140
  cause?: unknown;
141
141
  constructor(message: string, options?: {
@@ -148,7 +148,7 @@ declare function parseScheduleEvent(request: Request): Promise<ScheduleMetadata>
148
148
  * Creates a web-standard route handler for schedule dispatches.
149
149
  *
150
150
  * ```ts
151
- * export const POST = handleSchedule(async (metadata) => {
151
+ * export const POST = handleSchedule(async (metadata, request) => {
152
152
  * console.log(metadata.name, metadata.scheduledAt);
153
153
  * });
154
154
  * ```
package/dist/index.d.ts CHANGED
@@ -135,7 +135,7 @@ interface ScheduleMetadata {
135
135
  /** How the schedule was defined, such as `static`. */
136
136
  source: string;
137
137
  }
138
- type ScheduleHandler = (metadata: ScheduleMetadata) => void | Promise<void>;
138
+ type ScheduleHandler = (metadata: ScheduleMetadata, request: Request) => void | Promise<void>;
139
139
  declare class ScheduleEventParseError extends Error {
140
140
  cause?: unknown;
141
141
  constructor(message: string, options?: {
@@ -148,7 +148,7 @@ declare function parseScheduleEvent(request: Request): Promise<ScheduleMetadata>
148
148
  * Creates a web-standard route handler for schedule dispatches.
149
149
  *
150
150
  * ```ts
151
- * export const POST = handleSchedule(async (metadata) => {
151
+ * export const POST = handleSchedule(async (metadata, request) => {
152
152
  * console.log(metadata.name, metadata.scheduledAt);
153
153
  * });
154
154
  * ```
package/dist/index.js CHANGED
@@ -272,7 +272,7 @@ function handleSchedule(handler) {
272
272
  );
273
273
  }
274
274
  try {
275
- await handler(metadata);
275
+ await handler(metadata, request);
276
276
  return new Response(null, { status: 200 });
277
277
  } catch {
278
278
  return Response.json(
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api-client.ts","../src/constants.ts","../src/schedules.ts","../src/default-client.ts","../src/schedule-event.ts"],"sourcesContent":["import { getVercelOidcToken } from '@vercel/oidc';\nimport { DEFAULT_SCHEDULES_BASE_URL } from './constants';\n\nexport interface SchedulesApiClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: typeof fetch;\n}\n\nfunction trimTrailingSlashes(path: string): string {\n let end = path.length;\n while (end > 0 && path[end - 1] === '/') {\n end--;\n }\n return path.slice(0, end);\n}\n\nexport class SchedulesApiError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = 'SchedulesApiError';\n this.status = status;\n }\n}\n\nexport class SchedulesApiClient {\n private readonly baseUrl?: URL;\n private readonly token?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly configurationError?: Error;\n\n constructor(options: SchedulesApiClientOptions = {}) {\n this.token = options.token;\n this.fetchImpl = options.fetch ?? fetch;\n\n const envBaseUrl = process.env.VERCEL_SCHEDULE_BASE_URL;\n const devApiVersion = process.env.VERCEL_SCHEDULE_DEV_API_VERSION;\n let advertisedBaseUrl: URL | undefined;\n try {\n advertisedBaseUrl = new URL(envBaseUrl ?? '');\n } catch {\n // An independent explicit endpoint does not need the injected URL.\n }\n\n const explicitBaseUrl =\n options.baseUrl === undefined ? undefined : new URL(options.baseUrl);\n const localSelected =\n process.env.NODE_ENV === 'development' &&\n process.env.VERCEL_DEPLOYMENT_ID === undefined &&\n devApiVersion !== undefined &&\n (explicitBaseUrl === undefined ||\n (advertisedBaseUrl !== undefined &&\n explicitBaseUrl.origin === advertisedBaseUrl.origin &&\n trimTrailingSlashes(explicitBaseUrl.pathname) ===\n trimTrailingSlashes(advertisedBaseUrl.pathname)));\n\n if (localSelected) {\n try {\n if (devApiVersion !== '1') {\n throw new Error(\n 'Unsupported VERCEL_SCHEDULE_DEV_API_VERSION. This SDK supports local Schedules API version \"1\".',\n );\n }\n if (\n !advertisedBaseUrl ||\n !['http:', 'https:'].includes(advertisedBaseUrl.protocol) ||\n advertisedBaseUrl.username ||\n advertisedBaseUrl.password ||\n advertisedBaseUrl.search ||\n advertisedBaseUrl.hash\n ) {\n throw new Error(\n 'Local Schedules requires VERCEL_SCHEDULE_BASE_URL to be an absolute HTTP(S) URL without credentials, a query, or a fragment.',\n );\n }\n this.token = options.token ?? process.env.VERCEL_SCHEDULE_TOKEN;\n if (!this.token?.trim()) {\n throw new Error(\n 'Local Schedules requires VERCEL_SCHEDULE_TOKEN or an explicit token option.',\n );\n }\n } catch (err) {\n // Defer only selected-local configuration errors so the default\n // singleton does not prevent importing independent clients.\n this.configurationError =\n err instanceof Error ? err : new Error(String(err));\n return;\n }\n }\n\n this.baseUrl = new URL(\n options.baseUrl ?? envBaseUrl ?? DEFAULT_SCHEDULES_BASE_URL,\n );\n this.baseUrl.pathname = `${trimTrailingSlashes(this.baseUrl.pathname)}/`;\n }\n\n protected async getToken(): Promise<string> {\n if (this.configurationError) {\n throw this.configurationError;\n }\n if (this.token) {\n return this.token;\n }\n\n try {\n return await getVercelOidcToken();\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n const isDev = process.env.NODE_ENV === 'development';\n\n throw new Error(\n isDev\n ? 'Failed to get OIDC token for local development.\\n\\n' +\n 'To fix this, pull your environment variables with Vercel CLI:\\n' +\n ' `vercel env pull`\\n\\n' +\n `Cause: ${cause}`\n : 'Failed to get OIDC token. This usually means the function is running ' +\n 'outside of a Vercel Function environment.\\n\\n' +\n 'To fix this, either:\\n' +\n ' - Deploy to Vercel (OIDC tokens are provisioned automatically)\\n' +\n ' - Provide a token explicitly: `new Schedules({ token: \"...\" })`\\n\\n' +\n `Cause: ${cause}`,\n );\n }\n }\n\n protected async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n });\n\n if (body !== undefined) {\n headers.set('Content-Type', 'application/json');\n }\n\n const response = await this.fetchImpl(\n new URL(path.replace(/^\\/+/, ''), this.baseUrl),\n {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new SchedulesApiError(response.status, text || response.statusText);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return (await response.json()) as T;\n }\n}\n","export const DEFAULT_SCHEDULES_BASE_URL = 'https://vercel-schedules.com';\n","import { SchedulesApiClient } from './api-client';\nimport type {\n CreateScheduleParams,\n CreateScheduleResponse,\n InvokeScheduleParams,\n ListSchedulesParams,\n ListSchedulesResponse,\n Schedule,\n ScheduleIdentifier,\n UpdateScheduleParams,\n UpdateScheduleResponse,\n} from './types';\n\nfunction schedulePath(name: string, namespace?: string, suffix = ''): string {\n const searchParams = new URLSearchParams();\n\n if (namespace !== undefined) {\n searchParams.set('namespace', namespace);\n }\n\n const query = searchParams.toString();\n const path = `/v1/schedules/${encodeURIComponent(name)}${suffix}`;\n\n return query ? `${path}?${query}` : path;\n}\n\nexport class SchedulesClient extends SchedulesApiClient {\n create({\n target,\n ...params\n }: CreateScheduleParams): Promise<CreateScheduleResponse> {\n return this.request('POST', '/v1/schedules', {\n ...params,\n target: {\n type: 'queue',\n topic: target.topic,\n },\n });\n }\n\n list(params: ListSchedulesParams = {}): Promise<ListSchedulesResponse> {\n const searchParams = new URLSearchParams();\n\n if (params.namespace !== undefined) {\n searchParams.set('namespace', params.namespace);\n }\n if (params.cursor !== undefined) {\n searchParams.set('cursor', params.cursor);\n }\n if (params.limit !== undefined) {\n searchParams.set('limit', String(params.limit));\n }\n\n const query = searchParams.toString();\n const path = query ? `/v1/schedules?${query}` : '/v1/schedules';\n\n return this.request('GET', path);\n }\n\n get({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('GET', schedulePath(name, namespace));\n }\n\n update({\n name,\n namespace,\n target,\n ...params\n }: UpdateScheduleParams): Promise<UpdateScheduleResponse> {\n return this.request('PATCH', schedulePath(name, namespace), {\n ...params,\n ...(target === undefined\n ? {}\n : {\n target: {\n type: 'queue',\n topic: target.topic,\n },\n }),\n });\n }\n\n async delete({ name, namespace }: ScheduleIdentifier): Promise<void> {\n await this.request('DELETE', schedulePath(name, namespace));\n }\n\n enable({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('POST', schedulePath(name, namespace, '/enable'));\n }\n\n disable({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('POST', schedulePath(name, namespace, '/disable'));\n }\n\n async invoke({ name, namespace }: InvokeScheduleParams): Promise<void> {\n await this.request('POST', schedulePath(name, namespace, '/invoke'));\n }\n}\n","import { SchedulesClient } from './schedules';\n\nexport const schedules = new SchedulesClient();\n","/** CloudEvent type used for schedule function dispatches. */\nexport const SCHEDULE_CLOUD_EVENT_TYPE = 'com.vercel.schedule.v1beta';\nexport const CLOUD_EVENT_SPEC_VERSION_HEADER = 'ce-specversion';\nexport const CLOUD_EVENT_TYPE_HEADER = 'ce-type';\nexport const CLOUD_EVENT_SOURCE_HEADER = 'ce-source';\nexport const CLOUD_EVENT_ID_HEADER = 'ce-id';\nexport const SCHEDULE_SCHEDULED_AT_HEADER = 'ce-vssscheduledat';\nexport const SCHEDULE_ID_HEADER = 'ce-vssscheduleid';\nexport const SCHEDULE_NAME_HEADER = 'ce-vssschedulename';\nexport const SCHEDULE_NAMESPACE_HEADER = 'ce-vssnamespace';\nexport const SCHEDULE_SOURCE_HEADER = 'ce-vssschedulesource';\n\nexport interface ScheduleMetadata {\n /** Unique identifier of the schedule. */\n scheduleId: string;\n /** Unique identifier for this schedule occurrence. */\n executionId: string;\n /** Schedule name, unique within its project and namespace. */\n name: string;\n /** Namespace the schedule belongs to. */\n namespace: string;\n /**\n * Nominal scheduled time for this occurrence, based on the schedule expression.\n * Does not account for jitter. The dispatch may arrive later within the jitter window.\n */\n scheduledAt: Date;\n /** How the schedule was defined, such as `static`. */\n source: string;\n}\n\nexport type ScheduleHandler = (\n metadata: ScheduleMetadata,\n) => void | Promise<void>;\n\nexport class ScheduleEventParseError extends Error {\n cause?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = 'ScheduleEventParseError';\n if (options && 'cause' in options) {\n this.cause = options.cause;\n }\n }\n}\n\nfunction requiredHeader(request: Request, name: string): string {\n const value = request.headers.get(name);\n if (!value) {\n throw new ScheduleEventParseError(\n `Request is missing the ${name} header; it does not look like a schedule dispatch`,\n );\n }\n return value;\n}\n\n/** Parses schedule metadata from a binary-mode schedule CloudEvent. */\nexport async function parseScheduleEvent(\n request: Request,\n): Promise<ScheduleMetadata> {\n if (request.method !== 'POST') {\n throw new ScheduleEventParseError(\n `Schedule dispatches are POST requests, received ${request.method}`,\n );\n }\n\n const specVersion = requiredHeader(request, CLOUD_EVENT_SPEC_VERSION_HEADER);\n if (specVersion !== '1.0') {\n throw new ScheduleEventParseError(\n `Unsupported CloudEvent spec version: ${specVersion}`,\n );\n }\n\n const eventType = requiredHeader(request, CLOUD_EVENT_TYPE_HEADER);\n if (eventType !== SCHEDULE_CLOUD_EVENT_TYPE) {\n throw new ScheduleEventParseError(\n `Unsupported schedule CloudEvent type: ${eventType}`,\n );\n }\n\n requiredHeader(request, CLOUD_EVENT_SOURCE_HEADER);\n const executionId = requiredHeader(request, CLOUD_EVENT_ID_HEADER);\n const scheduledAtValue = requiredHeader(\n request,\n SCHEDULE_SCHEDULED_AT_HEADER,\n );\n const metadata: ScheduleMetadata = {\n scheduleId: requiredHeader(request, SCHEDULE_ID_HEADER),\n executionId,\n name: requiredHeader(request, SCHEDULE_NAME_HEADER),\n namespace: requiredHeader(request, SCHEDULE_NAMESPACE_HEADER),\n scheduledAt: new Date(scheduledAtValue),\n source: requiredHeader(request, SCHEDULE_SOURCE_HEADER),\n };\n\n if (Number.isNaN(metadata.scheduledAt.getTime())) {\n throw new ScheduleEventParseError(\n `Schedule scheduledAt is not a valid timestamp: ${scheduledAtValue}`,\n );\n }\n\n return metadata;\n}\n\n/**\n * Creates a web-standard route handler for schedule dispatches.\n *\n * ```ts\n * export const POST = handleSchedule(async (metadata) => {\n * console.log(metadata.name, metadata.scheduledAt);\n * });\n * ```\n */\nexport function handleSchedule(\n handler: ScheduleHandler,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let metadata: ScheduleMetadata;\n try {\n metadata = await parseScheduleEvent(request);\n } catch (error) {\n if (error instanceof ScheduleEventParseError) {\n return Response.json({ error: error.message }, { status: 400 });\n }\n return Response.json(\n { error: 'Failed to parse schedule dispatch' },\n { status: 500 },\n );\n }\n\n try {\n await handler(metadata);\n return new Response(null, { status: 200 });\n } catch {\n return Response.json(\n { error: 'Schedule handler failed' },\n { status: 500 },\n );\n }\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/api-client.ts","../src/constants.ts","../src/schedules.ts","../src/default-client.ts","../src/schedule-event.ts"],"sourcesContent":["import { getVercelOidcToken } from '@vercel/oidc';\nimport { DEFAULT_SCHEDULES_BASE_URL } from './constants';\n\nexport interface SchedulesApiClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: typeof fetch;\n}\n\nfunction trimTrailingSlashes(path: string): string {\n let end = path.length;\n while (end > 0 && path[end - 1] === '/') {\n end--;\n }\n return path.slice(0, end);\n}\n\nexport class SchedulesApiError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = 'SchedulesApiError';\n this.status = status;\n }\n}\n\nexport class SchedulesApiClient {\n private readonly baseUrl?: URL;\n private readonly token?: string;\n private readonly fetchImpl: typeof fetch;\n private readonly configurationError?: Error;\n\n constructor(options: SchedulesApiClientOptions = {}) {\n this.token = options.token;\n this.fetchImpl = options.fetch ?? fetch;\n\n const envBaseUrl = process.env.VERCEL_SCHEDULE_BASE_URL;\n const devApiVersion = process.env.VERCEL_SCHEDULE_DEV_API_VERSION;\n let advertisedBaseUrl: URL | undefined;\n try {\n advertisedBaseUrl = new URL(envBaseUrl ?? '');\n } catch {\n // An independent explicit endpoint does not need the injected URL.\n }\n\n const explicitBaseUrl =\n options.baseUrl === undefined ? undefined : new URL(options.baseUrl);\n const localSelected =\n process.env.NODE_ENV === 'development' &&\n process.env.VERCEL_DEPLOYMENT_ID === undefined &&\n devApiVersion !== undefined &&\n (explicitBaseUrl === undefined ||\n (advertisedBaseUrl !== undefined &&\n explicitBaseUrl.origin === advertisedBaseUrl.origin &&\n trimTrailingSlashes(explicitBaseUrl.pathname) ===\n trimTrailingSlashes(advertisedBaseUrl.pathname)));\n\n if (localSelected) {\n try {\n if (devApiVersion !== '1') {\n throw new Error(\n 'Unsupported VERCEL_SCHEDULE_DEV_API_VERSION. This SDK supports local Schedules API version \"1\".',\n );\n }\n if (\n !advertisedBaseUrl ||\n !['http:', 'https:'].includes(advertisedBaseUrl.protocol) ||\n advertisedBaseUrl.username ||\n advertisedBaseUrl.password ||\n advertisedBaseUrl.search ||\n advertisedBaseUrl.hash\n ) {\n throw new Error(\n 'Local Schedules requires VERCEL_SCHEDULE_BASE_URL to be an absolute HTTP(S) URL without credentials, a query, or a fragment.',\n );\n }\n this.token = options.token ?? process.env.VERCEL_SCHEDULE_TOKEN;\n if (!this.token?.trim()) {\n throw new Error(\n 'Local Schedules requires VERCEL_SCHEDULE_TOKEN or an explicit token option.',\n );\n }\n } catch (err) {\n // Defer only selected-local configuration errors so the default\n // singleton does not prevent importing independent clients.\n this.configurationError =\n err instanceof Error ? err : new Error(String(err));\n return;\n }\n }\n\n this.baseUrl = new URL(\n options.baseUrl ?? envBaseUrl ?? DEFAULT_SCHEDULES_BASE_URL,\n );\n this.baseUrl.pathname = `${trimTrailingSlashes(this.baseUrl.pathname)}/`;\n }\n\n protected async getToken(): Promise<string> {\n if (this.configurationError) {\n throw this.configurationError;\n }\n if (this.token) {\n return this.token;\n }\n\n try {\n return await getVercelOidcToken();\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n const isDev = process.env.NODE_ENV === 'development';\n\n throw new Error(\n isDev\n ? 'Failed to get OIDC token for local development.\\n\\n' +\n 'To fix this, pull your environment variables with Vercel CLI:\\n' +\n ' `vercel env pull`\\n\\n' +\n `Cause: ${cause}`\n : 'Failed to get OIDC token. This usually means the function is running ' +\n 'outside of a Vercel Function environment.\\n\\n' +\n 'To fix this, either:\\n' +\n ' - Deploy to Vercel (OIDC tokens are provisioned automatically)\\n' +\n ' - Provide a token explicitly: `new Schedules({ token: \"...\" })`\\n\\n' +\n `Cause: ${cause}`,\n );\n }\n }\n\n protected async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n });\n\n if (body !== undefined) {\n headers.set('Content-Type', 'application/json');\n }\n\n const response = await this.fetchImpl(\n new URL(path.replace(/^\\/+/, ''), this.baseUrl),\n {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new SchedulesApiError(response.status, text || response.statusText);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return (await response.json()) as T;\n }\n}\n","export const DEFAULT_SCHEDULES_BASE_URL = 'https://vercel-schedules.com';\n","import { SchedulesApiClient } from './api-client';\nimport type {\n CreateScheduleParams,\n CreateScheduleResponse,\n InvokeScheduleParams,\n ListSchedulesParams,\n ListSchedulesResponse,\n Schedule,\n ScheduleIdentifier,\n UpdateScheduleParams,\n UpdateScheduleResponse,\n} from './types';\n\nfunction schedulePath(name: string, namespace?: string, suffix = ''): string {\n const searchParams = new URLSearchParams();\n\n if (namespace !== undefined) {\n searchParams.set('namespace', namespace);\n }\n\n const query = searchParams.toString();\n const path = `/v1/schedules/${encodeURIComponent(name)}${suffix}`;\n\n return query ? `${path}?${query}` : path;\n}\n\nexport class SchedulesClient extends SchedulesApiClient {\n create({\n target,\n ...params\n }: CreateScheduleParams): Promise<CreateScheduleResponse> {\n return this.request('POST', '/v1/schedules', {\n ...params,\n target: {\n type: 'queue',\n topic: target.topic,\n },\n });\n }\n\n list(params: ListSchedulesParams = {}): Promise<ListSchedulesResponse> {\n const searchParams = new URLSearchParams();\n\n if (params.namespace !== undefined) {\n searchParams.set('namespace', params.namespace);\n }\n if (params.cursor !== undefined) {\n searchParams.set('cursor', params.cursor);\n }\n if (params.limit !== undefined) {\n searchParams.set('limit', String(params.limit));\n }\n\n const query = searchParams.toString();\n const path = query ? `/v1/schedules?${query}` : '/v1/schedules';\n\n return this.request('GET', path);\n }\n\n get({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('GET', schedulePath(name, namespace));\n }\n\n update({\n name,\n namespace,\n target,\n ...params\n }: UpdateScheduleParams): Promise<UpdateScheduleResponse> {\n return this.request('PATCH', schedulePath(name, namespace), {\n ...params,\n ...(target === undefined\n ? {}\n : {\n target: {\n type: 'queue',\n topic: target.topic,\n },\n }),\n });\n }\n\n async delete({ name, namespace }: ScheduleIdentifier): Promise<void> {\n await this.request('DELETE', schedulePath(name, namespace));\n }\n\n enable({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('POST', schedulePath(name, namespace, '/enable'));\n }\n\n disable({ name, namespace }: ScheduleIdentifier): Promise<Schedule> {\n return this.request('POST', schedulePath(name, namespace, '/disable'));\n }\n\n async invoke({ name, namespace }: InvokeScheduleParams): Promise<void> {\n await this.request('POST', schedulePath(name, namespace, '/invoke'));\n }\n}\n","import { SchedulesClient } from './schedules';\n\nexport const schedules = new SchedulesClient();\n","/** CloudEvent type used for schedule function dispatches. */\nexport const SCHEDULE_CLOUD_EVENT_TYPE = 'com.vercel.schedule.v1beta';\nexport const CLOUD_EVENT_SPEC_VERSION_HEADER = 'ce-specversion';\nexport const CLOUD_EVENT_TYPE_HEADER = 'ce-type';\nexport const CLOUD_EVENT_SOURCE_HEADER = 'ce-source';\nexport const CLOUD_EVENT_ID_HEADER = 'ce-id';\nexport const SCHEDULE_SCHEDULED_AT_HEADER = 'ce-vssscheduledat';\nexport const SCHEDULE_ID_HEADER = 'ce-vssscheduleid';\nexport const SCHEDULE_NAME_HEADER = 'ce-vssschedulename';\nexport const SCHEDULE_NAMESPACE_HEADER = 'ce-vssnamespace';\nexport const SCHEDULE_SOURCE_HEADER = 'ce-vssschedulesource';\n\nexport interface ScheduleMetadata {\n /** Unique identifier of the schedule. */\n scheduleId: string;\n /** Unique identifier for this schedule occurrence. */\n executionId: string;\n /** Schedule name, unique within its project and namespace. */\n name: string;\n /** Namespace the schedule belongs to. */\n namespace: string;\n /**\n * Nominal scheduled time for this occurrence, based on the schedule expression.\n * Does not account for jitter. The dispatch may arrive later within the jitter window.\n */\n scheduledAt: Date;\n /** How the schedule was defined, such as `static`. */\n source: string;\n}\n\nexport type ScheduleHandler = (\n metadata: ScheduleMetadata,\n request: Request,\n) => void | Promise<void>;\n\nexport class ScheduleEventParseError extends Error {\n cause?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = 'ScheduleEventParseError';\n if (options && 'cause' in options) {\n this.cause = options.cause;\n }\n }\n}\n\nfunction requiredHeader(request: Request, name: string): string {\n const value = request.headers.get(name);\n if (!value) {\n throw new ScheduleEventParseError(\n `Request is missing the ${name} header; it does not look like a schedule dispatch`,\n );\n }\n return value;\n}\n\n/** Parses schedule metadata from a binary-mode schedule CloudEvent. */\nexport async function parseScheduleEvent(\n request: Request,\n): Promise<ScheduleMetadata> {\n if (request.method !== 'POST') {\n throw new ScheduleEventParseError(\n `Schedule dispatches are POST requests, received ${request.method}`,\n );\n }\n\n const specVersion = requiredHeader(request, CLOUD_EVENT_SPEC_VERSION_HEADER);\n if (specVersion !== '1.0') {\n throw new ScheduleEventParseError(\n `Unsupported CloudEvent spec version: ${specVersion}`,\n );\n }\n\n const eventType = requiredHeader(request, CLOUD_EVENT_TYPE_HEADER);\n if (eventType !== SCHEDULE_CLOUD_EVENT_TYPE) {\n throw new ScheduleEventParseError(\n `Unsupported schedule CloudEvent type: ${eventType}`,\n );\n }\n\n requiredHeader(request, CLOUD_EVENT_SOURCE_HEADER);\n const executionId = requiredHeader(request, CLOUD_EVENT_ID_HEADER);\n const scheduledAtValue = requiredHeader(\n request,\n SCHEDULE_SCHEDULED_AT_HEADER,\n );\n const metadata: ScheduleMetadata = {\n scheduleId: requiredHeader(request, SCHEDULE_ID_HEADER),\n executionId,\n name: requiredHeader(request, SCHEDULE_NAME_HEADER),\n namespace: requiredHeader(request, SCHEDULE_NAMESPACE_HEADER),\n scheduledAt: new Date(scheduledAtValue),\n source: requiredHeader(request, SCHEDULE_SOURCE_HEADER),\n };\n\n if (Number.isNaN(metadata.scheduledAt.getTime())) {\n throw new ScheduleEventParseError(\n `Schedule scheduledAt is not a valid timestamp: ${scheduledAtValue}`,\n );\n }\n\n return metadata;\n}\n\n/**\n * Creates a web-standard route handler for schedule dispatches.\n *\n * ```ts\n * export const POST = handleSchedule(async (metadata, request) => {\n * console.log(metadata.name, metadata.scheduledAt);\n * });\n * ```\n */\nexport function handleSchedule(\n handler: ScheduleHandler,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let metadata: ScheduleMetadata;\n try {\n metadata = await parseScheduleEvent(request);\n } catch (error) {\n if (error instanceof ScheduleEventParseError) {\n return Response.json({ error: error.message }, { status: 400 });\n }\n return Response.json(\n { error: 'Failed to parse schedule dispatch' },\n { status: 500 },\n );\n }\n\n try {\n await handler(metadata, request);\n return new Response(null, { status: 200 });\n } catch {\n return Response.json(\n { error: 'Schedule handler failed' },\n { status: 500 },\n );\n }\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/schedules",
3
- "version": "0.0.0-alpha.11",
3
+ "version": "0.0.0-alpha.12",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },