inngest
Version:
Official SDK for Inngest.com. Inngest is the reliability layer for modern applications. Inngest combines durable execution, events, and queues into a zero-infra platform with built-in observability.
95 lines (93 loc) • 3.25 kB
JavaScript
import { getISOString, isTemporalDuration, isTemporalInstant, isTemporalZonedDateTime } from "./temporal.js";
import stringify from "json-stringify-safe";
import hashjs from "hash.js";
import ms from "ms";
import { Temporal } from "temporal-polyfill";
//#region src/helpers/strings.ts
const { sha256 } = hashjs;
/**
* Constant-time equality check for two strings. Returns `false` immediately if
* lengths differ; otherwise XOR-accumulates every char code so the total time
* is independent of where (or whether) the strings diverge.
*
* Used for HMAC signature verification — `===`/`!==` short-circuit on the
* first mismatched character and leak the matching-prefix length via timing.
*/
function timingSafeEqual(a, b) {
if (a.length !== b.length) return false;
let diff = 0;
for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
return diff === 0;
}
/**
* Safely `JSON.stringify()` an `input`, handling circular refernences and
* removing `BigInt` values.
*/
const stringify$1 = (input) => {
return stringify(input, (_key, value) => {
if (typeof value !== "bigint") return value;
});
};
/**
* Returns a slugified string used to generate consistent IDs.
*
* This can be used to generate a consistent ID for a function when migrating
* from v2 to v3 of the SDK.
*
* @public
*/
const slugify = (str) => {
const join = "-";
return str.toLowerCase().replace(/[^a-z0-9-]+/g, join).replace(/-+/g, join).split(join).filter(Boolean).join(join);
};
const second = 1 * 1e3;
const minute = second * 60;
const hour = minute * 60;
const day = hour * 24;
/**
* A collection of periods in milliseconds and their suffixes used when creating
* time strings.
*/
const periods = [
["w", day * 7],
["d", day],
["h", hour],
["m", minute],
["s", second]
];
/**
* Convert a given `Date`, `number`, or `ms`-compatible `string` to a
* Inngest sleep-compatible time string (e.g. `"1d"` or `"2h3010s"`).
*/
const timeStr = (input) => {
if (input instanceof Date) return input.toISOString();
if (isTemporalInstant(input) || isTemporalZonedDateTime(input)) return getISOString(input);
let milliseconds;
if (isTemporalDuration(input)) milliseconds = input.total({
unit: "milliseconds",
relativeTo: Temporal.Now.plainDateTimeISO("UTC").toString()
});
else if (typeof input === "string") milliseconds = ms(input);
else milliseconds = input;
const [, timeStr$1] = periods.reduce(([num, str], [suffix, period]) => {
const numPeriods = Math.floor(num / period);
if (numPeriods > 0) return [num % period, `${str}${numPeriods}${suffix}`];
return [num, str];
}, [milliseconds, ""]);
return timeStr$1;
};
const hashEventKey = (eventKey) => {
return sha256().update(eventKey).digest("hex");
};
const hashSigningKey = (signingKey) => {
if (!signingKey) return "";
const prefix = signingKey.match(/^signkey-[\w]+-/)?.shift() || "";
const key = removeSigningKeyPrefix(signingKey);
return `${prefix}${sha256().update(key, "hex").digest("hex")}`;
};
function removeSigningKeyPrefix(signingKey) {
return signingKey.replace(/^signkey-[\w]+-/, "");
}
//#endregion
export { hashEventKey, hashSigningKey, removeSigningKeyPrefix, slugify, stringify$1 as stringify, timeStr, timingSafeEqual };
//# sourceMappingURL=strings.js.map