create-gui 8.3.0 → 8.3.2

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 (125) hide show
  1. package/dist/cjs/create-gui-constants.js +5 -0
  2. package/dist/cjs/create-gui-constants.js.map +1 -0
  3. package/dist/cjs/helpers/asciiArts.js +43 -0
  4. package/dist/cjs/helpers/asciiArts.js.map +1 -0
  5. package/dist/cjs/helpers/cloneStarter.js +192 -0
  6. package/dist/cjs/helpers/cloneStarter.js.map +1 -0
  7. package/dist/cjs/helpers/getProjectName.js +46 -0
  8. package/dist/cjs/helpers/getProjectName.js.map +1 -0
  9. package/dist/cjs/helpers/getTemplateInfo.js +31 -0
  10. package/dist/cjs/helpers/getTemplateInfo.js.map +1 -0
  11. package/dist/cjs/helpers/installDependencies.js +26 -0
  12. package/dist/cjs/helpers/installDependencies.js.map +1 -0
  13. package/dist/cjs/helpers/rainbowChalk.js +20 -0
  14. package/dist/cjs/helpers/rainbowChalk.js.map +1 -0
  15. package/dist/cjs/helpers/validateNpmPackage.js +16 -0
  16. package/dist/cjs/helpers/validateNpmPackage.js.map +1 -0
  17. package/dist/cjs/here.js +6 -0
  18. package/dist/cjs/here.js.map +1 -0
  19. package/dist/cjs/index.js +165 -0
  20. package/dist/cjs/index.js.map +1 -0
  21. package/dist/cjs/manifest.js +8 -0
  22. package/dist/cjs/manifest.js.map +1 -0
  23. package/dist/cjs/package.json +1 -0
  24. package/dist/cjs/steps/expo-router.js +18 -0
  25. package/dist/cjs/steps/expo-router.js.map +1 -0
  26. package/dist/cjs/steps/remix.js +22 -0
  27. package/dist/cjs/steps/remix.js.map +1 -0
  28. package/dist/cjs/steps/starter-free.js +35 -0
  29. package/dist/cjs/steps/starter-free.js.map +1 -0
  30. package/dist/cjs/steps/takeout.js +174 -0
  31. package/dist/cjs/steps/takeout.js.map +1 -0
  32. package/dist/cjs/steps/types.js +3 -0
  33. package/dist/cjs/steps/types.js.map +1 -0
  34. package/dist/cjs/templates.js +97 -0
  35. package/dist/cjs/templates.js.map +1 -0
  36. package/dist/esm/create-gui-constants.js +2 -0
  37. package/dist/esm/create-gui-constants.js.map +1 -0
  38. package/dist/esm/helpers/asciiArts.js +39 -0
  39. package/dist/esm/helpers/asciiArts.js.map +1 -0
  40. package/dist/esm/helpers/cloneStarter.js +187 -0
  41. package/dist/esm/helpers/cloneStarter.js.map +1 -0
  42. package/dist/esm/helpers/getProjectName.js +41 -0
  43. package/dist/esm/helpers/getProjectName.js.map +1 -0
  44. package/dist/esm/helpers/getTemplateInfo.js +26 -0
  45. package/dist/esm/helpers/getTemplateInfo.js.map +1 -0
  46. package/dist/esm/helpers/installDependencies.js +22 -0
  47. package/dist/esm/helpers/installDependencies.js.map +1 -0
  48. package/dist/esm/helpers/rainbowChalk.js +15 -0
  49. package/dist/esm/helpers/rainbowChalk.js.map +1 -0
  50. package/dist/esm/helpers/validateNpmPackage.js +12 -0
  51. package/dist/esm/helpers/validateNpmPackage.js.map +1 -0
  52. package/dist/esm/here.js +3 -0
  53. package/dist/esm/here.js.map +1 -0
  54. package/dist/esm/index.js +162 -0
  55. package/dist/esm/index.js.map +1 -0
  56. package/dist/esm/manifest.js +5 -0
  57. package/dist/esm/manifest.js.map +1 -0
  58. package/dist/esm/steps/expo-router.js +15 -0
  59. package/dist/esm/steps/expo-router.js.map +1 -0
  60. package/dist/esm/steps/remix.js +19 -0
  61. package/dist/esm/steps/remix.js.map +1 -0
  62. package/dist/esm/steps/starter-free.js +32 -0
  63. package/dist/esm/steps/starter-free.js.map +1 -0
  64. package/dist/esm/steps/takeout.js +171 -0
  65. package/dist/esm/steps/takeout.js.map +1 -0
  66. package/dist/esm/steps/types.js +2 -0
  67. package/dist/esm/steps/types.js.map +1 -0
  68. package/dist/esm/templates.js +93 -0
  69. package/dist/esm/templates.js.map +1 -0
  70. package/package.json +38 -30
  71. package/src/create-gui-constants.ts +1 -0
  72. package/src/helpers/asciiArts.ts +49 -0
  73. package/src/helpers/cloneStarter.ts +220 -0
  74. package/src/helpers/getProjectName.ts +48 -0
  75. package/src/helpers/getTemplateInfo.ts +34 -0
  76. package/src/helpers/installDependencies.ts +23 -0
  77. package/src/helpers/rainbowChalk.ts +17 -0
  78. package/src/helpers/validateNpmPackage.ts +16 -0
  79. package/src/here.cjs.ts +3 -0
  80. package/src/here.ts +2 -0
  81. package/src/index.ts +223 -0
  82. package/src/manifest.ts +10 -0
  83. package/src/steps/expo-router.ts +20 -0
  84. package/src/steps/remix.ts +24 -0
  85. package/src/steps/starter-free.ts +40 -0
  86. package/src/steps/takeout.ts +210 -0
  87. package/src/steps/types.ts +5 -0
  88. package/src/templates.ts +116 -0
  89. package/types/create-gui-constants.d.ts +2 -0
  90. package/types/create-gui-constants.d.ts.map +1 -0
  91. package/types/helpers/asciiArts.d.ts +5 -0
  92. package/types/helpers/asciiArts.d.ts.map +1 -0
  93. package/types/helpers/cloneStarter.d.ts +3 -0
  94. package/types/helpers/cloneStarter.d.ts.map +1 -0
  95. package/types/helpers/getProjectName.d.ts +2 -0
  96. package/types/helpers/getProjectName.d.ts.map +1 -0
  97. package/types/helpers/getTemplateInfo.d.ts +3 -0
  98. package/types/helpers/getTemplateInfo.d.ts.map +1 -0
  99. package/types/helpers/installDependencies.d.ts +2 -0
  100. package/types/helpers/installDependencies.d.ts.map +1 -0
  101. package/types/helpers/rainbowChalk.d.ts +3 -0
  102. package/types/helpers/rainbowChalk.d.ts.map +1 -0
  103. package/types/helpers/validateNpmPackage.d.ts +5 -0
  104. package/types/helpers/validateNpmPackage.d.ts.map +1 -0
  105. package/types/here.d.ts +2 -0
  106. package/types/here.d.ts.map +1 -0
  107. package/types/index.d.ts +3 -0
  108. package/types/index.d.ts.map +1 -0
  109. package/types/manifest.d.ts +5 -0
  110. package/types/manifest.d.ts.map +1 -0
  111. package/types/steps/expo-router.d.ts +4 -0
  112. package/types/steps/expo-router.d.ts.map +1 -0
  113. package/types/steps/remix.d.ts +4 -0
  114. package/types/steps/remix.d.ts.map +1 -0
  115. package/types/steps/starter-free.d.ts +4 -0
  116. package/types/steps/starter-free.d.ts.map +1 -0
  117. package/types/steps/takeout.d.ts +4 -0
  118. package/types/steps/takeout.d.ts.map +1 -0
  119. package/types/steps/types.d.ts +6 -0
  120. package/types/steps/types.d.ts.map +1 -0
  121. package/types/templates.d.ts +16 -0
  122. package/types/templates.d.ts.map +1 -0
  123. package/dist/index.cjs +0 -929
  124. package/dist/index.native.js +0 -930
  125. package/run.js +0 -12
