{"version":3,"file":"strings.cjs","names":["hashjs","isTemporalInstant","isTemporalZonedDateTime","getISOString","milliseconds: number","isTemporalDuration","Temporal","timeStr"],"sources":["../../src/helpers/strings.ts"],"sourcesContent":["import hashjs from \"hash.js\";\nimport { default as safeStringify } from \"json-stringify-safe\";\nimport ms from \"ms\";\nimport { Temporal } from \"temporal-polyfill\";\nimport type { TimeStr } from \"../types.ts\";\nimport {\n  type DurationLike,\n  getISOString,\n  type InstantLike,\n  isTemporalDuration,\n  isTemporalInstant,\n  isTemporalZonedDateTime,\n  type ZonedDateTimeLike,\n} from \"./temporal.ts\";\n\nconst { sha256 } = hashjs;\n\n/**\n * Constant-time equality check for two strings. Returns `false` immediately if\n * lengths differ; otherwise XOR-accumulates every char code so the total time\n * is independent of where (or whether) the strings diverge.\n *\n * Used for HMAC signature verification — `===`/`!==` short-circuit on the\n * first mismatched character and leak the matching-prefix length via timing.\n */\nexport function timingSafeEqual(a: string, b: string): boolean {\n  if (a.length !== b.length) {\n    return false;\n  }\n\n  let diff = 0;\n  for (let i = 0; i < a.length; i++) {\n    diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n  }\n  return diff === 0;\n}\n\n/**\n * Safely `JSON.stringify()` an `input`, handling circular refernences and\n * removing `BigInt` values.\n */\n// biome-ignore lint/suspicious/noExplicitAny: intentional\nexport const stringify = (input: any): string => {\n  return safeStringify(input, (_key, value) => {\n    if (typeof value !== \"bigint\") {\n      return value;\n    }\n  });\n};\n\n/**\n * Returns a slugified string used to generate consistent IDs.\n *\n * This can be used to generate a consistent ID for a function when migrating\n * from v2 to v3 of the SDK.\n *\n * @public\n */\nexport const slugify = (str: string): string => {\n  const join = \"-\";\n  return str\n    .toLowerCase()\n    .replace(/[^a-z0-9-]+/g, join)\n    .replace(/-+/g, join)\n    .split(join)\n    .filter(Boolean)\n    .join(join);\n};\n\nconst millisecond = 1;\nconst second = millisecond * 1000;\nconst minute = second * 60;\nconst hour = minute * 60;\nconst day = hour * 24;\nconst week = day * 7;\n\n/**\n * A collection of periods in milliseconds and their suffixes used when creating\n * time strings.\n */\nconst periods = [\n  [\"w\", week],\n  [\"d\", day],\n  [\"h\", hour],\n  [\"m\", minute],\n  [\"s\", second],\n] as const;\n\n/**\n * Convert a given `Date`, `number`, or `ms`-compatible `string` to a\n * Inngest sleep-compatible time string (e.g. `\"1d\"` or `\"2h3010s\"`).\n */\nexport const timeStr = (\n  /**\n   * The future date to use to convert to a time string.\n   */\n  input:\n    | string\n    | number\n    | Date\n    | DurationLike\n    | InstantLike\n    | ZonedDateTimeLike,\n): string => {\n  if (input instanceof Date) {\n    return input.toISOString();\n  }\n\n  if (isTemporalInstant(input) || isTemporalZonedDateTime(input)) {\n    return getISOString(input);\n  }\n\n  let milliseconds: number;\n  if (isTemporalDuration(input)) {\n    // `relativeTo` is required for calendar units (months/years/weeks). We\n    // pass it as an ISO string rather than a Temporal object so this works\n    // regardless of which Temporal implementation the user's Duration came\n    // from (temporal-polyfill, @js-temporal/polyfill, native Temporal):\n    // ISO strings are spec-defined and parsed by every implementation;\n    // cross-polyfill object passing is not.\n    milliseconds = input.total({\n      unit: \"milliseconds\",\n      relativeTo: Temporal.Now.plainDateTimeISO(\"UTC\").toString(),\n    });\n  } else if (typeof input === \"string\") {\n    milliseconds = ms(input as `${number}`);\n  } else {\n    milliseconds = input as number;\n  }\n\n  const [, timeStr] = periods.reduce<[number, string]>(\n    ([num, str], [suffix, period]) => {\n      const numPeriods = Math.floor(num / period);\n\n      if (numPeriods > 0) {\n        return [num % period, `${str}${numPeriods}${suffix}`];\n      }\n\n      return [num, str];\n    },\n    [milliseconds, \"\"],\n  );\n\n  return timeStr as TimeStr;\n};\n\n/**\n * Given an unknown input, stringify it if it's a boolean, a number, or a\n * string, else return `undefined`.\n */\nexport const stringifyUnknown = (input: unknown): string | undefined => {\n  if (\n    typeof input === \"boolean\" ||\n    typeof input === \"number\" ||\n    typeof input === \"string\"\n  ) {\n    return input.toString();\n  }\n\n  return;\n};\n\nexport const hashEventKey = (eventKey: string): string => {\n  return sha256().update(eventKey).digest(\"hex\");\n};\n\nexport const hashSigningKey = (signingKey: string | undefined): string => {\n  if (!signingKey) {\n    return \"\";\n  }\n\n  const prefix = signingKey.match(/^signkey-[\\w]+-/)?.shift() || \"\";\n  const key = removeSigningKeyPrefix(signingKey);\n\n  // Decode the key from its hex representation into a bytestream\n  return `${prefix}${sha256().update(key, \"hex\").digest(\"hex\")}`;\n};\n\nexport function removeSigningKeyPrefix(signingKey: string): string {\n  return signingKey.replace(/^signkey-[\\w]+-/, \"\");\n}\n"],"mappings":";;;;;;;;;;;AAeA,MAAM,EAAE,WAAWA;;;;;;;;;AAUnB,SAAgB,gBAAgB,GAAW,GAAoB;AAC7D,KAAI,EAAE,WAAW,EAAE,OACjB,QAAO;CAGT,IAAI,OAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAC5B,SAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE;AAE3C,QAAO,SAAS;;;;;;AAQlB,MAAa,aAAa,UAAuB;AAC/C,yCAAqB,QAAQ,MAAM,UAAU;AAC3C,MAAI,OAAO,UAAU,SACnB,QAAO;GAET;;;;;;;;;;AAWJ,MAAa,WAAW,QAAwB;CAC9C,MAAM,OAAO;AACb,QAAO,IACJ,aAAa,CACb,QAAQ,gBAAgB,KAAK,CAC7B,QAAQ,OAAO,KAAK,CACpB,MAAM,KAAK,CACX,OAAO,QAAQ,CACf,KAAK,KAAK;;AAIf,MAAM,SADc,IACS;AAC7B,MAAM,SAAS,SAAS;AACxB,MAAM,OAAO,SAAS;AACtB,MAAM,MAAM,OAAO;;;;;AAOnB,MAAM,UAAU;CACd,CAAC,KAPU,MAAM,EAON;CACX,CAAC,KAAK,IAAI;CACV,CAAC,KAAK,KAAK;CACX,CAAC,KAAK,OAAO;CACb,CAAC,KAAK,OAAO;CACd;;;;;AAMD,MAAa,WAIX,UAOW;AACX,KAAI,iBAAiB,KACnB,QAAO,MAAM,aAAa;AAG5B,KAAIC,mCAAkB,MAAM,IAAIC,yCAAwB,MAAM,CAC5D,QAAOC,8BAAa,MAAM;CAG5B,IAAIC;AACJ,KAAIC,oCAAmB,MAAM,CAO3B,gBAAe,MAAM,MAAM;EACzB,MAAM;EACN,YAAYC,2BAAS,IAAI,iBAAiB,MAAM,CAAC,UAAU;EAC5D,CAAC;UACO,OAAO,UAAU,SAC1B,gCAAkB,MAAqB;KAEvC,gBAAe;CAGjB,MAAM,GAAGC,aAAW,QAAQ,QACzB,CAAC,KAAK,MAAM,CAAC,QAAQ,YAAY;EAChC,MAAM,aAAa,KAAK,MAAM,MAAM,OAAO;AAE3C,MAAI,aAAa,EACf,QAAO,CAAC,MAAM,QAAQ,GAAG,MAAM,aAAa,SAAS;AAGvD,SAAO,CAAC,KAAK,IAAI;IAEnB,CAAC,cAAc,GAAG,CACnB;AAED,QAAOA;;AAmBT,MAAa,gBAAgB,aAA6B;AACxD,QAAO,QAAQ,CAAC,OAAO,SAAS,CAAC,OAAO,MAAM;;AAGhD,MAAa,kBAAkB,eAA2C;AACxE,KAAI,CAAC,WACH,QAAO;CAGT,MAAM,SAAS,WAAW,MAAM,kBAAkB,EAAE,OAAO,IAAI;CAC/D,MAAM,MAAM,uBAAuB,WAAW;AAG9C,QAAO,GAAG,SAAS,QAAQ,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,MAAM;;AAG9D,SAAgB,uBAAuB,YAA4B;AACjE,QAAO,WAAW,QAAQ,mBAAmB,GAAG"}