UNPKG

generate-next-links

Version:

Generate links enum containing paths to nextjs pages

2 lines (1 loc) 9.64 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@cl-live-server/logger"),t=require("process"),o=require("fs/promises"),n=require("path"),r=require("prettier");function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=i(e);function a(e,t,o,n){return new(o||(o=Promise))((function(r,i){function s(e){try{l(n.next(e))}catch(e){i(e)}}function a(e){try{l(n.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(s,a)}l((n=n.apply(e,t||[])).next())}))}const l="\nUsage: generate-next-links \n\nIf no 'path' is specified, a 'pages' folder must be located\ninside the folder where the script is running from\n\nOptions:\n -N --name [NAME] name of generated TypeScript enum\n -P --path [PATH] path to folder where 'pages' directory resides\n -O --out [PATH] path to folder where ts file will be written to\n -B --base [PATH] nextjs base path, defaults to '/'\n -S --tab-size [INT] specify tab size used in generated file\n -A --api include API paths found in '/pages/api' folder\n -R --root include an 'ROOT' entry with path '/'\n -D --dry perform all operations except writing to disk\n -V --verbose show all log messages in stdout\n -T --omit-timestamp omit timestamp from written ts file\n -J --export-json export json instead of ts enum\n -C --convert-camel-case convert camel case to be delimited by underscore\n -E --convert-hyphens convert kebab case to be delimited by underscore\n -Q --single-quote use single quotes in the generated file\n -I --version show current version\n -H --help show help \n",c=/(?=[A-Z])/,u=/-/g,d=/\.(tsx|jsx|ts|js)/,p=(e,t)=>e.startsWith(t)?e:t+e,v=(e,t)=>e.length>0&&!Number.isNaN(parseInt(e[0]))?p(e,t||"N"):e,g=(e,o,r)=>{if(e){const i=["--name","-N"].includes(o),a=["--tab-size","-S"].includes(o),l=["--base","-B"].includes(o),c=p(e,((e,t)=>e?"/":t)(l,r.nativeSeparator)),u=i||a?e:c;["--out","-O"].includes(o)?r.out=n.join(r.out,u):i?r.name=v(u.replace(/[^a-z0-9]/gi,""),""):["--path","-P"].includes(o)?r.path=n.join(r.path,u):l?r.base=u:a&&(r.tabWidth=(e=>{const o=parseInt(e);if("number"==typeof o&&!Number.isNaN(o))return o;const n=`flag '--tab-size' '-S' requires integer argument, not '${e}'`;s.default.error(n),t.exit(1)})(u))}else s.default.error(`a flag '${o}' that requires an argument was passed without an argument`),t.exit(1)},f=n=>a(void 0,void 0,void 0,(function*(){var r;(yield(r=n.path,a(void 0,void 0,void 0,(function*(){try{return(yield o.lstat(r)).isDirectory()}catch(t){s.default.log(e.LogLevel.More,e.LogSeverity.Error,t)}return!1}))))||(s.default.error("`pages` folder not found.. exiting.."),s.default.print(l,e.LogSeverity.None),t.exit(1))}));var h=o=>a(void 0,void 0,void 0,(function*(){const r=(e=>({path:e,out:e,nativeSeparator:"win32"===t.platform?"\\":"/",tabWidth:4,name:"links",base:"/",dry:!1,api:!1,root:!1,verbose:!1,omitTimestamp:!1,exportJson:!1,singleQuotes:!1,convertCamelCase:!1,convertHyphens:!1,start:Date.now()}))(process.cwd());for(let n=0;n<o.length;n++){const i=o[n];switch(i){case"--out":case"-O":case"--path":case"-P":case"--name":case"-N":case"--base":case"-B":case"--tab-size":case"-S":g(o[n+1],i,r);break;case"--version":case"-I":return s.default.print("version: 3.1.0",e.LogSeverity.None),t.exit(0);case"--dry":case"-D":r.dry=!0;break;case"--verbose":case"-V":s.default.logLevel=e.LogLevel.Verbose,r.verbose=!0;break;case"--api":case"-A":r.api=!0;break;case"--single-quote":case"-Q":r.singleQuotes=!0;break;case"--root":case"-R":r.root=!0;break;case"--omit-timestamp":case"-T":r.omitTimestamp=!0;break;case"--convert-camel-case":case"-C":r.convertCamelCase=!0;break;case"--convert-hyphens":case"-E":r.convertHyphens=!0;break;case"--export-json":case"-J":r.exportJson=!0;break;case"--help":case"-H":return s.default.print(l,e.LogSeverity.None),t.exit(0)}}return(e=>{const t=e.path.split(e.nativeSeparator),o=t.length-1;"pages"!==t[o]&&"pages"!==t[o-1]?e.path=n.join(e.path,"pages"):e.path=n.join("/",...t)})(r),s.default.debug("parsed config: ",r),yield f(r),r}));const y=(e,t)=>a(void 0,void 0,void 0,(function*(){let o;try{o=yield e()}catch(e){o=yield t(e)}return o})),m=e=>{const t=e[e.length-1];return void 0!==t?t:null},b=(e,t,r,i,s,l,c)=>a(void 0,void 0,void 0,(function*(){const u=n.resolve(t,s),d=yield(p=()=>o.stat(u),a(void 0,void 0,void 0,(function*(){return y(p,(()=>a(void 0,void 0,void 0,(function*(){return null}))))})));var p;if(d&&d.isDirectory())return x(e,u,r,l,c);if(i.file.test(u)){const e=u.replace(i.pages,"");l.push(e)}return Promise.resolve()})),x=(n,r,i,l=[],c=[])=>a(void 0,void 0,void 0,(function*(){const u=((e,t)=>({file:e?new RegExp(`^(.+.(tsx|jsx)|.*\\${t}api\\${t}.+.(ts|js))$`):/^.+\.(tsx|jsx)$/,pages:new RegExp(`.+\\${t}pages\\${t}`)}))(n,i),d=yield(p=()=>o.readdir(r),a(void 0,void 0,void 0,(function*(){return y(p,(o=>{s.default.log(e.LogLevel.More,e.LogSeverity.Error,o),t.exit(1)}))})));var p;return c=d.map((e=>b(n,r,i,u,e,l,c))),yield Promise.all(c),l}));const L=(()=>{const e=/\/(\[){1,2}\.{3}[a-zA-Z]+(\]){1,2}/;return{separator:e,opt:/(\[)|(\])/g,label:/\.{3}([a-zA-Z]+)/,notSeparator:new RegExp(`^${e.source}$`)}})();class w{constructor(e,t){this.options=Object.assign({convertCamelCase:!1,convertHyphens:!1},t),this.strippedBase="/"+this.stripForwardSlash(this.options.base),[this.key,this.value]=this.generateLink(e)}toString(){return JSON.stringify({name:this.key,link:this.value},null,4)}getNameWithoutExtension(e){const t=m(e);return null!==t?t.replace(d,""):""}generateLink(e){const t=this.getInitialLink(e),o=L.notSeparator.test(t),n=this.runConversions(t).replace(L.separator,(e=>{var t;const n=4===(null===(t=e.match(L.opt))||void 0===t?void 0:t.length),r=L.label.exec(e);if(r&&r.length>1){return(o?"":"_")+(n?"optional_catchall_":"catchall_")+r[1]}return e}));return[this.runClean(n),t]}runConversions(e){return this.options.convertCamelCase&&(e=(e=>{const t=[];return e.split(" ").forEach((e=>{if(""!==e){const o=e.split(c).join("_");t.push(o.charAt(0)+o.slice(1))}})),t.join(" ")})(e)),this.options.convertHyphens&&(e=(e=>e.replace(u,"_"))(e)),e}runClean(e){let t="";for(let o=0;o<e.length;o++){const n=e[o];"/"===n&&o>0?t+="_":"/"===n&&0===o||["[","]"," ","-"].includes(n)?t+="":t+=n.toUpperCase()}return v(t)}getInitialLink(e){const t=this.getNameWithoutExtension(e),o=[...e];o.pop();const n=o.join("/")+"/"+("index"===t?"":t);return this.appendToBase(n)}stripForwardSlash(e){return e.startsWith("/")&&(e=e.slice(1)),e.endsWith("/")&&(e=e.slice(0,e.length-1)),e}appendToBase(e){const t=this.stripForwardSlash(e);return this.strippedBase+("/"===this.strippedBase?t:"/"+t)}}class S extends w{constructor(e){super([],e),this.key=this.key+"ROOT",this.value=this.strippedBase}}const k=({config:t,separator:o,regex:n,links:r},i)=>a(void 0,void 0,void 0,(function*(){const a=i.split(o),l=m(a),c="index"===(null==l?void 0:l.split(".")[0]),u=a.length>1;if(!l||n.file.test(l)||c&&!u)s.default.log(e.LogLevel.More,e.LogSeverity.Warning,`ignoring file: ${l}`);else{const o=new w(a,t);s.default.log(e.LogLevel.More,e.LogSeverity.None,`generated link ${o}`),r.push(o)}}));var j=({api:t,path:o,nativeSeparator:n,convertCamelCase:r,convertHyphens:i,base:l,root:c})=>a(void 0,void 0,void 0,(function*(){const u={convertCamelCase:r,convertHyphens:i,base:l},d=[];if(c){const t=new S(u);s.default.log(e.LogLevel.More,e.LogSeverity.None,`generated link ${t}`),d.push(t)}const p=(e=>({ext:e?/\.(tsx|jsx|ts|js)/g:/\.(tsx|jsx)/g,file:/^(_app|_document)\.(tsx|jsx)$/}))(t),v=yield((e,t,o)=>a(void 0,void 0,void 0,(function*(){const n=yield x(e,t,o);return s.default.debug("found potential file paths",n),n})))(t,o,n),g=k.bind(null,{regex:p,links:d,separator:n,config:u}),f=v.map((e=>g(e)));return yield Promise.all(f),d}));var $=(i,l)=>a(void 0,void 0,void 0,(function*(){const c=(e=>e.sort(((e,t)=>t.key>e.key?-1:1)))(i),u=(({out:e,name:t,omitTimestamp:o,exportJson:r})=>n.join(e,`${t.toLowerCase()}${o?"":"_"+Date.now()}.${r?"json":"ts"}`))(l);let d;try{d=r.format(((e,{name:t,exportJson:o})=>o?JSON.stringify(e.reduce(((e,t)=>Object.assign(Object.assign({},e),{[t.key]:t.value})),{})):`\n export enum ${t} {\n ${e.map((e=>`${e.key} = "${e.value}"`))}\n };\n `)(c,l),{parser:l.exportJson?"json":"typescript",tabWidth:l.tabWidth,singleQuote:l.singleQuotes})}catch(o){s.default.log(e.LogLevel.More,e.LogSeverity.Error,o),s.default.error("Error: failed to format content"),s.default.log(e.LogLevel.More,e.LogSeverity.Default,"Suggestion: run with flag `-V` to debug"),t.exit(1)}return l.dry?s.default.log(e.LogLevel.More,e.LogSeverity.Warning,"dry run chosen, no files committed"):(s.default.debug(`creating file: ${u}`),yield((n,r)=>a(void 0,void 0,void 0,(function*(){try{yield o.writeFile(n,r)}catch(o){s.default.log(e.LogLevel.More,e.LogSeverity.Error,o),s.default.error("Error: failed to write file: "+n),s.default.log(e.LogLevel.More,e.LogSeverity.Default,"Suggestion: run with flag `-V` to debug"),t.exit(1)}})))(u,d)),[d,u]}));exports.main=t=>a(void 0,void 0,void 0,(function*(){const o=yield h(t),n=yield j(o),[r,i]=yield $(n,o),a=`generated ${n.length} nextjs links in ${l=o.start,((Date.now()-l)/1e3).toFixed(3)} seconds`;var l;return o.dry?(s.default.log(e.LogLevel.More,e.LogSeverity.None,r),s.default.success("dry run "+a)):s.default.success(a+" here: "+i),s.default.log(e.LogLevel.Less,e.LogSeverity.None,""),r}));