package/src/index.ts ADDED
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env node
2
+ // inspired by https://github.com/vercel/next.js/blob/0355e5f63f87db489f36db8d814958cb4c2b828b/packages/create-next-app/helpers/examples.ts#L71
3
+
4
+ import chalk from 'chalk'
5
+ import { Command } from 'commander'
6
+ import { detect } from 'detect-package-manager'
7
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs'
8
+ import { execSync } from 'node:child_process'
9
+ import fs from 'node:fs'
10
+ import path from 'node:path'
11
+ import { cwd } from 'node:process'
12
+ import open from 'opener'
13
+ import prompts from 'prompts'
14
+ import { IS_TEST } from './create-gui-constants.ts'
15
+ import { hanzoguiDuckAsciiArt, hanzoguiRainbowAsciiArt } from './helpers/asciiArts.ts'
16
+ import { cloneStarter } from './helpers/cloneStarter.ts'
17
+ import { getProjectName } from './helpers/getProjectName.ts'
18
+ import { getTemplateInfo } from './helpers/getTemplateInfo.ts'
19
+ import { installDependencies } from './helpers/installDependencies.ts'
20
+ import { validateNpmName } from './helpers/validateNpmPackage.ts'
21
+ import { packageJson } from './manifest.ts'
22
+
23
+ let projectPath = ''
24
+
25
+ if (IS_TEST) {
26
+ console.info(`🧐 Running create-gui in test mode 🧐`)
27
+ }
28
+
29
+ function exit() {
30
+ process.exit(0)
31
+ }
32
+
33
+ process.on('SIGTERM', exit)
34
+ process.on('SIGINT', exit)
35
+
36
+ const program = new Command(packageJson.name)
37
+ .version(packageJson.version)
38
+ .arguments('[project-directory]')
39
+ .action((name) => {
40
+ projectPath = name
41
+ })
42
+ .option(`--info`, 'Just shows the setup guide for the starter.')
43
+ .option(
44
+ `-t, --template <template>`,
45
+ 'Choose between four or more starter templates.',
46
+ ''
47
+ )
48
+ .allowUnknownOption()
49
+ .usage(
50
+ `${chalk.green('<project-directory>')} [options]
51
+
52
+ Example usage:
53
+
54
+ ${chalk.blueBright(`npx ${packageJson.name} next-expo`)}`
55
+ )
56
+ .parse(process.argv)
57
+
58
+ if (process.argv.includes('--version')) {
59
+ console.info(packageJson.version)
60
+ process.exit(0)
61
+ }
62
+ const options = program.opts()
63
+ const info = !!options.info
64
+
65
+ async function run() {
66
+ try {
67
+ if (info) {
68
+ let template = await getTemplateInfo(options.template)
69
+ if (template?.extraSteps) {
70
+ await template.extraSteps({
71
+ isFullClone: false,
72
+ projectName: path.basename(cwd()),
73
+ projectPath: cwd(),
74
+ })
75
+ }
76
+ process.exit(0)
77
+ }
78
+
79
+ console.info()
80
+ console.info(
81
+ chalk.bold(
82
+ ' Note: You may need to run "npm create hanzogui@latest" to get the latest version!'
83
+ )
84
+ )
85
+ console.info()
86
+
87
+ console.info() // this newline prevents the ascii art from breaking
88
+ console.info(hanzoguiRainbowAsciiArt)
89
+ console.info(chalk.bold('Creating hanzogui app...'))
90
+
91
+ const gitVersionString = Number.parseFloat(
92
+ execSync(`git --version`).toString().replace(`git version `, '').trim()
93
+ )
94
+ if (gitVersionString < 2.27) {
95
+ console.error(`\n\n ⚠️ Gui can't install: Git version must be >= 2.27\n\n`)
96
+ process.exit(1)
97
+ }
98
+
99
+ projectPath ||= await getProjectName(projectPath)
100
+
101
+ let template = await getTemplateInfo(options.template)
102
+
103
+ if (template.type === 'premium') {
104
+ const didPurchase = (
105
+ await prompts({
106
+ type: 'confirm',
107
+ name: 'purchased',
108
+ message: `Have you purchased Takeout on https://hanzogui.dev/takeout`,
109
+ })
110
+ ).purchased
111
+
112
+ if (!didPurchase) {
113
+ open(`https://hanzogui.dev/takeout`)
114
+ console.info(
115
+ `\nOpening Takeout website - once you purchase you can restart the create process. Thank you!\n`
116
+ )
117
+ process.exit(0)
118
+ }
119
+ }
120
+
121
+ // space
122
+ console.info()
123
+
124
+ const resolvedProjectPath = path.resolve(process.cwd(), projectPath)
125
+ const projectName = path.basename(resolvedProjectPath)
126
+
127
+ const { valid, problems } = validateNpmName(projectName)
128
+ if (!valid) {
129
+ console.error(
130
+ `Could not create a project called ${chalk.red(
131
+ `"${projectName}"`
132
+ )} because of npm naming restrictions:`
133
+ )
134
+
135
+ problems!.forEach((p) => console.error(` ${chalk.red.bold('*')} ${p}`))
136
+ process.exit(1)
137
+ }
138
+
139
+ if (fs.existsSync(resolvedProjectPath)) {
140
+ console.info()
141
+ console.info(
142
+ chalk.red('🚨 [hanzogui] error'),
143
+ `You tried to make a project called ${chalk.underline(
144
+ chalk.blueBright(projectName)
145
+ )}, but a folder with that name already exists: ${chalk.blueBright(
146
+ resolvedProjectPath
147
+ )}
148
+
149
+ ${chalk.bold(chalk.red(`Please pick a different project name 🥸`))}`
150
+ )
151
+ console.info()
152
+ console.info()
153
+ process.exit(1)
154
+ }
155
+ console.info()
156
+ console.info(
157
+ `Creating a new hanzogui app ${chalk.blueBright(resolvedProjectPath)}...`
158
+ )
159
+ fs.mkdirSync(resolvedProjectPath)
160
+ console.info(chalk.green(`${projectName} folder created.`))
161
+
162
+ try {
163
+ await cloneStarter(template, resolvedProjectPath, projectName)
164
+ process.chdir(resolvedProjectPath)
165
+ // space
166
+ console.info()
167
+ } catch (e) {
168
+ console.error(
169
+ `[hanzogui] Failed to copy example into ${resolvedProjectPath}\n\n`,
170
+ e
171
+ )
172
+ process.exit(1)
173
+ }
174
+
175
+ // change root package.json's name to project name
176
+ updatePackageJsonName(projectName, resolvedProjectPath)
177
+
178
+ console.info('Installing packages. This might take a couple of minutes.')
179
+ console.info()
180
+
181
+ const packageManager =
182
+ ('packageManager' in template ? template.packageManager : undefined) ||
183
+ (await detect())
184
+
185
+ try {
186
+ console.info('installing with ' + packageManager)
187
+ await installDependencies(resolvedProjectPath, packageManager)
188
+ } catch (e: any) {
189
+ console.error('[hanzogui] error installing with ' + packageManager + '\n' + `${e}`)
190
+ process.exit(1)
191
+ }
192
+
193
+ await template?.extraSteps?.({
194
+ isFullClone: true,
195
+ projectName,
196
+ projectPath: resolvedProjectPath,
197
+ })
198
+
199
+ console.info()
200
+ console.info(chalk.gray(hanzoguiDuckAsciiArt))
201
+ process.exit(0)
202
+ } catch (error) {
203
+ console.error('An unexpected error occurred:', error)
204
+ process.exit(1)
205
+ }
206
+ }
207
+
208
+ function updatePackageJsonName(projectName: string, dir: string) {
209
+ const packageJsonPath = path.join(dir, 'package.json')
210
+ if (existsSync(packageJsonPath)) {
211
+ const content = readFileSync(packageJsonPath).toString()
212
+ const contentWithUpdatedName = content.replace(
213
+ /("name": ")(.*)(",)/,
214
+ `$1${projectName}$3`
215
+ )
216
+ writeFileSync(packageJsonPath, contentWithUpdatedName)
217
+ }
218
+ }
219
+
220
+ run().catch((error) => {
221
+ console.error('An unexpected error occurred:', error)
222
+ process.exit(1)
223
+ })
@@ -0,0 +1,10 @@
1
+ import { readFileSync } from 'node:fs'
2
+ import { url } from './here.ts'
3
+
4
+ // This package's own manifest, read from the package root at run time.
5
+ export const packageJson = JSON.parse(
6
+ readFileSync(new URL('../../package.json', url), 'utf8')
7
+ ) as {
8
+ name: string
9
+ version: string
10
+ }
@@ -0,0 +1,20 @@
1
+ import chalk from 'chalk'
2
+
3
+ import type { ExtraSteps } from './types.ts'
4
+
5
+ const packageManager = 'bun'
6
+
7
+ const runCommand = (scriptName: string) => `${packageManager} run ${scriptName}`
8
+
9
+ const main: ExtraSteps = async ({ isFullClone, projectName }) => {
10
+ if (isFullClone) {
11
+ console.info(`
12
+ ${chalk.green.bold('Done!')} created a new project under ./${projectName}
13
+
14
+ visit your project:
15
+ ${chalk.green('cd')} ${projectName}
16
+ `)
17
+ }
18
+ }
19
+
20
+ export default main
@@ -0,0 +1,24 @@
1
+ import chalk from 'chalk'
2
+
3
+ import type { ExtraSteps } from './types.ts'
4
+
5
+ const packageManager = 'bun'
6
+
7
+ const runCommand = (scriptName: string) => `${packageManager} run ${scriptName}`
8
+
9
+ const main: ExtraSteps = async ({ isFullClone, projectName }) => {
10
+ if (isFullClone) {
11
+ console.info(`
12
+ ${chalk.green.bold('Done!')} created a new project under ./${projectName}
13
+
14
+ visit your project:
15
+ ${chalk.green('cd')} ${projectName}
16
+ `)
17
+ }
18
+ console.info(`
19
+ To start the Remix development server, run:
20
+ ${chalk.green(runCommand('dev'))}
21
+ `)
22
+ }
23
+
24
+ export default main
@@ -0,0 +1,40 @@
1
+ import chalk from 'chalk'
2
+
3
+ import type { ExtraSteps } from './types.ts'
4
+
5
+ const packageManager = 'bun'
6
+
7
+ const runCommand = (scriptName: string) => `${packageManager} run ${scriptName}`
8
+
9
+ const main: ExtraSteps = async ({ isFullClone, projectName }) => {
10
+ console.info(`Note: you need bun for this repo.`)
11
+
12
+ if (isFullClone) {
13
+ console.info(`${chalk.green.bold(
14
+ 'Done!'
15
+ )} created a new project under ./${projectName}
16
+
17
+ visit your project:
18
+ ${chalk.green('cd')} ${projectName}
19
+ `)
20
+ }
21
+ console.info(`
22
+ To start the Next.js development server, run:
23
+ ${chalk.green(runCommand('web'))}
24
+
25
+ To start Expo Go for mobile development, run:
26
+ ${chalk.green(runCommand('native'))}
27
+
28
+ You can also create Expo development builds by doing:
29
+
30
+ ${chalk.green(`cd apps/expo`)}
31
+ then:
32
+ ${chalk.green(runCommand('ios'))}
33
+ or...
34
+ ${chalk.green(runCommand('android'))}
35
+
36
+ Be sure to replace yourprojectsname in app.json with the uid you'd like for your app.
37
+ `)
38
+ }
39
+
40
+ export default main
@@ -0,0 +1,210 @@
1
+ import { execSync } from 'node:child_process'
2
+ import { existsSync, readFileSync, renameSync } from 'node:fs'
3
+ import fs from 'node:fs/promises'
4
+ import path from 'node:path'
5
+
6
+ import chalk from 'chalk'
7
+ import prompts from 'prompts'
8
+
9
+ import { takeoutAsciiArt, hanzoguiRainbowAsciiArt } from '../helpers/asciiArts.ts'
10
+ import type { ExtraSteps } from './types.ts'
11
+
12
+ const packageManager = 'bun'
13
+
14
+ const runCommand = (scriptName: string) => `${packageManager} run ${scriptName}`
15
+
16
+ const main: ExtraSteps = async ({ isFullClone, projectName, projectPath }) => {
17
+ console.info(`
18
+ ${hanzoguiRainbowAsciiArt
19
+ .split('\n')
20
+ .map((line) => ` ${line}`)
21
+ .join('\n')}
22
+ ${takeoutAsciiArt}
23
+
24
+ `)
25
+
26
+ console.info()
27
+ const { setupSupabase } = await prompts({
28
+ name: 'setupSupabase',
29
+ message: 'Set up Supabase?',
30
+ type: 'confirm',
31
+ initial: true,
32
+ })
33
+
34
+ if (setupSupabase) {
35
+ console.info()
36
+ const { startLocalSupabase } = await prompts({
37
+ name: 'startLocalSupabase',
38
+ type: 'confirm',
39
+ message: 'Start local Supabase instance for you? (Requires Docker)',
40
+ initial: true,
41
+ })
42
+
43
+ if (startLocalSupabase) {
44
+ const supabaseStarted = await runRetryableCommand(`bun run supa start`)
45
+
46
+ if (supabaseStarted) {
47
+ console.info()
48
+ const { setUpSupabaseEnv } = await prompts({
49
+ name: 'setUpSupabaseEnv',
50
+ type: 'confirm',
51
+ message:
52
+ 'Do you want us to add the local env variables for you? This will create a file called .env.local.',
53
+ initial: true,
54
+ })
55
+
56
+ if (setUpSupabaseEnv) {
57
+ const envs = getEnvFromSupabaseStatus(
58
+ execSync('bun run supa status').toString()
59
+ )
60
+ const newEnvContent = Object.entries(envs)
61
+ .map(([key, value]) => `${key}=${value}`)
62
+ .join('\n')
63
+
64
+ if (existsSync(path.join(projectPath, '.env.local'))) {
65
+ if (
66
+ readFileSync(path.join(projectPath, '.env.local')).toString() !==
67
+ newEnvContent
68
+ ) {
69
+ renameSync(
70
+ path.join(projectPath, '.env.local'),
71
+ path.join(projectPath, `.env.local.old-${Number(new Date())}`)
72
+ )
73
+ }
74
+ }
75
+
76
+ await fs.writeFile(path.join(projectPath, './.env.local'), newEnvContent)
77
+ }
78
+ }
79
+ }
80
+
81
+ console.info()
82
+ const { setupRemoteSupabase } = await prompts({
83
+ name: 'setupRemoteSupabase',
84
+ type: 'confirm',
85
+ message:
86
+ 'Link remote Supabase instance for you? (Create a project on https://app.supabase.com/projects first)',
87
+ initial: true,
88
+ })
89
+
90
+ if (setupRemoteSupabase) {
91
+ await runRetryableCommand(`npx supabase login`)
92
+ console.info()
93
+ await linkSupabase()
94
+
95
+ // console.info()
96
+ // const { runSupabaseMigrations } = await prompts({ name: 'runSupabaseMigrations', type: 'confirm', message: 'Run Supabase migrations on your remote Supabase instance?' })
97
+
98
+ // if (runSupabaseMigrations) {
99
+ // execSync(`yarn supa migrate`, { stdio: 'inherit' })
100
+ // }
101
+ }
102
+ }
103
+
104
+ if (isFullClone) {
105
+ console.info(`
106
+ ${chalk.green.bold('Done!')} created a new project under ./${projectName}
107
+
108
+ visit your project:
109
+ ${chalk.green(' cd')} ${projectName}
110
+ `)
111
+ }
112
+
113
+ console.info(`
114
+ To start the Next.js development server, run:
115
+ ${chalk.green(runCommand('web'))}
116
+
117
+ To start developing with Expo for native, run:
118
+ ${chalk.green(runCommand('native'))}
119
+
120
+ To start developing for Expo dev build, run:
121
+ ${chalk.green(runCommand('ios'))}
122
+ ${chalk.green(runCommand('android'))}
123
+
124
+ To run Supabase scripts, cd into the supabase package:
125
+ ${chalk.green('cd supabase')}
126
+
127
+ ${chalk.green('yarn reset')} - Resets local database
128
+ ${chalk.green('yarn generate')} - Generates new types
129
+
130
+ Find info on the rest of the scripts in ${chalk.cyan(`supabase/README.md`)}
131
+
132
+ If you've purchased and gained access to font and icon packages, you can run:
133
+ ${chalk.green('yarn add:icon')}
134
+ ${chalk.green('yarn add:font')}
135
+ `)
136
+ }
137
+ export default main
138
+
139
+ async function runRetryableCommand(cmd: string, retriesCount = 0) {
140
+ try {
141
+ execSync(cmd, { stdio: 'inherit' })
142
+ return true
143
+ } catch (error) {
144
+ const { tryAgain } = await prompts({
145
+ name: 'tryAgain',
146
+ message: 'An error occurred. Do you want to try again?',
147
+ type: 'confirm',
148
+ initial: true,
149
+ })
150
+ if (tryAgain) {
151
+ await runRetryableCommand(cmd, retriesCount + 1)
152
+ } else {
153
+ console.info(
154
+ chalk.yellow(
155
+ `⚠️ Skipping this step. You can try running this command later. The failed command was \`${chalk.underline(
156
+ cmd
157
+ )}\`.`
158
+ )
159
+ )
160
+ return false
161
+ }
162
+ }
163
+ }
164
+
165
+ async function linkSupabase() {
166
+ const { supabaseRefId } = await prompts({
167
+ name: 'supabaseRefId',
168
+ type: 'text',
169
+ message: "Enter your supabase project's ID (e.g. abcdefghijklmnopqrst)",
170
+ initial: true,
171
+ })
172
+ const cmd = `npx supabase link --project-ref ${supabaseRefId.trim()}`
173
+
174
+ try {
175
+ execSync(cmd, {
176
+ stdio: 'inherit',
177
+ })
178
+ return true
179
+ } catch (error) {
180
+ const { tryAgain } = await prompts({
181
+ name: 'tryAgain',
182
+ message: 'An error occurred. Do you want to try again?',
183
+ type: 'confirm',
184
+ initial: true,
185
+ })
186
+ if (tryAgain) {
187
+ await linkSupabase()
188
+ } else {
189
+ console.info(
190
+ chalk.yellow(
191
+ `⚠️ Skipping this step. You can try running this command later. The failed command was \`${chalk.underline(
192
+ cmd
193
+ )}\`.`
194
+ )
195
+ )
196
+ return false
197
+ }
198
+ }
199
+ }
200
+
201
+ function getEnvFromSupabaseStatus(status: string) {
202
+ return {
203
+ NEXT_PUBLIC_SUPABASE_URL: status.match(/API URL: (.*)/)?.[1],
204
+ NEXT_PUBLIC_SUPABASE_GRAPHQL_URL: status.match(/GraphQL URL: (.*)/)?.[1],
205
+ SUPABASE_DB_URL: status.match(/DB URL: (.*)/)?.[1],
206
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: status.match(/anon key: (.*)/)?.[1],
207
+ SUPABASE_SERVICE_ROLE: status.match(/service_role key: (.*)/)?.[1],
208
+ SUPABASE_JWT_SECRET: status.match(/JWT secret: (.*)/)?.[1],
209
+ }
210
+ }
@@ -0,0 +1,5 @@
1
+ export type ExtraSteps = (args: {
2
+ isFullClone: boolean
3
+ projectPath: string
4
+ projectName: string
5
+ }) => Promise<void>
@@ -0,0 +1,116 @@
1
+ import type { ExtraSteps } from './steps/types.ts'
2
+
3
+ import chalk from 'chalk'
4
+
5
+ import expoRouterSteps from './steps/expo-router.ts'
6
+ import remixSteps from './steps/remix.ts'
7
+ import starterFree from './steps/starter-free.ts'
8
+ import takeoutSteps from './steps/takeout.ts'
9
+
10
+ export const templates: Array<{
11
+ title: string
12
+ value: string
13
+ type: 'free' | 'premium' | 'included-in-monorepo'
14
+ hidden: boolean
15
+ packageManager: 'yarn' | 'npm' | 'pnpm' | 'bun'
16
+ repo: { url: string; sshFallback: string; dir: string[]; branch: string }
17
+ extraSteps?: ExtraSteps
18
+ }> = [
19
+ {
20
+ title: `${chalk.bold.underline(
21
+ `🥡 ${chalk.magenta('Takeout')} ${chalk.green('Free')}`
22
+ )} - Full stack starter: https://hanzogui.dev/takeout`,
23
+ value: 'takeout-free',
24
+ type: 'free',
25
+ hidden: false,
26
+ packageManager: 'bun',
27
+ repo: {
28
+ url: `https://github.com/hanzogui/takeout-free`,
29
+ sshFallback: `git@github.com:hanzogui/takeout-free.git`,
30
+ dir: [],
31
+ branch: 'main',
32
+ },
33
+ extraSteps: starterFree,
34
+ },
35
+
36
+ {
37
+ title: `${chalk.bold.underline(
38
+ `🥡 ${chalk.magenta('Takeout')} ${chalk.red('Pro')}`
39
+ )} - Full featured starter: https://hanzogui.dev/takeout`,
40
+ value: `takeout-pro`,
41
+ type: 'premium',
42
+ packageManager: 'yarn',
43
+ hidden: false,
44
+ repo: {
45
+ url: `https://github.com/hanzogui/takeout2`,
46
+ sshFallback: `git@github.com:hanzogui/takeout2.git`,
47
+ dir: [],
48
+ branch: 'main',
49
+ },
50
+ extraSteps: takeoutSteps,
51
+ },
52
+
53
+ {
54
+ title: `${chalk.bold.underline(
55
+ `🥡 ${chalk.magenta('Takeout')} ${chalk.yellow('Pro Classic')}`
56
+ )} - Original Pro starter: https://hanzogui.dev/takeout`,
57
+ value: `takeout-pro-classic`,
58
+ type: 'premium',
59
+ packageManager: 'yarn',
60
+ hidden: false,
61
+ repo: {
62
+ url: `https://github.com/hanzogui/takeout`,
63
+ sshFallback: `git@github.com:hanzogui/takeout.git`,
64
+ dir: [],
65
+ branch: 'main',
66
+ },
67
+ extraSteps: takeoutSteps,
68
+ },
69
+
70
+ {
71
+ title: `Expo Router - Expo with file-based routing`,
72
+ value: 'expo-router',
73
+ type: 'free',
74
+ hidden: false,
75
+ packageManager: 'bun',
76
+ repo: {
77
+ url: `https://github.com/hanzoai/gui`,
78
+ sshFallback: `git@github.com:hanzoai/gui.git`,
79
+ dir: ['apps', 'starters', 'expo-router'],
80
+ branch: 'main',
81
+ },
82
+ extraSteps: expoRouterSteps,
83
+ },
84
+
85
+ {
86
+ title: `Remix - Remix with Vite`,
87
+ value: 'remix',
88
+ type: 'free',
89
+ hidden: false,
90
+ packageManager: 'bun',
91
+ repo: {
92
+ url: `https://github.com/hanzoai/gui`,
93
+ sshFallback: `git@github.com:hanzoai/gui.git`,
94
+ dir: ['apps', 'starters', 'remix'],
95
+ branch: 'main',
96
+ },
97
+ extraSteps: remixSteps,
98
+ },
99
+
100
+ {
101
+ title: `Next + Expo - Production ready monorepo`,
102
+ value: 'starter-free',
103
+ type: 'free',
104
+ hidden: false,
105
+ packageManager: 'yarn',
106
+ repo: {
107
+ url:
108
+ process.env.STARTER_FREE_REPO_SOURCE ||
109
+ `https://github.com/hanzogui/starter-free.git`,
110
+ sshFallback: `git@github.com:hanzogui/starter-free.git`,
111
+ dir: [],
112
+ branch: 'main',
113
+ },
114
+ extraSteps: starterFree,
115
+ },
116
+ ]
@@ -0,0 +1,2 @@
1
+ export declare const IS_TEST: boolean;
2
+ //# sourceMappingURL=create-gui-constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-gui-constants.d.ts","sourceRoot":"","sources":["../src/create-gui-constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,SAAkC,CAAA"}
@@ -0,0 +1,5 @@
1
+ export declare const hanzoguiAsciiArt = "\u2580\u2588\u2580\u2003\u2584\u2580\u2588\u2003\u2588\u2580\u2584\u2580\u2588\u2003\u2584\u2580\u2588\u2003\u2588\u2580\u2580\u2003\u2588 \u2588\u2003\u2588\n \u2588 \u2003\u2588\u2580\u2588\u2003\u2588 \u2580 \u2588\u2003\u2588\u2580\u2588\u2003\u2588\u2584\u2588\u2003\u2588\u2584\u2588\u2003\u2588";
2
+ export declare const hanzoguiRainbowAsciiArt: string;
3
+ export declare const takeoutAsciiArt = "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2591\u2588\u2588\u2588\u2588\u2588\u2557\u2591\u2588\u2588\u2557\u2591\u2591\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2591\u2588\u2588\u2588\u2588\u2588\u2557\u2591\u2588\u2588\u2557\u2591\u2591\u2591\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\n\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2591\u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2591\u2591\u2591\u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\n\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2550\u255D\u2591\u2588\u2588\u2588\u2588\u2588\u2557\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2588\u2588\u2551\u2588\u2588\u2551\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2591\n\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2591\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2588\u2588\u2557\u2591\u2588\u2588\u2554\u2550\u2550\u255D\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2588\u2588\u2551\u2588\u2588\u2551\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2591\n\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2588\u2588\u2551\u2588\u2588\u2551\u2591\u255A\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2591\u2591\u2591\u2588\u2588\u2551\u2591\u2591\u2591\n\u2591\u2591\u2591\u255A\u2550\u255D\u2591\u2591\u2591\u255A\u2550\u255D\u2591\u2591\u255A\u2550\u255D\u255A\u2550\u255D\u2591\u2591\u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u2591\u255A\u2550\u2550\u2550\u2550\u255D\u2591\u2591\u255A\u2550\u2550\u2550\u2550\u2550\u255D\u2591\u2591\u2591\u2591\u255A\u2550\u255D\u2591\u2591\u2591";
4
+ export declare const hanzoguiDuckAsciiArt = " \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \n \u2588\u2588 \u2588\u2588 \n \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \n \u2588\u2588 \u2588\u2588 \u2588\u2588\n \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\n \u2588\u2588 \u2588\u2588\n \u2588\u2588 \u2588\u2588\u2588\u2588 \n\u2588\u2588 \u2588\u2588 \n\u2588\u2588 \u2588\u2588 ";
5
+ //# sourceMappingURL=asciiArts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asciiArts.d.ts","sourceRoot":"","sources":["../../src/helpers/asciiArts.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,kTACD,CAAA;AAE5B,eAAO,MAAM,uBAAuB,QAwBhC,CAAA;AAEJ,eAAO,MAAM,eAAe,2lEAKgC,CAAA;AAE5D,eAAO,MAAM,oBAAoB,+kBAQF,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { templates } from '../templates.ts';
2
+ export declare const cloneStarter: (template: (typeof templates)[number], resolvedProjectPath: string, projectName: string) => Promise<void>;
3
+ //# sourceMappingURL=cloneStarter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloneStarter.d.ts","sourceRoot":"","sources":["../../src/helpers/cloneStarter.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAchD,eAAO,MAAM,YAAY,aACb,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,uBACf,MAAM,eACd,MAAM,kBAyBpB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const getProjectName: (projectPath?: string) => Promise<string>;
2
+ //# sourceMappingURL=getProjectName.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getProjectName.d.ts","sourceRoot":"","sources":["../../src/helpers/getProjectName.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,cAAc,iBAAwB,MAAM,oBAuCxD,CAAA"}