UNPKG

ts-switch-case

Version:

A TypeScript-first switch-case utility with object-based and chainable syntax

173 lines (169 loc) 5.89 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // index.ts var index_exports = {}; __export(index_exports, { assertUnreachable: () => assertUnreachable, switchCase: () => switchCase }); module.exports = __toCommonJS(index_exports); // src/utils.ts function logCyclicError(obj, path, context) { console.error("[Cyclic Reference]", { timestamp: (/* @__PURE__ */ new Date()).toISOString(), context, path: path.join(" -> "), objectType: obj?.constructor?.name || "unknown" }); } function isCyclic(obj, seen = /* @__PURE__ */ new WeakSet(), path = ["root"]) { if (obj && typeof obj === "object") { if (seen.has(obj)) { logCyclicError(obj, path, "Cycle detected"); return true; } seen.add(obj); for (const key in obj) { if (isCyclic(obj[key], seen, [...path, key])) return true; } } return false; } // src/switchCase.ts function switchCase(value, discriminatorOrCases, casesOrDefault, defaultHandler) { if (discriminatorOrCases === void 0) { const cases2 = []; let defaultFn; const builder = { case(match, handler) { cases2.push({ match, handler }); return this; }, default(handler) { defaultFn = handler; return this; }, exhaustive() { return this.run(); }, run() { for (const { match, handler } of cases2) { const isMatch = typeof match === "function" ? match(value) : match === value; if (isMatch) { return typeof handler === "function" ? handler(value) : handler; } } if (defaultFn) { return defaultFn(value); } throw new Error(`No matching case for value: ${JSON.stringify(value)}`); } }; return builder; } if (Array.isArray(discriminatorOrCases)) { if (isCyclic(discriminatorOrCases)) throw new Error( "Cyclic cases detected. See ts-switch-case README for handling cycles (e.g., sanitizeNode for React)." ); const cases2 = discriminatorOrCases; const defaultFn = casesOrDefault; for (const { match, handler } of cases2) { if (match(value)) { return typeof handler === "function" ? handler(value) : handler; } } if (defaultFn) { return defaultFn(value); } throw new Error(`No matching case for value: ${JSON.stringify(value)}`); } if (typeof discriminatorOrCases === "object") { if (isCyclic(discriminatorOrCases)) throw new Error( "Cyclic cases detected. See ts-switch-case README for handling cycles (e.g., sanitizeNode for React)." ); const cases2 = discriminatorOrCases; const defaultFn = casesOrDefault; const literalHandler = cases2[String(value)]; if (literalHandler !== void 0) { const result = typeof literalHandler === "function" ? literalHandler() : literalHandler; if (isCyclic(result)) throw new Error( "Cyclic result detected. See ts-switch-case README for handling cycles (e.g., sanitizeNode for React)." ); return result; } for (const key of Object.keys(cases2)) { const c = cases2[key]; if (typeof c !== "function") { const match = typeof c.match === "function" ? c.match(value) : c.match === value; if (match) { const result = typeof c.handler === "function" ? c.handler(value) : c.handler; if (isCyclic(result)) throw new Error( "Cyclic result detected. See ts-switch-case README for handling cycles (e.g., sanitizeNode for React)." ); return result; } } } if (defaultFn) { const result = defaultFn(value); if (isCyclic(result)) throw new Error( "Cyclic result detected. See ts-switch-case README for handling cycles (e.g., sanitizeNode for React)." ); return result; } throw new Error(`No matching case for value: ${JSON.stringify(value)}`); } if (isCyclic(casesOrDefault)) throw new Error("Cyclic cases"); const discriminator = discriminatorOrCases; const cases = casesOrDefault; const discriminatorValue = String(value[discriminator]); const handlerOrValue = cases[discriminatorValue]; if (handlerOrValue !== void 0) { const result = typeof handlerOrValue === "function" ? handlerOrValue(value) : handlerOrValue; if (isCyclic(result)) throw new Error( "Cyclic result detected. See ts-switch-case README for handling cycles (e.g., sanitizeNode for React)." ); return result; } if (defaultHandler) { const result = defaultHandler(value); if (isCyclic(result)) throw new Error( "Cyclic result detected. See ts-switch-case README for handling cycles (e.g., sanitizeNode for React)." ); return result; } throw new Error( `No matching case for ${String(discriminator)}: ${discriminatorValue}` ); } function assertUnreachable(value) { throw new Error(`Unreachable case: ${value}`); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { assertUnreachable, switchCase });