@aiquants/html-to-markdown 1.2.1 → 1.3.1

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/index.cjs CHANGED
@@ -1 +1 @@
1
- const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e}),Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./core-diGadcw4.cjs"),t=require("./mcp-server-DSLDlYZX.cjs"),c=require("./mcp-server-streamable-DZ7VyWAg.cjs");exports.getMessage=r.getMessage,exports.htmlToMarkdown=r.htmlToMarkdown,exports.createMcpServer=t.createMcpServer,exports.runMcpServer=t.runMcpServer,exports.createStreamableMcpServer=c.createStreamableMcpServer,exports.runStreamableMcpServer=c.runStreamableMcpServer;
1
+ const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e}),Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./core-CHYQAf6b.cjs"),t=require("./mcp-server-D18WYyj-.cjs"),c=require("./mcp-server-streamable-BPxUnvzy.cjs");exports.getMessage=r.getMessage,exports.htmlToMarkdown=r.htmlToMarkdown,exports.createMcpServer=t.createMcpServer,exports.runMcpServer=t.runMcpServer,exports.createStreamableMcpServer=c.createStreamableMcpServer,exports.runStreamableMcpServer=c.runStreamableMcpServer;
@@ -0,0 +1,2 @@
1
+ export * from './src/index'
2
+ export {}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{Window as e}from"happy-dom";const r=new e;Object.assign(global,{document:r.document,window:r,self:r});import{g as a,h as s}from"./core-CTBCnkuY.js";import{c as o,r as m}from"./mcp-server-DmJXoVRZ.js";import{c as t,r as c}from"./mcp-server-streamable-CgJP5t9P.js";export{o as createMcpServer,t as createStreamableMcpServer,a as getMessage,s as htmlToMarkdown,m as runMcpServer,c as runStreamableMcpServer};
1
+ import{Window as e}from"happy-dom";const r=new e;Object.assign(global,{document:r.document,window:r,self:r});import{g as a,h as s}from"./core-CkCUqS2i.js";import{c as o,r as m}from"./mcp-server-BviJ0BJj.js";import{c as t,r as c}from"./mcp-server-streamable-D4CUcTDr.js";export{o as createMcpServer,t as createStreamableMcpServer,a as getMessage,s as htmlToMarkdown,m as runMcpServer,c as runStreamableMcpServer};
package/dist/main.cjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e});const t=require("./core-diGadcw4.cjs");var r="undefined"!=typeof document?document.currentScript:null;(async()=>{(("undefined"==typeof document?require("url").pathToFileURL(__filename).href:r&&"SCRIPT"===r.tagName.toUpperCase()&&r.src||new URL("main.cjs",document.baseURI).href).endsWith(process.argv[1])||process.argv[1]&&process.argv[1].includes("vite-node"))&&(async()=>{const e=(await import("yargs-parser")).default,r=await import("node:fs"),o=await import("node:path"),c=e(process.argv.slice(2),{string:["locale","output","html-content"],alias:{output:["o"],"html-content":["h"]},default:{locale:"en-US"}}),n=c._[0],s=c.locale,a=c.output,i=c["html-content"];if(n||i||process.exit(1),n&&!i)try{new URL(n)}catch(p){process.exit(1)}try{const{markdown:e,html:c}=await t.htmlToMarkdown(n||"direct-html-input",{locale:s,htmlContent:i});let p;if(a){p=o.resolve(process.cwd(),a);const e=o.dirname(p);r.existsSync(e)||r.mkdirSync(e,{recursive:!0})}else{let e;e=i?"html_content":n.replace(/https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"_");const t=`${e}_${Date.now()}.md`,c=o.join(process.cwd(),".outputs","raw");r.existsSync(c)||r.mkdirSync(c,{recursive:!0}),p=o.join(c,t)}r.writeFileSync(p,e);const l=o.parse(p),d=o.join(l.dir,`${l.name}.html`);r.writeFileSync(d,c)}catch(p){process.exit(1)}})()})();
2
+ Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e});const t=require("./core-CHYQAf6b.cjs");var r="undefined"!=typeof document?document.currentScript:null;(async()=>{(("undefined"==typeof document?require("url").pathToFileURL(__filename).href:r&&"SCRIPT"===r.tagName.toUpperCase()&&r.src||new URL("main.cjs",document.baseURI).href).endsWith(process.argv[1])||process.argv[1]&&process.argv[1].includes("vite-node"))&&(async()=>{const e=(await import("yargs-parser")).default,r=await import("node:fs"),o=await import("node:path"),s=e(process.argv.slice(2),{string:["locale","output","html-content"],alias:{output:["o"],"html-content":["h"]},default:{locale:"en-US"}}),c=s._[0],n=s.locale,a=s.output,i=s["html-content"];if(c||i||process.exit(1),c&&!i)try{new URL(c)}catch(p){process.exit(1)}try{const{markdown:e,html:s}=await t.htmlToMarkdown(c||"direct-html-input",{locale:n,htmlContent:i});let p;if(a){p=o.resolve(process.cwd(),a);const e=o.dirname(p);r.existsSync(e)||r.mkdirSync(e,{recursive:!0})}else{let e;e=i?"html_content":c.replace(/https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"_");const t=`${e}_${Date.now()}.md`,s=o.join(process.cwd(),".outputs","raw");r.existsSync(s)||r.mkdirSync(s,{recursive:!0}),p=o.join(s,t)}r.writeFileSync(p,e);const l=o.parse(p),d=o.join(l.dir,`${l.name}.html`);r.writeFileSync(d,s),t.Logger.info(`\n${t.getMessage(n,"success_save")}`),t.Logger.info(t.getMessage(n,"success_path",{path:p})),t.Logger.info(t.getMessage(n,"success_path",{path:d}))}catch(p){t.Logger.error(`\n${t.getMessage(n,"error_app")}`,p),process.exit(1)}})()})();
package/dist/main.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{Window as t}from"happy-dom";const e=new t;Object.assign(global,{document:e.document,window:e,self:e});import{g as o,h as s}from"./core-CTBCnkuY.js";(async()=>{(import.meta.url.endsWith(process.argv[1])||process.argv[1]&&process.argv[1].includes("vite-node"))&&(async()=>{const t=(await import("yargs-parser")).default,e=await import("node:fs"),o=await import("node:path"),c=t(process.argv.slice(2),{string:["locale","output","html-content"],alias:{output:["o"],"html-content":["h"]},default:{locale:"en-US"}}),r=c._[0],n=c.locale,a=c.output,i=c["html-content"];if(r||i||process.exit(1),r&&!i)try{new URL(r)}catch(l){process.exit(1)}try{const{markdown:t,html:c}=await s(r||"direct-html-input",{locale:n,htmlContent:i});let l;if(a){l=o.resolve(process.cwd(),a);const t=o.dirname(l);e.existsSync(t)||e.mkdirSync(t,{recursive:!0})}else{let t;t=i?"html_content":r.replace(/https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"_");const s=`${t}_${Date.now()}.md`,c=o.join(process.cwd(),".outputs","raw");e.existsSync(c)||e.mkdirSync(c,{recursive:!0}),l=o.join(c,s)}e.writeFileSync(l,t);const p=o.parse(l),m=o.join(p.dir,`${p.name}.html`);e.writeFileSync(m,c)}catch(l){process.exit(1)}})()})();
2
+ import{Window as t}from"happy-dom";const e=new t;Object.assign(global,{document:e.document,window:e,self:e});import{g as s,h as o,L as c}from"./core-CkCUqS2i.js";(async()=>{(import.meta.url.endsWith(process.argv[1])||process.argv[1]&&process.argv[1].includes("vite-node"))&&(async()=>{const t=(await import("yargs-parser")).default,e=await import("node:fs"),r=await import("node:path"),n=t(process.argv.slice(2),{string:["locale","output","html-content"],alias:{output:["o"],"html-content":["h"]},default:{locale:"en-US"}}),a=n._[0],i=n.locale,p=n.output,l=n["html-content"];if(a||l||process.exit(1),a&&!l)try{new URL(a)}catch(m){process.exit(1)}try{const{markdown:t,html:n}=await o(a||"direct-html-input",{locale:i,htmlContent:l});let m;if(p){m=r.resolve(process.cwd(),p);const t=r.dirname(m);e.existsSync(t)||e.mkdirSync(t,{recursive:!0})}else{let t;t=l?"html_content":a.replace(/https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"_");const s=`${t}_${Date.now()}.md`,o=r.join(process.cwd(),".outputs","raw");e.existsSync(o)||e.mkdirSync(o,{recursive:!0}),m=r.join(o,s)}e.writeFileSync(m,t);const d=r.parse(m),h=r.join(d.dir,`${d.name}.html`);e.writeFileSync(h,n),c.info(`\n${s(i,"success_save")}`),c.info(s(i,"success_path",{path:m})),c.info(s(i,"success_path",{path:h}))}catch(m){c.error(`\n${s(i,"error_app")}`,m),process.exit(1)}})()})();
@@ -0,0 +1 @@
1
+ import{Window as t}from"happy-dom";const e=new t;Object.assign(global,{document:e.document,window:e,self:e});import{J as r,g as a,S as n,L as s,M as o,C as i,p as c,c as l,a as d,b as h,s as u,d as f}from"./version-Fr0FqrXS.js";import m from"node:process";import{h as p,L as _}from"./core-CkCUqS2i.js";class w{append(t){this._buffer=this._buffer?Buffer.concat([this._buffer,t]):t}readMessage(){if(!this._buffer)return null;const t=this._buffer.indexOf("\n");if(-1===t)return null;const e=this._buffer.toString("utf8",0,t).replace(/\r$/,"");return this._buffer=this._buffer.subarray(t+1),function(t){return r.parse(JSON.parse(t))}(e)}clear(){this._buffer=void 0}}class v{constructor(t=m.stdin,e=m.stdout){this._stdin=t,this._stdout=e,this._readBuffer=new w,this._started=!1,this._ondata=t=>{this._readBuffer.append(t),this.processReadBuffer()},this._onerror=t=>{this.onerror?.(t)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(;;)try{const t=this._readBuffer.readMessage();if(null===t)break;this.onmessage?.(t)}catch(t){this.onerror?.(t)}}async close(){this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror);0===this._stdin.listenerCount("data")&&this._stdin.pause(),this._readBuffer.clear(),this.onclose?.()}send(t){return new Promise(e=>{const r=function(t){return JSON.stringify(t)+"\n"}(t);this._stdout.write(r)?e():this._stdout.once("drain",e)})}}class y{constructor(){this.version=a(),this.server=new n({name:"@aiquants/html-to-markdown",version:this.version},{capabilities:{tools:{}}}),this.setupToolHandlers()}setupToolHandlers(){this.server.setRequestHandler(s,async()=>({tools:[{name:"html_to_markdown",description:"Convert web pages or HTML strings to Markdown format. Handles JavaScript-rendered dynamic content and preserves table structures.",inputSchema:o.htmlToMarkdown},{name:"save_content_to_file",description:"Save text content to a file with specified path or directory. Supports automatic filename generation and format detection.",inputSchema:o.saveContentToFile},{name:"url_to_markdown_file",description:"Convert web pages or HTML strings directly to Markdown files. Combines HTML-to-Markdown conversion and file saving in one step. Handles JavaScript-rendered dynamic content.",inputSchema:o.urlToMarkdownFile}]})),this.server.setRequestHandler(i,async t=>{switch(t.params.name){case"html_to_markdown":return await this.handleHtmlToMarkdown(t.params.arguments);case"save_content_to_file":return await this.handleSaveContentToFile(t.params.arguments);case"url_to_markdown_file":return await this.handleUrlToMarkdownFile(t.params.arguments);default:throw new Error(`Unknown tool: ${t.params.name}`)}})}async handleHtmlToMarkdown(t){try{const e=c(t),{url:r,html_content:a,locale:n="en-US"}=e;if(r)try{new URL(r)}catch{throw new Error(`Invalid URL: ${r}`)}const s=(await p(r||"direct-html-input",{locale:n,htmlContent:a})).markdown;return l(s)}catch(e){return d(e)}}async handleSaveContentToFile(t){try{const e=h(t),{content:r,save_path:a,save_directory:n,filename:s}=e,o=await u(r,a,n,s);return l(`File saved successfully to: ${o}`)}catch(e){return d(e)}}async handleUrlToMarkdownFile(t){try{const e=f(t),{url:r,html_content:a,locale:n="en-US",save_path:s,save_directory:o,filename:i}=e;if(r)try{new URL(r)}catch{throw new Error(`Invalid URL: ${r}`)}const c=(await p(r||"direct-html-input",{locale:n,htmlContent:a})).markdown;let d=i;!d&&r&&(d=this.generateFilenameFromUrl(r));const h=await u(c,s,o,d);return l(`URL successfully converted to Markdown and saved to: ${h}`)}catch(e){return d(e)}}generateFilenameFromUrl(t){try{let e=new URL(t).pathname.split("/").pop()||"page";return e=e.replace(/\.[^.]*$/,""),e=e.replace(/[<>:"/\\|?*]/g,"_"),e&&!e.match(/^\.+$/)||(e="page"),e}catch{return"page"}}async start(){const t=new v;await this.server.connect(t),_.info("HTML to Markdown MCP server started")}}const g=()=>new y,k=async()=>{const t=g();await t.start()};export{g as c,k as r};
@@ -0,0 +1 @@
1
+ const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e});const t=require("./version-Dbzh6HLt.cjs"),r=require("node:process"),n=require("./core-CHYQAf6b.cjs");class a{append(e){this._buffer=this._buffer?Buffer.concat([this._buffer,e]):e}readMessage(){if(!this._buffer)return null;const e=this._buffer.indexOf("\n");if(-1===e)return null;const r=this._buffer.toString("utf8",0,e).replace(/\r$/,"");return this._buffer=this._buffer.subarray(e+1),function(e){return t.JSONRPCMessageSchema.parse(JSON.parse(e))}(r)}clear(){this._buffer=void 0}}class s{constructor(e=r.stdin,t=r.stdout){this._stdin=e,this._stdout=t,this._readBuffer=new a,this._started=!1,this._ondata=e=>{this._readBuffer.append(e),this.processReadBuffer()},this._onerror=e=>{this.onerror?.(e)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(;;)try{const e=this._readBuffer.readMessage();if(null===e)break;this.onmessage?.(e)}catch(e){this.onerror?.(e)}}async close(){this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror);0===this._stdin.listenerCount("data")&&this._stdin.pause(),this._readBuffer.clear(),this.onclose?.()}send(e){return new Promise(t=>{const r=function(e){return JSON.stringify(e)+"\n"}(e);this._stdout.write(r)?t():this._stdout.once("drain",t)})}}class o{constructor(){this.version=t.getPackageVersion(),this.server=new t.Server({name:"@aiquants/html-to-markdown",version:this.version},{capabilities:{tools:{}}}),this.setupToolHandlers()}setupToolHandlers(){this.server.setRequestHandler(t.ListToolsRequestSchema,async()=>({tools:[{name:"html_to_markdown",description:"Convert web pages or HTML strings to Markdown format. Handles JavaScript-rendered dynamic content and preserves table structures.",inputSchema:t.MCP_TOOL_SCHEMAS.htmlToMarkdown},{name:"save_content_to_file",description:"Save text content to a file with specified path or directory. Supports automatic filename generation and format detection.",inputSchema:t.MCP_TOOL_SCHEMAS.saveContentToFile},{name:"url_to_markdown_file",description:"Convert web pages or HTML strings directly to Markdown files. Combines HTML-to-Markdown conversion and file saving in one step. Handles JavaScript-rendered dynamic content.",inputSchema:t.MCP_TOOL_SCHEMAS.urlToMarkdownFile}]})),this.server.setRequestHandler(t.CallToolRequestSchema,async e=>{switch(e.params.name){case"html_to_markdown":return await this.handleHtmlToMarkdown(e.params.arguments);case"save_content_to_file":return await this.handleSaveContentToFile(e.params.arguments);case"url_to_markdown_file":return await this.handleUrlToMarkdownFile(e.params.arguments);default:throw new Error(`Unknown tool: ${e.params.name}`)}})}async handleHtmlToMarkdown(e){try{const r=t.parseHtmlToMarkdownArgs(e),{url:a,html_content:s,locale:o="en-US"}=r;if(a)try{new URL(a)}catch{throw new Error(`Invalid URL: ${a}`)}const i=(await n.htmlToMarkdown(a||"direct-html-input",{locale:o,htmlContent:s})).markdown;return t.createSuccessResult(i)}catch(r){return t.createErrorResult(r)}}async handleSaveContentToFile(e){try{const r=t.parseSaveContentArgs(e),{content:n,save_path:a,save_directory:s,filename:o}=r,i=`File saved successfully to: ${await t.saveContentToFile(n,a,s,o)}`;return t.createSuccessResult(i)}catch(r){return t.createErrorResult(r)}}async handleUrlToMarkdownFile(e){try{const r=t.parseUrlToMarkdownFileArgs(e),{url:a,html_content:s,locale:o="en-US",save_path:i,save_directory:c,filename:l}=r;if(a)try{new URL(a)}catch{throw new Error(`Invalid URL: ${a}`)}const d=(await n.htmlToMarkdown(a||"direct-html-input",{locale:o,htmlContent:s})).markdown;let u=l;!u&&a&&(u=this.generateFilenameFromUrl(a));const h=`URL successfully converted to Markdown and saved to: ${await t.saveContentToFile(d,i,c,u)}`;return t.createSuccessResult(h)}catch(r){return t.createErrorResult(r)}}generateFilenameFromUrl(e){try{let t=new URL(e).pathname.split("/").pop()||"page";return t=t.replace(/\.[^.]*$/,""),t=t.replace(/[<>:"/\\|?*]/g,"_"),t&&!t.match(/^\.+$/)||(t="page"),t}catch{return"page"}}async start(){const e=new s;await this.server.connect(e),n.Logger.info("HTML to Markdown MCP server started")}}const i=()=>new o;exports.createMcpServer=i,exports.runMcpServer=async()=>{const e=i();await e.start()};
@@ -0,0 +1 @@
1
+ "use strict";const e=require("./version-Dbzh6HLt.cjs");require("http");const t=require("http2"),r=require("stream"),s=require("crypto"),n=require("cors"),o=require("express"),a=require("yargs-parser"),i=require("./core-CHYQAf6b.cjs");var l=class extends Error{constructor(e,t){super(e,t),this.name="RequestError"}},c=global.Request,d=class extends c{constructor(e,t){"object"==typeof e&&p in e&&(e=e[p]()),void 0!==t?.body?.getReader&&(t.duplex??="half"),super(e,t)}},h=Symbol("wrapBodyStream"),p=Symbol("getRequestCache"),u=Symbol("requestCache"),m=Symbol("incomingKey"),f=Symbol("urlKey"),g=Symbol("headersKey"),y=Symbol("abortControllerKey"),w=Symbol("getAbortController"),v={get method(){return this[m].method||"GET"},get url(){return this[f]},get headers(){return this[g]||=(e=>{const t=[],r=e.rawHeaders;for(let s=0;s<r.length;s+=2){const{[s]:e,[s+1]:n}=r;58!==e.charCodeAt(0)&&t.push([e,n])}return new Headers(t)})(this[m])},[w](){return this[p](),this[y]},[p](){return this[y]||=new AbortController,this[u]||=((e,t,s,n,o)=>{const a={method:e,headers:s,signal:o.signal};if("TRACE"===e){a.method="GET";const e=new d(t,a);return Object.defineProperty(e,"method",{get:()=>"TRACE"}),e}if("GET"!==e&&"HEAD"!==e)if("rawBody"in n&&n.rawBody instanceof Buffer)a.body=new ReadableStream({start(e){e.enqueue(n.rawBody),e.close()}});else if(n[h]){let e;a.body=new ReadableStream({async pull(t){try{e||=r.Readable.toWeb(n).getReader();const{done:s,value:o}=await e.read();s?t.close():t.enqueue(o)}catch(s){t.error(s)}}})}else a.body=r.Readable.toWeb(n);return new d(t,a)})(this.method,this[f],this.headers,this[m],this[y])}};["body","bodyUsed","cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","signal","keepalive"].forEach(e=>{Object.defineProperty(v,e,{get(){return this[p]()[e]}})}),["arrayBuffer","blob","clone","formData","json","text"].forEach(e=>{Object.defineProperty(v,e,{value:function(){return this[p]()[e]()}})}),Object.defineProperty(v,Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Request (lightweight) ${r({method:this.method,url:this.url,headers:this.headers,nativeRequest:this[u]},{...t,depth:null==e?null:e-1})}`}}),Object.setPrototypeOf(v,d.prototype);var S=Symbol("responseCache"),R=Symbol("getResponseCache"),b=Symbol("cache"),E=global.Response,_=class e{#e;#t;[R](){return delete this[b],this[S]||=new E(this.#e,this.#t)}constructor(t,r){let s;if(this.#e=t,r instanceof e){const e=r[S];if(e)return this.#t=e,void this[R]();this.#t=r.#t,s=new Headers(r.#t.headers)}else this.#t=r;("string"==typeof t||void 0!==t?.getReader||t instanceof Blob||t instanceof Uint8Array)&&(this[b]=[r?.status||200,t,s||r?.headers])}get headers(){const e=this[b];return e?(e[2]instanceof Headers||(e[2]=new Headers(e[2]||{"content-type":"text/plain; charset=UTF-8"})),e[2]):this[R]().headers}get status(){return this[b]?.[0]??this[R]().status}get ok(){const e=this.status;return e>=200&&e<300}};async function T(e){return Promise.race([e,Promise.resolve().then(()=>Promise.resolve(void 0))])}function q(e,t,r){const s=t=>{e.cancel(t).catch(()=>{})};return t.on("close",s),t.on("error",s),(r??e.read()).then(a,n),e.closed.finally(()=>{t.off("close",s),t.off("error",s)});function n(e){e&&t.destroy(e)}function o(){e.read().then(a,n)}function a({done:r,value:s}){try{if(r)t.end();else{if(t.write(s))return e.read().then(a,n);t.once("drain",o)}}catch(i){n(i)}}}["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach(e=>{Object.defineProperty(_.prototype,e,{get(){return this[R]()[e]}})}),["arrayBuffer","blob","clone","formData","json","text"].forEach(e=>{Object.defineProperty(_.prototype,e,{value:function(){return this[R]()[e]()}})}),Object.defineProperty(_.prototype,Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Response (lightweight) ${r({status:this.status,headers:this.headers,ok:this.ok,nativeResponse:this[S]},{...t,depth:null==e?null:e-1})}`}}),Object.setPrototypeOf(_,E),Object.setPrototypeOf(_.prototype,E.prototype);var I=e=>{const t={};e instanceof Headers||(e=new Headers(e??void 0));const r=[];for(const[s,n]of e)"set-cookie"===s?r.push(n):t[s]=n;return r.length>0&&(t["set-cookie"]=r),t["content-type"]??="text/plain; charset=UTF-8",t};void 0===global.crypto&&(global.crypto=s);var C=Symbol("outgoingEnded"),M=Symbol("incomingDraining"),O=e=>{const r=e;if(e.destroyed||r[M])return;if(r[M]=!0,e instanceof t.Http2ServerRequest){try{e.stream?.close?.(t.constants.NGHTTP2_NO_ERROR)}catch{}return}let s=0;const n=()=>{clearTimeout(a),e.off("data",i),e.off("end",n),e.off("error",n)},o=()=>{n();const t=e.socket;t&&!t.destroyed&&t.destroySoon()},a=setTimeout(o,500);a.unref?.();const i=e=>{s+=e.length,s>67108864&&o()};e.on("data",i),e.on("end",n),e.on("error",n),e.resume()},P=e=>new Response(null,{status:e instanceof Error&&("TimeoutError"===e.name||"TimeoutError"===e.constructor.name)?504:500}),J=(e,t)=>{const r=e instanceof Error?e:new Error("unknown error",{cause:e});"ERR_STREAM_PREMATURE_CLOSE"===r.code||(t.headersSent||t.writeHead(500,{"Content-Type":"text/plain"}),t.end(`Error: ${r.message}`),t.destroy(r))},j=e=>{"flushHeaders"in e&&e.writable&&e.flushHeaders()},H=async(e,t)=>{let[r,s,n]=e[b],o=!1;if(n){if(n instanceof Headers)o=n.has("content-length"),n=I(n);else if(Array.isArray(n)){const e=new Headers(n);o=e.has("content-length"),n=I(e)}else for(const a in n)if(14===a.length&&"content-length"===a.toLowerCase()){o=!0;break}}else n={"content-type":"text/plain; charset=UTF-8"};o||("string"==typeof s?n["Content-Length"]=Buffer.byteLength(s):s instanceof Uint8Array?n["Content-Length"]=s.byteLength:s instanceof Blob&&(n["Content-Length"]=s.size)),t.writeHead(r,n),"string"==typeof s||s instanceof Uint8Array?t.end(s):s instanceof Blob?t.end(new Uint8Array(await s.arrayBuffer())):(j(t),await(function(e,t){if(e.locked)throw new TypeError("ReadableStream is locked.");if(!t.destroyed)return q(e.getReader(),t)}(s,t)?.catch(e=>J(e,t)))),t[C]?.()},U=(e,r={})=>{const s=r.autoCleanupIncoming??!0;return!1!==r.overrideGlobalObjects&&global.Request!==d&&(Object.defineProperty(global,"Request",{value:d}),Object.defineProperty(global,"Response",{value:_})),async(n,o)=>{let a,i;try{i=((e,r)=>{const s=Object.create(v);s[m]=e;const n=e.url||"";if("/"!==n[0]&&(n.startsWith("http://")||n.startsWith("https://"))){if(e instanceof t.Http2ServerRequest)throw new l("Absolute URL for :path is not allowed in HTTP/2");try{const e=new URL(n);s[f]=e.href}catch(c){throw new l("Invalid absolute URL",{cause:c})}return s}const o=(e instanceof t.Http2ServerRequest?e.authority:e.headers.host)||r;if(!o)throw new l("Missing host header");let a;if(e instanceof t.Http2ServerRequest){if(a=e.scheme,"http"!==a&&"https"!==a)throw new l("Unsupported scheme")}else a=e.socket&&e.socket.encrypted?"https":"http";const i=new URL(`${a}://${o}${n}`);if(i.hostname.length!==o.length&&i.hostname!==o.replace(/:\d+$/,""))throw new l("Invalid host header");return s[f]=i.href,s})(n,r.hostname);let c=!s||"GET"===n.method||"HEAD"===n.method;if(c||(n[h]=!0,n.on("end",()=>{c=!0}),n instanceof t.Http2ServerRequest&&(o[C]=()=>{c||setTimeout(()=>{c||setTimeout(()=>{O(n)})})}),o.on("finish",()=>{c||O(n)})),o.on("close",()=>{i[y]&&(n.errored?i[y].abort(n.errored.toString()):o.writableFinished||i[y].abort("Client connection prematurely closed.")),c||setTimeout(()=>{c||setTimeout(()=>{O(n)})})}),a=e(i,{incoming:n,outgoing:o}),b in a)return H(a,o)}catch(c){if(a)return J(c,o);if(r.errorHandler){if(a=await r.errorHandler(i?c:(e=>e instanceof l?e:new l(e.message,{cause:e}))(c)),!a)return}else a=i?P(c):new Response(null,{status:400})}try{return await(async(e,t,r={})=>{if((e=>"function"==typeof e.then)(e))if(r.errorHandler)try{e=await e}catch(n){const t=await r.errorHandler(n);if(!t)return;e=t}else e=await e.catch(P);if(b in e)return H(e,t);const s=I(e.headers);if(e.body){const r=e.body.getReader(),n=[];let o,a=!1;if("chunked"!==s["transfer-encoding"]){let e=2;for(let t=0;t<e;t++){o||=r.read();const s=await T(o).catch(e=>{a=!0});if(!s){if(1===t){await new Promise(e=>setTimeout(e)),e=3;continue}break}if(o=void 0,s.value&&n.push(s.value),s.done){a=!0;break}}a&&!("content-length"in s)&&(s["content-length"]=n.reduce((e,t)=>e+t.length,0))}t.writeHead(e.status,s),n.forEach(e=>{t.write(e)}),a?t.end():(0===n.length&&j(t),await q(r,t,o))}else s["x-hono-already-sent"]||(t.writeHead(e.status,s),t.end());t[C]?.()})(a,o,r)}catch(c){return J(c,o)}}};class k{constructor(e={}){this._started=!1,this._hasHandledRequest=!1,this._streamMapping=new Map,this._requestToStreamMapping=new Map,this._requestResponseMap=new Map,this._initialized=!1,this._enableJsonResponse=!1,this._standaloneSseStreamId="_GET_stream",this.sessionIdGenerator=e.sessionIdGenerator,this._enableJsonResponse=e.enableJsonResponse??!1,this._eventStore=e.eventStore,this._onsessioninitialized=e.onsessioninitialized,this._onsessionclosed=e.onsessionclosed,this._allowedHosts=e.allowedHosts,this._allowedOrigins=e.allowedOrigins,this._enableDnsRebindingProtection=e.enableDnsRebindingProtection??!1,this._retryInterval=e.retryInterval}async start(){if(this._started)throw new Error("Transport already started");this._started=!0}createJsonErrorResponse(e,t,r,s){const n={code:t,message:r};return void 0!==s?.data&&(n.data=s.data),new Response(JSON.stringify({jsonrpc:"2.0",error:n,id:null}),{status:e,headers:{"Content-Type":"application/json",...s?.headers}})}validateRequestHeaders(e){if(this._enableDnsRebindingProtection){if(this._allowedHosts&&this._allowedHosts.length>0){const t=e.headers.get("host");if(!t||!this._allowedHosts.includes(t)){const e=`Invalid Host header: ${t}`;return this.onerror?.(new Error(e)),this.createJsonErrorResponse(403,-32e3,e)}}if(this._allowedOrigins&&this._allowedOrigins.length>0){const t=e.headers.get("origin");if(t&&!this._allowedOrigins.includes(t)){const e=`Invalid Origin header: ${t}`;return this.onerror?.(new Error(e)),this.createJsonErrorResponse(403,-32e3,e)}}}}async handleRequest(e,t){if(!this.sessionIdGenerator&&this._hasHandledRequest)throw new Error("Stateless transport cannot be reused across requests. Create a new transport per request.");this._hasHandledRequest=!0;const r=this.validateRequestHeaders(e);if(r)return r;switch(e.method){case"POST":return this.handlePostRequest(e,t);case"GET":return this.handleGetRequest(e);case"DELETE":return this.handleDeleteRequest(e);default:return this.handleUnsupportedRequest()}}async writePrimingEvent(e,t,r,s){if(!this._eventStore)return;if(s<"2025-11-25")return;const n=await this._eventStore.storeEvent(r,{});let o=`id: ${n}\ndata: \n\n`;void 0!==this._retryInterval&&(o=`id: ${n}\nretry: ${this._retryInterval}\ndata: \n\n`),e.enqueue(t.encode(o))}async handleGetRequest(e){const t=e.headers.get("accept");if(!t?.includes("text/event-stream"))return this.onerror?.(new Error("Not Acceptable: Client must accept text/event-stream")),this.createJsonErrorResponse(406,-32e3,"Not Acceptable: Client must accept text/event-stream");const r=this.validateSession(e);if(r)return r;const s=this.validateProtocolVersion(e);if(s)return s;if(this._eventStore){const t=e.headers.get("last-event-id");if(t)return this.replayEvents(t)}if(void 0!==this._streamMapping.get(this._standaloneSseStreamId))return this.onerror?.(new Error("Conflict: Only one SSE stream is allowed per session")),this.createJsonErrorResponse(409,-32e3,"Conflict: Only one SSE stream is allowed per session");const n=new TextEncoder;let o;const a=new ReadableStream({start:e=>{o=e},cancel:()=>{this._streamMapping.delete(this._standaloneSseStreamId)}}),i={"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"};return void 0!==this.sessionId&&(i["mcp-session-id"]=this.sessionId),this._streamMapping.set(this._standaloneSseStreamId,{controller:o,encoder:n,cleanup:()=>{this._streamMapping.delete(this._standaloneSseStreamId);try{o.close()}catch{}}}),new Response(a,{headers:i})}async replayEvents(e){if(!this._eventStore)return this.onerror?.(new Error("Event store not configured")),this.createJsonErrorResponse(400,-32e3,"Event store not configured");try{let t;if(this._eventStore.getStreamIdForEventId){if(t=await this._eventStore.getStreamIdForEventId(e),!t)return this.onerror?.(new Error("Invalid event ID format")),this.createJsonErrorResponse(400,-32e3,"Invalid event ID format");if(void 0!==this._streamMapping.get(t))return this.onerror?.(new Error("Conflict: Stream already has an active connection")),this.createJsonErrorResponse(409,-32e3,"Conflict: Stream already has an active connection")}const r={"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"};void 0!==this.sessionId&&(r["mcp-session-id"]=this.sessionId);const s=new TextEncoder;let n;const o=new ReadableStream({start:e=>{n=e},cancel:()=>{}}),a=await this._eventStore.replayEventsAfter(e,{send:async(e,t)=>{if(!this.writeSSEEvent(n,s,t,e)){this.onerror?.(new Error("Failed replay events"));try{n.close()}catch{}}}});return this._streamMapping.set(a,{controller:n,encoder:s,cleanup:()=>{this._streamMapping.delete(a);try{n.close()}catch{}}}),new Response(o,{headers:r})}catch(t){return this.onerror?.(t),this.createJsonErrorResponse(500,-32e3,"Error replaying events")}}writeSSEEvent(e,t,r,s){try{let n="event: message\n";return s&&(n+=`id: ${s}\n`),n+=`data: ${JSON.stringify(r)}\n\n`,e.enqueue(t.encode(n)),!0}catch(n){return this.onerror?.(n),!1}}handleUnsupportedRequest(){return this.onerror?.(new Error("Method not allowed.")),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}),{status:405,headers:{Allow:"GET, POST, DELETE","Content-Type":"application/json"}})}async handlePostRequest(t,r){try{const s=t.headers.get("accept");if(!s?.includes("application/json")||!s.includes("text/event-stream"))return this.onerror?.(new Error("Not Acceptable: Client must accept both application/json and text/event-stream")),this.createJsonErrorResponse(406,-32e3,"Not Acceptable: Client must accept both application/json and text/event-stream");const n=t.headers.get("content-type");if(!n||!n.includes("application/json"))return this.onerror?.(new Error("Unsupported Media Type: Content-Type must be application/json")),this.createJsonErrorResponse(415,-32e3,"Unsupported Media Type: Content-Type must be application/json");const o={headers:Object.fromEntries(t.headers.entries()),url:new URL(t.url)};let a,i;if(void 0!==r?.parsedBody)a=r.parsedBody;else try{a=await t.json()}catch{return this.onerror?.(new Error("Parse error: Invalid JSON")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON")}try{i=Array.isArray(a)?a.map(t=>e.JSONRPCMessageSchema.parse(t)):[e.JSONRPCMessageSchema.parse(a)]}catch{return this.onerror?.(new Error("Parse error: Invalid JSON-RPC message")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON-RPC message")}const l=i.some(e.isInitializeRequest);if(l){if(this._initialized&&void 0!==this.sessionId)return this.onerror?.(new Error("Invalid Request: Server already initialized")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Server already initialized");if(i.length>1)return this.onerror?.(new Error("Invalid Request: Only one initialization request is allowed")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Only one initialization request is allowed");this.sessionId=this.sessionIdGenerator?.(),this._initialized=!0,this.sessionId&&this._onsessioninitialized&&await Promise.resolve(this._onsessioninitialized(this.sessionId))}if(!l){const e=this.validateSession(t);if(e)return e;const r=this.validateProtocolVersion(t);if(r)return r}if(!i.some(e.isJSONRPCRequest)){for(const e of i)this.onmessage?.(e,{authInfo:r?.authInfo,requestInfo:o});return new Response(null,{status:202})}const c=crypto.randomUUID(),d=i.find(t=>e.isInitializeRequest(t)),h=d?d.params.protocolVersion:t.headers.get("mcp-protocol-version")??e.DEFAULT_NEGOTIATED_PROTOCOL_VERSION;if(this._enableJsonResponse)return new Promise(t=>{this._streamMapping.set(c,{resolveJson:t,cleanup:()=>{this._streamMapping.delete(c)}});for(const r of i)e.isJSONRPCRequest(r)&&this._requestToStreamMapping.set(r.id,c);for(const e of i)this.onmessage?.(e,{authInfo:r?.authInfo,requestInfo:o})});const p=new TextEncoder;let u;const m=new ReadableStream({start:e=>{u=e},cancel:()=>{this._streamMapping.delete(c)}}),f={"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"};void 0!==this.sessionId&&(f["mcp-session-id"]=this.sessionId);for(const t of i)e.isJSONRPCRequest(t)&&(this._streamMapping.set(c,{controller:u,encoder:p,cleanup:()=>{this._streamMapping.delete(c);try{u.close()}catch{}}}),this._requestToStreamMapping.set(t.id,c));await this.writePrimingEvent(u,p,c,h);for(const t of i){let s,n;e.isJSONRPCRequest(t)&&this._eventStore&&h>="2025-11-25"&&(s=()=>{this.closeSSEStream(t.id)},n=()=>{this.closeStandaloneSSEStream()}),this.onmessage?.(t,{authInfo:r?.authInfo,requestInfo:o,closeSSEStream:s,closeStandaloneSSEStream:n})}return new Response(m,{status:200,headers:f})}catch(s){return this.onerror?.(s),this.createJsonErrorResponse(400,-32700,"Parse error",{data:String(s)})}}async handleDeleteRequest(e){const t=this.validateSession(e);if(t)return t;const r=this.validateProtocolVersion(e);return r||(await Promise.resolve(this._onsessionclosed?.(this.sessionId)),await this.close(),new Response(null,{status:200}))}validateSession(e){if(void 0===this.sessionIdGenerator)return;if(!this._initialized)return this.onerror?.(new Error("Bad Request: Server not initialized")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Server not initialized");const t=e.headers.get("mcp-session-id");return t?t!==this.sessionId?(this.onerror?.(new Error("Session not found")),this.createJsonErrorResponse(404,-32001,"Session not found")):void 0:(this.onerror?.(new Error("Bad Request: Mcp-Session-Id header is required")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Mcp-Session-Id header is required"))}validateProtocolVersion(t){const r=t.headers.get("mcp-protocol-version");if(null!==r&&!e.SUPPORTED_PROTOCOL_VERSIONS.includes(r))return this.onerror?.(new Error(`Bad Request: Unsupported protocol version: ${r} (supported versions: ${e.SUPPORTED_PROTOCOL_VERSIONS.join(", ")})`)),this.createJsonErrorResponse(400,-32e3,`Bad Request: Unsupported protocol version: ${r} (supported versions: ${e.SUPPORTED_PROTOCOL_VERSIONS.join(", ")})`)}async close(){this._streamMapping.forEach(({cleanup:e})=>{e()}),this._streamMapping.clear(),this._requestResponseMap.clear(),this.onclose?.()}closeSSEStream(e){const t=this._requestToStreamMapping.get(e);if(!t)return;const r=this._streamMapping.get(t);r&&r.cleanup()}closeStandaloneSSEStream(){const e=this._streamMapping.get(this._standaloneSseStreamId);e&&e.cleanup()}async send(t,r){let s=r?.relatedRequestId;if((e.isJSONRPCResultResponse(t)||e.isJSONRPCErrorResponse(t))&&(s=t.id),void 0===s){if(e.isJSONRPCResultResponse(t)||e.isJSONRPCErrorResponse(t))throw new Error("Cannot send a response on a standalone SSE stream unless resuming a previous client request");let r;this._eventStore&&(r=await this._eventStore.storeEvent(this._standaloneSseStreamId,t));const s=this._streamMapping.get(this._standaloneSseStreamId);if(void 0===s)return;return void(s.controller&&s.encoder&&this.writeSSEEvent(s.controller,s.encoder,t,r))}const n=this._requestToStreamMapping.get(s);if(!n)throw new Error(`No connection established for request ID: ${String(s)}`);const o=this._streamMapping.get(n);if(!this._enableJsonResponse&&o?.controller&&o?.encoder){let e;this._eventStore&&(e=await this._eventStore.storeEvent(n,t)),this.writeSSEEvent(o.controller,o.encoder,t,e)}if(e.isJSONRPCResultResponse(t)||e.isJSONRPCErrorResponse(t)){this._requestResponseMap.set(s,t);const e=Array.from(this._requestToStreamMapping.entries()).filter(([e,t])=>t===n).map(([e])=>e);if(e.every(e=>this._requestResponseMap.has(e))){if(!o)throw new Error(`No connection established for request ID: ${String(s)}`);if(this._enableJsonResponse&&o.resolveJson){const t={"Content-Type":"application/json"};void 0!==this.sessionId&&(t["mcp-session-id"]=this.sessionId);const r=e.map(e=>this._requestResponseMap.get(e));1===r.length?o.resolveJson(new Response(JSON.stringify(r[0]),{status:200,headers:t})):o.resolveJson(new Response(JSON.stringify(r),{status:200,headers:t}))}else o.cleanup();for(const t of e)this._requestResponseMap.delete(t),this._requestToStreamMapping.delete(t)}}}}class L{constructor(e={}){this._requestContext=new WeakMap,this._webStandardTransport=new k(e),this._requestListener=U(async e=>{const t=this._requestContext.get(e);return this._webStandardTransport.handleRequest(e,{authInfo:t?.authInfo,parsedBody:t?.parsedBody})},{overrideGlobalObjects:!1})}get sessionId(){return this._webStandardTransport.sessionId}set onclose(e){this._webStandardTransport.onclose=e}get onclose(){return this._webStandardTransport.onclose}set onerror(e){this._webStandardTransport.onerror=e}get onerror(){return this._webStandardTransport.onerror}set onmessage(e){this._webStandardTransport.onmessage=e}get onmessage(){return this._webStandardTransport.onmessage}async start(){return this._webStandardTransport.start()}async close(){return this._webStandardTransport.close()}async send(e,t){return this._webStandardTransport.send(e,t)}async handleRequest(e,t,r){const s=e.auth,n=U(async e=>this._webStandardTransport.handleRequest(e,{authInfo:s,parsedBody:r}),{overrideGlobalObjects:!1});await n(e,t)}closeSSEStream(e){this._webStandardTransport.closeSSEStream(e)}closeStandaloneSSEStream(){this._webStandardTransport.closeStandaloneSSEStream()}}class x{constructor(){this.version=e.getPackageVersion(),this.server=new e.Server({name:"@aiquants/html-to-markdown-streamable",version:this.version},{capabilities:{tools:{}}}),this.transport=new L({sessionIdGenerator:void 0}),this.tools=[{name:"html_to_markdown_streamable",description:"Streamable HTML to Markdown converter with real-time progress updates. Ideal for large pages and time-consuming conversions with JavaScript dynamic content support.",inputSchema:{type:"object",properties:{url:{type:"string",description:"URL of the web page to convert (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."},html_content:{type:"string",description:"HTML string to convert directly. Use instead of URL for local files or API response HTML content."},locale:{type:"string",description:"Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",enum:["en-US","ja-JP"],default:"en-US"}},anyOf:[{required:["url"]},{required:["html_content"]}]},handler:(e,t)=>this.handleHtmlToMarkdown(e,t)},{name:"save_content_to_file",description:"Save text content to a file with specified path or directory. Supports automatic filename generation. Content will be saved as Markdown format.",inputSchema:{type:"object",properties:{content:{type:"string",description:"Text content to save to file. Will be saved as Markdown format."},save_path:{type:"string",description:"Complete file path including filename to save content (e.g., '/home/user/output.md'). Cannot be used with save_directory."},save_directory:{type:"string",description:"Directory path to save content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."},filename:{type:"string",description:"Base filename to use when save_directory is specified (e.g., 'my-document'). Extension .md will be added automatically."}},required:["content"],anyOf:[{required:["save_path"]},{required:["save_directory"]}]},handler:(e,t)=>this.handleSaveContentToFile(e,t)},{name:"url_to_markdown_file_streamable",description:"Streamable URL to Markdown file converter with real-time progress updates. Combines HTML-to-Markdown conversion and file saving in one step. Ideal for large pages with JavaScript dynamic content support.",inputSchema:{type:"object",properties:{url:{type:"string",description:"URL of the web page to convert and save as Markdown file (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."},html_content:{type:"string",description:"HTML string to convert directly and save as Markdown file. Use instead of URL for local files or API response HTML content."},locale:{type:"string",description:"Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",enum:["en-US","ja-JP"],default:"en-US"},save_path:{type:"string",description:"Complete file path including filename to save the converted Markdown content (e.g., '/home/user/output.md'). Cannot be used with save_directory."},save_directory:{type:"string",description:"Directory path to save the converted Markdown content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."},filename:{type:"string",description:"Base filename to use when save_directory is specified (e.g., 'my-document'). Extension .md will be added automatically."}},anyOf:[{required:["url","save_path"]},{required:["url","save_directory"]},{required:["html_content","save_path"]},{required:["html_content","save_directory"]}]},handler:(e,t)=>this.handleUrlToMarkdownFile(e,t)}],this.setupRequestHandlers()}getServer(){return this.server}setupRequestHandlers(){this.server.setRequestHandler(e.InitializeRequestSchema,async e=>({protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"@aiquants/html-to-markdown-streamable",version:this.version}})),this.server.setRequestHandler(e.ListToolsRequestSchema,async()=>({tools:this.tools.map(({name:e,description:t,inputSchema:r})=>({name:e,description:t,inputSchema:r}))}));this.server.setRequestHandler(e.CallToolRequestSchema,async(e,t)=>{const r=this.tools.find(t=>t.name===e.params.name);if(!r)throw new Error(`Unknown tool: ${e.params.name}`);const s=(0,r.handler)(e.params.arguments,{}),n=e.params._meta?.progressToken;let o;for await(const l of s)if("progress"===l.type){if(void 0!==n){const e={method:"notifications/progress",params:{progressToken:n,progress:l.progress,total:l.total||100}};try{const t=this.transport;t.sendNotification&&await t.sendNotification(e)}catch(a){i.Logger.debug("Progress streamable not supported or failed:",a)}}}else if("result"===l.type){o=l.result;break}if(!o)throw new Error("Tool did not return a result");return o})}async*handleHtmlToMarkdown(t,r){try{const r=e.parseHtmlToMarkdownArgs(t),{url:s,html_content:n,locale:o="en-US"}=r;if(s)try{new URL(s)}catch{throw new Error(`Invalid URL: ${s}`)}yield{type:"progress",progress:0,message:"Web ページの内容を取得して Markdown に変換します。"};const a=await i.htmlToMarkdown(s||"direct-html-input",{locale:o,htmlContent:n});yield{type:"progress",progress:100,message:"変換が完了しました。"};const l=[{type:"text",text:a.markdown}];yield{type:"result",result:{content:l}}}catch(s){const e=s instanceof Error?s.message:String(s);yield{type:"result",result:{content:[{type:"text",text:`エラーが発生しました: ${e}`}]}}}}async*handleSaveContentToFile(t,r){try{const r=e.parseSaveContentArgs(t),{content:s,save_path:n,save_directory:o,filename:a}=r;yield{type:"progress",progress:20,message:"ファイル保存の準備中..."};const i=await e.saveContentToFile(s,n,o,a);yield{type:"progress",progress:100,message:"ファイル保存が完了しました。"};const l=`Content saved successfully to: ${i}`;yield{type:"result",result:{content:[{type:"text",text:l}],isError:!1}}}catch(s){const e=s instanceof Error?s.message:String(s);yield{type:"result",result:{content:[{type:"text",text:`エラーが発生しました: ${e}`}],isError:!0}}}}async*handleUrlToMarkdownFile(t,r){try{const r=e.parseUrlToMarkdownFileArgs(t),{url:s,html_content:n,locale:o="en-US",save_path:a,save_directory:l,filename:c}=r;if(s)try{new URL(s)}catch{throw new Error(`Invalid URL: ${s}`)}yield{type:"progress",progress:0,message:"Web ページの内容を取得して Markdown に変換します。"};const d=await i.htmlToMarkdown(s||"direct-html-input",{locale:o,htmlContent:n});yield{type:"progress",progress:70,message:"Markdown への変換が完了しました。ファイルに保存しています。"};const h=d.markdown;let p=c;!p&&s&&(p=this.generateFilenameFromUrl(s));const u=await e.saveContentToFile(h,a,l,p);yield{type:"progress",progress:100,message:"ファイルの保存が完了しました。"};const m=`URL successfully converted to Markdown and saved to: ${u}`;yield{type:"result",result:{content:[{type:"text",text:m}],isError:!1}}}catch(s){const e=s instanceof Error?s.message:String(s);yield{type:"result",result:{content:[{type:"text",text:`エラーが発生しました: ${e}`}],isError:!0}}}}generateFilenameFromUrl(e){try{let t=new URL(e).pathname.split("/").pop()||"page";return t=t.replace(/\.[^.]*$/,""),t=t.replace(/[<>:"/\\|?*]/g,"_"),t&&!t.match(/^\.+$/)||(t="page"),t}catch{return"page"}}async start(e="127.0.0.1",t=4001){const r=o();r.use(n({origin:"*",methods:["GET","POST","PUT","DELETE","OPTIONS"],allowedHeaders:["Content-Type","Authorization"]})),r.use(o.json()),await this.server.connect(this.transport),r.post("/mcp",async(e,t)=>{i.Logger.info("Received MCP request:",e.body);try{t.setHeader("Content-Type","application/json");const s=e.body;if(!s?.method)return void t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid Request"},id:s?.id||null});let n;if("initialize"===s.method)n={jsonrpc:"2.0",id:s.id,result:{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"@aiquants/html-to-markdown-streamable",version:this.version}}};else if("tools/list"===s.method)n={jsonrpc:"2.0",id:s.id,result:{tools:this.tools.map(({name:e,description:t,inputSchema:r})=>({name:e,description:t,inputSchema:r}))}};else if("tools/call"===s.method){const e=this.tools.find(e=>e.name===s.params.name);if(e)try{const t={},r=e.handler(s.params.arguments,t);let o;for await(const e of r)if("result"===e.type){o=e.result;break}n={jsonrpc:"2.0",id:s.id,result:o}}catch(r){n={jsonrpc:"2.0",id:s.id,error:{code:-32603,message:r instanceof Error?r.message:String(r)}}}else n={jsonrpc:"2.0",id:s.id,error:{code:-32601,message:`Unknown tool: ${s.params.name}`}}}else n={jsonrpc:"2.0",id:s.id,error:{code:-32601,message:"Method not found"}};t.status(200).json(n)}catch(r){i.Logger.error("Error handling MCP request:",r),t.headersSent||t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}}),r.get("/mcp",async(e,t)=>{i.Logger.info("Received GET MCP request"),t.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}),r.delete("/mcp",async(e,t)=>{i.Logger.info("Received DELETE MCP request"),t.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))});const s=r.listen(t,e,()=>{i.Logger.info(`HTML to Markdown Streamable MCP server started on http://${e}:${t}/mcp`)});process.on("SIGINT",async()=>{i.Logger.info("Shutting down server...");try{i.Logger.info("Closing transport"),await this.transport.close()}catch(e){i.Logger.error("Error closing transport:",e)}await this.server.close(),s.close(()=>{i.Logger.info("Server shutdown complete"),process.exit(0)})})}}const N=()=>new x;exports.createStreamableMcpServer=N,exports.runStreamableMcpServer=async()=>{const e=a(process.argv.slice(2)),t=e.host||"127.0.0.1",r=e.port||4001,s=N();await s.start(t,r)};
@@ -0,0 +1 @@
1
+ import{J as e,i as t,e as r,D as s,f as n,h as o,j as a,g as i,S as c,I as l,L as d,C as h,p,b as u,s as m,d as f}from"./version-Fr0FqrXS.js";import"http";import{Http2ServerRequest as y,constants as g}from"http2";import{Readable as w}from"stream";import v from"crypto";import S from"cors";import b from"express";import _ from"yargs-parser";import{h as E,L as R}from"./core-CkCUqS2i.js";var T=class extends Error{constructor(e,t){super(e,t),this.name="RequestError"}},q=global.Request,I=class extends q{constructor(e,t){"object"==typeof e&&C in e&&(e=e[C]()),void 0!==t?.body?.getReader&&(t.duplex??="half"),super(e,t)}},M=/* @__PURE__ */Symbol("wrapBodyStream"),C=/* @__PURE__ */Symbol("getRequestCache"),j=/* @__PURE__ */Symbol("requestCache"),P=/* @__PURE__ */Symbol("incomingKey"),H=/* @__PURE__ */Symbol("urlKey"),U=/* @__PURE__ */Symbol("headersKey"),J=/* @__PURE__ */Symbol("abortControllerKey"),O=/* @__PURE__ */Symbol("getAbortController"),k={get method(){return this[P].method||"GET"},get url(){return this[H]},get headers(){return this[U]||=(e=>{const t=[],r=e.rawHeaders;for(let s=0;s<r.length;s+=2){const{[s]:e,[s+1]:n}=r;58!==e.charCodeAt(0)&&t.push([e,n])}return new Headers(t)})(this[P])},[O](){return this[C](),this[J]},[C](){return this[J]||=new AbortController,this[j]||=((e,t,r,s,n)=>{const o={method:e,headers:r,signal:n.signal};if("TRACE"===e){o.method="GET";const e=new I(t,o);return Object.defineProperty(e,"method",{get:()=>"TRACE"}),e}if("GET"!==e&&"HEAD"!==e)if("rawBody"in s&&s.rawBody instanceof Buffer)o.body=new ReadableStream({start(e){e.enqueue(s.rawBody),e.close()}});else if(s[M]){let e;o.body=new ReadableStream({async pull(t){try{e||=w.toWeb(s).getReader();const{done:r,value:n}=await e.read();r?t.close():t.enqueue(n)}catch(r){t.error(r)}}})}else o.body=w.toWeb(s);return new I(t,o)})(this.method,this[H],this.headers,this[P],this[J])}};["body","bodyUsed","cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","signal","keepalive"].forEach(e=>{Object.defineProperty(k,e,{get(){return this[C]()[e]}})}),["arrayBuffer","blob","clone","formData","json","text"].forEach(e=>{Object.defineProperty(k,e,{value:function(){return this[C]()[e]()}})}),Object.defineProperty(k,/* @__PURE__ */Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Request (lightweight) ${r({method:this.method,url:this.url,headers:this.headers,nativeRequest:this[j]},{...t,depth:null==e?null:e-1})}`}}),Object.setPrototypeOf(k,I.prototype);var x=/* @__PURE__ */Symbol("responseCache"),L=/* @__PURE__ */Symbol("getResponseCache"),$=/* @__PURE__ */Symbol("cache"),A=global.Response,B=class e{#e;#t;[L](){return delete this[$],this[x]||=new A(this.#e,this.#t)}constructor(t,r){let s;if(this.#e=t,r instanceof e){const e=r[x];if(e)return this.#t=e,void this[L]();this.#t=r.#t,s=new Headers(r.#t.headers)}else this.#t=r;("string"==typeof t||void 0!==t?.getReader||t instanceof Blob||t instanceof Uint8Array)&&(this[$]=[r?.status||200,t,s||r?.headers])}get headers(){const e=this[$];return e?(e[2]instanceof Headers||(e[2]=new Headers(e[2]||{"content-type":"text/plain; charset=UTF-8"})),e[2]):this[L]().headers}get status(){return this[$]?.[0]??this[L]().status}get ok(){const e=this.status;return e>=200&&e<300}};async function N(e){return Promise.race([e,Promise.resolve().then(()=>Promise.resolve(void 0))])}function D(e,t,r){const s=t=>{e.cancel(t).catch(()=>{})};return t.on("close",s),t.on("error",s),(r??e.read()).then(a,n),e.closed.finally(()=>{t.off("close",s),t.off("error",s)});function n(e){e&&t.destroy(e)}function o(){e.read().then(a,n)}function a({done:r,value:s}){try{if(r)t.end();else{if(t.write(s))return e.read().then(a,n);t.once("drain",o)}}catch(i){n(i)}}}["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach(e=>{Object.defineProperty(B.prototype,e,{get(){return this[L]()[e]}})}),["arrayBuffer","blob","clone","formData","json","text"].forEach(e=>{Object.defineProperty(B.prototype,e,{value:function(){return this[L]()[e]()}})}),Object.defineProperty(B.prototype,/* @__PURE__ */Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Response (lightweight) ${r({status:this.status,headers:this.headers,ok:this.ok,nativeResponse:this[x]},{...t,depth:null==e?null:e-1})}`}}),Object.setPrototypeOf(B,A),Object.setPrototypeOf(B.prototype,A.prototype);var G=e=>{const t={};e instanceof Headers||(e=new Headers(e??void 0));const r=[];for(const[s,n]of e)"set-cookie"===s?r.push(n):t[s]=n;return r.length>0&&(t["set-cookie"]=r),t["content-type"]??="text/plain; charset=UTF-8",t};void 0===global.crypto&&(global.crypto=v);var z=/* @__PURE__ */Symbol("outgoingEnded"),F=/* @__PURE__ */Symbol("incomingDraining"),W=e=>{const t=e;if(e.destroyed||t[F])return;if(t[F]=!0,e instanceof y){try{e.stream?.close?.(g.NGHTTP2_NO_ERROR)}catch{}return}let r=0;const s=()=>{clearTimeout(o),e.off("data",a),e.off("end",s),e.off("error",s)},n=()=>{s();const t=e.socket;t&&!t.destroyed&&t.destroySoon()},o=setTimeout(n,500);o.unref?.();const a=e=>{r+=e.length,r>67108864&&n()};e.on("data",a),e.on("end",s),e.on("error",s),e.resume()},V=e=>new Response(null,{status:e instanceof Error&&("TimeoutError"===e.name||"TimeoutError"===e.constructor.name)?504:500}),K=(e,t)=>{const r=e instanceof Error?e:new Error("unknown error",{cause:e});"ERR_STREAM_PREMATURE_CLOSE"===r.code||(t.headersSent||t.writeHead(500,{"Content-Type":"text/plain"}),t.end(`Error: ${r.message}`),t.destroy(r))},Q=e=>{"flushHeaders"in e&&e.writable&&e.flushHeaders()},X=async(e,t)=>{let[r,s,n]=e[$],o=!1;if(n){if(n instanceof Headers)o=n.has("content-length"),n=G(n);else if(Array.isArray(n)){const e=new Headers(n);o=e.has("content-length"),n=G(e)}else for(const a in n)if(14===a.length&&"content-length"===a.toLowerCase()){o=!0;break}}else n={"content-type":"text/plain; charset=UTF-8"};o||("string"==typeof s?n["Content-Length"]=Buffer.byteLength(s):s instanceof Uint8Array?n["Content-Length"]=s.byteLength:s instanceof Blob&&(n["Content-Length"]=s.size)),t.writeHead(r,n),"string"==typeof s||s instanceof Uint8Array?t.end(s):s instanceof Blob?t.end(new Uint8Array(await s.arrayBuffer())):(Q(t),await(function(e,t){if(e.locked)throw new TypeError("ReadableStream is locked.");if(!t.destroyed)return D(e.getReader(),t)}(s,t)?.catch(e=>K(e,t)))),t[z]?.()},Y=(e,t={})=>{const r=t.autoCleanupIncoming??!0;return!1!==t.overrideGlobalObjects&&global.Request!==I&&(Object.defineProperty(global,"Request",{value:I}),Object.defineProperty(global,"Response",{value:B})),async(s,n)=>{let o,a;try{a=((e,t)=>{const r=Object.create(k);r[P]=e;const s=e.url||"";if("/"!==s[0]&&(s.startsWith("http://")||s.startsWith("https://"))){if(e instanceof y)throw new T("Absolute URL for :path is not allowed in HTTP/2");try{const e=new URL(s);r[H]=e.href}catch(i){throw new T("Invalid absolute URL",{cause:i})}return r}const n=(e instanceof y?e.authority:e.headers.host)||t;if(!n)throw new T("Missing host header");let o;if(e instanceof y){if(o=e.scheme,"http"!==o&&"https"!==o)throw new T("Unsupported scheme")}else o=e.socket&&e.socket.encrypted?"https":"http";const a=new URL(`${o}://${n}${s}`);if(a.hostname.length!==n.length&&a.hostname!==n.replace(/:\d+$/,""))throw new T("Invalid host header");return r[H]=a.href,r})(s,t.hostname);let i=!r||"GET"===s.method||"HEAD"===s.method;if(i||(s[M]=!0,s.on("end",()=>{i=!0}),s instanceof y&&(n[z]=()=>{i||setTimeout(()=>{i||setTimeout(()=>{W(s)})})}),n.on("finish",()=>{i||W(s)})),n.on("close",()=>{a[J]&&(s.errored?a[J].abort(s.errored.toString()):n.writableFinished||a[J].abort("Client connection prematurely closed.")),i||setTimeout(()=>{i||setTimeout(()=>{W(s)})})}),o=e(a,{incoming:s,outgoing:n}),$ in o)return X(o,n)}catch(i){if(o)return K(i,n);if(t.errorHandler){if(o=await t.errorHandler(a?i:(e=>e instanceof T?e:new T(e.message,{cause:e}))(i)),!o)return}else o=a?V(i):new Response(null,{status:400})}try{return await(async(e,t,r={})=>{if((e=>"function"==typeof e.then)(e))if(r.errorHandler)try{e=await e}catch(n){const t=await r.errorHandler(n);if(!t)return;e=t}else e=await e.catch(V);if($ in e)return X(e,t);const s=G(e.headers);if(e.body){const r=e.body.getReader(),n=[];let o,a=!1;if("chunked"!==s["transfer-encoding"]){let e=2;for(let t=0;t<e;t++){o||=r.read();const s=await N(o).catch(e=>{a=!0});if(!s){if(1===t){await new Promise(e=>setTimeout(e)),e=3;continue}break}if(o=void 0,s.value&&n.push(s.value),s.done){a=!0;break}}a&&!("content-length"in s)&&(s["content-length"]=n.reduce((e,t)=>e+t.length,0))}t.writeHead(e.status,s),n.forEach(e=>{t.write(e)}),a?t.end():(0===n.length&&Q(t),await D(r,t,o))}else s["x-hono-already-sent"]||(t.writeHead(e.status,s),t.end());t[z]?.()})(o,n,t)}catch(i){return K(i,n)}}};class Z{constructor(e={}){this._started=!1,this._hasHandledRequest=!1,this._streamMapping=/* @__PURE__ */new Map,this._requestToStreamMapping=/* @__PURE__ */new Map,this._requestResponseMap=/* @__PURE__ */new Map,this._initialized=!1,this._enableJsonResponse=!1,this._standaloneSseStreamId="_GET_stream",this.sessionIdGenerator=e.sessionIdGenerator,this._enableJsonResponse=e.enableJsonResponse??!1,this._eventStore=e.eventStore,this._onsessioninitialized=e.onsessioninitialized,this._onsessionclosed=e.onsessionclosed,this._allowedHosts=e.allowedHosts,this._allowedOrigins=e.allowedOrigins,this._enableDnsRebindingProtection=e.enableDnsRebindingProtection??!1,this._retryInterval=e.retryInterval}async start(){if(this._started)throw new Error("Transport already started");this._started=!0}createJsonErrorResponse(e,t,r,s){const n={code:t,message:r};return void 0!==s?.data&&(n.data=s.data),new Response(JSON.stringify({jsonrpc:"2.0",error:n,id:null}),{status:e,headers:{"Content-Type":"application/json",...s?.headers}})}validateRequestHeaders(e){if(this._enableDnsRebindingProtection){if(this._allowedHosts&&this._allowedHosts.length>0){const t=e.headers.get("host");if(!t||!this._allowedHosts.includes(t)){const e=`Invalid Host header: ${t}`;return this.onerror?.(new Error(e)),this.createJsonErrorResponse(403,-32e3,e)}}if(this._allowedOrigins&&this._allowedOrigins.length>0){const t=e.headers.get("origin");if(t&&!this._allowedOrigins.includes(t)){const e=`Invalid Origin header: ${t}`;return this.onerror?.(new Error(e)),this.createJsonErrorResponse(403,-32e3,e)}}}}async handleRequest(e,t){if(!this.sessionIdGenerator&&this._hasHandledRequest)throw new Error("Stateless transport cannot be reused across requests. Create a new transport per request.");this._hasHandledRequest=!0;const r=this.validateRequestHeaders(e);if(r)return r;switch(e.method){case"POST":return this.handlePostRequest(e,t);case"GET":return this.handleGetRequest(e);case"DELETE":return this.handleDeleteRequest(e);default:return this.handleUnsupportedRequest()}}async writePrimingEvent(e,t,r,s){if(!this._eventStore)return;if(s<"2025-11-25")return;const n=await this._eventStore.storeEvent(r,{});let o=`id: ${n}\ndata: \n\n`;void 0!==this._retryInterval&&(o=`id: ${n}\nretry: ${this._retryInterval}\ndata: \n\n`),e.enqueue(t.encode(o))}async handleGetRequest(e){const t=e.headers.get("accept");if(!t?.includes("text/event-stream"))return this.onerror?.(new Error("Not Acceptable: Client must accept text/event-stream")),this.createJsonErrorResponse(406,-32e3,"Not Acceptable: Client must accept text/event-stream");const r=this.validateSession(e);if(r)return r;const s=this.validateProtocolVersion(e);if(s)return s;if(this._eventStore){const t=e.headers.get("last-event-id");if(t)return this.replayEvents(t)}if(void 0!==this._streamMapping.get(this._standaloneSseStreamId))return this.onerror?.(new Error("Conflict: Only one SSE stream is allowed per session")),this.createJsonErrorResponse(409,-32e3,"Conflict: Only one SSE stream is allowed per session");const n=new TextEncoder;let o;const a=new ReadableStream({start:e=>{o=e},cancel:()=>{this._streamMapping.delete(this._standaloneSseStreamId)}}),i={"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"};return void 0!==this.sessionId&&(i["mcp-session-id"]=this.sessionId),this._streamMapping.set(this._standaloneSseStreamId,{controller:o,encoder:n,cleanup:()=>{this._streamMapping.delete(this._standaloneSseStreamId);try{o.close()}catch{}}}),new Response(a,{headers:i})}async replayEvents(e){if(!this._eventStore)return this.onerror?.(new Error("Event store not configured")),this.createJsonErrorResponse(400,-32e3,"Event store not configured");try{let t;if(this._eventStore.getStreamIdForEventId){if(t=await this._eventStore.getStreamIdForEventId(e),!t)return this.onerror?.(new Error("Invalid event ID format")),this.createJsonErrorResponse(400,-32e3,"Invalid event ID format");if(void 0!==this._streamMapping.get(t))return this.onerror?.(new Error("Conflict: Stream already has an active connection")),this.createJsonErrorResponse(409,-32e3,"Conflict: Stream already has an active connection")}const r={"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"};void 0!==this.sessionId&&(r["mcp-session-id"]=this.sessionId);const s=new TextEncoder;let n;const o=new ReadableStream({start:e=>{n=e},cancel:()=>{}}),a=await this._eventStore.replayEventsAfter(e,{send:async(e,t)=>{if(!this.writeSSEEvent(n,s,t,e)){this.onerror?.(new Error("Failed replay events"));try{n.close()}catch{}}}});return this._streamMapping.set(a,{controller:n,encoder:s,cleanup:()=>{this._streamMapping.delete(a);try{n.close()}catch{}}}),new Response(o,{headers:r})}catch(t){return this.onerror?.(t),this.createJsonErrorResponse(500,-32e3,"Error replaying events")}}writeSSEEvent(e,t,r,s){try{let n="event: message\n";return s&&(n+=`id: ${s}\n`),n+=`data: ${JSON.stringify(r)}\n\n`,e.enqueue(t.encode(n)),!0}catch(n){return this.onerror?.(n),!1}}handleUnsupportedRequest(){return this.onerror?.(new Error("Method not allowed.")),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}),{status:405,headers:{Allow:"GET, POST, DELETE","Content-Type":"application/json"}})}async handlePostRequest(n,o){try{const a=n.headers.get("accept");if(!a?.includes("application/json")||!a.includes("text/event-stream"))return this.onerror?.(new Error("Not Acceptable: Client must accept both application/json and text/event-stream")),this.createJsonErrorResponse(406,-32e3,"Not Acceptable: Client must accept both application/json and text/event-stream");const i=n.headers.get("content-type");if(!i||!i.includes("application/json"))return this.onerror?.(new Error("Unsupported Media Type: Content-Type must be application/json")),this.createJsonErrorResponse(415,-32e3,"Unsupported Media Type: Content-Type must be application/json");const c={headers:Object.fromEntries(n.headers.entries()),url:new URL(n.url)};let l,d;if(void 0!==o?.parsedBody)l=o.parsedBody;else try{l=await n.json()}catch{return this.onerror?.(new Error("Parse error: Invalid JSON")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON")}try{d=Array.isArray(l)?l.map(t=>e.parse(t)):[e.parse(l)]}catch{return this.onerror?.(new Error("Parse error: Invalid JSON-RPC message")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON-RPC message")}const h=d.some(t);if(h){if(this._initialized&&void 0!==this.sessionId)return this.onerror?.(new Error("Invalid Request: Server already initialized")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Server already initialized");if(d.length>1)return this.onerror?.(new Error("Invalid Request: Only one initialization request is allowed")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Only one initialization request is allowed");this.sessionId=this.sessionIdGenerator?.(),this._initialized=!0,this.sessionId&&this._onsessioninitialized&&await Promise.resolve(this._onsessioninitialized(this.sessionId))}if(!h){const e=this.validateSession(n);if(e)return e;const t=this.validateProtocolVersion(n);if(t)return t}if(!d.some(r)){for(const e of d)this.onmessage?.(e,{authInfo:o?.authInfo,requestInfo:c});return new Response(null,{status:202})}const p=crypto.randomUUID(),u=d.find(e=>t(e)),m=u?u.params.protocolVersion:n.headers.get("mcp-protocol-version")??s;if(this._enableJsonResponse)return new Promise(e=>{this._streamMapping.set(p,{resolveJson:e,cleanup:()=>{this._streamMapping.delete(p)}});for(const t of d)r(t)&&this._requestToStreamMapping.set(t.id,p);for(const t of d)this.onmessage?.(t,{authInfo:o?.authInfo,requestInfo:c})});const f=new TextEncoder;let y;const g=new ReadableStream({start:e=>{y=e},cancel:()=>{this._streamMapping.delete(p)}}),w={"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"};void 0!==this.sessionId&&(w["mcp-session-id"]=this.sessionId);for(const e of d)r(e)&&(this._streamMapping.set(p,{controller:y,encoder:f,cleanup:()=>{this._streamMapping.delete(p);try{y.close()}catch{}}}),this._requestToStreamMapping.set(e.id,p));await this.writePrimingEvent(y,f,p,m);for(const e of d){let t,s;r(e)&&this._eventStore&&m>="2025-11-25"&&(t=()=>{this.closeSSEStream(e.id)},s=()=>{this.closeStandaloneSSEStream()}),this.onmessage?.(e,{authInfo:o?.authInfo,requestInfo:c,closeSSEStream:t,closeStandaloneSSEStream:s})}return new Response(g,{status:200,headers:w})}catch(a){return this.onerror?.(a),this.createJsonErrorResponse(400,-32700,"Parse error",{data:String(a)})}}async handleDeleteRequest(e){const t=this.validateSession(e);if(t)return t;const r=this.validateProtocolVersion(e);return r||(await Promise.resolve(this._onsessionclosed?.(this.sessionId)),await this.close(),new Response(null,{status:200}))}validateSession(e){if(void 0===this.sessionIdGenerator)return;if(!this._initialized)return this.onerror?.(new Error("Bad Request: Server not initialized")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Server not initialized");const t=e.headers.get("mcp-session-id");return t?t!==this.sessionId?(this.onerror?.(new Error("Session not found")),this.createJsonErrorResponse(404,-32001,"Session not found")):void 0:(this.onerror?.(new Error("Bad Request: Mcp-Session-Id header is required")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Mcp-Session-Id header is required"))}validateProtocolVersion(e){const t=e.headers.get("mcp-protocol-version");if(null!==t&&!n.includes(t))return this.onerror?.(new Error(`Bad Request: Unsupported protocol version: ${t} (supported versions: ${n.join(", ")})`)),this.createJsonErrorResponse(400,-32e3,`Bad Request: Unsupported protocol version: ${t} (supported versions: ${n.join(", ")})`)}async close(){this._streamMapping.forEach(({cleanup:e})=>{e()}),this._streamMapping.clear(),this._requestResponseMap.clear(),this.onclose?.()}closeSSEStream(e){const t=this._requestToStreamMapping.get(e);if(!t)return;const r=this._streamMapping.get(t);r&&r.cleanup()}closeStandaloneSSEStream(){const e=this._streamMapping.get(this._standaloneSseStreamId);e&&e.cleanup()}async send(e,t){let r=t?.relatedRequestId;if((o(e)||a(e))&&(r=e.id),void 0===r){if(o(e)||a(e))throw new Error("Cannot send a response on a standalone SSE stream unless resuming a previous client request");let t;this._eventStore&&(t=await this._eventStore.storeEvent(this._standaloneSseStreamId,e));const r=this._streamMapping.get(this._standaloneSseStreamId);if(void 0===r)return;return void(r.controller&&r.encoder&&this.writeSSEEvent(r.controller,r.encoder,e,t))}const s=this._requestToStreamMapping.get(r);if(!s)throw new Error(`No connection established for request ID: ${String(r)}`);const n=this._streamMapping.get(s);if(!this._enableJsonResponse&&n?.controller&&n?.encoder){let t;this._eventStore&&(t=await this._eventStore.storeEvent(s,e)),this.writeSSEEvent(n.controller,n.encoder,e,t)}if(o(e)||a(e)){this._requestResponseMap.set(r,e);const t=Array.from(this._requestToStreamMapping.entries()).filter(([e,t])=>t===s).map(([e])=>e);if(t.every(e=>this._requestResponseMap.has(e))){if(!n)throw new Error(`No connection established for request ID: ${String(r)}`);if(this._enableJsonResponse&&n.resolveJson){const e={"Content-Type":"application/json"};void 0!==this.sessionId&&(e["mcp-session-id"]=this.sessionId);const r=t.map(e=>this._requestResponseMap.get(e));1===r.length?n.resolveJson(new Response(JSON.stringify(r[0]),{status:200,headers:e})):n.resolveJson(new Response(JSON.stringify(r),{status:200,headers:e}))}else n.cleanup();for(const e of t)this._requestResponseMap.delete(e),this._requestToStreamMapping.delete(e)}}}}class ee{constructor(e={}){this._requestContext=/* @__PURE__ */new WeakMap,this._webStandardTransport=new Z(e),this._requestListener=Y(async e=>{const t=this._requestContext.get(e);return this._webStandardTransport.handleRequest(e,{authInfo:t?.authInfo,parsedBody:t?.parsedBody})},{overrideGlobalObjects:!1})}get sessionId(){return this._webStandardTransport.sessionId}set onclose(e){this._webStandardTransport.onclose=e}get onclose(){return this._webStandardTransport.onclose}set onerror(e){this._webStandardTransport.onerror=e}get onerror(){return this._webStandardTransport.onerror}set onmessage(e){this._webStandardTransport.onmessage=e}get onmessage(){return this._webStandardTransport.onmessage}async start(){return this._webStandardTransport.start()}async close(){return this._webStandardTransport.close()}async send(e,t){return this._webStandardTransport.send(e,t)}async handleRequest(e,t,r){const s=e.auth,n=Y(async e=>this._webStandardTransport.handleRequest(e,{authInfo:s,parsedBody:r}),{overrideGlobalObjects:!1});await n(e,t)}closeSSEStream(e){this._webStandardTransport.closeSSEStream(e)}closeStandaloneSSEStream(){this._webStandardTransport.closeStandaloneSSEStream()}}class te{constructor(){this.version=i(),this.server=new c({name:"@aiquants/html-to-markdown-streamable",version:this.version},{capabilities:{tools:{}}}),this.transport=new ee({sessionIdGenerator:void 0}),this.tools=[{name:"html_to_markdown_streamable",description:"Streamable HTML to Markdown converter with real-time progress updates. Ideal for large pages and time-consuming conversions with JavaScript dynamic content support.",inputSchema:{type:"object",properties:{url:{type:"string",description:"URL of the web page to convert (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."},html_content:{type:"string",description:"HTML string to convert directly. Use instead of URL for local files or API response HTML content."},locale:{type:"string",description:"Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",enum:["en-US","ja-JP"],default:"en-US"}},anyOf:[{required:["url"]},{required:["html_content"]}]},handler:(e,t)=>this.handleHtmlToMarkdown(e,t)},{name:"save_content_to_file",description:"Save text content to a file with specified path or directory. Supports automatic filename generation. Content will be saved as Markdown format.",inputSchema:{type:"object",properties:{content:{type:"string",description:"Text content to save to file. Will be saved as Markdown format."},save_path:{type:"string",description:"Complete file path including filename to save content (e.g., '/home/user/output.md'). Cannot be used with save_directory."},save_directory:{type:"string",description:"Directory path to save content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."},filename:{type:"string",description:"Base filename to use when save_directory is specified (e.g., 'my-document'). Extension .md will be added automatically."}},required:["content"],anyOf:[{required:["save_path"]},{required:["save_directory"]}]},handler:(e,t)=>this.handleSaveContentToFile(e,t)},{name:"url_to_markdown_file_streamable",description:"Streamable URL to Markdown file converter with real-time progress updates. Combines HTML-to-Markdown conversion and file saving in one step. Ideal for large pages with JavaScript dynamic content support.",inputSchema:{type:"object",properties:{url:{type:"string",description:"URL of the web page to convert and save as Markdown file (e.g., https://example.com). Handles JavaScript-rendered dynamic content effectively."},html_content:{type:"string",description:"HTML string to convert directly and save as Markdown file. Use instead of URL for local files or API response HTML content."},locale:{type:"string",description:"Browser locale setting. Use 'ja-JP' for Japanese sites, 'en-US' for English sites. Affects content rendering and language detection.",enum:["en-US","ja-JP"],default:"en-US"},save_path:{type:"string",description:"Complete file path including filename to save the converted Markdown content (e.g., '/home/user/output.md'). Cannot be used with save_directory."},save_directory:{type:"string",description:"Directory path to save the converted Markdown content with auto-generated filename (e.g., '/home/user/downloads'). Cannot be used with save_path."},filename:{type:"string",description:"Base filename to use when save_directory is specified (e.g., 'my-document'). Extension .md will be added automatically."}},anyOf:[{required:["url","save_path"]},{required:["url","save_directory"]},{required:["html_content","save_path"]},{required:["html_content","save_directory"]}]},handler:(e,t)=>this.handleUrlToMarkdownFile(e,t)}],this.setupRequestHandlers()}getServer(){return this.server}setupRequestHandlers(){this.server.setRequestHandler(l,async e=>({protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"@aiquants/html-to-markdown-streamable",version:this.version}})),this.server.setRequestHandler(d,async()=>({tools:this.tools.map(({name:e,description:t,inputSchema:r})=>({name:e,description:t,inputSchema:r}))}));this.server.setRequestHandler(h,async(e,t)=>{const r=this.tools.find(t=>t.name===e.params.name);if(!r)throw new Error(`Unknown tool: ${e.params.name}`);const s=(0,r.handler)(e.params.arguments,{}),n=e.params._meta?.progressToken;let o;for await(const i of s)if("progress"===i.type){if(void 0!==n){const e={method:"notifications/progress",params:{progressToken:n,progress:i.progress,total:i.total||100}};try{const t=this.transport;t.sendNotification&&await t.sendNotification(e)}catch(a){R.debug("Progress streamable not supported or failed:",a)}}}else if("result"===i.type){o=i.result;break}if(!o)throw new Error("Tool did not return a result");return o})}async*handleHtmlToMarkdown(e,t){try{const t=p(e),{url:r,html_content:s,locale:n="en-US"}=t;if(r)try{new URL(r)}catch{throw new Error(`Invalid URL: ${r}`)}yield{type:"progress",progress:0,message:"Web ページの内容を取得して Markdown に変換します。"};const o=await E(r||"direct-html-input",{locale:n,htmlContent:s});yield{type:"progress",progress:100,message:"変換が完了しました。"};const a=[{type:"text",text:o.markdown}];yield{type:"result",result:{content:a}}}catch(r){const e=r instanceof Error?r.message:String(r);yield{type:"result",result:{content:[{type:"text",text:`エラーが発生しました: ${e}`}]}}}}async*handleSaveContentToFile(e,t){try{const t=u(e),{content:r,save_path:s,save_directory:n,filename:o}=t;yield{type:"progress",progress:20,message:"ファイル保存の準備中..."};const a=await m(r,s,n,o);yield{type:"progress",progress:100,message:"ファイル保存が完了しました。"};const i=`Content saved successfully to: ${a}`;yield{type:"result",result:{content:[{type:"text",text:i}],isError:!1}}}catch(r){const e=r instanceof Error?r.message:String(r);yield{type:"result",result:{content:[{type:"text",text:`エラーが発生しました: ${e}`}],isError:!0}}}}async*handleUrlToMarkdownFile(e,t){try{const t=f(e),{url:r,html_content:s,locale:n="en-US",save_path:o,save_directory:a,filename:i}=t;if(r)try{new URL(r)}catch{throw new Error(`Invalid URL: ${r}`)}yield{type:"progress",progress:0,message:"Web ページの内容を取得して Markdown に変換します。"};const c=await E(r||"direct-html-input",{locale:n,htmlContent:s});yield{type:"progress",progress:70,message:"Markdown への変換が完了しました。ファイルに保存しています。"};const l=c.markdown;let d=i;!d&&r&&(d=this.generateFilenameFromUrl(r));const h=await m(l,o,a,d);yield{type:"progress",progress:100,message:"ファイルの保存が完了しました。"};const p=`URL successfully converted to Markdown and saved to: ${h}`;yield{type:"result",result:{content:[{type:"text",text:p}],isError:!1}}}catch(r){const e=r instanceof Error?r.message:String(r);yield{type:"result",result:{content:[{type:"text",text:`エラーが発生しました: ${e}`}],isError:!0}}}}generateFilenameFromUrl(e){try{let t=new URL(e).pathname.split("/").pop()||"page";return t=t.replace(/\.[^.]*$/,""),t=t.replace(/[<>:"/\\|?*]/g,"_"),t&&!t.match(/^\.+$/)||(t="page"),t}catch{return"page"}}async start(e="127.0.0.1",t=4001){const r=b();r.use(S({origin:"*",methods:["GET","POST","PUT","DELETE","OPTIONS"],allowedHeaders:["Content-Type","Authorization"]})),r.use(b.json()),await this.server.connect(this.transport),r.post("/mcp",async(e,t)=>{R.info("Received MCP request:",e.body);try{t.setHeader("Content-Type","application/json");const s=e.body;if(!s?.method)return void t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid Request"},id:s?.id||null});let n;if("initialize"===s.method)n={jsonrpc:"2.0",id:s.id,result:{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"@aiquants/html-to-markdown-streamable",version:this.version}}};else if("tools/list"===s.method)n={jsonrpc:"2.0",id:s.id,result:{tools:this.tools.map(({name:e,description:t,inputSchema:r})=>({name:e,description:t,inputSchema:r}))}};else if("tools/call"===s.method){const e=this.tools.find(e=>e.name===s.params.name);if(e)try{const t={},r=e.handler(s.params.arguments,t);let o;for await(const e of r)if("result"===e.type){o=e.result;break}n={jsonrpc:"2.0",id:s.id,result:o}}catch(r){n={jsonrpc:"2.0",id:s.id,error:{code:-32603,message:r instanceof Error?r.message:String(r)}}}else n={jsonrpc:"2.0",id:s.id,error:{code:-32601,message:`Unknown tool: ${s.params.name}`}}}else n={jsonrpc:"2.0",id:s.id,error:{code:-32601,message:"Method not found"}};t.status(200).json(n)}catch(r){R.error("Error handling MCP request:",r),t.headersSent||t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}}),r.get("/mcp",async(e,t)=>{R.info("Received GET MCP request"),t.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}),r.delete("/mcp",async(e,t)=>{R.info("Received DELETE MCP request"),t.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))});const s=r.listen(t,e,()=>{R.info(`HTML to Markdown Streamable MCP server started on http://${e}:${t}/mcp`)});process.on("SIGINT",async()=>{R.info("Shutting down server...");try{R.info("Closing transport"),await this.transport.close()}catch(e){R.error("Error closing transport:",e)}await this.server.close(),s.close(()=>{R.info("Server shutdown complete"),process.exit(0)})})}}const re=()=>new te,se=async()=>{const e=_(process.argv.slice(2)),t=e.host||"127.0.0.1",r=e.port||4001,s=re();await s.start(t,r)};export{re as c,se as r};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- "use strict";require("./mcp-server-streamable-DZ7VyWAg.cjs").runStreamableMcpServer().catch(e=>{process.exit(1)});
2
+ "use strict";require("./mcp-server-streamable-BPxUnvzy.cjs").runStreamableMcpServer().catch(e=>{process.exit(1)});
@@ -0,0 +1 @@
1
+ export {}
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{r}from"./mcp-server-streamable-CgJP5t9P.js";r().catch(r=>{process.exit(1)});
2
+ import{r}from"./mcp-server-streamable-D4CUcTDr.js";r().catch(r=>{process.exit(1)});
package/dist/mcp.cjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e});require("./mcp-server-DSLDlYZX.cjs").runMcpServer().catch(e=>{process.exit(1)});
2
+ const e=new(require("happy-dom").Window);Object.assign(global,{document:e.document,window:e,self:e});require("./mcp-server-D18WYyj-.cjs").runMcpServer().catch(e=>{process.exit(1)});
package/dist/mcp.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {}
package/dist/mcp.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{Window as o}from"happy-dom";const e=new o;Object.assign(global,{document:e.document,window:e,self:e});import{r as s}from"./mcp-server-DmJXoVRZ.js";s().catch(o=>{process.exit(1)});
2
+ import{Window as o}from"happy-dom";const e=new o;Object.assign(global,{document:e.document,window:e,self:e});import{r as s}from"./mcp-server-BviJ0BJj.js";s().catch(o=>{process.exit(1)});
@@ -61,6 +61,7 @@ export declare class HtmlToMarkdownMcpServer {
61
61
  type: "resource_link";
62
62
  description?: string | undefined;
63
63
  mimeType?: string | undefined;
64
+ size?: number | undefined;
64
65
  annotations?: {
65
66
  audience?: ("user" | "assistant")[] | undefined;
66
67
  priority?: number | undefined;
@@ -73,6 +74,7 @@ export declare class HtmlToMarkdownMcpServer {
73
74
  src: string;
74
75
  mimeType?: string | undefined;
75
76
  sizes?: string[] | undefined;
77
+ theme?: "light" | "dark" | undefined;
76
78
  }[] | undefined;
77
79
  title?: string | undefined;
78
80
  } | {
@@ -103,8 +105,8 @@ export declare class HtmlToMarkdownMcpServer {
103
105
  })[];
104
106
  _meta?: {
105
107
  [x: string]: unknown;
108
+ progressToken?: string | number | undefined;
106
109
  "io.modelcontextprotocol/related-task"?: {
107
- [x: string]: unknown;
108
110
  taskId: string;
109
111
  } | undefined;
110
112
  } | undefined;
@@ -160,6 +162,7 @@ export declare class HtmlToMarkdownMcpServer {
160
162
  type: "resource_link";
161
163
  description?: string | undefined;
162
164
  mimeType?: string | undefined;
165
+ size?: number | undefined;
163
166
  annotations?: {
164
167
  audience?: ("user" | "assistant")[] | undefined;
165
168
  priority?: number | undefined;
@@ -172,6 +175,7 @@ export declare class HtmlToMarkdownMcpServer {
172
175
  src: string;
173
176
  mimeType?: string | undefined;
174
177
  sizes?: string[] | undefined;
178
+ theme?: "light" | "dark" | undefined;
175
179
  }[] | undefined;
176
180
  title?: string | undefined;
177
181
  } | {
@@ -202,8 +206,8 @@ export declare class HtmlToMarkdownMcpServer {
202
206
  })[];
203
207
  _meta?: {
204
208
  [x: string]: unknown;
209
+ progressToken?: string | number | undefined;
205
210
  "io.modelcontextprotocol/related-task"?: {
206
- [x: string]: unknown;
207
211
  taskId: string;
208
212
  } | undefined;
209
213
  } | undefined;
@@ -259,6 +263,7 @@ export declare class HtmlToMarkdownMcpServer {
259
263
  type: "resource_link";
260
264
  description?: string | undefined;
261
265
  mimeType?: string | undefined;
266
+ size?: number | undefined;
262
267
  annotations?: {
263
268
  audience?: ("user" | "assistant")[] | undefined;
264
269
  priority?: number | undefined;
@@ -271,6 +276,7 @@ export declare class HtmlToMarkdownMcpServer {
271
276
  src: string;
272
277
  mimeType?: string | undefined;
273
278
  sizes?: string[] | undefined;
279
+ theme?: "light" | "dark" | undefined;
274
280
  }[] | undefined;
275
281
  title?: string | undefined;
276
282
  } | {
@@ -301,8 +307,8 @@ export declare class HtmlToMarkdownMcpServer {
301
307
  })[];
302
308
  _meta?: {
303
309
  [x: string]: unknown;
310
+ progressToken?: string | number | undefined;
304
311
  "io.modelcontextprotocol/related-task"?: {
305
- [x: string]: unknown;
306
312
  taskId: string;
307
313
  } | undefined;
308
314
  } | undefined;
@@ -3,7 +3,7 @@
3
3
  * Rehype プラグインのインデックス
4
4
  */
5
5
  export { rehypeAbsoluteLinks } from './rehype-absolute-links.ts';
6
- export { rehypeDecodeEntities, preprocessHtmlEntities } from './rehype-decode-entities.ts';
6
+ export { preprocessHtmlEntities, rehypeDecodeEntities } from './rehype-decode-entities.ts';
7
7
  export { rehypeNamedAnchors } from './rehype-named-anchors.ts';
8
8
  export { rehypeParagraphWrapper } from './rehype-paragraph-wrapper.ts';
9
9
  export { rehypeSanitizeHtml } from './rehype-sanitize-html.ts';
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @module utils/logger
3
+ * @description Logger utility for consistent log management across the library.
4
+ * @description ライブラリ全体で一貫したログ管理を行うためのロガーユーティリティ。
5
+ */
6
+ /**
7
+ * @enum LogLevel
8
+ * @description Log levels for filtering output.
9
+ * @description 出力をフィルタリングするためのログレベル。
10
+ */
11
+ export declare enum LogLevel {
12
+ DEBUG = 0,
13
+ INFO = 1,
14
+ WARN = 2,
15
+ ERROR = 3,
16
+ NONE = 4
17
+ }
18
+ /**
19
+ * @interface ILogger
20
+ * @description Interface for a logger object compatible with Console.
21
+ * @description Console と互換性のあるロガーオブジェクトのインターフェース。
22
+ */
23
+ export interface ILogger {
24
+ debug(message?: unknown, ...optionalParams: unknown[]): void;
25
+ info(message?: unknown, ...optionalParams: unknown[]): void;
26
+ warn(message?: unknown, ...optionalParams: unknown[]): void;
27
+ error(message?: unknown, ...optionalParams: unknown[]): void;
28
+ }
29
+ /**
30
+ * @class Logger
31
+ * @description A wrapper class for handling logging with levels and prefixes.
32
+ * @description レベルとプレフィックスを使用したログ記録を処理するためのラッパークラス。
33
+ */
34
+ export declare class Logger implements ILogger {
35
+ private level;
36
+ private prefix;
37
+ private impl;
38
+ /**
39
+ * @constructor
40
+ * @param {LogLevel} [level=LogLevel.WARN] - The minimum log level to output.
41
+ * @param {string} [prefix="[html-to-markdown]"] - The prefix to add to all log messages.
42
+ * @param {ILogger} [impl=console] - The implementation to use for logging.
43
+ */
44
+ constructor(level?: LogLevel, prefix?: string, impl?: ILogger);
45
+ private static instance;
46
+ /**
47
+ * @method setLevel
48
+ * @description Updates the current log level for the static instance.
49
+ * @description 静的インスタンスの現在のログレベルを更新します。
50
+ * @param {LogLevel} level - The new log level.
51
+ */
52
+ static setLevel(level: LogLevel): void;
53
+ /**
54
+ * @method setLevel
55
+ * @description Updates the current log level.
56
+ * @description 現在のログレベルを更新します。
57
+ * @param {LogLevel} level - The new log level.
58
+ */
59
+ setLevel(level: LogLevel): void;
60
+ /**
61
+ * @method setImplementation
62
+ * @description Updates the logger implementation for the static instance.
63
+ * @description 静的インスタンスのロガーの実装を更新します。
64
+ * @param {ILogger} impl - The new logger implementation.
65
+ */
66
+ static setImplementation(impl: ILogger): void;
67
+ /**
68
+ * @method setImplementation
69
+ * @description Updates the logger implementation.
70
+ * @description ロガーの実装を更新します。
71
+ * @param {ILogger} impl - The new logger implementation.
72
+ */
73
+ setImplementation(impl: ILogger): void;
74
+ /**
75
+ * @method setPrefix
76
+ * @description Updates the log prefix for the static instance.
77
+ * @description 静的インスタンスのログのプレフィックスを更新します。
78
+ * @param {string} prefix - The new prefix.
79
+ */
80
+ static setPrefix(prefix: string): void;
81
+ /**
82
+ * @method setPrefix
83
+ * @description Updates the log prefix.
84
+ * @description ログのプレフィックスを更新します。
85
+ * @param {string} prefix - The new prefix.
86
+ */
87
+ setPrefix(prefix: string): void;
88
+ private formatMessage;
89
+ static debug(message?: unknown, ...optionalParams: unknown[]): void;
90
+ debug(message?: unknown, ...optionalParams: unknown[]): void;
91
+ static info(message?: unknown, ...optionalParams: unknown[]): void;
92
+ info(message?: unknown, ...optionalParams: unknown[]): void;
93
+ static warn(message?: unknown, ...optionalParams: unknown[]): void;
94
+ warn(message?: unknown, ...optionalParams: unknown[]): void;
95
+ static error(message?: unknown, ...optionalParams: unknown[]): void;
96
+ error(message?: unknown, ...optionalParams: unknown[]): void;
97
+ }