New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@tutorialkit/cli

Package Overview
Dependencies
Maintainers
3
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tutorialkit/cli - npm Package Compare versions

Comparing version 0.0.1-alpha.17 to 0.0.1-alpha.18

9

dist/index.js
#!/usr/bin/env node
import D from"chalk";import $e from"yargs-parser";import*as l from"@clack/prompts";import u from"chalk";import w from"node:fs";import E from"node:path";import"yargs-parser";var c={name:"@tutorialkit/cli",version:"0.0.1-alpha.17",description:"Interactive tutorials powered by WebContainer API",type:"module",bugs:"https://github.com/stackblitz/tutorialkit/issues",homepage:"https://github.com/stackblitz/tutorialkit",license:"MIT",bin:{tutorialkit:"dist/index.js"},main:"./dist/index.js",exports:{".":"./dist/index.js"},scripts:{build:"node scripts/build.js",prepack:"node scripts/pre-pack.js",postpack:"node scripts/cleanup.js"},files:["dist","template","template/.gitignore"],dependencies:{"@clack/prompts":"^0.7.0",chalk:"^5.3.0",ignore:"^5.3.1",lookpath:"^1.2.2","yargs-parser":"^21.1.1"},devDependencies:{"@types/fs-extra":"^11.0.4","@types/node":"^20.12.7","@types/yargs-parser":"^21.0.3",esbuild:"^0.20.2","esbuild-node-externals":"^1.13.0","fs-extra":"^11.2.0"},engines:{node:"^18.18.0"}};import d from"chalk";import ie from"chalk";var _=ie.bgHex("#0d6fe8");function x(e){return _(` ${d.whiteBright(e)} `)}function f(e){return d.bgRed(` ${d.white(e??"ERROR")} `)}function b(e){return d.bgYellow(` ${d.black(e??"WARN")} `)}function S({commandName:e,usage:t,tables:n,prolog:r,epilog:o}){let i=[],a=!1;if(r&&(i.push(r),a=!0),t){a&&i.push(""),a=!0;let s=Array.isArray(t)?t:[t],g="Usage:",k=" ".repeat(g.length+1);i.push(`${d.bold.underline(g)} ${d.green(e)} ${d.bold(s[0])}`);for(let C of s.slice(1))i.push(`${k}${d.green(e)} ${d.bold(C)}`)}if(n){let s=0,g=Object.entries(n);g.length>0&&a&&(i.push(""),a=!0);for(let[k,C]of g){let re=Object.values(C).reduce((R,I)=>{let P=I[0];return P.length>R?P.length:R},0);i.push(d.bold.underline(`${k}:`));for(let R of C){let[I,P]=R;i.push(` ${I.padEnd(re," ")} ${d.dim(P)}`)}s++<g.length-1&&i.push("")}}o&&(a&&i.push(""),i.push(o)),console.log(i.join(`
`))}function N(e){return e[Math.floor(e.length*Math.random())]}var z=["aged","ancient","autumn","billowing","bitter","black","blue","bold","broad","broken","calm","cold","cool","crimson","curly","damp","dark","dawn","delicate","divine","dry","empty","falling","fancy","flat","floral","fragrant","frosty","gentle","green","hidden","holy","icy","jolly","late","lingering","little","lively","long","lucky","misty","morning","muddy","mute","nameless","noisy","odd","old","orange","patient","plain","polished","proud","purple","quiet","rapid","raspy","red","restless","rough","round","royal","shiny","shrill","shy","silent","small","snowy","soft","solitary","sparkling","spring","square","steep","still","summer","super","sweet","throbbing","tight","tiny","twilight","wandering","weathered","white","wild","winter","wispy","withered","yellow","young"],V=["art","band","bar","base","bird","block","boat","bonus","bread","breeze","brook","bush","butterfly","cake","cell","cherry","cloud","credit","darkness","dawn","dew","disk","dream","dust","feather","field","fire","firefly","flower","fog","forest","frog","frost","glade","glitter","grass","hall","hat","haze","heart","hill","king","lab","lake","leaf","limit","math","meadow","mode","moon","morning","mountain","mouse","mud","night","paper","pine","poetry","pond","queen","rain","recipe","resonance","rice","river","salad","scene","sea","shadow","shape","silence","sky","smoke","snow","snowflake","sound","star","sun","sun","sunset","surf","term","thunder","tooth","tree","truth","union","unit","violet","voice","water","waterfall","wave","wildflower","wind","wood"];function W(){let e=N(z),t=N(V);return`${e}-${t}`}import*as y from"@clack/prompts";function m(e,t=0){if(y.isCancel(e))return y.cancel("Command aborted"),console.log("Until next time!"),process.exit(t)}async function M(e){if(e.disabled===!0)return;if(e.dryRun){y.log.warn(e.dryRunMessage??`Skipped '${e.title}'`);return}let t=y.spinner();t.start(e.title);try{let n=await e.task(t.message);t.stop(n||e.title)}catch(n){t.stop(`${f()} ${n.message??"Task failed"}`,1)}}import*as h from"@clack/prompts";import U from"chalk";import{lookpath as B}from"lookpath";import{spawn as oe}from"node:child_process";async function v(e,t,n={}){let r,o="",i="";try{r=oe(e,t,{cwd:n.cwd,shell:!0,stdio:n.stdio,timeout:n.timeout});let a=new Promise(s=>r.on("close",s));r.stdout?.setEncoding("utf8"),r.stderr?.setEncoding("utf8"),r.stdout?.on("data",s=>{o+=s}),r.stderr?.on("data",s=>{i+=s}),await a}catch{throw{stdout:o,stderr:i,exitCode:1}}return{stdout:o,stderr:i,exitCode:r.exitCode}}import H from"node:path";import{fileURLToPath as ae}from"node:url";var se=H.dirname(ae(import.meta.url)),$=H.resolve(se,"../template"),p={git:!0,install:!0,dryRun:!1,force:!1,packageManager:"npm"};async function J(e,t){let n=t.install??p.install;if(!t.defaults&&t.install===void 0){let i=await h.confirm({message:"Install dependencies?",initialValue:p.install});m(i),n=i}let r=!1,o=t.packageManager??p.packageManager;if(n){let i;t.packageManager&&(await B(String(t.packageManager))?i=t.packageManager:h.log.warn(`The specified package manager '${U.yellow(t.packageManager)}' doesn't seem to be installed!`)),i||(t.defaults?i=p.packageManager:i=await le()),o=i,await M({title:`Installing dependencies with ${i}`,dryRun:t.dryRun,dryRunMessage:`${b("DRY RUN")} Skipped dependency installation`,task:async()=>{try{return await v(i,["install"],{cwd:e,stdio:"ignore"}),r=!0,"Dependencies installed"}catch{let a=U.yellow(`${i} install`);throw new Error(`Failed to install dependencies. Please run ${a} manually after the setup.`)}}})}else h.log.message(`${U.blue("dependencies [skip]")} Remember to install the dependencies after the setup.`);return{selectedPackageManager:o,dependenciesInstalled:r}}async function le(){let e=await pe(),t=await h.select({message:"What package manager should we use?",initialValue:"pnpm",options:[{label:"npm",value:"npm"},...e.map(n=>({label:n,value:n}))]});return m(t),t}async function pe(){let e=[];for(let t of["yarn","pnpm","bun"])try{await B(t)&&e.push(t)}catch{}return e}import*as T from"@clack/prompts";import j from"chalk";import ce from"node:fs";import de from"node:path";async function G(e,t){let n=t.git??p.git;if(!t.defaults&&t.git===void 0){let r=await T.confirm({message:"Initialize a new git repository?",initialValue:p.git});m(r),n=r}n?await M({title:"Initializing git repository",dryRun:t.dryRun,dryRunMessage:`${b("DRY RUN")} Skipped initializing git repository`,task:async()=>await me(e)??"Git repository initialized"}):T.log.message(`${j.blue("git [skip]")} You can always run ${j.yellow("git init")} manually.`)}async function me(e){if(ce.existsSync(de.join(e,".git")))return`${j.cyan("Nice!")} Git has already been initialized`;try{await v("git",["init"],{cwd:e,stdio:"ignore"}),await v("git",["add","-A"],{cwd:e,stdio:"ignore"}),await v("git",["commit","-m",`"feat: initial commit from ${c.name}"`,'--author="StackBlitz <hello@stackblitz.com>"'],{cwd:e,stdio:"ignore"})}catch{throw new Error("Failed to initialize local git repository")}}import*as O from"@clack/prompts";import F from"node:fs";import ue from"node:path";async function K(e,t){let n=ue.resolve(e,"tutorialkit.config.json"),r=t.enterprise;if(!t.defaults&&t.enterprise===void 0){let o=await O.confirm({message:"TutorialKit uses StackBlitz WebContainers, do you want to configure the Enterprise version?",initialValue:!1});if(m(o),!o){t.dryRun||F.rmSync(n);return}let i=await O.text({message:"What's the origin of your StackBlitz instance?",placeholder:"https://editor.stackblitz.acme.com",validate:Y});m(i),r=new URL(i).origin}else if(r){let o=Y(r);if(o)throw o;r=new URL(r).origin}if(!t.dryRun&&r){let o=JSON.parse(F.readFileSync(n,"utf8"));o.enterprise={clientId:"wc_api",editorOrigin:r,scope:"turbo"},F.writeFileSync(n,JSON.stringify(o,void 0,2))}}function Y(e){if(!e)return"Please provide an origin!";try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return"Please provide an origin starting with http:// or https://"}catch{return"Please provide a valid origin URL!"}}import*as Q from"@clack/prompts";import ge from"ignore";import q from"node:fs";import L from"node:fs/promises";import A from"node:path";async function X(e,t){if(t.dryRun){Q.log.warn(`${b("DRY RUN")} Skipped copying template`);return}let n=ge().add(fe()),r=[],o=await L.readdir($);for(let i of o)n.ignores(i)||r.push(i);for(let i of r){let a=A.join($,i),s=i===".npmignore"?".gitignore":i,g=A.join(e,s),k=await L.stat(a);k.isDirectory()?await L.cp(a,g,{recursive:!0}):k.isFile()&&await L.copyFile(a,g)}}function fe(){try{return q.readFileSync(A.resolve($,".npmignore"),"utf8")}catch{return q.readFileSync(A.resolve($,".gitignore"),"utf8")}}var Z=c.version;async function te(e){if(e._[1]==="help"||e.help||e.h)return S({commandName:`${c.name} create`,usage:"[name] [...options]",tables:{Options:[["--dir, -d","The folder in which the tutorial gets created"],["--install, --no-install",`Install dependencies (default ${u.yellow(p.install)})`],["--git, --no-git",`Initialize a local git repository (default ${u.yellow(p.git)})`],["--dry-run",`Walk through steps without executing (default ${u.yellow(p.dryRun)})`],["--package-manager <name>, -p <name>",`The package used to install dependencies (default ${u.yellow(p.packageManager)})`],["--enterprise <origin>, -e <origin>",`The origin of your StackBlitz Enterprise instance (if not provided authentication is not turned on and your project will use ${u.yellow("https://stackblitz.com")})`],["--force",`Overwrite existing files in the target directory without prompting (default ${u.yellow(p.force)})`],["--defaults","Skip all prompts and initialize the tutorial using the defaults"]]}}),0;try{return ye(e)}catch(t){console.error(`${f()} Command failed`),t.stack&&console.error(`
${t.stack}`),process.exit(1)}}async function ye(e){xe(e),l.intro(x(c.name));let t=e._[1]!==void 0?String(e._[1]):void 0;if(t===void 0){let a=W();if(e.defaults)t=a;else{let s=await l.text({message:"What's the name of your tutorial?",placeholder:a,validate:g=>{if(!g)return"Please provide a name!"}});m(s),t=s}}l.log.info(`We'll call your tutorial ${u.blue(t)}`);let n=await he(t,e),r=E.resolve(process.cwd(),n);if(l.log.info(`Scaffolding tutorial in ${u.blue(r)}`),w.existsSync(r)&&!e.force){if(e.defaults)return console.error(`
${f()} Failed to create tutorial. Directory already exists.`),process.exit(1);let a;if(w.readdirSync(r).length>0?a=await l.confirm({message:"Directory is not empty. Continuing may overwrite existing files. Do you want to continue?",initialValue:!1}):a=await l.confirm({message:"Directory already exists. Continuing may overwrite existing files. Do you want to continue?",initialValue:!1}),m(a),!a)return ve()}else e.dryRun||w.mkdirSync(r,{recursive:!0});await X(r,e);let{selectedPackageManager:o,dependenciesInstalled:i}=await J(r,e);await K(r,e),ke(r,t,e),be(r,o,e),await G(r,e),l.log.success(u.green("Tutorial successfully created!")),we(n,o,i),l.outro("You're all set!"),console.log("Until next time \u{1F44B}")}async function he(e,t){let n=t.dir;if(n)return n;if(t.defaults)return`./${e}`;let r=await l.text({message:"Where should we create your new tutorial?",initialValue:`./${e}`,placeholder:"./",validate(o){if(!E.isAbsolute(o)&&!o.startsWith("./"))return"Please provide an absolute or relative path!"}});return m(r),r}function we(e,t,n){let r=0;l.log.message(u.bold.underline("Next Steps"));let o=[[`cd ${e}`,"Navigate to project"],[`${t} install`,"Install dependencies",!n],[`${t} run dev`,"Start development server"],[,`Head over to ${u.underline("http://localhost:4321")}`]];for(let[i,a,s]of o)s!==!1&&(r++,l.log.step(`${r}. ${i?`${u.blue(i)} - `:""}${a}`))}function ke(e,t,n){if(n.dryRun)return;let r=E.resolve(e,"package.json"),o=JSON.parse(w.readFileSync(r,"utf8"));o.name=t,ee(o.dependencies,Z),ee(o.devDependencies,Z),w.writeFileSync(r,JSON.stringify(o,void 0,2))}function ee(e,t){for(let n in e)e[n]==="workspace:*"&&(e[n]=t)}function be(e,t,n){if(n.dryRun)return;let r=E.resolve(e,"README.md"),o=w.readFileSync(r,"utf8");o=o.replaceAll("<% pkgManager %>",t??p.packageManager),w.writeFileSync(r,o)}function ve(e=0){l.outro("Until next time!"),process.exit(e)}function xe(e){e.d&&(e.dir=e.d),e.p&&(e.packageManager=e.p),e.e&&(e.enterprise=e.e)}var Ce=new Set(["version","help","create"]);Re();async function Re(){let e=$e(process.argv.slice(2)),t=Se(e);try{console.log("");let n=await Pe(t,e);process.exit(n||0)}catch(n){console.error(`${f()} ${n.message}`),process.exit(1)}}async function Pe(e,t){switch(e){case"version":{console.log(`${x(c.name)} ${D.green(`v${c.version}`)}`);return}case"help":{S({commandName:c.name,prolog:`${x(c.name)} ${D.green(`v${c.version}`)} Create tutorial apps powered by WebContainer API`,usage:["[command] [...options]","[ -h | --help | -v | --version ]"],tables:{Commands:[["create","Create new tutorial app"],["help","Show this help message"]]}});return}case"create":return te(t);default:return console.error(`${f()} Unknown command ${D.red(e)}`),1}}function Se(e){if(e.version||e.v)return"version";if(e._[0]==null&&(e.help||e.h))return"help";let t=String(e._.at(0));return Ce.has(t)?t:"help"}
import z from"chalk";import Ie from"yargs-parser";import*as c from"@clack/prompts";import y from"chalk";import k from"node:fs";import I from"node:path";import"yargs-parser";var u={name:"@tutorialkit/cli",version:"0.0.1-alpha.18",description:"Interactive tutorials powered by WebContainer API",type:"module",bugs:"https://github.com/stackblitz/tutorialkit/issues",homepage:"https://github.com/stackblitz/tutorialkit",license:"MIT",bin:{tutorialkit:"dist/index.js"},main:"./dist/index.js",exports:{".":"./dist/index.js"},scripts:{build:"node scripts/build.js",prepack:"node scripts/pre-pack.js",postpack:"node scripts/cleanup.js"},files:["dist","template","template/.gitignore"],dependencies:{"@babel/parser":"7.24.5","@babel/generator":"7.24.5","@babel/traverse":"7.24.5","@babel/types":"7.24.5","@clack/prompts":"^0.7.0",chalk:"^5.3.0",ignore:"^5.3.1",lookpath:"^1.2.2","yargs-parser":"^21.1.1"},devDependencies:{"@types/babel__generator":"7.6.8","@types/babel__traverse":"7.20.5","@types/fs-extra":"^11.0.4","@types/node":"^20.12.7","@types/yargs-parser":"^21.0.3",esbuild:"^0.20.2","esbuild-node-externals":"^1.13.0","fs-extra":"^11.2.0"},engines:{node:"^18.18.0"}};import f from"chalk";import de from"chalk";var V=de.bgHex("#0d6fe8");function C(e){return V(` ${f.whiteBright(e)} `)}function h(e){return f.bgRed(` ${f.white(e??"ERROR")} `)}function x(e){return f.bgYellow(` ${f.black(e??"WARN")} `)}function S({commandName:e,usage:t,tables:r,prolog:n,epilog:o}){let i=[],a=!1;if(n&&(i.push(n),a=!0),t){a&&i.push(""),a=!0;let s=Array.isArray(t)?t:[t],d="Usage:",l=" ".repeat(d.length+1);i.push(`${f.bold.underline(d)} ${f.green(e)} ${f.bold(s[0])}`);for(let O of s.slice(1))i.push(`${l}${f.green(e)} ${f.bold(O)}`)}if(r){let s=0,d=Object.entries(r);d.length>0&&a&&(i.push(""),a=!0);for(let[l,O]of d){let pe=Object.values(O).reduce((E,D)=>{let R=D[0];return R.length>E?R.length:E},0);i.push(f.bold.underline(`${l}:`));for(let E of O){let[D,R]=E;i.push(` ${D.padEnd(pe," ")} ${f.dim(R)}`)}s++<d.length-1&&i.push("")}}o&&(a&&i.push(""),i.push(o)),console.log(i.join(`
`))}function U(e){return e[Math.floor(e.length*Math.random())]}var W=["aged","ancient","autumn","billowing","bitter","black","blue","bold","broad","broken","calm","cold","cool","crimson","curly","damp","dark","dawn","delicate","divine","dry","empty","falling","fancy","flat","floral","fragrant","frosty","gentle","green","hidden","holy","icy","jolly","late","lingering","little","lively","long","lucky","misty","morning","muddy","mute","nameless","noisy","odd","old","orange","patient","plain","polished","proud","purple","quiet","rapid","raspy","red","restless","rough","round","royal","shiny","shrill","shy","silent","small","snowy","soft","solitary","sparkling","spring","square","steep","still","summer","super","sweet","throbbing","tight","tiny","twilight","wandering","weathered","white","wild","winter","wispy","withered","yellow","young"],H=["art","band","bar","base","bird","block","boat","bonus","bread","breeze","brook","bush","butterfly","cake","cell","cherry","cloud","credit","darkness","dawn","dew","disk","dream","dust","feather","field","fire","firefly","flower","fog","forest","frog","frost","glade","glitter","grass","hall","hat","haze","heart","hill","king","lab","lake","leaf","limit","math","meadow","mode","moon","morning","mountain","mouse","mud","night","paper","pine","poetry","pond","queen","rain","recipe","resonance","rice","river","salad","scene","sea","shadow","shape","silence","sky","smoke","snow","snowflake","sound","star","sun","sun","sunset","surf","term","thunder","tooth","tree","truth","union","unit","violet","voice","water","waterfall","wave","wildflower","wind","wood"];function B(){let e=U(W),t=U(H);return`${e}-${t}`}import*as w from"@clack/prompts";function g(e,t=0){if(w.isCancel(e))return w.cancel("Command aborted"),console.log("Until next time!"),process.exit(t)}async function j(e){if(e.disabled===!0)return;if(e.dryRun){w.log.warn(e.dryRunMessage??`Skipped '${e.title}'`);return}let t=w.spinner();t.start(e.title);try{let r=await e.task(t.message);t.stop(r||e.title)}catch(r){t.stop(`${h()} ${r.message??"Task failed"}`,1)}}import*as b from"@clack/prompts";import F from"chalk";import{lookpath as Y}from"lookpath";import{spawn as me}from"node:child_process";async function v(e,t,r={}){let n,o="",i="";try{n=me(e,t,{cwd:r.cwd,shell:!0,stdio:r.stdio,timeout:r.timeout});let a=new Promise(s=>n.on("close",s));n.stdout?.setEncoding("utf8"),n.stderr?.setEncoding("utf8"),n.stdout?.on("data",s=>{o+=s}),n.stderr?.on("data",s=>{i+=s}),await a}catch{throw{stdout:o,stderr:i,exitCode:1}}return{stdout:o,stderr:i,exitCode:n.exitCode}}import G from"node:path";import{fileURLToPath as ue}from"node:url";var fe=G.dirname(ue(import.meta.url)),$=G.resolve(fe,"../template"),m={git:!0,install:!0,dryRun:!1,force:!1,packageManager:"npm"};async function J(e,t){let r=t.install??m.install;if(!t.defaults&&t.install===void 0){let i=await b.confirm({message:"Install dependencies?",initialValue:m.install});g(i),r=i}let n=!1,o=t.packageManager??m.packageManager;if(r){let i;t.packageManager&&(await Y(String(t.packageManager))?i=t.packageManager:b.log.warn(`The specified package manager '${F.yellow(t.packageManager)}' doesn't seem to be installed!`)),i||(t.defaults?i=m.packageManager:i=await ge()),o=i,await j({title:`Installing dependencies with ${i}`,dryRun:t.dryRun,dryRunMessage:`${x("DRY RUN")} Skipped dependency installation`,task:async()=>{try{return await v(i,["install"],{cwd:e,stdio:"ignore"}),n=!0,"Dependencies installed"}catch{let a=F.yellow(`${i} install`);throw new Error(`Failed to install dependencies. Please run ${a} manually after the setup.`)}}})}else b.log.message(`${F.blue("dependencies [skip]")} Remember to install the dependencies after the setup.`);return{selectedPackageManager:o,dependenciesInstalled:n}}async function ge(){let e=await ye(),t=await b.select({message:"What package manager should we use?",initialValue:"pnpm",options:[{label:"npm",value:"npm"},...e.map(r=>({label:r,value:r}))]});return g(t),t}async function ye(){let e=[];for(let t of["yarn","pnpm","bun"])try{await Y(t)&&e.push(t)}catch{}return e}import*as M from"@clack/prompts";import N from"chalk";import he from"node:fs";import we from"node:path";async function q(e,t){let r=t.git??m.git;if(!t.defaults&&t.git===void 0){let n=await M.confirm({message:"Initialize a new git repository?",initialValue:m.git});g(n),r=n}r?await j({title:"Initializing git repository",dryRun:t.dryRun,dryRunMessage:`${x("DRY RUN")} Skipped initializing git repository`,task:async()=>await be(e)??"Git repository initialized"}):M.log.message(`${N.blue("git [skip]")} You can always run ${N.yellow("git init")} manually.`)}async function be(e){if(he.existsSync(we.join(e,".git")))return`${N.cyan("Nice!")} Git has already been initialized`;try{await v("git",["init"],{cwd:e,stdio:"ignore"}),await v("git",["add","-A"],{cwd:e,stdio:"ignore"}),await v("git",["commit","-m",`"feat: initial commit from ${u.name}"`,'--author="StackBlitz <hello@stackblitz.com>"'],{cwd:e,stdio:"ignore"})}catch{throw new Error("Failed to initialize local git repository")}}import*as T from"@clack/prompts";import $e from"node:fs";import Pe from"node:path";import Ce from"node:fs/promises";import ke from"@babel/generator";import xe from"@babel/parser";import ve from"@babel/traverse";import*as p from"@babel/types";var _=ve.default;function K(e){let t=ke.default,{code:r}=t(e);return r}var Q=e=>xe.parse(e,{sourceType:"unambiguous",plugins:["typescript"]});async function X(e){let t=await Ce.readFile(e,{encoding:"utf-8"}),r=Q(t);if(!r)throw new Error("Unknown error parsing astro config");if(r.errors.length>0)throw new Error("Error parsing astro config: "+JSON.stringify(r.errors));return r}function Z(e,t){let r="@tutorialkit/astro",n;if(_(t,{ImportDeclaration(o){if(o.node.source.value===r){let i=o.node.specifiers.find(a=>a.type==="ImportDefaultSpecifier");i&&(n=i.local)}}}),!n)throw new Error(`Could not find import to '${r}'`);_(t,{ExportDefaultDeclaration(o){if(!p.isCallExpression(o.node.declaration))return;let i=o.node.declaration.arguments[0];if(!p.isObjectExpression(i))throw new Error("TutorialKit is not part of the exported config");let a=i.properties.find(l=>l.type!=="ObjectProperty"?!1:l.key.type==="Identifier"&&l.key.name==="integrations"||l.key.type==="StringLiteral"&&l.key.value==="integrations");if(a.value.type!=="ArrayExpression")throw new Error("Unable to parse integrations in Astro config");let s=a.value.elements.find(l=>p.isCallExpression(l)&&p.isIdentifier(l.callee)&&l.callee.name===n.name);s||(s=p.callExpression(n,[]),a.value.elements.push(s));let d=s.arguments;if(d.length===0){let l=P(e);l.properties.length>0&&d.push(l);return}if(!p.isObjectExpression(d[0]))throw new Error("Only updating an existing object literal as the config is supported");ee(e,d[0])}})}function ee(e,t){if(typeof e!="object")return p.objectExpression([]);t??=p.objectExpression([]);for(let r of e){let n=t.properties.find(o=>o.type==="ObjectProperty"&&o.key===r);n?typeof e[r]=="object"&&p.isObjectExpression(n.value)?ee(e[r],n.value):n.value=P(e[r]):t.properties.push(p.objectProperty(p.identifier(r),P(e[r])))}}function P(e){return e==null?p.nullLiteral():typeof e=="string"?p.stringLiteral(e):typeof e=="number"?p.numericLiteral(e):Array.isArray(e)?p.arrayExpression(e.map(P)):p.objectExpression(Object.keys(e).map(t=>p.objectProperty(p.identifier(t),P(e[t]))))}async function re(e,t){let r=t.enterprise;if(!t.defaults&&t.enterprise===void 0){let o=await T.confirm({message:"TutorialKit uses StackBlitz WebContainers, do you want to configure the Enterprise version?",initialValue:!1});if(g(o),!o)return;let i=await T.text({message:"What's the origin of your StackBlitz instance?",placeholder:"https://editor.stackblitz.acme.com",validate:te});g(i),r=new URL(i).origin}else if(r){let o=te(r);if(o)throw o;r=new URL(r).origin}let n=Pe.resolve(e,"astro.config.ts");if(!t.dryRun&&r){let o=await X(n);Z({enterprise:{clientId:"wc_api",editorOrigin:r,scope:"turbo"}},o);let i="export default defineConfig",a=K(o);a=a.replace(i,`
${i}`),$e.writeFileSync(n,a)}}function te(e){if(!e)return"Please provide an origin!";try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")return"Please provide an origin starting with http:// or https://"}catch{return"Please provide a valid origin URL!"}}import*as ie from"@clack/prompts";import Oe from"ignore";import ne from"node:fs";import A from"node:fs/promises";import L from"node:path";async function oe(e,t){if(t.dryRun){ie.log.warn(`${x("DRY RUN")} Skipped copying template`);return}let r=Oe.default().add(Ee()),n=[],o=await A.readdir($);for(let i of o)r.ignores(i)||n.push(i);for(let i of n){let a=L.join($,i),s=i===".npmignore"?".gitignore":i,d=L.join(e,s),l=await A.stat(a);l.isDirectory()?await A.cp(a,d,{recursive:!0}):l.isFile()&&await A.copyFile(a,d)}}function Ee(){try{return ne.readFileSync(L.resolve($,".npmignore"),"utf8")}catch{return ne.readFileSync(L.resolve($,".gitignore"),"utf8")}}var ae=u.version;async function le(e){if(e._[1]==="help"||e.help||e.h)return S({commandName:`${u.name} create`,usage:"[name] [...options]",tables:{Options:[["--dir, -d","The folder in which the tutorial gets created"],["--install, --no-install",`Install dependencies (default ${y.yellow(m.install)})`],["--git, --no-git",`Initialize a local git repository (default ${y.yellow(m.git)})`],["--dry-run",`Walk through steps without executing (default ${y.yellow(m.dryRun)})`],["--package-manager <name>, -p <name>",`The package used to install dependencies (default ${y.yellow(m.packageManager)})`],["--enterprise <origin>, -e <origin>",`The origin of your StackBlitz Enterprise instance (if not provided authentication is not turned on and your project will use ${y.yellow("https://stackblitz.com")})`],["--force",`Overwrite existing files in the target directory without prompting (default ${y.yellow(m.force)})`],["--defaults","Skip all prompts and initialize the tutorial using the defaults"]]}}),0;try{return Re(e)}catch(t){console.error(`${h()} Command failed`),t.stack&&console.error(`
${t.stack}`),process.exit(1)}}async function Re(e){Le(e),c.intro(C(u.name));let t=e._[1]!==void 0?String(e._[1]):void 0;if(t===void 0){let a=B();if(e.defaults)t=a;else{let s=await c.text({message:"What's the name of your tutorial?",placeholder:a,validate:d=>{if(!d)return"Please provide a name!"}});g(s),t=s}}c.log.info(`We'll call your tutorial ${y.blue(t)}`);let r=await Se(t,e),n=I.resolve(process.cwd(),r);if(c.log.info(`Scaffolding tutorial in ${y.blue(n)}`),k.existsSync(n)&&!e.force){if(e.defaults)return console.error(`
${h()} Failed to create tutorial. Directory already exists.`),process.exit(1);let a;if(k.readdirSync(n).length>0?a=await c.confirm({message:"Directory is not empty. Continuing may overwrite existing files. Do you want to continue?",initialValue:!1}):a=await c.confirm({message:"Directory already exists. Continuing may overwrite existing files. Do you want to continue?",initialValue:!1}),g(a),!a)return Ae()}else e.dryRun||k.mkdirSync(n,{recursive:!0});await oe(n,e);let{selectedPackageManager:o,dependenciesInstalled:i}=await J(n,e);await re(n,e),Me(n,t,e),Te(n,o,e),await q(n,e),c.log.success(y.green("Tutorial successfully created!")),je(r,o,i),c.outro("You're all set!"),console.log("Until next time \u{1F44B}")}async function Se(e,t){let r=t.dir;if(r)return r;if(t.defaults)return`./${e}`;let n=await c.text({message:"Where should we create your new tutorial?",initialValue:`./${e}`,placeholder:"./",validate(o){if(!I.isAbsolute(o)&&!o.startsWith("./"))return"Please provide an absolute or relative path!"}});return g(n),n}function je(e,t,r){let n=0;c.log.message(y.bold.underline("Next Steps"));let o=[[`cd ${e}`,"Navigate to project"],[`${t} install`,"Install dependencies",!r],[`${t} run dev`,"Start development server"],[,`Head over to ${y.underline("http://localhost:4321")}`]];for(let[i,a,s]of o)s!==!1&&(n++,c.log.step(`${n}. ${i?`${y.blue(i)} - `:""}${a}`))}function Me(e,t,r){if(r.dryRun)return;let n=I.resolve(e,"package.json"),o=JSON.parse(k.readFileSync(n,"utf8"));o.name=t,se(o.dependencies,ae),se(o.devDependencies,ae),k.writeFileSync(n,JSON.stringify(o,void 0,2))}function se(e,t){for(let r in e)e[r]==="workspace:*"&&(e[r]=t)}function Te(e,t,r){if(r.dryRun)return;let n=I.resolve(e,"README.md"),o=k.readFileSync(n,"utf8");o=o.replaceAll("<% pkgManager %>",t??m.packageManager),k.writeFileSync(n,o)}function Ae(e=0){c.outro("Until next time!"),process.exit(e)}function Le(e){e.d&&(e.dir=e.d),e.p&&(e.packageManager=e.p),e.e&&(e.enterprise=e.e)}var De=new Set(["version","help","create"]);Ue();async function Ue(){let e=Ie(process.argv.slice(2)),t=Ne(e);try{console.log("");let r=await Fe(t,e);process.exit(r||0)}catch(r){console.error(`${h()} ${r.message}`),process.exit(1)}}async function Fe(e,t){switch(e){case"version":{console.log(`${C(u.name)} ${z.green(`v${u.version}`)}`);return}case"help":{S({commandName:u.name,prolog:`${C(u.name)} ${z.green(`v${u.version}`)} Create tutorial apps powered by WebContainer API`,usage:["[command] [...options]","[ -h | --help | -v | --version ]"],tables:{Commands:[["create","Create new tutorial app"],["help","Show this help message"]]}});return}case"create":return le(t);default:return console.error(`${h()} Unknown command ${z.red(e)}`),1}}function Ne(e){if(e.version||e.v)return"version";if(e._[0]==null&&(e.help||e.h))return"help";let t=String(e._.at(0));return De.has(t)?t:"help"}
{
"name": "@tutorialkit/cli",
"version": "0.0.1-alpha.17",
"version": "0.0.1-alpha.18",
"description": "Interactive tutorials powered by WebContainer API",

@@ -22,2 +22,6 @@ "type": "module",

"dependencies": {
"@babel/parser": "7.24.5",
"@babel/generator": "7.24.5",
"@babel/traverse": "7.24.5",
"@babel/types": "7.24.5",
"@clack/prompts": "^0.7.0",

@@ -30,2 +34,4 @@ "chalk": "^5.3.0",

"devDependencies": {
"@types/babel__generator": "7.6.8",
"@types/babel__traverse": "7.20.5",
"@types/fs-extra": "^11.0.4",

@@ -32,0 +38,0 @@ "@types/node": "^20.12.7",

{
"files.exclude": {
".astro": true,
".gitignore": true,
"astro.config.ts": true,
"theme.ts": true,
"uno.config.ts": true,
"tsconfig.json": true,
"package.json": true,
"package-lock.json": true,
"node_modules": true,
"icons": true,
"public": true,
"src/env.d.ts": true,

@@ -15,0 +9,0 @@ "**/.git": true,

@@ -1,9 +0,3 @@

import mdx from '@astrojs/mdx';
import react from '@astrojs/react';
import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections';
import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers';
import expressiveCode from 'astro-expressive-code';
import tutorialkit from '@tutorialkit/astro';
import { defineConfig } from 'astro/config';
import UnoCSS from 'unocss/astro';
import tutorialkit from '@tutorialkit/astro';

@@ -14,48 +8,3 @@ export default defineConfig({

},
integrations: [
tutorialkit(),
react(),
expressiveCode({
plugins: [pluginCollapsibleSections(), pluginLineNumbers()],
themes: ['dark-plus', 'light-plus'],
customizeTheme: (theme) => {
const isDark = theme.type === 'dark';
theme.styleOverrides = {
borderColor: 'var(--tk-border-secondary)',
borderWidth: '1px',
borderRadius: 'var(--code-border-radius, 0px)',
frames: {
terminalTitlebarBackground: `var(--tk-background-${isDark ? 'primary' : 'secondary'})`,
terminalTitlebarBorderBottomColor: `var(--tk-background-${isDark ? 'primary' : 'secondary'})`,
editorTabBorderRadius: 'var(--code-border-radius, 0px)',
editorTabBarBackground: `var(--tk-background-${isDark ? 'primary' : 'secondary'})`,
},
};
},
themeCssSelector: (theme) => {
let customThemeName = 'light';
if (theme.name === 'dark-plus') {
customThemeName = 'dark';
}
return `[data-theme='${customThemeName}']`;
},
defaultProps: {
showLineNumbers: false,
},
styleOverrides: {
frames: {
shadowColor: 'none',
},
},
}),
mdx(),
UnoCSS({
configDeps: ['./theme.ts'],
injectReset: true,
details: true,
}),
],
integrations: [tutorialkit()],
});

@@ -14,2 +14,3 @@ {

"dependencies": {
"@tutorialkit/components-react": "workspace:*",
"react": "^18.2.0",

@@ -20,6 +21,3 @@ "react-dom": "^18.2.0"

"@astrojs/check": "^0.6.0",
"@astrojs/mdx": "^3.0.0",
"@astrojs/react": "^3.3.4",
"@expressive-code/plugin-collapsible-sections": "^0.35.3",
"@expressive-code/plugin-line-numbers": "^0.35.3",
"@iconify-json/ph": "^1.1.12",

@@ -32,3 +30,2 @@ "@iconify-json/svg-spinners": "^1.1.2",

"astro": "^4.8.6",
"astro-expressive-code": "^0.35.3",
"fast-glob": "^3.3.2",

@@ -35,0 +32,0 @@ "prettier-plugin-astro": "^0.13.0",

import transformerDirectives from '@unocss/transformer-directives';
import { globSync } from 'fast-glob';
import fs from 'node:fs/promises';
import { basename, dirname } from 'node:path';
import { basename, dirname, join } from 'node:path';
import { defineConfig, presetIcons, presetUno } from 'unocss';

@@ -27,10 +27,8 @@ import { theme } from './theme';

// this didn't work
// filesystem: ['node_modules/@tutorialkit/astro/node_modules/@tutorialkit/components-react/dist/**/*.js'],
// filesystem: ['node_modules/**/@tutorialkit/components-react/dist/**/*.js'],
//
// but this hack did:
inline: globSync('node_modules/@tutorialkit/astro/node_modules/@tutorialkit/components-react/dist/**/*.js').map(
(filePath) => {
return () => fs.readFile(filePath, { encoding: 'utf8' });
},
),
inline: globSync(join(require.resolve('@tutorialkit/components-react'), '../**/*.js')).map((filePath) => {
return () => fs.readFile(filePath, { encoding: 'utf8' });
}),
},

@@ -50,3 +48,2 @@ rules: [

},
details: true,
transformers: [transformerDirectives()],

@@ -53,0 +50,0 @@ presets: [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc