{"version":3,"file":"log.cjs","names":["isRecord"],"sources":["../../src/helpers/log.ts"],"sourcesContent":["import type { LogArg, Logger } from \"../middleware/logger.ts\";\nimport { isRecord } from \"./types.ts\";\n\nconst loggedKeys = new Set<string>();\n\n/**\n * Log a message exactly once per process lifetime.\n * Subsequent calls with the same `key` are no-ops.\n */\nexport function logOnce(\n  logger: Logger,\n  level: \"debug\" | \"info\" | \"warn\" | \"error\",\n  key: string,\n  ...args: LogArg[]\n): void {\n  if (loggedKeys.has(key)) {\n    return;\n  }\n  loggedKeys.add(key);\n  logger[level](...args);\n}\n\n/**\n * Log a warning exactly once per process lifetime.\n * Subsequent calls with the same `key` are no-ops.\n */\nexport function warnOnce(logger: Logger, key: string, ...args: LogArg[]): void {\n  logOnce(logger, \"warn\", key, ...args);\n}\n\nexport interface StructuredLogMessage {\n  message: string;\n  code?: string;\n  explanation?: string;\n  action?: string;\n  docs?: string;\n}\n\n/**\n * Wraps a string-first logger (e.g. Winston) so it accepts Pino-style\n * object-first calls like `logger.info({ requestId: \"abc\" }, \"message\")`\n *\n * @example\n * const inngest = new Inngest({\n *   id: \"my-app\",\n *   logger: wrapStringFirstLogger(winstonLogger),\n * })\n */\nexport function wrapStringFirstLogger(logger: Logger): Logger {\n  function wrap(method: keyof Logger): (...args: LogArg[]) => void {\n    return (...args: LogArg[]) => {\n      if (args.length > 1 && isRecord(args[0]) && typeof args[1] === \"string\") {\n        // We got 2 args: 1st is a record and 2nd is a string\n        const [fields, message, ...rest] = args;\n        logger[method](message, fields, ...rest);\n      } else {\n        logger[method](...args);\n      }\n    };\n  }\n\n  return {\n    info: wrap(\"info\"),\n    warn: wrap(\"warn\"),\n    error: wrap(\"error\"),\n    debug: wrap(\"debug\"),\n  };\n}\n\nexport function formatLogMessage(opts: StructuredLogMessage): string {\n  return [\n    opts.message,\n    opts.explanation,\n    opts.action && `To fix: ${opts.action}`,\n    opts.docs && `See: ${opts.docs}`,\n    opts.code && `[${opts.code}]`,\n  ]\n    .filter(Boolean)\n    .join(\" \");\n}\n"],"mappings":";;;AAGA,MAAM,6BAAa,IAAI,KAAa;;;;;AAMpC,SAAgB,QACd,QACA,OACA,KACA,GAAG,MACG;AACN,KAAI,WAAW,IAAI,IAAI,CACrB;AAEF,YAAW,IAAI,IAAI;AACnB,QAAO,OAAO,GAAG,KAAK;;;;;;AAOxB,SAAgB,SAAS,QAAgB,KAAa,GAAG,MAAsB;AAC7E,SAAQ,QAAQ,QAAQ,KAAK,GAAG,KAAK;;;;;;;;;;;;AAqBvC,SAAgB,sBAAsB,QAAwB;CAC5D,SAAS,KAAK,QAAmD;AAC/D,UAAQ,GAAG,SAAmB;AAC5B,OAAI,KAAK,SAAS,KAAKA,uBAAS,KAAK,GAAG,IAAI,OAAO,KAAK,OAAO,UAAU;IAEvE,MAAM,CAAC,QAAQ,SAAS,GAAG,QAAQ;AACnC,WAAO,QAAQ,SAAS,QAAQ,GAAG,KAAK;SAExC,QAAO,QAAQ,GAAG,KAAK;;;AAK7B,QAAO;EACL,MAAM,KAAK,OAAO;EAClB,MAAM,KAAK,OAAO;EAClB,OAAO,KAAK,QAAQ;EACpB,OAAO,KAAK,QAAQ;EACrB;;AAGH,SAAgB,iBAAiB,MAAoC;AACnE,QAAO;EACL,KAAK;EACL,KAAK;EACL,KAAK,UAAU,WAAW,KAAK;EAC/B,KAAK,QAAQ,QAAQ,KAAK;EAC1B,KAAK,QAAQ,IAAI,KAAK,KAAK;EAC5B,CACE,OAAO,QAAQ,CACf,KAAK,IAAI"}