diff --git a/404.html b/404.html index d2c7e7c2..bfb33ff8 100644 --- a/404.html +++ b/404.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/assets/js/03a88bad.4d3d904a.js b/assets/js/03a88bad.294fb801.js similarity index 86% rename from assets/js/03a88bad.4d3d904a.js rename to assets/js/03a88bad.294fb801.js index c606ef4b..e49d4a34 100644 --- a/assets/js/03a88bad.4d3d904a.js +++ b/assets/js/03a88bad.294fb801.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[6568],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},s="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,c=e.originalType,p=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),s=l(r),d=o,m=s["".concat(p,".").concat(d)]||s[d]||f[d]||c;return r?n.createElement(m,a(a({ref:t},u),{},{components:r})):n.createElement(m,a({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var c=r.length,a=new Array(c);a[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[s]="string"==typeof e?e:o,a[1]=i;for(var l=2;l{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>p,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=r(7462),o=r(3366),c=(r(7294),r(3905)),a=["components"],i={},p=void 0,l={unversionedId:"index",id:"index",title:"index",description:"",source:"@site/../docs/index.md",sourceDirName:".",slug:"/",permalink:"/docs/",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/index.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{}},u={},s=[],f={toc:s},d="wrapper";function m(e){var t=e.components,r=(0,o.Z)(e,a);return(0,c.kt)(d,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("meta",{"http-equiv":"refresh",content:"0; url=https://oclif.io/docs/introduction.html"}))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[6568],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},s="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,c=e.originalType,p=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),s=l(r),d=o,m=s["".concat(p,".").concat(d)]||s[d]||f[d]||c;return r?n.createElement(m,a(a({ref:t},u),{},{components:r})):n.createElement(m,a({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var c=r.length,a=new Array(c);a[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[s]="string"==typeof e?e:o,a[1]=i;for(var l=2;l{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>p,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=r(7462),o=r(3366),c=(r(7294),r(3905)),a=["components"],i={},p=void 0,l={unversionedId:"index",id:"index",title:"index",description:"",source:"@site/../docs/index.md",sourceDirName:".",slug:"/",permalink:"/docs/",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/index.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{}},u={},s=[],f={toc:s},d="wrapper";function m(e){var t=e.components,r=(0,o.Z)(e,a);return(0,c.kt)(d,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,c.kt)("meta",{"http-equiv":"refresh",content:"0; url=https://oclif.io/docs/introduction.html"}))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/03abeb31.384a2f0f.js b/assets/js/03abeb31.17e39d3d.js similarity index 69% rename from assets/js/03abeb31.384a2f0f.js rename to assets/js/03abeb31.17e39d3d.js index 87f0505e..bdcfc6ea 100644 --- a/assets/js/03abeb31.384a2f0f.js +++ b/assets/js/03abeb31.17e39d3d.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1660],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),p=c(n),g=o,f=p["".concat(u,".").concat(g)]||p[g]||d[g]||i;return n?r.createElement(f,a(a({ref:t},s),{},{components:n})):r.createElement(f,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=g;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l[p]="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>u,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>p});var r=n(7462),o=n(3366),i=(n(7294),n(3905)),a=["components"],l={title:"Debugging"},u=void 0,c={unversionedId:"debugging",id:"debugging",title:"Debugging",description:"Use the debug for debugging. The CLI uses this module for all of its debugging. If you set the environment variable DEBUG=* it will print all the debug output to the screen.",source:"@site/../docs/debugging.md",sourceDirName:".",slug:"/debugging",permalink:"/docs/debugging",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/debugging.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Debugging"},sidebar:"docs",previous:{title:"Notifications",permalink:"/docs/notifications"},next:{title:"Flexible Taxonomy",permalink:"/docs/flexible_taxonomy"}},s={},p=[],d={toc:p},g="wrapper";function f(e){var t=e.components,l=(0,o.Z)(e,a);return(0,i.kt)(g,(0,r.Z)({},d,l,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Use the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/visionmedia/debug"},"debug")," for debugging. The CLI uses this module for all of its debugging. If you set the environment variable ",(0,i.kt)("inlineCode",{parentName:"p"},"DEBUG=*")," it will print all the debug output to the screen."),(0,i.kt)("p",null,"Depending on your shell you may need to escape this with ",(0,i.kt)("inlineCode",{parentName:"p"},"DEBUG=\\*"),". On Windows you can't set environment variables in line, so you'll need to run ",(0,i.kt)("inlineCode",{parentName:"p"},"set DEBUG=*")," before running the command."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"debug demo",src:n(4924).Z,width:"2658",height:"1250"})))}f.isMDXComponent=!0},4924:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/debug_demo-efc07abda59d2b82da3fc695b96596c8.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1660],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),p=c(n),g=o,f=p["".concat(u,".").concat(g)]||p[g]||d[g]||i;return n?r.createElement(f,a(a({ref:t},s),{},{components:n})):r.createElement(f,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=g;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l[p]="string"==typeof e?e:o,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>u,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>p});var r=n(7462),o=n(3366),i=(n(7294),n(3905)),a=["components"],l={title:"Debugging"},u=void 0,c={unversionedId:"debugging",id:"debugging",title:"Debugging",description:"Use the debug for debugging. The CLI uses this module for all of its debugging. If you set the environment variable DEBUG=* it will print all the debug output to the screen.",source:"@site/../docs/debugging.md",sourceDirName:".",slug:"/debugging",permalink:"/docs/debugging",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/debugging.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Debugging"},sidebar:"docs",previous:{title:"Notifications",permalink:"/docs/notifications"},next:{title:"Flexible Taxonomy",permalink:"/docs/flexible_taxonomy"}},s={},p=[],d={toc:p},g="wrapper";function f(e){var t=e.components,l=(0,o.Z)(e,a);return(0,i.kt)(g,(0,r.Z)({},d,l,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Use the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/visionmedia/debug"},"debug")," for debugging. The CLI uses this module for all of its debugging. If you set the environment variable ",(0,i.kt)("inlineCode",{parentName:"p"},"DEBUG=*")," it will print all the debug output to the screen."),(0,i.kt)("p",null,"Depending on your shell you may need to escape this with ",(0,i.kt)("inlineCode",{parentName:"p"},"DEBUG=\\*"),". On Windows you can't set environment variables in line, so you'll need to run ",(0,i.kt)("inlineCode",{parentName:"p"},"set DEBUG=*")," before running the command."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"debug demo",src:n(4924).Z,width:"2658",height:"1250"})))}f.isMDXComponent=!0},4924:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/debug_demo-efc07abda59d2b82da3fc695b96596c8.png"}}]); \ No newline at end of file diff --git a/assets/js/04855d6d.7543c909.js b/assets/js/04855d6d.7543c909.js new file mode 100644 index 00000000..2b0cc615 --- /dev/null +++ b/assets/js/04855d6d.7543c909.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9544],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),p=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,m=s(e,["components","mdxType","originalType","parentName"]),d=p(a),c=r,u=d["".concat(i,".").concat(c)]||d[c]||g[c]||o;return a?n.createElement(u,l(l({ref:t},m),{},{components:a})):n.createElement(u,l({ref:t},m))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,l=new Array(o);l[0]=c;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[d]="string"==typeof e?e:r,l[1]=s;for(var p=2;p{a.r(t),a.d(t,{assets:()=>m,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>p,toc:()=>d});var n=a(7462),r=a(3366),o=(a(7294),a(3905)),l=["components"],s={author:"Casey Watts and Jeff Dickey",title:"CLI Flags Explained"},i=void 0,p={permalink:"/blog/2019/02/20/cli-flags-explained",source:"@site/blog/2019-02-20-cli-flags-explained.md",title:"CLI Flags Explained",description:'oclif makes it easy to create a command line interface (CLI) in node. Most commands have parameters \u2014 also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.',date:"2019-02-20T00:00:00.000Z",formattedDate:"February 20, 2019",tags:[],readingTime:4.925,hasTruncateMarker:!1,authors:[{name:"Casey Watts and Jeff Dickey"}],frontMatter:{author:"Casey Watts and Jeff Dickey",title:"CLI Flags Explained"},prevItem:{title:"oclif's Current Node Support",permalink:"/blog/2019/10/31/oclif-node-updates"},nextItem:{title:"Introducing oclif",permalink:"/blog/2018/03/20/introducing-oclif"}},m={authorsImageUrls:[void 0]},d=[{value:"Parts of Speech",id:"parts-of-speech",level:2},{value:"Example ls",id:"example-ls",level:3},{value:"command",id:"command",level:4},{value:"argument",id:"argument",level:4},{value:"Long flag",id:"long-flag",level:4},{value:"Short flag",id:"short-flag",level:4},{value:"Flag arguments",id:"flag-arguments",level:4},{value:"Other Ways of Passing Data",id:"other-ways-of-passing-data",level:2},{value:"Designing a Command",id:"designing-a-command",level:2},{value:"argument",id:"argument-1",level:3},{value:"short flag with argument",id:"short-flag-with-argument",level:3},{value:"long flag with argument",id:"long-flag-with-argument",level:3},{value:"environment variable",id:"environment-variable",level:3},{value:"standard input",id:"standard-input",level:3},{value:"Command ergonomics",id:"command-ergonomics",level:2},{value:"Short flag vs long flag",id:"short-flag-vs-long-flag",level:3}],g={toc:d},c="wrapper";function u(e){var t=e.components,a=(0,r.Z)(e,l);return(0,o.kt)(c,(0,n.Z)({},g,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"oclif")," makes it easy to create a command line interface (CLI) in node. Most commands have ",(0,o.kt)("strong",{parentName:"p"},"parameters"),' \u2014 also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.'),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Note the following describes GNU-style flags. Not all CLIs follow this convention, but it is the most commonly used.")),(0,o.kt)("h2",{id:"parts-of-speech"},"Parts of Speech"),(0,o.kt)("p",null,'Any command line interface command has a few standard "parts of speech". As a user of CLI tools, knowing these parts of speech can help you make fewer typos. It can also help you understand complex commands other people share with you more quickly. If you are designing a CLI tool it is even more important to understand these parts of speech, so you can come up with the most ergonomic interface for your users.'),(0,o.kt)("p",null,"Of the many ways you can pass data to a CLI command, three of them are ",(0,o.kt)("strong",{parentName:"p"},"parameters"),' that are always to the "right" of the command. The three types of parameters are ',(0,o.kt)("strong",{parentName:"p"},"argument"),", ",(0,o.kt)("strong",{parentName:"p"},"short flag"),", and ",(0,o.kt)("strong",{parentName:"p"},"long flag"),"."),(0,o.kt)("h3",{id:"example-ls"},"Example ",(0,o.kt)("inlineCode",{parentName:"h3"},"ls")),(0,o.kt)("p",null,"One of the most common and simplest unix commands is ",(0,o.kt)("inlineCode",{parentName:"p"},"ls"),' which "lists" the contents of a directory.'),(0,o.kt)("h4",{id:"command"},"command"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls\n")),(0,o.kt)("p",null,"This command ",(0,o.kt)("inlineCode",{parentName:"p"},"ls")," works on its own, as a standalone ",(0,o.kt)("strong",{parentName:"p"},"command"),". Without any parameters this command will list the contents of the current folder, using an implied ",(0,o.kt)("inlineCode",{parentName:"p"},".")," directory."),(0,o.kt)("h4",{id:"argument"},"argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls .\nls ~/code/some-repo-name\n")),(0,o.kt)("p",null,"If you pass a command ",(0,o.kt)("strong",{parentName:"p"},"argument")," to this command, like the directory name ",(0,o.kt)("inlineCode",{parentName:"p"},".")," (current folder) or ",(0,o.kt)("inlineCode",{parentName:"p"},"~/code/some-repo-name"),", it will list the contents of that directory instead."),(0,o.kt)("p",null,"An argument is anything to the right of a command that is not a flag. An argument can come before or after flags."),(0,o.kt)("h4",{id:"long-flag"},"Long flag"),(0,o.kt)("p",null,"To list additional files that are normally hidden (like ",(0,o.kt)("inlineCode",{parentName:"p"},"~/.bashrc"),"), you can use a flag on the ",(0,o.kt)("inlineCode",{parentName:"p"},"ls")," command. ",(0,o.kt)("inlineCode",{parentName:"p"},"ls --all")," is the ",(0,o.kt)("strong",{parentName:"p"},"long flag")," form. A long flag always uses a double dash, and it is always represented by multiple characters."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls --all\nls . --all\n")),(0,o.kt)("h4",{id:"short-flag"},"Short flag"),(0,o.kt)("p",null,"There is also a ",(0,o.kt)("strong",{parentName:"p"},"short flag")," form of this flag: ",(0,o.kt)("inlineCode",{parentName:"p"},"ls -a"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"a")," is short for ",(0,o.kt)("inlineCode",{parentName:"p"},"all")," in this case. A short flag always uses a single dash, and it is always represented by a single letter."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls -a\nls . -a\n")),(0,o.kt)("p",null,"Short flags can ",(0,o.kt)("strong",{parentName:"p"},"stack")," too, so you don't need a separate dash for each one. Order does not matter for these, unless passing a flag argument."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls -la\n")),(0,o.kt)("h4",{id:"flag-arguments"},"Flag arguments"),(0,o.kt)("p",null,"Many flags accept an ",(0,o.kt)("strong",{parentName:"p"},"option"),', which is a "flag argument" (as opposed to a "command argument"). In general a command\'s parameters can be in any order, but flags that accept options must have the option directly after the flag.'),(0,o.kt)("p",null,"For an example, here the ",(0,o.kt)("inlineCode",{parentName:"p"},"-x")," flag does not accept an option but the ",(0,o.kt)("inlineCode",{parentName:"p"},"-f")," flag does. ",(0,o.kt)("inlineCode",{parentName:"p"},"archive.tar")," is the option being passed to ",(0,o.kt)("inlineCode",{parentName:"p"},"-f"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"tar -x -f archive.tar\ntar -xf archive.tar\n")),(0,o.kt)("p",null,"A flag and its option can be separated by a space ",(0,o.kt)("inlineCode",{parentName:"p"}," ")," or an equals sign ",(0,o.kt)("inlineCode",{parentName:"p"},"="),". Interestingly, short flags (but not long flags) can even skip the space, although many people find it much easier to read with the space or equals sign."),(0,o.kt)("p",null,"These three are all valid and equivalent:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"tar -f archive.tar\ntar -f=archive.tar\ntar -farchive.tar\n")),(0,o.kt)("p",null,"Long flags must have a space or equals sign to separate the flag from its option."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"git log --pretty=oneline\ngit log --pretty oneline\n")),(0,o.kt)("h2",{id:"other-ways-of-passing-data"},"Other Ways of Passing Data"),(0,o.kt)("p",null,"We've covered ",(0,o.kt)("strong",{parentName:"p"},"parameters"),", which are ",(0,o.kt)("strong",{parentName:"p"},"arguments"),", ",(0,o.kt)("strong",{parentName:"p"},"short flags")," and ",(0,o.kt)("strong",{parentName:"p"},"long flags"),". There are two other ways to pass data to a command: ",(0,o.kt)("strong",{parentName:"p"},"environment variables"),' ("env vars"), or ',(0,o.kt)("strong",{parentName:"p"},"standard input"),' ("stdin"). These won\'t be covered in this blog post.'),(0,o.kt)("h2",{id:"designing-a-command"},"Designing a Command"),(0,o.kt)("p",null,'Scenario: we want to design an oclif command that echos an input like "Casey", and returns "hi, Casey!". There are many ways the user could pass this in, and here we show an example of each type of input.'),(0,o.kt)("h3",{id:"argument-1"},"argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me Casey\n")),(0,o.kt)("h3",{id:"short-flag-with-argument"},"short flag with argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me -n Casey\ngreet-me -n=Casey\ngreet-me -nCasey\n")),(0,o.kt)("h3",{id:"long-flag-with-argument"},"long flag with argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me --name=Casey\ngreet-me --name Casey\n")),(0,o.kt)("h3",{id:"environment-variable"},"environment variable"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"NAME=Casey greet-me\n")),(0,o.kt)("h3",{id:"standard-input"},"standard input"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'echo "Casey" | greet-me\n')),(0,o.kt)("h2",{id:"command-ergonomics"},"Command ergonomics"),(0,o.kt)("h3",{id:"short-flag-vs-long-flag"},"Short flag vs long flag"),(0,o.kt)("p",null,"Many CLI commands allow for both long flag and short flag forms. In the Heroku CLI every flag has at least a long flag form and roughly half of the flags also have a short flag form."),(0,o.kt)("p",null,"The long flag form is easier to read, but takes more characters to type. It is often most useful when you want someone to understand a particular command statement quickly and easily, such as in a README."),(0,o.kt)("p",null,"The short flag form is quicker to type, and is often better for frequently used commands. Short flags are especially useful when stacking short flags together."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/04855d6d.d22e768e.js b/assets/js/04855d6d.d22e768e.js deleted file mode 100644 index 72ac813d..00000000 --- a/assets/js/04855d6d.d22e768e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9544],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),p=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,m=s(e,["components","mdxType","originalType","parentName"]),d=p(a),g=r,u=d["".concat(i,".").concat(g)]||d[g]||c[g]||o;return a?n.createElement(u,l(l({ref:t},m),{},{components:a})):n.createElement(u,l({ref:t},m))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,l=new Array(o);l[0]=g;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[d]="string"==typeof e?e:r,l[1]=s;for(var p=2;p{a.r(t),a.d(t,{assets:()=>m,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>p,toc:()=>d});var n=a(7462),r=a(3366),o=(a(7294),a(3905)),l=["components"],s={author:"Casey Watts and Jeff Dickey",title:"CLI Flags Explained"},i=void 0,p={permalink:"/blog/2019/02/20/cli-flags-explained",source:"@site/blog/2019-02-20-cli-flags-explained.md",title:"CLI Flags Explained",description:'oclif makes it easy to create a command line interface (CLI) in node. Most commands have parameters \u2014 also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.',date:"2019-02-20T00:00:00.000Z",formattedDate:"February 20, 2019",tags:[],readingTime:4.925,hasTruncateMarker:!1,authors:[{name:"Casey Watts and Jeff Dickey"}],frontMatter:{author:"Casey Watts and Jeff Dickey",title:"CLI Flags Explained"},prevItem:{title:"oclifconf 2019: A Recap",permalink:"/blog/2019/09/16/oclifconf-recap"},nextItem:{title:"Introducing oclif",permalink:"/blog/2018/03/20/introducing-oclif"}},m={authorsImageUrls:[void 0]},d=[{value:"Parts of Speech",id:"parts-of-speech",level:2},{value:"Example ls",id:"example-ls",level:3},{value:"command",id:"command",level:4},{value:"argument",id:"argument",level:4},{value:"Long flag",id:"long-flag",level:4},{value:"Short flag",id:"short-flag",level:4},{value:"Flag arguments",id:"flag-arguments",level:4},{value:"Other Ways of Passing Data",id:"other-ways-of-passing-data",level:2},{value:"Designing a Command",id:"designing-a-command",level:2},{value:"argument",id:"argument-1",level:3},{value:"short flag with argument",id:"short-flag-with-argument",level:3},{value:"long flag with argument",id:"long-flag-with-argument",level:3},{value:"environment variable",id:"environment-variable",level:3},{value:"standard input",id:"standard-input",level:3},{value:"Command ergonomics",id:"command-ergonomics",level:2},{value:"Short flag vs long flag",id:"short-flag-vs-long-flag",level:3}],c={toc:d},g="wrapper";function u(e){var t=e.components,a=(0,r.Z)(e,l);return(0,o.kt)(g,(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"oclif")," makes it easy to create a command line interface (CLI) in node. Most commands have ",(0,o.kt)("strong",{parentName:"p"},"parameters"),' \u2014 also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.'),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Note the following describes GNU-style flags. Not all CLIs follow this convention, but it is the most commonly used.")),(0,o.kt)("h2",{id:"parts-of-speech"},"Parts of Speech"),(0,o.kt)("p",null,'Any command line interface command has a few standard "parts of speech". As a user of CLI tools, knowing these parts of speech can help you make fewer typos. It can also help you understand complex commands other people share with you more quickly. If you are designing a CLI tool it is even more important to understand these parts of speech, so you can come up with the most ergonomic interface for your users.'),(0,o.kt)("p",null,"Of the many ways you can pass data to a CLI command, three of them are ",(0,o.kt)("strong",{parentName:"p"},"parameters"),' that are always to the "right" of the command. The three types of parameters are ',(0,o.kt)("strong",{parentName:"p"},"argument"),", ",(0,o.kt)("strong",{parentName:"p"},"short flag"),", and ",(0,o.kt)("strong",{parentName:"p"},"long flag"),"."),(0,o.kt)("h3",{id:"example-ls"},"Example ",(0,o.kt)("inlineCode",{parentName:"h3"},"ls")),(0,o.kt)("p",null,"One of the most common and simplest unix commands is ",(0,o.kt)("inlineCode",{parentName:"p"},"ls"),' which "lists" the contents of a directory.'),(0,o.kt)("h4",{id:"command"},"command"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls\n")),(0,o.kt)("p",null,"This command ",(0,o.kt)("inlineCode",{parentName:"p"},"ls")," works on its own, as a standalone ",(0,o.kt)("strong",{parentName:"p"},"command"),". Without any parameters this command will list the contents of the current folder, using an implied ",(0,o.kt)("inlineCode",{parentName:"p"},".")," directory."),(0,o.kt)("h4",{id:"argument"},"argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls .\nls ~/code/some-repo-name\n")),(0,o.kt)("p",null,"If you pass a command ",(0,o.kt)("strong",{parentName:"p"},"argument")," to this command, like the directory name ",(0,o.kt)("inlineCode",{parentName:"p"},".")," (current folder) or ",(0,o.kt)("inlineCode",{parentName:"p"},"~/code/some-repo-name"),", it will list the contents of that directory instead."),(0,o.kt)("p",null,"An argument is anything to the right of a command that is not a flag. An argument can come before or after flags."),(0,o.kt)("h4",{id:"long-flag"},"Long flag"),(0,o.kt)("p",null,"To list additional files that are normally hidden (like ",(0,o.kt)("inlineCode",{parentName:"p"},"~/.bashrc"),"), you can use a flag on the ",(0,o.kt)("inlineCode",{parentName:"p"},"ls")," command. ",(0,o.kt)("inlineCode",{parentName:"p"},"ls --all")," is the ",(0,o.kt)("strong",{parentName:"p"},"long flag")," form. A long flag always uses a double dash, and it is always represented by multiple characters."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls --all\nls . --all\n")),(0,o.kt)("h4",{id:"short-flag"},"Short flag"),(0,o.kt)("p",null,"There is also a ",(0,o.kt)("strong",{parentName:"p"},"short flag")," form of this flag: ",(0,o.kt)("inlineCode",{parentName:"p"},"ls -a"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"a")," is short for ",(0,o.kt)("inlineCode",{parentName:"p"},"all")," in this case. A short flag always uses a single dash, and it is always represented by a single letter."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls -a\nls . -a\n")),(0,o.kt)("p",null,"Short flags can ",(0,o.kt)("strong",{parentName:"p"},"stack")," too, so you don't need a separate dash for each one. Order does not matter for these, unless passing a flag argument."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls -la\n")),(0,o.kt)("h4",{id:"flag-arguments"},"Flag arguments"),(0,o.kt)("p",null,"Many flags accept an ",(0,o.kt)("strong",{parentName:"p"},"option"),', which is a "flag argument" (as opposed to a "command argument"). In general a command\'s parameters can be in any order, but flags that accept options must have the option directly after the flag.'),(0,o.kt)("p",null,"For an example, here the ",(0,o.kt)("inlineCode",{parentName:"p"},"-x")," flag does not accept an option but the ",(0,o.kt)("inlineCode",{parentName:"p"},"-f")," flag does. ",(0,o.kt)("inlineCode",{parentName:"p"},"archive.tar")," is the option being passed to ",(0,o.kt)("inlineCode",{parentName:"p"},"-f"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"tar -x -f archive.tar\ntar -xf archive.tar\n")),(0,o.kt)("p",null,"A flag and its option can be separated by a space ",(0,o.kt)("inlineCode",{parentName:"p"}," ")," or an equals sign ",(0,o.kt)("inlineCode",{parentName:"p"},"="),". Interestingly, short flags (but not long flags) can even skip the space, although many people find it much easier to read with the space or equals sign."),(0,o.kt)("p",null,"These three are all valid and equivalent:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"tar -f archive.tar\ntar -f=archive.tar\ntar -farchive.tar\n")),(0,o.kt)("p",null,"Long flags must have a space or equals sign to separate the flag from its option."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"git log --pretty=oneline\ngit log --pretty oneline\n")),(0,o.kt)("h2",{id:"other-ways-of-passing-data"},"Other Ways of Passing Data"),(0,o.kt)("p",null,"We've covered ",(0,o.kt)("strong",{parentName:"p"},"parameters"),", which are ",(0,o.kt)("strong",{parentName:"p"},"arguments"),", ",(0,o.kt)("strong",{parentName:"p"},"short flags")," and ",(0,o.kt)("strong",{parentName:"p"},"long flags"),". There are two other ways to pass data to a command: ",(0,o.kt)("strong",{parentName:"p"},"environment variables"),' ("env vars"), or ',(0,o.kt)("strong",{parentName:"p"},"standard input"),' ("stdin"). These won\'t be covered in this blog post.'),(0,o.kt)("h2",{id:"designing-a-command"},"Designing a Command"),(0,o.kt)("p",null,'Scenario: we want to design an oclif command that echos an input like "Casey", and returns "hi, Casey!". There are many ways the user could pass this in, and here we show an example of each type of input.'),(0,o.kt)("h3",{id:"argument-1"},"argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me Casey\n")),(0,o.kt)("h3",{id:"short-flag-with-argument"},"short flag with argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me -n Casey\ngreet-me -n=Casey\ngreet-me -nCasey\n")),(0,o.kt)("h3",{id:"long-flag-with-argument"},"long flag with argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me --name=Casey\ngreet-me --name Casey\n")),(0,o.kt)("h3",{id:"environment-variable"},"environment variable"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"NAME=Casey greet-me\n")),(0,o.kt)("h3",{id:"standard-input"},"standard input"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'echo "Casey" | greet-me\n')),(0,o.kt)("h2",{id:"command-ergonomics"},"Command ergonomics"),(0,o.kt)("h3",{id:"short-flag-vs-long-flag"},"Short flag vs long flag"),(0,o.kt)("p",null,"Many CLI commands allow for both long flag and short flag forms. In the Heroku CLI every flag has at least a long flag form and roughly half of the flags also have a short flag form."),(0,o.kt)("p",null,"The long flag form is easier to read, but takes more characters to type. It is often most useful when you want someone to understand a particular command statement quickly and easily, such as in a README."),(0,o.kt)("p",null,"The short flag form is quicker to type, and is often better for frequently used commands. Short flags are especially useful when stacking short flags together."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0b218a01.68f8be54.js b/assets/js/0b218a01.68f8be54.js new file mode 100644 index 00000000..750b7ce3 --- /dev/null +++ b/assets/js/0b218a01.68f8be54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[3321],{3905:(e,n,a)=>{a.d(n,{Zo:()=>p,kt:()=>f});var t=a(7294);function i(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function r(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function s(e){for(var n=1;n=0||(i[a]=e[a]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=t.createContext({}),c=function(e){var n=t.useContext(l),a=n;return e&&(a="function"==typeof e?e(n):s(s({},n),e)),a},p=function(e){var n=c(e.components);return t.createElement(l.Provider,{value:n},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=c(a),u=i,f=d["".concat(l,".").concat(u)]||d[u]||m[u]||r;return a?t.createElement(f,s(s({ref:n},p),{},{components:a})):t.createElement(f,s({ref:n},p))}));function f(e,n){var a=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=a.length,s=new Array(r);s[0]=u;var o={};for(var l in n)hasOwnProperty.call(n,l)&&(o[l]=n[l]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var c=2;c{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var t=a(7462),i=a(3366),r=(a(7294),a(3905)),s=["components"],o={title:"Aliases"},l=void 0,c={unversionedId:"aliases",id:"aliases",title:"Aliases",description:"Command Aliases",source:"@site/../docs/aliases.md",sourceDirName:".",slug:"/aliases",permalink:"/docs/aliases",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/aliases.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Aliases"},sidebar:"docs",previous:{title:"Just-in-Time Plugin Installation",permalink:"/docs/jit_plugins"},next:{title:"NSIS Installer Customization",permalink:"/docs/nsis-installer_customization"}},p={},d=[{value:"Command Aliases",id:"command-aliases",level:2},{value:"Flag Aliases",id:"flag-aliases",level:2},{value:"Bin Aliases",id:"bin-aliases",level:2}],m={toc:d},u="wrapper";function f(e){var n=e.components,a=(0,i.Z)(e,s);return(0,r.kt)(u,(0,t.Z)({},m,a,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"command-aliases"},"Command Aliases"),(0,r.kt)("p",null,"Aliases let you define a string that maps to a command. This command can be run as ",(0,r.kt)("inlineCode",{parentName:"p"},"mycli config"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"mycli config:index"),", or ",(0,r.kt)("inlineCode",{parentName:"p"},"mycli config:list"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"import {Command, Flags} from '@oclif/core'\n\nexport class ConfigIndex extends Command {\n static aliases = ['config:index', 'config:list']\n}\n")),(0,r.kt)("p",null,'By default, aliases find the "real" command and just work. If you\'re providing command aliases for backward compatibility but prefer users to use the "real" command, set ',(0,r.kt)("inlineCode",{parentName:"p"},"deprecateAliases")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"true")," to warn users about the correct name"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"export class ConfigIndex extends Command {\n static aliases = ['config:index', 'config:list']\n static deprecateAliases = true\n}\n")),(0,r.kt)("h2",{id:"flag-aliases"},"Flag Aliases"),(0,r.kt)("p",null,"Like command aliases, but on an individual flag. You can alias the name and short character, and optionally emit warnings when aliased names are used."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"export class ConfigIndex extends Command {\n static flags = {\n 'new-name': Flags.boolean({\n char: 'c',\n aliases: ['old-name', 'o'],\n deprecateAliases: true\n })\n }\n}\n\n")),(0,r.kt)("h2",{id:"bin-aliases"},"Bin Aliases"),(0,r.kt)("p",null,'Creating a CLI that responds to different names or "aliases" is easy, simply add a ',(0,r.kt)("inlineCode",{parentName:"p"},"binAliases")," property to your CLI's ",(0,r.kt)("inlineCode",{parentName:"p"},"oclif")," property in ",(0,r.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "name": "mycli",\n "version": "0.0.0",\n "description": "My CLI",\n "main": "bin/run",\n "bin": {\n "mycli": "./bin/run",\n "mycli-alias": "./bin/run"\n },\n "oclif": {\n "binAliases": ["mycli", "mycli-alias"]\n }\n}\n')),(0,r.kt)("p",null,"Adding this property allows your CLI to respond to either of those names, and is used during the bundling and building process when shipping your CLI. Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"bin")," section was also modified to include both aliases, which is how npm creates bin aliases. To create a unified experience, regardless of the installation method, a CLI author must change both to match. Bin aliases also play nicely with ",(0,r.kt)("inlineCode",{parentName:"p"},"@oclif/plugin-autocomplete"),", so typing an alias and using autocomplete is the same experience as using the original name."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0b218a01.990b2c7f.js b/assets/js/0b218a01.990b2c7f.js deleted file mode 100644 index 700a943f..00000000 --- a/assets/js/0b218a01.990b2c7f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[3321],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var a=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=a.createContext({}),c=function(e){var n=a.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=c(e.components);return a.createElement(l.Provider,{value:n},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=c(t),u=i,f=d["".concat(l,".").concat(u)]||d[u]||m[u]||r;return t?a.createElement(f,s(s({ref:n},p),{},{components:t})):a.createElement(f,s({ref:n},p))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var r=t.length,s=new Array(r);s[0]=u;var o={};for(var l in n)hasOwnProperty.call(n,l)&&(o[l]=n[l]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var c=2;c{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var a=t(7462),i=t(3366),r=(t(7294),t(3905)),s=["components"],o={title:"Aliases"},l=void 0,c={unversionedId:"aliases",id:"aliases",title:"Aliases",description:"Command Aliases",source:"@site/../docs/aliases.md",sourceDirName:".",slug:"/aliases",permalink:"/docs/aliases",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/aliases.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Aliases"},sidebar:"docs",previous:{title:"Just-in-Time Plugin Installation",permalink:"/docs/jit_plugins"},next:{title:"NSIS Installer Customization",permalink:"/docs/nsis-installer_customization"}},p={},d=[{value:"Command Aliases",id:"command-aliases",level:2},{value:"Flag Aliases",id:"flag-aliases",level:2},{value:"Bin Aliases",id:"bin-aliases",level:2}],m={toc:d},u="wrapper";function f(e){var n=e.components,t=(0,i.Z)(e,s);return(0,r.kt)(u,(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"command-aliases"},"Command Aliases"),(0,r.kt)("p",null,"Aliases let you define a string that maps to a command. This command can be run as ",(0,r.kt)("inlineCode",{parentName:"p"},"mycli config"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"mycli config:index"),", or ",(0,r.kt)("inlineCode",{parentName:"p"},"mycli config:list"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"import {Command, Flags} from '@oclif/core'\n\nexport class ConfigIndex extends Command {\n static aliases = ['config:index', 'config:list']\n}\n")),(0,r.kt)("p",null,'By default, aliases find the "real" command and just work. If you\'re providing command aliases for backward compatibility but prefer users to use the "real" command, set ',(0,r.kt)("inlineCode",{parentName:"p"},"deprecateAliases")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"true")," to warn users about the correct name"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"export class ConfigIndex extends Command {\n static aliases = ['config:index', 'config:list']\n static deprecateAliases = true\n}\n")),(0,r.kt)("h2",{id:"flag-aliases"},"Flag Aliases"),(0,r.kt)("p",null,"Like command aliases, but on an individual flag. You can alias the name and short character, and optionally emit warnings when aliased names are used."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"export class ConfigIndex extends Command {\n static flags = {\n 'new-name': Flags.boolean({\n char: 'c',\n aliases: ['old-name', 'o'],\n deprecateAliases: true\n })\n }\n}\n\n")),(0,r.kt)("h2",{id:"bin-aliases"},"Bin Aliases"),(0,r.kt)("p",null,'Creating a CLI that responds to different names or "aliases" is easy, simply add a ',(0,r.kt)("inlineCode",{parentName:"p"},"binAliases")," property to your CLI's ",(0,r.kt)("inlineCode",{parentName:"p"},"oclif")," property in ",(0,r.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "name": "mycli",\n "version": "0.0.0",\n "description": "My CLI",\n "main": "bin/run",\n "bin": {\n "mycli": "./bin/run",\n "mycli-alias": "./bin/run"\n },\n "oclif": {\n "binAliases": ["mycli", "mycli-alias"]\n }\n}\n')),(0,r.kt)("p",null,"Adding this property allows your CLI to respond to either of those names, and is used during the bundling and building process when shipping your CLI. Note that the ",(0,r.kt)("inlineCode",{parentName:"p"},"bin")," section was also modified to include both aliases, which is how npm creates bin aliases. To create a unified experience, regardless of the installation method, a CLI author must change both to match. Bin aliases also play nicely with ",(0,r.kt)("inlineCode",{parentName:"p"},"@oclif/plugin-autocomplete"),", so typing an alias and using autocomplete is the same experience as using the original name."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/104cbb75.3f6c249e.js b/assets/js/104cbb75.3f6c249e.js new file mode 100644 index 00000000..f48828a3 --- /dev/null +++ b/assets/js/104cbb75.3f6c249e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[3316],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var o=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var m=o.createContext({}),c=function(e){var n=o.useContext(m),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return o.createElement(m.Provider,{value:n},e.children)},s="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},u=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,m=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),s=c(t),u=r,f=s["".concat(m,".").concat(u)]||s[u]||d[u]||a;return t?o.createElement(f,i(i({ref:n},p),{},{components:t})):o.createElement(f,i({ref:n},p))}));function f(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,i=new Array(a);i[0]=u;var l={};for(var m in n)hasOwnProperty.call(n,m)&&(l[m]=n[m]);l.originalType=e,l[s]="string"==typeof e?e:r,i[1]=l;for(var c=2;c{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>m,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>s});var o=t(7462),r=t(3366),a=(t(7294),t(3905)),i=["components"],l={title:"Flexible Taxonomy"},m=void 0,c={unversionedId:"flexible_taxonomy",id:"flexible_taxonomy",title:"Flexible Taxonomy",description:"If you'd like for your customers to execute commands without adhereing to the defined command taxonomy, you can enable flexibleTaxonomy and add a hook to the oclif section of your package.json:",source:"@site/../docs/flexible_taxonomy.md",sourceDirName:".",slug:"/flexible_taxonomy",permalink:"/docs/flexible_taxonomy",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/flexible_taxonomy.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Flexible Taxonomy"},sidebar:"docs",previous:{title:"Debugging",permalink:"/docs/debugging"},next:{title:"Global Flags",permalink:"/docs/global_flags"}},p={},s=[{value:"Hook Implementation",id:"hook-implementation",level:3}],d={toc:s},u="wrapper";function f(e){var n=e.components,t=(0,r.Z)(e,i);return(0,a.kt)(u,(0,o.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"If you'd like for your customers to execute commands without adhereing to the defined command taxonomy, you can enable ",(0,a.kt)("inlineCode",{parentName:"p"},"flexibleTaxonomy")," and add a hook to the ",(0,a.kt)("inlineCode",{parentName:"p"},"oclif")," section of your package.json:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "oclif": {\n "flexibleTaxonomy": true,\n "hooks": {\n "command_incomplete": "./dist/hooks/command_incomplete.js"\n }\n }\n}\n')),(0,a.kt)("p",null,"There are two main benefits to enabling flexible taxonomy:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"It makes your CLI more user-friendly. For example, you might have a command, ",(0,a.kt)("inlineCode",{parentName:"li"},"my-cli foobars:list"),". If a user mistakenly enters ",(0,a.kt)("inlineCode",{parentName:"li"},"my-cli list:foobars")," then oclif will automatically know that it should execute ",(0,a.kt)("inlineCode",{parentName:"li"},"foobars:list")," instead of throwing an error."),(0,a.kt)("li",{parentName:"ol"},"It gives you the opportunity to prompt a user for the right command if they only provide part of a command. This makes individual commands more discoverable, especially if you have a large number of commands. See ",(0,a.kt)("a",{parentName:"li",href:"#hook-implementation"},"Hook Implementation")," for more details.")),(0,a.kt)("h3",{id:"hook-implementation"},"Hook Implementation"),(0,a.kt)("p",null,"When ",(0,a.kt)("inlineCode",{parentName:"p"},"flexibleTaxonomy")," is enabled, oclif will run the ",(0,a.kt)("inlineCode",{parentName:"p"},"command_incomplete")," hook anytime a user enters an incomplete command (e.g. the command is ",(0,a.kt)("inlineCode",{parentName:"p"},"one:two:three")," but they only entered ",(0,a.kt)("inlineCode",{parentName:"p"},"two"),"). This hook gives you the opportunity to create an interactive user experience."),(0,a.kt)("p",null,"This example shows how you can use the ",(0,a.kt)("a",{parentName:"p",href:"#https://www.npmjs.com/package/inquirer"},"inquirer")," package to prompt the user for which command they would like to run:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},'import { Hook, toConfiguredId, toStandardizedId } from "@oclif/core";\nimport { prompt } from "inquirer";\n\nconst hook: Hook.CommandIncomplete = async function ({\n config,\n matches,\n argv,\n}) {\n const { command } = await prompt<{ command: string }>([\n {\n name: "command",\n type: "list",\n message: "Which of these commands would you like to run?",\n choices: matches.map((p) => toConfiguredId(p.id, config)),\n },\n ]);\n\n if (argv.includes("--help") || argv.includes("-h")) {\n return config.runCommand("help", [toStandardizedId(command, config)]);\n }\n\n return config.runCommand(toStandardizedId(command, config), argv);\n};\n\nexport default hook;\n')),(0,a.kt)("p",null,"This is the prompt that the user would see:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ my-cli list\n? Which of these commands did you mean (Use arrow keys)\n\u276f foobars list\n config list\n env list\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/104cbb75.fac7d79f.js b/assets/js/104cbb75.fac7d79f.js deleted file mode 100644 index 42e5d513..00000000 --- a/assets/js/104cbb75.fac7d79f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[3316],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var m=o.createContext({}),c=function(e){var t=o.useContext(m),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(m.Provider,{value:t},e.children)},s="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,m=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),s=c(n),u=r,f=s["".concat(m,".").concat(u)]||s[u]||d[u]||a;return n?o.createElement(f,i(i({ref:t},p),{},{components:n})):o.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=u;var l={};for(var m in t)hasOwnProperty.call(t,m)&&(l[m]=t[m]);l.originalType=e,l[s]="string"==typeof e?e:r,i[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>m,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>s});var o=n(7462),r=n(3366),a=(n(7294),n(3905)),i=["components"],l={title:"Flexible Taxonomy"},m=void 0,c={unversionedId:"flexible_taxonomy",id:"flexible_taxonomy",title:"Flexible Taxonomy",description:"If you'd like for your customers to execute commands without adhereing to the defined command taxonomy, you can enable flexibleTaxonomy and add a hook to the oclif section of your package.json:",source:"@site/../docs/flexible_taxonomy.md",sourceDirName:".",slug:"/flexible_taxonomy",permalink:"/docs/flexible_taxonomy",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/flexible_taxonomy.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Flexible Taxonomy"},sidebar:"docs",previous:{title:"Debugging",permalink:"/docs/debugging"},next:{title:"Global Flags",permalink:"/docs/global_flags"}},p={},s=[{value:"Hook Implementation",id:"hook-implementation",level:3}],d={toc:s},u="wrapper";function f(e){var t=e.components,n=(0,r.Z)(e,i);return(0,a.kt)(u,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"If you'd like for your customers to execute commands without adhereing to the defined command taxonomy, you can enable ",(0,a.kt)("inlineCode",{parentName:"p"},"flexibleTaxonomy")," and add a hook to the ",(0,a.kt)("inlineCode",{parentName:"p"},"oclif")," section of your package.json:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "oclif": {\n "flexibleTaxonomy": true,\n "hooks": {\n "command_incomplete": "./dist/hooks/command_incomplete.js"\n }\n }\n}\n')),(0,a.kt)("p",null,"There are two main benefits to enabling flexible taxonomy:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"It makes your CLI more user-friendly. For example, you might have a command, ",(0,a.kt)("inlineCode",{parentName:"li"},"my-cli foobars:list"),". If a user mistakenly enters ",(0,a.kt)("inlineCode",{parentName:"li"},"my-cli list:foobars")," then oclif will automatically know that it should execute ",(0,a.kt)("inlineCode",{parentName:"li"},"foobars:list")," instead of throwing an error."),(0,a.kt)("li",{parentName:"ol"},"It gives you the opportunity to prompt a user for the right command if they only provide part of a command. This makes individual commands more discoverable, especially if you have a large number of commands. See ",(0,a.kt)("a",{parentName:"li",href:"#hook-implementation"},"Hook Implementation")," for more details.")),(0,a.kt)("h3",{id:"hook-implementation"},"Hook Implementation"),(0,a.kt)("p",null,"When ",(0,a.kt)("inlineCode",{parentName:"p"},"flexibleTaxonomy")," is enabled, oclif will run the ",(0,a.kt)("inlineCode",{parentName:"p"},"command_incomplete")," hook anytime a user enters an incomplete command (e.g. the command is ",(0,a.kt)("inlineCode",{parentName:"p"},"one:two:three")," but they only entered ",(0,a.kt)("inlineCode",{parentName:"p"},"two"),"). This hook gives you the opportunity to create an interactive user experience."),(0,a.kt)("p",null,"This example shows how you can use the ",(0,a.kt)("a",{parentName:"p",href:"#https://www.npmjs.com/package/inquirer"},"inquirer")," package to prompt the user for which command they would like to run:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},'import { Hook, toConfiguredId, toStandardizedId } from "@oclif/core";\nimport { prompt } from "inquirer";\n\nconst hook: Hook.CommandIncomplete = async function ({\n config,\n matches,\n argv,\n}) {\n const { command } = await prompt<{ command: string }>([\n {\n name: "command",\n type: "list",\n message: "Which of these commands would you like to run?",\n choices: matches.map((p) => toConfiguredId(p.id, config)),\n },\n ]);\n\n if (argv.includes("--help") || argv.includes("-h")) {\n return config.runCommand("help", [toStandardizedId(command, config)]);\n }\n\n return config.runCommand(toStandardizedId(command, config), argv);\n};\n\nexport default hook;\n')),(0,a.kt)("p",null,"This is the prompt that the user would see:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ my-cli list\n? Which of these commands did you mean (Use arrow keys)\n\u276f foobars list\n config list\n env list\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/19fd9079.f7259764.js b/assets/js/19fd9079.7e23dce2.js similarity index 76% rename from assets/js/19fd9079.f7259764.js rename to assets/js/19fd9079.7e23dce2.js index 98e6f1b8..a78ced76 100644 --- a/assets/js/19fd9079.f7259764.js +++ b/assets/js/19fd9079.7e23dce2.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8925],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=s(r),m=o,d=u["".concat(c,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,l(l({ref:t},p),{},{components:r})):n.createElement(d,l({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,l[1]=i;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),l=["components"],i={title:"External Links"},c=void 0,s={unversionedId:"external_links",id:"external_links",title:"External Links",description:"* Salesforce Release Announcement",source:"@site/../docs/external_links.md",sourceDirName:".",slug:"/external_links",permalink:"/docs/external_links",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/external_links.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"External Links"},sidebar:"docs",previous:{title:"Examples",permalink:"/docs/examples"},next:{title:"Related Repositories",permalink:"/docs/related_repos"}},p={},u=[],f={toc:u},m="wrapper";function d(e){var t=e.components,r=(0,o.Z)(e,l);return(0,a.kt)(m,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://engineering.salesforce.com/open-sourcing-oclif-the-cli-framework-that-powers-our-clis-21fbda99d33a"},"Salesforce Release Announcement")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://blog.heroku.com/open-cli-framework"},"Heroku Release Announcement"))))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8925],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=s(r),m=o,d=u["".concat(c,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,l(l({ref:t},p),{},{components:r})):n.createElement(d,l({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,l[1]=i;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),l=["components"],i={title:"External Links"},c=void 0,s={unversionedId:"external_links",id:"external_links",title:"External Links",description:"* Salesforce Release Announcement",source:"@site/../docs/external_links.md",sourceDirName:".",slug:"/external_links",permalink:"/docs/external_links",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/external_links.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"External Links"},sidebar:"docs",previous:{title:"Examples",permalink:"/docs/examples"},next:{title:"Related Repositories",permalink:"/docs/related_repos"}},p={},u=[],f={toc:u},m="wrapper";function d(e){var t=e.components,r=(0,o.Z)(e,l);return(0,a.kt)(m,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://engineering.salesforce.com/open-sourcing-oclif-the-cli-framework-that-powers-our-clis-21fbda99d33a"},"Salesforce Release Announcement")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://blog.heroku.com/open-cli-framework"},"Heroku Release Announcement"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1d5c88f5.08aca381.js b/assets/js/1d5c88f5.08aca381.js new file mode 100644 index 00000000..88c4e5c5 --- /dev/null +++ b/assets/js/1d5c88f5.08aca381.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5901],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),p=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},d="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,m=s(e,["components","mdxType","originalType","parentName"]),d=p(a),c=r,u=d["".concat(i,".").concat(c)]||d[c]||g[c]||o;return a?n.createElement(u,l(l({ref:t},m),{},{components:a})):n.createElement(u,l({ref:t},m))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,l=new Array(o);l[0]=c;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[d]="string"==typeof e?e:r,l[1]=s;for(var p=2;p{a.r(t),a.d(t,{assets:()=>m,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>p,toc:()=>d});var n=a(7462),r=a(3366),o=(a(7294),a(3905)),l=["components"],s={author:"Casey Watts and Jeff Dickey",title:"CLI Flags Explained"},i=void 0,p={permalink:"/blog/2019/02/20/cli-flags-explained",source:"@site/blog/2019-02-20-cli-flags-explained.md",title:"CLI Flags Explained",description:'oclif makes it easy to create a command line interface (CLI) in node. Most commands have parameters \u2014 also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.',date:"2019-02-20T00:00:00.000Z",formattedDate:"February 20, 2019",tags:[],readingTime:4.925,hasTruncateMarker:!1,authors:[{name:"Casey Watts and Jeff Dickey"}],frontMatter:{author:"Casey Watts and Jeff Dickey",title:"CLI Flags Explained"},prevItem:{title:"oclif's Current Node Support",permalink:"/blog/2019/10/31/oclif-node-updates"},nextItem:{title:"Introducing oclif",permalink:"/blog/2018/03/20/introducing-oclif"}},m={authorsImageUrls:[void 0]},d=[{value:"Parts of Speech",id:"parts-of-speech",level:2},{value:"Example ls",id:"example-ls",level:3},{value:"command",id:"command",level:4},{value:"argument",id:"argument",level:4},{value:"Long flag",id:"long-flag",level:4},{value:"Short flag",id:"short-flag",level:4},{value:"Flag arguments",id:"flag-arguments",level:4},{value:"Other Ways of Passing Data",id:"other-ways-of-passing-data",level:2},{value:"Designing a Command",id:"designing-a-command",level:2},{value:"argument",id:"argument-1",level:3},{value:"short flag with argument",id:"short-flag-with-argument",level:3},{value:"long flag with argument",id:"long-flag-with-argument",level:3},{value:"environment variable",id:"environment-variable",level:3},{value:"standard input",id:"standard-input",level:3},{value:"Command ergonomics",id:"command-ergonomics",level:2},{value:"Short flag vs long flag",id:"short-flag-vs-long-flag",level:3}],g={toc:d},c="wrapper";function u(e){var t=e.components,a=(0,r.Z)(e,l);return(0,o.kt)(c,(0,n.Z)({},g,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"oclif")," makes it easy to create a command line interface (CLI) in node. Most commands have ",(0,o.kt)("strong",{parentName:"p"},"parameters"),' \u2014 also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.'),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Note the following describes GNU-style flags. Not all CLIs follow this convention, but it is the most commonly used.")),(0,o.kt)("h2",{id:"parts-of-speech"},"Parts of Speech"),(0,o.kt)("p",null,'Any command line interface command has a few standard "parts of speech". As a user of CLI tools, knowing these parts of speech can help you make fewer typos. It can also help you understand complex commands other people share with you more quickly. If you are designing a CLI tool it is even more important to understand these parts of speech, so you can come up with the most ergonomic interface for your users.'),(0,o.kt)("p",null,"Of the many ways you can pass data to a CLI command, three of them are ",(0,o.kt)("strong",{parentName:"p"},"parameters"),' that are always to the "right" of the command. The three types of parameters are ',(0,o.kt)("strong",{parentName:"p"},"argument"),", ",(0,o.kt)("strong",{parentName:"p"},"short flag"),", and ",(0,o.kt)("strong",{parentName:"p"},"long flag"),"."),(0,o.kt)("h3",{id:"example-ls"},"Example ",(0,o.kt)("inlineCode",{parentName:"h3"},"ls")),(0,o.kt)("p",null,"One of the most common and simplest unix commands is ",(0,o.kt)("inlineCode",{parentName:"p"},"ls"),' which "lists" the contents of a directory.'),(0,o.kt)("h4",{id:"command"},"command"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls\n")),(0,o.kt)("p",null,"This command ",(0,o.kt)("inlineCode",{parentName:"p"},"ls")," works on its own, as a standalone ",(0,o.kt)("strong",{parentName:"p"},"command"),". Without any parameters this command will list the contents of the current folder, using an implied ",(0,o.kt)("inlineCode",{parentName:"p"},".")," directory."),(0,o.kt)("h4",{id:"argument"},"argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls .\nls ~/code/some-repo-name\n")),(0,o.kt)("p",null,"If you pass a command ",(0,o.kt)("strong",{parentName:"p"},"argument")," to this command, like the directory name ",(0,o.kt)("inlineCode",{parentName:"p"},".")," (current folder) or ",(0,o.kt)("inlineCode",{parentName:"p"},"~/code/some-repo-name"),", it will list the contents of that directory instead."),(0,o.kt)("p",null,"An argument is anything to the right of a command that is not a flag. An argument can come before or after flags."),(0,o.kt)("h4",{id:"long-flag"},"Long flag"),(0,o.kt)("p",null,"To list additional files that are normally hidden (like ",(0,o.kt)("inlineCode",{parentName:"p"},"~/.bashrc"),"), you can use a flag on the ",(0,o.kt)("inlineCode",{parentName:"p"},"ls")," command. ",(0,o.kt)("inlineCode",{parentName:"p"},"ls --all")," is the ",(0,o.kt)("strong",{parentName:"p"},"long flag")," form. A long flag always uses a double dash, and it is always represented by multiple characters."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls --all\nls . --all\n")),(0,o.kt)("h4",{id:"short-flag"},"Short flag"),(0,o.kt)("p",null,"There is also a ",(0,o.kt)("strong",{parentName:"p"},"short flag")," form of this flag: ",(0,o.kt)("inlineCode",{parentName:"p"},"ls -a"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"a")," is short for ",(0,o.kt)("inlineCode",{parentName:"p"},"all")," in this case. A short flag always uses a single dash, and it is always represented by a single letter."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls -a\nls . -a\n")),(0,o.kt)("p",null,"Short flags can ",(0,o.kt)("strong",{parentName:"p"},"stack")," too, so you don't need a separate dash for each one. Order does not matter for these, unless passing a flag argument."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls -la\n")),(0,o.kt)("h4",{id:"flag-arguments"},"Flag arguments"),(0,o.kt)("p",null,"Many flags accept an ",(0,o.kt)("strong",{parentName:"p"},"option"),', which is a "flag argument" (as opposed to a "command argument"). In general a command\'s parameters can be in any order, but flags that accept options must have the option directly after the flag.'),(0,o.kt)("p",null,"For an example, here the ",(0,o.kt)("inlineCode",{parentName:"p"},"-x")," flag does not accept an option but the ",(0,o.kt)("inlineCode",{parentName:"p"},"-f")," flag does. ",(0,o.kt)("inlineCode",{parentName:"p"},"archive.tar")," is the option being passed to ",(0,o.kt)("inlineCode",{parentName:"p"},"-f"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"tar -x -f archive.tar\ntar -xf archive.tar\n")),(0,o.kt)("p",null,"A flag and its option can be separated by a space ",(0,o.kt)("inlineCode",{parentName:"p"}," ")," or an equals sign ",(0,o.kt)("inlineCode",{parentName:"p"},"="),". Interestingly, short flags (but not long flags) can even skip the space, although many people find it much easier to read with the space or equals sign."),(0,o.kt)("p",null,"These three are all valid and equivalent:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"tar -f archive.tar\ntar -f=archive.tar\ntar -farchive.tar\n")),(0,o.kt)("p",null,"Long flags must have a space or equals sign to separate the flag from its option."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"git log --pretty=oneline\ngit log --pretty oneline\n")),(0,o.kt)("h2",{id:"other-ways-of-passing-data"},"Other Ways of Passing Data"),(0,o.kt)("p",null,"We've covered ",(0,o.kt)("strong",{parentName:"p"},"parameters"),", which are ",(0,o.kt)("strong",{parentName:"p"},"arguments"),", ",(0,o.kt)("strong",{parentName:"p"},"short flags")," and ",(0,o.kt)("strong",{parentName:"p"},"long flags"),". There are two other ways to pass data to a command: ",(0,o.kt)("strong",{parentName:"p"},"environment variables"),' ("env vars"), or ',(0,o.kt)("strong",{parentName:"p"},"standard input"),' ("stdin"). These won\'t be covered in this blog post.'),(0,o.kt)("h2",{id:"designing-a-command"},"Designing a Command"),(0,o.kt)("p",null,'Scenario: we want to design an oclif command that echos an input like "Casey", and returns "hi, Casey!". There are many ways the user could pass this in, and here we show an example of each type of input.'),(0,o.kt)("h3",{id:"argument-1"},"argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me Casey\n")),(0,o.kt)("h3",{id:"short-flag-with-argument"},"short flag with argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me -n Casey\ngreet-me -n=Casey\ngreet-me -nCasey\n")),(0,o.kt)("h3",{id:"long-flag-with-argument"},"long flag with argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me --name=Casey\ngreet-me --name Casey\n")),(0,o.kt)("h3",{id:"environment-variable"},"environment variable"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"NAME=Casey greet-me\n")),(0,o.kt)("h3",{id:"standard-input"},"standard input"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'echo "Casey" | greet-me\n')),(0,o.kt)("h2",{id:"command-ergonomics"},"Command ergonomics"),(0,o.kt)("h3",{id:"short-flag-vs-long-flag"},"Short flag vs long flag"),(0,o.kt)("p",null,"Many CLI commands allow for both long flag and short flag forms. In the Heroku CLI every flag has at least a long flag form and roughly half of the flags also have a short flag form."),(0,o.kt)("p",null,"The long flag form is easier to read, but takes more characters to type. It is often most useful when you want someone to understand a particular command statement quickly and easily, such as in a README."),(0,o.kt)("p",null,"The short flag form is quicker to type, and is often better for frequently used commands. Short flags are especially useful when stacking short flags together."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1d5c88f5.d6f4a0d4.js b/assets/js/1d5c88f5.d6f4a0d4.js deleted file mode 100644 index 06476283..00000000 --- a/assets/js/1d5c88f5.d6f4a0d4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5901],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),p=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},g=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,m=s(e,["components","mdxType","originalType","parentName"]),d=p(a),g=r,u=d["".concat(i,".").concat(g)]||d[g]||c[g]||o;return a?n.createElement(u,l(l({ref:t},m),{},{components:a})):n.createElement(u,l({ref:t},m))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,l=new Array(o);l[0]=g;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[d]="string"==typeof e?e:r,l[1]=s;for(var p=2;p{a.r(t),a.d(t,{assets:()=>m,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>p,toc:()=>d});var n=a(7462),r=a(3366),o=(a(7294),a(3905)),l=["components"],s={author:"Casey Watts and Jeff Dickey",title:"CLI Flags Explained"},i=void 0,p={permalink:"/blog/2019/02/20/cli-flags-explained",source:"@site/blog/2019-02-20-cli-flags-explained.md",title:"CLI Flags Explained",description:'oclif makes it easy to create a command line interface (CLI) in node. Most commands have parameters \u2014 also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.',date:"2019-02-20T00:00:00.000Z",formattedDate:"February 20, 2019",tags:[],readingTime:4.925,hasTruncateMarker:!1,authors:[{name:"Casey Watts and Jeff Dickey"}],frontMatter:{author:"Casey Watts and Jeff Dickey",title:"CLI Flags Explained"},prevItem:{title:"oclifconf 2019: A Recap",permalink:"/blog/2019/09/16/oclifconf-recap"},nextItem:{title:"Introducing oclif",permalink:"/blog/2018/03/20/introducing-oclif"}},m={authorsImageUrls:[void 0]},d=[{value:"Parts of Speech",id:"parts-of-speech",level:2},{value:"Example ls",id:"example-ls",level:3},{value:"command",id:"command",level:4},{value:"argument",id:"argument",level:4},{value:"Long flag",id:"long-flag",level:4},{value:"Short flag",id:"short-flag",level:4},{value:"Flag arguments",id:"flag-arguments",level:4},{value:"Other Ways of Passing Data",id:"other-ways-of-passing-data",level:2},{value:"Designing a Command",id:"designing-a-command",level:2},{value:"argument",id:"argument-1",level:3},{value:"short flag with argument",id:"short-flag-with-argument",level:3},{value:"long flag with argument",id:"long-flag-with-argument",level:3},{value:"environment variable",id:"environment-variable",level:3},{value:"standard input",id:"standard-input",level:3},{value:"Command ergonomics",id:"command-ergonomics",level:2},{value:"Short flag vs long flag",id:"short-flag-vs-long-flag",level:3}],c={toc:d},g="wrapper";function u(e){var t=e.components,a=(0,r.Z)(e,l);return(0,o.kt)(g,(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"oclif")," makes it easy to create a command line interface (CLI) in node. Most commands have ",(0,o.kt)("strong",{parentName:"p"},"parameters"),' \u2014 also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.'),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Note the following describes GNU-style flags. Not all CLIs follow this convention, but it is the most commonly used.")),(0,o.kt)("h2",{id:"parts-of-speech"},"Parts of Speech"),(0,o.kt)("p",null,'Any command line interface command has a few standard "parts of speech". As a user of CLI tools, knowing these parts of speech can help you make fewer typos. It can also help you understand complex commands other people share with you more quickly. If you are designing a CLI tool it is even more important to understand these parts of speech, so you can come up with the most ergonomic interface for your users.'),(0,o.kt)("p",null,"Of the many ways you can pass data to a CLI command, three of them are ",(0,o.kt)("strong",{parentName:"p"},"parameters"),' that are always to the "right" of the command. The three types of parameters are ',(0,o.kt)("strong",{parentName:"p"},"argument"),", ",(0,o.kt)("strong",{parentName:"p"},"short flag"),", and ",(0,o.kt)("strong",{parentName:"p"},"long flag"),"."),(0,o.kt)("h3",{id:"example-ls"},"Example ",(0,o.kt)("inlineCode",{parentName:"h3"},"ls")),(0,o.kt)("p",null,"One of the most common and simplest unix commands is ",(0,o.kt)("inlineCode",{parentName:"p"},"ls"),' which "lists" the contents of a directory.'),(0,o.kt)("h4",{id:"command"},"command"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls\n")),(0,o.kt)("p",null,"This command ",(0,o.kt)("inlineCode",{parentName:"p"},"ls")," works on its own, as a standalone ",(0,o.kt)("strong",{parentName:"p"},"command"),". Without any parameters this command will list the contents of the current folder, using an implied ",(0,o.kt)("inlineCode",{parentName:"p"},".")," directory."),(0,o.kt)("h4",{id:"argument"},"argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls .\nls ~/code/some-repo-name\n")),(0,o.kt)("p",null,"If you pass a command ",(0,o.kt)("strong",{parentName:"p"},"argument")," to this command, like the directory name ",(0,o.kt)("inlineCode",{parentName:"p"},".")," (current folder) or ",(0,o.kt)("inlineCode",{parentName:"p"},"~/code/some-repo-name"),", it will list the contents of that directory instead."),(0,o.kt)("p",null,"An argument is anything to the right of a command that is not a flag. An argument can come before or after flags."),(0,o.kt)("h4",{id:"long-flag"},"Long flag"),(0,o.kt)("p",null,"To list additional files that are normally hidden (like ",(0,o.kt)("inlineCode",{parentName:"p"},"~/.bashrc"),"), you can use a flag on the ",(0,o.kt)("inlineCode",{parentName:"p"},"ls")," command. ",(0,o.kt)("inlineCode",{parentName:"p"},"ls --all")," is the ",(0,o.kt)("strong",{parentName:"p"},"long flag")," form. A long flag always uses a double dash, and it is always represented by multiple characters."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls --all\nls . --all\n")),(0,o.kt)("h4",{id:"short-flag"},"Short flag"),(0,o.kt)("p",null,"There is also a ",(0,o.kt)("strong",{parentName:"p"},"short flag")," form of this flag: ",(0,o.kt)("inlineCode",{parentName:"p"},"ls -a"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"a")," is short for ",(0,o.kt)("inlineCode",{parentName:"p"},"all")," in this case. A short flag always uses a single dash, and it is always represented by a single letter."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls -a\nls . -a\n")),(0,o.kt)("p",null,"Short flags can ",(0,o.kt)("strong",{parentName:"p"},"stack")," too, so you don't need a separate dash for each one. Order does not matter for these, unless passing a flag argument."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"ls -la\n")),(0,o.kt)("h4",{id:"flag-arguments"},"Flag arguments"),(0,o.kt)("p",null,"Many flags accept an ",(0,o.kt)("strong",{parentName:"p"},"option"),', which is a "flag argument" (as opposed to a "command argument"). In general a command\'s parameters can be in any order, but flags that accept options must have the option directly after the flag.'),(0,o.kt)("p",null,"For an example, here the ",(0,o.kt)("inlineCode",{parentName:"p"},"-x")," flag does not accept an option but the ",(0,o.kt)("inlineCode",{parentName:"p"},"-f")," flag does. ",(0,o.kt)("inlineCode",{parentName:"p"},"archive.tar")," is the option being passed to ",(0,o.kt)("inlineCode",{parentName:"p"},"-f"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"tar -x -f archive.tar\ntar -xf archive.tar\n")),(0,o.kt)("p",null,"A flag and its option can be separated by a space ",(0,o.kt)("inlineCode",{parentName:"p"}," ")," or an equals sign ",(0,o.kt)("inlineCode",{parentName:"p"},"="),". Interestingly, short flags (but not long flags) can even skip the space, although many people find it much easier to read with the space or equals sign."),(0,o.kt)("p",null,"These three are all valid and equivalent:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"tar -f archive.tar\ntar -f=archive.tar\ntar -farchive.tar\n")),(0,o.kt)("p",null,"Long flags must have a space or equals sign to separate the flag from its option."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"git log --pretty=oneline\ngit log --pretty oneline\n")),(0,o.kt)("h2",{id:"other-ways-of-passing-data"},"Other Ways of Passing Data"),(0,o.kt)("p",null,"We've covered ",(0,o.kt)("strong",{parentName:"p"},"parameters"),", which are ",(0,o.kt)("strong",{parentName:"p"},"arguments"),", ",(0,o.kt)("strong",{parentName:"p"},"short flags")," and ",(0,o.kt)("strong",{parentName:"p"},"long flags"),". There are two other ways to pass data to a command: ",(0,o.kt)("strong",{parentName:"p"},"environment variables"),' ("env vars"), or ',(0,o.kt)("strong",{parentName:"p"},"standard input"),' ("stdin"). These won\'t be covered in this blog post.'),(0,o.kt)("h2",{id:"designing-a-command"},"Designing a Command"),(0,o.kt)("p",null,'Scenario: we want to design an oclif command that echos an input like "Casey", and returns "hi, Casey!". There are many ways the user could pass this in, and here we show an example of each type of input.'),(0,o.kt)("h3",{id:"argument-1"},"argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me Casey\n")),(0,o.kt)("h3",{id:"short-flag-with-argument"},"short flag with argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me -n Casey\ngreet-me -n=Casey\ngreet-me -nCasey\n")),(0,o.kt)("h3",{id:"long-flag-with-argument"},"long flag with argument"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"greet-me --name=Casey\ngreet-me --name Casey\n")),(0,o.kt)("h3",{id:"environment-variable"},"environment variable"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"NAME=Casey greet-me\n")),(0,o.kt)("h3",{id:"standard-input"},"standard input"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'echo "Casey" | greet-me\n')),(0,o.kt)("h2",{id:"command-ergonomics"},"Command ergonomics"),(0,o.kt)("h3",{id:"short-flag-vs-long-flag"},"Short flag vs long flag"),(0,o.kt)("p",null,"Many CLI commands allow for both long flag and short flag forms. In the Heroku CLI every flag has at least a long flag form and roughly half of the flags also have a short flag form."),(0,o.kt)("p",null,"The long flag form is easier to read, but takes more characters to type. It is often most useful when you want someone to understand a particular command statement quickly and easily, such as in a README."),(0,o.kt)("p",null,"The short flag form is quicker to type, and is often better for frequently used commands. Short flags are especially useful when stacking short flags together."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1ed4142b.13082c5b.js b/assets/js/1ed4142b.13082c5b.js deleted file mode 100644 index eddfb01f..00000000 --- a/assets/js/1ed4142b.13082c5b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[3725],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=o.createContext({}),u=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=u(e.components);return o.createElement(s.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=u(n),d=i,f=c["".concat(s,".").concat(d)]||c[d]||m[d]||r;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:i,a[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>u,toc:()=>c});var o=n(7462),i=n(3366),r=(n(7294),n(3905)),a=["components"],l={title:"Just-in-Time Plugin Installation"},s=void 0,u={unversionedId:"jit_plugins",id:"jit_plugins",title:"Just-in-Time Plugin Installation",description:"Sometimes you might want to have a plugin that isn't bundled in your CLI but gets installed the first time it's executed by the user - we call this just-in-time plugin installation, or JIT for short. This can be useful if you need to reduce the package size of your CLI while still allowing users access to all the plugins.",source:"@site/../docs/jit_plugins.md",sourceDirName:".",slug:"/jit_plugins",permalink:"/docs/jit_plugins",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/jit_plugins.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Just-in-Time Plugin Installation"},sidebar:"docs",previous:{title:"Running Commands Programmatically",permalink:"/docs/running_programmatically"},next:{title:"Aliases",permalink:"/docs/aliases"}},p={},c=[],m={toc:c},d="wrapper";function f(e){var t=e.components,n=(0,i.Z)(e,a);return(0,r.kt)(d,(0,o.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Sometimes you might want to have a plugin that isn't bundled in your CLI but gets installed the first time it's executed by the user - we call this just-in-time plugin installation, or JIT for short. This can be useful if you need to reduce the package size of your CLI while still allowing users access to all the plugins."),(0,r.kt)("p",null,"To use this feature you need to:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Add ",(0,r.kt)("inlineCode",{parentName:"li"},"jitPlugins")," to the ",(0,r.kt)("inlineCode",{parentName:"li"},"oclif")," section of your package.json")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'"oclif": {\n "jitPlugins": {\n "my-plugin": "^1.2.3",\n "another-plugin": "^1.2.3",\n }\n}\n')),(0,r.kt)("ol",{start:2},(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Ensure that your build process includes generating a manifest using ",(0,r.kt)("inlineCode",{parentName:"p"},"oclif manifest"),". The manifest will include the information about all the commands owned by JIT plugins which allows users to run ",(0,r.kt)("inlineCode",{parentName:"p"},"--help")," on those commands without having them installed yet. ",(0,r.kt)("strong",{parentName:"p"},"If the generated manifest doesn't get packed with your CLI, then the feature will not work."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Implement the ",(0,r.kt)("inlineCode",{parentName:"p"},"jit_plugin_not_installed")," hook."))),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"@oclif/core")," attempts to be UX-agnostic, meaning that we don't want to impose any particular user experience on you. Any time a user experience is required we utilize hooks so that you can design the exact user experience you want your users to have."),(0,r.kt)("p",null,"In the case of JIT plugin installation, there are many possible user experiences that you might want - maybe you want to prompt the user for confirmation first, or maybe you want to log a specific message, etc..."),(0,r.kt)("p",null,"Here's an example of how you might implement the hook,"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import { Hook, CLIError, ux } from '@oclif/core';\n\nconst hook: Hook<'jit_plugin_not_installed'> = async function (opts) {\n try {\n const answer = await ux.confirm(`${opts.command.pluginName} not installed. Would you like to install?`)\n if (answer === 'y') {\n await opts.config.runCommand('plugins:install', [`${opts.command.pluginName}@${opts.pluginVersion}`]);\n }\n } catch (error) {\n throw new CLIError(`Could not install ${opts.command.pluginName}`, 'JitPluginInstallError');\n }\n};\n\nexport default hook;\n\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1ed4142b.4b6a7049.js b/assets/js/1ed4142b.4b6a7049.js new file mode 100644 index 00000000..2048092b --- /dev/null +++ b/assets/js/1ed4142b.4b6a7049.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[3725],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),u=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=u(e.components);return o.createElement(s.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=u(n),d=r,f=c["".concat(s,".").concat(d)]||c[d]||m[d]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:r,a[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>u,toc:()=>c});var o=n(7462),r=n(3366),i=(n(7294),n(3905)),a=["components"],l={title:"Just-in-Time Plugin Installation"},s=void 0,u={unversionedId:"jit_plugins",id:"jit_plugins",title:"Just-in-Time Plugin Installation",description:"Sometimes you might want to have a plugin that isn't bundled in your CLI but gets installed the first time it's executed by the user - we call this just-in-time plugin installation, or JIT for short. This can be useful if you need to reduce the package size of your CLI while still allowing users access to all the plugins.",source:"@site/../docs/jit_plugins.md",sourceDirName:".",slug:"/jit_plugins",permalink:"/docs/jit_plugins",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/jit_plugins.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Just-in-Time Plugin Installation"},sidebar:"docs",previous:{title:"Running Commands Programmatically",permalink:"/docs/running_programmatically"},next:{title:"Aliases",permalink:"/docs/aliases"}},p={},c=[],m={toc:c},d="wrapper";function f(e){var t=e.components,n=(0,r.Z)(e,a);return(0,i.kt)(d,(0,o.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Sometimes you might want to have a plugin that isn't bundled in your CLI but gets installed the first time it's executed by the user - we call this just-in-time plugin installation, or JIT for short. This can be useful if you need to reduce the package size of your CLI while still allowing users access to all the plugins."),(0,i.kt)("p",null,"To use this feature you need to:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Add ",(0,i.kt)("inlineCode",{parentName:"li"},"jitPlugins")," to the ",(0,i.kt)("inlineCode",{parentName:"li"},"oclif")," section of your package.json")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'"oclif": {\n "jitPlugins": {\n "my-plugin": "^1.2.3",\n "another-plugin": "^1.2.3",\n }\n}\n')),(0,i.kt)("ol",{start:2},(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Ensure that your build process includes generating a manifest using ",(0,i.kt)("inlineCode",{parentName:"p"},"oclif manifest"),". The manifest will include the information about all the commands owned by JIT plugins which allows users to run ",(0,i.kt)("inlineCode",{parentName:"p"},"--help")," on those commands without having them installed yet. ",(0,i.kt)("strong",{parentName:"p"},"If the generated manifest doesn't get packed with your CLI, then the feature will not work."))),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("p",{parentName:"li"},"Implement the ",(0,i.kt)("inlineCode",{parentName:"p"},"jit_plugin_not_installed")," hook."))),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"@oclif/core")," attempts to be UX-agnostic, meaning that we don't want to impose any particular user experience on you. Any time a user experience is required we utilize hooks so that you can design the exact user experience you want your users to have."),(0,i.kt)("p",null,"In the case of JIT plugin installation, there are many possible user experiences that you might want - maybe you want to prompt the user for confirmation first, or maybe you want to log a specific message, etc..."),(0,i.kt)("p",null,"Here's an example of how you might implement the hook,"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"import { Hook, CLIError, ux } from '@oclif/core';\n\nconst hook: Hook<'jit_plugin_not_installed'> = async function (opts) {\n try {\n const answer = await ux.confirm(`${opts.command.pluginName} not installed. Would you like to install?`)\n if (answer === 'y') {\n await opts.config.runCommand('plugins:install', [`${opts.command.pluginName}@${opts.pluginVersion}`]);\n }\n } catch (error) {\n throw new CLIError(`Could not install ${opts.command.pluginName}`, 'JitPluginInstallError');\n }\n};\n\nexport default hook;\n\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1f61ef73.2397de34.js b/assets/js/1f61ef73.2397de34.js deleted file mode 100644 index af1096b6..00000000 --- a/assets/js/1f61ef73.2397de34.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7006],{3905:(e,r,n)=>{n.d(r,{Zo:()=>d,kt:()=>m});var t=n(7294);function o(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function a(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function i(e){for(var r=1;r=0||(o[n]=e[n]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=t.createContext({}),s=function(e){var r=t.useContext(c),n=r;return e&&(n="function"==typeof e?e(r):i(i({},r),e)),n},d=function(e){var r=s(e.components);return t.createElement(c.Provider,{value:r},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},u=t.forwardRef((function(e,r){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),h=s(n),u=o,m=h["".concat(c,".").concat(u)]||h[u]||p[u]||a;return n?t.createElement(m,i(i({ref:r},d),{},{components:n})):t.createElement(m,i({ref:r},d))}));function m(e,r){var n=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=u;var l={};for(var c in r)hasOwnProperty.call(r,c)&&(l[c]=r[c]);l.originalType=e,l[h]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(r),n.d(r,{assets:()=>d,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>h});var t=n(7462),o=n(3366),a=(n(7294),n(3905)),i=["components"],l={title:"Error Handling"},c=void 0,s={unversionedId:"error_handling",id:"error_handling",title:"Error Handling",description:"oclif handles intentionally - and unintentionally - thrown errors in two places. First in the Command.catch method and then, finally, in the bin/run catch handler where the Error is printed and the CLI exits. This error flow makes it possible for you to control and respond to errors that occur in your CLI as you see fit.",source:"@site/../docs/error_handling.md",sourceDirName:".",slug:"/error_handling",permalink:"/docs/error_handling",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/error_handling.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Error Handling"},sidebar:"docs",previous:{title:"Help Classes",permalink:"/docs/help_classes"},next:{title:"JSON",permalink:"/docs/json"}},d={},h=[{value:"Error Handling in the catch method",id:"error-handling-in-the-catch-method",level:2},{value:"bin/run catch handler",id:"binrun-catch-handler",level:2}],p={toc:h},u="wrapper";function m(e){var r=e.components,n=(0,o.Z)(e,i);return(0,a.kt)(u,(0,t.Z)({},p,n,{components:r,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"oclif handles intentionally - and unintentionally - thrown errors in two places. First in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Command.catch")," method and then, finally, in the bin/run ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," handler where the Error is printed and the CLI exits. This error flow makes it possible for you to control and respond to errors that occur in your CLI as you see fit."),(0,a.kt)("h2",{id:"error-handling-in-the-catch-method"},"Error Handling in the ",(0,a.kt)("inlineCode",{parentName:"h2"},"catch")," method"),(0,a.kt)("p",null,"Every ",(0,a.kt)("inlineCode",{parentName:"p"},"Command")," instance has a ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," method that is called when an error occurs throughout the course of a command run. This method handles the edge case of users asking for help or version output, if applicable, otherwise, it re-throws the error. You can extend or overwrite the ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," method in your command class."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import {Command, flags} from '@oclif/core'\n\nexport default class Hello extends Command {\n async catch(error) {\n // do something or\n // re-throw to be handled globally\n throw error;\n }\n}\n")),(0,a.kt)("p",null,"If this type of error handling is being implemented across multiple commands consider using a Custom Base Class (",(0,a.kt)("a",{parentName:"p",href:"https://oclif.io/docs/base_class#docsNav"},"https://oclif.io/docs/base_class#docsNav"),") for your commands and overriding the ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," method."),(0,a.kt)("h2",{id:"binrun-catch-handler"},"bin/run ",(0,a.kt)("inlineCode",{parentName:"h2"},"catch")," handler"),(0,a.kt)("p",null,"Every oclif CLI has a ./bin/run file that is the entry point of command invocation. Errors that occur in the CLI, including re-thrown errors from a Command, are caught here in the bin/run ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," handler."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},".catch(require('@oclif/core/handle'))\n")),(0,a.kt)("p",null,"This catch handler uses the ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/errors/handle")," function to display (and cleanup, if necessary) the error to the user. This handler can be swapped for any function that receives an error argument."),(0,a.kt)("p",null,"If you chose to implement your own handler here, we still recommend you delegate finally to the ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/core/handle")," function for clean-up and exiting logic."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},".catch((error) => {\n const oclifHandler = require('@oclif/core/handle');\n // do any extra work with error\n return oclifHandler(error);\n})\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1f61ef73.8b6eae52.js b/assets/js/1f61ef73.8b6eae52.js new file mode 100644 index 00000000..e11ec7e3 --- /dev/null +++ b/assets/js/1f61ef73.8b6eae52.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7006],{3905:(e,r,n)=>{n.d(r,{Zo:()=>d,kt:()=>m});var t=n(7294);function o(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function a(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function i(e){for(var r=1;r=0||(o[n]=e[n]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=t.createContext({}),s=function(e){var r=t.useContext(c),n=r;return e&&(n="function"==typeof e?e(r):i(i({},r),e)),n},d=function(e){var r=s(e.components);return t.createElement(c.Provider,{value:r},e.children)},h="mdxType",p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},u=t.forwardRef((function(e,r){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),h=s(n),u=o,m=h["".concat(c,".").concat(u)]||h[u]||p[u]||a;return n?t.createElement(m,i(i({ref:r},d),{},{components:n})):t.createElement(m,i({ref:r},d))}));function m(e,r){var n=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=u;var l={};for(var c in r)hasOwnProperty.call(r,c)&&(l[c]=r[c]);l.originalType=e,l[h]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(r),n.d(r,{assets:()=>d,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>h});var t=n(7462),o=n(3366),a=(n(7294),n(3905)),i=["components"],l={title:"Error Handling"},c=void 0,s={unversionedId:"error_handling",id:"error_handling",title:"Error Handling",description:"oclif handles intentionally - and unintentionally - thrown errors in two places. First in the Command.catch method and then, finally, in the bin/run catch handler where the Error is printed and the CLI exits. This error flow makes it possible for you to control and respond to errors that occur in your CLI as you see fit.",source:"@site/../docs/error_handling.md",sourceDirName:".",slug:"/error_handling",permalink:"/docs/error_handling",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/error_handling.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Error Handling"},sidebar:"docs",previous:{title:"Help Classes",permalink:"/docs/help_classes"},next:{title:"JSON",permalink:"/docs/json"}},d={},h=[{value:"Error Handling in the catch method",id:"error-handling-in-the-catch-method",level:2},{value:"bin/run catch handler",id:"binrun-catch-handler",level:2}],p={toc:h},u="wrapper";function m(e){var r=e.components,n=(0,o.Z)(e,i);return(0,a.kt)(u,(0,t.Z)({},p,n,{components:r,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"oclif handles intentionally - and unintentionally - thrown errors in two places. First in the ",(0,a.kt)("inlineCode",{parentName:"p"},"Command.catch")," method and then, finally, in the bin/run ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," handler where the Error is printed and the CLI exits. This error flow makes it possible for you to control and respond to errors that occur in your CLI as you see fit."),(0,a.kt)("h2",{id:"error-handling-in-the-catch-method"},"Error Handling in the ",(0,a.kt)("inlineCode",{parentName:"h2"},"catch")," method"),(0,a.kt)("p",null,"Every ",(0,a.kt)("inlineCode",{parentName:"p"},"Command")," instance has a ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," method that is called when an error occurs throughout the course of a command run. This method handles the edge case of users asking for help or version output, if applicable, otherwise, it re-throws the error. You can extend or overwrite the ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," method in your command class."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import {Command, flags} from '@oclif/core'\n\nexport default class Hello extends Command {\n async catch(error) {\n // do something or\n // re-throw to be handled globally\n throw error;\n }\n}\n")),(0,a.kt)("p",null,"If this type of error handling is being implemented across multiple commands consider using a Custom Base Class (",(0,a.kt)("a",{parentName:"p",href:"https://oclif.io/docs/base_class#docsNav"},"https://oclif.io/docs/base_class#docsNav"),") for your commands and overriding the ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," method."),(0,a.kt)("h2",{id:"binrun-catch-handler"},"bin/run ",(0,a.kt)("inlineCode",{parentName:"h2"},"catch")," handler"),(0,a.kt)("p",null,"Every oclif CLI has a ./bin/run file that is the entry point of command invocation. Errors that occur in the CLI, including re-thrown errors from a Command, are caught here in the bin/run ",(0,a.kt)("inlineCode",{parentName:"p"},"catch")," handler."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},".catch(require('@oclif/core/handle'))\n")),(0,a.kt)("p",null,"This catch handler uses the ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/errors/handle")," function to display (and cleanup, if necessary) the error to the user. This handler can be swapped for any function that receives an error argument."),(0,a.kt)("p",null,"If you chose to implement your own handler here, we still recommend you delegate finally to the ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/core/handle")," function for clean-up and exiting logic."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},".catch((error) => {\n const oclifHandler = require('@oclif/core/handle');\n // do any extra work with error\n return oclifHandler(error);\n})\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2486267b.7647b51d.js b/assets/js/2486267b.7647b51d.js deleted file mode 100644 index a9d6c033..00000000 --- a/assets/js/2486267b.7647b51d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9562],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>f,frontMatter:()=>s,metadata:()=>p,toc:()=>u});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),i=["components"],s={title:"Spinner"},c=void 0,p={unversionedId:"spinner",id:"spinner",title:"Spinner",description:"@oclif/core provides a simple ux.action, for more complex progress indicators we recommend using the listr library.",source:"@site/../docs/spinner.md",sourceDirName:".",slug:"/spinner",permalink:"/docs/spinner",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/spinner.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Spinner"},sidebar:"docs",previous:{title:"Prompting",permalink:"/docs/prompting"},next:{title:"Table",permalink:"/docs/table"}},l={},u=[{value:"ux.action",id:"uxaction",level:2},{value:"listr",id:"listr",level:2}],d={toc:u},m="wrapper";function f(e){var t=e.components,s=(0,o.Z)(e,i);return(0,a.kt)(m,(0,n.Z)({},d,s,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core"},"@oclif/core")," provides a simple ",(0,a.kt)("inlineCode",{parentName:"p"},"ux.action"),", for more complex progress indicators we recommend using the ",(0,a.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/listr"},"listr")," library."),(0,a.kt)("h2",{id:"uxaction"},(0,a.kt)("inlineCode",{parentName:"h2"},"ux.action")),(0,a.kt)("p",null,"Shows a basic spinner"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, ux} from '@oclif/core'\n\nexport class MyCommand extends Command {\n async run() {\n // start the spinner\n ux.action.start('starting a process')\n // do some action...\n // stop the spinner\n ux.action.stop() // shows 'starting a process... done'\n\n // show on stdout instead of stderr\n ux.action.start('starting a process', 'initializing', {stdout: true})\n // do some action...\n // stop the spinner with a custom message\n ux.action.stop('custom message') // shows 'starting a process... custom message'\n }\n}\n")),(0,a.kt)("p",null,"This degrades gracefully when not connected to a TTY. It queues up any writes to stdout/stderr so they are displayed above the spinner."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"action demo",src:r(1305).Z,width:"563",height:"271"})),(0,a.kt)("h2",{id:"listr"},"listr"),(0,a.kt)("p",null,"Here is an example of the complex workflows supported by ",(0,a.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/listr"},"listr"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"listr demo",src:r(3220).Z,width:"1177",height:"709"})))}f.isMDXComponent=!0},1305:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/action-3dc2f1c9da2526e7dacc7ba55a2e3f5a.gif"},3220:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/listr-fb034a43c5d3159c331547ffba3b6559.gif"}}]); \ No newline at end of file diff --git a/assets/js/2486267b.9e4c7cc3.js b/assets/js/2486267b.9e4c7cc3.js new file mode 100644 index 00000000..a2a23da4 --- /dev/null +++ b/assets/js/2486267b.9e4c7cc3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9562],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>f,frontMatter:()=>s,metadata:()=>p,toc:()=>u});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),i=["components"],s={title:"Spinner"},c=void 0,p={unversionedId:"spinner",id:"spinner",title:"Spinner",description:"@oclif/core provides a simple ux.action, for more complex progress indicators we recommend using the listr library.",source:"@site/../docs/spinner.md",sourceDirName:".",slug:"/spinner",permalink:"/docs/spinner",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/spinner.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Spinner"},sidebar:"docs",previous:{title:"Prompting",permalink:"/docs/prompting"},next:{title:"Table",permalink:"/docs/table"}},l={},u=[{value:"ux.action",id:"uxaction",level:2},{value:"listr",id:"listr",level:2}],d={toc:u},m="wrapper";function f(e){var t=e.components,s=(0,o.Z)(e,i);return(0,a.kt)(m,(0,r.Z)({},d,s,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core"},"@oclif/core")," provides a simple ",(0,a.kt)("inlineCode",{parentName:"p"},"ux.action"),", for more complex progress indicators we recommend using the ",(0,a.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/listr"},"listr")," library."),(0,a.kt)("h2",{id:"uxaction"},(0,a.kt)("inlineCode",{parentName:"h2"},"ux.action")),(0,a.kt)("p",null,"Shows a basic spinner"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, ux} from '@oclif/core'\n\nexport class MyCommand extends Command {\n async run() {\n // start the spinner\n ux.action.start('starting a process')\n // do some action...\n // stop the spinner\n ux.action.stop() // shows 'starting a process... done'\n\n // show on stdout instead of stderr\n ux.action.start('starting a process', 'initializing', {stdout: true})\n // do some action...\n // stop the spinner with a custom message\n ux.action.stop('custom message') // shows 'starting a process... custom message'\n }\n}\n")),(0,a.kt)("p",null,"This degrades gracefully when not connected to a TTY. It queues up any writes to stdout/stderr so they are displayed above the spinner."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"action demo",src:n(1305).Z,width:"563",height:"271"})),(0,a.kt)("h2",{id:"listr"},"listr"),(0,a.kt)("p",null,"Here is an example of the complex workflows supported by ",(0,a.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/listr"},"listr"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"listr demo",src:n(3220).Z,width:"1177",height:"709"})))}f.isMDXComponent=!0},1305:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/action-3dc2f1c9da2526e7dacc7ba55a2e3f5a.gif"},3220:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/listr-fb034a43c5d3159c331547ffba3b6559.gif"}}]); \ No newline at end of file diff --git a/assets/js/258a6413.6fec9b6b.js b/assets/js/258a6413.4357bd3d.js similarity index 73% rename from assets/js/258a6413.6fec9b6b.js rename to assets/js/258a6413.4357bd3d.js index 4a9014e5..32e58135 100644 --- a/assets/js/258a6413.6fec9b6b.js +++ b/assets/js/258a6413.4357bd3d.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2265],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),p=s(n),d=o,f=p["".concat(c,".").concat(d)]||p[d]||u[d]||a;return n?r.createElement(f,i(i({ref:t},m),{},{components:n})):r.createElement(f,i({ref:t},m))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>m,contentTitle:()=>c,default:()=>f,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),i=["components"],l={title:"Single Command CLI"},c=void 0,s={unversionedId:"single_command_cli",id:"single_command_cli",title:"Single Command CLI",description:"Sometimes you may want your CLI's executable to also be the only command, similar to many bash utilities like ls or cat.",source:"@site/../docs/single_command_cli.md",sourceDirName:".",slug:"/single_command_cli",permalink:"/docs/single_command_cli",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/single_command_cli.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Single Command CLI"},sidebar:"docs",previous:{title:"Global Flags",permalink:"/docs/global_flags"},next:{title:"ESM",permalink:"/docs/esm"}},m={},p=[],u={toc:p},d="wrapper";function f(e){var t=e.components,n=(0,o.Z)(e,i);return(0,a.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Sometimes you may want your CLI's executable to also be the only command, similar to many bash utilities like ",(0,a.kt)("inlineCode",{parentName:"p"},"ls")," or ",(0,a.kt)("inlineCode",{parentName:"p"},"cat"),"."),(0,a.kt)("p",null,"To support this, you will need to put your command logic into ",(0,a.kt)("inlineCode",{parentName:"p"},"src/index.ts")," and add the following to the oclif section of your package.json:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'oclif: {\n default: ".",\n commands: "./dist"\n}\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2265],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),p=s(n),d=o,f=p["".concat(c,".").concat(d)]||p[d]||u[d]||a;return n?r.createElement(f,i(i({ref:t},m),{},{components:n})):r.createElement(f,i({ref:t},m))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>m,contentTitle:()=>c,default:()=>f,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),i=["components"],l={title:"Single Command CLI"},c=void 0,s={unversionedId:"single_command_cli",id:"single_command_cli",title:"Single Command CLI",description:"Sometimes you may want your CLI's executable to also be the only command, similar to many bash utilities like ls or cat.",source:"@site/../docs/single_command_cli.md",sourceDirName:".",slug:"/single_command_cli",permalink:"/docs/single_command_cli",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/single_command_cli.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Single Command CLI"},sidebar:"docs",previous:{title:"Global Flags",permalink:"/docs/global_flags"},next:{title:"ESM",permalink:"/docs/esm"}},m={},p=[],u={toc:p},d="wrapper";function f(e){var t=e.components,n=(0,o.Z)(e,i);return(0,a.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Sometimes you may want your CLI's executable to also be the only command, similar to many bash utilities like ",(0,a.kt)("inlineCode",{parentName:"p"},"ls")," or ",(0,a.kt)("inlineCode",{parentName:"p"},"cat"),"."),(0,a.kt)("p",null,"To support this, you will need to put your command logic into ",(0,a.kt)("inlineCode",{parentName:"p"},"src/index.ts")," and add the following to the oclif section of your package.json:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'oclif: {\n default: ".",\n commands: "./dist"\n}\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2a33acc4.fad2e0ce.js b/assets/js/2a33acc4.e8bf0b44.js similarity index 61% rename from assets/js/2a33acc4.fad2e0ce.js rename to assets/js/2a33acc4.e8bf0b44.js index 13795e97..81ca4b18 100644 --- a/assets/js/2a33acc4.fad2e0ce.js +++ b/assets/js/2a33acc4.e8bf0b44.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9244],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=p(n),f=o,m=d["".concat(s,".").concat(f)]||d[f]||u[f]||i;return n?r.createElement(m,a(a({ref:t},l),{},{components:n})):r.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:o,a[1]=c;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>m,frontMatter:()=>c,metadata:()=>p,toc:()=>d});var r=n(7462),o=n(3366),i=(n(7294),n(3905)),a=["components"],c={title:"Topics"},s=void 0,p={unversionedId:"topics",id:"topics",title:"Topics",description:"As CLIs grow it can be useful to nest commands within topics. This is supported simply by placing command files in subdirectories. For example, with the Salesforce CLI we have a topic sf config with commands like sf config set and sf config get. The directory structure looks like this:",source:"@site/../docs/topics.md",sourceDirName:".",slug:"/topics",permalink:"/docs/topics",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/topics.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Topics"},sidebar:"docs",previous:{title:"Configuration",permalink:"/docs/config"},next:{title:"Topic Separators",permalink:"/docs/topic_separator"}},l={},d=[],u={toc:d},f="wrapper";function m(e){var t=e.components,n=(0,o.Z)(e,a);return(0,i.kt)(f,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"As CLIs grow it can be useful to nest commands within topics. This is supported simply by placing command files in subdirectories. For example, with the Salesforce CLI we have a topic ",(0,i.kt)("inlineCode",{parentName:"p"},"sf config")," with commands like ",(0,i.kt)("inlineCode",{parentName:"p"},"sf config set")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"sf config get"),". The directory structure looks like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"package.json\nsrc/\n\u2514\u2500\u2500 commands/\n \u2514\u2500\u2500 config/\n \xa0 \u251c\u2500\u2500 index.ts\n \xa0\xa0\u251c\u2500\u2500 set.ts\n \xa0\xa0 \u2514\u2500\u2500 get.ts\n")),(0,i.kt)("p",null,"The help descriptions will be the description of the first command within a directory. If you'd like to customize the help description, add it to the ",(0,i.kt)("inlineCode",{parentName:"p"},"package.json")," like so:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},'{\n "oclif": {\n "topics": {\n "apps:favorites": { "description": "manage favorite apps" },\n "config": { "description": "manage heroku config variables" },\n }\n }\n}\n')),(0,i.kt)("p",null,"Subtopics can be created by making subdirectories within topic directories, but for UX reasons we generally discourage going more than 1 or 2 levels deep even for the largest CLIs."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9244],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=p(n),f=o,m=d["".concat(s,".").concat(f)]||d[f]||u[f]||i;return n?r.createElement(m,a(a({ref:t},l),{},{components:n})):r.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:o,a[1]=c;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>m,frontMatter:()=>c,metadata:()=>p,toc:()=>d});var r=n(7462),o=n(3366),i=(n(7294),n(3905)),a=["components"],c={title:"Topics"},s=void 0,p={unversionedId:"topics",id:"topics",title:"Topics",description:"As CLIs grow it can be useful to nest commands within topics. This is supported simply by placing command files in subdirectories. For example, with the Salesforce CLI we have a topic sf config with commands like sf config set and sf config get. The directory structure looks like this:",source:"@site/../docs/topics.md",sourceDirName:".",slug:"/topics",permalink:"/docs/topics",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/topics.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Topics"},sidebar:"docs",previous:{title:"Configuration",permalink:"/docs/config"},next:{title:"Topic Separators",permalink:"/docs/topic_separator"}},l={},d=[],u={toc:d},f="wrapper";function m(e){var t=e.components,n=(0,o.Z)(e,a);return(0,i.kt)(f,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"As CLIs grow it can be useful to nest commands within topics. This is supported simply by placing command files in subdirectories. For example, with the Salesforce CLI we have a topic ",(0,i.kt)("inlineCode",{parentName:"p"},"sf config")," with commands like ",(0,i.kt)("inlineCode",{parentName:"p"},"sf config set")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"sf config get"),". The directory structure looks like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"package.json\nsrc/\n\u2514\u2500\u2500 commands/\n \u2514\u2500\u2500 config/\n \xa0 \u251c\u2500\u2500 index.ts\n \xa0\xa0\u251c\u2500\u2500 set.ts\n \xa0\xa0 \u2514\u2500\u2500 get.ts\n")),(0,i.kt)("p",null,"The help descriptions will be the description of the first command within a directory. If you'd like to customize the help description, add it to the ",(0,i.kt)("inlineCode",{parentName:"p"},"package.json")," like so:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},'{\n "oclif": {\n "topics": {\n "apps:favorites": { "description": "manage favorite apps" },\n "config": { "description": "manage heroku config variables" },\n }\n }\n}\n')),(0,i.kt)("p",null,"Subtopics can be created by making subdirectories within topic directories, but for UX reasons we generally discourage going more than 1 or 2 levels deep even for the largest CLIs."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2f98ad87.4b5209da.js b/assets/js/2f98ad87.4b5209da.js deleted file mode 100644 index 42acad0d..00000000 --- a/assets/js/2f98ad87.4b5209da.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2048],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>u});var r=t(7294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=r.createContext({}),m=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=m(e.components);return r.createElement(l.Provider,{value:n},e.children)},d="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},s=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=m(t),s=o,u=d["".concat(l,".").concat(s)]||d[s]||f[s]||a;return t?r.createElement(u,i(i({ref:n},p),{},{components:t})):r.createElement(u,i({ref:n},p))}));function u(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=s;var c={};for(var l in n)hasOwnProperty.call(n,l)&&(c[l]=n[l]);c.originalType=e,c[d]="string"==typeof e?e:o,i[1]=c;for(var m=2;m{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>u,frontMatter:()=>c,metadata:()=>m,toc:()=>d});var r=t(7462),o=t(3366),a=(t(7294),t(3905)),i=["components"],c={title:"Generator Commands"},l=void 0,m={unversionedId:"generator_commands",id:"generator_commands",title:"Generator Commands",description:"- oclif generate NAME",source:"@site/../docs/generator_commands.md",sourceDirName:".",slug:"/generator_commands",permalink:"/docs/generator_commands",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/generator_commands.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Generator Commands"},sidebar:"docs",previous:{title:"FAQs",permalink:"/docs/faqs"},next:{title:"Command Execution",permalink:"/docs/command_execution"}},p={},d=[{value:"oclif generate NAME",id:"oclif-generate-name",level:2},{value:"oclif generate command NAME",id:"oclif-generate-command-name",level:2},{value:"oclif generate hook NAME",id:"oclif-generate-hook-name",level:2}],f={toc:d},s="wrapper";function u(e){var n=e.components,t=(0,o.Z)(e,i);return(0,a.kt)(s,(0,r.Z)({},f,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#oclif-generate-name"},(0,a.kt)("inlineCode",{parentName:"a"},"oclif generate NAME"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#oclif-generate-command-name"},(0,a.kt)("inlineCode",{parentName:"a"},"oclif generate command NAME"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#oclif-generate-hook-name"},(0,a.kt)("inlineCode",{parentName:"a"},"oclif generate hook NAME")))),(0,a.kt)("h2",{id:"oclif-generate-name"},(0,a.kt)("inlineCode",{parentName:"h2"},"oclif generate NAME")),(0,a.kt)("p",null,"generate a new CLI"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"USAGE\n $ oclif generate [NAME]\n\nARGUMENTS\n NAME directory name of new project\n\nDESCRIPTION\n generate a new CLI\n\n This will clone the template repo 'oclif/hello-world' and update package properties\n")),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"See code: ",(0,a.kt)("a",{parentName:"em",href:"https://github.com/oclif/oclif/blob/v2.2.0/src/commands/generate.ts"},"src/commands/generate.ts"))),(0,a.kt)("h2",{id:"oclif-generate-command-name"},(0,a.kt)("inlineCode",{parentName:"h2"},"oclif generate command NAME")),(0,a.kt)("p",null,"add a command to an existing CLI or plugin"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"USAGE\n $ oclif generate command [NAME] [--force]\n\nARGUMENTS\n NAME name of command\n\nFLAGS\n --force overwrite existing files\n\nDESCRIPTION\n add a command to an existing CLI or plugin\n")),(0,a.kt)("h2",{id:"oclif-generate-hook-name"},(0,a.kt)("inlineCode",{parentName:"h2"},"oclif generate hook NAME")),(0,a.kt)("p",null,"add a hook to an existing CLI or plugin"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"USAGE\n $ oclif generate hook [NAME] [--force] [--event ]\n\nARGUMENTS\n NAME name of hook (snake_case)\n\nFLAGS\n --event= [default: init] event to run hook on\n --force overwrite existing files\n\nDESCRIPTION\n add a hook to an existing CLI or plugin\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2f98ad87.b23bda82.js b/assets/js/2f98ad87.b23bda82.js new file mode 100644 index 00000000..d1a62951 --- /dev/null +++ b/assets/js/2f98ad87.b23bda82.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2048],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>u});var r=t(7294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=r.createContext({}),m=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=m(e.components);return r.createElement(l.Provider,{value:n},e.children)},d="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},s=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=m(t),s=o,u=d["".concat(l,".").concat(s)]||d[s]||f[s]||a;return t?r.createElement(u,i(i({ref:n},p),{},{components:t})):r.createElement(u,i({ref:n},p))}));function u(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=s;var c={};for(var l in n)hasOwnProperty.call(n,l)&&(c[l]=n[l]);c.originalType=e,c[d]="string"==typeof e?e:o,i[1]=c;for(var m=2;m{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>u,frontMatter:()=>c,metadata:()=>m,toc:()=>d});var r=t(7462),o=t(3366),a=(t(7294),t(3905)),i=["components"],c={title:"Generator Commands"},l=void 0,m={unversionedId:"generator_commands",id:"generator_commands",title:"Generator Commands",description:"- oclif generate NAME",source:"@site/../docs/generator_commands.md",sourceDirName:".",slug:"/generator_commands",permalink:"/docs/generator_commands",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/generator_commands.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Generator Commands"},sidebar:"docs",previous:{title:"FAQs",permalink:"/docs/faqs"},next:{title:"Command Execution",permalink:"/docs/command_execution"}},p={},d=[{value:"oclif generate NAME",id:"oclif-generate-name",level:2},{value:"oclif generate command NAME",id:"oclif-generate-command-name",level:2},{value:"oclif generate hook NAME",id:"oclif-generate-hook-name",level:2}],f={toc:d},s="wrapper";function u(e){var n=e.components,t=(0,o.Z)(e,i);return(0,a.kt)(s,(0,r.Z)({},f,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#oclif-generate-name"},(0,a.kt)("inlineCode",{parentName:"a"},"oclif generate NAME"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#oclif-generate-command-name"},(0,a.kt)("inlineCode",{parentName:"a"},"oclif generate command NAME"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#oclif-generate-hook-name"},(0,a.kt)("inlineCode",{parentName:"a"},"oclif generate hook NAME")))),(0,a.kt)("h2",{id:"oclif-generate-name"},(0,a.kt)("inlineCode",{parentName:"h2"},"oclif generate NAME")),(0,a.kt)("p",null,"generate a new CLI"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"USAGE\n $ oclif generate [NAME]\n\nARGUMENTS\n NAME directory name of new project\n\nDESCRIPTION\n generate a new CLI\n\n This will clone the template repo 'oclif/hello-world' and update package properties\n")),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"See code: ",(0,a.kt)("a",{parentName:"em",href:"https://github.com/oclif/oclif/blob/v2.2.0/src/commands/generate.ts"},"src/commands/generate.ts"))),(0,a.kt)("h2",{id:"oclif-generate-command-name"},(0,a.kt)("inlineCode",{parentName:"h2"},"oclif generate command NAME")),(0,a.kt)("p",null,"add a command to an existing CLI or plugin"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"USAGE\n $ oclif generate command [NAME] [--force]\n\nARGUMENTS\n NAME name of command\n\nFLAGS\n --force overwrite existing files\n\nDESCRIPTION\n add a command to an existing CLI or plugin\n")),(0,a.kt)("h2",{id:"oclif-generate-hook-name"},(0,a.kt)("inlineCode",{parentName:"h2"},"oclif generate hook NAME")),(0,a.kt)("p",null,"add a hook to an existing CLI or plugin"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"USAGE\n $ oclif generate hook [NAME] [--force] [--event ]\n\nARGUMENTS\n NAME name of hook (snake_case)\n\nFLAGS\n --event= [default: init] event to run hook on\n --force overwrite existing files\n\nDESCRIPTION\n add a hook to an existing CLI or plugin\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3042343a.9579178d.js b/assets/js/3042343a.9579178d.js deleted file mode 100644 index 0f4309cc..00000000 --- a/assets/js/3042343a.9579178d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5917],{3905:(e,a,n)=>{n.d(a,{Zo:()=>c,kt:()=>g});var t=n(7294);function l(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function r(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var a=1;a=0||(l[n]=e[n]);return l}(e,a);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var i=t.createContext({}),f=function(e){var a=t.useContext(i),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},c=function(e){var a=f(e.components);return t.createElement(i.Provider,{value:a},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},p=t.forwardRef((function(e,a){var n=e.components,l=e.mdxType,r=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=f(n),p=l,g=m["".concat(i,".").concat(p)]||m[p]||u[p]||r;return n?t.createElement(g,o(o({ref:a},c),{},{components:n})):t.createElement(g,o({ref:a},c))}));function g(e,a){var n=arguments,l=a&&a.mdxType;if("string"==typeof e||l){var r=n.length,o=new Array(r);o[0]=p;var s={};for(var i in a)hasOwnProperty.call(a,i)&&(s[i]=a[i]);s.originalType=e,s[m]="string"==typeof e?e:l,o[1]=s;for(var f=2;f{n.r(a),n.d(a,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>s,metadata:()=>f,toc:()=>m});var t=n(7462),l=n(3366),r=(n(7294),n(3905)),o=["components"],s={title:"Command Flags"},i=void 0,f={unversionedId:"flags",id:"flags",title:"Command Flags",description:"Flag options are non-positional arguments passed to the command. Flags can either be option flags which take an argument, or boolean flags which do not. An option flag must have an argument.",source:"@site/../docs/flags.md",sourceDirName:".",slug:"/flags",permalink:"/docs/flags",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/flags.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Command Flags"},sidebar:"docs",previous:{title:"Command Arguments",permalink:"/docs/args"},next:{title:"Configuration",permalink:"/docs/config"}},c={},m=[{value:"Custom Flags",id:"custom-flags",level:2},{value:"Alternative Flag Inputs",id:"alternative-flag-inputs",level:2}],u={toc:m},p="wrapper";function g(e){var a=e.components,n=(0,l.Z)(e,o);return(0,r.kt)(p,(0,t.Z)({},u,n,{components:a,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Flag options are non-positional arguments passed to the command. Flags can either be option flags which take an argument, or boolean flags which do not. An option flag must have an argument."),(0,r.kt)("p",null,"For example, if this command was run like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ mycli --force --file=./myfile\n")),(0,r.kt)("p",null,"It would be declared like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"import {Command, Flags} from '@oclif/core'\n\nexport class MyCLI extends Command {\n static flags = {\n // can pass either --force or -f\n force: Flags.boolean({char: 'f'}),\n file: Flags.string(),\n }\n\n async run() {\n const {flags} = await this.parse(MyCLI)\n if (flags.force) console.log('--force is set')\n if (flags.file) console.log(`--file is: ${flags.file}`)\n }\n}\n")),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"oclif supports a wide range of ",(0,r.kt)("a",{parentName:"em",href:"#alternative-flag-inputs"},"alternative flag inputs"),".")),(0,r.kt)("p",null,"Here are the options flags can have:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"static flags = {\n name: Flags.string({\n char: 'n', // shorter flag version\n summary: 'brief summary', // help summary for flag\n helpGroup: 'THE BEST FLAGS', // Put flag into THE BEST FLAGS group in help\n description: 'in-depth overview', // help description for flag\n hidden: false, // hide from help\n multiple: false, // allow setting this flag multiple times\n env: 'MY_NAME', // default to value of environment variable\n options: ['a', 'b'], // only allow the value to be from a discrete set\n parse: async input => 'output', // instead of the user input, return a different value\n default: 'world', // default value if flag not passed (can be an async function that returns a string or undefined)\n required: false, // make flag required\n aliases: ['username', 'u'], // aliases for the flag - can be short char or long flags\n deprecateAliases: false, // emit deprecation warning anytime a flag alias is provided\n dependsOn: ['extra-flag'], // this flag requires another flag\n exclusive: ['extra-flag'], // this flag cannot be specified alongside this other flag\n exactlyOne: ['extra-flag', 'another-flag'], // exactly one of these flags must be provided\n relationships: [ // define complex relationships between flags\n // Make this flag dependent on all of these flags\n {type: 'all', flags: ['flag-one', 'flag-two']}\n // Make this flag dependent on at least one of these flags\n {type: 'some', flags: ['flag-three', 'flag-four']}\n // Make this flag exclusive of all these flags\n {type: 'none', flags: ['flag-five', 'flag-six']}\n\n // Make this flag dependent on all of these flags\n {type: 'all', flags: [\n 'flag-one',\n 'flag-two',\n // Include flag-seven but only when flag-eight is equal to FooBar\n {name: 'flag-seven', when: async (flags) => flags['flag-eight'] === 'FooBar'}\n ]}\n ]\n }),\n\n // flag with no value (-f, --force)\n force: Flags.boolean({\n char: 'f', // short character for flag\n default: true, // default value if flag not passed (can be a function that returns a boolean)\n env: 'MY_NAME', // default value to the value of an environment variable\n // boolean flags may be reversed with `--no-` (in this case: `--no-force`).\n // The flag will be set to false if reversed. This functionality\n // is disabled by default, to enable it:\n // allowNo: true\n }),\n}\n")),(0,r.kt)("h2",{id:"custom-flags"},"Custom Flags"),(0,r.kt)("p",null,"For larger CLIs, it can be useful to declare a custom flag that can be shared amongst multiple commands. Here is an example of a custom flag:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"// src/flags.ts\nimport {Flags} from '@oclif/core'\n\nclass Team {\n public name: string;\n // etc...\n}\n\nfunction getTeam(): Promise {\n // imagine this reads a configuration file or something to find the team\n return new Team()\n}\n\nexport const team = Flags.custom({\n char: 't',\n description: 'team to use',\n default: () => getTeam(),\n})\n\n// src/commands/mycommand.ts\nimport {team} from '../flags'\nimport {Command} from '@oclif/core'\n\nexport class MyCLI extends Command {\n static flags = {\n team: team(),\n }\n\n async run() {\n const {flags} = await this.parse(MyCLI)\n if (flags.team) console.log(`--team is ${flags.team.name}`)\n }\n}\n")),(0,r.kt)("p",null,"In the Salesforce CLI we make heavy use of custom flags. For example,"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A ",(0,r.kt)("a",{parentName:"li",href:"https://salesforcecli.github.io/sf-plugins-core/functions/flags_salesforceId.salesforceIdFlag.html"},(0,r.kt)("inlineCode",{parentName:"a"},"salesforceId"))," flag that ensures the provided string is a valid Salesforce Id."),(0,r.kt)("li",{parentName:"ul"},"A ",(0,r.kt)("a",{parentName:"li",href:"https://salesforcecli.github.io/sf-plugins-core/functions/flags_duration.durationFlag.html"},(0,r.kt)("inlineCode",{parentName:"a"},"duration"))," flag that converts a provided integer into a ",(0,r.kt)("inlineCode",{parentName:"li"},"Duration")," instance that we use for working with time based values.")),(0,r.kt)("p",null,"These and more are located ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/salesforcecli/sf-plugins-core/tree/main/src/flags"},"here")," if you want to see more examples. You can also read the ",(0,r.kt)("a",{parentName:"p",href:"https://salesforcecli.github.io/sf-plugins-core/"},"API docs"),"."),(0,r.kt)("h2",{id:"alternative-flag-inputs"},"Alternative Flag Inputs"),(0,r.kt)("p",null,"Here are some other ways the user can use input flags. This is assuming the command has flags like ",(0,r.kt)("inlineCode",{parentName:"p"},"-f, --file=file")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"-v, --verbose")," (string and boolean flag):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh-session"},"$ mycli --verbose\n$ mycli -v\n$ mycli --file=foo\n$ mycli --file foo\n$ mycli -f foo\n$ mycli -f=foo\n$ mycli -ffoo\n$ mycli -vffoo\n")),(0,r.kt)("p",null,"The last one seems a little odd at first glance, but it's relatively standard in unix and makes commands like ",(0,r.kt)("inlineCode",{parentName:"p"},"tar -xvzfmytarball.tar.gz")," possible."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3042343a.adb1110b.js b/assets/js/3042343a.adb1110b.js new file mode 100644 index 00000000..de44d879 --- /dev/null +++ b/assets/js/3042343a.adb1110b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5917],{3905:(e,a,n)=>{n.d(a,{Zo:()=>c,kt:()=>g});var t=n(7294);function l(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function r(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var a=1;a=0||(l[n]=e[n]);return l}(e,a);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var i=t.createContext({}),f=function(e){var a=t.useContext(i),n=a;return e&&(n="function"==typeof e?e(a):o(o({},a),e)),n},c=function(e){var a=f(e.components);return t.createElement(i.Provider,{value:a},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},p=t.forwardRef((function(e,a){var n=e.components,l=e.mdxType,r=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=f(n),p=l,g=m["".concat(i,".").concat(p)]||m[p]||u[p]||r;return n?t.createElement(g,o(o({ref:a},c),{},{components:n})):t.createElement(g,o({ref:a},c))}));function g(e,a){var n=arguments,l=a&&a.mdxType;if("string"==typeof e||l){var r=n.length,o=new Array(r);o[0]=p;var s={};for(var i in a)hasOwnProperty.call(a,i)&&(s[i]=a[i]);s.originalType=e,s[m]="string"==typeof e?e:l,o[1]=s;for(var f=2;f{n.r(a),n.d(a,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>s,metadata:()=>f,toc:()=>m});var t=n(7462),l=n(3366),r=(n(7294),n(3905)),o=["components"],s={title:"Command Flags"},i=void 0,f={unversionedId:"flags",id:"flags",title:"Command Flags",description:"Flag options are non-positional arguments passed to the command. Flags can either be option flags which take an argument, or boolean flags which do not. An option flag must have an argument.",source:"@site/../docs/flags.md",sourceDirName:".",slug:"/flags",permalink:"/docs/flags",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/flags.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Command Flags"},sidebar:"docs",previous:{title:"Command Arguments",permalink:"/docs/args"},next:{title:"Configuration",permalink:"/docs/config"}},c={},m=[{value:"Custom Flags",id:"custom-flags",level:2},{value:"Alternative Flag Inputs",id:"alternative-flag-inputs",level:2}],u={toc:m},p="wrapper";function g(e){var a=e.components,n=(0,l.Z)(e,o);return(0,r.kt)(p,(0,t.Z)({},u,n,{components:a,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Flag options are non-positional arguments passed to the command. Flags can either be option flags which take an argument, or boolean flags which do not. An option flag must have an argument."),(0,r.kt)("p",null,"For example, if this command was run like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"$ mycli --force --file=./myfile\n")),(0,r.kt)("p",null,"It would be declared like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"import {Command, Flags} from '@oclif/core'\n\nexport class MyCLI extends Command {\n static flags = {\n // can pass either --force or -f\n force: Flags.boolean({char: 'f'}),\n file: Flags.string(),\n }\n\n async run() {\n const {flags} = await this.parse(MyCLI)\n if (flags.force) console.log('--force is set')\n if (flags.file) console.log(`--file is: ${flags.file}`)\n }\n}\n")),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"oclif supports a wide range of ",(0,r.kt)("a",{parentName:"em",href:"#alternative-flag-inputs"},"alternative flag inputs"),".")),(0,r.kt)("p",null,"Here are the options flags can have:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"static flags = {\n name: Flags.string({\n char: 'n', // shorter flag version\n summary: 'brief summary', // help summary for flag\n helpGroup: 'THE BEST FLAGS', // Put flag into THE BEST FLAGS group in help\n description: 'in-depth overview', // help description for flag\n hidden: false, // hide from help\n multiple: false, // allow setting this flag multiple times\n env: 'MY_NAME', // default to value of environment variable\n options: ['a', 'b'], // only allow the value to be from a discrete set\n parse: async input => 'output', // instead of the user input, return a different value\n default: 'world', // default value if flag not passed (can be an async function that returns a string or undefined)\n required: false, // make flag required\n aliases: ['username', 'u'], // aliases for the flag - can be short char or long flags\n deprecateAliases: false, // emit deprecation warning anytime a flag alias is provided\n dependsOn: ['extra-flag'], // this flag requires another flag\n exclusive: ['extra-flag'], // this flag cannot be specified alongside this other flag\n exactlyOne: ['extra-flag', 'another-flag'], // exactly one of these flags must be provided\n relationships: [ // define complex relationships between flags\n // Make this flag dependent on all of these flags\n {type: 'all', flags: ['flag-one', 'flag-two']}\n // Make this flag dependent on at least one of these flags\n {type: 'some', flags: ['flag-three', 'flag-four']}\n // Make this flag exclusive of all these flags\n {type: 'none', flags: ['flag-five', 'flag-six']}\n\n // Make this flag dependent on all of these flags\n {type: 'all', flags: [\n 'flag-one',\n 'flag-two',\n // Include flag-seven but only when flag-eight is equal to FooBar\n {name: 'flag-seven', when: async (flags) => flags['flag-eight'] === 'FooBar'}\n ]}\n ]\n }),\n\n // flag with no value (-f, --force)\n force: Flags.boolean({\n char: 'f', // short character for flag\n default: true, // default value if flag not passed (can be a function that returns a boolean)\n env: 'MY_NAME', // default value to the value of an environment variable\n // boolean flags may be reversed with `--no-` (in this case: `--no-force`).\n // The flag will be set to false if reversed. This functionality\n // is disabled by default, to enable it:\n // allowNo: true\n }),\n}\n")),(0,r.kt)("h2",{id:"custom-flags"},"Custom Flags"),(0,r.kt)("p",null,"For larger CLIs, it can be useful to declare a custom flag that can be shared amongst multiple commands. Here is an example of a custom flag:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"// src/flags.ts\nimport {Flags} from '@oclif/core'\n\nclass Team {\n public name: string;\n // etc...\n}\n\nfunction getTeam(): Promise {\n // imagine this reads a configuration file or something to find the team\n return new Team()\n}\n\nexport const team = Flags.custom({\n char: 't',\n description: 'team to use',\n default: () => getTeam(),\n})\n\n// src/commands/mycommand.ts\nimport {team} from '../flags'\nimport {Command} from '@oclif/core'\n\nexport class MyCLI extends Command {\n static flags = {\n team: team(),\n }\n\n async run() {\n const {flags} = await this.parse(MyCLI)\n if (flags.team) console.log(`--team is ${flags.team.name}`)\n }\n}\n")),(0,r.kt)("p",null,"In the Salesforce CLI we make heavy use of custom flags. For example,"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A ",(0,r.kt)("a",{parentName:"li",href:"https://salesforcecli.github.io/sf-plugins-core/functions/flags_salesforceId.salesforceIdFlag.html"},(0,r.kt)("inlineCode",{parentName:"a"},"salesforceId"))," flag that ensures the provided string is a valid Salesforce Id."),(0,r.kt)("li",{parentName:"ul"},"A ",(0,r.kt)("a",{parentName:"li",href:"https://salesforcecli.github.io/sf-plugins-core/functions/flags_duration.durationFlag.html"},(0,r.kt)("inlineCode",{parentName:"a"},"duration"))," flag that converts a provided integer into a ",(0,r.kt)("inlineCode",{parentName:"li"},"Duration")," instance that we use for working with time based values.")),(0,r.kt)("p",null,"These and more are located ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/salesforcecli/sf-plugins-core/tree/main/src/flags"},"here")," if you want to see more examples. You can also read the ",(0,r.kt)("a",{parentName:"p",href:"https://salesforcecli.github.io/sf-plugins-core/"},"API docs"),"."),(0,r.kt)("h2",{id:"alternative-flag-inputs"},"Alternative Flag Inputs"),(0,r.kt)("p",null,"Here are some other ways the user can use input flags. This is assuming the command has flags like ",(0,r.kt)("inlineCode",{parentName:"p"},"-f, --file=file")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"-v, --verbose")," (string and boolean flag):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh-session"},"$ mycli --verbose\n$ mycli -v\n$ mycli --file=foo\n$ mycli --file foo\n$ mycli -f foo\n$ mycli -f=foo\n$ mycli -ffoo\n$ mycli -vffoo\n")),(0,r.kt)("p",null,"The last one seems a little odd at first glance, but it's relatively standard in unix and makes commands like ",(0,r.kt)("inlineCode",{parentName:"p"},"tar -xvzfmytarball.tar.gz")," possible."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/32060389.063adfd6.js b/assets/js/32060389.063adfd6.js deleted file mode 100644 index d34b8eab..00000000 --- a/assets/js/32060389.063adfd6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7905],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>f});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function l(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),c=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},u=function(e){var n=c(e.components);return a.createElement(s.Provider,{value:n},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(t),d=r,f=p["".concat(s,".").concat(d)]||p[d]||m[d]||o;return t?a.createElement(f,l(l({ref:n},u),{},{components:t})):a.createElement(f,l({ref:n},u))}));function f(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,l=new Array(o);l[0]=d;var i={};for(var s in n)hasOwnProperty.call(n,s)&&(i[s]=n[s]);i.originalType=e,i[p]="string"==typeof e?e:r,l[1]=i;for(var c=2;c{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var a=t(7462),r=t(3366),o=(t(7294),t(3905)),l=["components"],i={title:"Table"},s=void 0,c={unversionedId:"table",id:"table",title:"Table",description:"ux.table",source:"@site/../docs/table.md",sourceDirName:".",slug:"/table",permalink:"/docs/table",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/table.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Table"},sidebar:"docs",previous:{title:"Spinner",permalink:"/docs/spinner"},next:{title:"Notifications",permalink:"/docs/notifications"}},u={},p=[{value:"ux.table",id:"uxtable",level:2}],m={toc:p},d="wrapper";function f(e){var n=e.components,t=(0,r.Z)(e,l);return(0,o.kt)(d,(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"uxtable"},(0,o.kt)("inlineCode",{parentName:"h2"},"ux.table")),(0,o.kt)("p",null,"Displays tabular data"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"ux.table(data, columns, options)\n")),(0,o.kt)("p",null,"Where:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"data"),": array of data objects to display"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"columns"),": ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/oclif/core/blob/main/src/cli-ux/styled/table.ts"},"Table.Columns")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"options"),": ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/oclif/core/blob/main/src/cli-ux/styled/table.ts"},"Table.Options"))),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"ux.table.flags()")," returns an object containing all the table flags to include in your command."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"{\n columns: Flags.string({exclusive: ['additional'], description: 'only show provided columns (comma-seperated)'}),\n sort: Flags.string({description: 'property to sort by (prepend '-' for descending)'}),\n filter: Flags.string({description: 'filter property by partial string matching, ex: name=foo'}),\n csv: Flags.boolean({exclusive: ['no-truncate'], description: 'output is csv format'}),\n extended: Flags.boolean({char: 'x', description: 'show extra columns'}),\n 'no-truncate': Flags.boolean({exclusive: ['csv'], description: 'do not truncate output to fit screen'}),\n 'no-header': Flags.boolean({exclusive: ['csv'], description: 'hide table header from output'}),\n}\n")),(0,o.kt)("p",null,"Passing ",(0,o.kt)("inlineCode",{parentName:"p"},"{only: ['columns']}")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"{except: ['columns']}")," as an argument into ",(0,o.kt)("inlineCode",{parentName:"p"},"cli.table.flags()")," will allow/block those flags from the returned object."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"ux.Table.Columns")," defines the table columns and their display options."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"const columns: ux.Table.Columns = {\n // where `.name` is a property of a data object\n name: {}, // \"Name\" inferred as the column header\n id: {\n header: 'ID', // override column header\n minWidth: '10', // column must display at this width or greater\n extended: true, // only display this column when the --extended flag is present\n get: row => `US-O1-${row.id}`, // custom getter for data row object\n },\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"ux.Table.Options")," defines the table options, most of which are the parsed flags from the user for display customization, all of which are optional."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"const options: ux.Table.Options = {\n printLine: myLogger, // custom logger\n columns: flags.columns,\n sort: flags.sort,\n filter: flags.filter,\n csv: flags.csv,\n extended: flags.extended,\n 'no-truncate': flags['no-truncate'],\n 'no-header': flags['no-header'],\n}\n")),(0,o.kt)("p",null,"Example class:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, ux} from '@oclif/core'\nimport axios from 'axios'\n\nexport default class Users extends Command {\n static flags = {\n ...ux.table.flags()\n }\n\n async run() {\n const {flags} = await this.parse(Users)\n const {data: users} = await axios.get('https://jsonplaceholder.typicode.com/users')\n\n ux.table(users, {\n name: {\n minWidth: 7,\n },\n company: {\n get: row => row.company && row.company.name\n },\n id: {\n header: 'ID',\n extended: true\n }\n }, {\n printLine: this.log.bind(this),\n ...flags, // parsed flags\n })\n }\n}\n")),(0,o.kt)("p",null,"Displays:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},'$ example-cli users\nName Company\nLeanne Graham Romaguera-Crona\nErvin Howell Deckow-Crist\nClementine Bauch Romaguera-Jacobson\nPatricia Lebsack Robel-Corkery\nChelsey Dietrich Keebler LLC\nMrs. Dennis Schulist Considine-Lockman\nKurtis Weissnat Johns Group\nNicholas Runolfsdottir V Abernathy Group\nGlenna Reichert Yost and Sons\nClementina DuBuque Hoeger LLC\n\n$ example-cli users --extended\nName Company ID\nLeanne Graham Romaguera-Crona 1\nErvin Howell Deckow-Crist 2\nClementine Bauch Romaguera-Jacobson 3\nPatricia Lebsack Robel-Corkery 4\nChelsey Dietrich Keebler LLC 5\nMrs. Dennis Schulist Considine-Lockman 6\nKurtis Weissnat Johns Group 7\nNicholas Runolfsdottir V Abernathy Group 8\nGlenna Reichert Yost and Sons 9\nClementina DuBuque Hoeger LLC 10\n\n$ example-cli users --columns=name\nName\nLeanne Graham\nErvin Howell\nClementine Bauch\nPatricia Lebsack\nChelsey Dietrich\nMrs. Dennis Schulist\nKurtis Weissnat\nNicholas Runolfsdottir V\nGlenna Reichert\nClementina DuBuque\n\n$ example-cli users --filter="company=Group"\nName Company\nKurtis Weissnat Johns Group\nNicholas Runolfsdottir V Abernathy Group\n\n$ example-cli users --sort=company\nName Company\nNicholas Runolfsdottir V Abernathy Group\nMrs. Dennis Schulist Considine-Lockman\nErvin Howell Deckow-Crist\nClementina DuBuque Hoeger LLC\nKurtis Weissnat Johns Group\nChelsey Dietrich Keebler LLC\nPatricia Lebsack Robel-Corkery\nLeanne Graham Romaguera-Crona\nClementine Bauch Romaguera-Jacobson\nGlenna Reichert Yost and Sons\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/32060389.38b5822f.js b/assets/js/32060389.38b5822f.js new file mode 100644 index 00000000..5a6387bf --- /dev/null +++ b/assets/js/32060389.38b5822f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7905],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>f});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function l(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),c=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},u=function(e){var n=c(e.components);return a.createElement(s.Provider,{value:n},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(t),d=r,f=p["".concat(s,".").concat(d)]||p[d]||m[d]||o;return t?a.createElement(f,l(l({ref:n},u),{},{components:t})):a.createElement(f,l({ref:n},u))}));function f(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,l=new Array(o);l[0]=d;var i={};for(var s in n)hasOwnProperty.call(n,s)&&(i[s]=n[s]);i.originalType=e,i[p]="string"==typeof e?e:r,l[1]=i;for(var c=2;c{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var a=t(7462),r=t(3366),o=(t(7294),t(3905)),l=["components"],i={title:"Table"},s=void 0,c={unversionedId:"table",id:"table",title:"Table",description:"ux.table",source:"@site/../docs/table.md",sourceDirName:".",slug:"/table",permalink:"/docs/table",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/table.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Table"},sidebar:"docs",previous:{title:"Spinner",permalink:"/docs/spinner"},next:{title:"Notifications",permalink:"/docs/notifications"}},u={},p=[{value:"ux.table",id:"uxtable",level:2}],m={toc:p},d="wrapper";function f(e){var n=e.components,t=(0,r.Z)(e,l);return(0,o.kt)(d,(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"uxtable"},(0,o.kt)("inlineCode",{parentName:"h2"},"ux.table")),(0,o.kt)("p",null,"Displays tabular data"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"ux.table(data, columns, options)\n")),(0,o.kt)("p",null,"Where:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"data"),": array of data objects to display"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"columns"),": ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/oclif/core/blob/main/src/cli-ux/styled/table.ts"},"Table.Columns")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"options"),": ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/oclif/core/blob/main/src/cli-ux/styled/table.ts"},"Table.Options"))),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"ux.table.flags()")," returns an object containing all the table flags to include in your command."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"{\n columns: Flags.string({exclusive: ['additional'], description: 'only show provided columns (comma-seperated)'}),\n sort: Flags.string({description: 'property to sort by (prepend '-' for descending)'}),\n filter: Flags.string({description: 'filter property by partial string matching, ex: name=foo'}),\n csv: Flags.boolean({exclusive: ['no-truncate'], description: 'output is csv format'}),\n extended: Flags.boolean({char: 'x', description: 'show extra columns'}),\n 'no-truncate': Flags.boolean({exclusive: ['csv'], description: 'do not truncate output to fit screen'}),\n 'no-header': Flags.boolean({exclusive: ['csv'], description: 'hide table header from output'}),\n}\n")),(0,o.kt)("p",null,"Passing ",(0,o.kt)("inlineCode",{parentName:"p"},"{only: ['columns']}")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"{except: ['columns']}")," as an argument into ",(0,o.kt)("inlineCode",{parentName:"p"},"cli.table.flags()")," will allow/block those flags from the returned object."),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"ux.Table.Columns")," defines the table columns and their display options."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"const columns: ux.Table.Columns = {\n // where `.name` is a property of a data object\n name: {}, // \"Name\" inferred as the column header\n id: {\n header: 'ID', // override column header\n minWidth: '10', // column must display at this width or greater\n extended: true, // only display this column when the --extended flag is present\n get: row => `US-O1-${row.id}`, // custom getter for data row object\n },\n}\n")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"ux.Table.Options")," defines the table options, most of which are the parsed flags from the user for display customization, all of which are optional."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"const options: ux.Table.Options = {\n printLine: myLogger, // custom logger\n columns: flags.columns,\n sort: flags.sort,\n filter: flags.filter,\n csv: flags.csv,\n extended: flags.extended,\n 'no-truncate': flags['no-truncate'],\n 'no-header': flags['no-header'],\n}\n")),(0,o.kt)("p",null,"Example class:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, ux} from '@oclif/core'\nimport axios from 'axios'\n\nexport default class Users extends Command {\n static flags = {\n ...ux.table.flags()\n }\n\n async run() {\n const {flags} = await this.parse(Users)\n const {data: users} = await axios.get('https://jsonplaceholder.typicode.com/users')\n\n ux.table(users, {\n name: {\n minWidth: 7,\n },\n company: {\n get: row => row.company && row.company.name\n },\n id: {\n header: 'ID',\n extended: true\n }\n }, {\n printLine: this.log.bind(this),\n ...flags, // parsed flags\n })\n }\n}\n")),(0,o.kt)("p",null,"Displays:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-shell"},'$ example-cli users\nName Company\nLeanne Graham Romaguera-Crona\nErvin Howell Deckow-Crist\nClementine Bauch Romaguera-Jacobson\nPatricia Lebsack Robel-Corkery\nChelsey Dietrich Keebler LLC\nMrs. Dennis Schulist Considine-Lockman\nKurtis Weissnat Johns Group\nNicholas Runolfsdottir V Abernathy Group\nGlenna Reichert Yost and Sons\nClementina DuBuque Hoeger LLC\n\n$ example-cli users --extended\nName Company ID\nLeanne Graham Romaguera-Crona 1\nErvin Howell Deckow-Crist 2\nClementine Bauch Romaguera-Jacobson 3\nPatricia Lebsack Robel-Corkery 4\nChelsey Dietrich Keebler LLC 5\nMrs. Dennis Schulist Considine-Lockman 6\nKurtis Weissnat Johns Group 7\nNicholas Runolfsdottir V Abernathy Group 8\nGlenna Reichert Yost and Sons 9\nClementina DuBuque Hoeger LLC 10\n\n$ example-cli users --columns=name\nName\nLeanne Graham\nErvin Howell\nClementine Bauch\nPatricia Lebsack\nChelsey Dietrich\nMrs. Dennis Schulist\nKurtis Weissnat\nNicholas Runolfsdottir V\nGlenna Reichert\nClementina DuBuque\n\n$ example-cli users --filter="company=Group"\nName Company\nKurtis Weissnat Johns Group\nNicholas Runolfsdottir V Abernathy Group\n\n$ example-cli users --sort=company\nName Company\nNicholas Runolfsdottir V Abernathy Group\nMrs. Dennis Schulist Considine-Lockman\nErvin Howell Deckow-Crist\nClementina DuBuque Hoeger LLC\nKurtis Weissnat Johns Group\nChelsey Dietrich Keebler LLC\nPatricia Lebsack Robel-Corkery\nLeanne Graham Romaguera-Crona\nClementine Bauch Romaguera-Jacobson\nGlenna Reichert Yost and Sons\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/35586d92.2e93a9eb.js b/assets/js/35586d92.2e93a9eb.js deleted file mode 100644 index 62789e98..00000000 --- a/assets/js/35586d92.2e93a9eb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1160],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var p=r.createContext({}),s=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(p.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),m=i,g=d["".concat(p,".").concat(m)]||d[m]||c[m]||o;return n?r.createElement(g,a(a({ref:t},u),{},{components:n})):r.createElement(g,a({ref:t},u))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[d]="string"==typeof e?e:i,a[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>p,default:()=>g,frontMatter:()=>l,metadata:()=>s,toc:()=>d});var r=n(7462),i=n(3366),o=(n(7294),n(3905)),a=["components"],l={title:"Plugin Loading"},p=void 0,s={unversionedId:"plugin_loading",id:"plugin_loading",title:"Plugin Loading",description:"Below is a diagram that outlines how a plugin is loaded into the CLI.",source:"@site/../docs/plugin_loading.md",sourceDirName:".",slug:"/plugin_loading",permalink:"/docs/plugin_loading",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/plugin_loading.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Plugin Loading"},sidebar:"docs",previous:{title:"Command Execution",permalink:"/docs/command_execution"},next:{title:"Commands",permalink:"/docs/commands"}},u={},d=[{value:"Plugin Resolution Order",id:"plugin-resolution-order",level:3},{value:"Manifests Improve Performance",id:"manifests-improve-performance",level:3},{value:"Plugin Loading Diagram",id:"plugin-loading-diagram",level:2}],c={toc:d},m="wrapper";function g(e){var t=e.components,l=(0,i.Z)(e,a);return(0,o.kt)(m,(0,r.Z)({},c,l,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Below is a diagram that outlines how a plugin is loaded into the CLI."),(0,o.kt)("p",null,"There are a couple of important takeaways from this diagram:"),(0,o.kt)("h3",{id:"plugin-resolution-order"},"Plugin Resolution Order"),(0,o.kt)("p",null,"Plugins are resolved in the following order:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"User plugins (i.e. plugins installed by the users)"),(0,o.kt)("li",{parentName:"ol"},"Dev plugins (i.e. plugins listed under ",(0,o.kt)("inlineCode",{parentName:"li"},"devPlugins"),")"),(0,o.kt)("li",{parentName:"ol"},"Core plugins (i.e. plugins listed under ",(0,o.kt)("inlineCode",{parentName:"li"},"plugins"),")")),(0,o.kt)("h3",{id:"manifests-improve-performance"},"Manifests Improve Performance"),(0,o.kt)("p",null,"When loading a plugin, oclif needs to require each command file in order to get the static properties of the command - the ",(0,o.kt)("inlineCode",{parentName:"p"},"description"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"examples"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"flags"),", etc..."),(0,o.kt)("p",null,"However, oclif can skip this step if the plugin has an ",(0,o.kt)("inlineCode",{parentName:"p"},"oclif.manifest.json")," (generated by ",(0,o.kt)("inlineCode",{parentName:"p"},"oclif manifest"),"). The manifest caches all of these properties so that there's no need to require every single command on every command execution."),(0,o.kt)("h2",{id:"plugin-loading-diagram"},"Plugin Loading Diagram"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"plugin loading",src:n(1944).Z,width:"8787",height:"5576"})))}g.isMDXComponent=!0},1944:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/plugin-loading-63d248baba4db7ba0a9340ef6b0c0856.jpg"}}]); \ No newline at end of file diff --git a/assets/js/35586d92.d1a54b33.js b/assets/js/35586d92.d1a54b33.js new file mode 100644 index 00000000..5ad2c923 --- /dev/null +++ b/assets/js/35586d92.d1a54b33.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1160],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>g});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=r.createContext({}),s=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},u=function(e){var n=s(e.components);return r.createElement(p.Provider,{value:n},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(t),m=i,g=d["".concat(p,".").concat(m)]||d[m]||c[m]||o;return t?r.createElement(g,a(a({ref:n},u),{},{components:t})):r.createElement(g,a({ref:n},u))}));function g(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=m;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l[d]="string"==typeof e?e:i,a[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>p,default:()=>g,frontMatter:()=>l,metadata:()=>s,toc:()=>d});var r=t(7462),i=t(3366),o=(t(7294),t(3905)),a=["components"],l={title:"Plugin Loading"},p=void 0,s={unversionedId:"plugin_loading",id:"plugin_loading",title:"Plugin Loading",description:"Below is a diagram that outlines how a plugin is loaded into the CLI.",source:"@site/../docs/plugin_loading.md",sourceDirName:".",slug:"/plugin_loading",permalink:"/docs/plugin_loading",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/plugin_loading.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Plugin Loading"},sidebar:"docs",previous:{title:"Command Execution",permalink:"/docs/command_execution"},next:{title:"Commands",permalink:"/docs/commands"}},u={},d=[{value:"Plugin Resolution Order",id:"plugin-resolution-order",level:3},{value:"Manifests Improve Performance",id:"manifests-improve-performance",level:3},{value:"Plugin Loading Diagram",id:"plugin-loading-diagram",level:2}],c={toc:d},m="wrapper";function g(e){var n=e.components,l=(0,i.Z)(e,a);return(0,o.kt)(m,(0,r.Z)({},c,l,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Below is a diagram that outlines how a plugin is loaded into the CLI."),(0,o.kt)("p",null,"There are a couple of important takeaways from this diagram:"),(0,o.kt)("h3",{id:"plugin-resolution-order"},"Plugin Resolution Order"),(0,o.kt)("p",null,"Plugins are resolved in the following order:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"User plugins (i.e. plugins installed by the users)"),(0,o.kt)("li",{parentName:"ol"},"Dev plugins (i.e. plugins listed under ",(0,o.kt)("inlineCode",{parentName:"li"},"devPlugins"),")"),(0,o.kt)("li",{parentName:"ol"},"Core plugins (i.e. plugins listed under ",(0,o.kt)("inlineCode",{parentName:"li"},"plugins"),")")),(0,o.kt)("h3",{id:"manifests-improve-performance"},"Manifests Improve Performance"),(0,o.kt)("p",null,"When loading a plugin, oclif needs to require each command file in order to get the static properties of the command - the ",(0,o.kt)("inlineCode",{parentName:"p"},"description"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"examples"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"flags"),", etc..."),(0,o.kt)("p",null,"However, oclif can skip this step if the plugin has an ",(0,o.kt)("inlineCode",{parentName:"p"},"oclif.manifest.json")," (generated by ",(0,o.kt)("inlineCode",{parentName:"p"},"oclif manifest"),"). The manifest caches all of these properties so that there's no need to require every single command on every command execution."),(0,o.kt)("h2",{id:"plugin-loading-diagram"},"Plugin Loading Diagram"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"plugin loading",src:t(1944).Z,width:"8787",height:"5576"})))}g.isMDXComponent=!0},1944:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/plugin-loading-63d248baba4db7ba0a9340ef6b0c0856.jpg"}}]); \ No newline at end of file diff --git a/assets/js/3e452c7e.7adc444d.js b/assets/js/3e452c7e.7adc444d.js deleted file mode 100644 index 553af6c7..00000000 --- a/assets/js/3e452c7e.7adc444d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[637],{3905:(e,n,t)=>{t.d(n,{Zo:()=>m,kt:()=>u});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),i=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},m=function(e){var n=i(e.components);return r.createElement(l.Provider,{value:n},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,s=e.originalType,l=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),p=i(t),f=a,u=p["".concat(l,".").concat(f)]||p[f]||d[f]||s;return t?r.createElement(u,o(o({ref:n},m),{},{components:t})):r.createElement(u,o({ref:n},m))}));function u(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var s=t.length,o=new Array(s);o[0]=f;var c={};for(var l in n)hasOwnProperty.call(n,l)&&(c[l]=n[l]);c.originalType=e,c[p]="string"==typeof e?e:a,o[1]=c;for(var i=2;i{t.r(n),t.d(n,{assets:()=>m,contentTitle:()=>l,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>p});var r=t(7462),a=t(3366),s=(t(7294),t(3905)),o=["components"],c={title:"Custom Base Class"},l=void 0,i={unversionedId:"base_class",id:"base_class",title:"Custom Base Class",description:"Use inheritance to share functionality between common commands. Here is an example of a command base class that has some common shared flags.",source:"@site/../docs/base_class.md",sourceDirName:".",slug:"/base_class",permalink:"/docs/base_class",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/base_class.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Custom Base Class"},sidebar:"docs",previous:{title:"NSIS Installer Customization",permalink:"/docs/nsis-installer_customization"},next:{title:"Prompting",permalink:"/docs/prompting"}},m={},p=[],d={toc:p},f="wrapper";function u(e){var n=e.components,t=(0,a.Z)(e,o);return(0,s.kt)(f,(0,r.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,s.kt)("p",null,"Use inheritance to share functionality between common commands. Here is an example of a command base class that has some common shared flags."),(0,s.kt)("p",null,"For large CLIs with multiple plugins, it's useful to put this base class into its own npm package to be shared."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-typescript"},"// src/baseCommand.ts\nimport {Command, Flags, Interfaces} from '@oclif/core'\n\nenum LogLevel {\n debug = 'debug',\n info = 'info',\n warn = 'warn',\n error = 'error',\n}\n\nexport type Flags = Interfaces.InferredFlags\nexport type Args = Interfaces.InferredArgs\n\nexport abstract class BaseCommand extends Command {\n // add the --json flag\n static enableJsonFlag = true\n\n // define flags that can be inherited by any command that extends BaseCommand\n static baseFlags = {\n 'log-level': Flags.custom({\n summary: 'Specify level for logging.',\n options: Object.values(LogLevel),\n helpGroup: 'GLOBAL',\n })(),\n }\n\n protected flags!: Flags\n protected args!: Args\n\n public async init(): Promise {\n await super.init()\n const {args, flags} = await this.parse({\n flags: this.ctor.flags,\n baseFlags: (super.ctor as typeof BaseCommand).baseFlags,\n args: this.ctor.args,\n strict: this.ctor.strict,\n })\n this.flags = flags as Flags\n this.args = args as Args\n }\n\n protected async catch(err: Error & {exitCode?: number}): Promise {\n // add any custom logic to handle errors from the command\n // or simply return the parent class error handling\n return super.catch(err)\n }\n\n protected async finally(_: Error | undefined): Promise {\n // called after run and catch regardless of whether or not the command errored\n return super.finally(_)\n }\n}\n\n// src/commands/my-command.ts\n\nexport default class MyCommand extends BaseCommand {\n static summary = 'child class that extends BaseCommand'\n\n static examples = [\n '<%= config.bin %> <%= command.id %>',\n '<%= config.bin %> <%= command.id %> --json',\n '<%= config.bin %> <%= command.id %> --log-level debug',\n ]\n\n static flags = {\n name: Flags.string({\n char: 'n',\n summary: 'Name to print.',\n required: true,\n }),\n }\n\n public async run(): Promise> {\n for (const [flag, value] of Object.entries(this.flags)) {\n this.log(`${flag}: ${value}`)\n }\n\n return this.flags\n }\n}\n")),(0,s.kt)("p",null,"For a more complex example, ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/salesforcecli/sf-plugins-core/blob/main/src/sfCommand.ts"},"here's")," how we do this for the Salesforce CLI."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3e452c7e.b52cc06b.js b/assets/js/3e452c7e.b52cc06b.js new file mode 100644 index 00000000..3a65e0cd --- /dev/null +++ b/assets/js/3e452c7e.b52cc06b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[637],{3905:(e,n,t)=>{t.d(n,{Zo:()=>m,kt:()=>u});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),i=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},m=function(e){var n=i(e.components);return r.createElement(l.Provider,{value:n},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,s=e.originalType,l=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),p=i(t),f=a,u=p["".concat(l,".").concat(f)]||p[f]||d[f]||s;return t?r.createElement(u,o(o({ref:n},m),{},{components:t})):r.createElement(u,o({ref:n},m))}));function u(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var s=t.length,o=new Array(s);o[0]=f;var c={};for(var l in n)hasOwnProperty.call(n,l)&&(c[l]=n[l]);c.originalType=e,c[p]="string"==typeof e?e:a,o[1]=c;for(var i=2;i{t.r(n),t.d(n,{assets:()=>m,contentTitle:()=>l,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>p});var r=t(7462),a=t(3366),s=(t(7294),t(3905)),o=["components"],c={title:"Custom Base Class"},l=void 0,i={unversionedId:"base_class",id:"base_class",title:"Custom Base Class",description:"Use inheritance to share functionality between common commands. Here is an example of a command base class that has some common shared flags.",source:"@site/../docs/base_class.md",sourceDirName:".",slug:"/base_class",permalink:"/docs/base_class",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/base_class.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Custom Base Class"},sidebar:"docs",previous:{title:"NSIS Installer Customization",permalink:"/docs/nsis-installer_customization"},next:{title:"Prompting",permalink:"/docs/prompting"}},m={},p=[],d={toc:p},f="wrapper";function u(e){var n=e.components,t=(0,a.Z)(e,o);return(0,s.kt)(f,(0,r.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,s.kt)("p",null,"Use inheritance to share functionality between common commands. Here is an example of a command base class that has some common shared flags."),(0,s.kt)("p",null,"For large CLIs with multiple plugins, it's useful to put this base class into its own npm package to be shared."),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-typescript"},"// src/baseCommand.ts\nimport {Command, Flags, Interfaces} from '@oclif/core'\n\nenum LogLevel {\n debug = 'debug',\n info = 'info',\n warn = 'warn',\n error = 'error',\n}\n\nexport type Flags = Interfaces.InferredFlags\nexport type Args = Interfaces.InferredArgs\n\nexport abstract class BaseCommand extends Command {\n // add the --json flag\n static enableJsonFlag = true\n\n // define flags that can be inherited by any command that extends BaseCommand\n static baseFlags = {\n 'log-level': Flags.custom({\n summary: 'Specify level for logging.',\n options: Object.values(LogLevel),\n helpGroup: 'GLOBAL',\n })(),\n }\n\n protected flags!: Flags\n protected args!: Args\n\n public async init(): Promise {\n await super.init()\n const {args, flags} = await this.parse({\n flags: this.ctor.flags,\n baseFlags: (super.ctor as typeof BaseCommand).baseFlags,\n args: this.ctor.args,\n strict: this.ctor.strict,\n })\n this.flags = flags as Flags\n this.args = args as Args\n }\n\n protected async catch(err: Error & {exitCode?: number}): Promise {\n // add any custom logic to handle errors from the command\n // or simply return the parent class error handling\n return super.catch(err)\n }\n\n protected async finally(_: Error | undefined): Promise {\n // called after run and catch regardless of whether or not the command errored\n return super.finally(_)\n }\n}\n\n// src/commands/my-command.ts\n\nexport default class MyCommand extends BaseCommand {\n static summary = 'child class that extends BaseCommand'\n\n static examples = [\n '<%= config.bin %> <%= command.id %>',\n '<%= config.bin %> <%= command.id %> --json',\n '<%= config.bin %> <%= command.id %> --log-level debug',\n ]\n\n static flags = {\n name: Flags.string({\n char: 'n',\n summary: 'Name to print.',\n required: true,\n }),\n }\n\n public async run(): Promise> {\n for (const [flag, value] of Object.entries(this.flags)) {\n this.log(`${flag}: ${value}`)\n }\n\n return this.flags\n }\n}\n")),(0,s.kt)("p",null,"For a more complex example, ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/salesforcecli/sf-plugins-core/blob/main/src/sfCommand.ts"},"here's")," how we do this for the Salesforce CLI."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/49140ced.017f98c9.js b/assets/js/49140ced.7ab97290.js similarity index 90% rename from assets/js/49140ced.017f98c9.js rename to assets/js/49140ced.7ab97290.js index c4af68c5..8ec49f85 100644 --- a/assets/js/49140ced.017f98c9.js +++ b/assets/js/49140ced.7ab97290.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7591],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},g=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),g=r,f=d["".concat(s,".").concat(g)]||d[g]||u[g]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:r,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var o=n(7462),r=n(3366),i=(n(7294),n(3905)),a=["components"],l={title:"oclif's Current Node Support"},s=void 0,c={permalink:"/blog/2019/10/31/oclif-node-updates",source:"@site/blog/2019-10-31-oclif-node-updates.md",title:"oclif's Current Node Support",description:"To maintain a healthy project trajectory, oclif follows and supports Node Active LTS release, currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining Node 8 and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes.",date:"2019-10-31T00:00:00.000Z",formattedDate:"October 31, 2019",tags:[],readingTime:2.4,hasTruncateMarker:!1,authors:[],frontMatter:{title:"oclif's Current Node Support"},prevItem:{title:"oclif TSLint to ESLint Migration",permalink:"/blog/2019/12/05/oclif-eslint-migration"},nextItem:{title:"oclifconf 2019: A Recap",permalink:"/blog/2019/09/16/oclifconf-recap"}},p={authorsImageUrls:[]},d=[{value:"CI Environments",id:"ci-environments",level:2},{value:".circleci/config.yml",id:"circleciconfigyml",level:3},{value:"appveyor.yml",id:"appveyoryml",level:3},{value:"Deprecating Node 8 & Updating packge.json engines",id:"deprecating-node-8--updating-packgejson-engines",level:2},{value:"Packaged Node Version",id:"packaged-node-version",level:2},{value:"Supporting the future",id:"supporting-the-future",level:2}],u={toc:d},g="wrapper";function f(e){var t=e.components,n=(0,r.Z)(e,a);return(0,i.kt)(g,(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"To maintain a healthy project trajectory, oclif follows and supports ",(0,i.kt)("a",{parentName:"p",href:"https://nodejs.org/en/about/releases/"},"Node Active LTS release"),", currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/nodejs/Release#release-schedule"},"Node 8")," and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes."),(0,i.kt)("h2",{id:"ci-environments"},"CI Environments"),(0,i.kt)("p",null,"CLIs created with the oclif cli going forward will be generated with a CircleCI configuration with Node 10 & 12 and an Appveyor configuration using Node 10. We have also added Node latest to CircleCi to be an early warning detection against coming Node changes (Node latest is managed by CircleCI)."),(0,i.kt)("p",null,"We have already updated every oclif repo's CI configs to reflect this."),(0,i.kt)("p",null,"If your existing CLI uses either Appveyor or CircleCI you can update your config files also, like so:"),(0,i.kt)("h3",{id:"circleciconfigyml"},".circleci/config.yml"),(0,i.kt)("p",null,"Your CircleCI config should contain a ",(0,i.kt)("inlineCode",{parentName:"p"},"node-latest")," job, aliased as ",(0,i.kt)("inlineCode",{parentName:"p"},"test"),". From this, there should be two extensions of this job for the Active LTS Node versions, Node 10 and Node 12."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," node-10:\n <<: *node-latest\n docker:\n - image: node:10\n node-12:\n <<: *node-latest\n docker:\n - image: node:12\n")),(0,i.kt)("p",null,"Notice that these declarations only change the Docker Node images used to run that job."),(0,i.kt)("p",null,"Additionally, the jobs listed within workflows must also be updated to reflect our changes in configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," jobs:\n - node-latest\n - node-10\n - node-12\n")),(0,i.kt)("h3",{id:"appveyoryml"},"appveyor.yml"),(0,i.kt)("p",null,"For appveyor we are currently only testing the oldest Active LTS Node version, Node 10. Update the ",(0,i.kt)("inlineCode",{parentName:"p"},"nodejs_version")," proppert in your appveyor.yml file to reflect this."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'environment:\n nodejs_version: "10"\n')),(0,i.kt)("h2",{id:"deprecating-node-8--updating-packgejson-engines"},"Deprecating Node 8 & Updating packge.json engines"),(0,i.kt)("p",null,"In Jan 2020, Node will end its Node 8 maintenance. We will follow suit by setting the package.json engine property in oclif packages to ",(0,i.kt)("inlineCode",{parentName:"p"},">=10")," and bumping the package's major versions."),(0,i.kt)("p",null,"Depending on how you ship your CLI you may wish to also bump the engines version in your CLI's package.json. You can read more about the implications of the engines property configuration in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/files/package.json#engines"},"npm documentation"),"."),(0,i.kt)("p",null,"Also consider distributing your CLI with ",(0,i.kt)("a",{parentName:"p",href:"https://oclif.io/docs/releasing#standalone-tarballs"},"its own Node version"),"."),(0,i.kt)("h2",{id:"packaged-node-version"},"Packaged Node Version"),(0,i.kt)("p",null,"When using dev-cli to pack your CLI it will use the Node version as specified in your package.json under the ",(0,i.kt)("inlineCode",{parentName:"p"},"oclif.update.node.version")," property. This value should reflect an Active LTS Node version (dev-cli does not currently enforce versions)."),(0,i.kt)("h2",{id:"supporting-the-future"},"Supporting the future"),(0,i.kt)("p",null,"As a community we may discover bumps along the way as we upgrade. If you notice something related to oclif please feel free to open an issue or submit a pull request under the relevant oclif package within ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/oclif"},"the org"),"."),(0,i.kt)("p",null,"We look forward to using the latest from Node and the community and keeping oclif healthy along the way."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7591],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),p=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},g=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),g=r,f=d["".concat(s,".").concat(g)]||d[g]||u[g]||i;return n?o.createElement(f,a(a({ref:t},c),{},{components:n})):o.createElement(f,a({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:r,a[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>p,toc:()=>d});var o=n(7462),r=n(3366),i=(n(7294),n(3905)),a=["components"],l={title:"oclif's Current Node Support"},s=void 0,p={permalink:"/blog/2019/10/31/oclif-node-updates",source:"@site/blog/2019-10-31-oclif-node-updates.md",title:"oclif's Current Node Support",description:"To maintain a healthy project trajectory, oclif follows and supports Node Active LTS release, currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining Node 8 and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes.",date:"2019-10-31T00:00:00.000Z",formattedDate:"October 31, 2019",tags:[],readingTime:2.4,hasTruncateMarker:!1,authors:[],frontMatter:{title:"oclif's Current Node Support"},prevItem:{title:"oclif TSLint to ESLint Migration",permalink:"/blog/2019/12/05/oclif-eslint-migration"},nextItem:{title:"CLI Flags Explained",permalink:"/blog/2019/02/20/cli-flags-explained"}},c={authorsImageUrls:[]},d=[{value:"CI Environments",id:"ci-environments",level:2},{value:".circleci/config.yml",id:"circleciconfigyml",level:3},{value:"appveyor.yml",id:"appveyoryml",level:3},{value:"Deprecating Node 8 & Updating packge.json engines",id:"deprecating-node-8--updating-packgejson-engines",level:2},{value:"Packaged Node Version",id:"packaged-node-version",level:2},{value:"Supporting the future",id:"supporting-the-future",level:2}],u={toc:d},g="wrapper";function f(e){var t=e.components,n=(0,r.Z)(e,a);return(0,i.kt)(g,(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"To maintain a healthy project trajectory, oclif follows and supports ",(0,i.kt)("a",{parentName:"p",href:"https://nodejs.org/en/about/releases/"},"Node Active LTS release"),", currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/nodejs/Release#release-schedule"},"Node 8")," and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes."),(0,i.kt)("h2",{id:"ci-environments"},"CI Environments"),(0,i.kt)("p",null,"CLIs created with the oclif cli going forward will be generated with a CircleCI configuration with Node 10 & 12 and an Appveyor configuration using Node 10. We have also added Node latest to CircleCi to be an early warning detection against coming Node changes (Node latest is managed by CircleCI)."),(0,i.kt)("p",null,"We have already updated every oclif repo's CI configs to reflect this."),(0,i.kt)("p",null,"If your existing CLI uses either Appveyor or CircleCI you can update your config files also, like so:"),(0,i.kt)("h3",{id:"circleciconfigyml"},".circleci/config.yml"),(0,i.kt)("p",null,"Your CircleCI config should contain a ",(0,i.kt)("inlineCode",{parentName:"p"},"node-latest")," job, aliased as ",(0,i.kt)("inlineCode",{parentName:"p"},"test"),". From this, there should be two extensions of this job for the Active LTS Node versions, Node 10 and Node 12."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," node-10:\n <<: *node-latest\n docker:\n - image: node:10\n node-12:\n <<: *node-latest\n docker:\n - image: node:12\n")),(0,i.kt)("p",null,"Notice that these declarations only change the Docker Node images used to run that job."),(0,i.kt)("p",null,"Additionally, the jobs listed within workflows must also be updated to reflect our changes in configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," jobs:\n - node-latest\n - node-10\n - node-12\n")),(0,i.kt)("h3",{id:"appveyoryml"},"appveyor.yml"),(0,i.kt)("p",null,"For appveyor we are currently only testing the oldest Active LTS Node version, Node 10. Update the ",(0,i.kt)("inlineCode",{parentName:"p"},"nodejs_version")," proppert in your appveyor.yml file to reflect this."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'environment:\n nodejs_version: "10"\n')),(0,i.kt)("h2",{id:"deprecating-node-8--updating-packgejson-engines"},"Deprecating Node 8 & Updating packge.json engines"),(0,i.kt)("p",null,"In Jan 2020, Node will end its Node 8 maintenance. We will follow suit by setting the package.json engine property in oclif packages to ",(0,i.kt)("inlineCode",{parentName:"p"},">=10")," and bumping the package's major versions."),(0,i.kt)("p",null,"Depending on how you ship your CLI you may wish to also bump the engines version in your CLI's package.json. You can read more about the implications of the engines property configuration in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/files/package.json#engines"},"npm documentation"),"."),(0,i.kt)("p",null,"Also consider distributing your CLI with ",(0,i.kt)("a",{parentName:"p",href:"https://oclif.io/docs/releasing#standalone-tarballs"},"its own Node version"),"."),(0,i.kt)("h2",{id:"packaged-node-version"},"Packaged Node Version"),(0,i.kt)("p",null,"When using dev-cli to pack your CLI it will use the Node version as specified in your package.json under the ",(0,i.kt)("inlineCode",{parentName:"p"},"oclif.update.node.version")," property. This value should reflect an Active LTS Node version (dev-cli does not currently enforce versions)."),(0,i.kt)("h2",{id:"supporting-the-future"},"Supporting the future"),(0,i.kt)("p",null,"As a community we may discover bumps along the way as we upgrade. If you notice something related to oclif please feel free to open an issue or submit a pull request under the relevant oclif package within ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/oclif"},"the org"),"."),(0,i.kt)("p",null,"We look forward to using the latest from Node and the community and keeping oclif healthy along the way."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/53e18611.9065e053.js b/assets/js/53e18611.4c65a9af.js similarity index 57% rename from assets/js/53e18611.9065e053.js rename to assets/js/53e18611.4c65a9af.js index 001c437e..7ef4857b 100644 --- a/assets/js/53e18611.9065e053.js +++ b/assets/js/53e18611.4c65a9af.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8349],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(r),f=o,m=p["".concat(c,".").concat(f)]||p[f]||d[f]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),i=["components"],l={title:"Introduction"},c=void 0,s={unversionedId:"introduction",id:"introduction",title:"Introduction",description:"oclif is a framework for building CLIs in Node. It can be used like a simple flag parser but is capable of much more. It's designed to be extensible so that you can easily add plugins such as the update warning plugin or build your own for users to install at runtime.",source:"@site/../docs/introduction.md",sourceDirName:".",slug:"/introduction",permalink:"/docs/introduction",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/introduction.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Introduction"},sidebar:"docs",next:{title:"Features",permalink:"/docs/features"}},u={},p=[{value:"Requirements",id:"requirements",level:2},{value:"Quickstart",id:"quickstart",level:2}],d={toc:p},f="wrapper";function m(e){var t=e.components,r=(0,o.Z)(e,i);return(0,a.kt)(f,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"oclif is a framework for building CLIs in Node. It can be used like a ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core#usage"},"simple flag parser")," but is capable of much more. It's designed to be extensible so that you can easily add plugins such as the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-warn-if-update-available"},"update warning plugin")," or build your own for users to install at runtime."),(0,a.kt)("p",null,"The oclif generator creates a CLI project in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/hello-world"},"TypeScript")," to get you started quickly. It requires very few runtime dependencies and has extremely minimal overhead."),(0,a.kt)("p",null,"Everything is customizable in oclif. Even the flag parser and help generation is optional and can be replaced. It's a platform to build upon that provides smart defaults without locking you in to any specific tools or behavior."),(0,a.kt)("h2",{id:"requirements"},"Requirements"),(0,a.kt)("p",null,"Only ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/about/releases/"},"LTS Node versions")," are supported. You can add the ",(0,a.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/node"},"node")," package to your CLI to ensure users are on a specific Node version."),(0,a.kt)("h2",{id:"quickstart"},"Quickstart"),(0,a.kt)("p",null,"Creating a CLI:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh-session"},"$ npx oclif generate mynewcli\n? npm package name (mynewcli): mynewcli\n$ cd mynewcli\n$ ./bin/dev hello world\nhello world! (./src/commands/hello/world.ts)\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8349],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(r),f=o,m=p["".concat(c,".").concat(f)]||p[f]||d[f]||a;return r?n.createElement(m,i(i({ref:t},u),{},{components:r})):n.createElement(m,i({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),i=["components"],l={title:"Introduction"},c=void 0,s={unversionedId:"introduction",id:"introduction",title:"Introduction",description:"oclif is a framework for building CLIs in Node. It can be used like a simple flag parser but is capable of much more. It's designed to be extensible so that you can easily add plugins such as the update warning plugin or build your own for users to install at runtime.",source:"@site/../docs/introduction.md",sourceDirName:".",slug:"/introduction",permalink:"/docs/introduction",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/introduction.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Introduction"},sidebar:"docs",next:{title:"Features",permalink:"/docs/features"}},u={},p=[{value:"Requirements",id:"requirements",level:2},{value:"Quickstart",id:"quickstart",level:2}],d={toc:p},f="wrapper";function m(e){var t=e.components,r=(0,o.Z)(e,i);return(0,a.kt)(f,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"oclif is a framework for building CLIs in Node. It can be used like a ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core#usage"},"simple flag parser")," but is capable of much more. It's designed to be extensible so that you can easily add plugins such as the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-warn-if-update-available"},"update warning plugin")," or build your own for users to install at runtime."),(0,a.kt)("p",null,"The oclif generator creates a CLI project in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/hello-world"},"TypeScript")," to get you started quickly. It requires very few runtime dependencies and has extremely minimal overhead."),(0,a.kt)("p",null,"Everything is customizable in oclif. Even the flag parser and help generation is optional and can be replaced. It's a platform to build upon that provides smart defaults without locking you in to any specific tools or behavior."),(0,a.kt)("h2",{id:"requirements"},"Requirements"),(0,a.kt)("p",null,"Only ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/about/releases/"},"LTS Node versions")," are supported. You can add the ",(0,a.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/node"},"node")," package to your CLI to ensure users are on a specific Node version."),(0,a.kt)("h2",{id:"quickstart"},"Quickstart"),(0,a.kt)("p",null,"Creating a CLI:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh-session"},"$ npx oclif generate mynewcli\n? npm package name (mynewcli): mynewcli\n$ cd mynewcli\n$ ./bin/dev hello world\nhello world! (./src/commands/hello/world.ts)\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5d5620c4.af357ea8.js b/assets/js/5d5620c4.af357ea8.js new file mode 100644 index 00000000..304250f8 --- /dev/null +++ b/assets/js/5d5620c4.af357ea8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1926],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=i.createContext({}),s=function(e){var t=i.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return i.createElement(p.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,p=e.parentName,u=r(e,["components","mdxType","originalType","parentName"]),c=s(n),m=a,g=c["".concat(p,".").concat(m)]||c[m]||d[m]||l;return n?i.createElement(g,o(o({ref:t},u),{},{components:n})):i.createElement(g,o({ref:t},u))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=m;var r={};for(var p in t)hasOwnProperty.call(t,p)&&(r[p]=t[p]);r.originalType=e,r[c]="string"==typeof e?e:a,o[1]=r;for(var s=2;s{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>p,default:()=>g,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var i=n(7462),a=n(3366),l=(n(7294),n(3905)),o=["components"],r={title:"ESM"},p=void 0,s={unversionedId:"esm",id:"esm",title:"ESM",description:"Version 3.0.0 of @oclif/core officially supports ESM plugin development and CJS/ESM interoperability, meaning that you can have a root plugin written with CJS and your bundled plugins written in ESM or vice versa.",source:"@site/../docs/esm.md",sourceDirName:".",slug:"/esm",permalink:"/docs/esm",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/esm.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"ESM"},sidebar:"docs",previous:{title:"Single Command CLI",permalink:"/docs/single_command_cli"},next:{title:"ES2022",permalink:"/docs/ES2022"}},u={},c=[{value:"Interoperability Overview",id:"interoperability-overview",level:2},{value:"ESM Root plugin",id:"esm-root-plugin",level:3},{value:"CJS Root plugin",id:"cjs-root-plugin",level:3},{value:"Creating an ESM plugin",id:"creating-an-esm-plugin",level:2},{value:"Migrating a CJS plugin to ESM",id:"migrating-a-cjs-plugin-to-esm",level:2},{value:"Update bin scripts",id:"update-bin-scripts",level:3},{value:"bin/dev \u2192 bin/dev.js",id:"bindev--bindevjs",level:4},{value:"bin/run \u2192 bin/run.js",id:"binrun--binrunjs",level:4},{value:"Update tsconfig.json",id:"update-tsconfigjson",level:3},{value:"Update package.json to "module" type",id:"update-packagejson-to-module-type",level:3},{value:"Update references to bin scripts",id:"update-references-to-bin-scripts",level:3},{value:"Update mocharc settings",id:"update-mocharc-settings",level:3}],d={toc:c},m="wrapper";function g(e){var t=e.components,n=(0,a.Z)(e,o);return(0,l.kt)(m,(0,i.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("p",null,"Version ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/tree/3.0.0-beta.12"},"3.0.0 of ",(0,l.kt)("inlineCode",{parentName:"a"},"@oclif/core"))," officially supports ESM plugin development and CJS/ESM interoperability, meaning that you can have a root plugin written with CJS and your bundled plugins written in ESM or vice versa."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#interoperability-overview"},"Interoperability Overview"),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#esm-root-plugin"},"ESM Root plugin")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#cjs-root-plugin"},"CJS Root plugin")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#creating-an-esm-plugin"},"Creating an ESM plugin")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#migrating-a-cjs-plugin-to-esm"},"Migrating a CJS plugin to ESM"),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-bin-scripts"},"Update bin scripts"),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#bindev--bindevjs"},"bin/dev \u2192 bin/dev.js")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#binrun--binrunjs"},"bin/run \u2192 bin/run.js")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-tsconfigjson"},"Update tsconfig.json")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-packagejson-to-module-type"},'Update package.json to "module" type')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-references-to-bin-scripts"},"Update references to bin scripts")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-mocharc-settings"},"Update mocharc settings"))))),(0,l.kt)("h2",{id:"interoperability-overview"},"Interoperability Overview"),(0,l.kt)("p",null,"Here's a high level overview of ESM/CJS interoperability:"),(0,l.kt)("h3",{id:"esm-root-plugin"},"ESM Root plugin"),(0,l.kt)("p",null,"\u2705 Install CJS plugins"),(0,l.kt)("p",null,"\u2705 Install ESM plugins"),(0,l.kt)("p",null,"\u2705 Link CJS plugins"),(0,l.kt)("p",null,"\u26a0\ufe0f Link ESM plugins"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Auto-compilation will ",(0,l.kt)("strong",{parentName:"li"},"not")," work with linked ESM plugins. Instead, oclif will use the plugin's compiled source - this means that you must compile the plugin yourself before executing any of the commands. We plan to support this again once the node ecosystem offers more comprehensive native support for ESM.")),(0,l.kt)("h3",{id:"cjs-root-plugin"},"CJS Root plugin"),(0,l.kt)("p",null,"\u2705 Install CJS plugins"),(0,l.kt)("p",null,"\u2705 Install ESM plugins"),(0,l.kt)("p",null,"\u2705 Link CJS plugins"),(0,l.kt)("p",null,"\u26a0\ufe0f Link ESM plugins"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Auto-compilation will ",(0,l.kt)("strong",{parentName:"li"},"not")," work with linked ESM plugins. Instead, oclif will use the plugin's compiled source - this means that you must compile the plugin yourself before executing any of the commands. We plan to support this again once the node ecosystem offers more comprehensive native support for ESM.")),(0,l.kt)("h2",{id:"creating-an-esm-plugin"},"Creating an ESM plugin"),(0,l.kt)("p",null,"To generate a new ESM plugin from the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/oclif/hello-world-esm"},"hello-world-esm template")," run the ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif generate")," command and select ",(0,l.kt)("inlineCode",{parentName:"p"},"ESM")," when it prompts you to select a module type:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"$ npx oclif generate my-esm-plugin\n? Select a module type\n CommonJS\n\u276f ESM\n")),(0,l.kt)("h2",{id:"migrating-a-cjs-plugin-to-esm"},"Migrating a CJS plugin to ESM"),(0,l.kt)("h3",{id:"update-bin-scripts"},"Update bin scripts"),(0,l.kt)("p",null,"First you will need to update the bin scripts under the ",(0,l.kt)("inlineCode",{parentName:"p"},"bin")," directory."),(0,l.kt)("h4",{id:"bindev--bindevjs"},"bin/dev \u2192 bin/dev.js"),(0,l.kt)("p",null,"Rename ",(0,l.kt)("inlineCode",{parentName:"p"},"bin/dev")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"bin/dev.js")," and replace the existing code with the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},"#!/usr/bin/env node\n// eslint-disable-next-line node/shebang\nvoid (async () => {\n const oclif = await import('@oclif/core')\n await oclif.execute({development: true, dir: import.meta.url})\n})()\n")),(0,l.kt)("p",null,"This leverages oclif's ",(0,l.kt)("inlineCode",{parentName:"p"},"execute")," function which handles all the development setup for you. You no longer need set the ",(0,l.kt)("inlineCode",{parentName:"p"},"NODE_ENV")," env var or register the project with ",(0,l.kt)("inlineCode",{parentName:"p"},"ts-node"),". You still adjust oclif ",(0,l.kt)("inlineCode",{parentName:"p"},"settings")," before executing the CLI. For example,"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},"#!/usr/bin/env node\n// eslint-disable-next-line node/shebang\nvoid (async () => {\n const oclif = await import('@oclif/core')\n oclif.settings.performanceEnabled = true\n await oclif.execute({type: 'esm', development: true, dir: import.meta.url})\n})()\n")),(0,l.kt)("h4",{id:"binrun--binrunjs"},"bin/run \u2192 bin/run.js"),(0,l.kt)("p",null,"Rename ",(0,l.kt)("inlineCode",{parentName:"p"},"bin/run")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"bin/run.js")," and replace the existing code with the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},"#!/usr/bin/env node\nvoid (async () => {\n const oclif = await import('@oclif/core')\n await oclif.execute({dir: import.meta.url})\n})()\n")),(0,l.kt)("h3",{id:"update-tsconfigjson"},"Update tsconfig.json"),(0,l.kt)("p",null,"After updating the bin scripts you now need to update the ",(0,l.kt)("inlineCode",{parentName:"p"},"tsconfig.json")," to include the following options:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},'{\n "compilerOptions": {\n "module": "ES2020",\n "moduleResolution": "node16",\n },\n "ts-node": {\n "esm": true\n }\n}\n')),(0,l.kt)("h3",{id:"update-packagejson-to-module-type"},'Update package.json to "module" type'),(0,l.kt)("p",null,"Add ",(0,l.kt)("inlineCode",{parentName:"p"},'"type": "module"')," to your package.json so that your files will be loaded as ESM modules"),(0,l.kt)("h3",{id:"update-references-to-bin-scripts"},"Update references to bin scripts"),(0,l.kt)("p",null,"You will need to update the references to your bin scripts to the bin scripts with the ",(0,l.kt)("inlineCode",{parentName:"p"},".js")," extension. In the ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json")," you will need to update the ",(0,l.kt)("inlineCode",{parentName:"p"},"bin")," like so:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},' "bin": {\n "my-cli": "./bin/run"\n },\n')),(0,l.kt)("p",null,"to"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},' "bin": {\n "my-cli": "./bin/run.js"\n },\n')),(0,l.kt)("p",null,"You may have references to the bin scripts in your ",(0,l.kt)("inlineCode",{parentName:"p"},".vscode/launch.json"),". You'll need to update these as well."),(0,l.kt)("h3",{id:"update-mocharc-settings"},"Update mocharc settings"),(0,l.kt)("p",null,"In order for your mocha tests to run, you'll need to make a couple of changes:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Add the following to the ",(0,l.kt)("inlineCode",{parentName:"li"},".mocharc.json"))),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},'{\n "node-option": [\n "loader=ts-node/esm"\n ]\n}\n')),(0,l.kt)("ol",{start:2},(0,l.kt)("li",{parentName:"ol"},"Update ",(0,l.kt)("inlineCode",{parentName:"li"},"test/helpers/init.js"))),(0,l.kt)("p",null,"If your plugin was generated ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif generate")," then you likely have a ",(0,l.kt)("inlineCode",{parentName:"p"},"test/helpers/init.js")," file that needs to be updated. You can either update the file extension to ",(0,l.kt)("inlineCode",{parentName:"p"},".cjs")," or update the ",(0,l.kt)("inlineCode",{parentName:"p"},"require")," at the top of the file to an ",(0,l.kt)("inlineCode",{parentName:"p"},"import"),","),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},"import path from 'node:path'\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5d5620c4.e0441eec.js b/assets/js/5d5620c4.e0441eec.js deleted file mode 100644 index 4614b723..00000000 --- a/assets/js/5d5620c4.e0441eec.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1926],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=i.createContext({}),s=function(e){var t=i.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return i.createElement(p.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,p=e.parentName,u=r(e,["components","mdxType","originalType","parentName"]),c=s(n),m=a,g=c["".concat(p,".").concat(m)]||c[m]||d[m]||l;return n?i.createElement(g,o(o({ref:t},u),{},{components:n})):i.createElement(g,o({ref:t},u))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=m;var r={};for(var p in t)hasOwnProperty.call(t,p)&&(r[p]=t[p]);r.originalType=e,r[c]="string"==typeof e?e:a,o[1]=r;for(var s=2;s{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>p,default:()=>g,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var i=n(7462),a=n(3366),l=(n(7294),n(3905)),o=["components"],r={title:"ESM"},p=void 0,s={unversionedId:"esm",id:"esm",title:"ESM",description:"Version 3.0.0 of @oclif/core officially supports ESM plugin development and CJS/ESM interoperability, meaning that you can have a root plugin written with CJS and your bundled plugins written in ESM or vice versa.",source:"@site/../docs/esm.md",sourceDirName:".",slug:"/esm",permalink:"/docs/esm",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/esm.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"ESM"},sidebar:"docs",previous:{title:"Single Command CLI",permalink:"/docs/single_command_cli"},next:{title:"ES2022",permalink:"/docs/ES2022"}},u={},c=[{value:"Interoperability Overview",id:"interoperability-overview",level:2},{value:"ESM Root plugin",id:"esm-root-plugin",level:3},{value:"CJS Root plugin",id:"cjs-root-plugin",level:3},{value:"Creating an ESM plugin",id:"creating-an-esm-plugin",level:2},{value:"Migrating a CJS plugin to ESM",id:"migrating-a-cjs-plugin-to-esm",level:2},{value:"Update bin scripts",id:"update-bin-scripts",level:3},{value:"bin/dev \u2192 bin/dev.js",id:"bindev--bindevjs",level:4},{value:"bin/run \u2192 bin/run.js",id:"binrun--binrunjs",level:4},{value:"Update tsconfig.json",id:"update-tsconfigjson",level:3},{value:"Update package.json to "module" type",id:"update-packagejson-to-module-type",level:3},{value:"Update references to bin scripts",id:"update-references-to-bin-scripts",level:3},{value:"Update mocharc settings",id:"update-mocharc-settings",level:3}],d={toc:c},m="wrapper";function g(e){var t=e.components,n=(0,a.Z)(e,o);return(0,l.kt)(m,(0,i.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("p",null,"Version ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/tree/3.0.0-beta.12"},"3.0.0 of ",(0,l.kt)("inlineCode",{parentName:"a"},"@oclif/core"))," officially supports ESM plugin development and CJS/ESM interoperability, meaning that you can have a root plugin written with CJS and your bundled plugins written in ESM or vice versa."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#interoperability-overview"},"Interoperability Overview"),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#esm-root-plugin"},"ESM Root plugin")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#cjs-root-plugin"},"CJS Root plugin")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#creating-an-esm-plugin"},"Creating an ESM plugin")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#migrating-a-cjs-plugin-to-esm"},"Migrating a CJS plugin to ESM"),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-bin-scripts"},"Update bin scripts"),(0,l.kt)("ul",{parentName:"li"},(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#bindev--bindevjs"},"bin/dev \u2192 bin/dev.js")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#binrun--binrunjs"},"bin/run \u2192 bin/run.js")))),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-tsconfigjson"},"Update tsconfig.json")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-packagejson-to-module-type"},'Update package.json to "module" type')),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-references-to-bin-scripts"},"Update references to bin scripts")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#update-mocharc-settings"},"Update mocharc settings"))))),(0,l.kt)("h2",{id:"interoperability-overview"},"Interoperability Overview"),(0,l.kt)("p",null,"Here's a high level overview of ESM/CJS interoperability:"),(0,l.kt)("h3",{id:"esm-root-plugin"},"ESM Root plugin"),(0,l.kt)("p",null,"\u2705 Install CJS plugins"),(0,l.kt)("p",null,"\u2705 Install ESM plugins"),(0,l.kt)("p",null,"\u2705 Link CJS plugins"),(0,l.kt)("p",null,"\u26a0\ufe0f Link ESM plugins"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Auto-compilation will ",(0,l.kt)("strong",{parentName:"li"},"not")," work with linked ESM plugins. Instead, oclif will use the plugin's compiled source - this means that you must compile the plugin yourself before executing any of the commands. We plan to support this again once the node ecosystem offers more comprehensive native support for ESM.")),(0,l.kt)("h3",{id:"cjs-root-plugin"},"CJS Root plugin"),(0,l.kt)("p",null,"\u2705 Install CJS plugins"),(0,l.kt)("p",null,"\u2705 Install ESM plugins"),(0,l.kt)("p",null,"\u2705 Link CJS plugins"),(0,l.kt)("p",null,"\u26a0\ufe0f Link ESM plugins"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Auto-compilation will ",(0,l.kt)("strong",{parentName:"li"},"not")," work with linked ESM plugins. Instead, oclif will use the plugin's compiled source - this means that you must compile the plugin yourself before executing any of the commands. We plan to support this again once the node ecosystem offers more comprehensive native support for ESM.")),(0,l.kt)("h2",{id:"creating-an-esm-plugin"},"Creating an ESM plugin"),(0,l.kt)("p",null,"To generate a new ESM plugin from the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/oclif/hello-world-esm"},"hello-world-esm template")," run the ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif generate")," command and select ",(0,l.kt)("inlineCode",{parentName:"p"},"ESM")," when it prompts you to select a module type:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"$ npx oclif generate my-esm-plugin\n? Select a module type\n CommonJS\n\u276f ESM\n")),(0,l.kt)("h2",{id:"migrating-a-cjs-plugin-to-esm"},"Migrating a CJS plugin to ESM"),(0,l.kt)("h3",{id:"update-bin-scripts"},"Update bin scripts"),(0,l.kt)("p",null,"First you will need to update the bin scripts under the ",(0,l.kt)("inlineCode",{parentName:"p"},"bin")," directory."),(0,l.kt)("h4",{id:"bindev--bindevjs"},"bin/dev \u2192 bin/dev.js"),(0,l.kt)("p",null,"Rename ",(0,l.kt)("inlineCode",{parentName:"p"},"bin/dev")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"bin/dev.js")," and replace the existing code with the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},"#!/usr/bin/env node\n// eslint-disable-next-line node/shebang\nvoid (async () => {\n const oclif = await import('@oclif/core')\n await oclif.execute({development: true, dir: import.meta.url})\n})()\n")),(0,l.kt)("p",null,"This leverages oclif's ",(0,l.kt)("inlineCode",{parentName:"p"},"execute")," function which handles all the development setup for you. You no longer need set the ",(0,l.kt)("inlineCode",{parentName:"p"},"NODE_ENV")," env var or register the project with ",(0,l.kt)("inlineCode",{parentName:"p"},"ts-node"),". You still adjust oclif ",(0,l.kt)("inlineCode",{parentName:"p"},"settings")," before executing the CLI. For example,"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},"#!/usr/bin/env node\n// eslint-disable-next-line node/shebang\nvoid (async () => {\n const oclif = await import('@oclif/core')\n oclif.settings.performanceEnabled = true\n await oclif.execute({type: 'esm', development: true, dir: import.meta.url})\n})()\n")),(0,l.kt)("h4",{id:"binrun--binrunjs"},"bin/run \u2192 bin/run.js"),(0,l.kt)("p",null,"Rename ",(0,l.kt)("inlineCode",{parentName:"p"},"bin/run")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"bin/run.js")," and replace the existing code with the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},"#!/usr/bin/env node\nvoid (async () => {\n const oclif = await import('@oclif/core')\n await oclif.execute({dir: import.meta.url})\n})()\n")),(0,l.kt)("h3",{id:"update-tsconfigjson"},"Update tsconfig.json"),(0,l.kt)("p",null,"After updating the bin scripts you now need to update the ",(0,l.kt)("inlineCode",{parentName:"p"},"tsconfig.json")," to include the following options:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},'{\n "compilerOptions": {\n "module": "ES2020",\n "moduleResolution": "node16",\n },\n "ts-node": {\n "esm": true\n }\n}\n')),(0,l.kt)("h3",{id:"update-packagejson-to-module-type"},'Update package.json to "module" type'),(0,l.kt)("p",null,"Add ",(0,l.kt)("inlineCode",{parentName:"p"},'"type": "module"')," to your package.json so that your files will be loaded as ESM modules"),(0,l.kt)("h3",{id:"update-references-to-bin-scripts"},"Update references to bin scripts"),(0,l.kt)("p",null,"You will need to update the references to your bin scripts to the bin scripts with the ",(0,l.kt)("inlineCode",{parentName:"p"},".js")," extension. In the ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json")," you will need to update the ",(0,l.kt)("inlineCode",{parentName:"p"},"bin")," like so:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},' "bin": {\n "my-cli": "./bin/run"\n },\n')),(0,l.kt)("p",null,"to"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},' "bin": {\n "my-cli": "./bin/run.js"\n },\n')),(0,l.kt)("p",null,"You may have references to the bin scripts in your ",(0,l.kt)("inlineCode",{parentName:"p"},".vscode/launch.json"),". You'll need to update these as well."),(0,l.kt)("h3",{id:"update-mocharc-settings"},"Update mocharc settings"),(0,l.kt)("p",null,"In order for your mocha tests to run, you'll need to make a couple of changes:"),(0,l.kt)("ol",null,(0,l.kt)("li",{parentName:"ol"},"Add the following to the ",(0,l.kt)("inlineCode",{parentName:"li"},".mocharc.json"))),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},'{\n "node-option": [\n "loader=ts-node/esm"\n ]\n}\n')),(0,l.kt)("ol",{start:2},(0,l.kt)("li",{parentName:"ol"},"Update ",(0,l.kt)("inlineCode",{parentName:"li"},"test/helpers/init.js"))),(0,l.kt)("p",null,"If your plugin was generated ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif generate")," then you likely have a ",(0,l.kt)("inlineCode",{parentName:"p"},"test/helpers/init.js")," file that needs to be updated. You can either update the file extension to ",(0,l.kt)("inlineCode",{parentName:"p"},".cjs")," or update the ",(0,l.kt)("inlineCode",{parentName:"p"},"require")," at the top of the file to an ",(0,l.kt)("inlineCode",{parentName:"p"},"import"),","),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},"import path from 'node:path'\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/61da8087.8164af3c.js b/assets/js/61da8087.8164af3c.js deleted file mode 100644 index f7f7456d..00000000 --- a/assets/js/61da8087.8164af3c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7117],{3905:(e,t,o)=>{o.d(t,{Zo:()=>p,kt:()=>m});var n=o(7294);function a(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function r(e){for(var t=1;t=0||(a[o]=e[o]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(a[o]=e[o])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var o=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(o),h=a,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||i;return o?n.createElement(m,r(r({ref:t},p),{},{components:o})):n.createElement(m,r({ref:t},p))}));function m(e,t){var o=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=o.length,r=new Array(i);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,r[1]=s;for(var c=2;c{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var n=o(7462),a=o(3366),i=(o(7294),o(3905)),r=["components"],s={title:"oclifconf 2019: A Recap"},l=void 0,c={permalink:"/blog/2019/09/16/oclifconf-recap",source:"@site/blog/2019-09-16-oclifconf-recap.md",title:"oclifconf 2019: A Recap",description:"In May, Heroku and Salesforce Open Source organized oclifconf, a conference for developers & product managers building CLI tools on top of the open source oclif framework. The speakers came from various tech companies, such as Adobe, Netlify, and Apollo, who have already built amazing CLI experiences. The topics covered everything from the incredible capabilities oclif has unlocked, to the community-built plugins extending its functionality, and even what the behavior of an adaptive CLI tool might look like.",date:"2019-09-16T00:00:00.000Z",formattedDate:"September 16, 2019",tags:[],readingTime:3.56,hasTruncateMarker:!1,authors:[],frontMatter:{title:"oclifconf 2019: A Recap"},prevItem:{title:"oclif's Current Node Support",permalink:"/blog/2019/10/31/oclif-node-updates"},nextItem:{title:"CLI Flags Explained",permalink:"/blog/2019/02/20/cli-flags-explained"}},p={authorsImageUrls:[]},d=[{value:"The future of oclif by Jeff Dickey",id:"the-future-of-oclif-by-jeff-dickey",level:2},{value:"Open Source Citizenship by Josh Simmons",id:"open-source-citizenship-by-josh-simmons",level:2},{value:"Building an enterprise-grade CLI with oclif by Thomas Dvornik",id:"building-an-enterprise-grade-cli-with-oclif-by-thomas-dvornik",level:2},{value:"How Adobe I/O built an extensible CLI with oclif by Jesse MacFadyen",id:"how-adobe-io-built-an-extensible-cli-with-oclif-by-jesse-macfadyen",level:2},{value:"Integrating oclif with GraphQL and Apollo by Evans Hauser",id:"integrating-oclif-with-graphql-and-apollo-by-evans-hauser",level:2},{value:"Adaptive Intent-based CLI State Machines by Shawn Wang",id:"adaptive-intent-based-cli-state-machines-by-shawn-wang",level:2}],u={toc:d},h="wrapper";function m(e){var t=e.components,o=(0,a.Z)(e,r);return(0,i.kt)(h,(0,n.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"In May, Heroku and Salesforce Open Source organized ",(0,i.kt)("a",{parentName:"p",href:"https://oclif.io/conf"},"oclifconf"),", a conference for developers & product managers building CLI tools on top of ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif"},"the open source oclif framework"),". The speakers came from various tech companies, such as Adobe, Netlify, and Apollo, who have already built amazing CLI experiences. The topics covered everything from the incredible capabilities oclif has unlocked, to the community-built plugins extending its functionality, and even what the behavior of an adaptive CLI tool might look like."),(0,i.kt)("p",null,"Below is a listing of all of the talks from the event, along with a short summary. Enjoy!"),(0,i.kt)("h2",{id:"the-future-of-oclif-by-jeff-dickey"},"The future of oclif by Jeff Dickey"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/1TKh2YBxRMY",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"In its relatively short lifetime, oclif has already inspired many developers and companies to adopt its framework as a means for implementing their own command-line tooling. In this talk, Jeff Dickey, an oclif founding team member, recaps the project's history and inspiration. He also looks towards the future and outlines some features and improvements that the tool could adapt. This isn't so much a definitive roadmap of where oclif is headed, but rather, a call to inspiration for developers eager to contribute! And if you are interested in contributing, check out the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif/issues"},"open issues"),' in the oclif GitHub repo and come say "Hello!" on ',(0,i.kt)("a",{parentName:"p",href:"https://spectrum.chat/oclif"},"Spectrum Chat"),"."),(0,i.kt)("h2",{id:"open-source-citizenship-by-josh-simmons"},"Open Source Citizenship by Josh Simmons"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/54hhR5DoV6g",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"When it comes to open source, it's more than just individuals now. More and more frequently, large corporations are contributing to projects by donating to contributors, sponsoring events, or upstreaming contributions. But keeping open source projects and communities healthy requires more than just money and brainpower. Josh Simmons surveyed multiple open source communities and relays his findings as to what help maintainers and contributors actually need in this talk."),(0,i.kt)("h2",{id:"building-an-enterprise-grade-cli-with-oclif-by-thomas-dvornik"},"Building an enterprise-grade CLI with oclif by Thomas Dvornik"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/v4saIi5zoy8",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"Security and performance are all about trust. While oclif is an extremely extensible framework for building CLI tooling, there are additional requirements to fulfill for enterprise businesses to adopt it that might not be necessary for individual developers. Thomas Dvornik outlines what he and his colleagues at Salesforce have implemented as plugins to oclif to satisfy these needs, including encrypted OAuth, plugin signing, lazy loading dependencies, synchronizing weekly releases and deprecations across dozens of repositories, and establishing cross-team coding and documentation standards."),(0,i.kt)("h2",{id:"how-adobe-io-built-an-extensible-cli-with-oclif-by-jesse-macfadyen"},"How Adobe I/O built an extensible CLI with oclif by Jesse MacFadyen"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/Mxhx1wmoHlA",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"Perhaps oclif's most appealing feature is its support for plugins. In Cordova's case, they've created a sophisticated telemetry system that helps Adobe developers see which commands users are using--and reports on which ones are erroring out. By embedding a feedback system into the tool, users are even able to quickly send their suggestions to a form, without ever leaving the terminal. Jesse MacFadyen demonstrates how oclif's plugin system can work beyond simply executing commands."),(0,i.kt)("h2",{id:"integrating-oclif-with-graphql-and-apollo-by-evans-hauser"},"Integrating oclif with GraphQL and Apollo by Evans Hauser"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/Zh78npkypas",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,'For Evans Hauser and the team at Apollo, oclif is best thought of as "React for the CLI." As a client paired with a strongly-typed API contract to a server, it can deliver structured and consistent commands to retrieve external data. What better mechanism to use for this transfer than GraphQL, a framework which empowers the client to ask precisely for the data it needs, and nothing more?'),(0,i.kt)("h2",{id:"adaptive-intent-based-cli-state-machines-by-shawn-wang"},"Adaptive Intent-based CLI State Machines by Shawn Wang"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/ZueoIYnHiaI",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"In designing oclif, ",(0,i.kt)("a",{parentName:"p",href:"https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46"},"Jeff Dickey wrote out 12 CLI factors to keep in mind"),". In this talk, Shawn Wang outlines a 13th: state. State is hard, because it depends on context, and context depends on understanding what a user intends to do, not what they are asking. Shawn is working towards enabling oclif to better understand the commands a user has entered, so that it can predict and interpret future commands that might be entered next. This would enable CLI tools to not just interpret a users' commands, but to also interpret their intent."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6f3bb722.39d31cf8.js b/assets/js/6f3bb722.39d31cf8.js deleted file mode 100644 index 5a881ba9..00000000 --- a/assets/js/6f3bb722.39d31cf8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8504],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),m=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=m(e.components);return o.createElement(l.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=m(n),u=r,h=c["".concat(l,".").concat(u)]||c[u]||p[u]||a;return n?o.createElement(h,i(i({ref:t},d),{},{components:n})):o.createElement(h,i({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:r,i[1]=s;for(var m=2;m{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>m,toc:()=>c});var o=n(7462),r=n(3366),a=(n(7294),n(3905)),i=["components"],s={title:"Commands"},l=void 0,m={unversionedId:"commands",id:"commands",title:"Commands",description:"A basic command looks like the following in TypeScript:",source:"@site/../docs/commands.md",sourceDirName:".",slug:"/commands",permalink:"/docs/commands",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/commands.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Commands"},sidebar:"docs",previous:{title:"Plugin Loading",permalink:"/docs/plugin_loading"},next:{title:"Command Arguments",permalink:"/docs/args"}},d={},c=[{value:"Avoiding Timeouts",id:"avoiding-timeouts",level:3},{value:"Other Command Options",id:"other-command-options",level:3},{value:"Command Methods",id:"command-methods",level:2},{value:"this.log(message: string)",id:"thislogmessage-string",level:3},{value:"this.warn(message: string | Error)",id:"thiswarnmessage-string--error",level:3},{value:"this.error(message: string | Error, options?: {code?: string, exit?: number, ref?: string; suggestions?: string[];})",id:"thiserrormessage-string--error-options-code-string-exit-number-ref-string-suggestions-string",level:3},{value:"this.exit(code: number = 0)",id:"thisexitcode-number--0",level:3},{value:"this.logToStderr(message: string)",id:"thislogtostderrmessage-string",level:3},{value:"this.jsonEnabled()",id:"thisjsonenabled",level:3},{value:"this.toSuccessJson(result: unknown)",id:"thistosuccessjsonresult-unknown",level:3},{value:"this.toErrorJson(result: unknown)",id:"thistoerrorjsonresult-unknown",level:3}],p={toc:c},u="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,i);return(0,a.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"A basic command looks like the following in TypeScript:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import {Command} from '@oclif/core'\n\nexport class MyCommand extends Command {\n static description = 'description of this example command'\n\n async run(): Promise {\n console.log('running my command')\n }\n}\n")),(0,a.kt)("p",null,"The only part that is required is the run function. Accept user input with ",(0,a.kt)("a",{parentName:"p",href:"/docs/args"},"arguments")," and ",(0,a.kt)("a",{parentName:"p",href:"/docs/flags"},"flags"),"."),(0,a.kt)("p",null,"In JavaScript:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"const {Command} = require('@oclif/core')\n\nclass MyCommand extends Command {\n async run() {\n console.log('running my command')\n }\n}\n\nMyCommand.description = 'description of this example command'\n\nmodule.exports = MyCommand\n")),(0,a.kt)("p",null,"Note that the following examples will be in TypeScript. As JavaScript does not yet have static class properties, you will have to add them to the class after it is declared like we did with the description above."),(0,a.kt)("h3",{id:"avoiding-timeouts"},"Avoiding Timeouts"),(0,a.kt)("p",null,"In order to avoid command executions running indefinitely, oclif will terminate the node process 10 seconds after ",(0,a.kt)("inlineCode",{parentName:"p"},"Command.run")," resolves. This means that all command logic inside the ",(0,a.kt)("inlineCode",{parentName:"p"},"run")," method should either run synchronously or should return a ",(0,a.kt)("inlineCode",{parentName:"p"},"Promise"),". This will allow the entire command to run before the 10 second timeout starts."),(0,a.kt)("p",null,"In other words, ",(0,a.kt)("strong",{parentName:"p"},"if you execute a promise in ",(0,a.kt)("inlineCode",{parentName:"strong"},"Command.run")," without a awaiting it, then the command will likely timeout before it's completed.")),(0,a.kt)("h3",{id:"other-command-options"},"Other Command Options"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/command.ts"},"See the base class to get an idea of what methods can be called on a command"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\n\nexport class MyCommand extends Command {\n static summary = 'A brief overview of your command.'\n static description = `\nAn in-depth description of the command.\nIt can be multiline.\n`\n\n // hide the command from help\n static hidden = false\n\n // custom usage string for help\n // this overrides the default usage\n static usage = 'mycommand --myflag'\n\n // examples to add to help\n // <%= config.bin %> resolves to the executable name\n // <%= command.id %> resolves to the command name\n static examples = [\n // Examples can be simple strings\n '<%= config.bin %> <%= command.id %> --help',\n // Or objects that provide a description of the example command\n {\n description: 'Force the command to execute',\n command: '<%= config.bin %> <%= command.id %> --force',\n }\n ]\n\n // this makes the parser not fail when it receives invalid arguments\n // defaults to true\n // set it to false if you need to accept a variable number of arguments\n static strict = false\n\n // define aliases that can execute this command.\n static aliases = ['alternate:name:for:this:command']\n\n // Set to true if you want to add the --json flag to your command.\n // oclif will automatically suppress logs (if you use this.log, this.warn, or this.error) and\n // display the JSON returned by the command's run method.\n static enableJsonFlag = true\n\n async run() {\n // show a warning\n this.warn('uh oh!')\n // exit with an error message\n this.error('uh oh!!!')\n // exit with status code\n this.exit(1)\n }\n}\n")),(0,a.kt)("h2",{id:"command-methods"},"Command Methods"),(0,a.kt)("p",null,""),(0,a.kt)("p",null,"The following assumes you are in the ",(0,a.kt)("inlineCode",{parentName:"p"},"run()")," method of an oclif ",(0,a.kt)("a",{parentName:"p",href:"/docs/commands"},"command"),"."),(0,a.kt)("h3",{id:"thislogmessage-string"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.log(message: string)")),(0,a.kt)("p",null,"Output message to stdout (non-blocking). ",(0,a.kt)("inlineCode",{parentName:"p"},"console.log()")," works fine too, but that is a blocking call and won't be automatically suppressed when the ",(0,a.kt)("inlineCode",{parentName:"p"},"--json")," flag is present. This uses ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/api/util.html#util_util_format_format_args"},"util.format()")," which behaves the same as ",(0,a.kt)("inlineCode",{parentName:"p"},"console.log()"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"this.log('hello, world!')\n")),(0,a.kt)("h3",{id:"thiswarnmessage-string--error"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.warn(message: string | Error)")),(0,a.kt)("p",null,"Display an error or message as a warning"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"this.warn('uh oh!')\nthis.warn(new Error('uh oh!'))\n")),(0,a.kt)("h3",{id:"thiserrormessage-string--error-options-code-string-exit-number-ref-string-suggestions-string"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.error(message: string | Error, options?: {code?: string, exit?: number, ref?: string; suggestions?: string[];})")),(0,a.kt)("p",null,"Display error and exit. Also add a code to error object or exit status."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"this.error('uh oh!', {exit: 2})\nthis.error(new Error('uh oh!'))\n")),(0,a.kt)("p",null,"The options object has the following options:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"exit")," \u2014 exit code to use"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"code")," \u2014 a unique error code for the type of error"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"suggestions")," \u2014 an array of suggestions for a user to try next that may be useful or provide additional context"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ref")," \u2014 a url to documentation related to this error or fixing it")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"message"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"code"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"suggestions"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"ref")," properties will be displayed when an error is shown. Reusable ",(0,a.kt)("inlineCode",{parentName:"p"},"Error")," classes can be created that display the optional outputs above by implementing the ",(0,a.kt)("inlineCode",{parentName:"p"},"PrettyPrintableError")," interface from @oclif/errors and ",(0,a.kt)("inlineCode",{parentName:"p"},"this.error")," will handle them appropriately."),(0,a.kt)("p",null,"Note: You may need to install the latest ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/core")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/errors")," for ",(0,a.kt)("inlineCode",{parentName:"p"},"code"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"suggestions")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"ref")," to be displayed."),(0,a.kt)("p",null,"These errors are friendly and won't show a traceback unless debugging is enabled with ",(0,a.kt)("inlineCode",{parentName:"p"},"DEBUG=*")," or ",(0,a.kt)("inlineCode",{parentName:"p"},"CLI_NAME_DEBUG=1"),". If you want to raise errors like this outside of a command, use ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/errors"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {CLIError} from '@oclif/errors'\n\nthrow new CLIError('my friendly error')\n")),(0,a.kt)("p",null,"Any error caught by the command of this ",(0,a.kt)("inlineCode",{parentName:"p"},"CLIError")," type will be shown without traceback."),(0,a.kt)("h3",{id:"thisexitcode-number--0"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.exit(code: number = 0)")),(0,a.kt)("p",null,"Exit process. Defaults to status 0."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"this.exit()\nthis.exit(1)\n")),(0,a.kt)("h3",{id:"thislogtostderrmessage-string"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.logToStderr(message: string)")),(0,a.kt)("p",null,"Log a message to the terminal's ",(0,a.kt)("inlineCode",{parentName:"p"},"stderr"),"."),(0,a.kt)("h3",{id:"thisjsonenabled"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.jsonEnabled()")),(0,a.kt)("p",null,"Returns to ",(0,a.kt)("inlineCode",{parentName:"p"},"true")," if the ",(0,a.kt)("inlineCode",{parentName:"p"},"--json")," flag is present and ",(0,a.kt)("inlineCode",{parentName:"p"},"enableJsonFlag")," is set to ",(0,a.kt)("inlineCode",{parentName:"p"},"true")),(0,a.kt)("h3",{id:"thistosuccessjsonresult-unknown"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.toSuccessJson(result: unknown)")),(0,a.kt)("p",null,"Modify the command's success JSON output before it's displayed to the user."),(0,a.kt)("h3",{id:"thistoerrorjsonresult-unknown"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.toErrorJson(result: unknown)")),(0,a.kt)("p",null,"Modify the command's error JSON output before it's displayed to the user."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6f3bb722.fc7f2554.js b/assets/js/6f3bb722.fc7f2554.js new file mode 100644 index 00000000..3feaea22 --- /dev/null +++ b/assets/js/6f3bb722.fc7f2554.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8504],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),m=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=m(e.components);return o.createElement(l.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=m(n),u=r,h=c["".concat(l,".").concat(u)]||c[u]||p[u]||a;return n?o.createElement(h,i(i({ref:t},d),{},{components:n})):o.createElement(h,i({ref:t},d))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:r,i[1]=s;for(var m=2;m{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>m,toc:()=>c});var o=n(7462),r=n(3366),a=(n(7294),n(3905)),i=["components"],s={title:"Commands"},l=void 0,m={unversionedId:"commands",id:"commands",title:"Commands",description:"A basic command looks like the following in TypeScript:",source:"@site/../docs/commands.md",sourceDirName:".",slug:"/commands",permalink:"/docs/commands",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/commands.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Commands"},sidebar:"docs",previous:{title:"Plugin Loading",permalink:"/docs/plugin_loading"},next:{title:"Command Arguments",permalink:"/docs/args"}},d={},c=[{value:"Avoiding Timeouts",id:"avoiding-timeouts",level:3},{value:"Other Command Options",id:"other-command-options",level:3},{value:"Command Methods",id:"command-methods",level:2},{value:"this.log(message: string)",id:"thislogmessage-string",level:3},{value:"this.warn(message: string | Error)",id:"thiswarnmessage-string--error",level:3},{value:"this.error(message: string | Error, options?: {code?: string, exit?: number, ref?: string; suggestions?: string[];})",id:"thiserrormessage-string--error-options-code-string-exit-number-ref-string-suggestions-string",level:3},{value:"this.exit(code: number = 0)",id:"thisexitcode-number--0",level:3},{value:"this.logToStderr(message: string)",id:"thislogtostderrmessage-string",level:3},{value:"this.jsonEnabled()",id:"thisjsonenabled",level:3},{value:"this.toSuccessJson(result: unknown)",id:"thistosuccessjsonresult-unknown",level:3},{value:"this.toErrorJson(result: unknown)",id:"thistoerrorjsonresult-unknown",level:3}],p={toc:c},u="wrapper";function h(e){var t=e.components,n=(0,r.Z)(e,i);return(0,a.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"A basic command looks like the following in TypeScript:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import {Command} from '@oclif/core'\n\nexport class MyCommand extends Command {\n static description = 'description of this example command'\n\n async run(): Promise {\n console.log('running my command')\n }\n}\n")),(0,a.kt)("p",null,"The only part that is required is the run function. Accept user input with ",(0,a.kt)("a",{parentName:"p",href:"/docs/args"},"arguments")," and ",(0,a.kt)("a",{parentName:"p",href:"/docs/flags"},"flags"),"."),(0,a.kt)("p",null,"In JavaScript:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"const {Command} = require('@oclif/core')\n\nclass MyCommand extends Command {\n async run() {\n console.log('running my command')\n }\n}\n\nMyCommand.description = 'description of this example command'\n\nmodule.exports = MyCommand\n")),(0,a.kt)("p",null,"Note that the following examples will be in TypeScript. As JavaScript does not yet have static class properties, you will have to add them to the class after it is declared like we did with the description above."),(0,a.kt)("h3",{id:"avoiding-timeouts"},"Avoiding Timeouts"),(0,a.kt)("p",null,"In order to avoid command executions running indefinitely, oclif will terminate the node process 10 seconds after ",(0,a.kt)("inlineCode",{parentName:"p"},"Command.run")," resolves. This means that all command logic inside the ",(0,a.kt)("inlineCode",{parentName:"p"},"run")," method should either run synchronously or should return a ",(0,a.kt)("inlineCode",{parentName:"p"},"Promise"),". This will allow the entire command to run before the 10 second timeout starts."),(0,a.kt)("p",null,"In other words, ",(0,a.kt)("strong",{parentName:"p"},"if you execute a promise in ",(0,a.kt)("inlineCode",{parentName:"strong"},"Command.run")," without a awaiting it, then the command will likely timeout before it's completed.")),(0,a.kt)("h3",{id:"other-command-options"},"Other Command Options"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/command.ts"},"See the base class to get an idea of what methods can be called on a command"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\n\nexport class MyCommand extends Command {\n static summary = 'A brief overview of your command.'\n static description = `\nAn in-depth description of the command.\nIt can be multiline.\n`\n\n // hide the command from help\n static hidden = false\n\n // custom usage string for help\n // this overrides the default usage\n static usage = 'mycommand --myflag'\n\n // examples to add to help\n // <%= config.bin %> resolves to the executable name\n // <%= command.id %> resolves to the command name\n static examples = [\n // Examples can be simple strings\n '<%= config.bin %> <%= command.id %> --help',\n // Or objects that provide a description of the example command\n {\n description: 'Force the command to execute',\n command: '<%= config.bin %> <%= command.id %> --force',\n }\n ]\n\n // this makes the parser not fail when it receives invalid arguments\n // defaults to true\n // set it to false if you need to accept a variable number of arguments\n static strict = false\n\n // define aliases that can execute this command.\n static aliases = ['alternate:name:for:this:command']\n\n // Set to true if you want to add the --json flag to your command.\n // oclif will automatically suppress logs (if you use this.log, this.warn, or this.error) and\n // display the JSON returned by the command's run method.\n static enableJsonFlag = true\n\n async run() {\n // show a warning\n this.warn('uh oh!')\n // exit with an error message\n this.error('uh oh!!!')\n // exit with status code\n this.exit(1)\n }\n}\n")),(0,a.kt)("h2",{id:"command-methods"},"Command Methods"),(0,a.kt)("p",null,""),(0,a.kt)("p",null,"The following assumes you are in the ",(0,a.kt)("inlineCode",{parentName:"p"},"run()")," method of an oclif ",(0,a.kt)("a",{parentName:"p",href:"/docs/commands"},"command"),"."),(0,a.kt)("h3",{id:"thislogmessage-string"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.log(message: string)")),(0,a.kt)("p",null,"Output message to stdout (non-blocking). ",(0,a.kt)("inlineCode",{parentName:"p"},"console.log()")," works fine too, but that is a blocking call and won't be automatically suppressed when the ",(0,a.kt)("inlineCode",{parentName:"p"},"--json")," flag is present. This uses ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/api/util.html#util_util_format_format_args"},"util.format()")," which behaves the same as ",(0,a.kt)("inlineCode",{parentName:"p"},"console.log()"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"this.log('hello, world!')\n")),(0,a.kt)("h3",{id:"thiswarnmessage-string--error"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.warn(message: string | Error)")),(0,a.kt)("p",null,"Display an error or message as a warning"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"this.warn('uh oh!')\nthis.warn(new Error('uh oh!'))\n")),(0,a.kt)("h3",{id:"thiserrormessage-string--error-options-code-string-exit-number-ref-string-suggestions-string"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.error(message: string | Error, options?: {code?: string, exit?: number, ref?: string; suggestions?: string[];})")),(0,a.kt)("p",null,"Display error and exit. Also add a code to error object or exit status."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"this.error('uh oh!', {exit: 2})\nthis.error(new Error('uh oh!'))\n")),(0,a.kt)("p",null,"The options object has the following options:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"exit")," \u2014 exit code to use"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"code")," \u2014 a unique error code for the type of error"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"suggestions")," \u2014 an array of suggestions for a user to try next that may be useful or provide additional context"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ref")," \u2014 a url to documentation related to this error or fixing it")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"message"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"code"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"suggestions"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"ref")," properties will be displayed when an error is shown. Reusable ",(0,a.kt)("inlineCode",{parentName:"p"},"Error")," classes can be created that display the optional outputs above by implementing the ",(0,a.kt)("inlineCode",{parentName:"p"},"PrettyPrintableError")," interface from @oclif/errors and ",(0,a.kt)("inlineCode",{parentName:"p"},"this.error")," will handle them appropriately."),(0,a.kt)("p",null,"Note: You may need to install the latest ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/core")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/errors")," for ",(0,a.kt)("inlineCode",{parentName:"p"},"code"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"suggestions")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"ref")," to be displayed."),(0,a.kt)("p",null,"These errors are friendly and won't show a traceback unless debugging is enabled with ",(0,a.kt)("inlineCode",{parentName:"p"},"DEBUG=*")," or ",(0,a.kt)("inlineCode",{parentName:"p"},"CLI_NAME_DEBUG=1"),". If you want to raise errors like this outside of a command, use ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/errors"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {CLIError} from '@oclif/errors'\n\nthrow new CLIError('my friendly error')\n")),(0,a.kt)("p",null,"Any error caught by the command of this ",(0,a.kt)("inlineCode",{parentName:"p"},"CLIError")," type will be shown without traceback."),(0,a.kt)("h3",{id:"thisexitcode-number--0"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.exit(code: number = 0)")),(0,a.kt)("p",null,"Exit process. Defaults to status 0."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"this.exit()\nthis.exit(1)\n")),(0,a.kt)("h3",{id:"thislogtostderrmessage-string"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.logToStderr(message: string)")),(0,a.kt)("p",null,"Log a message to the terminal's ",(0,a.kt)("inlineCode",{parentName:"p"},"stderr"),"."),(0,a.kt)("h3",{id:"thisjsonenabled"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.jsonEnabled()")),(0,a.kt)("p",null,"Returns to ",(0,a.kt)("inlineCode",{parentName:"p"},"true")," if the ",(0,a.kt)("inlineCode",{parentName:"p"},"--json")," flag is present and ",(0,a.kt)("inlineCode",{parentName:"p"},"enableJsonFlag")," is set to ",(0,a.kt)("inlineCode",{parentName:"p"},"true")),(0,a.kt)("h3",{id:"thistosuccessjsonresult-unknown"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.toSuccessJson(result: unknown)")),(0,a.kt)("p",null,"Modify the command's success JSON output before it's displayed to the user."),(0,a.kt)("h3",{id:"thistoerrorjsonresult-unknown"},(0,a.kt)("inlineCode",{parentName:"h3"},"this.toErrorJson(result: unknown)")),(0,a.kt)("p",null,"Modify the command's error JSON output before it's displayed to the user."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/713bb917.a73a27c1.js b/assets/js/713bb917.a73a27c1.js new file mode 100644 index 00000000..8a4b1b95 --- /dev/null +++ b/assets/js/713bb917.a73a27c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[187],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),u=p(a),h=i,m=u["".concat(s,".").concat(h)]||u[h]||c[h]||l;return a?n.createElement(m,o(o({ref:t},d),{},{components:a})):n.createElement(m,o({ref:t},d))}));function m(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var l=a.length,o=new Array(l);o[0]=h;var r={};for(var s in t)hasOwnProperty.call(t,s)&&(r[s]=t[s]);r.originalType=e,r[u]="string"==typeof e?e:i,o[1]=r;for(var p=2;p{a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>m,frontMatter:()=>r,metadata:()=>p,toc:()=>u});var n=a(7462),i=a(3366),l=(a(7294),a(3905)),o=["components"],r={title:"Release"},s=void 0,p={unversionedId:"releasing",id:"releasing",title:"Release",description:"There are 2 main strategies for releasing oclif CLIs: npm and standalone tarballs. You can publish to one or both.",source:"@site/../docs/releasing.md",sourceDirName:".",slug:"/releasing",permalink:"/docs/releasing",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/releasing.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Release"},sidebar:"docs",previous:{title:"JSON",permalink:"/docs/json"},next:{title:"Testing",permalink:"/docs/testing"}},d={},u=[{value:"npm",id:"npm",level:2},{value:"Standalone tarballs",id:"standalone-tarballs",level:2},{value:"Brew",id:"brew",level:2},{value:"Autoupdater",id:"autoupdater",level:2},{value:"Autoupdate Channels",id:"autoupdate-channels",level:2},{value:"Windows installer",id:"windows-installer",level:2},{value:"macOS installer",id:"macos-installer",level:2},{value:"Ubuntu/Debian packages",id:"ubuntudebian-packages",level:2},{value:"Snapcraft",id:"snapcraft",level:2}],c={toc:u},h="wrapper";function m(e){var t=e.components,a=(0,i.Z)(e,o);return(0,l.kt)(h,(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("p",null,"There are 2 main strategies for releasing oclif CLIs: npm and standalone tarballs. You can publish to one or both."),(0,l.kt)("h2",{id:"npm"},"npm"),(0,l.kt)("p",null,"Just use ",(0,l.kt)("inlineCode",{parentName:"p"},"npm publish")," like any other npm project. This includes a ",(0,l.kt)("inlineCode",{parentName:"p"},"run.cmd")," script that will automatically be used for Windows users."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh-session"},"$ npm version (major|minor|patch) # bumps version, updates README, adds git tag\n$ npm publish\n$ npm install -g mynewcli\n$ mynewcli\n# OR\n$ npx mynewcli\n")),(0,l.kt)("p",null,"You'll need to ",(0,l.kt)("a",{parentName:"p",href:"https://www.npmjs.com/signup"},"register with npm")," and have verified your email address in order to publish."),(0,l.kt)("p",null,"This workflow can be improved slightly by running ",(0,l.kt)("inlineCode",{parentName:"p"},"npm version major|minor|patch")," before publishing which will create a git tag and bump the version automatically."),(0,l.kt)("h2",{id:"standalone-tarballs"},"Standalone tarballs"),(0,l.kt)("p",null,"Build standalone tarballs with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack tarballs")," from the root of your CLI. These include the node binary so the user does not have to already have node installed to use the CLI. It won't put this node binary on the PATH so the binary will not conflict with any node installation on the machine."),(0,l.kt)("p",null,"To publish, you can copy the files from ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist")," or use ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif upload tarballs")," to copy the files to S3. You'll need to set ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif.update.s3.bucket")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json")," to a valid S3 bucket and have credentials set in ",(0,l.kt)("inlineCode",{parentName:"p"},"AWS_ACCESS_KEY_ID")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"AWS_SECRET_ACCESS_KEY")," environment vars."),(0,l.kt)("p",null,"After you've uploaded the tarballs to S3, you can promote the tarballs to a release channel within S3 using ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif promote"),". This allows you to quickly promote and demote a specific version between release channels. For example, the Salesforce CLI has separate ",(0,l.kt)("inlineCode",{parentName:"p"},"stable")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"stable-rc")," channels that are updated weekly."),(0,l.kt)("h2",{id:"brew"},"Brew"),(0,l.kt)("p",null,"Your formula can be distributed through Brew. The main caveat is you must set the ",(0,l.kt)("inlineCode",{parentName:"p"},"CLIENT_HOME")," variable when you ship, otherwise it will break the update cycle. An example of this can be found in the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/heroku/homebrew-brew/blob/master/Formula/heroku.rb#L9"},"heroku cli formula"),". By exporting a variable of the form ",(0,l.kt)("inlineCode",{parentName:"p"},"CLI_NAME_OCLIF_CLIENT_HOME")," (where ",(0,l.kt)("inlineCode",{parentName:"p"},"CLI_NAME")," is the name of your CLI), you force the update mechanism to look at the brew install location instead of the default (which is ",(0,l.kt)("inlineCode",{parentName:"p"},"$XDG_DATA_HOME/.local/share/package_name/client"),")."),(0,l.kt)("h2",{id:"autoupdater"},"Autoupdater"),(0,l.kt)("p",null,"These tarballs as well as the installers below can be made autoupdatable by adding the ",(0,l.kt)("inlineCode",{parentName:"p"},"@oclif/plugin-update")," plugin. Just add this plugin and the CLI will autoupdate in the background or when ",(0,l.kt)("inlineCode",{parentName:"p"},"mycli update")," is run."),(0,l.kt)("p",null,"If you don't want to use S3, you can still run ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack")," and it will build tarballs. To get the updater to work, set ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif.update.s3.host")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json")," to a host that has the files built in ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist")," from ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack"),". This host does not need to be an S3 host. To customize the URL paths, see the S3 templates in ",(0,l.kt)("inlineCode",{parentName:"p"},"@oclif/core"),"."),(0,l.kt)("h2",{id:"autoupdate-channels"},"Autoupdate Channels"),(0,l.kt)("p",null,"You can have separate channels for releases that work like Google Chrome Channels (such as beta, dev, canary). To create a channel, just change the version in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json")," from ",(0,l.kt)("inlineCode",{parentName:"p"},"1.0.0")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"1.0.0-beta"),' (where "beta" is any string you like). Then when you pack with ',(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack"),", it will create beta tarballs. The user can change their channel with ",(0,l.kt)("inlineCode",{parentName:"p"},"mycli update beta")," and will receive all the future releases on that channel."),(0,l.kt)("p",null,"In the Heroku CLI, we have it automatically build and release the beta channel on every commit to the master branch. Then we have it build and release stable channel whenever a git tag is created in our CI."),(0,l.kt)("h2",{id:"windows-installer"},"Windows installer"),(0,l.kt)("p",null,"Build a windows installer with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack win"),". It will build into ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist/win"),". This can be uploaded to S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif upload win")," and promoted within S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif promote --win"),"."),(0,l.kt)("h2",{id:"macos-installer"},"macOS installer"),(0,l.kt)("p",null,"Build a macOS .pkg installer with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack macos"),". It will build into ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist/macos"),". This can be uploaded to S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif upload macos")," and promoted within S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif promote --macos"),". You need to set the macOS identifier at ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif.macos.identifier")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json"),' (we use "com.heroku.cli" and "com.salesforce.cli" as the identifiers for the Heroku CLI and the Salesforce CLI, respectively).'),(0,l.kt)("p",null,"To ",(0,l.kt)("a",{parentName:"p",href:"https://developer.apple.com/developer-id/"},"sign the installer"),", set ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif.macos.sign")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json"),' to a certificate (For the Heroku CLI this is "Developer ID Installer: Heroku INC"). And optionally set the keychain with ',(0,l.kt)("inlineCode",{parentName:"p"},"OSX_KEYCHAIN"),"."),(0,l.kt)("h2",{id:"ubuntudebian-packages"},"Ubuntu/Debian packages"),(0,l.kt)("p",null,"Build a deb package with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack deb"),". Set the ",(0,l.kt)("inlineCode",{parentName:"p"},"MYCLI_DEB_KEY")," to a gpg key id to create the gpg files. This will include all the files needed for an apt repository in ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist/deb"),". They can be uploaded to S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif upload deb")," and promoted within S3 using ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif promote --deb"),"."),(0,l.kt)("p",null,"Once it's published to S3, users can install with the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh-session"},'$ wget -qO- https://mys3bucket.s3.amazonaws.com/apt/release.key | apt-key add - # you will need to upload this file manually\n$ sudo echo "deb https://mys3bucket.s3.amazonaws.com/apt ./" > /etc/apt/sources.list.d/mycli.list\n$ sudo apt update\n$ sudo apt install -y mycli\n')),(0,l.kt)("p",null,"This can be placed in a ",(0,l.kt)("a",{parentName:"p",href:"https://cli-assets.heroku.com/install-ubuntu.sh"},"script")," for users to install with ",(0,l.kt)("inlineCode",{parentName:"p"},"curl https://pathto/myscript | sh"),"."),(0,l.kt)("p",null,"These will not autoupdate as Ubuntu already has a reliable way for users to update their package."),(0,l.kt)("h2",{id:"snapcraft"},"Snapcraft"),(0,l.kt)("p",null,"Snap is a great way to distribute Linux CLIs and comes built into Ubuntu 16+. The Heroku CLI's ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/heroku/cli/blob/master/snap/snapcraft.yaml"},"snapcraft.yml")," file can be easily modified to work with any oclif CLI."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/713bb917.d046d7a9.js b/assets/js/713bb917.d046d7a9.js deleted file mode 100644 index 6a73c5e4..00000000 --- a/assets/js/713bb917.d046d7a9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[187],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),u=p(a),h=i,m=u["".concat(s,".").concat(h)]||u[h]||c[h]||l;return a?n.createElement(m,o(o({ref:t},d),{},{components:a})):n.createElement(m,o({ref:t},d))}));function m(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var l=a.length,o=new Array(l);o[0]=h;var r={};for(var s in t)hasOwnProperty.call(t,s)&&(r[s]=t[s]);r.originalType=e,r[u]="string"==typeof e?e:i,o[1]=r;for(var p=2;p{a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>m,frontMatter:()=>r,metadata:()=>p,toc:()=>u});var n=a(7462),i=a(3366),l=(a(7294),a(3905)),o=["components"],r={title:"Release"},s=void 0,p={unversionedId:"releasing",id:"releasing",title:"Release",description:"There are 2 main strategies for releasing oclif CLIs: npm and standalone tarballs. You can publish to one or both.",source:"@site/../docs/releasing.md",sourceDirName:".",slug:"/releasing",permalink:"/docs/releasing",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/releasing.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Release"},sidebar:"docs",previous:{title:"JSON",permalink:"/docs/json"},next:{title:"Testing",permalink:"/docs/testing"}},d={},u=[{value:"npm",id:"npm",level:2},{value:"Standalone tarballs",id:"standalone-tarballs",level:2},{value:"Brew",id:"brew",level:2},{value:"Autoupdater",id:"autoupdater",level:2},{value:"Autoupdate Channels",id:"autoupdate-channels",level:2},{value:"Windows installer",id:"windows-installer",level:2},{value:"macOS installer",id:"macos-installer",level:2},{value:"Ubuntu/Debian packages",id:"ubuntudebian-packages",level:2},{value:"Snapcraft",id:"snapcraft",level:2}],c={toc:u},h="wrapper";function m(e){var t=e.components,a=(0,i.Z)(e,o);return(0,l.kt)(h,(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("p",null,"There are 2 main strategies for releasing oclif CLIs: npm and standalone tarballs. You can publish to one or both."),(0,l.kt)("h2",{id:"npm"},"npm"),(0,l.kt)("p",null,"Just use ",(0,l.kt)("inlineCode",{parentName:"p"},"npm publish")," like any other npm project. This includes a ",(0,l.kt)("inlineCode",{parentName:"p"},"run.cmd")," script that will automatically be used for Windows users."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh-session"},"$ npm version (major|minor|patch) # bumps version, updates README, adds git tag\n$ npm publish\n$ npm install -g mynewcli\n$ mynewcli\n# OR\n$ npx mynewcli\n")),(0,l.kt)("p",null,"You'll need to ",(0,l.kt)("a",{parentName:"p",href:"https://www.npmjs.com/signup"},"register with npm")," and have verified your email address in order to publish."),(0,l.kt)("p",null,"This workflow can be improved slightly by running ",(0,l.kt)("inlineCode",{parentName:"p"},"npm version major|minor|patch")," before publishing which will create a git tag and bump the version automatically."),(0,l.kt)("h2",{id:"standalone-tarballs"},"Standalone tarballs"),(0,l.kt)("p",null,"Build standalone tarballs with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack tarballs")," from the root of your CLI. These include the node binary so the user does not have to already have node installed to use the CLI. It won't put this node binary on the PATH so the binary will not conflict with any node installation on the machine."),(0,l.kt)("p",null,"To publish, you can copy the files from ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist")," or use ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif upload tarballs")," to copy the files to S3. You'll need to set ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif.update.s3.bucket")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json")," to a valid S3 bucket and have credentials set in ",(0,l.kt)("inlineCode",{parentName:"p"},"AWS_ACCESS_KEY_ID")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"AWS_SECRET_ACCESS_KEY")," environment vars."),(0,l.kt)("p",null,"After you've uploaded the tarballs to S3, you can promote the tarballs to a release channel within S3 using ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif promote"),". This allows you to quickly promote and demote a specific version between release channels. For example, the Salesforce CLI has separate ",(0,l.kt)("inlineCode",{parentName:"p"},"stable")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"stable-rc")," channels that are updated weekly."),(0,l.kt)("h2",{id:"brew"},"Brew"),(0,l.kt)("p",null,"Your formula can be distributed through Brew. The main caveat is you must set the ",(0,l.kt)("inlineCode",{parentName:"p"},"CLIENT_HOME")," variable when you ship, otherwise it will break the update cycle. An example of this can be found in the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/heroku/homebrew-brew/blob/master/Formula/heroku.rb#L9"},"heroku cli formula"),". By exporting a variable of the form ",(0,l.kt)("inlineCode",{parentName:"p"},"CLI_NAME_OCLIF_CLIENT_HOME")," (where ",(0,l.kt)("inlineCode",{parentName:"p"},"CLI_NAME")," is the name of your CLI), you force the update mechanism to look at the brew install location instead of the default (which is ",(0,l.kt)("inlineCode",{parentName:"p"},"$XDG_DATA_HOME/.local/share/package_name/client"),")."),(0,l.kt)("h2",{id:"autoupdater"},"Autoupdater"),(0,l.kt)("p",null,"These tarballs as well as the installers below can be made autoupdatable by adding the ",(0,l.kt)("inlineCode",{parentName:"p"},"@oclif/plugin-update")," plugin. Just add this plugin and the CLI will autoupdate in the background or when ",(0,l.kt)("inlineCode",{parentName:"p"},"mycli update")," is run."),(0,l.kt)("p",null,"If you don't want to use S3, you can still run ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack")," and it will build tarballs. To get the updater to work, set ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif.update.s3.host")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json")," to a host that has the files built in ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist")," from ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack"),". This host does not need to be an S3 host. To customize the URL paths, see the S3 templates in ",(0,l.kt)("inlineCode",{parentName:"p"},"@oclif/core"),"."),(0,l.kt)("h2",{id:"autoupdate-channels"},"Autoupdate Channels"),(0,l.kt)("p",null,"You can have separate channels for releases that work like Google Chrome Channels (such as beta, dev, canary). To create a channel, just change the version in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json")," from ",(0,l.kt)("inlineCode",{parentName:"p"},"1.0.0")," to ",(0,l.kt)("inlineCode",{parentName:"p"},"1.0.0-beta"),' (where "beta" is any string you like). Then when you pack with ',(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack"),", it will create beta tarballs. The user can change their channel with ",(0,l.kt)("inlineCode",{parentName:"p"},"mycli update beta")," and will receive all the future releases on that channel."),(0,l.kt)("p",null,"In the Heroku CLI, we have it automatically build and release the beta channel on every commit to the master branch. Then we have it build and release stable channel whenever a git tag is created in our CI."),(0,l.kt)("h2",{id:"windows-installer"},"Windows installer"),(0,l.kt)("p",null,"Build a windows installer with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack win"),". It will build into ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist/win"),". This can be uploaded to S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif upload win")," and promoted within S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif promote --win"),"."),(0,l.kt)("h2",{id:"macos-installer"},"macOS installer"),(0,l.kt)("p",null,"Build a macOS .pkg installer with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack macos"),". It will build into ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist/macos"),". This can be uploaded to S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif upload macos")," and promoted within S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif promote --macos"),". You need to set the macOS identifier at ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif.macos.identifier")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json"),' (we use "com.heroku.cli" and "com.salesforce.cli" as the identifiers for the Heroku CLI and the Salesforce CLI, respectively).'),(0,l.kt)("p",null,"To ",(0,l.kt)("a",{parentName:"p",href:"https://developer.apple.com/developer-id/"},"sign the installer"),", set ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif.macos.sign")," in ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json"),' to a certificate (For the Heroku CLI this is "Developer ID Installer: Heroku INC"). And optionally set the keychain with ',(0,l.kt)("inlineCode",{parentName:"p"},"OSX_KEYCHAIN"),"."),(0,l.kt)("h2",{id:"ubuntudebian-packages"},"Ubuntu/Debian packages"),(0,l.kt)("p",null,"Build a deb package with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif pack deb"),". Set the ",(0,l.kt)("inlineCode",{parentName:"p"},"MYCLI_DEB_KEY")," to a gpg key id to create the gpg files. This will include all the files needed for an apt repository in ",(0,l.kt)("inlineCode",{parentName:"p"},"./dist/deb"),". They can be uploaded to S3 with ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif upload deb")," and promoted within S3 using ",(0,l.kt)("inlineCode",{parentName:"p"},"oclif promote --deb"),"."),(0,l.kt)("p",null,"Once it's published to S3, users can install with the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh-session"},'$ wget -qO- https://mys3bucket.s3.amazonaws.com/apt/release.key | apt-key add - # you will need to upload this file manually\n$ sudo echo "deb https://mys3bucket.s3.amazonaws.com/apt ./" > /etc/apt/sources.list.d/mycli.list\n$ sudo apt update\n$ sudo apt install -y mycli\n')),(0,l.kt)("p",null,"This can be placed in a ",(0,l.kt)("a",{parentName:"p",href:"https://cli-assets.heroku.com/install-ubuntu.sh"},"script")," for users to install with ",(0,l.kt)("inlineCode",{parentName:"p"},"curl https://pathto/myscript | sh"),"."),(0,l.kt)("p",null,"These will not autoupdate as Ubuntu already has a reliable way for users to update their package."),(0,l.kt)("h2",{id:"snapcraft"},"Snapcraft"),(0,l.kt)("p",null,"Snap is a great way to distribute Linux CLIs and comes built into Ubuntu 16+. The Heroku CLI's ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/heroku/cli/blob/master/snap/snapcraft.yaml"},"snapcraft.yml")," file can be easily modified to work with any oclif CLI."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/765c6b61.3586cbba.js b/assets/js/765c6b61.ff5592fd.js similarity index 90% rename from assets/js/765c6b61.3586cbba.js rename to assets/js/765c6b61.ff5592fd.js index 0c612b89..9ac433d2 100644 --- a/assets/js/765c6b61.3586cbba.js +++ b/assets/js/765c6b61.ff5592fd.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[4535],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},g=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),g=r,f=d["".concat(s,".").concat(g)]||d[g]||u[g]||i;return n?o.createElement(f,a(a({ref:t},p),{},{components:n})):o.createElement(f,a({ref:t},p))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:r,a[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var o=n(7462),r=n(3366),i=(n(7294),n(3905)),a=["components"],l={title:"oclif's Current Node Support"},s=void 0,c={permalink:"/blog/2019/10/31/oclif-node-updates",source:"@site/blog/2019-10-31-oclif-node-updates.md",title:"oclif's Current Node Support",description:"To maintain a healthy project trajectory, oclif follows and supports Node Active LTS release, currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining Node 8 and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes.",date:"2019-10-31T00:00:00.000Z",formattedDate:"October 31, 2019",tags:[],readingTime:2.4,hasTruncateMarker:!1,authors:[],frontMatter:{title:"oclif's Current Node Support"},prevItem:{title:"oclif TSLint to ESLint Migration",permalink:"/blog/2019/12/05/oclif-eslint-migration"},nextItem:{title:"oclifconf 2019: A Recap",permalink:"/blog/2019/09/16/oclifconf-recap"}},p={authorsImageUrls:[]},d=[{value:"CI Environments",id:"ci-environments",level:2},{value:".circleci/config.yml",id:"circleciconfigyml",level:3},{value:"appveyor.yml",id:"appveyoryml",level:3},{value:"Deprecating Node 8 & Updating packge.json engines",id:"deprecating-node-8--updating-packgejson-engines",level:2},{value:"Packaged Node Version",id:"packaged-node-version",level:2},{value:"Supporting the future",id:"supporting-the-future",level:2}],u={toc:d},g="wrapper";function f(e){var t=e.components,n=(0,r.Z)(e,a);return(0,i.kt)(g,(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"To maintain a healthy project trajectory, oclif follows and supports ",(0,i.kt)("a",{parentName:"p",href:"https://nodejs.org/en/about/releases/"},"Node Active LTS release"),", currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/nodejs/Release#release-schedule"},"Node 8")," and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes."),(0,i.kt)("h2",{id:"ci-environments"},"CI Environments"),(0,i.kt)("p",null,"CLIs created with the oclif cli going forward will be generated with a CircleCI configuration with Node 10 & 12 and an Appveyor configuration using Node 10. We have also added Node latest to CircleCi to be an early warning detection against coming Node changes (Node latest is managed by CircleCI)."),(0,i.kt)("p",null,"We have already updated every oclif repo's CI configs to reflect this."),(0,i.kt)("p",null,"If your existing CLI uses either Appveyor or CircleCI you can update your config files also, like so:"),(0,i.kt)("h3",{id:"circleciconfigyml"},".circleci/config.yml"),(0,i.kt)("p",null,"Your CircleCI config should contain a ",(0,i.kt)("inlineCode",{parentName:"p"},"node-latest")," job, aliased as ",(0,i.kt)("inlineCode",{parentName:"p"},"test"),". From this, there should be two extensions of this job for the Active LTS Node versions, Node 10 and Node 12."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," node-10:\n <<: *node-latest\n docker:\n - image: node:10\n node-12:\n <<: *node-latest\n docker:\n - image: node:12\n")),(0,i.kt)("p",null,"Notice that these declarations only change the Docker Node images used to run that job."),(0,i.kt)("p",null,"Additionally, the jobs listed within workflows must also be updated to reflect our changes in configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," jobs:\n - node-latest\n - node-10\n - node-12\n")),(0,i.kt)("h3",{id:"appveyoryml"},"appveyor.yml"),(0,i.kt)("p",null,"For appveyor we are currently only testing the oldest Active LTS Node version, Node 10. Update the ",(0,i.kt)("inlineCode",{parentName:"p"},"nodejs_version")," proppert in your appveyor.yml file to reflect this."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'environment:\n nodejs_version: "10"\n')),(0,i.kt)("h2",{id:"deprecating-node-8--updating-packgejson-engines"},"Deprecating Node 8 & Updating packge.json engines"),(0,i.kt)("p",null,"In Jan 2020, Node will end its Node 8 maintenance. We will follow suit by setting the package.json engine property in oclif packages to ",(0,i.kt)("inlineCode",{parentName:"p"},">=10")," and bumping the package's major versions."),(0,i.kt)("p",null,"Depending on how you ship your CLI you may wish to also bump the engines version in your CLI's package.json. You can read more about the implications of the engines property configuration in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/files/package.json#engines"},"npm documentation"),"."),(0,i.kt)("p",null,"Also consider distributing your CLI with ",(0,i.kt)("a",{parentName:"p",href:"https://oclif.io/docs/releasing#standalone-tarballs"},"its own Node version"),"."),(0,i.kt)("h2",{id:"packaged-node-version"},"Packaged Node Version"),(0,i.kt)("p",null,"When using dev-cli to pack your CLI it will use the Node version as specified in your package.json under the ",(0,i.kt)("inlineCode",{parentName:"p"},"oclif.update.node.version")," property. This value should reflect an Active LTS Node version (dev-cli does not currently enforce versions)."),(0,i.kt)("h2",{id:"supporting-the-future"},"Supporting the future"),(0,i.kt)("p",null,"As a community we may discover bumps along the way as we upgrade. If you notice something related to oclif please feel free to open an issue or submit a pull request under the relevant oclif package within ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/oclif"},"the org"),"."),(0,i.kt)("p",null,"We look forward to using the latest from Node and the community and keeping oclif healthy along the way."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[4535],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),p=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},g=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=p(n),g=r,f=d["".concat(s,".").concat(g)]||d[g]||u[g]||i;return n?o.createElement(f,a(a({ref:t},c),{},{components:n})):o.createElement(f,a({ref:t},c))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:r,a[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>p,toc:()=>d});var o=n(7462),r=n(3366),i=(n(7294),n(3905)),a=["components"],l={title:"oclif's Current Node Support"},s=void 0,p={permalink:"/blog/2019/10/31/oclif-node-updates",source:"@site/blog/2019-10-31-oclif-node-updates.md",title:"oclif's Current Node Support",description:"To maintain a healthy project trajectory, oclif follows and supports Node Active LTS release, currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining Node 8 and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes.",date:"2019-10-31T00:00:00.000Z",formattedDate:"October 31, 2019",tags:[],readingTime:2.4,hasTruncateMarker:!1,authors:[],frontMatter:{title:"oclif's Current Node Support"},prevItem:{title:"oclif TSLint to ESLint Migration",permalink:"/blog/2019/12/05/oclif-eslint-migration"},nextItem:{title:"CLI Flags Explained",permalink:"/blog/2019/02/20/cli-flags-explained"}},c={authorsImageUrls:[]},d=[{value:"CI Environments",id:"ci-environments",level:2},{value:".circleci/config.yml",id:"circleciconfigyml",level:3},{value:"appveyor.yml",id:"appveyoryml",level:3},{value:"Deprecating Node 8 & Updating packge.json engines",id:"deprecating-node-8--updating-packgejson-engines",level:2},{value:"Packaged Node Version",id:"packaged-node-version",level:2},{value:"Supporting the future",id:"supporting-the-future",level:2}],u={toc:d},g="wrapper";function f(e){var t=e.components,n=(0,r.Z)(e,a);return(0,i.kt)(g,(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"To maintain a healthy project trajectory, oclif follows and supports ",(0,i.kt)("a",{parentName:"p",href:"https://nodejs.org/en/about/releases/"},"Node Active LTS release"),", currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/nodejs/Release#release-schedule"},"Node 8")," and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes."),(0,i.kt)("h2",{id:"ci-environments"},"CI Environments"),(0,i.kt)("p",null,"CLIs created with the oclif cli going forward will be generated with a CircleCI configuration with Node 10 & 12 and an Appveyor configuration using Node 10. We have also added Node latest to CircleCi to be an early warning detection against coming Node changes (Node latest is managed by CircleCI)."),(0,i.kt)("p",null,"We have already updated every oclif repo's CI configs to reflect this."),(0,i.kt)("p",null,"If your existing CLI uses either Appveyor or CircleCI you can update your config files also, like so:"),(0,i.kt)("h3",{id:"circleciconfigyml"},".circleci/config.yml"),(0,i.kt)("p",null,"Your CircleCI config should contain a ",(0,i.kt)("inlineCode",{parentName:"p"},"node-latest")," job, aliased as ",(0,i.kt)("inlineCode",{parentName:"p"},"test"),". From this, there should be two extensions of this job for the Active LTS Node versions, Node 10 and Node 12."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," node-10:\n <<: *node-latest\n docker:\n - image: node:10\n node-12:\n <<: *node-latest\n docker:\n - image: node:12\n")),(0,i.kt)("p",null,"Notice that these declarations only change the Docker Node images used to run that job."),(0,i.kt)("p",null,"Additionally, the jobs listed within workflows must also be updated to reflect our changes in configuration:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"}," jobs:\n - node-latest\n - node-10\n - node-12\n")),(0,i.kt)("h3",{id:"appveyoryml"},"appveyor.yml"),(0,i.kt)("p",null,"For appveyor we are currently only testing the oldest Active LTS Node version, Node 10. Update the ",(0,i.kt)("inlineCode",{parentName:"p"},"nodejs_version")," proppert in your appveyor.yml file to reflect this."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'environment:\n nodejs_version: "10"\n')),(0,i.kt)("h2",{id:"deprecating-node-8--updating-packgejson-engines"},"Deprecating Node 8 & Updating packge.json engines"),(0,i.kt)("p",null,"In Jan 2020, Node will end its Node 8 maintenance. We will follow suit by setting the package.json engine property in oclif packages to ",(0,i.kt)("inlineCode",{parentName:"p"},">=10")," and bumping the package's major versions."),(0,i.kt)("p",null,"Depending on how you ship your CLI you may wish to also bump the engines version in your CLI's package.json. You can read more about the implications of the engines property configuration in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/files/package.json#engines"},"npm documentation"),"."),(0,i.kt)("p",null,"Also consider distributing your CLI with ",(0,i.kt)("a",{parentName:"p",href:"https://oclif.io/docs/releasing#standalone-tarballs"},"its own Node version"),"."),(0,i.kt)("h2",{id:"packaged-node-version"},"Packaged Node Version"),(0,i.kt)("p",null,"When using dev-cli to pack your CLI it will use the Node version as specified in your package.json under the ",(0,i.kt)("inlineCode",{parentName:"p"},"oclif.update.node.version")," property. This value should reflect an Active LTS Node version (dev-cli does not currently enforce versions)."),(0,i.kt)("h2",{id:"supporting-the-future"},"Supporting the future"),(0,i.kt)("p",null,"As a community we may discover bumps along the way as we upgrade. If you notice something related to oclif please feel free to open an issue or submit a pull request under the relevant oclif package within ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/oclif"},"the org"),"."),(0,i.kt)("p",null,"We look forward to using the latest from Node and the community and keeping oclif healthy along the way."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7bd58895.25bba184.js b/assets/js/7bd58895.25bba184.js new file mode 100644 index 00000000..ba3de178 --- /dev/null +++ b/assets/js/7bd58895.25bba184.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[257],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),m=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=m(e.components);return r.createElement(p.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),c=m(n),d=o,g=c["".concat(p,".").concat(d)]||c[d]||u[d]||a;return n?r.createElement(g,i(i({ref:t},l),{},{components:n})):r.createElement(g,i({ref:t},l))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[c]="string"==typeof e?e:o,i[1]=s;for(var m=2;m{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>p,default:()=>g,frontMatter:()=>s,metadata:()=>m,toc:()=>c});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),i=["components"],s={title:"Prompting"},p=void 0,m={unversionedId:"prompting",id:"prompting",title:"Prompting",description:"The ux export provides a simple cli.prompt() function, for more complex input prompts, we recommend using the inquirer library.",source:"@site/../docs/prompting.md",sourceDirName:".",slug:"/prompting",permalink:"/docs/prompting",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/prompting.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Prompting"},sidebar:"docs",previous:{title:"Custom Base Class",permalink:"/docs/base_class"},next:{title:"Spinner",permalink:"/docs/spinner"}},l={},c=[{value:"ux.prompt()",id:"uxprompt",level:2},{value:"inquirer",id:"inquirer",level:2}],u={toc:c},d="wrapper";function g(e){var t=e.components,s=(0,o.Z)(e,i);return(0,a.kt)(d,(0,r.Z)({},u,s,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/cli-ux/README.md"},"ux")," export provides a simple ",(0,a.kt)("inlineCode",{parentName:"p"},"cli.prompt()")," function, for more complex input prompts, we recommend using the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/SBoudrias/Inquirer.js"},"inquirer")," library."),(0,a.kt)("h2",{id:"uxprompt"},(0,a.kt)("inlineCode",{parentName:"h2"},"ux.prompt()")),(0,a.kt)("p",null,"Prompt for basic input with ",(0,a.kt)("inlineCode",{parentName:"p"},"ux"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, ux} from '@oclif/core'\n\nexport class MyCommand extends Command {\n async run() {\n // just prompt for input\n const name = await ux.prompt('What is your name?')\n\n // mask input after enter is pressed\n const secondFactor = await ux.prompt('What is your two-factor token?', {type: 'mask'})\n\n // hide input while typing\n const password = await ux.prompt('What is your password?', {type: 'hide'})\n\n this.log(`You entered: ${name}, ${secondFactor}, ${password}`)\n }\n}\n")),(0,a.kt)("p",null,"Demo:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"prompt demo",src:n(740).Z,width:"941",height:"605"})),(0,a.kt)("h2",{id:"inquirer"},(0,a.kt)("inlineCode",{parentName:"h2"},"inquirer")),(0,a.kt)("p",null,"Here is an example command that uses ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/SBoudrias/Inquirer.js"},"inquirer"),". You will need to add ",(0,a.kt)("inlineCode",{parentName:"p"},"inquirer")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"@types/inquirer")," (for TypeScript CLIs) for this to work."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\nimport * as inquirer from 'inquirer'\n\nexport class MyCommand extends Command {\n static flags = {\n stage: Flags.string({options: ['development', 'staging', 'production']})\n }\n\n async run() {\n const {flags} = await this.parse(MyCommand)\n let stage = flags.stage\n if (!stage) {\n let responses: any = await inquirer.prompt([{\n name: 'stage',\n message: 'select a stage',\n type: 'list',\n choices: [{name: 'development'}, {name: 'staging'}, {name: 'production'}],\n }])\n stage = responses.stage\n }\n this.log(`the stage is: ${stage}`)\n }\n}\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"NOTE"),": inquirer >= v9 is an ESM package. If you aren't using ESM in your CLI/plugin, you should set ",(0,a.kt)("a",{parentName:"p",href:"https://www.typescriptlang.org/tsconfig#moduleResolution"},(0,a.kt)("inlineCode",{parentName:"a"},"moduleResolution")," to ",(0,a.kt)("inlineCode",{parentName:"a"},"node16"))," in your tsconfig.json and ",(0,a.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"},"import it using ",(0,a.kt)("inlineCode",{parentName:"a"},"await import")),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\n\nexport class MyCommand extends Command {\n static flags = {\n stage: Flags.string({options: ['development', 'staging', 'production']})\n }\n\n async run() {\n const {flags} = await this.parse(MyCommand)\n let stage = flags.stage\n if (!stage) {\n const { default: inquirer } = await import(\"inquirer\")\n let responses: any = inquirer.prompt([{\n name: 'stage',\n message: 'select a stage',\n type: 'list',\n choices: [{name: 'development'}, {name: 'staging'}, {name: 'production'}],\n }])\n stage = responses.stage\n }\n this.log(`the stage is: ${stage}`)\n }\n}\n")),(0,a.kt)("p",null,"Demo:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"inquirer demo",src:n(2813).Z,width:"1254",height:"806"})))}g.isMDXComponent=!0},2813:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/inquirer_demo-4d4cd8f9cf0bf300a5b853a4beef5672.gif"},740:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/prompt_demo-7bc9d5f614fdad73636bec3c864aff15.gif"}}]); \ No newline at end of file diff --git a/assets/js/7bd58895.78b0552b.js b/assets/js/7bd58895.78b0552b.js deleted file mode 100644 index 98109710..00000000 --- a/assets/js/7bd58895.78b0552b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[257],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var p=r.createContext({}),m=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=m(e.components);return r.createElement(p.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),c=m(n),d=o,g=c["".concat(p,".").concat(d)]||c[d]||u[d]||a;return n?r.createElement(g,i(i({ref:t},l),{},{components:n})):r.createElement(g,i({ref:t},l))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[c]="string"==typeof e?e:o,i[1]=s;for(var m=2;m{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>p,default:()=>g,frontMatter:()=>s,metadata:()=>m,toc:()=>c});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),i=["components"],s={title:"Prompting"},p=void 0,m={unversionedId:"prompting",id:"prompting",title:"Prompting",description:"The ux export provides a simple cli.prompt() function, for more complex input prompts, we recommend using the inquirer library.",source:"@site/../docs/prompting.md",sourceDirName:".",slug:"/prompting",permalink:"/docs/prompting",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/prompting.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Prompting"},sidebar:"docs",previous:{title:"Custom Base Class",permalink:"/docs/base_class"},next:{title:"Spinner",permalink:"/docs/spinner"}},l={},c=[{value:"ux.prompt()",id:"uxprompt",level:2},{value:"inquirer",id:"inquirer",level:2}],u={toc:c},d="wrapper";function g(e){var t=e.components,s=(0,o.Z)(e,i);return(0,a.kt)(d,(0,r.Z)({},u,s,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/cli-ux/README.md"},"ux")," export provides a simple ",(0,a.kt)("inlineCode",{parentName:"p"},"cli.prompt()")," function, for more complex input prompts, we recommend using the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/SBoudrias/Inquirer.js"},"inquirer")," library."),(0,a.kt)("h2",{id:"uxprompt"},(0,a.kt)("inlineCode",{parentName:"h2"},"ux.prompt()")),(0,a.kt)("p",null,"Prompt for basic input with ",(0,a.kt)("inlineCode",{parentName:"p"},"ux"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, ux} from '@oclif/core'\n\nexport class MyCommand extends Command {\n async run() {\n // just prompt for input\n const name = await ux.prompt('What is your name?')\n\n // mask input after enter is pressed\n const secondFactor = await ux.prompt('What is your two-factor token?', {type: 'mask'})\n\n // hide input while typing\n const password = await ux.prompt('What is your password?', {type: 'hide'})\n\n this.log(`You entered: ${name}, ${secondFactor}, ${password}`)\n }\n}\n")),(0,a.kt)("p",null,"Demo:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"prompt demo",src:n(740).Z,width:"941",height:"605"})),(0,a.kt)("h2",{id:"inquirer"},(0,a.kt)("inlineCode",{parentName:"h2"},"inquirer")),(0,a.kt)("p",null,"Here is an example command that uses ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/SBoudrias/Inquirer.js"},"inquirer"),". You will need to add ",(0,a.kt)("inlineCode",{parentName:"p"},"inquirer")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"@types/inquirer")," (for TypeScript CLIs) for this to work."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\nimport * as inquirer from 'inquirer'\n\nexport class MyCommand extends Command {\n static flags = {\n stage: Flags.string({options: ['development', 'staging', 'production']})\n }\n\n async run() {\n const {flags} = await this.parse(MyCommand)\n let stage = flags.stage\n if (!stage) {\n let responses: any = await inquirer.prompt([{\n name: 'stage',\n message: 'select a stage',\n type: 'list',\n choices: [{name: 'development'}, {name: 'staging'}, {name: 'production'}],\n }])\n stage = responses.stage\n }\n this.log(`the stage is: ${stage}`)\n }\n}\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"NOTE"),": inquirer >= v9 is an ESM package. If you aren't using ESM in your CLI/plugin, you should set ",(0,a.kt)("a",{parentName:"p",href:"https://www.typescriptlang.org/tsconfig#moduleResolution"},(0,a.kt)("inlineCode",{parentName:"a"},"moduleResolution")," to ",(0,a.kt)("inlineCode",{parentName:"a"},"node16"))," in your tsconfig.json and ",(0,a.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"},"import it using ",(0,a.kt)("inlineCode",{parentName:"a"},"await import")),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\n\nexport class MyCommand extends Command {\n static flags = {\n stage: Flags.string({options: ['development', 'staging', 'production']})\n }\n\n async run() {\n const {flags} = await this.parse(MyCommand)\n let stage = flags.stage\n if (!stage) {\n const { default: inquirer } = await import(\"inquirer\")\n let responses: any = inquirer.prompt([{\n name: 'stage',\n message: 'select a stage',\n type: 'list',\n choices: [{name: 'development'}, {name: 'staging'}, {name: 'production'}],\n }])\n stage = responses.stage\n }\n this.log(`the stage is: ${stage}`)\n }\n}\n")),(0,a.kt)("p",null,"Demo:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"inquirer demo",src:n(2813).Z,width:"1254",height:"806"})))}g.isMDXComponent=!0},2813:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/inquirer_demo-4d4cd8f9cf0bf300a5b853a4beef5672.gif"},740:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/prompt_demo-7bc9d5f614fdad73636bec3c864aff15.gif"}}]); \ No newline at end of file diff --git a/assets/js/82247a8b.d70508e5.js b/assets/js/82247a8b.d70508e5.js new file mode 100644 index 00000000..c3b373b2 --- /dev/null +++ b/assets/js/82247a8b.d70508e5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2026],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>f});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},m=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),c=p(n),d=r,f=c["".concat(s,".").concat(d)]||c[d]||u[d]||i;return n?a.createElement(f,o(o({ref:t},m),{},{components:n})):a.createElement(f,o({ref:t},m))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:r,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>m,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var a=n(7462),r=n(3366),i=(n(7294),n(3905)),o=["components"],l={title:"Configuration"},s=void 0,p={unversionedId:"config",id:"config",title:"Configuration",description:"Inside a command, this.config provides useful properties you can use in your command. Here are a list of its methods and properties:",source:"@site/../docs/config.md",sourceDirName:".",slug:"/config",permalink:"/docs/config",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/config.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Configuration"},sidebar:"docs",previous:{title:"Command Flags",permalink:"/docs/flags"},next:{title:"Topics",permalink:"/docs/topics"}},m={},c=[{value:"Custom User Configuration",id:"custom-user-configuration",level:2}],u={toc:c},d="wrapper";function f(e){var t=e.components,n=(0,r.Z)(e,o);return(0,i.kt)(d,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Inside a command, ",(0,i.kt)("inlineCode",{parentName:"p"},"this.config")," provides useful properties you can use in your command. Here are a list of its methods and properties:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"name")," - name of CLI"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"version")," - Version of the CLI."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"pjson")," - Parsed and ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/npm/normalize-package-data"},"normalized")," CLI ",(0,i.kt)("inlineCode",{parentName:"li"},"package.json"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"bin")," - CLI bin name"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"binAliases")," - An array of strings that will all execute the CLI's bin. This is useful for backwards compatibility and for CLIs built with installers or tarballs. For npm-installed CLIs, change the ",(0,i.kt)("inlineCode",{parentName:"li"},"bin")," property in ",(0,i.kt)("inlineCode",{parentName:"li"},"package.json")," instead. See ",(0,i.kt)("a",{parentName:"li",href:"https://oclif.io/docs/aliases"},"Bin Aliases")," for more information."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"nsisCustomization")," - A path to a .nsis file that's used to customize the installer for Windows. See ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/oclif/nsis-custom"},"nsis-custom")," for more information."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"cacheDir")," - CLI cache directory",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"macOS: ",(0,i.kt)("inlineCode",{parentName:"li"},"~/Library/Caches/mycli")),(0,i.kt)("li",{parentName:"ul"},"Unix: ",(0,i.kt)("inlineCode",{parentName:"li"},"~/.cache/mycli")),(0,i.kt)("li",{parentName:"ul"},"Windows: ",(0,i.kt)("inlineCode",{parentName:"li"},"%LOCALAPPDATA%\\mycli")),(0,i.kt)("li",{parentName:"ul"},"Can be overridden with ",(0,i.kt)("inlineCode",{parentName:"li"},"XDG_CACHE_HOME")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"configDir")," - CLI config directory",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Unix: ",(0,i.kt)("inlineCode",{parentName:"li"},"~/.config/mycli")),(0,i.kt)("li",{parentName:"ul"},"Windows: ",(0,i.kt)("inlineCode",{parentName:"li"},"%LOCALAPPDATA%\\mycli")),(0,i.kt)("li",{parentName:"ul"},"Can be overridden with ",(0,i.kt)("inlineCode",{parentName:"li"},"XDG_CONFIG_HOME")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"dataDir")," - CLI data directory",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Unix: ",(0,i.kt)("inlineCode",{parentName:"li"},"~/.data/mycli")),(0,i.kt)("li",{parentName:"ul"},"Windows: ",(0,i.kt)("inlineCode",{parentName:"li"},"%LOCALAPPDATA%\\mycli")),(0,i.kt)("li",{parentName:"ul"},"Can be overridden with ",(0,i.kt)("inlineCode",{parentName:"li"},"XDG_DATA_HOME")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"dirname")," - dirname used with ",(0,i.kt)("inlineCode",{parentName:"li"},"cacheDir|configDir|dataDir"),". Can be overridden in ",(0,i.kt)("inlineCode",{parentName:"li"},"package.json"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"errlog")," - path to error log inside of ",(0,i.kt)("inlineCode",{parentName:"li"},"cacheDir")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"home")," - user home directory"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"platform")," - operating system ",(0,i.kt)("inlineCode",{parentName:"li"},"darwin|linux|win32")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"arch")," - process architecture ",(0,i.kt)("inlineCode",{parentName:"li"},"x64|x86")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"shell")," - current shell in use"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"userAgent")," - user-agent intended for http calls. example: ",(0,i.kt)("inlineCode",{parentName:"li"},"mycli/1.2.3 (darwin-x64) node-9.0.0")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"windows")," - boolean"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"topicSeparator")," - the separator to use between topics - only colons (",(0,i.kt)("inlineCode",{parentName:"li"},'":"'),") and spaces (",(0,i.kt)("inlineCode",{parentName:"li"},'" "'),") are supported."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"debug")," - set to 1 if debug is enabled (with ",(0,i.kt)("inlineCode",{parentName:"li"},"${BIN}_DEBUG=1")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"DEBUG=$BIN"),"). In the future this may be used for multiple debug levels."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"npmRegistry")," - current npm registry to use with the ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-plugins"},"plugins")," plugin"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"plugins")," - loaded plugins"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"commands")," - all commands in CLI"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"default")," - default cli command"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"topics")," - all topics in CLI"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"commandIDs")," - string IDs of all commands"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"async runHook(event, opts)")," - trigger a hook")),(0,i.kt)("h2",{id:"custom-user-configuration"},"Custom User Configuration"),(0,i.kt)("p",null,"Often it's useful to have a custom configuration for your users. One way to implement this is to read a ",(0,i.kt)("inlineCode",{parentName:"p"},"config.json")," file from the CLI's config directory:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command} from '@oclif/core'\nimport * as fs from 'fs-extra'\nimport * as path from 'path'\n\nexport class extends Command {\n async run() {\n const userConfig = await fs.readJSON(path.join(this.config.configDir, 'config.json'))\n\n this.log('User config:')\n console.dir(userConfig)\n }\n}\n")),(0,i.kt)("p",null,"To share this logic between different commands, use a ",(0,i.kt)("a",{parentName:"p",href:"/docs/base_class"},"base class"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/82247a8b.fba1120f.js b/assets/js/82247a8b.fba1120f.js deleted file mode 100644 index 6b4f7725..00000000 --- a/assets/js/82247a8b.fba1120f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2026],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>f});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},m=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),c=p(n),d=r,f=c["".concat(s,".").concat(d)]||c[d]||u[d]||i;return n?a.createElement(f,o(o({ref:t},m),{},{components:n})):a.createElement(f,o({ref:t},m))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:r,o[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>m,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var a=n(7462),r=n(3366),i=(n(7294),n(3905)),o=["components"],l={title:"Configuration"},s=void 0,p={unversionedId:"config",id:"config",title:"Configuration",description:"Inside a command, this.config provides useful properties you can use in your command. Here are a list of its methods and properties:",source:"@site/../docs/config.md",sourceDirName:".",slug:"/config",permalink:"/docs/config",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/config.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Configuration"},sidebar:"docs",previous:{title:"Command Flags",permalink:"/docs/flags"},next:{title:"Topics",permalink:"/docs/topics"}},m={},c=[{value:"Custom User Configuration",id:"custom-user-configuration",level:2}],u={toc:c},d="wrapper";function f(e){var t=e.components,n=(0,r.Z)(e,o);return(0,i.kt)(d,(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Inside a command, ",(0,i.kt)("inlineCode",{parentName:"p"},"this.config")," provides useful properties you can use in your command. Here are a list of its methods and properties:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"name")," - name of CLI"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"version")," - Version of the CLI."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"pjson")," - Parsed and ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/npm/normalize-package-data"},"normalized")," CLI ",(0,i.kt)("inlineCode",{parentName:"li"},"package.json"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"bin")," - CLI bin name"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"binAliases")," - An array of strings that will all execute the CLI's bin. This is useful for backwards compatibility and for CLIs built with installers or tarballs. For npm-installed CLIs, change the ",(0,i.kt)("inlineCode",{parentName:"li"},"bin")," property in ",(0,i.kt)("inlineCode",{parentName:"li"},"package.json")," instead. See ",(0,i.kt)("a",{parentName:"li",href:"https://oclif.io/docs/aliases"},"Bin Aliases")," for more information."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"nsisCustomization")," - A path to a .nsis file that's used to customize the installer for Windows. See ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/oclif/nsis-custom"},"nsis-custom")," for more information."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"cacheDir")," - CLI cache directory",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"macOS: ",(0,i.kt)("inlineCode",{parentName:"li"},"~/Library/Caches/mycli")),(0,i.kt)("li",{parentName:"ul"},"Unix: ",(0,i.kt)("inlineCode",{parentName:"li"},"~/.cache/mycli")),(0,i.kt)("li",{parentName:"ul"},"Windows: ",(0,i.kt)("inlineCode",{parentName:"li"},"%LOCALAPPDATA%\\mycli")),(0,i.kt)("li",{parentName:"ul"},"Can be overridden with ",(0,i.kt)("inlineCode",{parentName:"li"},"XDG_CACHE_HOME")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"configDir")," - CLI config directory",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Unix: ",(0,i.kt)("inlineCode",{parentName:"li"},"~/.config/mycli")),(0,i.kt)("li",{parentName:"ul"},"Windows: ",(0,i.kt)("inlineCode",{parentName:"li"},"%LOCALAPPDATA%\\mycli")),(0,i.kt)("li",{parentName:"ul"},"Can be overridden with ",(0,i.kt)("inlineCode",{parentName:"li"},"XDG_CONFIG_HOME")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"dataDir")," - CLI data directory",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Unix: ",(0,i.kt)("inlineCode",{parentName:"li"},"~/.data/mycli")),(0,i.kt)("li",{parentName:"ul"},"Windows: ",(0,i.kt)("inlineCode",{parentName:"li"},"%LOCALAPPDATA%\\mycli")),(0,i.kt)("li",{parentName:"ul"},"Can be overridden with ",(0,i.kt)("inlineCode",{parentName:"li"},"XDG_DATA_HOME")))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"dirname")," - dirname used with ",(0,i.kt)("inlineCode",{parentName:"li"},"cacheDir|configDir|dataDir"),". Can be overridden in ",(0,i.kt)("inlineCode",{parentName:"li"},"package.json"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"errlog")," - path to error log inside of ",(0,i.kt)("inlineCode",{parentName:"li"},"cacheDir")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"home")," - user home directory"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"platform")," - operating system ",(0,i.kt)("inlineCode",{parentName:"li"},"darwin|linux|win32")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"arch")," - process architecture ",(0,i.kt)("inlineCode",{parentName:"li"},"x64|x86")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"shell")," - current shell in use"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"userAgent")," - user-agent intended for http calls. example: ",(0,i.kt)("inlineCode",{parentName:"li"},"mycli/1.2.3 (darwin-x64) node-9.0.0")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"windows")," - boolean"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"topicSeparator")," - the separator to use between topics - only colons (",(0,i.kt)("inlineCode",{parentName:"li"},'":"'),") and spaces (",(0,i.kt)("inlineCode",{parentName:"li"},'" "'),") are supported."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"debug")," - set to 1 if debug is enabled (with ",(0,i.kt)("inlineCode",{parentName:"li"},"${BIN}_DEBUG=1")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"DEBUG=$BIN"),"). In the future this may be used for multiple debug levels."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"npmRegistry")," - current npm registry to use with the ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-plugins"},"plugins")," plugin"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"plugins")," - loaded plugins"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"commands")," - all commands in CLI"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"default")," - default cli command"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"topics")," - all topics in CLI"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"commandIDs")," - string IDs of all commands"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"async runHook(event, opts)")," - trigger a hook")),(0,i.kt)("h2",{id:"custom-user-configuration"},"Custom User Configuration"),(0,i.kt)("p",null,"Often it's useful to have a custom configuration for your users. One way to implement this is to read a ",(0,i.kt)("inlineCode",{parentName:"p"},"config.json")," file from the CLI's config directory:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command} from '@oclif/core'\nimport * as fs from 'fs-extra'\nimport * as path from 'path'\n\nexport class extends Command {\n async run() {\n const userConfig = await fs.readJSON(path.join(this.config.configDir, 'config.json'))\n\n this.log('User config:')\n console.dir(userConfig)\n }\n}\n")),(0,i.kt)("p",null,"To share this logic between different commands, use a ",(0,i.kt)("a",{parentName:"p",href:"/docs/base_class"},"base class"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8705a681.1f18d578.js b/assets/js/8705a681.1f18d578.js new file mode 100644 index 00000000..7b958a27 --- /dev/null +++ b/assets/js/8705a681.1f18d578.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2863],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=c(n),u=r,g=m["".concat(l,".").concat(u)]||m[u]||d[u]||o;return n?a.createElement(g,i(i({ref:t},p),{},{components:n})):a.createElement(g,i({ref:t},p))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[m]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>g,frontMatter:()=>s,metadata:()=>c,toc:()=>m});var a=n(7462),r=n(3366),o=(n(7294),n(3905)),i=["components"],s={title:"Running Commands Programmatically"},l=void 0,c={unversionedId:"running_programmatically",id:"running_programmatically",title:"Running Commands Programmatically",description:"If you need to run a command from another, or programmatically run a command in another codebase, there are a couple options.",source:"@site/../docs/running_programmatically.md",sourceDirName:".",slug:"/running_programmatically",permalink:"/docs/running_programmatically",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/running_programmatically.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Running Commands Programmatically"},sidebar:"docs",previous:{title:"Testing",permalink:"/docs/testing"},next:{title:"Just-in-Time Plugin Installation",permalink:"/docs/jit_plugins"}},p={},m=[{value:"Sharing code with modules",id:"sharing-code-with-modules",level:2},{value:"Calling commands directly",id:"calling-commands-directly",level:2}],d={toc:m},u="wrapper";function g(e){var t=e.components,n=(0,r.Z)(e,i);return(0,o.kt)(u,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"If you need to run a command from another, or programmatically run a command in another codebase, there are a couple options."),(0,o.kt)("p",null,"First, it is generally a bad idea to run a command directly as the command exports a user interface, not a code interface. It's a design smell that should rarely (if ever) be used. Generally speaking, it's better to break up the code so that it can be called directly rather than as a command. We'll show this better method first."),(0,o.kt)("h2",{id:"sharing-code-with-modules"},"Sharing code with modules"),(0,o.kt)("p",null,"For example, if we use ",(0,o.kt)("inlineCode",{parentName:"p"},"sf config list")," as an example, we could have a command that outputs the config vars of an app to the screen like this:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/commands/config/list.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"export class ConfigList extends Command {\n static flags = {\n app: Flags.string({required: true})\n }\n\n async run() {\n const {flags} = await this.parse(ConfigList)\n const config = await api.get(`/apps/${flags.app}/config-vars`)\n for (let [key, value] of Object.entries(config)) {\n this.log(`${key}=${value}`)\n }\n }\n}\n")),(0,o.kt)("p",null,"If we had another command such as ",(0,o.kt)("inlineCode",{parentName:"p"},"sf config update")," that would do some logic then display the config variables using the same logic, we should create a new module that we could call directly:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/commands/config/update.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {displayConfigVars} from '../displayConfigVars'\n\nexport class ConfigUpdate extends Command {\n static flags = {\n app: Flags.string({required: true})\n }\n\n async run() {\n const {flags} = await this.parse(ConfigUpdate)\n await this.doUpdate(flags.app)\n await displayConfigVars(flags.app)\n }\n}\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/displayConfigVars.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"export async function displayConfigVars(app: string) {\n const config = await api.get(`/apps/${app}config-vars`)\n for (let [key, value] of Object.entries(config)) {\n this.log(`${key}=${value}`)\n }\n}\n")),(0,o.kt)("p",null,"This is the recommended way to share code. This can be extended further by putting shared code into its own npm package."),(0,o.kt)("h2",{id:"calling-commands-directly"},"Calling commands directly"),(0,o.kt)("p",null,"Still, if you ",(0,o.kt)("em",{parentName:"p"},"really")," want to call a command directly, it's easy to do. You have a couple of options."),(0,o.kt)("p",null,"If you know that the command you want to run is installed in the CLI, you can use ",(0,o.kt)("inlineCode",{parentName:"p"},"this.config.runCommand"),". For this, we could write our ",(0,o.kt)("inlineCode",{parentName:"p"},"sf config update")," command like so:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/commands/config/update.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"export class ConfigUpdate extends Command {\n static flags = {\n app: Flags.string({required: true})\n }\n\n async run() {\n const {flags} = await this.parse(ConfigUpdate)\n await this.doUpdate(flags.app)\n await this.config.runCommand('config:list', ['--global'])\n }\n}\n")),(0,o.kt)("p",null,"Or you could import the command directly and execute it directly like so:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/commands/config/update.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {ConfigList} from './config/list'\n\nexport class ConfigUpdate extends Command {\n static flags = {\n app: Flags.string({required: true})\n }\n\n async run() {\n const {flags} = await this.parse(ConfigUpdate)\n await this.doUpdate(flags.app)\n await ConfigList.run(['--global'])\n }\n}\n")),(0,o.kt)("p",null,"This works because commands have a static ",(0,o.kt)("inlineCode",{parentName:"p"},".run()")," ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/command.ts"},"method on them")," that can be used to instantiate the command and run the instance ",(0,o.kt)("inlineCode",{parentName:"p"},".run()")," method. It takes in the argv as input to the command."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8705a681.2d191624.js b/assets/js/8705a681.2d191624.js deleted file mode 100644 index 115ca19c..00000000 --- a/assets/js/8705a681.2d191624.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2863],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=c(n),u=r,g=m["".concat(l,".").concat(u)]||m[u]||d[u]||o;return n?a.createElement(g,i(i({ref:t},p),{},{components:n})):a.createElement(g,i({ref:t},p))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[m]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>g,frontMatter:()=>s,metadata:()=>c,toc:()=>m});var a=n(7462),r=n(3366),o=(n(7294),n(3905)),i=["components"],s={title:"Running Commands Programmatically"},l=void 0,c={unversionedId:"running_programmatically",id:"running_programmatically",title:"Running Commands Programmatically",description:"If you need to run a command from another, or programmatically run a command in another codebase, there are a couple options.",source:"@site/../docs/running_programmatically.md",sourceDirName:".",slug:"/running_programmatically",permalink:"/docs/running_programmatically",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/running_programmatically.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Running Commands Programmatically"},sidebar:"docs",previous:{title:"Testing",permalink:"/docs/testing"},next:{title:"Just-in-Time Plugin Installation",permalink:"/docs/jit_plugins"}},p={},m=[{value:"Sharing code with modules",id:"sharing-code-with-modules",level:2},{value:"Calling commands directly",id:"calling-commands-directly",level:2}],d={toc:m},u="wrapper";function g(e){var t=e.components,n=(0,r.Z)(e,i);return(0,o.kt)(u,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"If you need to run a command from another, or programmatically run a command in another codebase, there are a couple options."),(0,o.kt)("p",null,"First, it is generally a bad idea to run a command directly as the command exports a user interface, not a code interface. It's a design smell that should rarely (if ever) be used. Generally speaking, it's better to break up the code so that it can be called directly rather than as a command. We'll show this better method first."),(0,o.kt)("h2",{id:"sharing-code-with-modules"},"Sharing code with modules"),(0,o.kt)("p",null,"For example, if we use ",(0,o.kt)("inlineCode",{parentName:"p"},"sf config list")," as an example, we could have a command that outputs the config vars of an app to the screen like this:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/commands/config/list.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"export class ConfigList extends Command {\n static flags = {\n app: Flags.string({required: true})\n }\n\n async run() {\n const {flags} = await this.parse(ConfigList)\n const config = await api.get(`/apps/${flags.app}/config-vars`)\n for (let [key, value] of Object.entries(config)) {\n this.log(`${key}=${value}`)\n }\n }\n}\n")),(0,o.kt)("p",null,"If we had another command such as ",(0,o.kt)("inlineCode",{parentName:"p"},"sf config update")," that would do some logic then display the config variables using the same logic, we should create a new module that we could call directly:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/commands/config/update.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {displayConfigVars} from '../displayConfigVars'\n\nexport class ConfigUpdate extends Command {\n static flags = {\n app: Flags.string({required: true})\n }\n\n async run() {\n const {flags} = await this.parse(ConfigUpdate)\n await this.doUpdate(flags.app)\n await displayConfigVars(flags.app)\n }\n}\n")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/displayConfigVars.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"export async function displayConfigVars(app: string) {\n const config = await api.get(`/apps/${app}config-vars`)\n for (let [key, value] of Object.entries(config)) {\n this.log(`${key}=${value}`)\n }\n}\n")),(0,o.kt)("p",null,"This is the recommended way to share code. This can be extended further by putting shared code into its own npm package."),(0,o.kt)("h2",{id:"calling-commands-directly"},"Calling commands directly"),(0,o.kt)("p",null,"Still, if you ",(0,o.kt)("em",{parentName:"p"},"really")," want to call a command directly, it's easy to do. You have a couple of options."),(0,o.kt)("p",null,"If you know that the command you want to run is installed in the CLI, you can use ",(0,o.kt)("inlineCode",{parentName:"p"},"this.config.runCommand"),". For this, we could write our ",(0,o.kt)("inlineCode",{parentName:"p"},"sf config update")," command like so:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/commands/config/update.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"export class ConfigUpdate extends Command {\n static flags = {\n app: Flags.string({required: true})\n }\n\n async run() {\n const {flags} = await this.parse(ConfigUpdate)\n await this.doUpdate(flags.app)\n await this.config.runCommand('config:list', ['--global'])\n }\n}\n")),(0,o.kt)("p",null,"Or you could import the command directly and execute it directly like so:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"./src/commands/config/update.ts")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {ConfigList} from './config/list'\n\nexport class ConfigUpdate extends Command {\n static flags = {\n app: Flags.string({required: true})\n }\n\n async run() {\n const {flags} = await this.parse(ConfigUpdate)\n await this.doUpdate(flags.app)\n await ConfigList.run(['--global'])\n }\n}\n")),(0,o.kt)("p",null,"This works because commands have a static ",(0,o.kt)("inlineCode",{parentName:"p"},".run()")," ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/command.ts"},"method on them")," that can be used to instantiate the command and run the instance ",(0,o.kt)("inlineCode",{parentName:"p"},".run()")," method. It takes in the argv as input to the command."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935116ff.792ff3fd.js b/assets/js/935116ff.792ff3fd.js new file mode 100644 index 00000000..9fe6e55e --- /dev/null +++ b/assets/js/935116ff.792ff3fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2638],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>f});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function i(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),o=t;return e&&(o="function"==typeof e?e(t):i(i({},t),e)),o},u=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(o),h=r,f=c["".concat(s,".").concat(h)]||c[h]||d[h]||a;return o?n.createElement(f,i(i({ref:t},u),{},{components:o})):n.createElement(f,i({ref:t},u))}));function f(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=o.length,i=new Array(a);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:r,i[1]=l;for(var p=2;p{o.r(t),o.d(t,{assets:()=>u,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var n=o(7462),r=o(3366),a=(o(7294),o(3905)),i=["components"],l={title:"FAQs"},s=void 0,p={unversionedId:"faqs",id:"faqs",title:"FAQs",description:"Why Node?",source:"@site/../docs/faqs.md",sourceDirName:".",slug:"/faqs",permalink:"/docs/faqs",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/faqs.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"FAQs"},sidebar:"docs",previous:{title:"Features",permalink:"/docs/features"},next:{title:"Generator Commands",permalink:"/docs/generator_commands"}},u={},c=[{value:"Why Node?",id:"why-node",level:2},{value:"I want a single binary CLI like with Go",id:"i-want-a-single-binary-cli-like-with-go",level:2},{value:"Should I use TypeScript or JavaScript?",id:"should-i-use-typescript-or-javascript",level:2},{value:"What editor is best for oclif?",id:"what-editor-is-best-for-oclif",level:2},{value:"Should I use npm or yarn?",id:"should-i-use-npm-or-yarn",level:2},{value:"How can I make the oclif generator run faster?",id:"how-can-i-make-the-oclif-generator-run-faster",level:2},{value:"Why isn't Node X supported?",id:"why-isnt-node-x-supported",level:2},{value:"How do I pronounce "oclif"?",id:"how-do-i-pronounce-oclif",level:2}],d={toc:c},h="wrapper";function f(e){var t=e.components,o=(0,r.Z)(e,i);return(0,a.kt)(h,(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"why-node"},"Why Node?"),(0,a.kt)("p",null,"There are a number of reasons why Node is the best choice for writing CLI code. At Salesforce, we've released the heroku CLI in Ruby, Go, as well as Node. ",(0,a.kt)("a",{parentName:"p",href:"https://blog.heroku.com/evolution-of-heroku-cli-2008-2017"},"This article gets more into detail on that history"),", but we've certainly found that Node offers the best of everything."),(0,a.kt)("p",null,"First, JavaScript is the biggest language in the world. More people are able to write JavaScript than any other language and it by far has the biggest open source community. Everyone can write it and you'll find the most helpful libraries to help build your CLI."),(0,a.kt)("p",null,"We've found that Node has the best cross platform support of any language we've used. In general, if you write code on macOS, you won't find many issues making it also run on Windows."),(0,a.kt)("p",null,"Node has the best support for our ",(0,a.kt)("a",{parentName:"p",href:"/docs/plugins"},"plugins")," model. Plugins are a way to share code between CLIs, to modularize a CLIs codebase, or allow users to add functionality to an existing CLI. With Node, we're able to have separate dependency versions sitting alongside one another. This means if you want to release an update to a dependency in one plugin, it won't affect how another plugin works. oclif takes this to an extreme and even flag parsing is done at the individual plugin level. If we ever want to make a breaking change to flag parsing (we certainly don't intend to, but this is just an example), you can update just one plugin and keep the old behavior in other plugins. This is very helpful for large CLI codebases where you want to migrate to new code slowly."),(0,a.kt)("h2",{id:"i-want-a-single-binary-cli-like-with-go"},"I want a single binary CLI like with Go"),(0,a.kt)("p",null,"Use ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/zeit/pkg"},"pkg"),". Just make sure to add the commands and other source files by setting ",(0,a.kt)("inlineCode",{parentName:"p"},'pkg.scripts: "./lib/**/*.js"')," in ",(0,a.kt)("inlineCode",{parentName:"p"},"package.json"),"."),(0,a.kt)("p",null,"In the Salesforce CLI, however, we prefer to ship a tarball (and various installers) that has Node baked in. Use ",(0,a.kt)("inlineCode",{parentName:"p"},"oclif pack")," to create a set of tarballs for different platforms with Node built in. You'll likely need to use ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-update"},"@oclif/plugin-update")," with this, otherwise the users won't have a way to update the CLI from the tarball without reinstalling it."),(0,a.kt)("h2",{id:"should-i-use-typescript-or-javascript"},"Should I use TypeScript or JavaScript?"),(0,a.kt)("p",null,"We suggest TypeScript as we find the typing to really help when refactoring code and updating dependencies. It's nicer to get compilation errors rather than finding errors in production."),(0,a.kt)("p",null,"We've put a lot of care into making it easy to make a TypeScript CLI even if you've never written TypeScript before. We generate CLIs and plugins that use ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/TypeStrong/ts-node"},"ts-node")," to make it fast to run the TypeScript code without a compilation step. You won't have to mess around with build configuration using oclif."),(0,a.kt)("p",null,"Still, the languages today are very similar. The code you write in JavaScript will be nearly identical to what you would have in TypeScript. (Just no type definitions, of course)"),(0,a.kt)("h2",{id:"what-editor-is-best-for-oclif"},"What editor is best for oclif?"),(0,a.kt)("p",null,"Of course if you already have a go-to editor, you should use that. However, we typically recommend ",(0,a.kt)("a",{parentName:"p",href:"https://code.visualstudio.com"},"vscode"),"."),(0,a.kt)("p",null,"Microsoft has done a great job with this editor and it works particularly well in TypeScript projects. You'll get nice type checking, linting, and autocomplete right out of the box."),(0,a.kt)("h2",{id:"should-i-use-npm-or-yarn"},"Should I use npm or yarn?"),(0,a.kt)("p",null,"It really doesn't make that much of a difference. If you're just getting started, keep it simple and use npm which comes with Node. We like to use yarn internally as it's a bit faster and we find the lockfiles friendlier."),(0,a.kt)("h2",{id:"how-can-i-make-the-oclif-generator-run-faster"},"How can I make the oclif generator run faster?"),(0,a.kt)("p",null,"If you're using npx, install it first with ",(0,a.kt)("inlineCode",{parentName:"p"},"npm install -g oclif"),". This won't stay current with updates though, so you'll need to run ",(0,a.kt)("inlineCode",{parentName:"p"},"npm update -g oclif")," to get new versions of the generator."),(0,a.kt)("h2",{id:"why-isnt-node-x-supported"},"Why isn't Node X supported?"),(0,a.kt)("p",null,"The oclif project follows and supports ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/about/releases/"},"Node's LTS support schedule"),". This allows oclif to stay current with Node's development."),(0,a.kt)("h2",{id:"how-do-i-pronounce-oclif"},'How do I pronounce "oclif"?'),(0,a.kt)("p",null,'We say "oh-cliff".'))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935116ff.abca0cdf.js b/assets/js/935116ff.abca0cdf.js deleted file mode 100644 index 670d7690..00000000 --- a/assets/js/935116ff.abca0cdf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2638],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>f});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function i(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),o=t;return e&&(o="function"==typeof e?e(t):i(i({},t),e)),o},u=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,a=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(o),h=r,f=c["".concat(s,".").concat(h)]||c[h]||d[h]||a;return o?n.createElement(f,i(i({ref:t},u),{},{components:o})):n.createElement(f,i({ref:t},u))}));function f(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=o.length,i=new Array(a);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:r,i[1]=l;for(var p=2;p{o.r(t),o.d(t,{assets:()=>u,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var n=o(7462),r=o(3366),a=(o(7294),o(3905)),i=["components"],l={title:"FAQs"},s=void 0,p={unversionedId:"faqs",id:"faqs",title:"FAQs",description:"Why Node?",source:"@site/../docs/faqs.md",sourceDirName:".",slug:"/faqs",permalink:"/docs/faqs",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/faqs.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"FAQs"},sidebar:"docs",previous:{title:"Features",permalink:"/docs/features"},next:{title:"Generator Commands",permalink:"/docs/generator_commands"}},u={},c=[{value:"Why Node?",id:"why-node",level:2},{value:"I want a single binary CLI like with Go",id:"i-want-a-single-binary-cli-like-with-go",level:2},{value:"Should I use TypeScript or JavaScript?",id:"should-i-use-typescript-or-javascript",level:2},{value:"What editor is best for oclif?",id:"what-editor-is-best-for-oclif",level:2},{value:"Should I use npm or yarn?",id:"should-i-use-npm-or-yarn",level:2},{value:"How can I make the oclif generator run faster?",id:"how-can-i-make-the-oclif-generator-run-faster",level:2},{value:"Why isn't Node X supported?",id:"why-isnt-node-x-supported",level:2},{value:"How do I pronounce "oclif"?",id:"how-do-i-pronounce-oclif",level:2}],d={toc:c},h="wrapper";function f(e){var t=e.components,o=(0,r.Z)(e,i);return(0,a.kt)(h,(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"why-node"},"Why Node?"),(0,a.kt)("p",null,"There are a number of reasons why Node is the best choice for writing CLI code. At Salesforce, we've released the heroku CLI in Ruby, Go, as well as Node. ",(0,a.kt)("a",{parentName:"p",href:"https://blog.heroku.com/evolution-of-heroku-cli-2008-2017"},"This article gets more into detail on that history"),", but we've certainly found that Node offers the best of everything."),(0,a.kt)("p",null,"First, JavaScript is the biggest language in the world. More people are able to write JavaScript than any other language and it by far has the biggest open source community. Everyone can write it and you'll find the most helpful libraries to help build your CLI."),(0,a.kt)("p",null,"We've found that Node has the best cross platform support of any language we've used. In general, if you write code on macOS, you won't find many issues making it also run on Windows."),(0,a.kt)("p",null,"Node has the best support for our ",(0,a.kt)("a",{parentName:"p",href:"/docs/plugins"},"plugins")," model. Plugins are a way to share code between CLIs, to modularize a CLIs codebase, or allow users to add functionality to an existing CLI. With Node, we're able to have separate dependency versions sitting alongside one another. This means if you want to release an update to a dependency in one plugin, it won't affect how another plugin works. oclif takes this to an extreme and even flag parsing is done at the individual plugin level. If we ever want to make a breaking change to flag parsing (we certainly don't intend to, but this is just an example), you can update just one plugin and keep the old behavior in other plugins. This is very helpful for large CLI codebases where you want to migrate to new code slowly."),(0,a.kt)("h2",{id:"i-want-a-single-binary-cli-like-with-go"},"I want a single binary CLI like with Go"),(0,a.kt)("p",null,"Use ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/zeit/pkg"},"pkg"),". Just make sure to add the commands and other source files by setting ",(0,a.kt)("inlineCode",{parentName:"p"},'pkg.scripts: "./lib/**/*.js"')," in ",(0,a.kt)("inlineCode",{parentName:"p"},"package.json"),"."),(0,a.kt)("p",null,"In the Salesforce CLI, however, we prefer to ship a tarball (and various installers) that has Node baked in. Use ",(0,a.kt)("inlineCode",{parentName:"p"},"oclif pack")," to create a set of tarballs for different platforms with Node built in. You'll likely need to use ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-update"},"@oclif/plugin-update")," with this, otherwise the users won't have a way to update the CLI from the tarball without reinstalling it."),(0,a.kt)("h2",{id:"should-i-use-typescript-or-javascript"},"Should I use TypeScript or JavaScript?"),(0,a.kt)("p",null,"We suggest TypeScript as we find the typing to really help when refactoring code and updating dependencies. It's nicer to get compilation errors rather than finding errors in production."),(0,a.kt)("p",null,"We've put a lot of care into making it easy to make a TypeScript CLI even if you've never written TypeScript before. We generate CLIs and plugins that use ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/TypeStrong/ts-node"},"ts-node")," to make it fast to run the TypeScript code without a compilation step. You won't have to mess around with build configuration using oclif."),(0,a.kt)("p",null,"Still, the languages today are very similar. The code you write in JavaScript will be nearly identical to what you would have in TypeScript. (Just no type definitions, of course)"),(0,a.kt)("h2",{id:"what-editor-is-best-for-oclif"},"What editor is best for oclif?"),(0,a.kt)("p",null,"Of course if you already have a go-to editor, you should use that. However, we typically recommend ",(0,a.kt)("a",{parentName:"p",href:"https://code.visualstudio.com"},"vscode"),"."),(0,a.kt)("p",null,"Microsoft has done a great job with this editor and it works particularly well in TypeScript projects. You'll get nice type checking, linting, and autocomplete right out of the box."),(0,a.kt)("h2",{id:"should-i-use-npm-or-yarn"},"Should I use npm or yarn?"),(0,a.kt)("p",null,"It really doesn't make that much of a difference. If you're just getting started, keep it simple and use npm which comes with Node. We like to use yarn internally as it's a bit faster and we find the lockfiles friendlier."),(0,a.kt)("h2",{id:"how-can-i-make-the-oclif-generator-run-faster"},"How can I make the oclif generator run faster?"),(0,a.kt)("p",null,"If you're using npx, install it first with ",(0,a.kt)("inlineCode",{parentName:"p"},"npm install -g oclif"),". This won't stay current with updates though, so you'll need to run ",(0,a.kt)("inlineCode",{parentName:"p"},"npm update -g oclif")," to get new versions of the generator."),(0,a.kt)("h2",{id:"why-isnt-node-x-supported"},"Why isn't Node X supported?"),(0,a.kt)("p",null,"The oclif project follows and supports ",(0,a.kt)("a",{parentName:"p",href:"https://nodejs.org/en/about/releases/"},"Node's LTS support schedule"),". This allows oclif to stay current with Node's development."),(0,a.kt)("h2",{id:"how-do-i-pronounce-oclif"},'How do I pronounce "oclif"?'),(0,a.kt)("p",null,'We say "oh-cliff".'))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9b8720eb.8faf9117.js b/assets/js/9b8720eb.8faf9117.js deleted file mode 100644 index 4da7d025..00000000 --- a/assets/js/9b8720eb.8faf9117.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1267],{3905:(e,t,o)=>{o.d(t,{Zo:()=>p,kt:()=>m});var n=o(7294);function a(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function r(e){for(var t=1;t=0||(a[o]=e[o]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(a[o]=e[o])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var o=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(o),h=a,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||i;return o?n.createElement(m,r(r({ref:t},p),{},{components:o})):n.createElement(m,r({ref:t},p))}));function m(e,t){var o=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=o.length,r=new Array(i);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,r[1]=s;for(var c=2;c{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var n=o(7462),a=o(3366),i=(o(7294),o(3905)),r=["components"],s={title:"oclifconf 2019: A Recap"},l=void 0,c={permalink:"/blog/2019/09/16/oclifconf-recap",source:"@site/blog/2019-09-16-oclifconf-recap.md",title:"oclifconf 2019: A Recap",description:"In May, Heroku and Salesforce Open Source organized oclifconf, a conference for developers & product managers building CLI tools on top of the open source oclif framework. The speakers came from various tech companies, such as Adobe, Netlify, and Apollo, who have already built amazing CLI experiences. The topics covered everything from the incredible capabilities oclif has unlocked, to the community-built plugins extending its functionality, and even what the behavior of an adaptive CLI tool might look like.",date:"2019-09-16T00:00:00.000Z",formattedDate:"September 16, 2019",tags:[],readingTime:3.56,hasTruncateMarker:!1,authors:[],frontMatter:{title:"oclifconf 2019: A Recap"},prevItem:{title:"oclif's Current Node Support",permalink:"/blog/2019/10/31/oclif-node-updates"},nextItem:{title:"CLI Flags Explained",permalink:"/blog/2019/02/20/cli-flags-explained"}},p={authorsImageUrls:[]},d=[{value:"The future of oclif by Jeff Dickey",id:"the-future-of-oclif-by-jeff-dickey",level:2},{value:"Open Source Citizenship by Josh Simmons",id:"open-source-citizenship-by-josh-simmons",level:2},{value:"Building an enterprise-grade CLI with oclif by Thomas Dvornik",id:"building-an-enterprise-grade-cli-with-oclif-by-thomas-dvornik",level:2},{value:"How Adobe I/O built an extensible CLI with oclif by Jesse MacFadyen",id:"how-adobe-io-built-an-extensible-cli-with-oclif-by-jesse-macfadyen",level:2},{value:"Integrating oclif with GraphQL and Apollo by Evans Hauser",id:"integrating-oclif-with-graphql-and-apollo-by-evans-hauser",level:2},{value:"Adaptive Intent-based CLI State Machines by Shawn Wang",id:"adaptive-intent-based-cli-state-machines-by-shawn-wang",level:2}],u={toc:d},h="wrapper";function m(e){var t=e.components,o=(0,a.Z)(e,r);return(0,i.kt)(h,(0,n.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"In May, Heroku and Salesforce Open Source organized ",(0,i.kt)("a",{parentName:"p",href:"https://oclif.io/conf"},"oclifconf"),", a conference for developers & product managers building CLI tools on top of ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif"},"the open source oclif framework"),". The speakers came from various tech companies, such as Adobe, Netlify, and Apollo, who have already built amazing CLI experiences. The topics covered everything from the incredible capabilities oclif has unlocked, to the community-built plugins extending its functionality, and even what the behavior of an adaptive CLI tool might look like."),(0,i.kt)("p",null,"Below is a listing of all of the talks from the event, along with a short summary. Enjoy!"),(0,i.kt)("h2",{id:"the-future-of-oclif-by-jeff-dickey"},"The future of oclif by Jeff Dickey"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/1TKh2YBxRMY",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"In its relatively short lifetime, oclif has already inspired many developers and companies to adopt its framework as a means for implementing their own command-line tooling. In this talk, Jeff Dickey, an oclif founding team member, recaps the project's history and inspiration. He also looks towards the future and outlines some features and improvements that the tool could adapt. This isn't so much a definitive roadmap of where oclif is headed, but rather, a call to inspiration for developers eager to contribute! And if you are interested in contributing, check out the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif/issues"},"open issues"),' in the oclif GitHub repo and come say "Hello!" on ',(0,i.kt)("a",{parentName:"p",href:"https://spectrum.chat/oclif"},"Spectrum Chat"),"."),(0,i.kt)("h2",{id:"open-source-citizenship-by-josh-simmons"},"Open Source Citizenship by Josh Simmons"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/54hhR5DoV6g",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"When it comes to open source, it's more than just individuals now. More and more frequently, large corporations are contributing to projects by donating to contributors, sponsoring events, or upstreaming contributions. But keeping open source projects and communities healthy requires more than just money and brainpower. Josh Simmons surveyed multiple open source communities and relays his findings as to what help maintainers and contributors actually need in this talk."),(0,i.kt)("h2",{id:"building-an-enterprise-grade-cli-with-oclif-by-thomas-dvornik"},"Building an enterprise-grade CLI with oclif by Thomas Dvornik"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/v4saIi5zoy8",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"Security and performance are all about trust. While oclif is an extremely extensible framework for building CLI tooling, there are additional requirements to fulfill for enterprise businesses to adopt it that might not be necessary for individual developers. Thomas Dvornik outlines what he and his colleagues at Salesforce have implemented as plugins to oclif to satisfy these needs, including encrypted OAuth, plugin signing, lazy loading dependencies, synchronizing weekly releases and deprecations across dozens of repositories, and establishing cross-team coding and documentation standards."),(0,i.kt)("h2",{id:"how-adobe-io-built-an-extensible-cli-with-oclif-by-jesse-macfadyen"},"How Adobe I/O built an extensible CLI with oclif by Jesse MacFadyen"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/Mxhx1wmoHlA",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"Perhaps oclif's most appealing feature is its support for plugins. In Cordova's case, they've created a sophisticated telemetry system that helps Adobe developers see which commands users are using--and reports on which ones are erroring out. By embedding a feedback system into the tool, users are even able to quickly send their suggestions to a form, without ever leaving the terminal. Jesse MacFadyen demonstrates how oclif's plugin system can work beyond simply executing commands."),(0,i.kt)("h2",{id:"integrating-oclif-with-graphql-and-apollo-by-evans-hauser"},"Integrating oclif with GraphQL and Apollo by Evans Hauser"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/Zh78npkypas",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,'For Evans Hauser and the team at Apollo, oclif is best thought of as "React for the CLI." As a client paired with a strongly-typed API contract to a server, it can deliver structured and consistent commands to retrieve external data. What better mechanism to use for this transfer than GraphQL, a framework which empowers the client to ask precisely for the data it needs, and nothing more?'),(0,i.kt)("h2",{id:"adaptive-intent-based-cli-state-machines-by-shawn-wang"},"Adaptive Intent-based CLI State Machines by Shawn Wang"),(0,i.kt)("iframe",{width:"560",height:"315",src:"https://www.youtube-nocookie.com/embed/ZueoIYnHiaI",frameborder:"0",allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),(0,i.kt)("p",null,"In designing oclif, ",(0,i.kt)("a",{parentName:"p",href:"https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46"},"Jeff Dickey wrote out 12 CLI factors to keep in mind"),". In this talk, Shawn Wang outlines a 13th: state. State is hard, because it depends on context, and context depends on understanding what a user intends to do, not what they are asking. Shawn is working towards enabling oclif to better understand the commands a user has entered, so that it can predict and interpret future commands that might be entered next. This would enable CLI tools to not just interpret a users' commands, but to also interpret their intent."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9eaa546a.17810b0f.js b/assets/js/9eaa546a.17810b0f.js new file mode 100644 index 00000000..a43da6b1 --- /dev/null +++ b/assets/js/9eaa546a.17810b0f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8059],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),u=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=u(e.components);return o.createElement(s.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=u(n),m=a,f=c["".concat(s,".").concat(m)]||c[m]||d[m]||r;return n?o.createElement(f,i(i({ref:t},p),{},{components:n})):o.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:a,i[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>u,toc:()=>c});var o=n(7462),a=n(3366),r=(n(7294),n(3905)),i=["components"],l={title:"Features"},s=void 0,u={unversionedId:"features",id:"features",title:"Features",description:"Flag/Argument parsing",source:"@site/../docs/features.md",sourceDirName:".",slug:"/features",permalink:"/docs/features",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/features.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Features"},sidebar:"docs",previous:{title:"Introduction",permalink:"/docs/introduction"},next:{title:"FAQs",permalink:"/docs/faqs"}},p={},c=[{value:"Flag/Argument parsing",id:"flagargument-parsing",level:3},{value:"Configurable Topic Separators",id:"configurable-topic-separators",level:3},{value:"Super Speed",id:"super-speed",level:3},{value:"CLI Generator",id:"cli-generator",level:3},{value:"Testing Helpers",id:"testing-helpers",level:3},{value:"Auto-documentation",id:"auto-documentation",level:3},{value:"Plugins",id:"plugins",level:3},{value:"Hooks",id:"hooks",level:3},{value:"JSON Output",id:"json-output",level:3},{value:"TypeScript (or not)",id:"typescript-or-not",level:3},{value:"Auto-updating Installers",id:"auto-updating-installers",level:3},{value:"Autocomplete",id:"autocomplete",level:3}],d={toc:c},m="wrapper";function f(e){var t=e.components,n=(0,a.Z)(e,i);return(0,r.kt)(m,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"flagargument-parsing"},"Flag/Argument parsing"),(0,r.kt)("p",null,"No CLI framework would be complete without a flag parser. We've built a custom one from years of experimentation that we feel consistently handles user input flexible enough for the user to be able to easily use the CLI in ways they expect, but without compromising strictness guarantees to the developer."),(0,r.kt)("h3",{id:"configurable-topic-separators"},"Configurable Topic Separators"),(0,r.kt)("p",null,"By default topics will be separated with colons, e.g. ",(0,r.kt)("inlineCode",{parentName:"p"},"my:awesome:command"),". However, you have the option to use spaces if you prefer, e.g. ",(0,r.kt)("inlineCode",{parentName:"p"},"my awesome command"),"."),(0,r.kt)("h3",{id:"super-speed"},"Super Speed"),(0,r.kt)("p",null,"The overhead for running an oclif CLI command is almost nothing. ",(0,r.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/@oclif/core?activeTab=dependencies"},"It requires very few dependencies")," (only 28 dependencies in a minimal setup\u2014including all transitive dependencies). Also, only the command to be executed will be required with node. So large CLIs with many commands will load just as fast as a small one with a single command."),(0,r.kt)("h3",{id:"cli-generator"},"CLI Generator"),(0,r.kt)("p",null,"Run a single command to scaffold out a fully functional CLI and get started quickly. See ",(0,r.kt)("a",{parentName:"p",href:"https://oclif.io/docs/generator_commands"},"Generator Commands"),"."),(0,r.kt)("h3",{id:"testing-helpers"},"Testing Helpers"),(0,r.kt)("p",null,"We've put a lot of work into making commands easily testable and easy to mock out stdout/stderr. The generator will automatically create ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/hello-world/blob/main/test/commands/hello/world.test.ts"},"scaffolded tests"),"."),(0,r.kt)("h3",{id:"auto-documentation"},"Auto-documentation"),(0,r.kt)("p",null,"By default you can pass ",(0,r.kt)("inlineCode",{parentName:"p"},"--help")," to the CLI to get help such as flag options and argument information. This information is also automatically placed in the README whenever the npm package of the CLI is published. See the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/hello-world"},"hello-world CLI example")),(0,r.kt)("h3",{id:"plugins"},"Plugins"),(0,r.kt)("p",null,"Using plugins, users of the CLI can extend it with new functionality, a CLI can be split into modular components, and functionality can be shared amongst multiple CLIs. See ",(0,r.kt)("a",{parentName:"p",href:"https://oclif.io/docs/plugins#building-your-own-plugin"},"Building your own plugin"),"."),(0,r.kt)("h3",{id:"hooks"},"Hooks"),(0,r.kt)("p",null,"Use lifecycle hooks to run functionality any time a CLI starts, or on custom triggers. Use this whenever custom functionality needs to be shared between various components of the CLI. See ",(0,r.kt)("a",{parentName:"p",href:"https://oclif.io/docs/hooks"},"Hooks"),"."),(0,r.kt)("h3",{id:"json-output"},"JSON Output"),(0,r.kt)("p",null,"You can opt-in to using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--json")," flag which will automatically suppress console logs and display the final result of the command as valid JSON output. This is very useful if you want your CLI to be used for scripting in CI/CD environments. See ",(0,r.kt)("a",{parentName:"p",href:"https://oclif.io/docs/json"},"JSON"),"."),(0,r.kt)("h3",{id:"typescript-or-not"},"TypeScript (or not)"),(0,r.kt)("p",null,"Everything in the core of oclif is written in TypeScript and the generator can build fully configured TypeScript CLIs or just plain JavaScript CLIs. By virtue of static properties in TypeScript the syntax is a bit cleaner in TypeScript \u2014 but everything will work no matter which language you choose. If you use plugins support, the CLI will automatically use ",(0,r.kt)("inlineCode",{parentName:"p"},"ts-node")," to run the plugins making it easy and fast to use TypeScript with minimal-to-no boilerplate needed for any oclif CLI."),(0,r.kt)("h3",{id:"auto-updating-installers"},"Auto-updating Installers"),(0,r.kt)("p",null,"oclif can package your CLI into ",(0,r.kt)("a",{parentName:"p",href:"/docs/releasing"},"different installers")," that will not require the user to already have node installed on the machine. These can be made auto-updatable by using ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-update"},"plugin-update"),"."),(0,r.kt)("h3",{id:"autocomplete"},"Autocomplete"),(0,r.kt)("p",null,"Include terminal autocompletion for your CLI via ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-autocomplete"},"plugin-autocomplete"),". Once installed, users can complete command names and flag names."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ my-cli p # will list all commands starting with 'p' for completion\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9eaa546a.a127ea4a.js b/assets/js/9eaa546a.a127ea4a.js deleted file mode 100644 index 5a127bbd..00000000 --- a/assets/js/9eaa546a.a127ea4a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[8059],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),u=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=u(e.components);return o.createElement(s.Provider,{value:t},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=u(n),m=a,f=c["".concat(s,".").concat(m)]||c[m]||d[m]||r;return n?o.createElement(f,i(i({ref:t},p),{},{components:n})):o.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:a,i[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>u,toc:()=>c});var o=n(7462),a=n(3366),r=(n(7294),n(3905)),i=["components"],l={title:"Features"},s=void 0,u={unversionedId:"features",id:"features",title:"Features",description:"Flag/Argument parsing",source:"@site/../docs/features.md",sourceDirName:".",slug:"/features",permalink:"/docs/features",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/features.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Features"},sidebar:"docs",previous:{title:"Introduction",permalink:"/docs/introduction"},next:{title:"FAQs",permalink:"/docs/faqs"}},p={},c=[{value:"Flag/Argument parsing",id:"flagargument-parsing",level:3},{value:"Configurable Topic Separators",id:"configurable-topic-separators",level:3},{value:"Super Speed",id:"super-speed",level:3},{value:"CLI Generator",id:"cli-generator",level:3},{value:"Testing Helpers",id:"testing-helpers",level:3},{value:"Auto-documentation",id:"auto-documentation",level:3},{value:"Plugins",id:"plugins",level:3},{value:"Hooks",id:"hooks",level:3},{value:"JSON Output",id:"json-output",level:3},{value:"TypeScript (or not)",id:"typescript-or-not",level:3},{value:"Auto-updating Installers",id:"auto-updating-installers",level:3},{value:"Autocomplete",id:"autocomplete",level:3}],d={toc:c},m="wrapper";function f(e){var t=e.components,n=(0,a.Z)(e,i);return(0,r.kt)(m,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"flagargument-parsing"},"Flag/Argument parsing"),(0,r.kt)("p",null,"No CLI framework would be complete without a flag parser. We've built a custom one from years of experimentation that we feel consistently handles user input flexible enough for the user to be able to easily use the CLI in ways they expect, but without compromising strictness guarantees to the developer."),(0,r.kt)("h3",{id:"configurable-topic-separators"},"Configurable Topic Separators"),(0,r.kt)("p",null,"By default topics will be separated with colons, e.g. ",(0,r.kt)("inlineCode",{parentName:"p"},"my:awesome:command"),". However, you have the option to use spaces if you prefer, e.g. ",(0,r.kt)("inlineCode",{parentName:"p"},"my awesome command"),"."),(0,r.kt)("h3",{id:"super-speed"},"Super Speed"),(0,r.kt)("p",null,"The overhead for running an oclif CLI command is almost nothing. ",(0,r.kt)("a",{parentName:"p",href:"https://www.npmjs.com/package/@oclif/core?activeTab=dependencies"},"It requires very few dependencies")," (only 28 dependencies in a minimal setup\u2014including all transitive dependencies). Also, only the command to be executed will be required with node. So large CLIs with many commands will load just as fast as a small one with a single command."),(0,r.kt)("h3",{id:"cli-generator"},"CLI Generator"),(0,r.kt)("p",null,"Run a single command to scaffold out a fully functional CLI and get started quickly. See ",(0,r.kt)("a",{parentName:"p",href:"https://oclif.io/docs/generator_commands"},"Generator Commands"),"."),(0,r.kt)("h3",{id:"testing-helpers"},"Testing Helpers"),(0,r.kt)("p",null,"We've put a lot of work into making commands easily testable and easy to mock out stdout/stderr. The generator will automatically create ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/hello-world/blob/main/test/commands/hello/world.test.ts"},"scaffolded tests"),"."),(0,r.kt)("h3",{id:"auto-documentation"},"Auto-documentation"),(0,r.kt)("p",null,"By default you can pass ",(0,r.kt)("inlineCode",{parentName:"p"},"--help")," to the CLI to get help such as flag options and argument information. This information is also automatically placed in the README whenever the npm package of the CLI is published. See the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/hello-world"},"hello-world CLI example")),(0,r.kt)("h3",{id:"plugins"},"Plugins"),(0,r.kt)("p",null,"Using plugins, users of the CLI can extend it with new functionality, a CLI can be split into modular components, and functionality can be shared amongst multiple CLIs. See ",(0,r.kt)("a",{parentName:"p",href:"https://oclif.io/docs/plugins#building-your-own-plugin"},"Building your own plugin"),"."),(0,r.kt)("h3",{id:"hooks"},"Hooks"),(0,r.kt)("p",null,"Use lifecycle hooks to run functionality any time a CLI starts, or on custom triggers. Use this whenever custom functionality needs to be shared between various components of the CLI. See ",(0,r.kt)("a",{parentName:"p",href:"https://oclif.io/docs/hooks"},"Hooks"),"."),(0,r.kt)("h3",{id:"json-output"},"JSON Output"),(0,r.kt)("p",null,"You can opt-in to using the ",(0,r.kt)("inlineCode",{parentName:"p"},"--json")," flag which will automatically suppress console logs and display the final result of the command as valid JSON output. This is very useful if you want your CLI to be used for scripting in CI/CD environments. See ",(0,r.kt)("a",{parentName:"p",href:"https://oclif.io/docs/json"},"JSON"),"."),(0,r.kt)("h3",{id:"typescript-or-not"},"TypeScript (or not)"),(0,r.kt)("p",null,"Everything in the core of oclif is written in TypeScript and the generator can build fully configured TypeScript CLIs or just plain JavaScript CLIs. By virtue of static properties in TypeScript the syntax is a bit cleaner in TypeScript \u2014 but everything will work no matter which language you choose. If you use plugins support, the CLI will automatically use ",(0,r.kt)("inlineCode",{parentName:"p"},"ts-node")," to run the plugins making it easy and fast to use TypeScript with minimal-to-no boilerplate needed for any oclif CLI."),(0,r.kt)("h3",{id:"auto-updating-installers"},"Auto-updating Installers"),(0,r.kt)("p",null,"oclif can package your CLI into ",(0,r.kt)("a",{parentName:"p",href:"/docs/releasing"},"different installers")," that will not require the user to already have node installed on the machine. These can be made auto-updatable by using ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-update"},"plugin-update"),"."),(0,r.kt)("h3",{id:"autocomplete"},"Autocomplete"),(0,r.kt)("p",null,"Include terminal autocompletion for your CLI via ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-autocomplete"},"plugin-autocomplete"),". Once installed, users can complete command names and flag names."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ my-cli p # will list all commands starting with 'p' for completion\n")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a92e169d.fd7774d7.js b/assets/js/a92e169d.eb7674a1.js similarity index 69% rename from assets/js/a92e169d.fd7774d7.js rename to assets/js/a92e169d.eb7674a1.js index 8cc6d0d6..84bbacf8 100644 --- a/assets/js/a92e169d.fd7774d7.js +++ b/assets/js/a92e169d.eb7674a1.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[6332],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),s=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return a.createElement(i.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(n),f=r,u=m["".concat(i,".").concat(f)]||m[f]||d[f]||o;return n?a.createElement(u,l(l({ref:t},p),{},{components:n})):a.createElement(u,l({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[m]="string"==typeof e?e:r,l[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>c,metadata:()=>s,toc:()=>m});var a=n(7462),r=n(3366),o=(n(7294),n(3905)),l=["components"],c={title:"Global Flags"},i=void 0,s={unversionedId:"global_flags",id:"global_flags",title:"Global Flags",description:"There are some instances where you might want to define a flag once for all of your commands. In this case you can add a global flag to an abstract base Command class. For example,",source:"@site/../docs/global_flags.md",sourceDirName:".",slug:"/global_flags",permalink:"/docs/global_flags",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/global_flags.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Global Flags"},sidebar:"docs",previous:{title:"Flexible Taxonomy",permalink:"/docs/flexible_taxonomy"},next:{title:"Single Command CLI",permalink:"/docs/single_command_cli"}},p={},m=[],d={toc:m},f="wrapper";function u(e){var t=e.components,n=(0,r.Z)(e,l);return(0,o.kt)(f,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"There are some instances where you might want to define a flag once for all of your commands. In this case you can add a global flag to an abstract base ",(0,o.kt)("inlineCode",{parentName:"p"},"Command")," class. For example,"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import { Command, Flags } from '@oclif/core';\n\nexport abstract class BaseCommand extends Command {\n static baseFlags = {\n interactive: Flags.boolean({\n char: 'i',\n description: 'Run command in interactive mode',\n }),\n };\n}\n")),(0,o.kt)("p",null,"Any command that extends ",(0,o.kt)("inlineCode",{parentName:"p"},"BaseCommand")," will now have an ",(0,o.kt)("inlineCode",{parentName:"p"},"--interactive")," flag on it."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[6332],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),s=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=s(e.components);return a.createElement(i.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(n),f=r,u=m["".concat(i,".").concat(f)]||m[f]||d[f]||o;return n?a.createElement(u,l(l({ref:t},p),{},{components:n})):a.createElement(u,l({ref:t},p))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=f;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[m]="string"==typeof e?e:r,l[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>c,metadata:()=>s,toc:()=>m});var a=n(7462),r=n(3366),o=(n(7294),n(3905)),l=["components"],c={title:"Global Flags"},i=void 0,s={unversionedId:"global_flags",id:"global_flags",title:"Global Flags",description:"There are some instances where you might want to define a flag once for all of your commands. In this case you can add a global flag to an abstract base Command class. For example,",source:"@site/../docs/global_flags.md",sourceDirName:".",slug:"/global_flags",permalink:"/docs/global_flags",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/global_flags.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Global Flags"},sidebar:"docs",previous:{title:"Flexible Taxonomy",permalink:"/docs/flexible_taxonomy"},next:{title:"Single Command CLI",permalink:"/docs/single_command_cli"}},p={},m=[],d={toc:m},f="wrapper";function u(e){var t=e.components,n=(0,r.Z)(e,l);return(0,o.kt)(f,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"There are some instances where you might want to define a flag once for all of your commands. In this case you can add a global flag to an abstract base ",(0,o.kt)("inlineCode",{parentName:"p"},"Command")," class. For example,"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import { Command, Flags } from '@oclif/core';\n\nexport abstract class BaseCommand extends Command {\n static baseFlags = {\n interactive: Flags.boolean({\n char: 'i',\n description: 'Run command in interactive mode',\n }),\n };\n}\n")),(0,o.kt)("p",null,"Any command that extends ",(0,o.kt)("inlineCode",{parentName:"p"},"BaseCommand")," will now have an ",(0,o.kt)("inlineCode",{parentName:"p"},"--interactive")," flag on it."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a96ec439.c1b47e48.js b/assets/js/a96ec439.a91ea7bd.js similarity index 65% rename from assets/js/a96ec439.c1b47e48.js rename to assets/js/a96ec439.a91ea7bd.js index 479cdbec..cb254edd 100644 --- a/assets/js/a96ec439.c1b47e48.js +++ b/assets/js/a96ec439.a91ea7bd.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[6731],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),f=l(n),m=o,d=f["".concat(s,".").concat(m)]||f[m]||u[m]||i;return n?r.createElement(d,a(a({ref:t},p),{},{components:n})):r.createElement(d,a({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[f]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>d,frontMatter:()=>c,metadata:()=>l,toc:()=>f});var r=n(7462),o=n(3366),i=(n(7294),n(3905)),a=["components"],c={title:"Notifications"},s=void 0,l={unversionedId:"notifications",id:"notifications",title:"Notifications",description:"Use node-notifier for cross-platform OS notifications.",source:"@site/../docs/notifications.md",sourceDirName:".",slug:"/notifications",permalink:"/docs/notifications",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/notifications.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Notifications"},sidebar:"docs",previous:{title:"Table",permalink:"/docs/table"},next:{title:"Debugging",permalink:"/docs/debugging"}},p={},f=[],u={toc:f},m="wrapper";function d(e){var t=e.components,c=(0,o.Z)(e,a);return(0,i.kt)(m,(0,r.Z)({},u,c,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Use ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/mikaelbr/node-notifier"},"node-notifier")," for cross-platform OS notifications."),(0,i.kt)("p",null,"Example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command} from '@oclif/core'\nimport * as notifier from 'node-notifier'\n\nexport class MyCommand extends Command {\n async run() {\n notifier.notify({\n title: 'My notification',\n message: 'Hello!'\n })\n }\n}\n")),(0,i.kt)("p",null,"Demo:"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"notification demo",src:n(5925).Z,width:"1028",height:"803"})),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://github.com/mikaelbr/node-notifier"},"node-notifier")," is capable of much more such as adding images, sounds, and even buttons and user input."))}d.isMDXComponent=!0},5925:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/notification_demo-4cc045397623e249062842eb4b8afab0.gif"}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[6731],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),f=l(n),m=o,d=f["".concat(s,".").concat(m)]||f[m]||u[m]||i;return n?r.createElement(d,a(a({ref:t},p),{},{components:n})):r.createElement(d,a({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[f]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>d,frontMatter:()=>c,metadata:()=>l,toc:()=>f});var r=n(7462),o=n(3366),i=(n(7294),n(3905)),a=["components"],c={title:"Notifications"},s=void 0,l={unversionedId:"notifications",id:"notifications",title:"Notifications",description:"Use node-notifier for cross-platform OS notifications.",source:"@site/../docs/notifications.md",sourceDirName:".",slug:"/notifications",permalink:"/docs/notifications",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/notifications.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Notifications"},sidebar:"docs",previous:{title:"Table",permalink:"/docs/table"},next:{title:"Debugging",permalink:"/docs/debugging"}},p={},f=[],u={toc:f},m="wrapper";function d(e){var t=e.components,c=(0,o.Z)(e,a);return(0,i.kt)(m,(0,r.Z)({},u,c,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Use ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/mikaelbr/node-notifier"},"node-notifier")," for cross-platform OS notifications."),(0,i.kt)("p",null,"Example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command} from '@oclif/core'\nimport * as notifier from 'node-notifier'\n\nexport class MyCommand extends Command {\n async run() {\n notifier.notify({\n title: 'My notification',\n message: 'Hello!'\n })\n }\n}\n")),(0,i.kt)("p",null,"Demo:"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"notification demo",src:n(5925).Z,width:"1028",height:"803"})),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://github.com/mikaelbr/node-notifier"},"node-notifier")," is capable of much more such as adding images, sounds, and even buttons and user input."))}d.isMDXComponent=!0},5925:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/notification_demo-4cc045397623e249062842eb4b8afab0.gif"}}]); \ No newline at end of file diff --git a/assets/js/b2b675dd.45ebc9d4.js b/assets/js/b2b675dd.aeb2bd53.js similarity index 55% rename from assets/js/b2b675dd.45ebc9d4.js rename to assets/js/b2b675dd.aeb2bd53.js index 0d08a29b..3b5fce9b 100644 --- a/assets/js/b2b675dd.45ebc9d4.js +++ b/assets/js/b2b675dd.aeb2bd53.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[533],{8017:e=>{e.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":10,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[533],{8017:e=>{e.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":9,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/b2f554cd.dd4e8019.js b/assets/js/b2f554cd.d0fa6f76.js similarity index 64% rename from assets/js/b2f554cd.dd4e8019.js rename to assets/js/b2f554cd.d0fa6f76.js index 9691f566..61ae0dc8 100644 --- a/assets/js/b2f554cd.dd4e8019.js +++ b/assets/js/b2f554cd.d0fa6f76.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1477],{10:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"/2022/01/12/announcing-oclif-v2","metadata":{"permalink":"/blog/2022/01/12/announcing-oclif-v2","source":"@site/blog/2022-01-12-announcing-oclif-v2.md","title":"Announcing oclif v2!","description":"Hello and happy new year! It\'s our great pleasure to announce that we have released oclif v2, which uses the new @oclif/core library! \ud83c\udf89","date":"2022-01-12T00:00:00.000Z","formattedDate":"January 12, 2022","tags":[],"readingTime":4.48,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Announcing oclif v2!"},"nextItem":{"title":"Introducing @oclif/core","permalink":"/blog/2021/03/01/introducing-oclif-core"}},"content":"Hello and happy new year! It\'s our great pleasure to announce that we have released oclif v2, which uses the new [@oclif/core](https://github.com/oclif/core) library! \ud83c\udf89\\n\\noclif v2 includes many changes that improve the experience of both creating and using an oclif CLI.\\n\\nGoing forward, we don\'t plan to make any updates to oclif v1 and its corresponding libraries, except for critical security fixes. See the [compatibility matrix](#compatibility-matrix) for a list of these libraries. In order to give developers time to migrate from v1 to v2, we\'re not completely dropping support yet. But at some point in the future we\'ll archive the v1 repositories and deprecate their versions on npm.\\n\\n## What\u2019s changing?\\n\\n### Repository Changes\\n\\nAll repositories under the [oclif org](https://github.com/oclif/) now use `main` as their primary branch and `oclif-v1` as the legacy branch. The `main` branch corresponds to oclif v2 and the `oclif-v1` branch to oclif v1. If you find any repos that don\u2019t have a `main` branch, you can safely assume that they\'re not used in oclif v2 and will be deprecated in the future.\\n\\n### Consolidating Tools & Libraries\\n\\nThe [`oclif-dev`](https://github.com/oclif/dev-cli) CLI has now been incorporated into [`oclif`](https://github.com/oclif/oclif). You now no longer need to install a separate package to manage your entire CLI\u2019s lifecycle.\\n\\nThe following libraries have been consolidated under [`@oclif/core`](https://github.com/oclif/core) and will be deprecated at some point in the future. Read the [migration guide](https://github.com/oclif/core/blob/main/MIGRATION.md) to learn how to update your CLI or plugin to use the new core library.\\n\\n* `@oclif/command`\\n* `@oclif/config`\\n* `@oclif/error`\\n* `@oclif/help`\\n* `@oclif/parser`\\n\\n### No more single vs multi command CLIs\\n\\nThere\'s only one \\"type\\" of oclif v2 CLI, but it can have as few or as many commands as a developer wants. As a result, there\u2019s only one command to generate CLIs, `oclif generate`, as opposed to the old `oclif single` and `oclif multi` commands.\\n\\n### Node > 12\\n\\nTo ensure oclif CLIs are as secure as possible, all v2 libraries and plugins support only Node 12 or higher as of now. Going forward, they\'ll support only Node Maintenance or higher, as defined by Node\'s release schedule here: https://nodejs.org/en/about/releases/.\\n\\n## What\u2019s new?\\n\\n### New example CLI\\n\\n[`oclif-hello-world`](https://github.com/oclif/hello-world/) is our new example repo. This is also the repo that\'s [used as a template](https://github.com/oclif/oclif/blob/edc6616e51/src/generators/cli.ts#L74) when running `oclif generate` to create a new CLI. This repo will always be able to be referenced as an example of what an oclif v2 CLI should look like.\\n\\n### Spaced commands\\n\\noclif CLIs can now use spaces, instead of colons, to separate topics and subcommands. To enable this feature, simply add `\u201ctopicSeparator\\": \\" \\"` to the oclif config in your package.json. See an example in our [example repo](https://github.com/oclif/hello-world/blob/main/package.json#L55).\\n\\n```\\n// Old commands that use :\\n$ mycli do:something\\n```\\n```\\n// New spaced commands\\n$ mycli do something\\n```\\n\\n> Note: Spaced commands are backwards compatible. So if you enable spaced commands for your CLI, users will still be able to use `:` as a separator. This ensures that any existing scripts don\'t break.\\n\\n### New Help Output\\n\\nWe\u2019ve revamped the way command help is outputted to the terminal, making it both easier to implement and easier to read. See the difference between the old help output on the left and the new help output on the right in the screenshots below.\\n\\n\\n \\n \\n \\n \\n \\n \\n \\n \\n
oclif v1oclif v2
\\n\\nNotice that there are new sections for flags and global flags, examples are displayed with better spacing, and there is a section at the bottom called Configuration Variables. This Configuration Variables section is not part of the new help by default. But we\'ve added support for custom help sections, which is what the `sf` CLI uses to create the new section. \\n\\n### Async Command Parsing\\n\\nWe\u2019ve also improved the performance of new CLIs by rewriting how commands are parsed on initialization. The [new parser](https://github.com/oclif/core/blob/main/src/parser/parse.ts) is asynchronous, which makes CLIs with a lot of commands or installed plugins much faster.\\n\\n## What\u2019s coming next?\\n\\nPart of our charter for the release of oclif v2 includes improving our engagement with the oclif community. We know that over the past couple of years we\u2019ve reduced our involvement, and a lot of issues and PRs have languished in limbo. Hopefully you\u2019ve already seen increased activity and responses from oclif maintainers recently, but if you haven\u2019t, please don\u2019t hesitate to ping us by tagging [@admins](https://github.com/orgs/oclif/teams/admins) in oclif repos.\\n\\nWe also want to start interviewing members of the oclif community to acquire feedback and prioritize the features and fixes you deem most important!\\n\\nBest,\\n\\nThe oclif team\\n\\n
\\n\\n### Reference material \\n\\n#### Migration Guide\\n\\nThis guide explains how to upgrade a CLI or plugin from the old oclif v1 libraries to the new `@oclif/core` library that oclif v2 uses.\\n\\nhttps://github.com/oclif/core/blob/main/MIGRATION.md\\n\\n#### Compatibility Matrix\\n\\nThe following matrix shows how the v1 libraries and plugins relate to the new v2 ones. Use this matrix as a guide to know what to drop and which versions to switch when upgrading your plugins and CLIs to v2.\\n\\n| | oclif \\"v1\\" | oclif \\"v2\\" |\\n| - | - | -|\\n| Utility CLIs | oclif@<2
@oclif/dev-cli@<2 | oclif@>=2\\n| Main packages | @oclif/command
@oclif/config
@oclif/errors
@oclif/parser
@oclif/plugin-help
| @oclif/core@>=1\\n| Node LTS | Node v8-14 | Node v12+ (at time of writing) |\\n| TypeScript | typescript@<4 | typescript@>=4 |\\n| Main plugins | @oclif/plugin-autocomplete@<1
@oclif/plugin-commands@<2
@oclif/plugin-help@<4
@oclif/plugin-not-found@<2
@oclif/plugin-plugins@<2
@oclif/plugin-update@<2
plugin-warn-if-update-available@<2
plugin-which@<2
| @oclif/plugin-autocomplete@>=1
@oclif/plugin-commands@>=2
@oclif/plugin-help@>=4
@oclif/plugin-not-found@>=2
@oclif/plugin-plugins@>=2
@oclif/plugin-update@>=2
@oclif/plugin-warn-if-update-available@>=2
@oclif/plugin-which@>=2
|"},{"id":"/2021/03/01/introducing-oclif-core","metadata":{"permalink":"/blog/2021/03/01/introducing-oclif-core","source":"@site/blog/2021-03-01-introducing-oclif-core.md","title":"Introducing @oclif/core","description":"Greetings!","date":"2021-03-01T00:00:00.000Z","formattedDate":"March 1, 2021","tags":[],"readingTime":2.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Introducing @oclif/core"},"prevItem":{"title":"Announcing oclif v2!","permalink":"/blog/2022/01/12/announcing-oclif-v2"},"nextItem":{"title":"oclif Summer Update","permalink":"/blog/2020/08/26/summer-update"}},"content":"Greetings!\\n\\nWe hope this blog post finds you well.\\n\\n### Introducing...\\n\\nWe are excited to announce the next iteration of the oclif project today: `@oclif/core`.\\n\\nWe have learned a lot in the last three years of developing oclif, developing on oclif and supporting millions of command runs a day via Heroku and Salesforce CLIs.\\n`@oclif/core` (\\"Core\\") simplifies the oclif development experience and introduces highly requested new features.\\n\\nCore combines the essential oclif packages into one \\"core\\" package, aptly named `@oclif/core`.\\n\\nCore also introduces:\\n- A default command option\\n- Colon or space command syntax\\n- Async command parsing\\n- Command piping to arguments\\n\\nWith the introduction of default command functionality, Core simplifies the oclif project and removes the notion of single or multi command CLIs. Core CLIs can have 1 or many commands.\\n\\nAlong with Core, we moved the oclif-dev CLI into the oclif CLI creating a single \\"utility\\" CLI. This CLI also introduces a new AWS S3 compatible publishing scheme.\\n\\n### What to expect in the near future\\n\\nCore is in pre-release beta and being actively developed for new internal Salesforce CLIs.\\n\\nMuch documentation needs to be written in the coming months including migration paths. Migration onto Core should be as painless as possible with many exports remaining entirely unchanged. Look for forthcoming blog posts and documentation on [oclif.io](https://oclif.io).\\n\\nEarly this summer, tentively June 1, we will release Core v1. Core\'s release will coincide with major bumps to many other oclif plugin packages. See the compatibility matrix below.\\n\\nAt Core\'s v1 release, the current \\"main\\" oclif packages (namely: command, config, errors & parser) will go into maintenance mode until Jan 2022. They will receive _only_ bug and security fixes and they remain compatible with current versions of the oclif and oclif-dev CLIs. Afterwhich, they will be archived.\\n\\nCompanioning Core, the next major release of the oclif CLI (literally `oclif@2`) will generate Core CLIs.\\n\\n### Going forward\\n\\nWe are excited to release Core! We invite you to poke around the [Core repo](https://github.com/oclif/core). It may appear to be a big change but Core keeps what you already enjoy about oclif while reducing development complexity, project dependencies, package coupling and bundle size and introduces many requested features previously too prickly to weave into the current oclif architecture.\\n\\nBest,\\n\\nThe oclif team\\n\\n#### Reference: Compatibility matrix\\n\\n| | oclif \\"v1\\" | oclif \\"Core\\" |\\n| - | - | -|\\n| Utility CLIs | oclif@<2
@oclif/dev-cli@<2 | oclif@>=2\\n| Main packages | @oclif/core@<2
@oclif/config@<2
@oclif/errors@<2
@oclif/parser@<4
@oclif/plugin-help@<4
| @oclif/core@>=1\\n| Node LTS | Node v8-14 | Node v12+ |\\n| TypeScript | typescript@<4 | typescript@>=4 |\\n| Main plugins | @oclif/plugin-autocomplete@<1
@oclif/plugin-commands@<2
@oclif/plugin-help@<4
@oclif/plugin-not-found@<2
@oclif/plugin-plugins@<2
@oclif/plugin-update@<2
plugin-warn-if-update-available@<2
plugin-which@<2
| @oclif/plugin-autocomplete@>=2
@oclif/plugin-commands@>=2
@oclif/plugin-help@>=4
@oclif/plugin-not-found@>=2
@oclif/plugin-plugins@>=2
@oclif/plugin-update@>=2
@oclif/plugin-warn-if-update-available@>=2
@oclif/plugin-which@>=2
|"},{"id":"/2020/08/26/summer-update","metadata":{"permalink":"/blog/2020/08/26/summer-update","source":"@site/blog/2020-08-26-summer-update.md","title":"oclif Summer Update","description":"Hello oclif developers! We hope you are all doing well.","date":"2020-08-26T00:00:00.000Z","formattedDate":"August 26, 2020","tags":[],"readingTime":1.355,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"oclif Summer Update"},"prevItem":{"title":"Introducing @oclif/core","permalink":"/blog/2021/03/01/introducing-oclif-core"},"nextItem":{"title":"Pretty Printable Errors","permalink":"/blog/2020/07/01/pretty-printable-errors"}},"content":"Hello oclif developers! We hope you are all doing well.\\n\\nEarlier this year, we started our planning for oclifconf v2 and, like all conference, had to change course. We opted not to hold a virtual conference, however, we wanted to take some time to highlight a few oclif features shipped this year.\\n\\n## Feature: Help templating\\n\\nOne of the most requested features, help templating enables oclif developers to customize the help output for their CLI.\\n\\nRead [the announcement](/blog/introducing-custom-help-classes).\\n\\n## Feature: Custom error delegation\\n\\nThis feature both improved how oclif throws and handles errors and allows oclif developers to overwrite or interject in oclif\u2019s error handling.\\n\\nRead [the announcement](/blog/2020/07/01/pretty-printable-errors).\\n\\n## Feature: postrun hooks\\n\\nWe have added a new lifecycle event `postrun`. Your CLI can now run a hook after a command has ran.\\n\\nSee our [hook documentation](/docs/hooks).\\n\\n## Feature: Root index command\\n\\nPreviously, oclif would display CLI help if only the binary name with no command ID was invoked, oclif now supports a \\"root index\\" command. If present, a command defined at `src/commands/index.ts` will be run if no command ID is found.\\n\\n## 1 million weekly downloads\\n\\nWhile exact oclif usage metrics are hard to pin down, we use npm download statistics of oclif packages as a rough approximation. Earlier this year, oclif\'s command package hit 1 million weekly downloads for the first time!\\n\\n\\nThis year has been presented its challenges on everyone. We want to thank you, oclif developers, whom have taken the time to use and improve the oclif project. We look forward to seeing you all - in person - in the future!\\n\\nAll our best,\\n\\nThe oclif team"},{"id":"/2020/07/01/pretty-printable-errors","metadata":{"permalink":"/blog/2020/07/01/pretty-printable-errors","source":"@site/blog/2020-07-01-pretty-printable-errors.md","title":"Pretty Printable Errors","description":"Often CLIs are used as handy tools and when things go wrong it\u2019s useful to have additional context. In oclif we have added a couple of additional properties that can show extra context to the users when an error is displayed. The code, ref and suggestions will now be displayed if they are included. This will work with an existing oclif CLI by adding the latest @oclif/errors and @oclif/core to the CLI\'s package.json dependencies.","date":"2020-07-01T00:00:00.000Z","formattedDate":"July 1, 2020","tags":[],"readingTime":0.995,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Pretty Printable Errors"},"prevItem":{"title":"oclif Summer Update","permalink":"/blog/2020/08/26/summer-update"},"nextItem":{"title":"Customizing Help in oclif","permalink":"/blog/2020/05/05/introducing-custom-help-classes"}},"content":"Often CLIs are used as handy tools and when things go wrong it\u2019s useful to have additional context. In oclif we have added a couple of additional properties that can show extra context to the users when an error is displayed. The `code`, `ref` and `suggestions` will now be displayed if they are included. This will work with an existing oclif CLI by adding the latest @oclif/errors and @oclif/core to the CLI\'s package.json dependencies.\\n\\nFor example, using `this.error` with the additional properties:\\n```js\\nclass TestError extends Command {\\n async run() {\\n this.error(\\"An error has occurred!\\", {\\n code: \\"OCLIF_ERR\\",\\n ref: \\"https://oclif.io/docs/commands#thiserrormessage-string--error-options-code-string-exit-number\\",\\n suggestions: [\\"Use these extra properties to provide additional context\\"],\\n })\\n }\\n}\\n```\\n\\nwould result with the following output:\\n```text\\n\u203a Error: An error has occurred!\\n\u203a Code: OCLIF_ERR\\n\u203a Try this: Use these extra properties to provide additional context\\n\u203a Reference: https://oclif.io/docs/commands#thiserrormessage-string--error-options-code-string-exit-number\\n```\\n\\nIf these properties are not provided then nothing changes and the CLI will continue to display the single error message output as it did before. Additionally, as part of this exercise we\u2019ve added documentation around [Error Handling in oclif](/docs/error_handling) which should come in handy if the need arises to extend oclif\u2019s default handling of errors."},{"id":"/2020/05/05/introducing-custom-help-classes","metadata":{"permalink":"/blog/2020/05/05/introducing-custom-help-classes","source":"@site/blog/2020-05-05-introducing-custom-help-classes.md","title":"Customizing Help in oclif","description":"Out of the box oclif provides a great help experience for CLIs.","date":"2020-05-05T00:00:00.000Z","formattedDate":"May 5, 2020","tags":[],"readingTime":1.67,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Customizing Help in oclif"},"prevItem":{"title":"Pretty Printable Errors","permalink":"/blog/2020/07/01/pretty-printable-errors"},"nextItem":{"title":"oclif TSLint to ESLint Migration","permalink":"/blog/2019/12/05/oclif-eslint-migration"}},"content":"Out of the box oclif provides a great help experience for CLIs.\\n\\nBut what if, as an oclif developer, you want to customize some or all of the output?\\n\\nYou can now customize your CLI\'s help output by implementing the `HelpBase` abstract class.\\n\\n## Getting started with custom help\\n\\nIf you have not done so yet, update `@oclif/core`.\\n\\n\\n```\\n$ yarn add --latest @oclif/core\\n```\\n\\nTo get started, first define the filepath to your help class in oclif\'s config in package.json. This is a relative path to the help class, without a file extension.\\n\\nFor this example, the help class will be created in a file at \\"[project root]/src/help.ts\\".\\n\\n```\\n{\\n // ...\\n \\"oclif\\": {\\n \\"helpClass\\": \\"./lib/help\\"\\n // ...\\n }\\n // ...\\n}\\n```\\n\\nFrom here there are two paths, implement the `HelpBase` abstract class yourself or overwrite the parts of the default `Help` class you want to customize (ex: how command usage is displayed). We recommend the latter approach but cover both in the new [Help Classes docs](../../../../docs/help_classes).\\n\\n\\n## Separating TOPICS & COMMANDS in the new deafult `Help` class\\n\\nPreviously, topics and child commands were listed in help output under a single list heading called \\"COMMANDS\\". But we found this can be slightly confusing. Some topics are commands also (a.k.a. topic-commands) while others are simply organizational namespacing (and when ran just show their help).\\n\\nThe new default `Help` class splits the list of children into distinct lists of \\"TOPICS\\" and \\"COMMANDS\\", with the possibility of an item appearing in both if it a topic-command. This makes it clearer what is expected to be ran - \\"COMMANDS\\" - and what is providing structure - \\"TOPICS\\" - when looking at the help output.\\n\\n```\\nVERSION\\n plugin-help-example/0.0.0 darwin-x64 node-v12.12.0\\n\\nUSAGE\\n $ plugin-help-example [COMMAND]\\n\\nTOPICS\\n topic this is a topic and has child topics or commands\\n\\nCOMMANDS\\n hello describe the command here\\n help display help for plugin-help-example\\n```\\n\\nWe look forward to seeing what custom help features you implement in your oclif CLIs with this new feature!"},{"id":"/2019/12/05/oclif-eslint-migration","metadata":{"permalink":"/blog/2019/12/05/oclif-eslint-migration","source":"@site/blog/2019-12-05-oclif-eslint-migration.md","title":"oclif TSLint to ESLint Migration","description":"Back in February of this year, plans were announced to deprecate TSLint in favor of ESLint. TSLint\'s goal has become to work toward a \u201cunified developer experience\u201d by supporting ESLint development going forward.","date":"2019-12-05T00:00:00.000Z","formattedDate":"December 5, 2019","tags":[],"readingTime":2.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"oclif TSLint to ESLint Migration"},"prevItem":{"title":"Customizing Help in oclif","permalink":"/blog/2020/05/05/introducing-custom-help-classes"},"nextItem":{"title":"oclif\'s Current Node Support","permalink":"/blog/2019/10/31/oclif-node-updates"}},"content":"Back in February of this year, plans were announced to [deprecate TSLint](https://github.com/palantir/tslint/issues/4534) in favor of ESLint. TSLint\'s goal has become to work toward a \u201cunified developer experience\u201d by supporting ESLint development going forward.\\n\\n\\n\\n## What has changed in oclif\\n\\nTo keep inline with the community, oclif has transitioned to ESLint for all our core libraries as well as all our official plugins.\\n\\nStarting in v1.15.x, oclif will now optionally generate projects with ESLint for both TypeScript and JavaScript CLI\u2019s.\\n\\nESLint does require Node to be on stable LTS version, at the time of writing, Node 8.10.x, Node 10.13.x & Node 12.x.x.\\n\\n## How does this affect you\\n\\nExisting CLI\u2019s are unchanged, but any newly generated CLI\'s will only give the option of using ESLint. If you are running tslint in your CLI, we recommend you switch to ESLint as well.\\n\\nIn migrating our projects we took the following steps (for an example of these changes see this [pull request](https://github.com/oclif/githubcli/pull/10)).\\n\\n1. Install eslint\\n\\n `$ yarn add eslint eslint-config-oclif eslint-config-oclif-typescript --dev`\\n2. Add eslint related files\\n```shell\\n$ echo \'{\\n \\"extends\\": [\\n \\"oclif\\",\\n \\"oclif-typescript\\"\\n ],\\n \\"rules\\": {\\n }\\n}\' > .eslintrc\\n```\\n3. Remove tslint and related packages\\n\\n `$ yarn remove @oclif/tslint tslint`\\n4. Remove tslint related configuration files\\n\\n `$ rm tslint.json`\\n5. Change lint script in our package.json from something like:\\n\\n `\\"lint\\": \\"tsc -p test --noEmit && tslint -p test -t stylish\\"`\\n \\n to\\n \\n `\\"lint\\": \\"eslint . --ext .ts --config .eslintrc\\"`\\n\\nTo preserve the test compile (tsc -p test --noEmit) we also made the following updates to our scripts:\\n\\n`\\"pretest\\": \\"tsc -p test --noEmit\\"`\\n\\nIn some cases we had our posttest duplicating the same steps as our lint script so it\u2019s cleaner to have it reference the lint job directly with:\\n\\n`\\"posttest\\": \\"yarn lint\\"`\\n\\n\\n6. Run `yarn lint --fix`. This attempts to auto-fix any linting violations automatically. In the case an auto-fix isn\u2019t available it should be fixed manually or ignored (see the [eslint configuration doc](https://eslint.org/docs/user-guide/configuring) for more information) \\n7. Do a search in the codebase for `tslint` and remove any unnecessary tslint disabling comments, like: \\n```javascript\\n/* tslint:disable:object-literal-sort-keys */\\n```\\n\\n\\nIf you are on a version of Node that is not supported by ESLint, you will also need to update your Node engine. ESLint supports Node 8, 10, and 12 so you should upgrade to the most recent Node version compatible with your CLI and also supported by ESLint (see ESLint\'s [Installation and Usage](https://www.npmjs.com/package/eslint#installation-and-usage) instructions).\\n\\n## When will this take effect\\n\\nThese changes have taken effect in oclif v1.15.1. When you generate a new CLI or plugin it will now contain configuration for ESLint instead of TSLint."},{"id":"/2019/10/31/oclif-node-updates","metadata":{"permalink":"/blog/2019/10/31/oclif-node-updates","source":"@site/blog/2019-10-31-oclif-node-updates.md","title":"oclif\'s Current Node Support","description":"To maintain a healthy project trajectory, oclif follows and supports Node Active LTS release, currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining Node 8 and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes.","date":"2019-10-31T00:00:00.000Z","formattedDate":"October 31, 2019","tags":[],"readingTime":2.4,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"oclif\'s Current Node Support"},"prevItem":{"title":"oclif TSLint to ESLint Migration","permalink":"/blog/2019/12/05/oclif-eslint-migration"},"nextItem":{"title":"oclifconf 2019: A Recap","permalink":"/blog/2019/09/16/oclifconf-recap"}},"content":"To maintain a healthy project trajectory, oclif follows and supports [Node Active LTS release](https://nodejs.org/en/about/releases/), currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining [Node 8](https://github.com/nodejs/Release#release-schedule) and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes.\\n\\n## CI Environments\\n\\nCLIs created with the oclif cli going forward will be generated with a CircleCI configuration with Node 10 & 12 and an Appveyor configuration using Node 10. We have also added Node latest to CircleCi to be an early warning detection against coming Node changes (Node latest is managed by CircleCI).\\n\\nWe have already updated every oclif repo\'s CI configs to reflect this.\\n\\nIf your existing CLI uses either Appveyor or CircleCI you can update your config files also, like so:\\n\\n### .circleci/config.yml\\n\\nYour CircleCI config should contain a `node-latest` job, aliased as `test`. From this, there should be two extensions of this job for the Active LTS Node versions, Node 10 and Node 12.\\n\\n```\\n node-10:\\n <<: *node-latest\\n docker:\\n - image: node:10\\n node-12:\\n <<: *node-latest\\n docker:\\n - image: node:12\\n```\\n\\nNotice that these declarations only change the Docker Node images used to run that job.\\n\\nAdditionally, the jobs listed within workflows must also be updated to reflect our changes in configuration:\\n\\n```\\n jobs:\\n - node-latest\\n - node-10\\n - node-12\\n```\\n\\n### appveyor.yml\\n\\nFor appveyor we are currently only testing the oldest Active LTS Node version, Node 10. Update the `nodejs_version` proppert in your appveyor.yml file to reflect this.\\n\\n```\\nenvironment:\\n nodejs_version: \\"10\\"\\n```\\n\\n\\n## Deprecating Node 8 & Updating packge.json engines\\n\\nIn Jan 2020, Node will end its Node 8 maintenance. We will follow suit by setting the package.json engine property in oclif packages to `>=10` and bumping the package\'s major versions.\\n\\nDepending on how you ship your CLI you may wish to also bump the engines version in your CLI\'s package.json. You can read more about the implications of the engines property configuration in the [npm documentation](https://docs.npmjs.com/files/package.json#engines).\\n\\nAlso consider distributing your CLI with [its own Node version](https://oclif.io/docs/releasing#standalone-tarballs).\\n\\n## Packaged Node Version\\n\\nWhen using dev-cli to pack your CLI it will use the Node version as specified in your package.json under the `oclif.update.node.version` property. This value should reflect an Active LTS Node version (dev-cli does not currently enforce versions).\\n\\n## Supporting the future\\n\\nAs a community we may discover bumps along the way as we upgrade. If you notice something related to oclif please feel free to open an issue or submit a pull request under the relevant oclif package within [the org](https://github.com/oclif).\\n\\nWe look forward to using the latest from Node and the community and keeping oclif healthy along the way."},{"id":"/2019/09/16/oclifconf-recap","metadata":{"permalink":"/blog/2019/09/16/oclifconf-recap","source":"@site/blog/2019-09-16-oclifconf-recap.md","title":"oclifconf 2019: A Recap","description":"In May, Heroku and Salesforce Open Source organized oclifconf, a conference for developers & product managers building CLI tools on top of the open source oclif framework. The speakers came from various tech companies, such as Adobe, Netlify, and Apollo, who have already built amazing CLI experiences. The topics covered everything from the incredible capabilities oclif has unlocked, to the community-built plugins extending its functionality, and even what the behavior of an adaptive CLI tool might look like.","date":"2019-09-16T00:00:00.000Z","formattedDate":"September 16, 2019","tags":[],"readingTime":3.56,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"oclifconf 2019: A Recap"},"prevItem":{"title":"oclif\'s Current Node Support","permalink":"/blog/2019/10/31/oclif-node-updates"},"nextItem":{"title":"CLI Flags Explained","permalink":"/blog/2019/02/20/cli-flags-explained"}},"content":"In May, Heroku and Salesforce Open Source organized [oclifconf](https://oclif.io/conf), a conference for developers & product managers building CLI tools on top of [the open source oclif framework](https://github.com/oclif/oclif). The speakers came from various tech companies, such as Adobe, Netlify, and Apollo, who have already built amazing CLI experiences. The topics covered everything from the incredible capabilities oclif has unlocked, to the community-built plugins extending its functionality, and even what the behavior of an adaptive CLI tool might look like.\\n\\nBelow is a listing of all of the talks from the event, along with a short summary. Enjoy!\\n\\n## The future of oclif by Jeff Dickey\\n\\n\\n\\nIn its relatively short lifetime, oclif has already inspired many developers and companies to adopt its framework as a means for implementing their own command-line tooling. In this talk, Jeff Dickey, an oclif founding team member, recaps the project\'s history and inspiration. He also looks towards the future and outlines some features and improvements that the tool could adapt. This isn\'t so much a definitive roadmap of where oclif is headed, but rather, a call to inspiration for developers eager to contribute! And if you are interested in contributing, check out the [open issues](https://github.com/oclif/oclif/issues) in the oclif GitHub repo and come say \\"Hello!\\" on [Spectrum Chat](https://spectrum.chat/oclif).\\n\\n## Open Source Citizenship by Josh Simmons\\n\\n\\n\\nWhen it comes to open source, it\'s more than just individuals now. More and more frequently, large corporations are contributing to projects by donating to contributors, sponsoring events, or upstreaming contributions. But keeping open source projects and communities healthy requires more than just money and brainpower. Josh Simmons surveyed multiple open source communities and relays his findings as to what help maintainers and contributors actually need in this talk.\\n\\n## Building an enterprise-grade CLI with oclif by Thomas Dvornik\\n\\n\\n\\nSecurity and performance are all about trust. While oclif is an extremely extensible framework for building CLI tooling, there are additional requirements to fulfill for enterprise businesses to adopt it that might not be necessary for individual developers. Thomas Dvornik outlines what he and his colleagues at Salesforce have implemented as plugins to oclif to satisfy these needs, including encrypted OAuth, plugin signing, lazy loading dependencies, synchronizing weekly releases and deprecations across dozens of repositories, and establishing cross-team coding and documentation standards.\\n\\n## How Adobe I/O built an extensible CLI with oclif by Jesse MacFadyen\\n\\n\\n\\nPerhaps oclif\'s most appealing feature is its support for plugins. In Cordova\'s case, they\'ve created a sophisticated telemetry system that helps Adobe developers see which commands users are using--and reports on which ones are erroring out. By embedding a feedback system into the tool, users are even able to quickly send their suggestions to a form, without ever leaving the terminal. Jesse MacFadyen demonstrates how oclif\'s plugin system can work beyond simply executing commands.\\n\\n## Integrating oclif with GraphQL and Apollo by Evans Hauser\\n\\n\\n\\nFor Evans Hauser and the team at Apollo, oclif is best thought of as \\"React for the CLI.\\" As a client paired with a strongly-typed API contract to a server, it can deliver structured and consistent commands to retrieve external data. What better mechanism to use for this transfer than GraphQL, a framework which empowers the client to ask precisely for the data it needs, and nothing more?\\n\\n## Adaptive Intent-based CLI State Machines by Shawn Wang\\n\\n\\n\\nIn designing oclif, [Jeff Dickey wrote out 12 CLI factors to keep in mind](https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46). In this talk, Shawn Wang outlines a 13th: state. State is hard, because it depends on context, and context depends on understanding what a user intends to do, not what they are asking. Shawn is working towards enabling oclif to better understand the commands a user has entered, so that it can predict and interpret future commands that might be entered next. This would enable CLI tools to not just interpret a users\' commands, but to also interpret their intent."},{"id":"/2019/02/20/cli-flags-explained","metadata":{"permalink":"/blog/2019/02/20/cli-flags-explained","source":"@site/blog/2019-02-20-cli-flags-explained.md","title":"CLI Flags Explained","description":"oclif makes it easy to create a command line interface (CLI) in node. Most commands have parameters \u2014 also known as \\"flags\\", \\"args\\", and sometimes \\"options\\". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.","date":"2019-02-20T00:00:00.000Z","formattedDate":"February 20, 2019","tags":[],"readingTime":4.925,"hasTruncateMarker":false,"authors":[{"name":"Casey Watts and Jeff Dickey"}],"frontMatter":{"author":"Casey Watts and Jeff Dickey","title":"CLI Flags Explained"},"prevItem":{"title":"oclifconf 2019: A Recap","permalink":"/blog/2019/09/16/oclifconf-recap"},"nextItem":{"title":"Introducing oclif","permalink":"/blog/2018/03/20/introducing-oclif"}},"content":"`oclif` makes it easy to create a command line interface (CLI) in node. Most commands have **parameters** \u2014 also known as \\"flags\\", \\"args\\", and sometimes \\"options\\". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.\\n\\n_Note the following describes GNU-style flags. Not all CLIs follow this convention, but it is the most commonly used._\\n\\n## Parts of Speech\\n\\nAny command line interface command has a few standard \\"parts of speech\\". As a user of CLI tools, knowing these parts of speech can help you make fewer typos. It can also help you understand complex commands other people share with you more quickly. If you are designing a CLI tool it is even more important to understand these parts of speech, so you can come up with the most ergonomic interface for your users.\\n\x3c!-- DIAGRAM OF PARTS OF SPEECH EXAMPLE --\x3e\\n\\nOf the many ways you can pass data to a CLI command, three of them are **parameters** that are always to the \\"right\\" of the command. The three types of parameters are **argument**, **short flag**, and **long flag**.\\n\\n### Example `ls`\\nOne of the most common and simplest unix commands is `ls` which \\"lists\\" the contents of a directory.\\n\\n#### command\\n\\n```\\nls\\n```\\n\\nThis command `ls` works on its own, as a standalone **command**. Without any parameters this command will list the contents of the current folder, using an implied `.` directory.\\n\\n#### argument\\n\\n```\\nls .\\nls ~/code/some-repo-name\\n```\\n\\nIf you pass a command **argument** to this command, like the directory name `.` (current folder) or `~/code/some-repo-name`, it will list the contents of that directory instead.\\n\\nAn argument is anything to the right of a command that is not a flag. An argument can come before or after flags.\\n\\n#### Long flag\\nTo list additional files that are normally hidden (like `~/.bashrc`), you can use a flag on the `ls` command. `ls --all` is the **long flag** form. A long flag always uses a double dash, and it is always represented by multiple characters.\\n\\n```\\nls --all\\nls . --all\\n```\\n\\n#### Short flag\\n\\nThere is also a **short flag** form of this flag: `ls -a`. The `a` is short for `all` in this case. A short flag always uses a single dash, and it is always represented by a single letter.\\n\\n```\\nls -a\\nls . -a\\n```\\n\\nShort flags can **stack** too, so you don\'t need a separate dash for each one. Order does not matter for these, unless passing a flag argument.\\n\\n```\\nls -la\\n```\\n\\n#### Flag arguments\\nMany flags accept an **option**, which is a \\"flag argument\\" (as opposed to a \\"command argument\\"). In general a command\'s parameters can be in any order, but flags that accept options must have the option directly after the flag.\\n\\nFor an example, here the `-x` flag does not accept an option but the `-f` flag does. `archive.tar` is the option being passed to `-f`.\\n\\n```\\ntar -x -f archive.tar\\ntar -xf archive.tar\\n```\\n\\nA flag and its option can be separated by a space ` ` or an equals sign `=`. Interestingly, short flags (but not long flags) can even skip the space, although many people find it much easier to read with the space or equals sign.\\n\\nThese three are all valid and equivalent:\\n\\n```\\ntar -f archive.tar\\ntar -f=archive.tar\\ntar -farchive.tar\\n```\\n\\nLong flags must have a space or equals sign to separate the flag from its option.\\n\\n```\\ngit log --pretty=oneline\\ngit log --pretty oneline\\n```\\n\\n## Other Ways of Passing Data\\n\\nWe\'ve covered **parameters**, which are **arguments**, **short flags** and **long flags**. There are two other ways to pass data to a command: **environment variables** (\\"env vars\\"), or **standard input** (\\"stdin\\"). These won\'t be covered in this blog post.\\n\\n\\n## Designing a Command\\n\\nScenario: we want to design an oclif command that echos an input like \\"Casey\\", and returns \\"hi, Casey!\\". There are many ways the user could pass this in, and here we show an example of each type of input.\\n\\n### argument\\n\\n```\\ngreet-me Casey\\n```\\n\\n### short flag with argument\\n\\n```\\ngreet-me -n Casey\\ngreet-me -n=Casey\\ngreet-me -nCasey\\n```\\n\\n### long flag with argument\\n\\n```\\ngreet-me --name=Casey\\ngreet-me --name Casey\\n```\\n\\n### environment variable\\n\\n```\\nNAME=Casey greet-me\\n```\\n\\n### standard input\\n\\n```\\necho \\"Casey\\" | greet-me\\n```\\n\\n## Command ergonomics\\n\\n### Short flag vs long flag\\nMany CLI commands allow for both long flag and short flag forms. In the Heroku CLI every flag has at least a long flag form and roughly half of the flags also have a short flag form.\\n\\nThe long flag form is easier to read, but takes more characters to type. It is often most useful when you want someone to understand a particular command statement quickly and easily, such as in a README.\\n\\nThe short flag form is quicker to type, and is often better for frequently used commands. Short flags are especially useful when stacking short flags together.\\n\\n\\n\x3c!-- ## Did you mean?\\nIt is really easy to make a typo and use one dash instead of two, or vice versa. This \\"Long flag / short flag mismatch\\" is quite common. We hope that by catching these typos we will help you make fewer typos, save you from frustration, and speed up your development.\\n\\n`oclif` can now detect when you accidentally have the wrong number of dashes for a command, and suggest a change to the command.\\n\\n```\\nheroku config --s\\n> did you mean \\"heroku config -s\\"?\\n```\\n\\n```\\nheroku config -something-long\\n> did you mean \\"heroku config --something-long\\"?\\n```\\n\\n```\\nheroku config ---something-long\\n> did you mean to use FEWER DASHES? (something like this?)\\n```\\n\\nThis is an example of a \\"did you mean?\\" command, like this ruby plugin [did_you_mean](https://github.com/yuki24/did_you_mean).\\n--\x3e"},{"id":"/2018/03/20/introducing-oclif","metadata":{"permalink":"/blog/2018/03/20/introducing-oclif","source":"@site/blog/2018-03-20-introducing-oclif.md","title":"Introducing oclif","description":"Introducing oclif","date":"2018-03-20T00:00:00.000Z","formattedDate":"March 20, 2018","tags":[],"readingTime":0.285,"hasTruncateMarker":false,"authors":[{"name":"Jeff Dickey"}],"frontMatter":{"author":"Jeff Dickey","title":"Introducing oclif"},"prevItem":{"title":"CLI Flags Explained","permalink":"/blog/2019/02/20/cli-flags-explained"}},"content":"![Introducing oclif](/img/2018-03-20-introducing-oclif/header.png)\\n\\nCoding for the browser takes serious time. You need to deal with front-end JS, CSS, design, product, and a ton more. On the other hand, building for a CLI takes a fraction of the effort. This makes CLIs particularly great for prototyping out new functionality, offering admin/internal tools, or power-user functionality.\\n\\nRead More"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1477],{10:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"/2022/01/12/announcing-oclif-v2","metadata":{"permalink":"/blog/2022/01/12/announcing-oclif-v2","source":"@site/blog/2022-01-12-announcing-oclif-v2.md","title":"Announcing oclif v2!","description":"Hello and happy new year! It\'s our great pleasure to announce that we have released oclif v2, which uses the new @oclif/core library! \ud83c\udf89","date":"2022-01-12T00:00:00.000Z","formattedDate":"January 12, 2022","tags":[],"readingTime":4.48,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Announcing oclif v2!"},"nextItem":{"title":"Introducing @oclif/core","permalink":"/blog/2021/03/01/introducing-oclif-core"}},"content":"Hello and happy new year! It\'s our great pleasure to announce that we have released oclif v2, which uses the new [@oclif/core](https://github.com/oclif/core) library! \ud83c\udf89\\n\\noclif v2 includes many changes that improve the experience of both creating and using an oclif CLI.\\n\\nGoing forward, we don\'t plan to make any updates to oclif v1 and its corresponding libraries, except for critical security fixes. See the [compatibility matrix](#compatibility-matrix) for a list of these libraries. In order to give developers time to migrate from v1 to v2, we\'re not completely dropping support yet. But at some point in the future we\'ll archive the v1 repositories and deprecate their versions on npm.\\n\\n## What\u2019s changing?\\n\\n### Repository Changes\\n\\nAll repositories under the [oclif org](https://github.com/oclif/) now use `main` as their primary branch and `oclif-v1` as the legacy branch. The `main` branch corresponds to oclif v2 and the `oclif-v1` branch to oclif v1. If you find any repos that don\u2019t have a `main` branch, you can safely assume that they\'re not used in oclif v2 and will be deprecated in the future.\\n\\n### Consolidating Tools & Libraries\\n\\nThe [`oclif-dev`](https://github.com/oclif/dev-cli) CLI has now been incorporated into [`oclif`](https://github.com/oclif/oclif). You now no longer need to install a separate package to manage your entire CLI\u2019s lifecycle.\\n\\nThe following libraries have been consolidated under [`@oclif/core`](https://github.com/oclif/core) and will be deprecated at some point in the future. Read the [migration guide](https://github.com/oclif/core/blob/main/MIGRATION.md) to learn how to update your CLI or plugin to use the new core library.\\n\\n* `@oclif/command`\\n* `@oclif/config`\\n* `@oclif/error`\\n* `@oclif/help`\\n* `@oclif/parser`\\n\\n### No more single vs multi command CLIs\\n\\nThere\'s only one \\"type\\" of oclif v2 CLI, but it can have as few or as many commands as a developer wants. As a result, there\u2019s only one command to generate CLIs, `oclif generate`, as opposed to the old `oclif single` and `oclif multi` commands.\\n\\n### Node > 12\\n\\nTo ensure oclif CLIs are as secure as possible, all v2 libraries and plugins support only Node 12 or higher as of now. Going forward, they\'ll support only Node Maintenance or higher, as defined by Node\'s release schedule here: https://nodejs.org/en/about/releases/.\\n\\n## What\u2019s new?\\n\\n### New example CLI\\n\\n[`oclif-hello-world`](https://github.com/oclif/hello-world/) is our new example repo. This is also the repo that\'s [used as a template](https://github.com/oclif/oclif/blob/edc6616e51/src/generators/cli.ts#L74) when running `oclif generate` to create a new CLI. This repo will always be able to be referenced as an example of what an oclif v2 CLI should look like.\\n\\n### Spaced commands\\n\\noclif CLIs can now use spaces, instead of colons, to separate topics and subcommands. To enable this feature, simply add `\u201ctopicSeparator\\": \\" \\"` to the oclif config in your package.json. See an example in our [example repo](https://github.com/oclif/hello-world/blob/main/package.json#L55).\\n\\n```\\n// Old commands that use :\\n$ mycli do:something\\n```\\n```\\n// New spaced commands\\n$ mycli do something\\n```\\n\\n> Note: Spaced commands are backwards compatible. So if you enable spaced commands for your CLI, users will still be able to use `:` as a separator. This ensures that any existing scripts don\'t break.\\n\\n### New Help Output\\n\\nWe\u2019ve revamped the way command help is outputted to the terminal, making it both easier to implement and easier to read. See the difference between the old help output on the left and the new help output on the right in the screenshots below.\\n\\n\\n \\n \\n \\n \\n \\n \\n \\n \\n
oclif v1oclif v2
\\n\\nNotice that there are new sections for flags and global flags, examples are displayed with better spacing, and there is a section at the bottom called Configuration Variables. This Configuration Variables section is not part of the new help by default. But we\'ve added support for custom help sections, which is what the `sf` CLI uses to create the new section. \\n\\n### Async Command Parsing\\n\\nWe\u2019ve also improved the performance of new CLIs by rewriting how commands are parsed on initialization. The [new parser](https://github.com/oclif/core/blob/main/src/parser/parse.ts) is asynchronous, which makes CLIs with a lot of commands or installed plugins much faster.\\n\\n## What\u2019s coming next?\\n\\nPart of our charter for the release of oclif v2 includes improving our engagement with the oclif community. We know that over the past couple of years we\u2019ve reduced our involvement, and a lot of issues and PRs have languished in limbo. Hopefully you\u2019ve already seen increased activity and responses from oclif maintainers recently, but if you haven\u2019t, please don\u2019t hesitate to ping us by tagging [@admins](https://github.com/orgs/oclif/teams/admins) in oclif repos.\\n\\nWe also want to start interviewing members of the oclif community to acquire feedback and prioritize the features and fixes you deem most important!\\n\\nBest,\\n\\nThe oclif team\\n\\n
\\n\\n### Reference material \\n\\n#### Migration Guide\\n\\nThis guide explains how to upgrade a CLI or plugin from the old oclif v1 libraries to the new `@oclif/core` library that oclif v2 uses.\\n\\nhttps://github.com/oclif/core/blob/main/MIGRATION.md\\n\\n#### Compatibility Matrix\\n\\nThe following matrix shows how the v1 libraries and plugins relate to the new v2 ones. Use this matrix as a guide to know what to drop and which versions to switch when upgrading your plugins and CLIs to v2.\\n\\n| | oclif \\"v1\\" | oclif \\"v2\\" |\\n| - | - | -|\\n| Utility CLIs | oclif@<2
@oclif/dev-cli@<2 | oclif@>=2\\n| Main packages | @oclif/command
@oclif/config
@oclif/errors
@oclif/parser
@oclif/plugin-help
| @oclif/core@>=1\\n| Node LTS | Node v8-14 | Node v12+ (at time of writing) |\\n| TypeScript | typescript@<4 | typescript@>=4 |\\n| Main plugins | @oclif/plugin-autocomplete@<1
@oclif/plugin-commands@<2
@oclif/plugin-help@<4
@oclif/plugin-not-found@<2
@oclif/plugin-plugins@<2
@oclif/plugin-update@<2
plugin-warn-if-update-available@<2
plugin-which@<2
| @oclif/plugin-autocomplete@>=1
@oclif/plugin-commands@>=2
@oclif/plugin-help@>=4
@oclif/plugin-not-found@>=2
@oclif/plugin-plugins@>=2
@oclif/plugin-update@>=2
@oclif/plugin-warn-if-update-available@>=2
@oclif/plugin-which@>=2
|"},{"id":"/2021/03/01/introducing-oclif-core","metadata":{"permalink":"/blog/2021/03/01/introducing-oclif-core","source":"@site/blog/2021-03-01-introducing-oclif-core.md","title":"Introducing @oclif/core","description":"Greetings!","date":"2021-03-01T00:00:00.000Z","formattedDate":"March 1, 2021","tags":[],"readingTime":2.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Introducing @oclif/core"},"prevItem":{"title":"Announcing oclif v2!","permalink":"/blog/2022/01/12/announcing-oclif-v2"},"nextItem":{"title":"oclif Summer Update","permalink":"/blog/2020/08/26/summer-update"}},"content":"Greetings!\\n\\nWe hope this blog post finds you well.\\n\\n### Introducing...\\n\\nWe are excited to announce the next iteration of the oclif project today: `@oclif/core`.\\n\\nWe have learned a lot in the last three years of developing oclif, developing on oclif and supporting millions of command runs a day via Heroku and Salesforce CLIs.\\n`@oclif/core` (\\"Core\\") simplifies the oclif development experience and introduces highly requested new features.\\n\\nCore combines the essential oclif packages into one \\"core\\" package, aptly named `@oclif/core`.\\n\\nCore also introduces:\\n- A default command option\\n- Colon or space command syntax\\n- Async command parsing\\n- Command piping to arguments\\n\\nWith the introduction of default command functionality, Core simplifies the oclif project and removes the notion of single or multi command CLIs. Core CLIs can have 1 or many commands.\\n\\nAlong with Core, we moved the oclif-dev CLI into the oclif CLI creating a single \\"utility\\" CLI. This CLI also introduces a new AWS S3 compatible publishing scheme.\\n\\n### What to expect in the near future\\n\\nCore is in pre-release beta and being actively developed for new internal Salesforce CLIs.\\n\\nMuch documentation needs to be written in the coming months including migration paths. Migration onto Core should be as painless as possible with many exports remaining entirely unchanged. Look for forthcoming blog posts and documentation on [oclif.io](https://oclif.io).\\n\\nEarly this summer, tentively June 1, we will release Core v1. Core\'s release will coincide with major bumps to many other oclif plugin packages. See the compatibility matrix below.\\n\\nAt Core\'s v1 release, the current \\"main\\" oclif packages (namely: command, config, errors & parser) will go into maintenance mode until Jan 2022. They will receive _only_ bug and security fixes and they remain compatible with current versions of the oclif and oclif-dev CLIs. Afterwhich, they will be archived.\\n\\nCompanioning Core, the next major release of the oclif CLI (literally `oclif@2`) will generate Core CLIs.\\n\\n### Going forward\\n\\nWe are excited to release Core! We invite you to poke around the [Core repo](https://github.com/oclif/core). It may appear to be a big change but Core keeps what you already enjoy about oclif while reducing development complexity, project dependencies, package coupling and bundle size and introduces many requested features previously too prickly to weave into the current oclif architecture.\\n\\nBest,\\n\\nThe oclif team\\n\\n#### Reference: Compatibility matrix\\n\\n| | oclif \\"v1\\" | oclif \\"Core\\" |\\n| - | - | -|\\n| Utility CLIs | oclif@<2
@oclif/dev-cli@<2 | oclif@>=2\\n| Main packages | @oclif/core@<2
@oclif/config@<2
@oclif/errors@<2
@oclif/parser@<4
@oclif/plugin-help@<4
| @oclif/core@>=1\\n| Node LTS | Node v8-14 | Node v12+ |\\n| TypeScript | typescript@<4 | typescript@>=4 |\\n| Main plugins | @oclif/plugin-autocomplete@<1
@oclif/plugin-commands@<2
@oclif/plugin-help@<4
@oclif/plugin-not-found@<2
@oclif/plugin-plugins@<2
@oclif/plugin-update@<2
plugin-warn-if-update-available@<2
plugin-which@<2
| @oclif/plugin-autocomplete@>=2
@oclif/plugin-commands@>=2
@oclif/plugin-help@>=4
@oclif/plugin-not-found@>=2
@oclif/plugin-plugins@>=2
@oclif/plugin-update@>=2
@oclif/plugin-warn-if-update-available@>=2
@oclif/plugin-which@>=2
|"},{"id":"/2020/08/26/summer-update","metadata":{"permalink":"/blog/2020/08/26/summer-update","source":"@site/blog/2020-08-26-summer-update.md","title":"oclif Summer Update","description":"Hello oclif developers! We hope you are all doing well.","date":"2020-08-26T00:00:00.000Z","formattedDate":"August 26, 2020","tags":[],"readingTime":1.355,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"oclif Summer Update"},"prevItem":{"title":"Introducing @oclif/core","permalink":"/blog/2021/03/01/introducing-oclif-core"},"nextItem":{"title":"Pretty Printable Errors","permalink":"/blog/2020/07/01/pretty-printable-errors"}},"content":"Hello oclif developers! We hope you are all doing well.\\n\\nEarlier this year, we started our planning for oclifconf v2 and, like all conference, had to change course. We opted not to hold a virtual conference, however, we wanted to take some time to highlight a few oclif features shipped this year.\\n\\n## Feature: Help templating\\n\\nOne of the most requested features, help templating enables oclif developers to customize the help output for their CLI.\\n\\nRead [the announcement](/blog/introducing-custom-help-classes).\\n\\n## Feature: Custom error delegation\\n\\nThis feature both improved how oclif throws and handles errors and allows oclif developers to overwrite or interject in oclif\u2019s error handling.\\n\\nRead [the announcement](/blog/2020/07/01/pretty-printable-errors).\\n\\n## Feature: postrun hooks\\n\\nWe have added a new lifecycle event `postrun`. Your CLI can now run a hook after a command has ran.\\n\\nSee our [hook documentation](/docs/hooks).\\n\\n## Feature: Root index command\\n\\nPreviously, oclif would display CLI help if only the binary name with no command ID was invoked, oclif now supports a \\"root index\\" command. If present, a command defined at `src/commands/index.ts` will be run if no command ID is found.\\n\\n## 1 million weekly downloads\\n\\nWhile exact oclif usage metrics are hard to pin down, we use npm download statistics of oclif packages as a rough approximation. Earlier this year, oclif\'s command package hit 1 million weekly downloads for the first time!\\n\\n\\nThis year has been presented its challenges on everyone. We want to thank you, oclif developers, whom have taken the time to use and improve the oclif project. We look forward to seeing you all - in person - in the future!\\n\\nAll our best,\\n\\nThe oclif team"},{"id":"/2020/07/01/pretty-printable-errors","metadata":{"permalink":"/blog/2020/07/01/pretty-printable-errors","source":"@site/blog/2020-07-01-pretty-printable-errors.md","title":"Pretty Printable Errors","description":"Often CLIs are used as handy tools and when things go wrong it\u2019s useful to have additional context. In oclif we have added a couple of additional properties that can show extra context to the users when an error is displayed. The code, ref and suggestions will now be displayed if they are included. This will work with an existing oclif CLI by adding the latest @oclif/errors and @oclif/core to the CLI\'s package.json dependencies.","date":"2020-07-01T00:00:00.000Z","formattedDate":"July 1, 2020","tags":[],"readingTime":0.995,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Pretty Printable Errors"},"prevItem":{"title":"oclif Summer Update","permalink":"/blog/2020/08/26/summer-update"},"nextItem":{"title":"Customizing Help in oclif","permalink":"/blog/2020/05/05/introducing-custom-help-classes"}},"content":"Often CLIs are used as handy tools and when things go wrong it\u2019s useful to have additional context. In oclif we have added a couple of additional properties that can show extra context to the users when an error is displayed. The `code`, `ref` and `suggestions` will now be displayed if they are included. This will work with an existing oclif CLI by adding the latest @oclif/errors and @oclif/core to the CLI\'s package.json dependencies.\\n\\nFor example, using `this.error` with the additional properties:\\n```js\\nclass TestError extends Command {\\n async run() {\\n this.error(\\"An error has occurred!\\", {\\n code: \\"OCLIF_ERR\\",\\n ref: \\"https://oclif.io/docs/commands#thiserrormessage-string--error-options-code-string-exit-number\\",\\n suggestions: [\\"Use these extra properties to provide additional context\\"],\\n })\\n }\\n}\\n```\\n\\nwould result with the following output:\\n```text\\n\u203a Error: An error has occurred!\\n\u203a Code: OCLIF_ERR\\n\u203a Try this: Use these extra properties to provide additional context\\n\u203a Reference: https://oclif.io/docs/commands#thiserrormessage-string--error-options-code-string-exit-number\\n```\\n\\nIf these properties are not provided then nothing changes and the CLI will continue to display the single error message output as it did before. Additionally, as part of this exercise we\u2019ve added documentation around [Error Handling in oclif](/docs/error_handling) which should come in handy if the need arises to extend oclif\u2019s default handling of errors."},{"id":"/2020/05/05/introducing-custom-help-classes","metadata":{"permalink":"/blog/2020/05/05/introducing-custom-help-classes","source":"@site/blog/2020-05-05-introducing-custom-help-classes.md","title":"Customizing Help in oclif","description":"Out of the box oclif provides a great help experience for CLIs.","date":"2020-05-05T00:00:00.000Z","formattedDate":"May 5, 2020","tags":[],"readingTime":1.67,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Customizing Help in oclif"},"prevItem":{"title":"Pretty Printable Errors","permalink":"/blog/2020/07/01/pretty-printable-errors"},"nextItem":{"title":"oclif TSLint to ESLint Migration","permalink":"/blog/2019/12/05/oclif-eslint-migration"}},"content":"Out of the box oclif provides a great help experience for CLIs.\\n\\nBut what if, as an oclif developer, you want to customize some or all of the output?\\n\\nYou can now customize your CLI\'s help output by implementing the `HelpBase` abstract class.\\n\\n## Getting started with custom help\\n\\nIf you have not done so yet, update `@oclif/core`.\\n\\n\\n```\\n$ yarn add --latest @oclif/core\\n```\\n\\nTo get started, first define the filepath to your help class in oclif\'s config in package.json. This is a relative path to the help class, without a file extension.\\n\\nFor this example, the help class will be created in a file at \\"[project root]/src/help.ts\\".\\n\\n```\\n{\\n // ...\\n \\"oclif\\": {\\n \\"helpClass\\": \\"./lib/help\\"\\n // ...\\n }\\n // ...\\n}\\n```\\n\\nFrom here there are two paths, implement the `HelpBase` abstract class yourself or overwrite the parts of the default `Help` class you want to customize (ex: how command usage is displayed). We recommend the latter approach but cover both in the new [Help Classes docs](../../../../docs/help_classes).\\n\\n\\n## Separating TOPICS & COMMANDS in the new deafult `Help` class\\n\\nPreviously, topics and child commands were listed in help output under a single list heading called \\"COMMANDS\\". But we found this can be slightly confusing. Some topics are commands also (a.k.a. topic-commands) while others are simply organizational namespacing (and when ran just show their help).\\n\\nThe new default `Help` class splits the list of children into distinct lists of \\"TOPICS\\" and \\"COMMANDS\\", with the possibility of an item appearing in both if it a topic-command. This makes it clearer what is expected to be ran - \\"COMMANDS\\" - and what is providing structure - \\"TOPICS\\" - when looking at the help output.\\n\\n```\\nVERSION\\n plugin-help-example/0.0.0 darwin-x64 node-v12.12.0\\n\\nUSAGE\\n $ plugin-help-example [COMMAND]\\n\\nTOPICS\\n topic this is a topic and has child topics or commands\\n\\nCOMMANDS\\n hello describe the command here\\n help display help for plugin-help-example\\n```\\n\\nWe look forward to seeing what custom help features you implement in your oclif CLIs with this new feature!"},{"id":"/2019/12/05/oclif-eslint-migration","metadata":{"permalink":"/blog/2019/12/05/oclif-eslint-migration","source":"@site/blog/2019-12-05-oclif-eslint-migration.md","title":"oclif TSLint to ESLint Migration","description":"Back in February of this year, plans were announced to deprecate TSLint in favor of ESLint. TSLint\'s goal has become to work toward a \u201cunified developer experience\u201d by supporting ESLint development going forward.","date":"2019-12-05T00:00:00.000Z","formattedDate":"December 5, 2019","tags":[],"readingTime":2.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"oclif TSLint to ESLint Migration"},"prevItem":{"title":"Customizing Help in oclif","permalink":"/blog/2020/05/05/introducing-custom-help-classes"},"nextItem":{"title":"oclif\'s Current Node Support","permalink":"/blog/2019/10/31/oclif-node-updates"}},"content":"Back in February of this year, plans were announced to [deprecate TSLint](https://github.com/palantir/tslint/issues/4534) in favor of ESLint. TSLint\'s goal has become to work toward a \u201cunified developer experience\u201d by supporting ESLint development going forward.\\n\\n\\n\\n## What has changed in oclif\\n\\nTo keep inline with the community, oclif has transitioned to ESLint for all our core libraries as well as all our official plugins.\\n\\nStarting in v1.15.x, oclif will now optionally generate projects with ESLint for both TypeScript and JavaScript CLI\u2019s.\\n\\nESLint does require Node to be on stable LTS version, at the time of writing, Node 8.10.x, Node 10.13.x & Node 12.x.x.\\n\\n## How does this affect you\\n\\nExisting CLI\u2019s are unchanged, but any newly generated CLI\'s will only give the option of using ESLint. If you are running tslint in your CLI, we recommend you switch to ESLint as well.\\n\\nIn migrating our projects we took the following steps (for an example of these changes see this [pull request](https://github.com/oclif/githubcli/pull/10)).\\n\\n1. Install eslint\\n\\n `$ yarn add eslint eslint-config-oclif eslint-config-oclif-typescript --dev`\\n2. Add eslint related files\\n```shell\\n$ echo \'{\\n \\"extends\\": [\\n \\"oclif\\",\\n \\"oclif-typescript\\"\\n ],\\n \\"rules\\": {\\n }\\n}\' > .eslintrc\\n```\\n3. Remove tslint and related packages\\n\\n `$ yarn remove @oclif/tslint tslint`\\n4. Remove tslint related configuration files\\n\\n `$ rm tslint.json`\\n5. Change lint script in our package.json from something like:\\n\\n `\\"lint\\": \\"tsc -p test --noEmit && tslint -p test -t stylish\\"`\\n \\n to\\n \\n `\\"lint\\": \\"eslint . --ext .ts --config .eslintrc\\"`\\n\\nTo preserve the test compile (tsc -p test --noEmit) we also made the following updates to our scripts:\\n\\n`\\"pretest\\": \\"tsc -p test --noEmit\\"`\\n\\nIn some cases we had our posttest duplicating the same steps as our lint script so it\u2019s cleaner to have it reference the lint job directly with:\\n\\n`\\"posttest\\": \\"yarn lint\\"`\\n\\n\\n6. Run `yarn lint --fix`. This attempts to auto-fix any linting violations automatically. In the case an auto-fix isn\u2019t available it should be fixed manually or ignored (see the [eslint configuration doc](https://eslint.org/docs/user-guide/configuring) for more information) \\n7. Do a search in the codebase for `tslint` and remove any unnecessary tslint disabling comments, like: \\n```javascript\\n/* tslint:disable:object-literal-sort-keys */\\n```\\n\\n\\nIf you are on a version of Node that is not supported by ESLint, you will also need to update your Node engine. ESLint supports Node 8, 10, and 12 so you should upgrade to the most recent Node version compatible with your CLI and also supported by ESLint (see ESLint\'s [Installation and Usage](https://www.npmjs.com/package/eslint#installation-and-usage) instructions).\\n\\n## When will this take effect\\n\\nThese changes have taken effect in oclif v1.15.1. When you generate a new CLI or plugin it will now contain configuration for ESLint instead of TSLint."},{"id":"/2019/10/31/oclif-node-updates","metadata":{"permalink":"/blog/2019/10/31/oclif-node-updates","source":"@site/blog/2019-10-31-oclif-node-updates.md","title":"oclif\'s Current Node Support","description":"To maintain a healthy project trajectory, oclif follows and supports Node Active LTS release, currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining Node 8 and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes.","date":"2019-10-31T00:00:00.000Z","formattedDate":"October 31, 2019","tags":[],"readingTime":2.4,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"oclif\'s Current Node Support"},"prevItem":{"title":"oclif TSLint to ESLint Migration","permalink":"/blog/2019/12/05/oclif-eslint-migration"},"nextItem":{"title":"CLI Flags Explained","permalink":"/blog/2019/02/20/cli-flags-explained"}},"content":"To maintain a healthy project trajectory, oclif follows and supports [Node Active LTS release](https://nodejs.org/en/about/releases/), currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining [Node 8](https://github.com/nodejs/Release#release-schedule) and it is our intent at that time to also follow suit. Let\u2019s take a look at a few ways we will be supporting these changes.\\n\\n## CI Environments\\n\\nCLIs created with the oclif cli going forward will be generated with a CircleCI configuration with Node 10 & 12 and an Appveyor configuration using Node 10. We have also added Node latest to CircleCi to be an early warning detection against coming Node changes (Node latest is managed by CircleCI).\\n\\nWe have already updated every oclif repo\'s CI configs to reflect this.\\n\\nIf your existing CLI uses either Appveyor or CircleCI you can update your config files also, like so:\\n\\n### .circleci/config.yml\\n\\nYour CircleCI config should contain a `node-latest` job, aliased as `test`. From this, there should be two extensions of this job for the Active LTS Node versions, Node 10 and Node 12.\\n\\n```\\n node-10:\\n <<: *node-latest\\n docker:\\n - image: node:10\\n node-12:\\n <<: *node-latest\\n docker:\\n - image: node:12\\n```\\n\\nNotice that these declarations only change the Docker Node images used to run that job.\\n\\nAdditionally, the jobs listed within workflows must also be updated to reflect our changes in configuration:\\n\\n```\\n jobs:\\n - node-latest\\n - node-10\\n - node-12\\n```\\n\\n### appveyor.yml\\n\\nFor appveyor we are currently only testing the oldest Active LTS Node version, Node 10. Update the `nodejs_version` proppert in your appveyor.yml file to reflect this.\\n\\n```\\nenvironment:\\n nodejs_version: \\"10\\"\\n```\\n\\n\\n## Deprecating Node 8 & Updating packge.json engines\\n\\nIn Jan 2020, Node will end its Node 8 maintenance. We will follow suit by setting the package.json engine property in oclif packages to `>=10` and bumping the package\'s major versions.\\n\\nDepending on how you ship your CLI you may wish to also bump the engines version in your CLI\'s package.json. You can read more about the implications of the engines property configuration in the [npm documentation](https://docs.npmjs.com/files/package.json#engines).\\n\\nAlso consider distributing your CLI with [its own Node version](https://oclif.io/docs/releasing#standalone-tarballs).\\n\\n## Packaged Node Version\\n\\nWhen using dev-cli to pack your CLI it will use the Node version as specified in your package.json under the `oclif.update.node.version` property. This value should reflect an Active LTS Node version (dev-cli does not currently enforce versions).\\n\\n## Supporting the future\\n\\nAs a community we may discover bumps along the way as we upgrade. If you notice something related to oclif please feel free to open an issue or submit a pull request under the relevant oclif package within [the org](https://github.com/oclif).\\n\\nWe look forward to using the latest from Node and the community and keeping oclif healthy along the way."},{"id":"/2019/02/20/cli-flags-explained","metadata":{"permalink":"/blog/2019/02/20/cli-flags-explained","source":"@site/blog/2019-02-20-cli-flags-explained.md","title":"CLI Flags Explained","description":"oclif makes it easy to create a command line interface (CLI) in node. Most commands have parameters \u2014 also known as \\"flags\\", \\"args\\", and sometimes \\"options\\". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.","date":"2019-02-20T00:00:00.000Z","formattedDate":"February 20, 2019","tags":[],"readingTime":4.925,"hasTruncateMarker":false,"authors":[{"name":"Casey Watts and Jeff Dickey"}],"frontMatter":{"author":"Casey Watts and Jeff Dickey","title":"CLI Flags Explained"},"prevItem":{"title":"oclif\'s Current Node Support","permalink":"/blog/2019/10/31/oclif-node-updates"},"nextItem":{"title":"Introducing oclif","permalink":"/blog/2018/03/20/introducing-oclif"}},"content":"`oclif` makes it easy to create a command line interface (CLI) in node. Most commands have **parameters** \u2014 also known as \\"flags\\", \\"args\\", and sometimes \\"options\\". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.\\n\\n_Note the following describes GNU-style flags. Not all CLIs follow this convention, but it is the most commonly used._\\n\\n## Parts of Speech\\n\\nAny command line interface command has a few standard \\"parts of speech\\". As a user of CLI tools, knowing these parts of speech can help you make fewer typos. It can also help you understand complex commands other people share with you more quickly. If you are designing a CLI tool it is even more important to understand these parts of speech, so you can come up with the most ergonomic interface for your users.\\n\x3c!-- DIAGRAM OF PARTS OF SPEECH EXAMPLE --\x3e\\n\\nOf the many ways you can pass data to a CLI command, three of them are **parameters** that are always to the \\"right\\" of the command. The three types of parameters are **argument**, **short flag**, and **long flag**.\\n\\n### Example `ls`\\nOne of the most common and simplest unix commands is `ls` which \\"lists\\" the contents of a directory.\\n\\n#### command\\n\\n```\\nls\\n```\\n\\nThis command `ls` works on its own, as a standalone **command**. Without any parameters this command will list the contents of the current folder, using an implied `.` directory.\\n\\n#### argument\\n\\n```\\nls .\\nls ~/code/some-repo-name\\n```\\n\\nIf you pass a command **argument** to this command, like the directory name `.` (current folder) or `~/code/some-repo-name`, it will list the contents of that directory instead.\\n\\nAn argument is anything to the right of a command that is not a flag. An argument can come before or after flags.\\n\\n#### Long flag\\nTo list additional files that are normally hidden (like `~/.bashrc`), you can use a flag on the `ls` command. `ls --all` is the **long flag** form. A long flag always uses a double dash, and it is always represented by multiple characters.\\n\\n```\\nls --all\\nls . --all\\n```\\n\\n#### Short flag\\n\\nThere is also a **short flag** form of this flag: `ls -a`. The `a` is short for `all` in this case. A short flag always uses a single dash, and it is always represented by a single letter.\\n\\n```\\nls -a\\nls . -a\\n```\\n\\nShort flags can **stack** too, so you don\'t need a separate dash for each one. Order does not matter for these, unless passing a flag argument.\\n\\n```\\nls -la\\n```\\n\\n#### Flag arguments\\nMany flags accept an **option**, which is a \\"flag argument\\" (as opposed to a \\"command argument\\"). In general a command\'s parameters can be in any order, but flags that accept options must have the option directly after the flag.\\n\\nFor an example, here the `-x` flag does not accept an option but the `-f` flag does. `archive.tar` is the option being passed to `-f`.\\n\\n```\\ntar -x -f archive.tar\\ntar -xf archive.tar\\n```\\n\\nA flag and its option can be separated by a space ` ` or an equals sign `=`. Interestingly, short flags (but not long flags) can even skip the space, although many people find it much easier to read with the space or equals sign.\\n\\nThese three are all valid and equivalent:\\n\\n```\\ntar -f archive.tar\\ntar -f=archive.tar\\ntar -farchive.tar\\n```\\n\\nLong flags must have a space or equals sign to separate the flag from its option.\\n\\n```\\ngit log --pretty=oneline\\ngit log --pretty oneline\\n```\\n\\n## Other Ways of Passing Data\\n\\nWe\'ve covered **parameters**, which are **arguments**, **short flags** and **long flags**. There are two other ways to pass data to a command: **environment variables** (\\"env vars\\"), or **standard input** (\\"stdin\\"). These won\'t be covered in this blog post.\\n\\n\\n## Designing a Command\\n\\nScenario: we want to design an oclif command that echos an input like \\"Casey\\", and returns \\"hi, Casey!\\". There are many ways the user could pass this in, and here we show an example of each type of input.\\n\\n### argument\\n\\n```\\ngreet-me Casey\\n```\\n\\n### short flag with argument\\n\\n```\\ngreet-me -n Casey\\ngreet-me -n=Casey\\ngreet-me -nCasey\\n```\\n\\n### long flag with argument\\n\\n```\\ngreet-me --name=Casey\\ngreet-me --name Casey\\n```\\n\\n### environment variable\\n\\n```\\nNAME=Casey greet-me\\n```\\n\\n### standard input\\n\\n```\\necho \\"Casey\\" | greet-me\\n```\\n\\n## Command ergonomics\\n\\n### Short flag vs long flag\\nMany CLI commands allow for both long flag and short flag forms. In the Heroku CLI every flag has at least a long flag form and roughly half of the flags also have a short flag form.\\n\\nThe long flag form is easier to read, but takes more characters to type. It is often most useful when you want someone to understand a particular command statement quickly and easily, such as in a README.\\n\\nThe short flag form is quicker to type, and is often better for frequently used commands. Short flags are especially useful when stacking short flags together.\\n\\n\\n\x3c!-- ## Did you mean?\\nIt is really easy to make a typo and use one dash instead of two, or vice versa. This \\"Long flag / short flag mismatch\\" is quite common. We hope that by catching these typos we will help you make fewer typos, save you from frustration, and speed up your development.\\n\\n`oclif` can now detect when you accidentally have the wrong number of dashes for a command, and suggest a change to the command.\\n\\n```\\nheroku config --s\\n> did you mean \\"heroku config -s\\"?\\n```\\n\\n```\\nheroku config -something-long\\n> did you mean \\"heroku config --something-long\\"?\\n```\\n\\n```\\nheroku config ---something-long\\n> did you mean to use FEWER DASHES? (something like this?)\\n```\\n\\nThis is an example of a \\"did you mean?\\" command, like this ruby plugin [did_you_mean](https://github.com/yuki24/did_you_mean).\\n--\x3e"},{"id":"/2018/03/20/introducing-oclif","metadata":{"permalink":"/blog/2018/03/20/introducing-oclif","source":"@site/blog/2018-03-20-introducing-oclif.md","title":"Introducing oclif","description":"Introducing oclif","date":"2018-03-20T00:00:00.000Z","formattedDate":"March 20, 2018","tags":[],"readingTime":0.285,"hasTruncateMarker":false,"authors":[{"name":"Jeff Dickey"}],"frontMatter":{"author":"Jeff Dickey","title":"Introducing oclif"},"prevItem":{"title":"CLI Flags Explained","permalink":"/blog/2019/02/20/cli-flags-explained"}},"content":"![Introducing oclif](/img/2018-03-20-introducing-oclif/header.png)\\n\\nCoding for the browser takes serious time. You need to deal with front-end JS, CSS, design, product, and a ton more. On the other hand, building for a CLI takes a fraction of the effort. This makes CLIs particularly great for prototyping out new functionality, offering admin/internal tools, or power-user functionality.\\n\\nRead More"}]}')}}]); \ No newline at end of file diff --git a/assets/js/b3cc73c6.a31ce7e2.js b/assets/js/b3cc73c6.a31ce7e2.js new file mode 100644 index 00000000..94e62bcc --- /dev/null +++ b/assets/js/b3cc73c6.a31ce7e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9638],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>m});var a=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function n(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,a)}return o}function i(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):i(i({},t),e)),o},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var o=e.components,r=e.mdxType,n=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(o),f=r,m=p["".concat(l,".").concat(f)]||p[f]||d[f]||n;return o?a.createElement(m,i(i({ref:t},u),{},{components:o})):a.createElement(m,i({ref:t},u))}));function m(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var n=o.length,i=new Array(n);i[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{o.r(t),o.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>c,toc:()=>p});var a=o(7462),r=o(3366),n=(o(7294),o(3905)),i=["components"],s={title:"How We Work"},l=void 0,c={unversionedId:"how_we_work",id:"how_we_work",title:"How We Work",description:"oclif is an open-source project built and maintained by Salesforce and an essential component of Salesforce's developer experiences, powering millions of users' CLIs a day via the Salesforce CLI, the Heroku CLI and others.",source:"@site/../docs/how_we_work.md",sourceDirName:".",slug:"/how_we_work",permalink:"/docs/how_we_work",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/how_we_work.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"How We Work"},sidebar:"docs",previous:{title:"Related Repositories",permalink:"/docs/related_repos"},next:{title:"Feedback",permalink:"/docs/feedback"}},u={},p=[{value:"Code of Conduct & Community Guidelines",id:"code-of-conduct--community-guidelines",level:2},{value:"Work Tracking",id:"work-tracking",level:2},{value:"Issues",id:"issues",level:2},{value:"Pull Requests",id:"pull-requests",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Blog Posts",id:"blog-posts",level:2},{value:"Feedback",id:"feedback",level:2},{value:"Updates to How We Work",id:"updates-to-how-we-work",level:2}],d={toc:p},f="wrapper";function m(e){var t=e.components,o=(0,r.Z)(e,i);return(0,n.kt)(f,(0,a.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"oclif is an open-source project built and maintained by Salesforce and an essential component of Salesforce's developer experiences, powering millions of users' CLIs a day via the Salesforce CLI, the Heroku CLI and ",(0,n.kt)("a",{parentName:"p",href:"https://www.npmjs.com/browse/depended/@oclif/core"},"others"),"."),(0,n.kt)("p",null,"As an open-source project, ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/oclif"},"oclif repos live on GitHub")," and are published to ",(0,n.kt)("a",{parentName:"p",href:"https://www.npmjs.com/search?q=oclif"},"npmjs.com"),"."),(0,n.kt)("h2",{id:"code-of-conduct--community-guidelines"},"Code of Conduct & Community Guidelines"),(0,n.kt)("p",null,"We are thrilled to offer oclif as open-source. As such, please review our project ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/salesforce/oss-template/blob/master/CODE_OF_CONDUCT.md"},"Code of Conduct"),". If you have any questions or concerns, please ",(0,n.kt)("a",{parentName:"p",href:"/docs/feedback"},"contact us"),"."),(0,n.kt)("h2",{id:"work-tracking"},"Work Tracking"),(0,n.kt)("p",null,"We use a ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/orgs/oclif/projects/1"},"GitHub Project board")," to manage our work across all oclif repos. This board is used kanban style, in which, cards (i.e. work items) move left to right as they progress towards \u201cDone\u201d and higher priority cards sit towards the top of the columns, with lower priority cards sitting further below."),(0,n.kt)("h2",{id:"issues"},"Issues"),(0,n.kt)("p",null,"Issues are made in their corresponding repo as appropriate. If you are unsure which repo an issue might belong to, make an ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif/issues"},"issue in the oclif repo"),"."),(0,n.kt)("p",null,"We triage issues as we can, usually with a week of when it was created (unfortunately, we can make no commitment to when an issue will be triaged)."),(0,n.kt)("p",null,"Issues triaged by an our team will be marked with one of the following labels :"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u201cbug\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cenhancement\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cdocs\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cwont-fix\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cinvalid\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cduplicate\u201d")),(0,n.kt)("p",null,"An issue will be considered stale after a month has passed with no further feedback or input from the author after input from an oclif team member. Stale issues will be notified with a comment of its stale state and any actions needed to take to keep it alive."),(0,n.kt)("p",null,"An issue will be closed if:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"It has been fixed via a PR"),(0,n.kt)("li",{parentName:"ul"},"Has a \u201cwont-fix\u201d, \u201cinvalid\u201d or \u201cduplicate\u201d label"),(0,n.kt)("li",{parentName:"ul"},"A week has passed after a stale issue notification has been posted with no further feedback or input from the author")),(0,n.kt)("h2",{id:"pull-requests"},"Pull Requests"),(0,n.kt)("p",null,"We review repo PRs as we can, usually with two weeks of when it was created (unfortunately, we can make no commitment to when a PR will be reviewed)."),(0,n.kt)("p",null,"PRs reviewers may seek additional changes or clarifying input from the author as appropriate."),(0,n.kt)("p",null,"Note: It is often more conducive to first open an issue and solicit feedback on possible solutions for your PR. We hate to see PR\u2019s we don\u2019t end up accepting and this helps to avoid that!"),(0,n.kt)("p",null,"A PR will be considered stale after a month has passed with no further feedback or input from the author after input from an oclif team member. Stale PRs will be notified with a comment of its stale state and any actions needed to take to keep it alive."),(0,n.kt)("p",null,"A PR will be closed if:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"It has been merged"),(0,n.kt)("li",{parentName:"ul"},"After a dialogue with the author informing them why the PR cannot be accepted"),(0,n.kt)("li",{parentName:"ul"},"A week has passed after a stale PR notification has been posted with no further feedback or input from the author")),(0,n.kt)("h2",{id:"deprecations"},"Deprecations"),(0,n.kt)("p",null,"oclif packages follow semantic versioning and therefore only deprecate features in new major version releases."),(0,n.kt)("p",null,"In the exceptional case a deprecation needs to happen outside a new major version, we will notify users via our blog or, as appropriate, with deprecation warnings in the tooling itself."),(0,n.kt)("h2",{id:"blog-posts"},"Blog Posts"),(0,n.kt)("p",null,"We aim to announce most features via ",(0,n.kt)("a",{parentName:"p",href:"/blog"},"our blog"),". Be sure to check back regularly to see new announcements!"),(0,n.kt)("h2",{id:"feedback"},"Feedback"),(0,n.kt)("p",null,"See our ",(0,n.kt)("a",{parentName:"p",href:"/docs/feedback"},"Feedback page"),"."),(0,n.kt)("h2",{id:"updates-to-how-we-work"},"Updates to How We Work"),(0,n.kt)("p",null,"Please check back periodically to review any updates to this page."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b3cc73c6.b28e6c13.js b/assets/js/b3cc73c6.b28e6c13.js deleted file mode 100644 index 2b1fa9b9..00000000 --- a/assets/js/b3cc73c6.b28e6c13.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9638],{3905:(e,t,o)=>{o.d(t,{Zo:()=>u,kt:()=>h});var a=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function n(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,a)}return o}function i(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var l=a.createContext({}),c=function(e){var t=a.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):i(i({},t),e)),o},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var o=e.components,r=e.mdxType,n=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(o),f=r,h=p["".concat(l,".").concat(f)]||p[f]||d[f]||n;return o?a.createElement(h,i(i({ref:t},u),{},{components:o})):a.createElement(h,i({ref:t},u))}));function h(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var n=o.length,i=new Array(n);i[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{o.r(t),o.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>p});var a=o(7462),r=o(3366),n=(o(7294),o(3905)),i=["components"],s={title:"How We Work"},l=void 0,c={unversionedId:"how_we_work",id:"how_we_work",title:"How We Work",description:"oclif is an open-source project built and maintained by Salesforce and an essential component of Salesforce's developer experiences, powering millions of users' CLIs a day via the Salesforce CLI, the Heroku CLI and others.",source:"@site/../docs/how_we_work.md",sourceDirName:".",slug:"/how_we_work",permalink:"/docs/how_we_work",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/how_we_work.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"How We Work"},sidebar:"docs",previous:{title:"Related Repositories",permalink:"/docs/related_repos"},next:{title:"Feedback",permalink:"/docs/feedback"}},u={},p=[{value:"Code of Conduct & Community Guidelines",id:"code-of-conduct--community-guidelines",level:2},{value:"Work Tracking",id:"work-tracking",level:2},{value:"Issues",id:"issues",level:2},{value:"Pull Requests",id:"pull-requests",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Blog Posts",id:"blog-posts",level:2},{value:"Feedback",id:"feedback",level:2},{value:"Updates to How We Work",id:"updates-to-how-we-work",level:2}],d={toc:p},f="wrapper";function h(e){var t=e.components,o=(0,r.Z)(e,i);return(0,n.kt)(f,(0,a.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"oclif is an open-source project built and maintained by Salesforce and an essential component of Salesforce's developer experiences, powering millions of users' CLIs a day via the Salesforce CLI, the Heroku CLI and ",(0,n.kt)("a",{parentName:"p",href:"https://www.npmjs.com/browse/depended/@oclif/core"},"others"),"."),(0,n.kt)("p",null,"As an open-source project, ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/oclif"},"oclif repos live on GitHub")," and are published to ",(0,n.kt)("a",{parentName:"p",href:"https://www.npmjs.com/search?q=oclif"},"npmjs.com"),"."),(0,n.kt)("h2",{id:"code-of-conduct--community-guidelines"},"Code of Conduct & Community Guidelines"),(0,n.kt)("p",null,"We are thrilled to offer oclif as open-source. As such, please review our project ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/salesforce/oss-template/blob/master/CODE_OF_CONDUCT.md"},"Code of Conduct"),". If you have any questions or concerns, please ",(0,n.kt)("a",{parentName:"p",href:"/docs/feedback"},"contact us"),"."),(0,n.kt)("h2",{id:"work-tracking"},"Work Tracking"),(0,n.kt)("p",null,"We use a ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/orgs/oclif/projects/1"},"GitHub Project board")," to manage our work across all oclif repos. This board is used kanban style, in which, cards (i.e. work items) move left to right as they progress towards \u201cDone\u201d and higher priority cards sit towards the top of the columns, with lower priority cards sitting further below."),(0,n.kt)("h2",{id:"issues"},"Issues"),(0,n.kt)("p",null,"Issues are made in their corresponding repo as appropriate. If you are unsure which repo an issue might belong to, make an ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif/issues"},"issue in the oclif repo"),"."),(0,n.kt)("p",null,"We triage issues as we can, usually with a week of when it was created (unfortunately, we can make no commitment to when an issue will be triaged)."),(0,n.kt)("p",null,"Issues triaged by an our team will be marked with one of the following labels :"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u201cbug\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cenhancement\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cdocs\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cwont-fix\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cinvalid\u201d"),(0,n.kt)("li",{parentName:"ul"},"\u201cduplicate\u201d")),(0,n.kt)("p",null,"An issue will be considered stale after a month has passed with no further feedback or input from the author after input from an oclif team member. Stale issues will be notified with a comment of its stale state and any actions needed to take to keep it alive."),(0,n.kt)("p",null,"An issue will be closed if:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"It has been fixed via a PR"),(0,n.kt)("li",{parentName:"ul"},"Has a \u201cwont-fix\u201d, \u201cinvalid\u201d or \u201cduplicate\u201d label"),(0,n.kt)("li",{parentName:"ul"},"A week has passed after a stale issue notification has been posted with no further feedback or input from the author")),(0,n.kt)("h2",{id:"pull-requests"},"Pull Requests"),(0,n.kt)("p",null,"We review repo PRs as we can, usually with two weeks of when it was created (unfortunately, we can make no commitment to when a PR will be reviewed)."),(0,n.kt)("p",null,"PRs reviewers may seek additional changes or clarifying input from the author as appropriate."),(0,n.kt)("p",null,"Note: It is often more conducive to first open an issue and solicit feedback on possible solutions for your PR. We hate to see PR\u2019s we don\u2019t end up accepting and this helps to avoid that!"),(0,n.kt)("p",null,"A PR will be considered stale after a month has passed with no further feedback or input from the author after input from an oclif team member. Stale PRs will be notified with a comment of its stale state and any actions needed to take to keep it alive."),(0,n.kt)("p",null,"A PR will be closed if:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"It has been merged"),(0,n.kt)("li",{parentName:"ul"},"After a dialogue with the author informing them why the PR cannot be accepted"),(0,n.kt)("li",{parentName:"ul"},"A week has passed after a stale PR notification has been posted with no further feedback or input from the author")),(0,n.kt)("h2",{id:"deprecations"},"Deprecations"),(0,n.kt)("p",null,"oclif packages follow semantic versioning and therefore only deprecate features in new major version releases."),(0,n.kt)("p",null,"In the exceptional case a deprecation needs to happen outside a new major version, we will notify users via our blog or, as appropriate, with deprecation warnings in the tooling itself."),(0,n.kt)("h2",{id:"blog-posts"},"Blog Posts"),(0,n.kt)("p",null,"We aim to announce most features via ",(0,n.kt)("a",{parentName:"p",href:"/blog"},"our blog"),". Be sure to check back regularly to see new announcements!"),(0,n.kt)("h2",{id:"feedback"},"Feedback"),(0,n.kt)("p",null,"See our ",(0,n.kt)("a",{parentName:"p",href:"/docs/feedback"},"Feedback page"),"."),(0,n.kt)("h2",{id:"updates-to-how-we-work"},"Updates to How We Work"),(0,n.kt)("p",null,"Please check back periodically to review any updates to this page."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b4a95747.95a0f3d3.js b/assets/js/b4a95747.87a7f695.js similarity index 58% rename from assets/js/b4a95747.95a0f3d3.js rename to assets/js/b4a95747.87a7f695.js index 63106b8f..e640f6c6 100644 --- a/assets/js/b4a95747.95a0f3d3.js +++ b/assets/js/b4a95747.87a7f695.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5289],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=r.createContext({}),p=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(i.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),d=o,f=u["".concat(i,".").concat(d)]||u[d]||m[d]||a;return n?r.createElement(f,l(l({ref:t},c),{},{components:n})):r.createElement(f,l({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,l=new Array(a);l[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:o,l[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>s,metadata:()=>p,toc:()=>u});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),l=["components"],s={title:"JSON"},i=void 0,p={unversionedId:"json",id:"json",title:"JSON",description:"If you want to use the --json flag to return JSON output to the user, then you can set the enableJsonFlag property on the Command class.",source:"@site/../docs/json.md",sourceDirName:".",slug:"/json",permalink:"/docs/json",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/json.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"JSON"},sidebar:"docs",previous:{title:"Error Handling",permalink:"/docs/error_handling"},next:{title:"Release",permalink:"/docs/releasing"}},c={},u=[],m={toc:u},d="wrapper";function f(e){var t=e.components,n=(0,o.Z)(e,l);return(0,a.kt)(d,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"If you want to use the ",(0,a.kt)("inlineCode",{parentName:"p"},"--json")," flag to return JSON output to the user, then you can set the ",(0,a.kt)("inlineCode",{parentName:"p"},"enableJsonFlag")," property on the ",(0,a.kt)("inlineCode",{parentName:"p"},"Command")," class."),(0,a.kt)("p",null,"When this property is set and the user supplies the ",(0,a.kt)("inlineCode",{parentName:"p"},"--json")," flag, the command will suppress all logs and instead log the return value to the console in JSON format. ",(0,a.kt)("strong",{parentName:"p"},"Note")," log suppression will only work if you use the logging methods on the ",(0,a.kt)("inlineCode",{parentName:"p"},"Command")," class instance. In other words, ",(0,a.kt)("inlineCode",{parentName:"p"},"this.log")," will be automatically suppressed but ",(0,a.kt)("inlineCode",{parentName:"p"},"console.log")," will not be."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command} from '@oclif/core'\nexport class HelloCommand extends Command {\n public static enableJsonFlag = true\n public async run(): Promise<{ message: string }> {\n console.log('hello, world!')\n return { message: 'hello, world!' }\n }\n}\n\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"$ my-cli hello\nhello, world!\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'$ my-cli hello --json\n{\n "message": "hello, world!"\n}\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5289],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var i=r.createContext({}),p=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(i.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),d=o,f=u["".concat(i,".").concat(d)]||u[d]||m[d]||a;return n?r.createElement(f,l(l({ref:t},c),{},{components:n})):r.createElement(f,l({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,l=new Array(a);l[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:o,l[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>s,metadata:()=>p,toc:()=>u});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),l=["components"],s={title:"JSON"},i=void 0,p={unversionedId:"json",id:"json",title:"JSON",description:"If you want to use the --json flag to return JSON output to the user, then you can set the enableJsonFlag property on the Command class.",source:"@site/../docs/json.md",sourceDirName:".",slug:"/json",permalink:"/docs/json",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/json.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"JSON"},sidebar:"docs",previous:{title:"Error Handling",permalink:"/docs/error_handling"},next:{title:"Release",permalink:"/docs/releasing"}},c={},u=[],m={toc:u},d="wrapper";function f(e){var t=e.components,n=(0,o.Z)(e,l);return(0,a.kt)(d,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"If you want to use the ",(0,a.kt)("inlineCode",{parentName:"p"},"--json")," flag to return JSON output to the user, then you can set the ",(0,a.kt)("inlineCode",{parentName:"p"},"enableJsonFlag")," property on the ",(0,a.kt)("inlineCode",{parentName:"p"},"Command")," class."),(0,a.kt)("p",null,"When this property is set and the user supplies the ",(0,a.kt)("inlineCode",{parentName:"p"},"--json")," flag, the command will suppress all logs and instead log the return value to the console in JSON format. ",(0,a.kt)("strong",{parentName:"p"},"Note")," log suppression will only work if you use the logging methods on the ",(0,a.kt)("inlineCode",{parentName:"p"},"Command")," class instance. In other words, ",(0,a.kt)("inlineCode",{parentName:"p"},"this.log")," will be automatically suppressed but ",(0,a.kt)("inlineCode",{parentName:"p"},"console.log")," will not be."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command} from '@oclif/core'\nexport class HelloCommand extends Command {\n public static enableJsonFlag = true\n public async run(): Promise<{ message: string }> {\n console.log('hello, world!')\n return { message: 'hello, world!' }\n }\n}\n\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"$ my-cli hello\nhello, world!\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'$ my-cli hello --json\n{\n "message": "hello, world!"\n}\n')))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c1f37a13.7c34a1e9.js b/assets/js/c1f37a13.7c34a1e9.js deleted file mode 100644 index 741c8461..00000000 --- a/assets/js/c1f37a13.7c34a1e9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9727],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(n),f=a,d=m["".concat(l,".").concat(f)]||m[f]||u[f]||o;return n?r.createElement(d,s(s({ref:t},p),{},{components:n})):r.createElement(d,s({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=f;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[m]="string"==typeof e?e:a,s[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>m});var r=n(7462),a=n(3366),o=(n(7294),n(3905)),s=["components"],i={title:"ES2022"},l=void 0,c={unversionedId:"ES2022",id:"ES2022",title:"ES2022",description:"If your tsconfig.json targets ES2022 or newer there are some changes you will need to make to your commands to ensure that flags are properly set. See this comment on github for more context on why these changes are necessary.",source:"@site/../docs/ES2022.md",sourceDirName:".",slug:"/ES2022",permalink:"/docs/ES2022",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/ES2022.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"ES2022"},sidebar:"docs",previous:{title:"ESM",permalink:"/docs/esm"},next:{title:"Examples",permalink:"/docs/examples"}},p={},m=[{value:"Use static initialization blocks",id:"use-static-initialization-blocks",level:2}],u={toc:m},f="wrapper";function d(e){var t=e.components,n=(0,a.Z)(e,s);return(0,o.kt)(f,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"If your tsconfig.json targets ",(0,o.kt)("inlineCode",{parentName:"p"},"ES2022")," or newer there are some changes you will need to make to your commands to ensure that flags are properly set. See ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif/issues/1100#issuecomment-1454910926"},"this comment")," on github for more context on why these changes are necessary."),(0,o.kt)("h2",{id:"use-static-initialization-blocks"},"Use static initialization blocks"),(0,o.kt)("p",null,"All static properties on ",(0,o.kt)("inlineCode",{parentName:"p"},"Command")," classes need to be set inside of a ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Static_initialization_blocks"},"static initialization block"),"."),(0,o.kt)("p",null,"For instance your command may look something like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\n\nexport default class Hello extends Command {\n static summary = 'Say hello!'\n static aliases = ['howdy']\n static enableJsonFlag = true\n static flags = {\n name: Flags.string({\n summary: 'person to say hello to',\n required: true,\n char: 'n',\n })\n }\n\n public async run(): Promise<{name: string}> {\n const {flags} = await this.parse(Hello)\n this.log(`hello ${flags.name}`)\n return {\n name: flags.name\n }\n }\n}\n")),(0,o.kt)("p",null,"To target ES2022 you'll need to update the command to look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\n\nexport default class Hello extends Command {\n static summary\n static aliases\n static enableJsonFlag\n // It's very important to declare the static flags prop here.\n // Otherwise, you'll loose all type safety on flags.\n static flags\n\n static {\n this.summary = 'Say hello!'\n this.aliases = ['howdy']\n this.enableJsonFlag = true\n this.flags = {\n name: Flags.string({\n summary: 'person to say hello to',\n required: true,\n char: 'n',\n }),\n }\n }\n\n public async run(): Promise<{name: string}> {\n const {flags} = await this.parse(Hello)\n this.log(`hello ${flags.name}`)\n return {\n name: flags.name\n }\n }\n}\n\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c1f37a13.b3d16bdd.js b/assets/js/c1f37a13.b3d16bdd.js new file mode 100644 index 00000000..12df25a0 --- /dev/null +++ b/assets/js/c1f37a13.b3d16bdd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9727],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(n),f=a,d=m["".concat(l,".").concat(f)]||m[f]||u[f]||o;return n?r.createElement(d,s(s({ref:t},p),{},{components:n})):r.createElement(d,s({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,s=new Array(o);s[0]=f;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[m]="string"==typeof e?e:a,s[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>m});var r=n(7462),a=n(3366),o=(n(7294),n(3905)),s=["components"],i={title:"ES2022"},l=void 0,c={unversionedId:"ES2022",id:"ES2022",title:"ES2022",description:"If your tsconfig.json targets ES2022 or newer there are some changes you will need to make to your commands to ensure that flags are properly set. See this comment on github for more context on why these changes are necessary.",source:"@site/../docs/ES2022.md",sourceDirName:".",slug:"/ES2022",permalink:"/docs/ES2022",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/ES2022.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"ES2022"},sidebar:"docs",previous:{title:"ESM",permalink:"/docs/esm"},next:{title:"Examples",permalink:"/docs/examples"}},p={},m=[{value:"Use static initialization blocks",id:"use-static-initialization-blocks",level:2}],u={toc:m},f="wrapper";function d(e){var t=e.components,n=(0,a.Z)(e,s);return(0,o.kt)(f,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"If your tsconfig.json targets ",(0,o.kt)("inlineCode",{parentName:"p"},"ES2022")," or newer there are some changes you will need to make to your commands to ensure that flags are properly set. See ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif/issues/1100#issuecomment-1454910926"},"this comment")," on github for more context on why these changes are necessary."),(0,o.kt)("h2",{id:"use-static-initialization-blocks"},"Use static initialization blocks"),(0,o.kt)("p",null,"All static properties on ",(0,o.kt)("inlineCode",{parentName:"p"},"Command")," classes need to be set inside of a ",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Static_initialization_blocks"},"static initialization block"),"."),(0,o.kt)("p",null,"For instance your command may look something like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\n\nexport default class Hello extends Command {\n static summary = 'Say hello!'\n static aliases = ['howdy']\n static enableJsonFlag = true\n static flags = {\n name: Flags.string({\n summary: 'person to say hello to',\n required: true,\n char: 'n',\n })\n }\n\n public async run(): Promise<{name: string}> {\n const {flags} = await this.parse(Hello)\n this.log(`hello ${flags.name}`)\n return {\n name: flags.name\n }\n }\n}\n")),(0,o.kt)("p",null,"To target ES2022 you'll need to update the command to look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Command, Flags} from '@oclif/core'\n\nexport default class Hello extends Command {\n static summary\n static aliases\n static enableJsonFlag\n // It's very important to declare the static flags prop here.\n // Otherwise, you'll loose all type safety on flags.\n static flags\n\n static {\n this.summary = 'Say hello!'\n this.aliases = ['howdy']\n this.enableJsonFlag = true\n this.flags = {\n name: Flags.string({\n summary: 'person to say hello to',\n required: true,\n char: 'n',\n }),\n }\n }\n\n public async run(): Promise<{name: string}> {\n const {flags} = await this.parse(Hello)\n this.log(`hello ${flags.name}`)\n return {\n name: flags.name\n }\n }\n}\n\n")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c81fd975.20af81da.js b/assets/js/c81fd975.20af81da.js deleted file mode 100644 index 7200b614..00000000 --- a/assets/js/c81fd975.20af81da.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9310],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,h=u["".concat(c,".").concat(m)]||u[m]||d[m]||r;return n?o.createElement(h,i(i({ref:t},p),{},{components:n})):o.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>l,toc:()=>u});var o=n(7462),a=n(3366),r=(n(7294),n(3905)),i=["components"],s={title:"Testing"},c=void 0,l={unversionedId:"testing",id:"testing",title:"Testing",description:"Testing in oclif can be done with any testing framework. You can run commands with MyCommand.run() which returns a promise you can wait on.",source:"@site/../docs/testing.md",sourceDirName:".",slug:"/testing",permalink:"/docs/testing",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/testing.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Testing"},sidebar:"docs",previous:{title:"Release",permalink:"/docs/releasing"},next:{title:"Running Commands Programmatically",permalink:"/docs/running_programmatically"}},p={},u=[{value:"stdout/stderr",id:"stdoutstderr",level:2},{value:"Code Coverage",id:"code-coverage",level:2}],d={toc:u},m="wrapper";function h(e){var t=e.components,n=(0,a.Z)(e,i);return(0,r.kt)(m,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Testing in oclif can be done with any testing framework. You can run commands with ",(0,r.kt)("inlineCode",{parentName:"p"},"MyCommand.run()")," which returns a promise you can wait on."),(0,r.kt)("p",null,"There are common tasks however when writing CLI tools. For this, we have a conventional set of tools that we suggest using to test your CLI. These are based on ",(0,r.kt)("a",{parentName:"p",href:"https://mochajs.org"},"mocha")," and ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/jdxcode/fancy-test"},"fancy-test"),"."),(0,r.kt)("p",null,"Mocha is the top JavaScript testing framework and a solid choice for any project. fancy-test is a tool we developed that builds on top of mocha to make it easy to repeat patterns and write concise mocha tests. There is also a library ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/test"},"@oclif/test")," that extends fancy-test with helpers specific to testing oclif CLIs. These are things like running a command or hook or checking if an exit status code is set, for example."),(0,r.kt)("p",null,"Any CLI built with oclif will come preloaded with these tools and an example test that should work out of the box with ",(0,r.kt)("inlineCode",{parentName:"p"},"npm test")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"yarn test"),"."),(0,r.kt)("p",null,"As an example, let's look at the ",(0,r.kt)("inlineCode",{parentName:"p"},"heroku whoami")," command which makes an API call to get the current logged in user. If the user is not logged in, it exits with status 100. (This is a simplified example, here is ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/heroku/heroku-cli-plugin-auth"},"the actual code"),".)"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"src/commands/whoami.ts")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"import Command from '@heroku-cli/command'\n\nexport class Whoami extends Command {\n async run() {\n try {\n let {body: account} = await this.heroku.get('/account')\n this.log(account.email)\n } catch (err) {\n if (err.statusCode === 401) {\n this.error('not logged in', {exit: 100})\n }\n throw err\n }\n }\n}\n")),(0,r.kt)("p",null,"Another common tool we like to use in testing oclif CLIs is ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/node-nock/nock"},"nock"),". Install the ",(0,r.kt)("inlineCode",{parentName:"p"},"nock")," package as a devDependency."),(0,r.kt)("p",null,"Here is the test code"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"test/commands/whoami.test.ts")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import {expect, test} from '@oclif/test'\n\ndescribe('auth:whoami', () => {\n test\n .nock('https://api.heroku.com', api => api\n .get('/account')\n // user is logged in, return their name\n .reply(200, {email: 'jeff@example.com'})\n )\n .stdout()\n .command(['auth:whoami'])\n .it('shows user email when logged in', ctx => {\n expect(ctx.stdout).to.equal('jeff@example.com\\n')\n })\n\n test\n .nock('https://api.heroku.com', api => api\n .get('/account')\n // HTTP 401 means the user is not logged in with valid credentials\n .reply(401)\n )\n .command(['auth:whoami'])\n // checks to ensure the command exits with status 100\n .exit(100)\n .it('exits with status 100 when not logged in')\n})\n")),(0,r.kt)("p",null,"These tools are setup to not only mock out the stdout/stderr and HTTP calls, but they're setup to ensure they automatically reset after the test. A common issue we've had when building CLIs with simpler ",(0,r.kt)("inlineCode",{parentName:"p"},"beforeEach/afterEach")," filters is that if the ",(0,r.kt)("inlineCode",{parentName:"p"},"afterEach")," filters aren't setup correctly, a failing test can leave mocks around that make later tests fail. Using fancy-test, we avoid this problem and only have to declare our mocks once."),(0,r.kt)("p",null,"For more on how to test with oclif, check out the docs for ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/jdxcode/fancy-test"},"fancy-test")," and ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/test"},"@oclif/test"),"."),(0,r.kt)("h2",{id:"stdoutstderr"},"stdout/stderr"),(0,r.kt)("p",null,"The stdout/stderr mocks use ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/jdxcode/stdout-stderr"},"stdout-stderr")," under the hood. This library can be used standalone if you'd prefer to use jest or want a different testing setup but still have the ability to mock out stdout and stderr."),(0,r.kt)("p",null,"If you want to see the output but leave it mocked, you can either pass in ",(0,r.kt)("inlineCode",{parentName:"p"},"{print: true}")," to the options, or set ",(0,r.kt)("inlineCode",{parentName:"p"},"TEST_OUTPUT=1"),"."),(0,r.kt)("h2",{id:"code-coverage"},"Code Coverage"),(0,r.kt)("p",null,"Code coverage is provided automatically for JavaScript and TypeScript projects via ",(0,r.kt)("a",{parentName:"p",href:"https://npm.im/nyc"},"nyc"),". Just run ",(0,r.kt)("inlineCode",{parentName:"p"},"yarn test")," and it will show the code coverage. The coverage can optionally be sent to ",(0,r.kt)("a",{parentName:"p",href:"https://codecov.io"},"codecov")," in the CI scripts as well."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c81fd975.b3472bb0.js b/assets/js/c81fd975.b3472bb0.js new file mode 100644 index 00000000..2913a7f0 --- /dev/null +++ b/assets/js/c81fd975.b3472bb0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9310],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=o.createContext({}),l=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,h=u["".concat(c,".").concat(m)]||u[m]||d[m]||r;return n?o.createElement(h,i(i({ref:t},p),{},{components:n})):o.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>l,toc:()=>u});var o=n(7462),a=n(3366),r=(n(7294),n(3905)),i=["components"],s={title:"Testing"},c=void 0,l={unversionedId:"testing",id:"testing",title:"Testing",description:"Testing in oclif can be done with any testing framework. You can run commands with MyCommand.run() which returns a promise you can wait on.",source:"@site/../docs/testing.md",sourceDirName:".",slug:"/testing",permalink:"/docs/testing",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/testing.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Testing"},sidebar:"docs",previous:{title:"Release",permalink:"/docs/releasing"},next:{title:"Running Commands Programmatically",permalink:"/docs/running_programmatically"}},p={},u=[{value:"stdout/stderr",id:"stdoutstderr",level:2},{value:"Code Coverage",id:"code-coverage",level:2}],d={toc:u},m="wrapper";function h(e){var t=e.components,n=(0,a.Z)(e,i);return(0,r.kt)(m,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Testing in oclif can be done with any testing framework. You can run commands with ",(0,r.kt)("inlineCode",{parentName:"p"},"MyCommand.run()")," which returns a promise you can wait on."),(0,r.kt)("p",null,"There are common tasks however when writing CLI tools. For this, we have a conventional set of tools that we suggest using to test your CLI. These are based on ",(0,r.kt)("a",{parentName:"p",href:"https://mochajs.org"},"mocha")," and ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/jdxcode/fancy-test"},"fancy-test"),"."),(0,r.kt)("p",null,"Mocha is the top JavaScript testing framework and a solid choice for any project. fancy-test is a tool we developed that builds on top of mocha to make it easy to repeat patterns and write concise mocha tests. There is also a library ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/test"},"@oclif/test")," that extends fancy-test with helpers specific to testing oclif CLIs. These are things like running a command or hook or checking if an exit status code is set, for example."),(0,r.kt)("p",null,"Any CLI built with oclif will come preloaded with these tools and an example test that should work out of the box with ",(0,r.kt)("inlineCode",{parentName:"p"},"npm test")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"yarn test"),"."),(0,r.kt)("p",null,"As an example, let's look at the ",(0,r.kt)("inlineCode",{parentName:"p"},"heroku whoami")," command which makes an API call to get the current logged in user. If the user is not logged in, it exits with status 100. (This is a simplified example, here is ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/heroku/heroku-cli-plugin-auth"},"the actual code"),".)"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"src/commands/whoami.ts")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"import Command from '@heroku-cli/command'\n\nexport class Whoami extends Command {\n async run() {\n try {\n let {body: account} = await this.heroku.get('/account')\n this.log(account.email)\n } catch (err) {\n if (err.statusCode === 401) {\n this.error('not logged in', {exit: 100})\n }\n throw err\n }\n }\n}\n")),(0,r.kt)("p",null,"Another common tool we like to use in testing oclif CLIs is ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/node-nock/nock"},"nock"),". Install the ",(0,r.kt)("inlineCode",{parentName:"p"},"nock")," package as a devDependency."),(0,r.kt)("p",null,"Here is the test code"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"test/commands/whoami.test.ts")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-typescript"},"import {expect, test} from '@oclif/test'\n\ndescribe('auth:whoami', () => {\n test\n .nock('https://api.heroku.com', api => api\n .get('/account')\n // user is logged in, return their name\n .reply(200, {email: 'jeff@example.com'})\n )\n .stdout()\n .command(['auth:whoami'])\n .it('shows user email when logged in', ctx => {\n expect(ctx.stdout).to.equal('jeff@example.com\\n')\n })\n\n test\n .nock('https://api.heroku.com', api => api\n .get('/account')\n // HTTP 401 means the user is not logged in with valid credentials\n .reply(401)\n )\n .command(['auth:whoami'])\n // checks to ensure the command exits with status 100\n .exit(100)\n .it('exits with status 100 when not logged in')\n})\n")),(0,r.kt)("p",null,"These tools are setup to not only mock out the stdout/stderr and HTTP calls, but they're setup to ensure they automatically reset after the test. A common issue we've had when building CLIs with simpler ",(0,r.kt)("inlineCode",{parentName:"p"},"beforeEach/afterEach")," filters is that if the ",(0,r.kt)("inlineCode",{parentName:"p"},"afterEach")," filters aren't setup correctly, a failing test can leave mocks around that make later tests fail. Using fancy-test, we avoid this problem and only have to declare our mocks once."),(0,r.kt)("p",null,"For more on how to test with oclif, check out the docs for ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/jdxcode/fancy-test"},"fancy-test")," and ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/oclif/test"},"@oclif/test"),"."),(0,r.kt)("h2",{id:"stdoutstderr"},"stdout/stderr"),(0,r.kt)("p",null,"The stdout/stderr mocks use ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/jdxcode/stdout-stderr"},"stdout-stderr")," under the hood. This library can be used standalone if you'd prefer to use jest or want a different testing setup but still have the ability to mock out stdout and stderr."),(0,r.kt)("p",null,"If you want to see the output but leave it mocked, you can either pass in ",(0,r.kt)("inlineCode",{parentName:"p"},"{print: true}")," to the options, or set ",(0,r.kt)("inlineCode",{parentName:"p"},"TEST_OUTPUT=1"),"."),(0,r.kt)("h2",{id:"code-coverage"},"Code Coverage"),(0,r.kt)("p",null,"Code coverage is provided automatically for JavaScript and TypeScript projects via ",(0,r.kt)("a",{parentName:"p",href:"https://npm.im/nyc"},"nyc"),". Just run ",(0,r.kt)("inlineCode",{parentName:"p"},"yarn test")," and it will show the code coverage. The coverage can optionally be sent to ",(0,r.kt)("a",{parentName:"p",href:"https://codecov.io"},"codecov")," in the CI scripts as well."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c94a68c1.1ef5830a.js b/assets/js/c94a68c1.9f55f2b4.js similarity index 51% rename from assets/js/c94a68c1.1ef5830a.js rename to assets/js/c94a68c1.9f55f2b4.js index ff8f9c81..6e9305d8 100644 --- a/assets/js/c94a68c1.1ef5830a.js +++ b/assets/js/c94a68c1.9f55f2b4.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9147],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(r),d=a,g=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(g,i(i({ref:t},p),{},{components:r})):n.createElement(g,i({ref:t},p))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>g,frontMatter:()=>s,metadata:()=>c,toc:()=>u});var n=r(7462),a=r(3366),o=(r(7294),r(3905)),i=["components"],s={title:"Command Arguments"},l=void 0,c={unversionedId:"args",id:"args",title:"Command Arguments",description:"Arguments are positional arguments passed to the command. For example, if this command was run with mycli arg1 arg2 it would be declared like this:",source:"@site/../docs/args.md",sourceDirName:".",slug:"/args",permalink:"/docs/args",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/args.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Command Arguments"},sidebar:"docs",previous:{title:"Commands",permalink:"/docs/commands"},next:{title:"Command Flags",permalink:"/docs/flags"}},p={},u=[],m={toc:u},d="wrapper";function g(e){var t=e.components,r=(0,a.Z)(e,i);return(0,o.kt)(d,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Arguments are positional arguments passed to the command. For example, if this command was run with ",(0,o.kt)("inlineCode",{parentName:"p"},"mycli arg1 arg2")," it would be declared like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Args, Command} from '@oclif/core'\n\nexport class MyCLI extends Command {\n static args = {\n firstArg: Args.string(),\n secondArg: Args.string(),\n }\n\n async run() {\n // can get args as an object\n const {args} = await this.parse(MyCLI)\n this.log(`running my command with args: ${args.firstArg}, ${args.secondArg}`)\n // can also get the args as an array\n const {argv} = await this.parse(MyCLI)\n this.log(`running my command with args: ${argv[0]}, ${argv[1]}`)\n }\n}\n")),(0,o.kt)("p",null,"Here are the options arguments can have:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},"static args = {\n firstArg: Args.string(\n {\n name: 'file', // name of arg to show in help and reference with args[name]\n required: false, // make the arg required with `required: true`\n description: 'output file', // help description\n hidden: true, // hide this arg from help\n parse: input => 'output', // instead of the user input, return a different value\n default: 'world', // default value if no arg input\n options: ['a', 'b'], // only allow input to be from a discrete set\n }\n ),\n}\n")),(0,o.kt)("p",null,"Here are the types of args that ",(0,o.kt)("inlineCode",{parentName:"p"},"Args")," exports:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"string"),(0,o.kt)("li",{parentName:"ul"},"integer"),(0,o.kt)("li",{parentName:"ul"},"boolean"),(0,o.kt)("li",{parentName:"ul"},"url"),(0,o.kt)("li",{parentName:"ul"},"file"),(0,o.kt)("li",{parentName:"ul"},"directory"),(0,o.kt)("li",{parentName:"ul"},"custom")),(0,o.kt)("p",null,"For variable length arguments, disable argument validation with ",(0,o.kt)("inlineCode",{parentName:"p"},"static strict = false")," on the command."))}g.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9147],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(r),d=a,g=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(g,i(i({ref:t},p),{},{components:r})):n.createElement(g,i({ref:t},p))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>g,frontMatter:()=>s,metadata:()=>c,toc:()=>u});var n=r(7462),a=r(3366),o=(r(7294),r(3905)),i=["components"],s={title:"Command Arguments"},l=void 0,c={unversionedId:"args",id:"args",title:"Command Arguments",description:"Arguments are positional arguments passed to the command. For example, if this command was run with mycli arg1 arg2 it would be declared like this:",source:"@site/../docs/args.md",sourceDirName:".",slug:"/args",permalink:"/docs/args",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/args.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Command Arguments"},sidebar:"docs",previous:{title:"Commands",permalink:"/docs/commands"},next:{title:"Command Flags",permalink:"/docs/flags"}},p={},u=[],m={toc:u},d="wrapper";function g(e){var t=e.components,r=(0,a.Z)(e,i);return(0,o.kt)(d,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Arguments are positional arguments passed to the command. For example, if this command was run with ",(0,o.kt)("inlineCode",{parentName:"p"},"mycli arg1 arg2")," it would be declared like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Args, Command} from '@oclif/core'\n\nexport class MyCLI extends Command {\n static args = {\n firstArg: Args.string(),\n secondArg: Args.string(),\n }\n\n async run() {\n // can get args as an object\n const {args} = await this.parse(MyCLI)\n this.log(`running my command with args: ${args.firstArg}, ${args.secondArg}`)\n // can also get the args as an array\n const {argv} = await this.parse(MyCLI)\n this.log(`running my command with args: ${argv[0]}, ${argv[1]}`)\n }\n}\n")),(0,o.kt)("p",null,"Here are the options arguments can have:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},"static args = {\n firstArg: Args.string(\n {\n name: 'file', // name of arg to show in help and reference with args[name]\n required: false, // make the arg required with `required: true`\n description: 'output file', // help description\n hidden: true, // hide this arg from help\n parse: input => 'output', // instead of the user input, return a different value\n default: 'world', // default value if no arg input\n options: ['a', 'b'], // only allow input to be from a discrete set\n }\n ),\n}\n")),(0,o.kt)("p",null,"Here are the types of args that ",(0,o.kt)("inlineCode",{parentName:"p"},"Args")," exports:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"string"),(0,o.kt)("li",{parentName:"ul"},"integer"),(0,o.kt)("li",{parentName:"ul"},"boolean"),(0,o.kt)("li",{parentName:"ul"},"url"),(0,o.kt)("li",{parentName:"ul"},"file"),(0,o.kt)("li",{parentName:"ul"},"directory"),(0,o.kt)("li",{parentName:"ul"},"custom")),(0,o.kt)("p",null,"For variable length arguments, disable argument validation with ",(0,o.kt)("inlineCode",{parentName:"p"},"static strict = false")," on the command."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d0e73d62.e161a6ef.js b/assets/js/d0e73d62.7326cfec.js similarity index 64% rename from assets/js/d0e73d62.e161a6ef.js rename to assets/js/d0e73d62.7326cfec.js index f117cf73..4b4b19be 100644 --- a/assets/js/d0e73d62.e161a6ef.js +++ b/assets/js/d0e73d62.7326cfec.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2134],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=c(n),m=i,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,s(s({ref:t},p),{},{components:n})):r.createElement(f,s({ref:t},p))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,s=new Array(o);s[0]=m;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:i,s[1]=a;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>u});var r=n(7462),i=n(3366),o=(n(7294),n(3905)),s=["components"],a={title:"NSIS Installer Customization"},l=void 0,c={unversionedId:"nsis-installer_customization",id:"nsis-installer_customization",title:"NSIS Installer Customization",description:"Sometimes you need to verify some dependencies, ensure there are no conflicting CLIs installed, or do some other custom logic before installing your CLI. For npm-scenarios, simply specify a preinstall script. But Windows installers don't include this script. You must instead write your own nsis modification to do these checks. See where this custom script gets placed in the installer in the oclif/oclif repo.",source:"@site/../docs/nsis-installer_customization.md",sourceDirName:".",slug:"/nsis-installer_customization",permalink:"/docs/nsis-installer_customization",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/nsis-installer_customization.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"NSIS Installer Customization"},sidebar:"docs",previous:{title:"Aliases",permalink:"/docs/aliases"},next:{title:"Custom Base Class",permalink:"/docs/base_class"}},p={},u=[],d={toc:u},m="wrapper";function f(e){var t=e.components,n=(0,i.Z)(e,s);return(0,o.kt)(m,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Sometimes you need to verify some dependencies, ensure there are no conflicting CLIs installed, or do some other custom logic before installing your CLI. For npm-scenarios, simply specify a ",(0,o.kt)("inlineCode",{parentName:"p"},"preinstall")," script. But Windows installers don't include this script. You must instead write your own nsis modification to do these checks. See where this custom script gets placed in the installer in the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif/blob/b8d76af9290716ef69d8d1026f98041268306dfd/src/commands/pack/win.ts#L60"},"oclif/oclif")," repo. "),(0,o.kt)("p",null,"See how ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/salesforcecli/cli"},"Salesforce CLI")," did this to prevent their new major version being installed on top of an older, and incompatible, version. In that ",(0,o.kt)("inlineCode",{parentName:"p"},"package.json"),", they specified an nsis installer like this: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'\n{\n "name": "mycli",\n "version": "0.0.0",\n "description": "My CLI",\n "main": "bin/run",\n "bin": "./bin/run",\n "oclif": {\n "nsisCustomization": "scripts/nsis.nsi"\n }\n}\n')),(0,o.kt)("p",null,"And then their custom script was loaded into the installer during the packing phase of the CLI."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2134],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=c(n),m=i,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,s(s({ref:t},p),{},{components:n})):r.createElement(f,s({ref:t},p))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,s=new Array(o);s[0]=m;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:i,s[1]=a;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>u});var r=n(7462),i=n(3366),o=(n(7294),n(3905)),s=["components"],a={title:"NSIS Installer Customization"},l=void 0,c={unversionedId:"nsis-installer_customization",id:"nsis-installer_customization",title:"NSIS Installer Customization",description:"Sometimes you need to verify some dependencies, ensure there are no conflicting CLIs installed, or do some other custom logic before installing your CLI. For npm-scenarios, simply specify a preinstall script. But Windows installers don't include this script. You must instead write your own nsis modification to do these checks. See where this custom script gets placed in the installer in the oclif/oclif repo.",source:"@site/../docs/nsis-installer_customization.md",sourceDirName:".",slug:"/nsis-installer_customization",permalink:"/docs/nsis-installer_customization",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/nsis-installer_customization.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"NSIS Installer Customization"},sidebar:"docs",previous:{title:"Aliases",permalink:"/docs/aliases"},next:{title:"Custom Base Class",permalink:"/docs/base_class"}},p={},u=[],d={toc:u},m="wrapper";function f(e){var t=e.components,n=(0,i.Z)(e,s);return(0,o.kt)(m,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"Sometimes you need to verify some dependencies, ensure there are no conflicting CLIs installed, or do some other custom logic before installing your CLI. For npm-scenarios, simply specify a ",(0,o.kt)("inlineCode",{parentName:"p"},"preinstall")," script. But Windows installers don't include this script. You must instead write your own nsis modification to do these checks. See where this custom script gets placed in the installer in the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/oclif/oclif/blob/b8d76af9290716ef69d8d1026f98041268306dfd/src/commands/pack/win.ts#L60"},"oclif/oclif")," repo. "),(0,o.kt)("p",null,"See how ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/salesforcecli/cli"},"Salesforce CLI")," did this to prevent their new major version being installed on top of an older, and incompatible, version. In that ",(0,o.kt)("inlineCode",{parentName:"p"},"package.json"),", they specified an nsis installer like this: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-json"},'\n{\n "name": "mycli",\n "version": "0.0.0",\n "description": "My CLI",\n "main": "bin/run",\n "bin": "./bin/run",\n "oclif": {\n "nsisCustomization": "scripts/nsis.nsi"\n }\n}\n')),(0,o.kt)("p",null,"And then their custom script was loaded into the installer during the packing phase of the CLI."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d665a578.af0a55e3.js b/assets/js/d665a578.3443bf80.js similarity index 79% rename from assets/js/d665a578.af0a55e3.js rename to assets/js/d665a578.3443bf80.js index 58377c77..e490a72b 100644 --- a/assets/js/d665a578.af0a55e3.js +++ b/assets/js/d665a578.3443bf80.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9510],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),u=p(r),f=o,d=u["".concat(c,".").concat(f)]||u[f]||m[f]||a;return r?n.createElement(d,l(l({ref:t},s),{},{components:r})):n.createElement(d,l({ref:t},s))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=f;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,l[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>u});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),l=["components"],i={title:"Examples"},c=void 0,p={unversionedId:"examples",id:"examples",title:"Examples",description:"Here are some examples to get an idea of how to use oclif in various setups.",source:"@site/../docs/examples.md",sourceDirName:".",slug:"/examples",permalink:"/docs/examples",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/examples.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Examples"},sidebar:"docs",previous:{title:"ES2022",permalink:"/docs/ES2022"},next:{title:"External Links",permalink:"/docs/external_links"}},s={},u=[],m={toc:u},f="wrapper";function d(e){var t=e.components,r=(0,o.Z)(e,l);return(0,a.kt)(f,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Here are some examples to get an idea of how to use oclif in various setups."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/oclif/hello-world"},"Hello World Example"))))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[9510],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),u=p(r),f=o,d=u["".concat(c,".").concat(f)]||u[f]||m[f]||a;return r?n.createElement(d,l(l({ref:t},s),{},{components:r})):n.createElement(d,l({ref:t},s))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=f;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,l[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>u});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),l=["components"],i={title:"Examples"},c=void 0,p={unversionedId:"examples",id:"examples",title:"Examples",description:"Here are some examples to get an idea of how to use oclif in various setups.",source:"@site/../docs/examples.md",sourceDirName:".",slug:"/examples",permalink:"/docs/examples",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/examples.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Examples"},sidebar:"docs",previous:{title:"ES2022",permalink:"/docs/ES2022"},next:{title:"External Links",permalink:"/docs/external_links"}},s={},u=[],m={toc:u},f="wrapper";function d(e){var t=e.components,r=(0,o.Z)(e,l);return(0,a.kt)(f,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Here are some examples to get an idea of how to use oclif in various setups."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/oclif/hello-world"},"Hello World Example"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d9b0bdb4.70e676e4.js b/assets/js/d9b0bdb4.005ede07.js similarity index 80% rename from assets/js/d9b0bdb4.70e676e4.js rename to assets/js/d9b0bdb4.005ede07.js index c8bb20a5..e256b1fb 100644 --- a/assets/js/d9b0bdb4.70e676e4.js +++ b/assets/js/d9b0bdb4.005ede07.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5933],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=l(r),d=o,m=p["".concat(s,".").concat(d)]||p[d]||f[d]||a;return r?n.createElement(m,c(c({ref:t},u),{},{components:r})):n.createElement(m,c({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:o,c[1]=i;for(var l=2;l{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),c=["components"],i={title:"Feedback"},s=void 0,l={unversionedId:"feedback",id:"feedback",title:"Feedback",description:"If you have any suggestions or just want to let us know what you think of oclif, send us a message at or file an issue in our repos.",source:"@site/../docs/feedback.md",sourceDirName:".",slug:"/feedback",permalink:"/docs/feedback",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/feedback.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Feedback"},sidebar:"docs",previous:{title:"How We Work",permalink:"/docs/how_we_work"}},u={},p=[],f={toc:p},d="wrapper";function m(e){var t=e.components,r=(0,o.Z)(e,c);return(0,a.kt)(d,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"If you have any suggestions or just want to let us know what you think of oclif, send us a message at ",(0,a.kt)("a",{parentName:"p",href:"mailto:alm-cli@salesforce.com"},"alm-cli@salesforce.com")," or file an issue in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif"},"our repos"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5933],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=l(r),d=o,m=p["".concat(s,".").concat(d)]||p[d]||f[d]||a;return r?n.createElement(m,c(c({ref:t},u),{},{components:r})):n.createElement(m,c({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:o,c[1]=i;for(var l=2;l{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),c=["components"],i={title:"Feedback"},s=void 0,l={unversionedId:"feedback",id:"feedback",title:"Feedback",description:"If you have any suggestions or just want to let us know what you think of oclif, send us a message at or file an issue in our repos.",source:"@site/../docs/feedback.md",sourceDirName:".",slug:"/feedback",permalink:"/docs/feedback",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/feedback.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Feedback"},sidebar:"docs",previous:{title:"How We Work",permalink:"/docs/how_we_work"}},u={},p=[],f={toc:p},d="wrapper";function m(e){var t=e.components,r=(0,o.Z)(e,c);return(0,a.kt)(d,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"If you have any suggestions or just want to let us know what you think of oclif, send us a message at ",(0,a.kt)("a",{parentName:"p",href:"mailto:alm-cli@salesforce.com"},"alm-cli@salesforce.com")," or file an issue in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif"},"our repos"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/df1cd967.e844fcfe.js b/assets/js/df1cd967.375c6b38.js similarity index 70% rename from assets/js/df1cd967.e844fcfe.js rename to assets/js/df1cd967.375c6b38.js index 5f7ce02b..9def6c0f 100644 --- a/assets/js/df1cd967.e844fcfe.js +++ b/assets/js/df1cd967.375c6b38.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2712],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function p(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=o.createContext({}),s=function(e){var t=o.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},l=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=s(r),m=n,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return r?o.createElement(f,p(p({ref:t},l),{},{components:r})):o.createElement(f,p({ref:t},l))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,p=new Array(a);p[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:n,p[1]=i;for(var s=2;s{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>f,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var o=r(7462),n=r(3366),a=(r(7294),r(3905)),p=["components"],i={title:"Topic Separators"},c=void 0,s={unversionedId:"topic_separator",id:"topic_separator",title:"Topic Separators",description:"By default, topics will be separated with colons, e.g. mycommand. However, you have the option to use spaces if you prefer, e.g. my awesome command.",source:"@site/../docs/topic_separator.md",sourceDirName:".",slug:"/topic_separator",permalink:"/docs/topic_separator",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/topic_separator.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Topic Separators"},sidebar:"docs",previous:{title:"Topics",permalink:"/docs/topics"},next:{title:"Hooks",permalink:"/docs/hooks"}},l={},u=[],d={toc:u},m="wrapper";function f(e){var t=e.components,r=(0,n.Z)(e,p);return(0,a.kt)(m,(0,o.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"By default, topics will be separated with colons, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"my:awesome:command"),". However, you have the option to use spaces if you prefer, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"my awesome command"),"."),(0,a.kt)("p",null,"To do this, simply set the ",(0,a.kt)("inlineCode",{parentName:"p"},"topicSeparator")," property in the oclif section of your package.json"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "oclif": {\n "topicSeparator": " "\n }\n}\n')),(0,a.kt)("p",null,"Currently colons (",(0,a.kt)("inlineCode",{parentName:"p"},'":"'),") and spaces (",(0,a.kt)("inlineCode",{parentName:"p"},'" "'),") are the only supported topic separators."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[2712],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function p(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=o.createContext({}),s=function(e){var t=o.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},l=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=s(r),m=n,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return r?o.createElement(f,p(p({ref:t},l),{},{components:r})):o.createElement(f,p({ref:t},l))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,p=new Array(a);p[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:n,p[1]=i;for(var s=2;s{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>f,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var o=r(7462),n=r(3366),a=(r(7294),r(3905)),p=["components"],i={title:"Topic Separators"},c=void 0,s={unversionedId:"topic_separator",id:"topic_separator",title:"Topic Separators",description:"By default, topics will be separated with colons, e.g. mycommand. However, you have the option to use spaces if you prefer, e.g. my awesome command.",source:"@site/../docs/topic_separator.md",sourceDirName:".",slug:"/topic_separator",permalink:"/docs/topic_separator",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/topic_separator.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Topic Separators"},sidebar:"docs",previous:{title:"Topics",permalink:"/docs/topics"},next:{title:"Hooks",permalink:"/docs/hooks"}},l={},u=[],d={toc:u},m="wrapper";function f(e){var t=e.components,r=(0,n.Z)(e,p);return(0,a.kt)(m,(0,o.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"By default, topics will be separated with colons, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"my:awesome:command"),". However, you have the option to use spaces if you prefer, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"my awesome command"),"."),(0,a.kt)("p",null,"To do this, simply set the ",(0,a.kt)("inlineCode",{parentName:"p"},"topicSeparator")," property in the oclif section of your package.json"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "oclif": {\n "topicSeparator": " "\n }\n}\n')),(0,a.kt)("p",null,"Currently colons (",(0,a.kt)("inlineCode",{parentName:"p"},'":"'),") and spaces (",(0,a.kt)("inlineCode",{parentName:"p"},'" "'),") are the only supported topic separators."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e360e27f.007614cd.js b/assets/js/e360e27f.007614cd.js deleted file mode 100644 index 22d625e6..00000000 --- a/assets/js/e360e27f.007614cd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5990],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var i=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=i.createContext({}),p=function(e){var t=i.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(u.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,o=e.mdxType,l=e.originalType,u=e.parentName,s=r(e,["components","mdxType","originalType","parentName"]),c=p(n),d=o,f=c["".concat(u,".").concat(d)]||c[d]||m[d]||l;return n?i.createElement(f,a(a({ref:t},s),{},{components:n})):i.createElement(f,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var l=n.length,a=new Array(l);a[0]=d;var r={};for(var u in t)hasOwnProperty.call(t,u)&&(r[u]=t[u]);r.originalType=e,r[c]="string"==typeof e?e:o,a[1]=r;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>u,default:()=>f,frontMatter:()=>r,metadata:()=>p,toc:()=>c});var i=n(7462),o=n(3366),l=(n(7294),n(3905)),a=["components"],r={title:"Plugins"},u=void 0,p={unversionedId:"plugins",id:"plugins",title:"Plugins",description:"Plugins are a great way to offer experimental functionality, allow users to extend your CLI, break up a CLI into modular components, or share functionality between CLIs.",source:"@site/../docs/plugins.md",sourceDirName:".",slug:"/plugins",permalink:"/docs/plugins",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/plugins.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Plugins"},sidebar:"docs",previous:{title:"Hooks",permalink:"/docs/hooks"},next:{title:"Help Classes",permalink:"/docs/help_classes"}},s={},c=[{value:"Useful Plugins",id:"useful-plugins",level:2},{value:"Community Plugins",id:"community-plugins",level:2},{value:"Building your own plugin",id:"building-your-own-plugin",level:2}],m={toc:c},d="wrapper";function f(e){var t=e.components,n=(0,o.Z)(e,a);return(0,l.kt)(d,(0,i.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("p",null,"Plugins are a great way to offer experimental functionality, allow users to extend your CLI, break up a CLI into modular components, or share functionality between CLIs."),(0,l.kt)("p",null,"Plugins can have commands or hooks just like a CLI. To add a plugin such as the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-not-found"},"not-found plugin")," plugin, first add it to your CLI with ",(0,l.kt)("inlineCode",{parentName:"p"},"yarn add @oclif/plugin-not-found"),", then add the following to your ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},'{\n "name": "mycli",\n "version": "0.0.0",\n // ...\n "oclif": {\n "plugins": [\n "@oclif/plugin-help",\n "@oclif/plugin-not-found"\n ]\n }\n}\n')),(0,l.kt)("p",null,"If you want users to be able to install their own plugins into your CLI, use the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-plugins"},"plugins plugin"),"."),(0,l.kt)("h2",{id:"useful-plugins"},"Useful Plugins"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-not-found"},"@oclif/plugin-not-found"),' - Display a friendly "did you mean" message if a command is not found.'),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-plugins"},"@oclif/plugin-plugins")," - Allow users to add plugins to extend your CLI."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-update"},"@oclif/plugin-update")," - Add autoupdate support to the CLI."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-help"},"@oclif/plugin-help")," - Help plugin for oclif."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-warn-if-update-available"},"@oclif/plugin-warn-if-update-available")," - Show a warning message if user is running an out of date CLI."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-which"},"@oclif/plugin-which")," - Show which plugin a command comes from."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-commands"},"@oclif/plugin-commands")," - Add a ",(0,l.kt)("inlineCode",{parentName:"li"},"commands")," command to list all the commands."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-autocomplete"},"@oclif/plugin-autocomplete")," - Add bash/zsh autocomplete.")),(0,l.kt)("h2",{id:"community-plugins"},"Community Plugins"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/natzcam/conf-cli"},"conf-cli")," - Adds a ",(0,l.kt)("inlineCode",{parentName:"li"},"conf")," command to share state/configuration between commands. Uses ",(0,l.kt)("a",{parentName:"li",href:"https://github.com/sindresorhus/conf"},"sindresorhus/conf"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://www.npmjs.com/package/oclif-dynamic-commands"},"dynamic-commands")," - Load commands dynamically based on commands found under the current working directory."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/oclif.github.io/blob/docs/docs/plugins.md"},"Add yours here"),"!")),(0,l.kt)("h2",{id:"building-your-own-plugin"},"Building your own plugin"),(0,l.kt)("p",null,"Writing code for plugins is essentially the same as writing within a CLI. They can export 3 different types: commands, hooks, and other plugins."),(0,l.kt)("p",null,"Run ",(0,l.kt)("inlineCode",{parentName:"p"},"npx oclif generate mynewplugin")," to create a plugin in a new directory. This will come with a sample command called ",(0,l.kt)("inlineCode",{parentName:"p"},"hello"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e360e27f.d0c752d3.js b/assets/js/e360e27f.d0c752d3.js new file mode 100644 index 00000000..5562a346 --- /dev/null +++ b/assets/js/e360e27f.d0c752d3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5990],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var i=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=i.createContext({}),p=function(e){var t=i.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(u.Provider,{value:t},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,o=e.mdxType,l=e.originalType,u=e.parentName,s=r(e,["components","mdxType","originalType","parentName"]),c=p(n),d=o,f=c["".concat(u,".").concat(d)]||c[d]||m[d]||l;return n?i.createElement(f,a(a({ref:t},s),{},{components:n})):i.createElement(f,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var l=n.length,a=new Array(l);a[0]=d;var r={};for(var u in t)hasOwnProperty.call(t,u)&&(r[u]=t[u]);r.originalType=e,r[c]="string"==typeof e?e:o,a[1]=r;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>u,default:()=>f,frontMatter:()=>r,metadata:()=>p,toc:()=>c});var i=n(7462),o=n(3366),l=(n(7294),n(3905)),a=["components"],r={title:"Plugins"},u=void 0,p={unversionedId:"plugins",id:"plugins",title:"Plugins",description:"Plugins are a great way to offer experimental functionality, allow users to extend your CLI, break up a CLI into modular components, or share functionality between CLIs.",source:"@site/../docs/plugins.md",sourceDirName:".",slug:"/plugins",permalink:"/docs/plugins",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/plugins.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Plugins"},sidebar:"docs",previous:{title:"Hooks",permalink:"/docs/hooks"},next:{title:"Help Classes",permalink:"/docs/help_classes"}},s={},c=[{value:"Useful Plugins",id:"useful-plugins",level:2},{value:"Community Plugins",id:"community-plugins",level:2},{value:"Building your own plugin",id:"building-your-own-plugin",level:2}],m={toc:c},d="wrapper";function f(e){var t=e.components,n=(0,o.Z)(e,a);return(0,l.kt)(d,(0,i.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("p",null,"Plugins are a great way to offer experimental functionality, allow users to extend your CLI, break up a CLI into modular components, or share functionality between CLIs."),(0,l.kt)("p",null,"Plugins can have commands or hooks just like a CLI. To add a plugin such as the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-not-found"},"not-found plugin")," plugin, first add it to your CLI with ",(0,l.kt)("inlineCode",{parentName:"p"},"yarn add @oclif/plugin-not-found"),", then add the following to your ",(0,l.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-js"},'{\n "name": "mycli",\n "version": "0.0.0",\n // ...\n "oclif": {\n "plugins": [\n "@oclif/plugin-help",\n "@oclif/plugin-not-found"\n ]\n }\n}\n')),(0,l.kt)("p",null,"If you want users to be able to install their own plugins into your CLI, use the ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/oclif/plugin-plugins"},"plugins plugin"),"."),(0,l.kt)("h2",{id:"useful-plugins"},"Useful Plugins"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-not-found"},"@oclif/plugin-not-found"),' - Display a friendly "did you mean" message if a command is not found.'),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-plugins"},"@oclif/plugin-plugins")," - Allow users to add plugins to extend your CLI."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-update"},"@oclif/plugin-update")," - Add autoupdate support to the CLI."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-help"},"@oclif/plugin-help")," - Help plugin for oclif."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-warn-if-update-available"},"@oclif/plugin-warn-if-update-available")," - Show a warning message if user is running an out of date CLI."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-which"},"@oclif/plugin-which")," - Show which plugin a command comes from."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-commands"},"@oclif/plugin-commands")," - Add a ",(0,l.kt)("inlineCode",{parentName:"li"},"commands")," command to list all the commands."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/plugin-autocomplete"},"@oclif/plugin-autocomplete")," - Add bash/zsh autocomplete.")),(0,l.kt)("h2",{id:"community-plugins"},"Community Plugins"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/natzcam/conf-cli"},"conf-cli")," - Adds a ",(0,l.kt)("inlineCode",{parentName:"li"},"conf")," command to share state/configuration between commands. Uses ",(0,l.kt)("a",{parentName:"li",href:"https://github.com/sindresorhus/conf"},"sindresorhus/conf"),"."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://www.npmjs.com/package/oclif-dynamic-commands"},"dynamic-commands")," - Load commands dynamically based on commands found under the current working directory."),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/oclif/oclif.github.io/blob/docs/docs/plugins.md"},"Add yours here"),"!")),(0,l.kt)("h2",{id:"building-your-own-plugin"},"Building your own plugin"),(0,l.kt)("p",null,"Writing code for plugins is essentially the same as writing within a CLI. They can export 3 different types: commands, hooks, and other plugins."),(0,l.kt)("p",null,"Run ",(0,l.kt)("inlineCode",{parentName:"p"},"npx oclif generate mynewplugin")," to create a plugin in a new directory. This will come with a sample command called ",(0,l.kt)("inlineCode",{parentName:"p"},"hello"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e3703649.0e8cb99f.js b/assets/js/e3703649.0e8cb99f.js deleted file mode 100644 index 7de27fbc..00000000 --- a/assets/js/e3703649.0e8cb99f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5679],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var o=n(7294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=o.createContext({}),i=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=i(e.components);return o.createElement(p.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,l=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=i(n),h=l,u=m["".concat(p,".").concat(h)]||m[h]||d[h]||a;return n?o.createElement(u,r(r({ref:t},c),{},{components:n})):o.createElement(u,r({ref:t},c))}));function u(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var a=n.length,r=new Array(a);r[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[m]="string"==typeof e?e:l,r[1]=s;for(var i=2;i{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>p,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>m});var o=n(7462),l=n(3366),a=(n(7294),n(3905)),r=["components"],s={title:"Help Classes"},p=void 0,i={unversionedId:"help_classes",id:"help_classes",title:"Help Classes",description:"Out of the box oclif provides a great help experience for CLIs. Users can invoke help with the --help flag.",source:"@site/../docs/help_classes.md",sourceDirName:".",slug:"/help_classes",permalink:"/docs/help_classes",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/help_classes.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Help Classes"},sidebar:"docs",previous:{title:"Plugins",permalink:"/docs/plugins"},next:{title:"Error Handling",permalink:"/docs/error_handling"}},c={},m=[{value:"Custom Help",id:"custom-help",level:2},{value:"Extending the HelpBase class",id:"extending-the-helpbase-class",level:2},{value:"Extending the default Help class",id:"extending-the-default-help-class",level:2},{value:"Building custom help classes in JavaScript projects",id:"building-custom-help-classes-in-javascript-projects",level:2}],d={toc:m},h="wrapper";function u(e){var t=e.components,n=(0,l.Z)(e,r);return(0,a.kt)(h,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Out of the box oclif provides a great help experience for CLIs. Users can invoke help with the ",(0,a.kt)("inlineCode",{parentName:"p"},"--help")," flag."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ my-cli login --help\n")),(0,a.kt)("p",null,"If you want your CLI to have an explicit ",(0,a.kt)("inlineCode",{parentName:"p"},"help")," command, add ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/plugin-help")," as an ",(0,a.kt)("a",{parentName:"p",href:"/docs/plugins"},"oclif plugin in your config"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ my-cli help\n")),(0,a.kt)("h2",{id:"custom-help"},"Custom Help"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ yarn add @oclif/core --latest\n")),(0,a.kt)("p",null,"To get started, first define the filepath to your help class in oclif's config in package.json. This is a relative path to the help class, without a file extension."),(0,a.kt)("p",null,'For this example, the help class will be created in a file at "',"[project root]",'/src/help.ts".'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'{\n // ...\n "oclif": {\n "helpClass": "./lib/help"\n // ...\n }\n // ...\n}\n')),(0,a.kt)("p",null,"From here there are two paths, implement the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelpBase")," abstract class yourself or overwrite the parts of the default ",(0,a.kt)("inlineCode",{parentName:"p"},"Help")," class you want to customize (ex: how command usage is displayed). We recommend the latter approach but cover both below."),(0,a.kt)("h2",{id:"extending-the-helpbase-class"},"Extending the ",(0,a.kt)("inlineCode",{parentName:"h2"},"HelpBase")," class"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"HelpBase")," abstract class provides a starting point requiring the minimum needed methods implemented to be compatible with oclif."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-TypeScript"},"import {Command, HelpBase} from '@oclif/core';\n\nexport default class CustomHelp extends HelpBase {\n showHelp(args: string[]) {\n console.log('This will be displayed in multi-command CLIs')\n }\n\n showCommandHelp(command: Command) {\n console.log('This will be displayed in single-command CLIs')\n }\n}\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"showHelp")," method is called by oclif to display help in multi-command CLIs, while ",(0,a.kt)("inlineCode",{parentName:"p"},"showCommandHelp")," is called directly for single-command CLIs."),(0,a.kt)("p",null,"The class is instantiated with a ",(0,a.kt)("inlineCode",{parentName:"p"},"config")," property that provides helpful context for constructing your custom output."),(0,a.kt)("p",null,"To see an example of what is possible take a look at the source code for the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/help/index.ts"},"default ",(0,a.kt)("inlineCode",{parentName:"a"},"Help")," class exported from @oclif/core"),"."),(0,a.kt)("h2",{id:"extending-the-default-help-class"},"Extending the default ",(0,a.kt)("inlineCode",{parentName:"h2"},"Help")," class"),(0,a.kt)("p",null,"The default ",(0,a.kt)("inlineCode",{parentName:"p"},"Help")," class provides many method \u201chooks\u201d that make it easy to override the particular parts of help's output you want to customize."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-TypeScript"},"import {Command, Help, Topic} from '@oclif/core';\n\nexport default class MyHelpClass extends Help {\n // acts as a \"router\"\n // and based on the args it receives\n // calls one of showRootHelp, showTopicHelp,\n // or showCommandHelp\n showHelp(args: string[]): void {\n }\n\n // display the root help of a CLI\n showRootHelp(): void {\n }\n\n // display help for a topic\n showTopicHelp(topic: Topic): void {\n }\n\n // display help for a command\n showCommandHelp(command: Command): void {\n }\n\n // the default implementations of showRootHelp\n // showTopicHelp and showCommandHelp\n // will call various format methods that\n // provide the formatting for their corresponding\n // help sections;\n // these can be overwritten as well\n\n // the formatting responsible for the header\n // displayed for the root help\n formatRoot(): string {\n }\n\n // the formatting for an individual topic\n formatTopic(topic: Config.Topic): string {\n }\n\n // the formatting for a list of topics\n protected formatTopics(topics: Config.Topic[]): string {\n }\n\n // the formatting for a list of commands\n formatCommands(commands: Config.Command[]): string {\n }\n\n // the formatting for an individual command\n formatCommand(command: Config.Command): string {\n }\n}\n")),(0,a.kt)("p",null,"To see the default implementation of these methods take a look at the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/help/index.ts"},"default ",(0,a.kt)("inlineCode",{parentName:"a"},"Help")," class exported from @oclif/core"),"."),(0,a.kt)("p",null,"To start experimenting, define ",(0,a.kt)("inlineCode",{parentName:"p"},"showCommandHelp")," in your custom help class and change the output."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-TypeScript"},"import {Command, Help, Topic} from '@oclif/core';\n\nexport default class MyHelpClass extends Help {\n public showCommandHelp(command: Config.Command) {\n console.log('Display my custom command help!')\n }\n}\n")),(0,a.kt)("p",null,"Then run help for any command."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ my-cli login --help\nDisplay my custom command help!\n")),(0,a.kt)("h2",{id:"building-custom-help-classes-in-javascript-projects"},"Building custom help classes in JavaScript projects"),(0,a.kt)("p",null,'These examples above followed a TypeScript project. For JavaScript project with an example help file at "',"[project root]",'/src/help.js" would have a package.json with the ',(0,a.kt)("inlineCode",{parentName:"p"},"helpClass")," defined:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'{\n // ...\n "oclif": {\n "helpClass": "./src/help"\n // ...\n }\n // ...\n}\n')),(0,a.kt)("p",null,"The imports are handled slightly different for JavaScript projects but the rest of the help class mimic the TypeScript examples above, except without type annotations."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"const {HelpBase} = require('@oclif/core');\n\nmodule.exports = class MyHelpClass extends HelpBase {\n showHelp(args) {\n console.log('This will be displayed in multi-command CLIs')\n }\n\n showCommandHelp(command) {\n console.log('This will be displayed for a single command')\n }\n}\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"const {Help} = require('@oclif/core');\n\nmodule.exports = class MyHelpClass extends Help {\n showHelp(args) {\n }\n\n showRootHelp() {\n }\n\n showTopicHelp(topic) {\n }\n\n showCommandHelp(command) {\n }\n\n formatRoot() {\n }\n\n formatTopic(topic) {\n }\n\n formatTopics(topics) {\n }\n\n formatCommands(commands) {\n }\n\n formatCommand(command) {\n }\n}\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e3703649.7738d85b.js b/assets/js/e3703649.7738d85b.js new file mode 100644 index 00000000..f4f04c1b --- /dev/null +++ b/assets/js/e3703649.7738d85b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5679],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var o=n(7294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var p=o.createContext({}),i=function(e){var t=o.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=i(e.components);return o.createElement(p.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,l=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=i(n),h=l,u=m["".concat(p,".").concat(h)]||m[h]||d[h]||a;return n?o.createElement(u,r(r({ref:t},c),{},{components:n})):o.createElement(u,r({ref:t},c))}));function u(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var a=n.length,r=new Array(a);r[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[m]="string"==typeof e?e:l,r[1]=s;for(var i=2;i{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>p,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>m});var o=n(7462),l=n(3366),a=(n(7294),n(3905)),r=["components"],s={title:"Help Classes"},p=void 0,i={unversionedId:"help_classes",id:"help_classes",title:"Help Classes",description:"Out of the box oclif provides a great help experience for CLIs. Users can invoke help with the --help flag.",source:"@site/../docs/help_classes.md",sourceDirName:".",slug:"/help_classes",permalink:"/docs/help_classes",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/help_classes.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Help Classes"},sidebar:"docs",previous:{title:"Plugins",permalink:"/docs/plugins"},next:{title:"Error Handling",permalink:"/docs/error_handling"}},c={},m=[{value:"Custom Help",id:"custom-help",level:2},{value:"Extending the HelpBase class",id:"extending-the-helpbase-class",level:2},{value:"Extending the default Help class",id:"extending-the-default-help-class",level:2},{value:"Building custom help classes in JavaScript projects",id:"building-custom-help-classes-in-javascript-projects",level:2}],d={toc:m},h="wrapper";function u(e){var t=e.components,n=(0,l.Z)(e,r);return(0,a.kt)(h,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Out of the box oclif provides a great help experience for CLIs. Users can invoke help with the ",(0,a.kt)("inlineCode",{parentName:"p"},"--help")," flag."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ my-cli login --help\n")),(0,a.kt)("p",null,"If you want your CLI to have an explicit ",(0,a.kt)("inlineCode",{parentName:"p"},"help")," command, add ",(0,a.kt)("inlineCode",{parentName:"p"},"@oclif/plugin-help")," as an ",(0,a.kt)("a",{parentName:"p",href:"/docs/plugins"},"oclif plugin in your config"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ my-cli help\n")),(0,a.kt)("h2",{id:"custom-help"},"Custom Help"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ yarn add @oclif/core --latest\n")),(0,a.kt)("p",null,"To get started, first define the filepath to your help class in oclif's config in package.json. This is a relative path to the help class, without a file extension."),(0,a.kt)("p",null,'For this example, the help class will be created in a file at "',"[project root]",'/src/help.ts".'),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'{\n // ...\n "oclif": {\n "helpClass": "./lib/help"\n // ...\n }\n // ...\n}\n')),(0,a.kt)("p",null,"From here there are two paths, implement the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelpBase")," abstract class yourself or overwrite the parts of the default ",(0,a.kt)("inlineCode",{parentName:"p"},"Help")," class you want to customize (ex: how command usage is displayed). We recommend the latter approach but cover both below."),(0,a.kt)("h2",{id:"extending-the-helpbase-class"},"Extending the ",(0,a.kt)("inlineCode",{parentName:"h2"},"HelpBase")," class"),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"HelpBase")," abstract class provides a starting point requiring the minimum needed methods implemented to be compatible with oclif."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-TypeScript"},"import {Command, HelpBase} from '@oclif/core';\n\nexport default class CustomHelp extends HelpBase {\n showHelp(args: string[]) {\n console.log('This will be displayed in multi-command CLIs')\n }\n\n showCommandHelp(command: Command) {\n console.log('This will be displayed in single-command CLIs')\n }\n}\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"showHelp")," method is called by oclif to display help in multi-command CLIs, while ",(0,a.kt)("inlineCode",{parentName:"p"},"showCommandHelp")," is called directly for single-command CLIs."),(0,a.kt)("p",null,"The class is instantiated with a ",(0,a.kt)("inlineCode",{parentName:"p"},"config")," property that provides helpful context for constructing your custom output."),(0,a.kt)("p",null,"To see an example of what is possible take a look at the source code for the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/help/index.ts"},"default ",(0,a.kt)("inlineCode",{parentName:"a"},"Help")," class exported from @oclif/core"),"."),(0,a.kt)("h2",{id:"extending-the-default-help-class"},"Extending the default ",(0,a.kt)("inlineCode",{parentName:"h2"},"Help")," class"),(0,a.kt)("p",null,"The default ",(0,a.kt)("inlineCode",{parentName:"p"},"Help")," class provides many method \u201chooks\u201d that make it easy to override the particular parts of help's output you want to customize."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-TypeScript"},"import {Command, Help, Topic} from '@oclif/core';\n\nexport default class MyHelpClass extends Help {\n // acts as a \"router\"\n // and based on the args it receives\n // calls one of showRootHelp, showTopicHelp,\n // or showCommandHelp\n showHelp(args: string[]): void {\n }\n\n // display the root help of a CLI\n showRootHelp(): void {\n }\n\n // display help for a topic\n showTopicHelp(topic: Topic): void {\n }\n\n // display help for a command\n showCommandHelp(command: Command): void {\n }\n\n // the default implementations of showRootHelp\n // showTopicHelp and showCommandHelp\n // will call various format methods that\n // provide the formatting for their corresponding\n // help sections;\n // these can be overwritten as well\n\n // the formatting responsible for the header\n // displayed for the root help\n formatRoot(): string {\n }\n\n // the formatting for an individual topic\n formatTopic(topic: Config.Topic): string {\n }\n\n // the formatting for a list of topics\n protected formatTopics(topics: Config.Topic[]): string {\n }\n\n // the formatting for a list of commands\n formatCommands(commands: Config.Command[]): string {\n }\n\n // the formatting for an individual command\n formatCommand(command: Config.Command): string {\n }\n}\n")),(0,a.kt)("p",null,"To see the default implementation of these methods take a look at the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/oclif/core/blob/main/src/help/index.ts"},"default ",(0,a.kt)("inlineCode",{parentName:"a"},"Help")," class exported from @oclif/core"),"."),(0,a.kt)("p",null,"To start experimenting, define ",(0,a.kt)("inlineCode",{parentName:"p"},"showCommandHelp")," in your custom help class and change the output."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-TypeScript"},"import {Command, Help, Topic} from '@oclif/core';\n\nexport default class MyHelpClass extends Help {\n public showCommandHelp(command: Config.Command) {\n console.log('Display my custom command help!')\n }\n}\n")),(0,a.kt)("p",null,"Then run help for any command."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"$ my-cli login --help\nDisplay my custom command help!\n")),(0,a.kt)("h2",{id:"building-custom-help-classes-in-javascript-projects"},"Building custom help classes in JavaScript projects"),(0,a.kt)("p",null,'These examples above followed a TypeScript project. For JavaScript project with an example help file at "',"[project root]",'/src/help.js" would have a package.json with the ',(0,a.kt)("inlineCode",{parentName:"p"},"helpClass")," defined:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'{\n // ...\n "oclif": {\n "helpClass": "./src/help"\n // ...\n }\n // ...\n}\n')),(0,a.kt)("p",null,"The imports are handled slightly different for JavaScript projects but the rest of the help class mimic the TypeScript examples above, except without type annotations."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"const {HelpBase} = require('@oclif/core');\n\nmodule.exports = class MyHelpClass extends HelpBase {\n showHelp(args) {\n console.log('This will be displayed in multi-command CLIs')\n }\n\n showCommandHelp(command) {\n console.log('This will be displayed for a single command')\n }\n}\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"const {Help} = require('@oclif/core');\n\nmodule.exports = class MyHelpClass extends Help {\n showHelp(args) {\n }\n\n showRootHelp() {\n }\n\n showTopicHelp(topic) {\n }\n\n showCommandHelp(command) {\n }\n\n formatRoot() {\n }\n\n formatTopic(topic) {\n }\n\n formatTopics(topics) {\n }\n\n formatCommands(commands) {\n }\n\n formatCommand(command) {\n }\n}\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f182954c.9b23b163.js b/assets/js/f182954c.bf136eda.js similarity index 76% rename from assets/js/f182954c.9b23b163.js rename to assets/js/f182954c.bf136eda.js index 3b808fed..ce31824a 100644 --- a/assets/js/f182954c.9b23b163.js +++ b/assets/js/f182954c.bf136eda.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[182],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(r),d=o,m=u["".concat(c,".").concat(d)]||u[d]||f[d]||a;return r?n.createElement(m,i(i({ref:t},p),{},{components:r})):n.createElement(m,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>u});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),i=["components"],l={title:"Related Repositories"},c=void 0,s={unversionedId:"related_repos",id:"related_repos",title:"Related Repositories",description:"* @oclif/core - Base library for oclif CLIs or plugins. This can be used directly without the generator.",source:"@site/../docs/related_repos.md",sourceDirName:".",slug:"/related_repos",permalink:"/docs/related_repos",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/related_repos.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Related Repositories"},sidebar:"docs",previous:{title:"External Links",permalink:"/docs/external_links"},next:{title:"How We Work",permalink:"/docs/how_we_work"}},p={},u=[],f={toc:u},d="wrapper";function m(e){var t=e.components,r=(0,o.Z)(e,i);return(0,a.kt)(d,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/oclif/core"},"@oclif/core")," - Base library for oclif CLIs or plugins. This can be used directly without the generator."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/oclif/test"},"@oclif/test")," - Test helper for oclif.")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[182],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(r),d=o,m=u["".concat(c,".").concat(d)]||u[d]||f[d]||a;return r?n.createElement(m,i(i({ref:t},p),{},{components:r})):n.createElement(m,i({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>u});var n=r(7462),o=r(3366),a=(r(7294),r(3905)),i=["components"],l={title:"Related Repositories"},c=void 0,s={unversionedId:"related_repos",id:"related_repos",title:"Related Repositories",description:"* @oclif/core - Base library for oclif CLIs or plugins. This can be used directly without the generator.",source:"@site/../docs/related_repos.md",sourceDirName:".",slug:"/related_repos",permalink:"/docs/related_repos",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/related_repos.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Related Repositories"},sidebar:"docs",previous:{title:"External Links",permalink:"/docs/external_links"},next:{title:"How We Work",permalink:"/docs/how_we_work"}},p={},u=[],f={toc:u},d="wrapper";function m(e){var t=e.components,r=(0,o.Z)(e,i);return(0,a.kt)(d,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/oclif/core"},"@oclif/core")," - Base library for oclif CLIs or plugins. This can be used directly without the generator."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/oclif/test"},"@oclif/test")," - Test helper for oclif.")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f6c5328e.1bc5a218.js b/assets/js/f6c5328e.1bc5a218.js new file mode 100644 index 00000000..9d93d6d0 --- /dev/null +++ b/assets/js/f6c5328e.1bc5a218.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5125],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),d=a,f=u["".concat(s,".").concat(d)]||u[d]||m[d]||i;return n?o.createElement(f,r(r({ref:t},p),{},{components:n})):o.createElement(f,r({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,r=new Array(i);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:a,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>u});var o=n(7462),a=n(3366),i=(n(7294),n(3905)),r=["components"],l={title:"Hooks"},s=void 0,c={unversionedId:"hooks",id:"hooks",title:"Hooks",description:"oclif exposes lifecycle event hooks such as init and commandnotfound. See below for a list of all the lifecycle events. In addition to these built-in events, you can create your own events and allow commands/plugins to watch for these custom events. It's a great way to allow multiple plugins to interact with each other.",source:"@site/../docs/hooks.md",sourceDirName:".",slug:"/hooks",permalink:"/docs/hooks",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/hooks.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Hooks"},sidebar:"docs",previous:{title:"Topic Separators",permalink:"/docs/topic_separator"},next:{title:"Plugins",permalink:"/docs/plugins"}},p={},u=[{value:"Lifecycle Events",id:"lifecycle-events",level:2},{value:"Custom Events",id:"custom-events",level:2}],m={toc:u},d="wrapper";function f(e){var t=e.components,n=(0,a.Z)(e,r);return(0,i.kt)(d,(0,o.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"oclif exposes lifecycle event hooks such as ",(0,i.kt)("inlineCode",{parentName:"p"},"init")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"command_not_found"),". ",(0,i.kt)("a",{parentName:"p",href:"#lifecycle-events"},"See below for a list of all the lifecycle events"),". In addition to these built-in events, you can create your own events and allow commands/plugins to watch for these custom events. It's a great way to allow multiple plugins to interact with each other."),(0,i.kt)("p",null,"Multiple hooks are run in parallel. ",(0,i.kt)("strong",{parentName:"p"},"This behavior may change in a future release.")),(0,i.kt)("p",null,"A basic hook looks like the following in TypeScript:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Hook} from '@oclif/core'\n\nconst hook: Hook<'init'> = async function (options) {\n console.log(`example init hook running before ${options.id}`)\n}\n\nexport default hook\n")),(0,i.kt)("p",null,"The hook must also be declared with the event's name and hook's file path under oclif's settings in ",(0,i.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},' "oclif": {\n "commands": "./lib/commands",\n "hooks": {\n "init": "./lib/hooks/init/example"\n }\n }\n')),(0,i.kt)("p",null,"Multiple hooks of the same event type can be declared with an array."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},' "oclif": {\n "commands": "./lib/commands",\n "hooks": {\n "init": [\n "./lib/hooks/init/example",\n "./lib/hooks/init/another_hook"\n ]\n }\n }\n')),(0,i.kt)("p",null,"You can create hooks with ",(0,i.kt)("inlineCode",{parentName:"p"},"oclif generate hook myhook --event=init"),"."),(0,i.kt)("h2",{id:"lifecycle-events"},"Lifecycle Events"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"init")," - runs when the CLI is initialized before a command is found to run"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"prerun")," - runs after ",(0,i.kt)("inlineCode",{parentName:"li"},"init")," and after the command is found, but just before running the command itself"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"postrun")," - runs after the command only if the command finishes with no error"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"command_not_found")," - runs if a command is not found before the error is displayed")),(0,i.kt)("h2",{id:"custom-events"},"Custom Events"),(0,i.kt)("p",null,"Custom events are just like lifecycle events, but you need to call ",(0,i.kt)("inlineCode",{parentName:"p"},"this.config.runHook()")," to fire the event."),(0,i.kt)("p",null,"For example, you could define an analytics post function that you will run in your command after submitting analytics telemetry. First define:"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"src/hooks/analytics/post.ts")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"const hook = async function (options: {id: string}) {\n // code to post options.id to analytics server\n}\n\nexport default hook\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"package.json")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},' "oclif": {\n "commands": "./lib/commands",\n "hooks": {\n "analytics": "./lib/hooks/analytics/post"\n },\n },\n')),(0,i.kt)("p",null,"Then in any command you want to trigger the event:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},"export class extends Command {\n async run() {\n // emit analytics\n await this.config.runHook('analytics', {id: 'my_command'})\n }\n}\n")),(0,i.kt)("p",null,"If you need to exit during a hook, use ",(0,i.kt)("inlineCode",{parentName:"p"},"this.error()")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"this.exit()"),". Otherwise the hook will just emit a warning. This is to prevent an issue such as a plugin failing in ",(0,i.kt)("inlineCode",{parentName:"p"},"init")," causing the entire CLI to not function."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f6c5328e.e20f6ee5.js b/assets/js/f6c5328e.e20f6ee5.js deleted file mode 100644 index 210bbebd..00000000 --- a/assets/js/f6c5328e.e20f6ee5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[5125],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(n),d=a,f=u["".concat(s,".").concat(d)]||u[d]||m[d]||i;return n?o.createElement(f,r(r({ref:t},p),{},{components:n})):o.createElement(f,r({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,r=new Array(i);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:a,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>u});var o=n(7462),a=n(3366),i=(n(7294),n(3905)),r=["components"],l={title:"Hooks"},s=void 0,c={unversionedId:"hooks",id:"hooks",title:"Hooks",description:"oclif exposes lifecycle event hooks such as init and commandnotfound. See below for a list of all the lifecycle events. In addition to these built-in events, you can create your own events and allow commands/plugins to watch for these custom events. It's a great way to allow multiple plugins to interact with each other.",source:"@site/../docs/hooks.md",sourceDirName:".",slug:"/hooks",permalink:"/docs/hooks",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/hooks.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Hooks"},sidebar:"docs",previous:{title:"Topic Separators",permalink:"/docs/topic_separator"},next:{title:"Plugins",permalink:"/docs/plugins"}},p={},u=[{value:"Lifecycle Events",id:"lifecycle-events",level:2},{value:"Custom Events",id:"custom-events",level:2}],m={toc:u},d="wrapper";function f(e){var t=e.components,n=(0,a.Z)(e,r);return(0,i.kt)(d,(0,o.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"oclif exposes lifecycle event hooks such as ",(0,i.kt)("inlineCode",{parentName:"p"},"init")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"command_not_found"),". ",(0,i.kt)("a",{parentName:"p",href:"#lifecycle-events"},"See below for a list of all the lifecycle events"),". In addition to these built-in events, you can create your own events and allow commands/plugins to watch for these custom events. It's a great way to allow multiple plugins to interact with each other."),(0,i.kt)("p",null,"Multiple hooks are run in parallel. ",(0,i.kt)("strong",{parentName:"p"},"This behavior may change in a future release.")),(0,i.kt)("p",null,"A basic hook looks like the following in TypeScript:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"import {Hook} from '@oclif/core'\n\nconst hook: Hook<'init'> = async function (options) {\n console.log(`example init hook running before ${options.id}`)\n}\n\nexport default hook\n")),(0,i.kt)("p",null,"The hook must also be declared with the event's name and hook's file path under oclif's settings in ",(0,i.kt)("inlineCode",{parentName:"p"},"package.json"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},' "oclif": {\n "commands": "./lib/commands",\n "hooks": {\n "init": "./lib/hooks/init/example"\n }\n }\n')),(0,i.kt)("p",null,"Multiple hooks of the same event type can be declared with an array."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},' "oclif": {\n "commands": "./lib/commands",\n "hooks": {\n "init": [\n "./lib/hooks/init/example",\n "./lib/hooks/init/another_hook"\n ]\n }\n }\n')),(0,i.kt)("p",null,"You can create hooks with ",(0,i.kt)("inlineCode",{parentName:"p"},"oclif generate hook myhook --event=init"),"."),(0,i.kt)("h2",{id:"lifecycle-events"},"Lifecycle Events"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"init")," - runs when the CLI is initialized before a command is found to run"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"prerun")," - runs after ",(0,i.kt)("inlineCode",{parentName:"li"},"init")," and after the command is found, but just before running the command itself"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"postrun")," - runs after the command only if the command finishes with no error"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"command_not_found")," - runs if a command is not found before the error is displayed")),(0,i.kt)("h2",{id:"custom-events"},"Custom Events"),(0,i.kt)("p",null,"Custom events are just like lifecycle events, but you need to call ",(0,i.kt)("inlineCode",{parentName:"p"},"this.config.runHook()")," to fire the event."),(0,i.kt)("p",null,"For example, you could define an analytics post function that you will run in your command after submitting analytics telemetry. First define:"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"src/hooks/analytics/post.ts")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-typescript"},"const hook = async function (options: {id: string}) {\n // code to post options.id to analytics server\n}\n\nexport default hook\n")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"package.json")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},' "oclif": {\n "commands": "./lib/commands",\n "hooks": {\n "analytics": "./lib/hooks/analytics/post"\n },\n },\n')),(0,i.kt)("p",null,"Then in any command you want to trigger the event:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},"export class extends Command {\n async run() {\n // emit analytics\n await this.config.runHook('analytics', {id: 'my_command'})\n }\n}\n")),(0,i.kt)("p",null,"If you need to exit during a hook, use ",(0,i.kt)("inlineCode",{parentName:"p"},"this.error()")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"this.exit()"),". Otherwise the hook will just emit a warning. This is to prevent an issue such as a plugin failing in ",(0,i.kt)("inlineCode",{parentName:"p"},"init")," causing the entire CLI to not function."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f905d0fe.6d326dc9.js b/assets/js/f905d0fe.885fd06e.js similarity index 77% rename from assets/js/f905d0fe.6d326dc9.js rename to assets/js/f905d0fe.885fd06e.js index ae2b25e8..86176269 100644 --- a/assets/js/f905d0fe.6d326dc9.js +++ b/assets/js/f905d0fe.885fd06e.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1342],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),m=s(n),d=o,f=m["".concat(l,".").concat(d)]||m[d]||p[d]||a;return n?r.createElement(f,c(c({ref:t},u),{},{components:n})):r.createElement(f,c({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,c=new Array(a);c[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[m]="string"==typeof e?e:o,c[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>f,frontMatter:()=>i,metadata:()=>s,toc:()=>m});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),c=["components"],i={title:"Command Execution"},l=void 0,s={unversionedId:"command_execution",id:"command_execution",title:"Command Execution",description:"Below is a diagram that outlines at a high level the process that occurs every time a user executes an oclif command.",source:"@site/../docs/command_execution.md",sourceDirName:".",slug:"/command_execution",permalink:"/docs/command_execution",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/command_execution.md",tags:[],version:"current",lastUpdatedBy:"Willhoit",lastUpdatedAt:1694207576,formattedLastUpdatedAt:"Sep 8, 2023",frontMatter:{title:"Command Execution"},sidebar:"docs",previous:{title:"Generator Commands",permalink:"/docs/generator_commands"},next:{title:"Plugin Loading",permalink:"/docs/plugin_loading"}},u={},m=[],p={toc:m},d="wrapper";function f(e){var t=e.components,i=(0,o.Z)(e,c);return(0,a.kt)(d,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Below is a diagram that outlines at a high level the process that occurs every time a user executes an oclif command."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"command execution flow",src:n(1799).Z,width:"3258",height:"4910"})))}f.isMDXComponent=!0},1799:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/command-execution-flow-7722f834b51111bcf89f6c2f7ae2cdf5.jpg"}}]); \ No newline at end of file +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[1342],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),m=s(n),d=o,f=m["".concat(l,".").concat(d)]||m[d]||p[d]||a;return n?r.createElement(f,c(c({ref:t},u),{},{components:n})):r.createElement(f,c({ref:t},u))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,c=new Array(a);c[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[m]="string"==typeof e?e:o,c[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>f,frontMatter:()=>i,metadata:()=>s,toc:()=>m});var r=n(7462),o=n(3366),a=(n(7294),n(3905)),c=["components"],i={title:"Command Execution"},l=void 0,s={unversionedId:"command_execution",id:"command_execution",title:"Command Execution",description:"Below is a diagram that outlines at a high level the process that occurs every time a user executes an oclif command.",source:"@site/../docs/command_execution.md",sourceDirName:".",slug:"/command_execution",permalink:"/docs/command_execution",draft:!1,editUrl:"https://github.com/oclif/oclif.github.io/tree/docs/docs/../docs/command_execution.md",tags:[],version:"current",lastUpdatedBy:"Mike Donnalley",lastUpdatedAt:1695753856,formattedLastUpdatedAt:"Sep 26, 2023",frontMatter:{title:"Command Execution"},sidebar:"docs",previous:{title:"Generator Commands",permalink:"/docs/generator_commands"},next:{title:"Plugin Loading",permalink:"/docs/plugin_loading"}},u={},m=[],p={toc:m},d="wrapper";function f(e){var t=e.components,i=(0,o.Z)(e,c);return(0,a.kt)(d,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Below is a diagram that outlines at a high level the process that occurs every time a user executes an oclif command."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"command execution flow",src:n(1799).Z,width:"3258",height:"4910"})))}f.isMDXComponent=!0},1799:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/command-execution-flow-7722f834b51111bcf89f6c2f7ae2cdf5.jpg"}}]); \ No newline at end of file diff --git a/assets/js/main.07d16250.js b/assets/js/main.07d16250.js new file mode 100644 index 00000000..5ebded80 --- /dev/null +++ b/assets/js/main.07d16250.js @@ -0,0 +1,2 @@ +/*! For license information please see main.07d16250.js.LICENSE.txt */ +(self.webpackChunk=self.webpackChunk||[]).push([[179],{830:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});var r=n(7294);function a(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),l=n(6887);const s={"0085e091":[function(){return n.e(5445).then(n.bind(n,3454))},"@site/blog/2018-03-20-introducing-oclif.md?truncated=true",3454],"03a88bad":[function(){return n.e(6568).then(n.bind(n,7989))},"@site/../docs/index.md",7989],"03abeb31":[function(){return n.e(1660).then(n.bind(n,2251))},"@site/../docs/debugging.md",2251],"04855d6d":[function(){return n.e(9544).then(n.bind(n,3939))},"@site/blog/2019-02-20-cli-flags-explained.md",3939],"0b218a01":[function(){return n.e(3321).then(n.bind(n,9993))},"@site/../docs/aliases.md",9993],"104cbb75":[function(){return n.e(3316).then(n.bind(n,269))},"@site/../docs/flexible_taxonomy.md",269],"169e66bc":[function(){return n.e(1369).then(n.bind(n,4577))},"@site/blog/2022-01-12-announcing-oclif-v2.md",4577],17896441:[function(){return Promise.all([n.e(532),n.e(394),n.e(7918)]).then(n.bind(n,8945))},"@theme/DocItem",8945],"19fd9079":[function(){return n.e(8925).then(n.bind(n,2933))},"@site/../docs/external_links.md",2933],"1a4e3797":[function(){return Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,9172))},"@theme/SearchPage",9172],"1be78505":[function(){return Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963))},"@theme/DocPage",9963],"1d5c88f5":[function(){return n.e(5901).then(n.bind(n,9321))},"@site/blog/2019-02-20-cli-flags-explained.md?truncated=true",9321],"1ed4142b":[function(){return n.e(3725).then(n.bind(n,5949))},"@site/../docs/jit_plugins.md",5949],"1f61ef73":[function(){return n.e(7006).then(n.bind(n,9854))},"@site/../docs/error_handling.md",9854],"2486267b":[function(){return n.e(9562).then(n.bind(n,6432))},"@site/../docs/spinner.md",6432],"253cd3dc":[function(){return n.e(3459).then(n.bind(n,5804))},"@site/blog/2022-01-12-announcing-oclif-v2.md?truncated=true",5804],"258a6413":[function(){return n.e(2265).then(n.bind(n,5834))},"@site/../docs/single_command_cli.md",5834],"28395ba4":[function(){return n.e(4299).then(n.t.bind(n,3769,19))},"/home/runner/work/oclif.github.io/oclif.github.io/website/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"2a33acc4":[function(){return n.e(9244).then(n.bind(n,7730))},"@site/../docs/topics.md",7730],"2f98ad87":[function(){return n.e(2048).then(n.bind(n,2320))},"@site/../docs/generator_commands.md",2320],"3042343a":[function(){return n.e(5917).then(n.bind(n,1587))},"@site/../docs/flags.md",1587],32060389:[function(){return n.e(7905).then(n.bind(n,7985))},"@site/../docs/table.md",7985],"35586d92":[function(){return n.e(1160).then(n.bind(n,9046))},"@site/../docs/plugin_loading.md",9046],"3ba497c2":[function(){return n.e(2728).then(n.t.bind(n,5745,19))},"/home/runner/work/oclif.github.io/oclif.github.io/website/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],"3bc14f20":[function(){return n.e(4026).then(n.t.bind(n,4469,19))},"/home/runner/work/oclif.github.io/oclif.github.io/website/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",4469],"3e452c7e":[function(){return n.e(637).then(n.bind(n,3562))},"@site/../docs/base_class.md",3562],"49140ced":[function(){return n.e(7591).then(n.bind(n,8743))},"@site/blog/2019-10-31-oclif-node-updates.md?truncated=true",8743],"4fdccd00":[function(){return n.e(3118).then(n.bind(n,4328))},"@site/blog/2018-03-20-introducing-oclif.md",4328],"53e18611":[function(){return n.e(8349).then(n.bind(n,7780))},"@site/../docs/introduction.md",7780],"5d5620c4":[function(){return n.e(1926).then(n.bind(n,6176))},"@site/../docs/esm.md",6176],"5e9f5e1a":[function(){return Promise.resolve().then(n.bind(n,6809))},"@generated/docusaurus.config",6809],"5f98988e":[function(){return n.e(3807).then(n.bind(n,885))},"@site/blog/2019-12-05-oclif-eslint-migration.md?truncated=true",885],"6de0e435":[function(){return n.e(6079).then(n.bind(n,4064))},"@site/blog/2020-05-05-introducing-custom-help-classes.md",4064],"6f3bb722":[function(){return n.e(8504).then(n.bind(n,5173))},"@site/../docs/commands.md",5173],"713bb917":[function(){return n.e(187).then(n.bind(n,3547))},"@site/../docs/releasing.md",3547],"765c6b61":[function(){return n.e(4535).then(n.bind(n,4443))},"@site/blog/2019-10-31-oclif-node-updates.md",4443],"7b0e8dfa":[function(){return n.e(9280).then(n.bind(n,3890))},"@site/blog/2020-08-26-summer-update.md?truncated=true",3890],"7bd58895":[function(){return n.e(257).then(n.bind(n,2210))},"@site/../docs/prompting.md",2210],"814f3328":[function(){return n.e(2535).then(n.t.bind(n,5641,19))},"~blog/default/blog-post-list-prop-default.json",5641],"82247a8b":[function(){return n.e(2026).then(n.bind(n,9353))},"@site/../docs/config.md",9353],"853133bb":[function(){return n.e(2796).then(n.bind(n,5524))},"@site/blog/2019-12-05-oclif-eslint-migration.md",5524],"8705a681":[function(){return n.e(2863).then(n.bind(n,1423))},"@site/../docs/running_programmatically.md",1423],"935116ff":[function(){return n.e(2638).then(n.bind(n,3048))},"@site/../docs/faqs.md",3048],"935f2afb":[function(){return n.e(53).then(n.t.bind(n,1109,19))},"~docs/default/version-current-metadata-prop-751.json",1109],"958c0a42":[function(){return n.e(3261).then(n.bind(n,2818))},"@site/blog/2020-05-05-introducing-custom-help-classes.md?truncated=true",2818],"9e4087bc":[function(){return n.e(3608).then(n.bind(n,3169))},"@theme/BlogArchivePage",3169],"9eaa546a":[function(){return n.e(8059).then(n.bind(n,2127))},"@site/../docs/features.md",2127],a6aa9e1f:[function(){return Promise.all([n.e(532),n.e(394),n.e(6048),n.e(3089)]).then(n.bind(n,3269))},"@theme/BlogListPage",3269],a92e169d:[function(){return n.e(6332).then(n.bind(n,6100))},"@site/../docs/global_flags.md",6100],a96ec439:[function(){return n.e(6731).then(n.bind(n,1230))},"@site/../docs/notifications.md",1230],b2b675dd:[function(){return n.e(533).then(n.t.bind(n,8017,19))},"~blog/default/blog-c06.json",8017],b2f554cd:[function(){return n.e(1477).then(n.t.bind(n,10,19))},"~blog/default/blog-archive-80c.json",10],b3cc73c6:[function(){return n.e(9638).then(n.bind(n,5217))},"@site/../docs/how_we_work.md",5217],b439faf3:[function(){return n.e(6109).then(n.bind(n,2068))},"@site/blog/2020-08-26-summer-update.md",2068],b4a95747:[function(){return n.e(5289).then(n.bind(n,8821))},"@site/../docs/json.md",8821],bc0981ca:[function(){return n.e(4117).then(n.t.bind(n,7085,19))},"/home/runner/work/oclif.github.io/oclif.github.io/website/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],c1f37a13:[function(){return n.e(9727).then(n.bind(n,5495))},"@site/../docs/ES2022.md",5495],c4b40215:[function(){return n.e(3457).then(n.bind(n,4607))},"@site/blog/2021-03-01-introducing-oclif-core.md?truncated=true",4607],c4f5d8e4:[function(){return n.e(4195).then(n.bind(n,2841))},"@site/src/pages/index.js",2841],c637b865:[function(){return n.e(5575).then(n.bind(n,6324))},"@site/blog/2020-07-01-pretty-printable-errors.md",6324],c81fd975:[function(){return n.e(9310).then(n.bind(n,1363))},"@site/../docs/testing.md",1363],c94a68c1:[function(){return n.e(9147).then(n.bind(n,7384))},"@site/../docs/args.md",7384],ccc49370:[function(){return Promise.all([n.e(532),n.e(394),n.e(6048),n.e(6103)]).then(n.bind(n,5203))},"@theme/BlogPostPage",5203],d0e73d62:[function(){return n.e(2134).then(n.bind(n,909))},"@site/../docs/nsis-installer_customization.md",909],d665a578:[function(){return n.e(9510).then(n.bind(n,974))},"@site/../docs/examples.md",974],d9b0bdb4:[function(){return n.e(5933).then(n.bind(n,3069))},"@site/../docs/feedback.md",3069],df1cd967:[function(){return n.e(2712).then(n.bind(n,1783))},"@site/../docs/topic_separator.md",1783],e2e9d59a:[function(){return n.e(7755).then(n.bind(n,9269))},"@site/blog/2020-07-01-pretty-printable-errors.md?truncated=true",9269],e360e27f:[function(){return n.e(5990).then(n.bind(n,8101))},"@site/../docs/plugins.md",8101],e3703649:[function(){return n.e(5679).then(n.bind(n,1700))},"@site/../docs/help_classes.md",1700],f182954c:[function(){return n.e(182).then(n.bind(n,904))},"@site/../docs/related_repos.md",904],f6c5328e:[function(){return n.e(5125).then(n.bind(n,9941))},"@site/../docs/hooks.md",9941],f85046f2:[function(){return n.e(3797).then(n.bind(n,1312))},"@site/blog/2021-03-01-introducing-oclif-core.md",1312],f905d0fe:[function(){return n.e(1342).then(n.bind(n,6393))},"@site/../docs/command_execution.md",6393]};function u(e){var t=e.error,n=e.retry,a=e.pastDelay;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var c=n(9670),d=n(226);function f(e,t){if("*"===e)return i()({loading:u,loader:function(){return n.e(4972).then(n.bind(n,4972))},modules:["@theme/NotFound"],webpack:function(){return[4972]},render:function(e,t){var n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});var o=l[e+"-"+t],f={},p=[],m=[],h=(0,c.Z)(o);return Object.entries(h).forEach((function(e){var t=e[0],n=e[1],r=s[n];r&&(f[t]=r[0],p.push(r[1]),m.push(r[2]))})),i().Map({loading:u,loader:f,modules:p,webpack:function(){return m},render:function(t,n){var i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((function(t){var n=t[0],r=t[1],a=r.default;if(!a)throw new Error("The page component at "+e+" doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.");"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((function(e){return"default"!==e})).forEach((function(e){a[e]=r[e]}));var o=i,l=n.split(".");l.slice(0,-1).forEach((function(e){o=o[e]})),o[l[l.length-1]]=a}));var l=i.__comp;delete i.__comp;var s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,a.Z)({},i,n)))}})}const p=[{path:"/blog",component:f("/blog","37d"),exact:!0},{path:"/blog/2018/03/20/introducing-oclif",component:f("/blog/2018/03/20/introducing-oclif","8a9"),exact:!0},{path:"/blog/2019/02/20/cli-flags-explained",component:f("/blog/2019/02/20/cli-flags-explained","881"),exact:!0},{path:"/blog/2019/10/31/oclif-node-updates",component:f("/blog/2019/10/31/oclif-node-updates","1a7"),exact:!0},{path:"/blog/2019/12/05/oclif-eslint-migration",component:f("/blog/2019/12/05/oclif-eslint-migration","a8a"),exact:!0},{path:"/blog/2020/05/05/introducing-custom-help-classes",component:f("/blog/2020/05/05/introducing-custom-help-classes","3ac"),exact:!0},{path:"/blog/2020/07/01/pretty-printable-errors",component:f("/blog/2020/07/01/pretty-printable-errors","6e9"),exact:!0},{path:"/blog/2020/08/26/summer-update",component:f("/blog/2020/08/26/summer-update","0a9"),exact:!0},{path:"/blog/2021/03/01/introducing-oclif-core",component:f("/blog/2021/03/01/introducing-oclif-core","2e9"),exact:!0},{path:"/blog/2022/01/12/announcing-oclif-v2",component:f("/blog/2022/01/12/announcing-oclif-v2","548"),exact:!0},{path:"/blog/archive",component:f("/blog/archive","ced"),exact:!0},{path:"/search",component:f("/search","ffa"),exact:!0},{path:"/docs",component:f("/docs","bc5"),routes:[{path:"/docs/",component:f("/docs/","a6b"),exact:!0},{path:"/docs/aliases",component:f("/docs/aliases","0d8"),exact:!0,sidebar:"docs"},{path:"/docs/args",component:f("/docs/args","9fb"),exact:!0,sidebar:"docs"},{path:"/docs/base_class",component:f("/docs/base_class","c57"),exact:!0,sidebar:"docs"},{path:"/docs/command_execution",component:f("/docs/command_execution","510"),exact:!0,sidebar:"docs"},{path:"/docs/commands",component:f("/docs/commands","96a"),exact:!0,sidebar:"docs"},{path:"/docs/config",component:f("/docs/config","dd2"),exact:!0,sidebar:"docs"},{path:"/docs/debugging",component:f("/docs/debugging","427"),exact:!0,sidebar:"docs"},{path:"/docs/error_handling",component:f("/docs/error_handling","fd2"),exact:!0,sidebar:"docs"},{path:"/docs/ES2022",component:f("/docs/ES2022","e19"),exact:!0,sidebar:"docs"},{path:"/docs/esm",component:f("/docs/esm","903"),exact:!0,sidebar:"docs"},{path:"/docs/examples",component:f("/docs/examples","321"),exact:!0,sidebar:"docs"},{path:"/docs/external_links",component:f("/docs/external_links","bb2"),exact:!0,sidebar:"docs"},{path:"/docs/faqs",component:f("/docs/faqs","ef2"),exact:!0,sidebar:"docs"},{path:"/docs/features",component:f("/docs/features","228"),exact:!0,sidebar:"docs"},{path:"/docs/feedback",component:f("/docs/feedback","0a2"),exact:!0,sidebar:"docs"},{path:"/docs/flags",component:f("/docs/flags","c96"),exact:!0,sidebar:"docs"},{path:"/docs/flexible_taxonomy",component:f("/docs/flexible_taxonomy","2bc"),exact:!0,sidebar:"docs"},{path:"/docs/generator_commands",component:f("/docs/generator_commands","bd4"),exact:!0,sidebar:"docs"},{path:"/docs/global_flags",component:f("/docs/global_flags","52c"),exact:!0,sidebar:"docs"},{path:"/docs/help_classes",component:f("/docs/help_classes","5f9"),exact:!0,sidebar:"docs"},{path:"/docs/hooks",component:f("/docs/hooks","68c"),exact:!0,sidebar:"docs"},{path:"/docs/how_we_work",component:f("/docs/how_we_work","368"),exact:!0,sidebar:"docs"},{path:"/docs/introduction",component:f("/docs/introduction","922"),exact:!0,sidebar:"docs"},{path:"/docs/jit_plugins",component:f("/docs/jit_plugins","d1e"),exact:!0,sidebar:"docs"},{path:"/docs/json",component:f("/docs/json","b5e"),exact:!0,sidebar:"docs"},{path:"/docs/notifications",component:f("/docs/notifications","9aa"),exact:!0,sidebar:"docs"},{path:"/docs/nsis-installer_customization",component:f("/docs/nsis-installer_customization","bcb"),exact:!0,sidebar:"docs"},{path:"/docs/plugin_loading",component:f("/docs/plugin_loading","750"),exact:!0,sidebar:"docs"},{path:"/docs/plugins",component:f("/docs/plugins","fc6"),exact:!0,sidebar:"docs"},{path:"/docs/prompting",component:f("/docs/prompting","721"),exact:!0,sidebar:"docs"},{path:"/docs/related_repos",component:f("/docs/related_repos","435"),exact:!0,sidebar:"docs"},{path:"/docs/releasing",component:f("/docs/releasing","5b4"),exact:!0,sidebar:"docs"},{path:"/docs/running_programmatically",component:f("/docs/running_programmatically","ef2"),exact:!0,sidebar:"docs"},{path:"/docs/single_command_cli",component:f("/docs/single_command_cli","28e"),exact:!0,sidebar:"docs"},{path:"/docs/spinner",component:f("/docs/spinner","947"),exact:!0,sidebar:"docs"},{path:"/docs/table",component:f("/docs/table","c2b"),exact:!0,sidebar:"docs"},{path:"/docs/testing",component:f("/docs/testing","8d8"),exact:!0,sidebar:"docs"},{path:"/docs/topic_separator",component:f("/docs/topic_separator","ac3"),exact:!0,sidebar:"docs"},{path:"/docs/topics",component:f("/docs/topics","704"),exact:!0,sidebar:"docs"}]},{path:"/",component:f("/","d94"),exact:!0},{path:"*",component:f("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294),a=r.createContext(!1);function o(e){var t=e.children,n=(0,r.useState)(!1),o=n[0],i=n[1];return(0,r.useEffect)((function(){i(!0)}),[]),r.createElement(a.Provider,{value:o},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),l=n(412);const s=[n(2497),n(3310),n(8320),n(2295)];var u=n(723),c=n(6550),d=n(8790);function f(e){var t=e.children;return r.createElement(r.Fragment,null,t)}var p=n(7462),m=n(5742),h=n(2263),g=n(4996),v=n(6668),b=n(833),y=n(4711),w=n(9727),k=n(3320),E=n(197);function S(){var e=(0,h.Z)().i18n,t=e.defaultLocale,n=e.localeConfigs,a=(0,y.l)();return r.createElement(m.Z,null,Object.entries(n).map((function(e){var t=e[0],n=e[1].htmlLang;return r.createElement("link",{key:t,rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:n})})),r.createElement("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}))}function x(e){var t=e.permalink,n=(0,h.Z)().siteConfig.url,a=function(){var e=(0,h.Z)().siteConfig.url,t=(0,c.TH)().pathname;return e+(0,g.Z)(t)}(),o=t?""+n+t:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function _(){var e=(0,h.Z)().i18n.currentLocale,t=(0,v.L)(),n=t.metadata,a=t.image;return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),a&&r.createElement(b.d,{image:a}),r.createElement(x,null),r.createElement(S,null),r.createElement(E.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,n.map((function(e,t){return r.createElement("meta",(0,p.Z)({key:t},e))}))))}var C=new Map;function T(e){if(C.has(e.pathname))return Object.assign({},e,{pathname:C.get(e.pathname)});if((0,d.f)(u.Z,e.pathname).some((function(e){return!0===e.route.exact})))return C.set(e.pathname,e.pathname),e;var t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),Object.assign({},e,{pathname:t})}var A=n(8934),L=n(8940),R=n(4578);function O(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = '+e+" "+("/"===e?" (default value)":"")+'

\n

We suggest trying baseUrl =

\n\n'}(e)).replace(/{"use strict";n.d(t,{_:()=>c,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"index","docs":[{"id":"aliases","path":"/docs/aliases","sidebar":"docs"},{"id":"args","path":"/docs/args","sidebar":"docs"},{"id":"base_class","path":"/docs/base_class","sidebar":"docs"},{"id":"command_execution","path":"/docs/command_execution","sidebar":"docs"},{"id":"commands","path":"/docs/commands","sidebar":"docs"},{"id":"config","path":"/docs/config","sidebar":"docs"},{"id":"debugging","path":"/docs/debugging","sidebar":"docs"},{"id":"error_handling","path":"/docs/error_handling","sidebar":"docs"},{"id":"ES2022","path":"/docs/ES2022","sidebar":"docs"},{"id":"esm","path":"/docs/esm","sidebar":"docs"},{"id":"examples","path":"/docs/examples","sidebar":"docs"},{"id":"external_links","path":"/docs/external_links","sidebar":"docs"},{"id":"faqs","path":"/docs/faqs","sidebar":"docs"},{"id":"features","path":"/docs/features","sidebar":"docs"},{"id":"feedback","path":"/docs/feedback","sidebar":"docs"},{"id":"flags","path":"/docs/flags","sidebar":"docs"},{"id":"flexible_taxonomy","path":"/docs/flexible_taxonomy","sidebar":"docs"},{"id":"generator_commands","path":"/docs/generator_commands","sidebar":"docs"},{"id":"global_flags","path":"/docs/global_flags","sidebar":"docs"},{"id":"help_classes","path":"/docs/help_classes","sidebar":"docs"},{"id":"hooks","path":"/docs/hooks","sidebar":"docs"},{"id":"how_we_work","path":"/docs/how_we_work","sidebar":"docs"},{"id":"index","path":"/docs/"},{"id":"introduction","path":"/docs/introduction","sidebar":"docs"},{"id":"jit_plugins","path":"/docs/jit_plugins","sidebar":"docs"},{"id":"json","path":"/docs/json","sidebar":"docs"},{"id":"notifications","path":"/docs/notifications","sidebar":"docs"},{"id":"nsis-installer_customization","path":"/docs/nsis-installer_customization","sidebar":"docs"},{"id":"plugin_loading","path":"/docs/plugin_loading","sidebar":"docs"},{"id":"plugins","path":"/docs/plugins","sidebar":"docs"},{"id":"prompting","path":"/docs/prompting","sidebar":"docs"},{"id":"related_repos","path":"/docs/related_repos","sidebar":"docs"},{"id":"releasing","path":"/docs/releasing","sidebar":"docs"},{"id":"running_programmatically","path":"/docs/running_programmatically","sidebar":"docs"},{"id":"single_command_cli","path":"/docs/single_command_cli","sidebar":"docs"},{"id":"spinner","path":"/docs/spinner","sidebar":"docs"},{"id":"table","path":"/docs/table","sidebar":"docs"},{"id":"testing","path":"/docs/testing","sidebar":"docs"},{"id":"topic_separator","path":"/docs/topic_separator","sidebar":"docs"},{"id":"topics","path":"/docs/topics","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/introduction","label":"introduction"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"2.4.1","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.4.1"}}}');var u={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},c=r.createContext(u);function d(e){var t=e.children;return r.createElement(c.Provider,{value:u},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(4578),a=n(7294),o=n(412),i=n(5742),l=n(8780),s=n(7452);function u(e){var t=e.error,n=e.tryAgain;return a.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},a.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),a.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),a.createElement(c,{error:t}))}function c(e){var t=e.error,n=(0,l.getErrorCausalChain)(t).map((function(e){return e.message})).join("\n\nCause:\n");return a.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function d(e){var t=e.error,n=e.tryAgain;return a.createElement(p,{fallback:function(){return a.createElement(u,{error:t,tryAgain:n})}},a.createElement(i.Z,null,a.createElement("title",null,"Page Error")),a.createElement(s.Z,null,a.createElement(u,{error:t,tryAgain:n})))}var f=function(e){return a.createElement(d,e)},p=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={error:null},n}(0,r.Z)(t,e);var n=t.prototype;return n.componentDidCatch=function(e){o.Z.canUseDOM&&this.setState({error:e})},n.render=function(){var e=this,t=this.props.children,n=this.state.error;if(n){var r,a={error:n,tryAgain:function(){return e.setState({error:null})}};return(null!=(r=this.props.fallback)?r:f)(a)}return null!=t?t:null},t}(a.Component)},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document;const a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>h});var r=n(7462),a=n(3366),o=n(7294),i=n(3727),l=n(8780),s=n(2263),u=n(3919),c=n(412),d=o.createContext({collectLink:function(){}});var f=n(4996),p=["isNavLink","to","href","activeClassName","isActive","data-noBrokenLinkCheck","autoAddBaseUrl"];function m(e,t){var n,m,h=e.isNavLink,g=e.to,v=e.href,b=e.activeClassName,y=e.isActive,w=e["data-noBrokenLinkCheck"],k=e.autoAddBaseUrl,E=void 0===k||k,S=(0,a.Z)(e,p),x=(0,s.Z)().siteConfig,_=x.trailingSlash,C=x.baseUrl,T=(0,f.C)().withBaseUrl,A=(0,o.useContext)(d),L=(0,o.useRef)(null);(0,o.useImperativeHandle)(t,(function(){return L.current}));var R=g||v;var O,P=(0,u.Z)(R),N=null==R?void 0:R.replace("pathname://",""),I=void 0!==N?(O=N,E&&function(e){return e.startsWith("/")}(O)?T(O):O):void 0;I&&P&&(I=(0,l.applyTrailingSlash)(I,{trailingSlash:_,baseUrl:C}));var D=(0,o.useRef)(!1),M=h?i.OL:i.rU,B=c.Z.canUseIntersectionObserver,F=(0,o.useRef)(),j=function(){D.current||null==I||(window.docusaurus.preload(I),D.current=!0)};(0,o.useEffect)((function(){return!B&&P&&null!=I&&window.docusaurus.prefetch(I),function(){B&&F.current&&F.current.disconnect()}}),[F,I,B,P]);var z=null!=(n=null==(m=I)?void 0:m.startsWith("#"))&&n,U=!I||!P||z;return U||w||A.collectLink(I),U?o.createElement("a",(0,r.Z)({ref:L,href:I},R&&!P&&{target:"_blank",rel:"noopener noreferrer"},S)):o.createElement(M,(0,r.Z)({},S,{onMouseEnter:j,onTouchStart:j,innerRef:function(e){L.current=e,B&&e&&P&&(F.current=new window.IntersectionObserver((function(t){t.forEach((function(t){e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(F.current.unobserve(e),F.current.disconnect(),null!=I&&window.docusaurus.prefetch(I))}))})),F.current.observe(e))},to:I},h&&{isActive:y,activeClassName:b}))}const h=o.forwardRef(m)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,I:()=>l});var r=n(7294);function a(e,t){var n=e.split(/(\{\w+\})/).map((function(e,n){if(n%2==1){var r=null==t?void 0:t[e.slice(1,-1)];if(void 0!==r)return r}return e}));return n.some((function(e){return(0,r.isValidElement)(e)}))?n.map((function(e,t){return(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e})).filter((function(e){return""!==e})):n.join("")}var o=n(7529);function i(e){var t,n,r=e.id,a=e.message;if(void 0===r&&void 0===a)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return null!=(t=null!=(n=o[null!=r?r:a])?n:a)?t:r}function l(e,t){return a(i({message:e.message,id:e.id}),t)}function s(e){var t=e.children,n=e.id,o=e.values;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");var l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});var r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(7294),a=n(2263),o=n(3919);function i(){var e=(0,a.Z)().siteConfig,t=e.baseUrl,n=e.url,i=(0,r.useCallback)((function(e,r){return function(e,t,n,r){var a=void 0===r?{}:r,i=a.forcePrependBaseUrl,l=void 0!==i&&i,s=a.absolute,u=void 0!==s&&s;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(l)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;var c=n.startsWith(t)?n:t+n.replace(/^\//,"");return u?e+c:c}(n,t,e,r)}),[n,t]);return{withBaseUrl:i}}function l(e,t){return void 0===t&&(t={}),(0,i().withBaseUrl)(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=function(e){return"object"==typeof e&&!!e&&Object.keys(e).length>0};function a(e){var t={};return function e(n,a){Object.entries(n).forEach((function(n){var o=n[0],i=n[1],l=a?a+"."+o:o;r(i)?e(i,l):t[l]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294),a=r.createContext(null);function o(e){var t=e.children,n=e.value,o=r.useContext(a),i=(0,r.useMemo)((function(){return function(e){var t=e.parent,n=e.value;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}var r=Object.assign({},t.data,null==n?void 0:n.data);return{plugin:t.plugin,data:r}}({parent:o,value:n})}),[o,n]);return r.createElement(a.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>v,gA:()=>p,WS:()=>m,_r:()=>d,Jo:()=>b,zh:()=>f,yW:()=>g,gB:()=>h});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});var n=(0,a.Z)().globalData[e];if(!n&&t.failfast)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin.');return n}var l=function(e){return e.versions.find((function(e){return e.isLast}))};function s(e,t){var n=l(e);return[].concat(e.versions.filter((function(e){return e!==n})),[n]).find((function(e){return!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})}))}function u(e,t){var n,a,o=s(e,t),i=null==o?void 0:o.docs.find((function(e){return!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})}));return{activeVersion:o,activeDoc:i,alternateDocVersions:i?(n=i.id,a={},e.versions.forEach((function(e){e.docs.forEach((function(t){t.id===n&&(a[e.name]=t)}))})),a):{}}}var c={},d=function(){var e;return null!=(e=i("docusaurus-plugin-content-docs"))?e:c},f=function(e){return function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});var r=i(e),a=null==r?void 0:r[t];if(!a&&n.failfast)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin with id "'+t+'".');return a}("docusaurus-plugin-content-docs",e,{failfast:!0})};function p(e){return void 0===e&&(e={}),function(e,t,n){void 0===n&&(n={});var a=Object.entries(e).sort((function(e,t){return t[1].path.localeCompare(e[1].path)})).find((function(e){var n=e[1];return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error("Can't find active docs plugin for \""+t+'" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: '+Object.values(e).map((function(e){return e.path})).join(", "));return o}(d(),(0,r.TH)().pathname,e)}function m(e){void 0===e&&(e={});var t=p(e),n=(0,r.TH)().pathname;if(t)return{activePlugin:t,activeVersion:s(t.pluginData,n)}}function h(e){return f(e).versions}function g(e){var t=f(e);return l(t)}function v(e){return u(f(e),(0,r.TH)().pathname)}function b(e){return function(e,t){var n=l(e);return{latestDocSuggestion:u(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(f(e),(0,r.TH)().pathname)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate:function(e){var t=e.location,n=e.previousLocation;if(n&&t.pathname!==n.pathname){var r=window.setTimeout((function(){a().start()}),200);return function(){return window.clearTimeout(r)}}},onRouteDidUpdate:function(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r,a,o=n(7410),i=n(6809);r=o.Z,a=i.default.themeConfig.prism.additionalLanguages,globalThis.Prism=r,a.forEach((function(e){n(6726)("./prism-"+e)})),delete globalThis.Prism},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){var t=e.width,n=void 0===t?13.5:t,o=e.height,i=void 0===o?13.5:o;return r.createElement("svg",{width:n,height:i,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7452:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Yt});var r=n(7294),a=n(6010),o=n(4763),i=n(833),l=n(7462),s=n(6550),u=n(5999),c=n(5936),d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){var e=(0,r.useRef)(null),t=(0,s.k6)().action,n=(0,r.useCallback)((function(e){e.preventDefault();var t,n=null!=(t=document.querySelector("main:first-of-type"))?t:document.getElementById(d);n&&f(n)}),[]);return(0,c.S)((function(n){var r=n.location;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}var m=(0,u.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){var t,n=null!=(t=e.children)?t:m,a=p(),o=a.containerRef,i=a.onClick;return r.createElement("div",{ref:o,role:"region","aria-label":m},r.createElement("a",(0,l.Z)({},e,{href:"#"+d,onClick:i}),n))}var g=n(5281),v=n(9727);const b={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(h,{className:b.skipToContent})}var w=n(6668),k=n(9689),E=n(3366),S=["width","height","color","strokeWidth","className"];function x(e){var t=e.width,n=void 0===t?21:t,a=e.height,o=void 0===a?21:a,i=e.color,s=void 0===i?"currentColor":i,u=e.strokeWidth,c=void 0===u?1.2:u,d=(e.className,(0,E.Z)(e,S));return r.createElement("svg",(0,l.Z)({viewBox:"0 0 15 15",width:n,height:o},d),r.createElement("g",{stroke:s,strokeWidth:c},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const _={closeButton:"closeButton_CVFx"};function C(e){return r.createElement("button",(0,l.Z)({type:"button","aria-label":(0,u.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",_.closeButton,e.className)}),r.createElement(x,{width:14,height:14,strokeWidth:3.1}))}const T={content:"content_knG7"};function A(e){var t=(0,w.L)().announcementBar.content;return r.createElement("div",(0,l.Z)({},e,{className:(0,a.Z)(T.content,e.className),dangerouslySetInnerHTML:{__html:t}}))}const L={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function R(){var e=(0,w.L)().announcementBar,t=(0,k.nT)(),n=t.isActive,a=t.close;if(!n)return null;var o=e.backgroundColor,i=e.textColor,l=e.isCloseable;return r.createElement("div",{className:L.announcementBar,style:{backgroundColor:o,color:i},role:"banner"},l&&r.createElement("div",{className:L.announcementBarPlaceholder}),r.createElement(A,{className:L.announcementBarContent}),l&&r.createElement(C,{onClick:a,className:L.announcementBarClose}))}var O=n(3163),P=n(2466);var N=n(9688),I=n(3102),D=r.createContext(null);function M(e){var t,n,a,o,i,l,s,u=e.children,c=(t=(0,O.e)(),n=(0,I.HY)(),a=(0,r.useState)(!1),o=a[0],i=a[1],l=null!==n.component,s=(0,N.D9)(l),(0,r.useEffect)((function(){l&&!s&&i(!0)}),[l,s]),(0,r.useEffect)((function(){l?t.shown||i(!0):i(!1)}),[t.shown,l]),(0,r.useMemo)((function(){return[o,i]}),[o]));return r.createElement(D.Provider,{value:c},u)}function B(e){if(e.component){var t=e.component;return r.createElement(t,e.props)}}function F(){var e=(0,r.useContext)(D);if(!e)throw new N.i6("NavbarSecondaryMenuDisplayProvider");var t=e[0],n=e[1],a=(0,r.useCallback)((function(){return n(!1)}),[n]),o=(0,I.HY)();return(0,r.useMemo)((function(){return{shown:t,hide:a,content:B(o)}}),[a,o,t])}function j(e){var t=e.header,n=e.primaryMenu,o=e.secondaryMenu,i=F().shown;return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var z=n(2949),U=n(2389);function Z(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function q(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function H(e){var t=e.className,n=e.buttonClassName,o=e.value,i=e.onChange,l=(0,U.Z)(),s=(0,u.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,u.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,u.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)($.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",$.toggleButton,!l&&$.toggleButtonDisabled,n),type:"button",onClick:function(){return i("dark"===o?"light":"dark")},disabled:!l,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(Z,{className:(0,a.Z)($.toggleIcon,$.lightToggleIcon)}),r.createElement(q,{className:(0,a.Z)($.toggleIcon,$.darkToggleIcon)})))}const G=r.memo(H),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){var t=e.className,n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,o=(0,z.I)(),i=o.colorMode,l=o.setColorMode;return a?null:r.createElement(G,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:i,onChange:l})}var K=n(1327);function Y(){return r.createElement(K.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Q(){var e=(0,O.e)();return r.createElement("button",{type:"button","aria-label":(0,u.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:function(){return e.toggle()}},r.createElement(x,{color:"var(--ifm-color-emphasis-600)"}))}function X(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(Y,null),r.createElement(W,{className:"margin-right--md"}),r.createElement(Q,null))}var J=n(9960),ee=n(4996),te=n(3919),ne=n(8022),re=n(9471),ae=["activeBasePath","activeBaseRegex","to","href","label","html","isDropdownLink","prependBaseUrlToHref"];function oe(e){var t=e.activeBasePath,n=e.activeBaseRegex,a=e.to,o=e.href,i=e.label,s=e.html,u=e.isDropdownLink,c=e.prependBaseUrlToHref,d=(0,E.Z)(e,ae),f=(0,ee.Z)(a),p=(0,ee.Z)(t),m=(0,ee.Z)(o,{forcePrependBaseUrl:!0}),h=i&&o&&!(0,te.Z)(o),g=s?{dangerouslySetInnerHTML:{__html:s}}:{children:r.createElement(r.Fragment,null,i,h&&r.createElement(re.Z,u&&{width:12,height:12}))};return o?r.createElement(J.Z,(0,l.Z)({href:c?m:o},d,g)):r.createElement(J.Z,(0,l.Z)({to:f,isNavLink:!0},(t||n)&&{isActive:function(e,t){return n?(0,ne.F)(n,t.pathname):t.pathname.startsWith(p)}},d,g))}var ie=["className","isDropdownItem"],le=["className","isDropdownItem"],se=["mobile","position"];function ue(e){var t=e.className,n=e.isDropdownItem,o=void 0!==n&&n,i=(0,E.Z)(e,ie),s=r.createElement(oe,(0,l.Z)({className:(0,a.Z)(o?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:o},i));return o?r.createElement("li",null,s):s}function ce(e){var t=e.className,n=(e.isDropdownItem,(0,E.Z)(e,le));return r.createElement("li",{className:"menu__list-item"},r.createElement(oe,(0,l.Z)({className:(0,a.Z)("menu__link",t)},n)))}function de(e){var t,n=e.mobile,a=void 0!==n&&n,o=(e.position,(0,E.Z)(e,se)),i=a?ce:ue;return r.createElement(i,(0,l.Z)({},o,{activeClassName:null!=(t=o.activeClassName)?t:a?"menu__link--active":"navbar__link--active"}))}var fe=n(6043),pe=n(8596),me=n(2263);var he=["items","position","className","onClick"],ge=["items","className","position","onClick"],ve=["mobile"];function be(e,t){return e.some((function(e){return function(e,t){return!!(0,pe.Mg)(e.to,t)||!!(0,ne.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)}))}function ye(e){var t,n=e.items,o=e.position,i=e.className,s=(e.onClick,(0,E.Z)(e,he)),u=(0,r.useRef)(null),c=(0,r.useState)(!1),d=c[0],f=c[1];return(0,r.useEffect)((function(){var e=function(e){u.current&&!u.current.contains(e.target)&&f(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),function(){document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[u]),r.createElement("div",{ref:u,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===o,"dropdown--show":d})},r.createElement(oe,(0,l.Z)({"aria-haspopup":"true","aria-expanded":d,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",i)},s,{onClick:s.to?void 0:function(e){return e.preventDefault()},onKeyDown:function(e){"Enter"===e.key&&(e.preventDefault(),f(!d))}}),null!=(t=s.children)?t:s.label),r.createElement("ul",{className:"dropdown__menu"},n.map((function(e,t){return r.createElement(it,(0,l.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))}))))}function we(e){var t,n,o=e.items,i=e.className,u=(e.position,e.onClick),c=(0,E.Z)(e,ge),d=(n=(0,me.Z)().siteConfig.baseUrl,(0,s.TH)().pathname.replace(n,"/")),f=be(o,d),p=(0,fe.u)({initialState:function(){return!f}}),m=p.collapsed,h=p.toggleCollapsed,g=p.setCollapsed;return(0,r.useEffect)((function(){f&&g(!f)}),[d,f,g]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":m})},r.createElement(oe,(0,l.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",i)},c,{onClick:function(e){e.preventDefault(),h()}}),null!=(t=c.children)?t:c.label),r.createElement(fe.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:m},o.map((function(e,t){return r.createElement(it,(0,l.Z)({mobile:!0,isDropdownItem:!0,onClick:u,activeClassName:"menu__link--active"},e,{key:t}))}))))}function ke(e){var t=e.mobile,n=void 0!==t&&t,a=(0,E.Z)(e,ve),o=n?we:ye;return r.createElement(o,a)}var Ee=n(4711),Se=["width","height"];function xe(e){var t=e.width,n=void 0===t?20:t,a=e.height,o=void 0===a?20:a,i=(0,E.Z)(e,Se);return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:n,height:o,"aria-hidden":!0},i),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const _e="iconLanguage_nlXk";var Ce=["mobile","dropdownItemsBefore","dropdownItemsAfter"];function Te(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var Ae=n(830),Le=["translations"];function Re(){return Re=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var Ie="Ctrl";var De=r.forwardRef((function(e,t){var n=e.translations,a=void 0===n?{}:n,o=Ne(e,Le),i=a.buttonText,l=void 0===i?"Search":i,s=a.buttonAriaLabel,u=void 0===s?"Search":s,c=Oe((0,r.useState)(null),2),d=c[0],f=c[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?f("\u2318"):f(Ie))}),[]),r.createElement("button",Re({type:"button",className:"DocSearch DocSearch-Button","aria-label":u},o,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(Ae.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},l)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===Ie?r.createElement(Te,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Me=n(5742),Be=n(6177),Fe=n(239),je=n(3320);var ze=n(3935);const Ue={button:{buttonText:(0,u.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,u.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,u.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,u.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,u.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,u.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,u.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,u.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,u.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,u.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,u.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,u.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,u.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,u.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,u.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,u.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,u.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,u.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,u.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,u.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,u.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,u.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,u.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,u.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,u.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,u.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,u.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};var Ze=["contextualSearch","externalUrlRegex"],qe=null;function $e(e){var t=e.hit,n=e.children;return r.createElement(J.Z,{to:t.url},n)}function He(e){var t=e.state,n=e.onClose,a=(0,Be.M)();return r.createElement(J.Z,{to:a(t.query),onClick:n},r.createElement(u.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits}},"See all {count} results"))}function Ge(e){var t,a,o,i,u,c=e.contextualSearch,d=e.externalUrlRegex,f=(0,E.Z)(e,Ze),p=(0,me.Z)().siteMetadata,m=(0,Fe.l)(),h=["language:"+(o=(0,je._q)()).locale,o.tags.map((function(e){return"docusaurus_tag:"+e}))],g=null!=(t=null==(a=f.searchParameters)?void 0:a.facetFilters)?t:[],v=c?(i=g,[].concat((u=function(e){return"string"==typeof e?[e]:e})(h),u(i))):g,b=Object.assign({},f.searchParameters,{facetFilters:v}),y=(0,s.k6)(),w=(0,r.useRef)(null),k=(0,r.useRef)(null),S=(0,r.useState)(!1),x=S[0],_=S[1],C=(0,r.useState)(void 0),T=C[0],A=C[1],L=(0,r.useCallback)((function(){return qe?Promise.resolve():Promise.all([n.e(1426).then(n.bind(n,1426)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,6945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,8894))]).then((function(e){var t=e[0].DocSearchModal;qe=t}))}),[]),R=(0,r.useCallback)((function(){L().then((function(){w.current=document.createElement("div"),document.body.insertBefore(w.current,document.body.firstChild),_(!0)}))}),[L,_]),O=(0,r.useCallback)((function(){var e;_(!1),null==(e=w.current)||e.remove()}),[_]),P=(0,r.useCallback)((function(e){L().then((function(){_(!0),A(e.key)}))}),[L,_,A]),N=(0,r.useRef)({navigate:function(e){var t=e.itemUrl;(0,ne.F)(d,t)?window.location.href=t:y.push(t)}}).current,I=(0,r.useRef)((function(e){return f.transformItems?f.transformItems(e):e.map((function(e){return Object.assign({},e,{url:m(e.url)})}))})).current,D=(0,r.useMemo)((function(){return function(e){return r.createElement(He,(0,l.Z)({},e,{onClose:O}))}}),[O]),M=(0,r.useCallback)((function(e){return e.addAlgoliaAgent("docusaurus",p.docusaurusVersion),e}),[p.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,a=e.onClose,o=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?a():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&o&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&o(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,a,o,i])}({isOpen:x,onOpen:R,onClose:O,onInput:P,searchButtonRef:k}),r.createElement(r.Fragment,null,r.createElement(Me.Z,null,r.createElement("link",{rel:"preconnect",href:"https://"+f.appId+"-dsn.algolia.net",crossOrigin:"anonymous"})),r.createElement(De,{onTouchStart:L,onFocus:L,onMouseOver:L,onClick:R,ref:k,translations:Ue.button}),x&&qe&&w.current&&(0,ze.createPortal)(r.createElement(qe,(0,l.Z)({onClose:O,initialScrollY:window.scrollY,initialQuery:T,navigator:N,transformItems:I,hitComponent:$e,transformSearchClient:M},f.searchPagePath&&{resultsFooterComponent:D},f,{searchParameters:b,placeholder:Ue.placeholder,translations:Ue.modal})),w.current))}function Ve(){var e=(0,me.Z)().siteConfig;return r.createElement(Ge,e.themeConfig.algolia)}const We={searchBox:"searchBox_ZlJk"};function Ke(e){var t=e.children,n=e.className;return r.createElement("div",{className:(0,a.Z)(n,We.searchBox)},t)}var Ye=n(143),Qe=n(8425),Xe=["docId","label","docsPluginId"];var Je=["sidebarId","label","docsPluginId"];var et=["label","to","docsPluginId"];var tt=n(373),nt=["mobile","docsPluginId","dropdownActiveClassDisabled","dropdownItemsBefore","dropdownItemsAfter"],rt=function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))};const at={default:de,localeDropdown:function(e){var t=e.mobile,n=e.dropdownItemsBefore,a=e.dropdownItemsAfter,o=(0,E.Z)(e,Ce),i=(0,me.Z)().i18n,c=i.currentLocale,d=i.locales,f=i.localeConfigs,p=(0,Ee.l)(),m=(0,s.TH)(),h=m.search,g=m.hash,v=d.map((function(e){var n=""+("pathname://"+p.createUrl({locale:e,fullyQualified:!1}))+h+g;return{label:f[e].label,lang:f[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===c?t?"menu__link--active":"dropdown__link--active":""}})),b=[].concat(n,v,a),y=t?(0,u.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):f[c].label;return r.createElement(ke,(0,l.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(xe,{className:_e}),y),items:b}))},search:function(e){var t=e.mobile,n=e.className;return t?null:r.createElement(Ke,{className:n},r.createElement(Ve,null))},dropdown:ke,html:function(e){var t=e.value,n=e.className,o=e.mobile,i=void 0!==o&&o,l=e.isDropdownItem,s=void 0!==l&&l,u=s?"li":"div";return r.createElement(u,{className:(0,a.Z)({navbar__item:!i&&!s,"menu__list-item":i},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){var t=e.docId,n=e.label,a=e.docsPluginId,o=(0,E.Z)(e,Xe),i=(0,Ye.Iw)(a).activeDoc,s=(0,Qe.vY)(t,a);return null===s?null:r.createElement(de,(0,l.Z)({exact:!0},o,{isActive:function(){return(null==i?void 0:i.path)===s.path||!(null==i||!i.sidebar)&&i.sidebar===s.sidebar},label:null!=n?n:s.id,to:s.path}))},docSidebar:function(e){var t=e.sidebarId,n=e.label,a=e.docsPluginId,o=(0,E.Z)(e,Je),i=(0,Ye.Iw)(a).activeDoc,s=(0,Qe.oz)(t,a).link;if(!s)throw new Error('DocSidebarNavbarItem: Sidebar with ID "'+t+"\" doesn't have anything to be linked to.");return r.createElement(de,(0,l.Z)({exact:!0},o,{isActive:function(){return(null==i?void 0:i.sidebar)===t},label:null!=n?n:s.label,to:s.path}))},docsVersion:function(e){var t=e.label,n=e.to,a=e.docsPluginId,o=(0,E.Z)(e,et),i=(0,Qe.lO)(a)[0],s=null!=t?t:i.label,u=null!=n?n:function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))}(i).path;return r.createElement(de,(0,l.Z)({},o,{label:s,to:u}))},docsVersionDropdown:function(e){var t=e.mobile,n=e.docsPluginId,a=e.dropdownActiveClassDisabled,o=e.dropdownItemsBefore,i=e.dropdownItemsAfter,c=(0,E.Z)(e,nt),d=(0,s.TH)(),f=d.search,p=d.hash,m=(0,Ye.Iw)(n),h=(0,Ye.gB)(n),g=(0,tt.J)(n).savePreferredVersionName,v=h.map((function(e){var t,n=null!=(t=m.alternateDocVersions[e.name])?t:rt(e);return{label:e.label,to:""+n.path+f+p,isActive:function(){return e===m.activeVersion},onClick:function(){return g(e.name)}}})),b=[].concat(o,v,i),y=(0,Qe.lO)(n)[0],w=t&&b.length>1?(0,u.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):y.label,k=t&&b.length>1?void 0:rt(y).path;return b.length<=1?r.createElement(de,(0,l.Z)({},c,{mobile:t,label:w,to:k,isActive:a?function(){return!1}:void 0})):r.createElement(ke,(0,l.Z)({},c,{mobile:t,label:w,to:k,items:b,isActive:a?function(){return!1}:void 0}))}};var ot=["type"];function it(e){var t=e.type,n=(0,E.Z)(e,ot),a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=at[a];if(!o)throw new Error('No NavbarItem component found for type "'+t+'".');return r.createElement(o,n)}function lt(){var e=(0,O.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map((function(t,n){return r.createElement(it,(0,l.Z)({mobile:!0},t,{onClick:function(){return e.toggle()},key:n}))})))}function st(e){return r.createElement("button",(0,l.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(u.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function ut(){var e=0===(0,w.L)().navbar.items.length,t=F();return r.createElement(r.Fragment,null,!e&&r.createElement(st,{onClick:function(){return t.hide()}}),t.content)}function ct(){var e,t=(0,O.e)();return void 0===(e=t.shown)&&(e=!0),(0,r.useEffect)((function(){return document.body.style.overflow=e?"hidden":"visible",function(){document.body.style.overflow="visible"}}),[e]),t.shouldRender?r.createElement(j,{header:r.createElement(X,null),primaryMenu:r.createElement(lt,null),secondaryMenu:r.createElement(ut,null)}):null}const dt={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function ft(e){return r.createElement("div",(0,l.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function pt(e){var t=e.children,n=(0,w.L)().navbar,o=n.hideOnScroll,i=n.style,l=(0,O.e)(),s=function(e){var t=(0,r.useState)(e),n=t[0],a=t[1],o=(0,r.useRef)(!1),i=(0,r.useRef)(0),l=(0,r.useCallback)((function(e){null!==e&&(i.current=e.getBoundingClientRect().height)}),[]);return(0,P.RF)((function(t,n){var r=t.scrollY;if(e)if(r=l?a(!1):r+u0&&r.createElement(Bt,{links:n}),logo:a&&r.createElement(Ut,{logo:a}),copyright:t&&r.createElement(Zt,{copyright:t})})}const Ht=r.memo($t);var Gt=(0,N.Qc)([z.S,k.pl,P.OC,tt.L5,i.VC,function(e){var t=e.children;return r.createElement(I.n2,null,r.createElement(O.M,null,r.createElement(M,null,t)))}]);function Vt(e){var t=e.children;return r.createElement(Gt,null,t)}function Wt(e){var t=e.error,n=e.tryAgain;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(u.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(vt,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(bt,{error:t})))))}const Kt={mainWrapper:"mainWrapper_z2l0"};function Yt(e){var t=e.children,n=e.noFooter,l=e.wrapperClassName,s=e.title,u=e.description;return(0,v.t)(),r.createElement(Vt,null,r.createElement(i.d,{title:s,description:u}),r.createElement(y,null),r.createElement(R,null),r.createElement(At,null),r.createElement("div",{id:d,className:(0,a.Z)(g.k.wrapper.main,Kt.mainWrapper,l)},r.createElement(o.Z,{fallback:function(e){return r.createElement(Wt,e)}},t)),!n&&r.createElement(Ht,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7462),a=n(3366),o=n(7294),i=n(9960),l=n(4996),s=n(2263),u=n(6668),c=n(941),d=["imageClassName","titleClassName"];function f(e){var t=e.logo,n=e.alt,r=e.imageClassName,a={light:(0,l.Z)(t.src),dark:(0,l.Z)(t.srcDark||t.src)},i=o.createElement(c.Z,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?o.createElement("div",{className:r},i):i}function p(e){var t,n=(0,s.Z)().siteConfig.title,c=(0,u.L)().navbar,p=c.title,m=c.logo,h=e.imageClassName,g=e.titleClassName,v=(0,a.Z)(e,d),b=(0,l.Z)((null==m?void 0:m.href)||"/"),y=p?"":n,w=null!=(t=null==m?void 0:m.alt)?t:y;return o.createElement(i.Z,(0,r.Z)({to:b},v,(null==m?void 0:m.target)&&{target:m.target}),m&&o.createElement(f,{logo:m,alt:w,imageClassName:h}),null!=p&&o.createElement("b",{className:g},p))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){var t=e.locale,n=e.version,o=e.tag,i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(3366),o=n(7294),i=n(6010),l=n(2389),s=n(2949);const u={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};var c=["sources","className","alt"];function d(e){var t=(0,l.Z)(),n=(0,s.I)().colorMode,d=e.sources,f=e.className,p=e.alt,m=(0,a.Z)(e,c),h=t?"dark"===n?["dark"]:["light"]:["light","dark"];return o.createElement(o.Fragment,null,h.map((function(e){return o.createElement("img",(0,r.Z)({key:e,src:d[e],alt:p,className:(0,i.Z)(u.themedImage,u["themedImage--"+e],f)},m))})))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>d,z:()=>y});var r=n(7462),a=n(3366),o=n(7294),i=n(412),l=n(1442),s=["collapsed"],u=["lazy"],c="ease-in-out";function d(e){var t=e.initialState,n=(0,o.useState)(null!=t&&t),r=n[0],a=n[1],i=(0,o.useCallback)((function(){a((function(e){return!e}))}),[]);return{collapsed:r,setCollapsed:a,toggleCollapsed:i}}var f={display:"none",overflow:"hidden",height:"0px"},p={display:"block",overflow:"visible",height:"auto"};function m(e,t){var n=t?f:p;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function h(e){var t=e.collapsibleRef,n=e.collapsed,r=e.animation,a=(0,o.useRef)(!1);(0,o.useEffect)((function(){var e,o=t.current;function i(){var e,t,n=o.scrollHeight,a=null!=(e=null==r?void 0:r.duration)?e:function(e){if((0,l.n)())return 1;var t=e/36;return Math.round(10*(4+15*Math.pow(t,.25)+t/5))}(n);return{transition:"height "+a+"ms "+(null!=(t=null==r?void 0:r.easing)?t:c),height:n+"px"}}function s(){var e=i();o.style.transition=e.transition,o.style.height=e.height}if(!a.current)return m(o,n),void(a.current=!0);return o.style.willChange="height",e=requestAnimationFrame((function(){n?(s(),requestAnimationFrame((function(){o.style.height=f.height,o.style.overflow=f.overflow}))):(o.style.display="block",requestAnimationFrame((function(){s()})))})),function(){return cancelAnimationFrame(e)}}),[t,n,r])}function g(e){if(!i.Z.canUseDOM)return e?f:p}function v(e){var t=e.as,n=void 0===t?"div":t,r=e.collapsed,a=e.children,i=e.animation,l=e.onCollapseTransitionEnd,s=e.className,u=e.disableSSRStyle,c=(0,o.useRef)(null);return h({collapsibleRef:c,collapsed:r,animation:i}),o.createElement(n,{ref:c,style:u?void 0:g(r),onTransitionEnd:function(e){"height"===e.propertyName&&(m(c.current,r),null==l||l(r))},className:s},a)}function b(e){var t=e.collapsed,n=(0,a.Z)(e,s),i=(0,o.useState)(!t),l=i[0],u=i[1],c=(0,o.useState)(t),d=c[0],f=c[1];return(0,o.useLayoutEffect)((function(){t||u(!0)}),[t]),(0,o.useLayoutEffect)((function(){l&&f(t)}),[l,t]),l?o.createElement(v,(0,r.Z)({},n,{collapsed:d})):null}function y(e){var t=e.lazy,n=(0,a.Z)(e,u),r=t?b:v;return o.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>p});var r=n(7294),a=n(2389),o=n(12),i=n(9688),l=n(6668),s=(0,o.WA)("docusaurus.announcement.dismiss"),u=(0,o.WA)("docusaurus.announcement.id"),c=function(){return"true"===s.get()},d=function(e){return s.set(String(e))},f=r.createContext(null);function p(e){var t=e.children,n=function(){var e=(0,l.L)().announcementBar,t=(0,a.Z)(),n=(0,r.useState)((function(){return!!t&&c()})),o=n[0],i=n[1];(0,r.useEffect)((function(){i(c())}),[]);var s=(0,r.useCallback)((function(){d(!0),i(!0)}),[]);return(0,r.useEffect)((function(){if(e){var t=e.id,n=u.get();"annoucement-bar"===n&&(n="announcement-bar");var r=t!==n;u.set(t),r&&d(!1),!r&&c()||i(!1)}}),[e]),(0,r.useMemo)((function(){return{isActive:!!e&&!o,close:s}}),[e,o,s])}();return r.createElement(f.Provider,{value:n},t)}function m(){var e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>g,S:()=>h});var r=n(7294),a=n(412),o=n(9688),i=n(12),l=n(6668),s=r.createContext(void 0),u="theme",c=(0,i.WA)(u),d={light:"light",dark:"dark"},f=function(e){return e===d.dark?d.dark:d.light},p=function(e){return a.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e)},m=function(e){c.set(f(e))};function h(e){var t=e.children,n=function(){var e=(0,l.L)().colorMode,t=e.defaultMode,n=e.disableSwitch,a=e.respectPrefersColorScheme,o=(0,r.useState)(p(t)),i=o[0],s=o[1];(0,r.useEffect)((function(){n&&c.del()}),[n]);var h=(0,r.useCallback)((function(e,n){void 0===n&&(n={});var r=n.persist,o=void 0===r||r;e?(s(e),o&&m(e)):(s(a?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:t),c.del())}),[a,t]);(0,r.useEffect)((function(){document.documentElement.setAttribute("data-theme",f(i))}),[i]),(0,r.useEffect)((function(){if(!n){var e=function(e){if(e.key===u){var t=c.get();null!==t&&h(f(t))}};return window.addEventListener("storage",e),function(){return window.removeEventListener("storage",e)}}}),[n,h]);var g=(0,r.useRef)(!1);return(0,r.useEffect)((function(){if(!n||a){var e=window.matchMedia("(prefers-color-scheme: dark)"),t=function(){window.matchMedia("print").matches||g.current?g.current=window.matchMedia("print").matches:h(null)};return e.addListener(t),function(){return e.removeListener(t)}}}),[h,n,a]),(0,r.useMemo)((function(){return{colorMode:i,setColorMode:h,get isDarkTheme(){return i===d.dark},setLightTheme:function(){h(d.light)},setDarkTheme:function(){h(d.dark)}}}),[i,h])}();return r.createElement(s.Provider,{value:n},t)}function g(){var e=(0,r.useContext)(s);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>b,L5:()=>g,Oh:()=>y});var r=n(7294),a=n(143),o=n(9935),i=n(6668),l=n(8425),s=n(9688),u=n(12),c=function(e){return"docs-preferred-version-"+e},d={save:function(e,t,n){(0,u.WA)(c(e),{persistence:t}).set(n)},read:function(e,t){return(0,u.WA)(c(e),{persistence:t}).get()},clear:function(e,t){(0,u.WA)(c(e),{persistence:t}).del()}},f=function(e){return Object.fromEntries(e.map((function(e){return[e,{preferredVersionName:null}]})))};var p=r.createContext(null);function m(){var e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((function(){return Object.keys(e)}),[e]),o=(0,r.useState)((function(){return f(n)})),l=o[0],s=o[1];return(0,r.useEffect)((function(){s(function(e){var t=e.pluginIds,n=e.versionPersistence,r=e.allDocsData;return Object.fromEntries(t.map((function(e){return[e,(t=e,a=d.read(t,n),r[t].versions.some((function(e){return e.name===a}))?{preferredVersionName:a}:(d.clear(t,n),{preferredVersionName:null}))];var t,a})))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]),[l,(0,r.useMemo)((function(){return{savePreferredVersion:function(e,n){d.save(e,t,n),s((function(t){var r;return Object.assign({},t,((r={})[e]={preferredVersionName:n},r))}))}}}),[t])]}function h(e){var t=e.children,n=m();return r.createElement(p.Provider,{value:n},t)}function g(e){var t=e.children;return l.cE?r.createElement(h,null,t):r.createElement(r.Fragment,null,t)}function v(){var e=(0,r.useContext)(p);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function b(e){var t;void 0===e&&(e=o.m);var n=(0,a.zh)(e),i=v(),l=i[0],s=i[1],u=l[e].preferredVersionName;return{preferredVersion:null!=(t=n.versions.find((function(e){return e.name===u})))?t:null,savePreferredVersionName:(0,r.useCallback)((function(t){s.savePreferredVersion(e,t)}),[s,e])}}function y(){var e=(0,a._r)(),t=v()[0];var n=Object.keys(e);return Object.fromEntries(n.map((function(n){return[n,(r=n,o=e[r],i=t[r].preferredVersionName,null!=(a=o.versions.find((function(e){return e.name===i})))?a:null)];var r,a,o,i})))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(7294),a=n(9688),o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){var t=e.children,n=e.name,a=e.items,o=(0,r.useMemo)((function(){return n&&a?{name:n,items:a}:null}),[n,a]);return r.createElement(i.Provider,{value:o},t)}function s(){var e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},3163:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>f});var r=n(7294),a=n(3102),o=n(7524),i=n(1980),l=n(6668),s=n(9688),u=r.createContext(void 0);function c(){var e,t=(e=(0,a.HY)(),0===(0,l.L)().navbar.items.length&&!e.component),n=(0,o.i)(),s=!t&&"mobile"===n,u=(0,r.useState)(!1),c=u[0],d=u[1];(0,i.Rb)((function(){if(c)return d(!1),!1}));var f=(0,r.useCallback)((function(){d((function(e){return!e}))}),[]);return(0,r.useEffect)((function(){"desktop"===n&&d(!1)}),[n]),(0,r.useMemo)((function(){return{disabled:t,shouldRender:s,toggle:f,shown:c}}),[t,s,f,c])}function d(e){var t=e.children,n=c();return r.createElement(u.Provider,{value:n},t)}function f(){var e=r.useContext(u);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(7294),a=n(9688),o=r.createContext(null);function i(e){var t=e.children,n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){var e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){var t=e.component,n=e.props,i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");var l=i[1],s=(0,a.Ql)(n);return(0,r.useEffect)((function(){l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((function(){return function(){return l({component:null,props:null})}}),[l]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294),a="navigation-with-keyboard";function o(){(0,r.useEffect)((function(){function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),function(){document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},6177:(e,t,n)=>{"use strict";n.d(t,{K:()=>l,M:()=>s});var r=n(7294),a=n(2263),o=n(1980),i="q";function l(){return(0,o.Nc)(i)}function s(){var e=(0,a.Z)().siteConfig,t=e.baseUrl,n=e.themeConfig.algolia.searchPagePath;return(0,r.useCallback)((function(e){return""+t+n+"?"+i+"="+encodeURIComponent(e)}),[t,n])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>u});var r=n(7294),a=n(412),o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}var s=!1;function u(){var e=(0,r.useState)((function(){return s?"ssr":l()})),t=e[0],n=e[1];return(0,r.useEffect)((function(){function e(){n(l())}var t=s?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),function(){window.removeEventListener("resize",e),clearTimeout(t)}}),[]),t}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});var r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:function(e){return"theme-admonition-"+e}},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:function(e){return"theme-doc-sidebar-item-category-level-"+e},docSidebarItemLinkLevel:function(e){return"theme-doc-sidebar-item-link-level-"+e}},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},8425:(e,t,n)=>{"use strict";function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[a++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}n.d(t,{Wl:()=>m,_F:()=>v,cE:()=>p,hI:()=>S,lO:()=>w,vY:()=>E,oz:()=>k,s1:()=>y});var o=n(7294),i=n(6550),l=n(8790),s=n(143),u=n(373),c=n(1116);function d(e){return Array.from(new Set(e))}var f=n(8596),p=!!s._r;function m(e){if(e.href)return e.href;for(var t,n=a(e.items);!(t=n()).done;){var r=t.value;if("link"===r.type)return r.href;if("category"===r.type){var o=m(r);if(o)return o}}}var h=function(e,t){return void 0!==e&&(0,f.Mg)(e,t)},g=function(e,t){return e.some((function(e){return v(e,t)}))};function v(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||g(e.items,t))}function b(e){var t=e.sidebarItems,n=e.pathname,r=e.onlyCategories,o=void 0!==r&&r,i=[];return function e(t){for(var r,l=a(t);!(r=l()).done;){var s=r.value;if("category"===s.type&&((0,f.Mg)(s.href,n)||e(s.items))||"link"===s.type&&(0,f.Mg)(s.href,n))return o&&"category"!==s.type||i.unshift(s),!0}return!1}(t),i}function y(){var e,t=(0,c.V)(),n=(0,i.TH)().pathname;return!1!==(null==(e=(0,s.gA)())?void 0:e.pluginData.breadcrumbs)&&t?b({sidebarItems:t.items,pathname:n}):null}function w(e){var t=(0,s.Iw)(e).activeVersion,n=(0,u.J)(e).preferredVersion,r=(0,s.yW)(e);return(0,o.useMemo)((function(){return d([t,n,r].filter(Boolean))}),[t,n,r])}function k(e,t){var n=w(t);return(0,o.useMemo)((function(){var t=n.flatMap((function(e){return e.sidebars?Object.entries(e.sidebars):[]})),r=t.find((function(t){return t[0]===e}));if(!r)throw new Error("Can't find any sidebar with id \""+e+'" in version'+(n.length>1?"s":"")+" "+n.map((function(e){return e.name})).join(", ")+'".\nAvailable sidebar ids are:\n- '+t.map((function(e){return e[0]})).join("\n- "));return r[1]}),[e,n])}function E(e,t){var n=w(t);return(0,o.useMemo)((function(){var t=n.flatMap((function(e){return e.docs})),r=t.find((function(t){return t.id===e}));if(!r){if(n.flatMap((function(e){return e.draftIds})).includes(e))return null;throw new Error("Couldn't find any doc with id \""+e+'" in version'+(n.length>1?"s":"")+' "'+n.map((function(e){return e.name})).join(", ")+'".\nAvailable doc ids are:\n- '+d(t.map((function(e){return e.id}))).join("\n- "))}return r}),[e,n])}function S(e){var t=e.route,n=e.versionMetadata,r=(0,i.TH)(),a=t.routes,o=a.find((function(e){return(0,i.LX)(r.pathname,e)}));if(!o)return null;var s=o.sidebar,u=s?n.docsSidebars[s]:void 0;return{docElement:(0,l.H)(a),sidebarName:s,sidebarItems:u}}},2128:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(2263);function a(e){var t=(0,r.Z)().siteConfig,n=t.title,a=t.titleDelimiter;return null!=e&&e.trim().length?e.trim()+" "+a+" "+n:n}},1980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>u,Rb:()=>l});var r=n(7294),a=n(6550),o=n(1688),i=n(9688);function l(e){!function(e){var t=(0,a.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((function(){return t.block((function(e,t){return n(e,t)}))}),[t,n])}((function(t,n){if("POP"===n)return e(t,n)}))}function s(e){return t=function(t){return null===e?null:new URLSearchParams(t.location.search).get(e)},n=(0,a.k6)(),(0,o.useSyncExternalStore)(n.listen,(function(){return t(n)}),(function(){return t(n)}));var t,n}function u(e){var t,n,o=null!=(t=s(e))?t:"",i=(n=(0,a.k6)(),(0,r.useCallback)((function(e,t,r){var a=new URLSearchParams(n.location.search);t?a.set(e,t):a.delete(e),(null!=r&&r.push?n.push:n.replace)({search:a.toString()})}),[n]));return[o,(0,r.useCallback)((function(t,n){i(e,t,n)}),[i,e])]}},833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>c,VC:()=>p});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function l(){var e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(4996),u=n(2128);function c(e){var t=e.title,n=e.description,a=e.keywords,i=e.image,l=e.children,c=(0,u.p)(t),d=(0,s.C)().withBaseUrl,f=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),l)}var d=r.createContext(void 0);function f(e){var t=e.className,n=e.children,i=r.useContext(d),l=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function p(e){var t=e.children,n=l(),o="plugin-"+n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,""),i="plugin-id-"+n.plugin.id;return r.createElement(f,{className:(0,a.Z)(o,i)},t)}},9688:(e,t,n)=>{"use strict";n.d(t,{i6:()=>p,Qc:()=>h,zX:()=>d,D9:()=>f,Ql:()=>m});var r=n(6528),a=n(4578);function o(e){return o=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},o(e)}var i=n(9611);function l(e,t,n){return l=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}()?Reflect.construct.bind():function(e,t,n){var r=[null];r.push.apply(r,t);var a=new(Function.bind.apply(e,r));return n&&(0,i.Z)(a,n.prototype),a},l.apply(null,arguments)}function s(e){var t="function"==typeof Map?new Map:void 0;return s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return l(e,arguments,o(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),(0,i.Z)(r,e)},s(e)}var u=n(7294),c=n(412).Z.canUseDOM?u.useLayoutEffect:u.useEffect;function d(e){var t=(0,u.useRef)(e);return c((function(){t.current=e}),[e]),(0,u.useCallback)((function(){return t.current.apply(t,arguments)}),[])}function f(e){var t=(0,u.useRef)();return c((function(){t.current=e})),t.current}var p=function(e){function t(t,n){var a,o,i;return(i=e.call(this)||this).name="ReactContextError",i.message="Hook "+(null!=(a=null==(o=i.stack)||null==(o=o.split("\n")[1])||null==(o=o.match((0,r.Z)(/at (?:\w+\.)?(\w+)/,{name:1})))?void 0:o.groups.name)?a:"")+" is called outside the <"+t+">. "+(null!=n?n:""),i}return(0,a.Z)(t,e),t}(s(Error));function m(e){var t=Object.entries(e);return t.sort((function(e,t){return e[0].localeCompare(t[0])})),(0,u.useMemo)((function(){return e}),t.flat())}function h(e){return function(t){var n=t.children;return u.createElement(u.Fragment,null,e.reduceRight((function(e,t){return u.createElement(t,null,e)}),n))}}},8022:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>r})},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(7294),a=n(723),o=n(2263);function i(e,t){var n=function(e){var t;return null==(t=!e||e.endsWith("/")?e:e+"/")?void 0:t.toLowerCase()};return n(e)===n(t)}function l(){var e=(0,o.Z)().siteConfig.baseUrl;return(0,r.useMemo)((function(){return function(e){var t=e.baseUrl;function n(e){return e.path===t&&!0===e.exact}function r(e){return e.path===t&&!e.exact}return function e(t){if(0!==t.length)return t.find(n)||e(t.filter(r).flatMap((function(e){var t;return null!=(t=e.routes)?t:[]})))}(e.routes)}({routes:a.Z,baseUrl:e})}),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>s,RF:()=>d});var r=n(7294),a=n(412),o=n(2389),i=n(9688);var l=r.createContext(void 0);function s(e){var t,n=e.children,a=(t=(0,r.useRef)(!0),(0,r.useMemo)((function(){return{scrollEventsEnabledRef:t,enableScrollEvents:function(){t.current=!0},disableScrollEvents:function(){t.current=!1}}}),[]));return r.createElement(l.Provider,{value:a},n)}function u(){var e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}var c=function(){return a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null};function d(e,t){void 0===t&&(t=[]);var n=u().scrollEventsEnabledRef,a=(0,r.useRef)(c()),o=(0,i.zX)(e);(0,r.useEffect)((function(){var e=function(){if(n.current){var e=c();o(e,a.current),a.current=e}},t={passive:!0};return e(),window.addEventListener("scroll",e,t),function(){return window.removeEventListener("scroll",e,t)}}),[o,n].concat(t))}function f(){var e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:function(n){e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),function(){}}(n):function(e){var t=null,n=document.documentElement.scrollTop>e;return function r(){var a=document.documentElement.scrollTop;(n&&a>e||!n&&a{"use strict";n.d(t,{HX:()=>i,_q:()=>s,os:()=>l});var r=n(143),a=n(2263),o=n(373),i="default";function l(e,t){return"docs-"+e+"-"+t}function s(){var e=(0,a.Z)().i18n,t=(0,r._r)(),n=(0,r.WS)(),s=(0,o.Oh)();var u=[i].concat(Object.keys(t).map((function(e){var r,a=(null==n?void 0:n.activePlugin.pluginId)===e?n.activeVersion:void 0,o=s[e],i=t[e].versions.find((function(e){return e.isLast}));return l(e,(null!=(r=null!=a?a:o)?r:i).name)})));return{locale:e.currentLocale,tags:u}}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>s});n(7294),n(1688);var r="localStorage";function a(e){var t=e.key,n=e.oldValue,r=e.newValue,a=e.storage;if(n!==r){var o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}var i=!1;var l={get:function(){return null},set:function(){},del:function(){},listen:function(){return function(){}}};function s(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error('Illegal storage API usage for storage key "'+e+'".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.')}return{get:t,set:t,del:t,listen:t}}(e);var n=o(null==t?void 0:t.persistence);return null===n?l:{get:function(){try{return n.getItem(e)}catch(t){return console.error("Docusaurus storage error, can't get key="+e,t),null}},set:function(t){try{var r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(o){console.error("Docusaurus storage error, can't set "+e+"="+t,o)}},del:function(){try{var t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(r){console.error("Docusaurus storage error, can't delete key="+e,r)}},listen:function(t){try{var r=function(r){r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),function(){return window.removeEventListener("storage",r)}}catch(a){return console.error("Docusaurus storage error, can't listen for changes of key="+e,a),function(){}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(2263),a=n(6550);function o(){var e=(0,r.Z)(),t=e.siteConfig,n=t.baseUrl,o=t.url,i=e.i18n,l=i.defaultLocale,s=i.currentLocale,u=(0,a.TH)().pathname,c=s===l?n:n.replace("/"+s+"/","/"),d=u.replace(n,"");return{createUrl:function(e){var t=e.locale;return""+(e.fullyQualified?o:"")+function(e){return e===l?""+c:""+c+e+"/"}(t)+d}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(9688);function i(e){var t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((function(){n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>l});var r=n(7294),a=n(8022),o=n(4996),i=n(6278);function l(){var e=(0,o.C)().withBaseUrl,t=(0,i.L)().algolia,n=t.externalUrlRegex,l=t.replaceSearchResultPathname;return(0,r.useCallback)((function(t){var r=new URL(t);if((0,a.F)(n,r.href))return t;var o=""+(r.pathname+r.hash);return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(o,l))}),[e,n,l])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var n=t.trailingSlash,r=t.baseUrl;if(e.startsWith("#"))return e;if(void 0===n)return e;var a,o=e.split(/[#?]/)[0],i="/"===o||o===r?o:(a=o,n?function(e){return e.endsWith("/")?e:e+"/"}(a):function(e){return e.endsWith("/")?e.slice(0,-1):e}(a));return e.replace(o,i)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t].concat(e(t.cause)):[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>p,PP:()=>A,Ep:()=>f});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(8776);function s(e){return"/"===e.charAt(0)?e:"/"+e}function u(e){return"/"===e.charAt(0)?e.substr(1):e}function c(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,h(),w.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=p(n);a&&a!==m&&e(t,a,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=s(t),h=s(n),g=0;g{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,a,o,i,l],c=0;(s=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),u=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);S+=E.value.length,E=E.next){var x=E.value;if(t.length>e.length)return;if(!(x instanceof a)){var _,C=1;if(b){if(!(_=o(k,S,e,v))||_.index>=e.length)break;var T=_.index,A=_.index+_[0].length,L=S;for(L+=E.value.length;T>=L;)L+=(E=E.next).value.length;if(S=L-=E.value.length,E.value instanceof a)continue;for(var R=E;R!==t.tail&&(Ld.reach&&(d.reach=I);var D=E.prev;if(P&&(D=s(t,D,P),S+=P.length),u(t,D,C),E=s(t,D,new a(f,g?r.tokenize(O,g):O,y,O)),N&&s(t,E,N),C>1){var M={cause:f+","+m,reach:I};i(e,t,n,E.prev,S,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function u(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s=0&&p(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function u(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function c(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,c={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return c[n]=a,n})).join(""),n,r),f=Object.keys(c);return i=0,function e(t){for(var n=0;n=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=u(c[a]),p=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),p){var h=[p];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=o.length);s++){var u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++a;var h=f.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=f.substring(m+p.length),b=[];h&&b.push.apply(b,i([h])),b.push(g),v&&b.push.apply(b,i([v])),"string"==typeof u?l.splice.apply(l,[s,1].concat(b)):u.content=b}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,u),t(s.optional,u),t(s.modify,u)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(u),l=(l||[]).map(u);var c=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(s),m=c;a(m);){for(var h in f={},m){var g=s[h];t(g&&g.modify,(function(e){e in d&&(f[e]=!0)}))}for(var v in d)if(!(v in c))for(var b in p(v))if(b in c){f[v]=!0;break}for(var y in m=f)c[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function u(e){if(e in l)return l[e];s[e]=!0;var a,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)a=r(e);else{var f=i(c.map((function(e){var t=u(e);return delete s[e],t})));o?a=o(f,(function(){return r(e)})):r(e)}return l[e]=a}for(var c in n)u(c);var d=[];for(var f in s)d.push(l[f]);return i(d)}(p,c,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n