@keystrokehq/keystroke 0.1.57 → 0.1.58

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/dist/trigger.cjs CHANGED
@@ -8518,23 +8518,46 @@ function isMinuteLevelCron(schedule) {
8518
8518
  function resolveCronSchedule(attachmentId, schedule, options) {
8519
8519
  return options.attachmentScheduleOverrides?.[attachmentId] ?? options.cronScheduleOverride ?? schedule;
8520
8520
  }
8521
+ /** Default timezone when none is authored — preserves historical UTC evaluation. */
8522
+ const DEFAULT_TRIGGER_TIMEZONE = "UTC";
8523
+ /**
8524
+ * Validates and brands an IANA timezone (e.g. `America/New_York`). Uses
8525
+ * `Intl.DateTimeFormat` so we don't need a timezone database dependency.
8526
+ */
8527
+ const timezoneSchema = zod.z.string().trim().min(1, "timezone must be a non-empty IANA timezone").refine(isValidIanaTimezone, "must be a valid IANA timezone").brand();
8528
+ /** Parse/validate an IANA timezone (throws on failure). */
8529
+ function parseTimezone(value) {
8530
+ return timezoneSchema.parse(value);
8531
+ }
8532
+ function isValidIanaTimezone(value) {
8533
+ try {
8534
+ new Intl.DateTimeFormat("en-US", { timeZone: value });
8535
+ return true;
8536
+ } catch {
8537
+ return false;
8538
+ }
8539
+ }
8521
8540
  /** Parse a schedule into a `cron-parser` expression (throws on invalid input). */
8522
- function parseTriggerSchedule(schedule) {
8523
- return parseCronExpression(schedule);
8541
+ function parseTriggerSchedule(schedule, timezone = "UTC") {
8542
+ return parseCronExpression(schedule, void 0, timezone);
8524
8543
  }
8525
- /** The next time the schedule fires at or after `from`. */
8526
- function nextTriggerRunAt(schedule, from = /* @__PURE__ */ new Date()) {
8527
- return parseCronExpression(schedule, from).next().toDate();
8544
+ /**
8545
+ * The next time the schedule fires at or after `from`.
8546
+ *
8547
+ * Cron fields are wall-clock times in `timezone` (default UTC). Absolute
8548
+ * instants are computed here — do not convert the cron string to UTC at write time.
8549
+ */
8550
+ function nextTriggerRunAt(schedule, from = /* @__PURE__ */ new Date(), timezone = "UTC") {
8551
+ return parseCronExpression(schedule, from, timezone).next().toDate();
8528
8552
  }
8529
- const UTC = "UTC";
8530
8553
  /**
8531
8554
  * Single touchpoint for the `cron-parser` library — every parse, validation,
8532
8555
  * and next-run calculation in this package goes through here.
8533
8556
  */
8534
- function parseCronExpression(schedule, currentDate) {
8557
+ function parseCronExpression(schedule, currentDate, timezone = "UTC") {
8535
8558
  return import_dist.CronExpressionParser.parse(schedule, {
8536
8559
  currentDate: currentDate ?? /* @__PURE__ */ new Date(),
8537
- tz: UTC
8560
+ tz: timezone
8538
8561
  });
8539
8562
  }
8540
8563
  function isParseableCron(value) {
@@ -8595,6 +8618,7 @@ const cronSourceSchema = zod.z.object({
8595
8618
  kind: zod.z.literal("cron"),
8596
8619
  ...baseSourceShape,
8597
8620
  schedule: cronScheduleSchema,
8621
+ timezone: timezoneSchema.optional(),
8598
8622
  payload: cronPayloadSchema.optional()
8599
8623
  });
8600
8624
  const pollSourceSchema = zod.z.object({
@@ -8602,6 +8626,7 @@ const pollSourceSchema = zod.z.object({
8602
8626
  ...baseSourceShape,
8603
8627
  id: zod.z.string().optional(),
8604
8628
  schedule: pollScheduleSchema,
8629
+ timezone: timezoneSchema.optional(),
8605
8630
  run: zod.z.function(),
8606
8631
  stateSchema: zodSchema.optional(),
8607
8632
  filters: zod.z.array(zod.z.function()),
@@ -8935,6 +8960,8 @@ function defineWebhookSource(options) {
8935
8960
  * `"0 9 * * *"`) for compile-time shape checking, or wrap with
8936
8961
  * `parseCronSchedule(...)` for 6-field, named (`MON`), or `@daily`-style
8937
8962
  * schedules. Validated at runtime; throws if the expression is invalid.
8963
+ * @param options.timezone - Optional IANA timezone (e.g. `America/New_York`).
8964
+ * Cron fields are wall-clock times in this zone. When omitted, UTC.
8938
8965
  * @param options.payload - Optional static JSON payload passed to attachments on
8939
8966
  * each tick (like a webhook body). When omitted, attachments receive `{}`.
8940
8967
  * Without a `transform`, the payload must be assignable to the workflow input.
@@ -8944,12 +8971,14 @@ function defineWebhookSource(options) {
8944
8971
  * defineCronSource({
8945
8972
  * slug: "morning-report",
8946
8973
  * schedule: "0 9 * * *",
8974
+ * timezone: "America/New_York",
8947
8975
  * payload: { report: "daily", region: "us" },
8948
8976
  * }).attach({ workflow });
8949
8977
  */
8950
8978
  function defineCronSource(options) {
8951
8979
  const sourceSlug = resolveAuthoringSlug(options, "defineCronSource");
8952
8980
  const schedule = parseCronSchedule(options.schedule);
8981
+ const timezone = options.timezone === void 0 ? void 0 : parseTimezone(options.timezone);
8953
8982
  const name = requireTriggerDisplayText(options.name, "name", "defineCronSource");
8954
8983
  const description = requireTriggerDisplayText(options.description, "description", "defineCronSource");
8955
8984
  const payload = options.payload === void 0 ? void 0 : parseCronPayload(options.payload);
@@ -8959,6 +8988,7 @@ function defineCronSource(options) {
8959
8988
  name,
8960
8989
  description,
8961
8990
  schedule,
8991
+ ...timezone !== void 0 ? { timezone } : {},
8962
8992
  ...payload !== void 0 ? { payload } : {},
8963
8993
  attach(attachOptions) {
8964
8994
  return attachFromSource(source, sourceSlug, attachOptions);
@@ -8969,6 +8999,7 @@ function defineCronSource(options) {
8969
8999
  function definePollSource(options) {
8970
9000
  const sourceSlug = resolveAuthoringSlug(options, "definePollSource");
8971
9001
  const schedule = parsePollSchedule(options.schedule);
9002
+ const timezone = options.timezone === void 0 ? void 0 : parseTimezone(options.timezone);
8972
9003
  const name = requireTriggerDisplayText(options.name, "name", "definePollSource");
8973
9004
  const description = requireTriggerDisplayText(options.description, "description", "definePollSource");
8974
9005
  if (options.state && options.id) throw new Error("definePollSource: `state` and `id` (poll grouping) cannot be used together");
@@ -8981,6 +9012,7 @@ function definePollSource(options) {
8981
9012
  description,
8982
9013
  id: options.id,
8983
9014
  schedule,
9015
+ ...timezone !== void 0 ? { timezone } : {},
8984
9016
  run: options.run,
8985
9017
  stateSchema: options.state,
8986
9018
  filters,
@@ -9076,6 +9108,7 @@ function resolveAttachmentInput(attachment, payload) {
9076
9108
  return applyAttachmentTransform(attachment, payload);
9077
9109
  }
9078
9110
  //#endregion
9111
+ exports.DEFAULT_TRIGGER_TIMEZONE = DEFAULT_TRIGGER_TIMEZONE;
9079
9112
  exports.TRIGGER_ATTACHMENT = TRIGGER_ATTACHMENT;
9080
9113
  exports.TRIGGER_ATTACHMENT_SIBLINGS = TRIGGER_ATTACHMENT_SIBLINGS;
9081
9114
  exports.agentKeyFromAgent = agentKeyFromAgent;
@@ -9101,6 +9134,7 @@ exports.normalizeWebhookEndpoint = normalizeWebhookEndpoint;
9101
9134
  exports.parseCronPayload = parseCronPayload;
9102
9135
  exports.parseCronSchedule = parseCronSchedule;
9103
9136
  exports.parsePollSchedule = parsePollSchedule;
9137
+ exports.parseTimezone = parseTimezone;
9104
9138
  exports.parseTriggerSchedule = parseTriggerSchedule;
9105
9139
  exports.pollScheduleSchema = pollScheduleSchema;
9106
9140
  exports.resolveAgentPrompt = resolveAgentPrompt;
@@ -9109,6 +9143,7 @@ exports.resolveAttachmentTransform = resolveAttachmentTransform;
9109
9143
  exports.resolveAuthoringSlug = resolveAuthoringSlug;
9110
9144
  exports.resolveCronSchedule = resolveCronSchedule;
9111
9145
  exports.sourceSlugFrom = sourceSlugFrom;
9146
+ exports.timezoneSchema = timezoneSchema;
9112
9147
  exports.triggerAttachmentsFromExport = triggerAttachmentsFromExport;
9113
9148
  exports.triggerMetaFromAttachment = triggerMetaFromAttachment;
9114
9149
  exports.triggerMetaFromSource = triggerMetaFromSource;