create-instant-app 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +2 -2
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -8,8 +8,8 @@ Usage: npx create-instant-app my-app --yes`);return{...C,appName:n,base:X(r)??C.
8
8
  \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 |_|_| |_|___/\\__\\__,_|_| |_|\\__|`,te=()=>{Me(`
9
9
  `+$e.split(`
10
10
  `).map(e=>`${ee.gray("\u2502")}${ee.hex("#EA580D").bold(" "+e)}`).join(`
11
- `))};import d from"path";import Ge from"degit";import c from"fs-extra";import ne from"path";import{fileURLToPath as De}from"url";var Be=De(import.meta.url),Ue=ne.dirname(Be),w=ne.join(Ue,"../");import _ from"chalk";var k=e=>{if(e==="bun-react")return"bun";let t=process.env.npm_config_user_agent;return t?t.startsWith("yarn")?"yarn":t.startsWith("pnpm")?"pnpm":t.startsWith("bun")?"bun":"npm":"npm"};import{renderUnwrap as re,UI as y}from"instant-cli/ui";import Le from"slugify";import Ve from"ignore";var oe=async(e,t)=>{let n=d.resolve(process.cwd(),t);if(c.existsSync(n))if(c.readdirSync(n).length===0)y.log(`${_.cyan.bold(e.appName)} exists but is empty, continuing...`,y.ciaModifier(null));else{let o=await re(new y.Select({promptText:_.redBright(`${_.bold("Warning:")} ${_.bold(e.appName)} already exists and isn't empty. How would you like to proceed?`),options:[{label:"Abort installation",value:"abort"},{label:"Clear the directory and continue installation",value:"clear"}],defaultValue:"abort",modifyOutput:y.ciaModifier()}));o==="abort"&&(y.log("Aborting installation..."),process.exit(1)),o==="clear"&&c.emptyDirSync(n)}let r=Je({projectDir:n,baseTemplateName:e.base}),a=e.appName==="."?"App":_.hex("#EA570B").bold(e.appName);if(await re(new y.Spinner({promise:r,workingText:"Scaffolding project files...",doneText:`Successfully scaffolded ${a}!`,errorText:"Error scaffolding project files",modifyOutput:y.ciaModifier(null)})),c.pathExistsSync(d.join(n,"pnpm-lock.yaml"))&&c.removeSync(d.join(n,"pnpm-lock.yaml")),c.pathExistsSync(d.join(n,"bun.lock"))&&c.removeSync(d.join(n,"bun.lock")),k(e.base)==="pnpm"&&e.base==="expo"&&await c.appendFile(d.join(n,".npmrc"),`node-linker=hoisted
12
- enable-pre-post-scripts=true`),e.base==="expo"){let o=Le.default(t);U(d.join(n,"app.json"),'"name": "expo-template"',`"name": "${t}"`),U(d.join(n,"app.json"),'"slug": "expo-template"',`"slug": "${o}"`),U(d.join(n,"app/_layout.tsx"),'"My Instant App"',`"${t}"`)}return n},U=(e,t,n)=>{let a=c.readFileSync(e,"utf8").replaceAll(t,n);c.writeFileSync(e,a)},We=async({projectDir:e,baseTemplateName:t})=>{let n=`instantdb/instant/examples/${t}`;await Ge(n,{mode:"tar",cache:!1}).clone(e)};async function ze(e,t){let n=Ve();n.add(".git");try{let r=d.join(e,".gitignore"),a=await c.readFile(r,"utf8");n.add(a)}catch{}await c.copy(e,t,{filter:r=>{let a=d.relative(e,r);return a===""?!0:!n.ignores(a)}})}var Je=async({projectDir:e,baseTemplateName:t})=>{let n=d.join(w,`template/base/${t}`),r=!!process.env.INSTANT_CLI_DEV&&!!process.env.INSTANT_REPO_FOLDER,a=c.pathExistsSync(n),o=r?"dev":a?"bundled-template":"degit";if(o==="bundled-template"){c.copySync(n,e);let i=d.join(e,"_gitignore"),s=d.join(e,".gitignore");c.pathExistsSync(i)&&c.renameSync(i,s);return}if(o==="dev"){let i=process.env.INSTANT_REPO_FOLDER;if(!i)throw new Error("INSTANT_REPO_FOLDER is required when using repo-examples scaffolding.");let s=d.join(i,"examples",t);await ze(s,e);return}process.env.INSTANT_CLI_DEV&&!process.env.INSTANT_REPO_FOLDER&&y.log(_.bold.yellowBright(`WARNING: INSTANT_CLI_DEV is TRUE but no INSTANT_REPO_FOLDER is set.
11
+ `))};import d from"path";import Ge from"tiged";import c from"fs-extra";import ne from"path";import{fileURLToPath as De}from"url";var Be=De(import.meta.url),Ue=ne.dirname(Be),w=ne.join(Ue,"../");import _ from"chalk";var k=e=>{if(e==="bun-react")return"bun";let t=process.env.npm_config_user_agent;return t?t.startsWith("yarn")?"yarn":t.startsWith("pnpm")?"pnpm":t.startsWith("bun")?"bun":"npm":"npm"};import{renderUnwrap as re,UI as y}from"instant-cli/ui";import Le from"slugify";import Ve from"ignore";var oe=async(e,t)=>{let n=d.resolve(process.cwd(),t);if(c.existsSync(n))if(c.readdirSync(n).length===0)y.log(`${_.cyan.bold(e.appName)} exists but is empty, continuing...`,y.ciaModifier(null));else{let o=await re(new y.Select({promptText:_.redBright(`${_.bold("Warning:")} ${_.bold(e.appName)} already exists and isn't empty. How would you like to proceed?`),options:[{label:"Abort installation",value:"abort"},{label:"Clear the directory and continue installation",value:"clear"}],defaultValue:"abort",modifyOutput:y.ciaModifier()}));o==="abort"&&(y.log("Aborting installation..."),process.exit(1)),o==="clear"&&c.emptyDirSync(n)}let r=Je({projectDir:n,baseTemplateName:e.base}),a=e.appName==="."?"App":_.hex("#EA570B").bold(e.appName);if(await re(new y.Spinner({promise:r,workingText:"Scaffolding project files...",doneText:`Successfully scaffolded ${a}!`,errorText:"Error scaffolding project files",modifyOutput:y.ciaModifier(null)})),c.pathExistsSync(d.join(n,"pnpm-lock.yaml"))&&c.removeSync(d.join(n,"pnpm-lock.yaml")),c.pathExistsSync(d.join(n,"bun.lock"))&&c.removeSync(d.join(n,"bun.lock")),k(e.base)==="pnpm"&&e.base==="expo"&&await c.appendFile(d.join(n,".npmrc"),`node-linker=hoisted
12
+ enable-pre-post-scripts=true`),e.base==="expo"){let o=Le.default(t);U(d.join(n,"app.json"),'"name": "expo-template"',`"name": "${t}"`),U(d.join(n,"app.json"),'"slug": "expo-template"',`"slug": "${o}"`),U(d.join(n,"app/_layout.tsx"),'"My Instant App"',`"${t}"`)}return n},U=(e,t,n)=>{let a=c.readFileSync(e,"utf8").replaceAll(t,n);c.writeFileSync(e,a)},We=async({projectDir:e,baseTemplateName:t})=>{let n=`instantdb/instant/examples/${t}`;await Ge(n,{mode:"tar",disableCache:!0}).clone(e)};async function ze(e,t){let n=Ve();n.add(".git");try{let r=d.join(e,".gitignore"),a=await c.readFile(r,"utf8");n.add(a)}catch{}await c.copy(e,t,{filter:r=>{let a=d.relative(e,r);return a===""?!0:!n.ignores(a)}})}var Je=async({projectDir:e,baseTemplateName:t})=>{let n=d.join(w,`template/base/${t}`),r=!!process.env.INSTANT_CLI_DEV&&!!process.env.INSTANT_REPO_FOLDER,a=c.pathExistsSync(n),o=r?"dev":a?"bundled-template":"tiged";if(o==="bundled-template"){c.copySync(n,e);let i=d.join(e,"_gitignore"),s=d.join(e,".gitignore");c.pathExistsSync(i)&&c.renameSync(i,s);return}if(o==="dev"){let i=process.env.INSTANT_REPO_FOLDER;if(!i)throw new Error("INSTANT_REPO_FOLDER is required when using repo-examples scaffolding.");let s=d.join(i,"examples",t);await ze(s,e);return}process.env.INSTANT_CLI_DEV&&!process.env.INSTANT_REPO_FOLDER&&y.log(_.bold.yellowBright(`WARNING: INSTANT_CLI_DEV is TRUE but no INSTANT_REPO_FOLDER is set.
13
13
  Using git to clone from main...`),y.ciaModifier(null)),await We({projectDir:e,baseTemplateName:t})};import{execa as Ke}from"execa";import{renderUnwrap as He,UI as O}from"instant-cli/ui";var ae=async(e,t)=>{let n=Ke(e,["install"],{cwd:t}),r=await He(new O.Spinner({promise:n,workingText:`Installing dependencies with ${e}...`,doneText:"Successfully installed dependencies!",modifyOutput:O.ciaModifier(null)}));r.exitCode!==0&&(O.log(r.stderr,O.ciaModifier(null)),process.exit(1))};import It from"chalk";import T from"fs-extra";import u from"path";var ie=({projectDir:e,ruleFilesToAdd:t})=>{if(t!==null)switch(t){case"cursor":T.ensureDirSync(u.join(e,".cursor/rules")),T.copyFileSync(u.join(w,"template/rules/cursor-rules.md"),u.join(e,".cursor/rules/instant.mdc"));break;case"claude":T.copyFileSync(u.join(w,"template/rules/AGENTS.md"),u.join(e,"CLAUDE.md"));break;case"codex":T.copyFileSync(u.join(w,"template/rules/AGENTS.md"),u.join(e,"AGENTS.md"));break;case"gemini":T.copyFileSync(u.join(w,"template/rules/AGENTS.md"),u.join(e,"GEMINI.md"));break;case"zed":T.copyFileSync(u.join(w,"template/rules/AGENTS.md"),u.join(e,"AGENTS.md"));break;case"windsurf":T.ensureDirSync(u.join(e,".windsurf/rules")),T.copyFileSync(u.join(w,"template/rules/windsurf-rules.md"),u.join(e,".windsurf/rules/instant.md"));break}};import{execSync as L}from"child_process";import G from"path";import*as pe from"@clack/prompts";import j from"chalk";import{execa as S}from"execa";import le from"fs-extra";import{renderUnwrap as se,UI as I}from"instant-cli/ui";var Ye=e=>{try{return L("git --version",{cwd:e}),!0}catch{return!1}},qe=e=>le.existsSync(G.join(e,".git")),Xe=async e=>{try{return await S("git",["rev-parse","--is-inside-work-tree"],{cwd:e,stdout:"ignore"}),!0}catch{return!1}},Ze=()=>{let t=L("git --version").toString().trim().split(" ")[2],n=t?.split(".")[0],r=t?.split(".")[1];return{major:Number(n),minor:Number(r)}},Qe=()=>L("git config --global init.defaultBranch || echo main").toString().trim(),ce=async e=>{if(!Ye(e)){pe.log.warn("Git is not installed. Skipping Git initialization.");return}let t=qe(e),n=await Xe(e),r=G.parse(e).name;if(n&&t){if(!await se(new I.Confirmation({promptText:`${j.redBright.bold("Warning:")} Git is already initialized in "${r}". Initializing a new git repository would delete the previous history. Would you like to continue anyways?`,defaultValue:!1,modifyOutput:I.ciaModifier()})))return;le.removeSync(G.join(e,".git"))}else if(n&&!t&&!await se(new I.Confirmation({promptText:`${j.redBright.bold("Warning:")} "${r}" is already in a git worktree.
14
14
  Would you still like to initialize a new git repository in this directory?
15
15
  `,defaultValue:!1,modifyOutput:I.ciaModifier()})))return;try{let a=Qe(),{major:o,minor:i}=Ze();o<2||o==2&&i<28?(await S("git",["init"],{cwd:e}),await S("git",["symbolic-ref","HEAD",`refs/heads/${a}`],{cwd:e})):await S("git",["init",`--initial-branch=${a}`],{cwd:e}),await S("git",["add","."],{cwd:e}),await S("git",["commit","-m","Initial commit (create-instant-app)"],{cwd:e}),I.log(j.dim(`${j.green("\u2713")} Git repository initialized successfully.`),I.ciaModifier(null))}catch{}};import tt from"env-paths";import{mkdir as nt,readFile as rt,writeFile as ot}from"node:fs/promises";import at from"open";import{join as it}from"node:path";import{randomUUID as me}from"node:crypto";import{version as et}from"@instantdb/version";var de=!!process.env.INSTANT_CLI_DEV,ue=de?"http://localhost:3000":"https://instantdb.com",V=process.env.INSTANT_CLI_API_URI||(de?"http://localhost:8888":"https://api.instantdb.com");async function b({path:e,body:t,method:n="GET",authToken:r,metadata:a}){let i={"Content-Type":"application/json","X-Instant-Source":"create-instant-app","X-Instant-Version":et,"X-Instant-Command":"create"};r&&(i.Authorization=`Bearer ${r}`),a&&(i["X-Instant-Metadata"]=JSON.stringify(a));let s=await fetch(`${V}${e}`,{method:n??"GET",headers:i,body:t?JSON.stringify(t):void 0,signal:AbortSignal.timeout(3e5)}),p;try{p=await s.json()}catch{p=null}if(!s.ok){let g=p.message||p.hint?.errors?.[0]?.message||"There was an error";throw new Error(g)}return p}import{renderUnwrap as R,UI as m}from"instant-cli/ui";function F(e){return e.replace(/[-_]/g," ").replace(/\b\w/g,t=>t.toUpperCase())}var st=!!process.env.INSTANT_CLI_DEV,pt=!!process.env.INSTANT_CLI_FORCE_EPHEMERAL;function ge(){let e=`instantdb-${st?"dev":"prod"}`,{config:t}=tt(e);return{authConfigFilePath:it(t,"a"),appConfigDirPath:t}}var fe=async(e,t,n,r)=>{let a=me(),o=me(),i={id:a,title:e,admin_token:o,org_id:n};return r?.rules&&(i.rules=r.rules),r?.schema&&(i.schema=r.schema),await b({method:"POST",authToken:t,path:"/dash/apps",body:i,metadata:r}),{appID:a,adminToken:o,source:"created"}},W=(e,t,n)=>{b({method:"POST",path:`/dash/apps/${e}/track-import`,authToken:t,metadata:n}).catch(()=>{})},he=async e=>await b({method:"GET",path:"/dash",authToken:e}),we=async(e,t)=>await b({method:"GET",path:`/dash/orgs/${t}`,authToken:e});var lt=async(e,t)=>{try{let n=await he(e),r=n.apps.find(a=>a.id===t);if(r)return{appId:r.id,adminToken:r.admin_token};for(let a of n.orgs){let{apps:o}=await we(e,a.id),i=o.find(s=>s.id===t);if(i)return{appId:i.id,adminToken:i.admin_token}}return null}catch{return null}},ct=async(e,t)=>{try{return await b({method:"GET",path:`/dash/apps/${e}/schema/pull`,authToken:t}),!0}catch{return!1}},dt=async()=>pt?null:process.env.INSTANT_CLI_AUTH_TOKEN?process.env.INSTANT_CLI_AUTH_TOKEN:await rt(ge().authConfigFilePath,"utf-8").catch(()=>null),z=async(e,t)=>{let n=await b({authToken:null,method:"POST",path:"/dash/apps/ephemeral",body:{title:e,rules:{$users:{view:"true"},$files:{allow:{view:"true",create:"true",delete:"true"}}}},metadata:t});return{appId:n.app.id,adminToken:n.app["admin-token"]}},ye=async(e,t,n)=>{let r=await dt();if(t?.yes&&!t?.app)if(r){let{appID:s,adminToken:p}=await fe(F(e),r,void 0,n);return{appId:s,adminToken:p,approach:"create"}}else{let{appId:s,adminToken:p}=await z(F(e),n);return{appId:s,adminToken:p,approach:"ephemeral"}}if(t?.app){if(t.token){if(!await ct(t.app,t.token))throw new Error("Invalid app ID and token combination. Please verify both the app ID and token are correct.");return m.log(`Linking to app: ${t.app}`,m.ciaModifier(null)),W(t.app,t.token,n),{appId:t.app,adminToken:t.token,approach:"import"}}if(r){let s=await lt(r,t.app);if(!s)throw new Error(`You don't have access to app "${t.app}". Please check the app ID or use --token to provide a token.`);return m.log(`Linking to app: ${t.app}`,m.ciaModifier(null)),W(s.appId,r,n),{appId:s.appId,adminToken:s.adminToken,approach:"import"}}throw new Error(`You must be logged in or provide --token when using --app. Either run 'npx instant-cli login' first, or use: --app ${t.app} --token <token>`)}if(!r){let s=await R(new m.Select({promptText:"You are not logged in.",options:[{label:"Login to your Instant account",value:"login"},{label:"Create a temporary app",value:"ephemeral"},{label:"Create an app later",value:"skip"}],modifyOutput:m.ciaModifier()}));if(s==="login"){let p=await b({authToken:null,method:"POST",path:"/dash/cli/auth/register"}).catch(Ee=>{throw new Error("Failed to register",{cause:Ee})}),{secret:g,ticket:h}=p;at(`${ue}/dash?ticket=${h}`);let M=mt({secret:g}),J=await R(new m.Spinner({promise:M,workingText:"Waiting for login in browser",disappearWhenDone:!0,modifyOutput:m.ciaModifier(null)}));await ft(J.token),r=J.token}if(s==="skip")return m.log("Skipping app link step",m.ciaModifier(null)),null;if(s==="ephemeral"){let p=await R(new m.TextInput({defaultValue:"my-cool-app",prompt:"Enter a name for your temporary app:",placeholder:"my-cool-app",modifyOutput:m.ciaModifier()}));return{...await z(p,n),approach:"ephemeral"}}}if(!r)return null;let a=await he(r).catch(s=>{throw new Error("Failed to fetch dashboard",{cause:s})}),o=a.orgs.filter(s=>s.role!=="app-member");a.orgs=o;let i=await R(new m.AppSelector({startingMenuIndex:0,defaultAppName:F(e),allowCreate:!0,allowEphemeral:!0,api:{getDash(){return a},createEphemeralApp(s){return z(s,n)},getAppsForOrg:async s=>{let{apps:p}=await we(r,s);return{apps:p}},createApp:async(s,p)=>{let{appID:g,adminToken:h}=await fe(s,r,p,n);return{appId:g,adminToken:h}}},modifyOutput:m.ciaModifier()}));return i?.approach==="import"&&W(i.appId,r,n),i};function ut(e){return new Promise(t=>setTimeout(t,e))}async function mt({secret:e}){for(let t=1;t<=120;t++){await ut(1e3);let n=await fetch(`${V}/dash/cli/auth/check`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({secret:e})});if(!(!n.ok&&(await n.json()).hint.errors?.[0]?.issue==="waiting-for-user")&&n.ok)return n.json()}throw new Error("Timed out waiting for login")}async function ft(e){let t=ge();return await nt(t.appConfigDirPath,{recursive:!0}),ot(t.authConfigFilePath,e,"utf-8")}import gt from"fs-extra";import ht from"path";var wt={"next-js-app-dir":"NEXT_PUBLIC_INSTANT_APP_ID","vite-vanilla":"VITE_INSTANT_APP_ID",expo:"EXPO_PUBLIC_INSTANT_APP_ID","tanstack-start":"VITE_INSTANT_APP_ID","bun-react":"BUN_PUBLIC_INSTANT_APP_ID","solidjs-vite":"VITE_INSTANT_APP_ID",sveltekit:"VITE_INSTANT_APP_ID","tanstack-start-with-tanstack-query":"VITE_INSTANT_APP_ID","vercel-ai-sdk":"NEXT_PUBLIC_INSTANT_APP_ID","ai-chat":"NEXT_PUBLIC_INSTANT_APP_ID"},Te=(e,t,n,r)=>{let a=ht.join(t,".env"),i=`${wt[e.base]}=${n}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-instant-app",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Scaffold a new web/mobile app with InstantDB",
5
5
  "homepage": "https://github.com/instantdb/instant/tree/main/client/packages/create-instant-app",
6
6
  "repository": {
@@ -23,10 +23,8 @@
23
23
  "@clack/core": "^0.5.0",
24
24
  "@clack/prompts": "^0.11.0",
25
25
  "@ianvs/prettier-plugin-sort-imports": "^4.2.1",
26
- "@types/degit": "^2.8.6",
27
26
  "chalk": "5.2.0",
28
27
  "commander": "^10.0.1",
29
- "degit": "^2.8.4",
30
28
  "env-paths": "^3.0.0",
31
29
  "execa": "^7.2.0",
32
30
  "fs-extra": "^11.3.1",
@@ -36,12 +34,14 @@
36
34
  "ora": "6.3.1",
37
35
  "slugify": "^1.6.6",
38
36
  "sort-package-json": "^2.10.0",
39
- "@instantdb/platform": "1.0.7",
40
- "@instantdb/version": "1.0.7",
41
- "instant-cli": "1.0.7"
37
+ "tiged": "^2.12.7",
38
+ "@instantdb/platform": "1.0.8",
39
+ "@instantdb/version": "1.0.8",
40
+ "instant-cli": "1.0.8"
42
41
  },
43
42
  "devDependencies": {
44
43
  "@anthropic-ai/sdk": "^0.60.0",
44
+ "@types/degit": "^2.8.6",
45
45
  "@types/fs-extra": "^11.0.4",
46
46
  "@types/node": "^18.11.18",
47
47
  "tsup": "^6.7.0",