@doocs/md-cli 0.1.2 → 0.1.4

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.
Files changed (70) hide show
  1. package/dist/apple-touch-icon.png +0 -0
  2. package/dist/favicon-16x16.png +0 -0
  3. package/dist/favicon-32x32.png +0 -0
  4. package/dist/favicon.ico +0 -0
  5. package/dist/index.html +17 -3
  6. package/dist/manifest.webmanifest +1 -0
  7. package/dist/mpmd/icon-256-gray.png +0 -0
  8. package/dist/pwa-192x192-maskable.png +0 -0
  9. package/dist/pwa-192x192.png +0 -0
  10. package/dist/pwa-512x512-maskable.png +0 -0
  11. package/dist/pwa-512x512.png +0 -0
  12. package/dist/registerSW.js +1 -0
  13. package/dist/static/css/md-index-B4AMcWDE.css +1 -0
  14. package/dist/static/css/md-vendor_-D8IL6iVj.css +1 -0
  15. package/dist/static/js/md-hljs-DzXSk77f.js +10 -0
  16. package/dist/static/js/md-index-CvCnfZRB.js +626 -0
  17. package/dist/static/js/md-mermaid-BPz6h6Vo.js +1972 -0
  18. package/dist/static/js/md-vendor_.pnpm-BdZ7DMjQ.js +1245 -0
  19. package/dist/sw.js +1 -0
  20. package/dist/workbox-3aa584b4.js +1 -0
  21. package/index.js +48 -29
  22. package/package.json +9 -7
  23. package/server.js +106 -0
  24. package/util.js +53 -100
  25. package/dist/static/css/md-index-BcSsiNbL.css +0 -1
  26. package/dist/static/js/md-_basePickBy-n_ptBhRl.js +0 -1
  27. package/dist/static/js/md-_baseUniq-UI9XjDSS.js +0 -1
  28. package/dist/static/js/md-arc-CG0xZpwd.js +0 -1
  29. package/dist/static/js/md-architectureDiagram-IEHRJDOE-B39-e7po.js +0 -36
  30. package/dist/static/js/md-blockDiagram-JOT3LUYC-LZ0ocwzX.js +0 -121
  31. package/dist/static/js/md-c4Diagram-VJAJSXHY-D9kp_i50.js +0 -10
  32. package/dist/static/js/md-channel-X9Rtbm_e.js +0 -1
  33. package/dist/static/js/md-chunk-4BMEZGHF-C8HfuzwX.js +0 -1
  34. package/dist/static/js/md-chunk-A2AXSNBT-EpvWi1vW.js +0 -164
  35. package/dist/static/js/md-chunk-AEK57VVT-DfI_dP3H.js +0 -220
  36. package/dist/static/js/md-chunk-D6G4REZN-eU4UvCQM.js +0 -1
  37. package/dist/static/js/md-chunk-RZ5BOZE2-Ed7DVqsi.js +0 -1
  38. package/dist/static/js/md-chunk-XZIHB7SX-DSEuEo-L.js +0 -1
  39. package/dist/static/js/md-classDiagram-GIVACNV2-C8j3o3BZ.js +0 -1
  40. package/dist/static/js/md-classDiagram-v2-COTLJTTW-C8j3o3BZ.js +0 -1
  41. package/dist/static/js/md-clone-BUv47ZVZ.js +0 -1
  42. package/dist/static/js/md-cytoscape.esm-CWd-UyhZ.js +0 -191
  43. package/dist/static/js/md-dagre-OKDRZEBW-bRx_xZmN.js +0 -4
  44. package/dist/static/js/md-diagram-SSKATNLV-B-n-ZMhl.js +0 -43
  45. package/dist/static/js/md-diagram-VNBRO52H-CEMh5zVN.js +0 -24
  46. package/dist/static/js/md-erDiagram-Q7BY3M3F-ClKBDTYs.js +0 -60
  47. package/dist/static/js/md-flowDiagram-4HSFHLVR-BZet97G-.js +0 -161
  48. package/dist/static/js/md-ganttDiagram-APWFNJXF-xU1noQGk.js +0 -257
  49. package/dist/static/js/md-gitGraphDiagram-7IBYFJ6S-sLIFQS94.js +0 -65
  50. package/dist/static/js/md-graph-DwcZOKUv.js +0 -1
  51. package/dist/static/js/md-index-lEHYkmyN.js +0 -1258
  52. package/dist/static/js/md-infoDiagram-PH2N3AL5-D7-qapHx.js +0 -2
  53. package/dist/static/js/md-init-Gi6I4Gst.js +0 -1
  54. package/dist/static/js/md-journeyDiagram-U35MCT3I-BNTJgTly.js +0 -138
  55. package/dist/static/js/md-kanban-definition-NDS4AKOZ-B1bGm5dE.js +0 -88
  56. package/dist/static/js/md-layout-BJ3G4Vtz.js +0 -1
  57. package/dist/static/js/md-linear-BJwrzNxm.js +0 -1
  58. package/dist/static/js/md-mindmap-definition-ALO5MXBD-DePXZ4X5.js +0 -95
  59. package/dist/static/js/md-ordinal-CxVaQH2l.js +0 -1
  60. package/dist/static/js/md-pieDiagram-IB7DONF6-ELBfb3J2.js +0 -30
  61. package/dist/static/js/md-quadrantDiagram-7GDLP6J5-Dt6sdst_.js +0 -7
  62. package/dist/static/js/md-radar-MK3ICKWK-BfSn9gz-.js +0 -128
  63. package/dist/static/js/md-requirementDiagram-KVF5MWMF-5nh_v62_.js +0 -64
  64. package/dist/static/js/md-sankeyDiagram-QLVOVGJD-DgxGKuA0.js +0 -10
  65. package/dist/static/js/md-sequenceDiagram-X6HHIX6F-CLQaG9fm.js +0 -122
  66. package/dist/static/js/md-stateDiagram-DGXRK772-C8bDEi8S.js +0 -1
  67. package/dist/static/js/md-stateDiagram-v2-YXO3MK2T-DEKZORpF.js +0 -1
  68. package/dist/static/js/md-timeline-definition-BDJGKUSR-D10WCdsV.js +0 -61
  69. package/dist/static/js/md-xychartDiagram-VJFVF3MP-DcCVYGwf.js +0 -7
  70. package/mm.config.js +0 -55
package/dist/sw.js ADDED
@@ -0,0 +1 @@
1
+ if(!self.define){let e,i={};const s=(s,c)=>(s=new URL(s+".js",c).href,i[s]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=i,document.head.appendChild(e)}else e=s,importScripts(s),i()}).then(()=>{let e=i[s];if(!e)throw new Error(`Module ${s} didn’t register its module`);return e}));self.define=(c,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(i[t])return;let n={};const d=e=>s(e,t),o={module:{uri:t},exports:n,require:d};i[t]=Promise.all(c.map(e=>o[e]||d(e))).then(e=>(r(...e),n))}}define(["./workbox-3aa584b4"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"index.html",revision:"f69cbcf3014376529005191986b9fe83"},{url:"registerSW.js",revision:"be0c844492cec152913022730fec9690"},{url:"static/css/md-index-B4AMcWDE.css",revision:"19b2ff2eba3784ea7fe2c20c71d002d7"},{url:"static/css/md-vendor_-D8IL6iVj.css",revision:"130d42342c30a618bd338c3b26b15e12"},{url:"static/js/md-hljs-DzXSk77f.js",revision:"c42327cabea4588b79fd0cad9c82c3f2"},{url:"static/js/md-index-CvCnfZRB.js",revision:"203bf4aade1a7dcb86ef2c902c2d45a9"},{url:"static/js/md-katex-DOuibLoa.js",revision:"e6378486c63c65ca0fe98349b96eb675"},{url:"static/js/md-mermaid-BPz6h6Vo.js",revision:"078563c97cfb3b91378a459ab8b1a386"},{url:"static/js/md-vendor_.pnpm-BdZ7DMjQ.js",revision:"b7d9b6b9836a7765bccda9b118e76d51"},{url:"favicon.ico",revision:"0efe5a78bd1152a55219edd1bb12ed19"},{url:"manifest.webmanifest",revision:"516684ec39c965a129132d7f34a1c05a"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
@@ -0,0 +1 @@
1
+ define(["exports"],function(t){"use strict";try{self["workbox:core:7.2.0"]&&_()}catch(t){}const e=(t,...e)=>{let s=t;return e.length>0&&(s+=` :: ${JSON.stringify(e)}`),s};class s extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}try{self["workbox:routing:7.2.0"]&&_()}catch(t){}const n=t=>t&&"object"==typeof t?t:{handle:t};class i{constructor(t,e,s="GET"){this.handler=n(e),this.match=t,this.method=s}setCatchHandler(t){this.catchHandler=n(t)}}class r extends i{constructor(t,e,s){super(({url:e})=>{const s=t.exec(e.href);if(s&&(e.origin===location.origin||0===s.index))return s.slice(1)},e,s)}}class o{constructor(){this.t=new Map,this.i=new Map}get routes(){return this.t}addFetchListener(){self.addEventListener("fetch",t=>{const{request:e}=t,s=this.handleRequest({request:e,event:t});s&&t.respondWith(s)})}addCacheListener(){self.addEventListener("message",t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,s=Promise.all(e.urlsToCache.map(e=>{"string"==typeof e&&(e=[e]);const s=new Request(...e);return this.handleRequest({request:s,event:t})}));t.waitUntil(s),t.ports&&t.ports[0]&&s.then(()=>t.ports[0].postMessage(!0))}})}handleRequest({request:t,event:e}){const s=new URL(t.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:e,request:t,sameOrigin:n,url:s});let o=r&&r.handler;const c=t.method;if(!o&&this.i.has(c)&&(o=this.i.get(c)),!o)return;let a;try{a=o.handle({url:s,request:t,event:e,params:i})}catch(t){a=Promise.reject(t)}const h=r&&r.catchHandler;return a instanceof Promise&&(this.o||h)&&(a=a.catch(async n=>{if(h)try{return await h.handle({url:s,request:t,event:e,params:i})}catch(t){t instanceof Error&&(n=t)}if(this.o)return this.o.handle({url:s,request:t,event:e});throw n})),a}findMatchingRoute({url:t,sameOrigin:e,request:s,event:n}){const i=this.t.get(s.method)||[];for(const r of i){let i;const o=r.match({url:t,sameOrigin:e,request:s,event:n});if(o)return i=o,(Array.isArray(i)&&0===i.length||o.constructor===Object&&0===Object.keys(o).length||"boolean"==typeof o)&&(i=void 0),{route:r,params:i}}return{}}setDefaultHandler(t,e="GET"){this.i.set(e,n(t))}setCatchHandler(t){this.o=n(t)}registerRoute(t){this.t.has(t.method)||this.t.set(t.method,[]),this.t.get(t.method).push(t)}unregisterRoute(t){if(!this.t.has(t.method))throw new s("unregister-route-but-not-found-with-method",{method:t.method});const e=this.t.get(t.method).indexOf(t);if(!(e>-1))throw new s("unregister-route-route-not-registered");this.t.get(t.method).splice(e,1)}}let c;const a=()=>(c||(c=new o,c.addFetchListener(),c.addCacheListener()),c);function h(t,e,n){let o;if("string"==typeof t){const s=new URL(t,location.href);o=new i(({url:t})=>t.href===s.href,e,n)}else if(t instanceof RegExp)o=new r(t,e,n);else if("function"==typeof t)o=new i(t,e,n);else{if(!(t instanceof i))throw new s("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});o=t}return a().registerRoute(o),o}const u={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},l=t=>[u.prefix,t,u.suffix].filter(t=>t&&t.length>0).join("-"),f=t=>t||l(u.precache),w=t=>t||l(u.runtime);function d(t,e){const s=e();return t.waitUntil(s),s}try{self["workbox:precaching:7.2.0"]&&_()}catch(t){}function p(t){if(!t)throw new s("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),r=new URL(n,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:r.href}}class y{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type&&e&&e.originalRequest&&e.originalRequest instanceof Request){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class g{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=(null==e?void 0:e.cacheKey)||this.h.getCacheKeyForURL(t.url);return s?new Request(s,{headers:t.headers}):t},this.h=t}}let R;async function m(t,e){let n=null;if(t.url){n=new URL(t.url).origin}if(n!==self.location.origin)throw new s("cross-origin-copy-response",{origin:n});const i=t.clone(),r={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=e?e(r):r,c=function(){if(void 0===R){const t=new Response("");if("body"in t)try{new Response(t.body),R=!0}catch(t){R=!1}R=!1}return R}()?i.body:await i.blob();return new Response(c,o)}function v(t,e){const s=new URL(t);for(const t of e)s.searchParams.delete(t);return s.href}class q{constructor(){this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}}const U=new Set;try{self["workbox:strategies:7.2.0"]&&_()}catch(t){}function L(t){return"string"==typeof t?new Request(t):t}class b{constructor(t,e){this.u={},Object.assign(this,e),this.event=e.event,this.l=t,this.p=new q,this.R=[],this.m=[...t.plugins],this.v=new Map;for(const t of this.m)this.v.set(t,{});this.event.waitUntil(this.p.promise)}async fetch(t){const{event:e}=this;let n=L(t);if("navigate"===n.mode&&e instanceof FetchEvent&&e.preloadResponse){const t=await e.preloadResponse;if(t)return t}const i=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const t of this.iterateCallbacks("requestWillFetch"))n=await t({request:n.clone(),event:e})}catch(t){if(t instanceof Error)throw new s("plugin-error-request-will-fetch",{thrownErrorMessage:t.message})}const r=n.clone();try{let t;t=await fetch(n,"navigate"===n.mode?void 0:this.l.fetchOptions);for(const s of this.iterateCallbacks("fetchDidSucceed"))t=await s({event:e,request:r,response:t});return t}catch(t){throw i&&await this.runCallbacks("fetchDidFail",{error:t,event:e,originalRequest:i.clone(),request:r.clone()}),t}}async fetchAndCachePut(t){const e=await this.fetch(t),s=e.clone();return this.waitUntil(this.cachePut(t,s)),e}async cacheMatch(t){const e=L(t);let s;const{cacheName:n,matchOptions:i}=this.l,r=await this.getCacheKey(e,"read"),o=Object.assign(Object.assign({},i),{cacheName:n});s=await caches.match(r,o);for(const t of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await t({cacheName:n,matchOptions:i,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(t,e){const n=L(t);var i;await(i=0,new Promise(t=>setTimeout(t,i)));const r=await this.getCacheKey(n,"write");if(!e)throw new s("cache-put-with-no-response",{url:(o=r.url,new URL(String(o),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var o;const c=await this.q(e);if(!c)return!1;const{cacheName:a,matchOptions:h}=this.l,u=await self.caches.open(a),l=this.hasCallback("cacheDidUpdate"),f=l?await async function(t,e,s,n){const i=v(e.url,s);if(e.url===i)return t.match(e,n);const r=Object.assign(Object.assign({},n),{ignoreSearch:!0}),o=await t.keys(e,r);for(const e of o)if(i===v(e.url,s))return t.match(e,n)}(u,r.clone(),["__WB_REVISION__"],h):null;try{await u.put(r,l?c.clone():c)}catch(t){if(t instanceof Error)throw"QuotaExceededError"===t.name&&await async function(){for(const t of U)await t()}(),t}for(const t of this.iterateCallbacks("cacheDidUpdate"))await t({cacheName:a,oldResponse:f,newResponse:c.clone(),request:r,event:this.event});return!0}async getCacheKey(t,e){const s=`${t.url} | ${e}`;if(!this.u[s]){let n=t;for(const t of this.iterateCallbacks("cacheKeyWillBeUsed"))n=L(await t({mode:e,request:n,event:this.event,params:this.params}));this.u[s]=n}return this.u[s]}hasCallback(t){for(const e of this.l.plugins)if(t in e)return!0;return!1}async runCallbacks(t,e){for(const s of this.iterateCallbacks(t))await s(e)}*iterateCallbacks(t){for(const e of this.l.plugins)if("function"==typeof e[t]){const s=this.v.get(e),n=n=>{const i=Object.assign(Object.assign({},n),{state:s});return e[t](i)};yield n}}waitUntil(t){return this.R.push(t),t}async doneWaiting(){let t;for(;t=this.R.shift();)await t}destroy(){this.p.resolve(null)}async q(t){let e=t,s=!1;for(const t of this.iterateCallbacks("cacheWillUpdate"))if(e=await t({request:this.request,response:e,event:this.event})||void 0,s=!0,!e)break;return s||e&&200!==e.status&&(e=void 0),e}}class C{constructor(t={}){this.cacheName=w(t.cacheName),this.plugins=t.plugins||[],this.fetchOptions=t.fetchOptions,this.matchOptions=t.matchOptions}handle(t){const[e]=this.handleAll(t);return e}handleAll(t){t instanceof FetchEvent&&(t={event:t,request:t.request});const e=t.event,s="string"==typeof t.request?new Request(t.request):t.request,n="params"in t?t.params:void 0,i=new b(this,{event:e,request:s,params:n}),r=this.U(i,s,e);return[r,this.L(r,i,s,e)]}async U(t,e,n){let i;await t.runCallbacks("handlerWillStart",{event:n,request:e});try{if(i=await this._(e,t),!i||"error"===i.type)throw new s("no-response",{url:e.url})}catch(s){if(s instanceof Error)for(const r of t.iterateCallbacks("handlerDidError"))if(i=await r({error:s,event:n,request:e}),i)break;if(!i)throw s}for(const s of t.iterateCallbacks("handlerWillRespond"))i=await s({event:n,request:e,response:i});return i}async L(t,e,s,n){let i,r;try{i=await t}catch(r){}try{await e.runCallbacks("handlerDidRespond",{event:n,request:s,response:i}),await e.doneWaiting()}catch(t){t instanceof Error&&(r=t)}if(await e.runCallbacks("handlerDidComplete",{event:n,request:s,response:i,error:r}),e.destroy(),r)throw r}}class E extends C{constructor(t={}){t.cacheName=f(t.cacheName),super(t),this.C=!1!==t.fallbackToNetwork,this.plugins.push(E.copyRedirectedCacheableResponsesPlugin)}async _(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.O(t,e):await this.N(t,e))}async N(t,e){let n;const i=e.params||{};if(!this.C)throw new s("missing-precache-entry",{cacheName:this.cacheName,url:t.url});{const s=i.integrity,r=t.integrity,o=!r||r===s;n=await e.fetch(new Request(t,{integrity:"no-cors"!==t.mode?r||s:void 0})),s&&o&&"no-cors"!==t.mode&&(this.k(),await e.cachePut(t,n.clone()))}return n}async O(t,e){this.k();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s("bad-precaching-response",{url:t.url,status:n.status});return n}k(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==E.copyRedirectedCacheableResponsesPlugin&&(n===E.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(E.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}E.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},E.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await m(t):t};class O{constructor({cacheName:t,plugins:e=[],fallbackToNetwork:s=!0}={}){this.K=new Map,this.P=new Map,this.T=new Map,this.l=new E({cacheName:f(t),plugins:[...e,new g({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.l}precache(t){this.addToCacheList(t),this.W||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.W=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=p(n),r="string"!=typeof n&&n.revision?"reload":"default";if(this.K.has(i)&&this.K.get(i)!==t)throw new s("add-to-cache-list-conflicting-entries",{firstEntry:this.K.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.T.has(t)&&this.T.get(t)!==n.integrity)throw new s("add-to-cache-list-conflicting-integrities",{url:i});this.T.set(t,n.integrity)}if(this.K.set(i,t),this.P.set(i,r),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return d(t,async()=>{const e=new y;this.strategy.plugins.push(e);for(const[e,s]of this.K){const n=this.T.get(s),i=this.P.get(e),r=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}})}activate(t){return d(t,async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.K.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}})}getURLsToCacheKeys(){return this.K}getCachedURLs(){return[...this.K.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.K.get(e.href)}getIntegrityForCacheKey(t){return this.T.get(t)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=Object.assign({cacheKey:e},s.params),this.strategy.handle(s))}}let x;const N=()=>(x||(x=new O),x);class k extends i{constructor(t,e){super(({request:s})=>{const n=t.getURLsToCacheKeys();for(const i of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const r=new URL(t,location.href);r.hash="",yield r.href;const o=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some(t=>t.test(s))&&t.searchParams.delete(s);return t}(r,e);if(yield o.href,s&&o.pathname.endsWith("/")){const t=new URL(o.href);t.pathname+=s,yield t.href}if(n){const t=new URL(o.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:r});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(i);if(e){return{cacheKey:e,integrity:t.getIntegrityForCacheKey(e)}}}},t.strategy)}}t.NavigationRoute=class extends i{constructor(t,{allowlist:e=[/./],denylist:s=[]}={}){super(t=>this.j(t),t),this.M=e,this.S=s}j({url:t,request:e}){if(e&&"navigate"!==e.mode)return!1;const s=t.pathname+t.search;for(const t of this.S)if(t.test(s))return!1;return!!this.M.some(t=>t.test(s))}},t.cleanupOutdatedCaches=function(){self.addEventListener("activate",t=>{const e=f();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter(s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t);return await Promise.all(s.map(t=>self.caches.delete(t))),s})(e).then(t=>{}))})},t.clientsClaim=function(){self.addEventListener("activate",()=>self.clients.claim())},t.createHandlerBoundToURL=function(t){return N().createHandlerBoundToURL(t)},t.precacheAndRoute=function(t,e){!function(t){N().precache(t)}(t),function(t){const e=N();h(new k(e,t))}(e)},t.registerRoute=h});
package/index.js CHANGED
@@ -1,38 +1,57 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { ProcessManager } = require(`@wll8/process-manager`);
4
- const getPort = require(`get-port`)
5
- const {
6
- handleSpace,
3
+ import { readFileSync } from 'fs'
4
+ import getPort from 'get-port'
5
+ import {
7
6
  colors,
8
7
  parseArgv,
9
- } = require(`./util.js`)
8
+ } from './util.js'
9
+ import { createServer } from './server.js'
10
+
11
+ const packageJson = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'))
10
12
 
11
13
  const arg = parseArgv()
12
14
 
13
- new Promise(async () => {
14
- let { port = 8800, testPort, replayPort } = arg
15
- port = Number(port)
16
- ;[port, testPort, replayPort] = await Promise.all([port, port+1, port+2].map(item => getPort({port: item}) )).catch(err => console.log(`err`, err))
17
- const line = Object.entries({
18
- ...arg,
19
- proxy: `https://doocs-md.pages.dev`,
20
- port,
21
- testPort,
22
- replayPort,
23
- '--config': handleSpace(`${__dirname}/mm.config.js`),
24
- }).map(([key, val]) => `${key}=${val}`)
25
- const cliArg = [handleSpace(`${__dirname}/node_modules/mockm/run.js`), `--log-line`, ...line]
26
- console.log(`doocs/md-cli v${require(`./package.json`).version}`)
27
- console.log(`服务启动中...`)
28
- const cp = new ProcessManager(cliArg)
29
- cp.on(`stdout`, (info = ``) => {
30
- if(info.match(`:${port}/`)) {
15
+ async function startServer() {
16
+ try {
17
+ let { port = 8800 } = arg
18
+ port = Number(port)
19
+
20
+ port = await getPort({ port }).catch(_ => {
21
+ console.log(`端口 ${port} 被占用,正在寻找可用端口...`)
22
+ return getPort()
23
+ })
24
+
25
+ console.log(`doocs/md-cli v${packageJson.version}`)
26
+ console.log(`服务启动中...`)
27
+
28
+ const app = createServer(port)
29
+
30
+ app.listen(port, '127.0.0.1', () => {
31
31
  console.log(`服务已启动:`)
32
32
  console.log(`打开链接 ${colors.green(`http://127.0.0.1:${port}/md/`)} 即刻使用吧~`)
33
- }
34
- if(info.match(`Port is occupied`)) {
35
- process.exit()
36
- }
37
- })
38
- }).catch(err => console.log(err))
33
+ console.log(``)
34
+
35
+ const { spaceId, clientSecret } = arg
36
+ if (spaceId && clientSecret) {
37
+ console.log(`${colors.green('✅ 云存储已配置,可通过自定义代码上传图片')}`)
38
+ }
39
+ })
40
+
41
+ process.once('SIGINT', () => {
42
+ console.log('\n服务器已关闭')
43
+ process.exit(0)
44
+ })
45
+
46
+ process.once('SIGTERM', () => {
47
+ console.log('\n服务器已关闭')
48
+ process.exit(0)
49
+ })
50
+
51
+ } catch (err) {
52
+ console.error('启动服务器失败:', err)
53
+ process.exit(1)
54
+ }
55
+ }
56
+
57
+ startServer()
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@doocs/md-cli",
3
- "version": "0.1.2",
4
- "description": "✍ 一款高度简洁的微信 Markdown 编辑器:支持 Markdown 所有基础语法、色盘取色、一键复制并粘贴到公众号后台、多图上传、一键下载文档、自定义 CSS 样式、一键重置等特性",
3
+ "version": "0.1.4",
4
+ "type": "module",
5
+ "description": "WeChat Markdown Editor | 一款高度简洁的微信 Markdown 编辑器:支持 Markdown 语法、自定义主题样式、内容管理、多图床、AI 助手等特性",
5
6
  "main": "index.js",
6
7
  "scripts": {
7
8
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -13,17 +14,18 @@
13
14
  "dist",
14
15
  "public",
15
16
  "index.js",
16
- "mm.config.js",
17
+ "server.js",
17
18
  "util.js"
18
19
  ],
19
20
  "keywords": [],
20
21
  "author": "wll8",
21
22
  "license": "ISC",
22
23
  "dependencies": {
23
- "@wll8/process-manager": "^1.0.4",
24
- "form-data": "4.0.2",
25
- "get-port": "5.1.1",
26
- "mockm": "^1.1.27-alpha.11",
24
+ "express": "^5.1.0",
25
+ "multer": "^2.0.2",
26
+ "http-proxy-middleware": "^3.0.5",
27
+ "form-data": "4.0.4",
28
+ "get-port": "7.1.0",
27
29
  "node-fetch": "^3.3.2"
28
30
  }
29
31
  }
package/server.js ADDED
@@ -0,0 +1,106 @@
1
+ import express from 'express'
2
+ import multer from 'multer'
3
+ import path from 'path'
4
+ import fs from 'fs'
5
+ import { fileURLToPath } from 'url'
6
+ import { dirname } from 'path'
7
+ import { createProxyMiddleware } from 'http-proxy-middleware'
8
+ import {
9
+ dcloud,
10
+ parseArgv,
11
+ colors
12
+ } from './util.js'
13
+
14
+ const __filename = fileURLToPath(import.meta.url)
15
+ const __dirname = dirname(__filename)
16
+ const arg = parseArgv()
17
+
18
+ // unicloud 服务空间配置
19
+ const spaceInfo = {
20
+ spaceId: ``,
21
+ clientSecret: ``,
22
+ ...arg,
23
+ }
24
+
25
+ /**
26
+ * 创建 Express 服务器
27
+ * @param {number} port - 服务器端口
28
+ */
29
+ export function createServer(port = 8800) {
30
+ const app = express()
31
+
32
+ // 确保上传目录存在
33
+ const uploadDir = path.join(__dirname, 'public/upload')
34
+ if (!fs.existsSync(uploadDir)) {
35
+ fs.mkdirSync(uploadDir, { recursive: true })
36
+ }
37
+
38
+ // 配置 multer 用于文件上传
39
+ const storage = multer.diskStorage({
40
+ destination: (req, file, cb) => {
41
+ cb(null, uploadDir)
42
+ },
43
+ filename: (req, file, cb) => {
44
+ cb(null, file.originalname)
45
+ }
46
+ })
47
+
48
+ const upload = multer({ storage })
49
+
50
+ // 中间件
51
+ app.use(express.json())
52
+ app.use(express.urlencoded({ extended: true }))
53
+
54
+ app.use('/public', express.static(path.join(__dirname, 'public')))
55
+
56
+ // 文件上传 API
57
+ app.post('/upload', upload.single('file'), async (req, res) => {
58
+ try {
59
+ if (!req.file) {
60
+ return res.status(400).json({ error: 'No file uploaded' })
61
+ }
62
+
63
+ const file = req.file
64
+ let url = `http://127.0.0.1:${port}/public/upload/${file.filename}`
65
+
66
+ try {
67
+ if (spaceInfo.spaceId && spaceInfo.clientSecret) {
68
+ url = await dcloud(spaceInfo)({
69
+ name: file.originalname,
70
+ file: fs.createReadStream(file.path)
71
+ })
72
+
73
+ // 上传成功后删除本地临时文件
74
+ fs.unlinkSync(file.path)
75
+ console.log('文件已上传到云端:', url)
76
+ } else {
77
+ console.log(`${colors.yellow('未配置云存储,降级到本地存储')}`)
78
+ }
79
+ } catch (err) {
80
+ // 云上传失败,降级到本地存储
81
+ console.log('云存储上传失败,降级到本地存储:', err.message)
82
+ }
83
+
84
+ res.json({ url })
85
+ } catch (error) {
86
+ console.error('Upload error:', error)
87
+ res.status(500).json({ error: error.message })
88
+ }
89
+ })
90
+
91
+ app.get('/', (_, res) => {
92
+ res.redirect('/md/')
93
+ })
94
+
95
+ console.log('代理到: https://doocs-md.pages.dev')
96
+ app.use(createProxyMiddleware({
97
+ target: 'https://doocs-md.pages.dev',
98
+ changeOrigin: true,
99
+ onError: (err, req, res) => {
100
+ console.error(`代理错误 ${req.path}:`, err.message)
101
+ res.status(502).send('代理服务暂不可用,请检查网络连接')
102
+ },
103
+ }))
104
+
105
+ return app
106
+ }
package/util.js CHANGED
@@ -1,56 +1,34 @@
1
- const fetch = (...args) => import(`node-fetch`).then(({default: fetch}) => fetch(...args))
2
- const FormData = require(`form-data`)
1
+ import FormData from 'form-data'
2
+ import process from 'process'
3
+ import os from 'os'
4
+ import net from 'net'
5
+ import util from 'util'
6
+ import crypto from 'crypto'
3
7
 
8
+ const fetch = (...args) => import(`node-fetch`).then(({ default: fetch }) => fetch(...args))
4
9
 
5
10
  /**
6
- * 判断端口是否可用
7
- * @param {string|array} port 多个端口用数组
11
+ * 自定义控制台颜色
12
+ * https://stackoverflow.com/questions/9781218/how-to-change-node-jss-console-font-color
13
+ * nodejs 内置颜色: https://nodejs.org/api/util.html#util_foreground_colors
8
14
  */
9
- function portIsOk (port) {
10
- if(typeof(port) === `object`) { // 判断多个端口
11
- return Promise.all(port.map(item => portIsOk(item)))
12
- }
13
- return new Promise(resolve => {
14
- const net = require(`net`)
15
- const server = net.createServer().listen(port)
16
- server.on(`listening`, () => server.close(resolve(true)))
17
- server.on(`error`, () => resolve(port))
18
- })
19
- }
20
-
21
- /**
22
- * 处理不同系统的命令行空格差异, 在 cp.spawn 中的参数中, 如果包含空格, win 平台需要使用双引号包裹, unix 不需要
23
- * @param {string} str
24
- */
25
- function handleSpace(str = ``) {
26
- const newStr = require('os').type() === 'Windows_NT' && str.match(` `) ? `"${str}"` : str
27
- return newStr
28
- }
29
-
30
- /**
31
- * 自定义控制台颜色
32
- * https://stackoverflow.com/questions/9781218/how-to-change-node-jss-console-font-color
33
- * nodejs 内置颜色: https://nodejs.org/api/util.html#util_foreground_colors
34
- */
35
- function colors () {
36
- const util = require('util')
37
-
38
- function colorize (color, text) {
15
+ function colors() {
16
+ function colorize(color, text) {
39
17
  const codes = util.inspect.colors[color]
40
- return `\x1b[${codes[0]}m${text}\x1b[${codes[1]}m`
18
+ return `\x1B[${codes[0]}m${text}\x1B[${codes[1]}m`
41
19
  }
42
20
 
43
- let returnValue = {}
21
+ const returnValue = {}
44
22
  Object.keys(util.inspect.colors).forEach((color) => {
45
- returnValue[color] = (text) => colorize(color, text)
23
+ returnValue[color] = text => colorize(color, text)
46
24
  })
47
25
 
48
26
  const colorTable = new Proxy(returnValue, {
49
- get (obj, prop) {
27
+ get(obj, prop) {
50
28
  // 在没有对应的具名颜色函数时, 返回空函数作为兼容处理
51
- const res = obj[prop] ? obj[prop] : (arg => arg)
29
+ const res = obj[prop] ? obj[prop] : arg => arg
52
30
  return res
53
- }
31
+ },
54
32
  })
55
33
 
56
34
  // 取消下行注释, 查看所有的颜色和名字:
@@ -58,66 +36,43 @@ function colors () {
58
36
  return colorTable
59
37
  }
60
38
 
61
- /**
62
- * 以 Promise 方式运行 spawn
63
- * @param {*} cmd 主程序
64
- * @param {*} args 程序参数数组
65
- * @param {*} opts spawn 选项
66
- */
67
- function spawn (cmd, args, opts) {
68
- opts = { stdio: `inherit`, ...opts }
69
- opts.shell = opts.shell || process.platform === 'win32'
70
- return new Promise((resolve, reject) => {
71
- const cp = require('child_process')
72
- const child = cp.spawn(cmd, args, opts)
73
- let stdout = ''
74
- let stderr = ''
75
- child.stdout && child.stdout.on('data', d => { stdout += d })
76
- child.stderr && child.stderr.on('data', d => { stderr += d })
77
- child.on('error', reject)
78
- child.on('close', code => {
79
- resolve({code, stdout, stderr})
80
- })
81
- })
82
- }
83
-
84
39
  /**
85
40
  * 解析命令行参数
86
- * @param {*} arr
87
- * @returns
41
+ * @param {*} arr
42
+ * @returns {Record<string, string | boolean>}
88
43
  */
89
44
  function parseArgv(arr) {
90
45
  return (arr || process.argv.slice(2)).reduce((acc, arg) => {
91
- let [k, ...v] = arg.split('=')
46
+ let [k, ...v] = arg.split(`=`)
92
47
  v = v.join(`=`) // 把带有 = 的值合并为字符串
93
- acc[k] = v === '' // 没有值时, 则表示为 true
48
+ acc[k] = v === `` // 没有值时, 则表示为 true
94
49
  ? true
95
50
  : (
96
51
  /^(true|false)$/.test(v) // 转换指明的 true/false
97
- ? v === 'true'
98
- : (
99
- /[\d|.]+/.test(v)
100
- ? (isNaN(Number(v)) ? v : Number(v)) // 如果转换为数字失败, 则使用原始字符
101
- : v
102
- )
52
+ ? v === `true`
53
+ : (
54
+ /[\d|.]+/.test(v)
55
+ ? (Number.isNaN(Number(v)) ? v : Number(v)) // 如果转换为数字失败, 则使用原始字符
56
+ : v
57
+ )
103
58
  )
104
59
  return acc
105
60
  }, {})
106
61
  }
107
62
 
108
63
  function dcloud(spaceInfo) {
109
- if(Boolean(spaceInfo.spaceId && spaceInfo.clientSecret) === false) {
64
+ if (Boolean(spaceInfo.spaceId && spaceInfo.clientSecret) === false) {
110
65
  throw new Error(`请填写 spaceInfo`)
111
66
  }
112
-
67
+
113
68
  function sign(data, secret) {
114
- const hmac = require(`crypto`).createHmac(`md5`, secret)
69
+ const hmac = crypto.createHmac(`md5`, secret)
115
70
  // 排序 obj 再转换为 key=val&key=val 的格式
116
71
  const str = Object.keys(data).sort().reduce((acc, cur) => `${acc}&${cur}=${data[cur]}`, ``).slice(1)
117
72
  hmac.update(str)
118
73
  return hmac.digest(`hex`)
119
74
  }
120
-
75
+
121
76
  async function anonymousAuthorize() {
122
77
  const data = {
123
78
  method: `serverless.auth.user.anonymousAuthorize`,
@@ -131,16 +86,16 @@ function dcloud(spaceInfo) {
131
86
  },
132
87
  body: `{"method":"serverless.auth.user.anonymousAuthorize","params":"{}","spaceId":"${spaceInfo.spaceId}","timestamp":${data.timestamp}}`,
133
88
  method: `POST`,
134
- }).then((res) => res.json())
89
+ }).then(res => res.json())
135
90
  }
136
-
91
+
137
92
  async function report({ id, token }) {
138
93
  const reportReq = {
139
94
  method: `serverless.file.resource.report`,
140
95
  params: `{"id":"${id}"}`,
141
96
  spaceId: spaceInfo.spaceId,
142
97
  timestamp: Date.now(),
143
- token: token,
98
+ token,
144
99
  }
145
100
  return await fetch(`https://api.bspapp.com/client`, {
146
101
  headers: {
@@ -149,9 +104,9 @@ function dcloud(spaceInfo) {
149
104
  },
150
105
  body: JSON.stringify(reportReq),
151
106
  method: `POST`,
152
- }).then((res) => res.json())
107
+ }).then(res => res.json())
153
108
  }
154
-
109
+
155
110
  async function generateProximalSign({ name, token }) {
156
111
  const data = {
157
112
  method: `serverless.file.resource.generateProximalSign`,
@@ -167,25 +122,25 @@ function dcloud(spaceInfo) {
167
122
  },
168
123
  body: JSON.stringify(data),
169
124
  method: `POST`,
170
- }).then((res) => res.json())
125
+ }).then(res => res.json())
171
126
  return res
172
127
  }
173
-
128
+
174
129
  async function upload({ data, file }) {
175
130
  const formdata = new FormData()
176
131
  Object.entries({
177
132
  'Cache-Control': `max-age=2592000`,
178
133
  'Content-Disposition': `attachment`,
179
- OSSAccessKeyId: data.accessKeyId,
180
- Signature: data.signature,
181
- host: data.host,
182
- id: data.id,
183
- key: data.ossPath,
184
- policy: data.policy,
185
- success_action_status: 200,
134
+ 'OSSAccessKeyId': data.accessKeyId,
135
+ 'Signature': data.signature,
136
+ 'host': data.host,
137
+ 'id': data.id,
138
+ 'key': data.ossPath,
139
+ 'policy': data.policy,
140
+ 'success_action_status': 200,
186
141
  file,
187
142
  }).forEach(([key, val]) => formdata.append(key, val))
188
-
143
+
189
144
  return await fetch(`https://${data.host}`, {
190
145
  headers: {
191
146
  'X-OSS-server-side-encrpytion': `AES256`,
@@ -194,7 +149,7 @@ function dcloud(spaceInfo) {
194
149
  method: `POST`,
195
150
  })
196
151
  }
197
-
152
+
198
153
  async function uploadFile({ name = `unnamed.file`, file }) {
199
154
  const token = (await anonymousAuthorize()).data.accessToken
200
155
  const res = await generateProximalSign({ name, token })
@@ -203,16 +158,14 @@ function dcloud(spaceInfo) {
203
158
  const fileUrl = `https://${res.data.cdnDomain}/${res.data.ossPath}`
204
159
  return fileUrl
205
160
  }
206
-
161
+
207
162
  return uploadFile
208
-
209
163
  }
210
164
 
211
- module.exports = {
212
- portIsOk,
213
- handleSpace,
214
- colors: colors(),
215
- spawn,
165
+ const colorsInstance = colors()
166
+
167
+ export {
216
168
  parseArgv,
217
169
  dcloud,
170
+ colorsInstance as colors,
218
171
  }