1- import { insertAfter , insertAtBeginning } from "@solid-cli/utils/fs" ; import { writeFile } from "fs/promises" ; import { fileExists , manipulateJsonFile , validateFilePath } from "./utils/helpers" ; import { $ } from "execa" ; import { getRunnerCommand , detectPackageManager } from "@solid-cli/utils/package-manager" ; import { createSignal } from "@solid-cli/reactivity" ; import * as p from "@clack/prompts" ; import color from "picocolors" ; import { cancelable } from "@solid-cli/ui" ; import { flushQueue } from "@solid-cli/utils/updates" ; import { PluginOptions } from "@solid-cli/utils/transform" ; // All the integrations/packages that we support export type Supported = keyof typeof integrations ; export type IntegrationsValue = { pluginOptions ?: PluginOptions ; installs : string [ ] ; installsDev ?: string [ ] ; additionalConfig ?: ( ) => Promise < void > ; postInstall ?: ( ) => Promise < void > ; } ; export type Integrations = Record < Supported , IntegrationsValue > ; export const [ rootFile , setRootFile ] = createSignal < string | undefined > ( undefined ) ; export const integrations : Record < string , IntegrationsValue > = { tailwind : { installs : [ "tailwindcss" , "postcss" , "autoprefixer" ] , postInstall : async ( ) => { const pM = detectPackageManager ( ) ; await $ `${ getRunnerCommand ( pM ) } tailwindcss init -p` ; let tailwindConfig = "tailwind.config.js" ; if ( ! fileExists ( tailwindConfig ) ) { p . log . error ( color . red ( `Can't find tailwind config file` ) ) ; await cancelable ( p . text ( { message : `Type path to tailwind config: ` , validate ( value ) { if ( ! value . length ) return `Path can not be empty` ; const path = validateFilePath ( value , "tailwind.config" ) ; if ( ! path ) return `Tailwind config at \`${ value } \` not found. Please try again` ; else { tailwindConfig = path ; } } , } ) , ) ; } let indexCss = "./src/index.css" ; if ( ! fileExists ( indexCss ) ) { p . log . error ( color . red ( `Can't find index.css` ) ) ; await cancelable ( p . text ( { message : `Type path to index.css: ` , validate ( value ) { if ( ! value . length ) return `Path can not be empty` ; const path = validateFilePath ( value , "index.css" ) ; if ( ! path ) return `index.css at \`${ value } \` not found. Please try again` ; else { indexCss = path ; } } , } ) , ) ; } p . log . info ( "Updating tailwind config" ) ; await insertAfter ( tailwindConfig , "content: [" , '"./index.html", "./src/**/*.{js,ts,jsx,tsx}"' ) ; await insertAtBeginning ( indexCss , "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n" ) ; // Instantly flush queue await flushQueue ( ) ; } , } , unocss : { pluginOptions : { importName : "UnoCss" , importSource : "unocss/vite" , isDefault : true , options : { } , } , installs : [ "" ] , installsDev : [ "unocss" ] , additionalConfig : async ( ) => { const path = rootFile ( ) ; if ( ! path ) return ; await insertAtBeginning ( path , `import "virtual:uno.css";\n` ) ; } , } , vitepwa : { pluginOptions : { importName : "VitePWA" , importSource : "vite-plugin-pwa" , isDefault : false , options : { } , } , installs : [ "vite-plugin-pwa" ] , } , "solid-devtools" : { pluginOptions : { importName : "devtools" , importSource : "solid-devtools/vite" , isDefault : true , options : { } , } , installs : [ "solid-devtools" ] , additionalConfig : async ( ) => { const path = rootFile ( ) ; if ( ! path ) return ; await insertAtBeginning ( path , `import "solid-devtools";\n` ) ; } , } , vitest : { installs : [ ] , installsDev : [ "vitest" , "jsdom" , "@solidjs/testing-library" , "@testing-library/user-event" , "@testing-library/jest-dom" , ] , additionalConfig : async ( ) => { try { p . log . info ( "Adding test script to package.json" ) ; let hasStart = false ; manipulateJsonFile ( "package.json" , ( packageJson ) => { if ( ! packageJson . scripts ) { packageJson . scripts = { } ; } if ( ! / \b v i t e s t \b / . test ( packageJson . scripts . test || "" ) ) { packageJson . scripts . test = "vitest" ; } hasStart = packageJson . dependencies [ "@solidjs/start" ] ; return packageJson ; } ) ; const hasTs = fileExists ( "tsconfig.json" ) ; if ( hasTs ) { p . log . info ( "Adding testing types to tsconfig.json" ) ; manipulateJsonFile ( "tsconfig.json" , ( tsConfig ) => { if ( ! tsConfig . compilerOptions ) { tsConfig . compilerOptions = { } ; } tsConfig . compilerOptions . types = [ ...new Set ( [ ...( tsConfig . compilerOptions . types || [ ] ) , "vite/client" , "@testing-library/jest-dom" ] ) , ] ; return tsConfig ; } ) ; } if ( hasStart && [ "ts" , "mjs" , "cjs" , "js" ] . every ( ( suffix ) => ! fileExists ( `vite.config.${ suffix } ` ) && ! fileExists ( `vitest.config.${ suffix } ` ) , ) ) { const suffix = hasTs ? "ts" : "mjs" ; p . log . info ( `Adding vitest.config.${ suffix } ` ) ; await writeFile ( `vitest.config.${ suffix } ` , `import solid from "vite-plugin-solid"; import { defineConfig } from "vitest/config"; export default defineConfig({ plugins: [solid()], resolve: { conditions: ["development", "browser"], }, }); ` , "utf-8" , ) ; } } catch ( err ) { console . error ( err ) ; } } , } , "tauri-v1.x" : { installs : [ "@tauri-apps/cli" ] , postInstall : async ( ) => { try { let name = "" ; manipulateJsonFile ( "package.json" , ( packageJson ) => { if ( ! packageJson . scripts ) { packageJson . scripts = { } ; } packageJson . scripts . tauri = "tauri" ; name = packageJson . name ; return packageJson ; } ) ; await flushQueue ( ) ; const pM = detectPackageManager ( ) ; await $ `${ getRunnerCommand ( pM ) } tauri init --ci -A ${ name } -W ${ name } -D ../dist -P http://localhost:3000` ; p . note ( `Make sure you have installed all prerequisites: https://tauri.app/v1/guides/getting-started/prerequisites Start tauri development with ${ color . bold ( pM . name ) } ${ color . bold ( pM . runScriptCommand ( "tauri dev" ) ) } ` ) ; } catch ( err ) { console . error ( err ) ; } } , } , "tauri-v2.x" : { installs : [ "@tauri-apps/cli@next" ] , postInstall : async ( ) => { try { let name = "" ; manipulateJsonFile ( "package.json" , ( packageJson ) => { if ( ! packageJson . scripts ) { packageJson . scripts = { } ; } packageJson . scripts . tauri = "tauri" ; name = packageJson . name ; return packageJson ; } ) ; await flushQueue ( ) ; const pM = detectPackageManager ( ) ; await $ `${ getRunnerCommand ( pM ) } tauri init --ci -A ${ name } -W ${ name } -D ../dist -P http://localhost:3000` ; p . note ( `Make sure you have installed all prerequisites: https://v2.tauri.app/start/prerequisites/ Start tauri development with ${ color . bold ( pM . name ) } ${ color . bold ( pM . runScriptCommand ( "tauri dev" ) ) } ` ) ; } catch ( err ) { console . error ( err ) ; } } , } , } ;
1+ import { insertAfter , insertAtBeginning } from "@solid-cli/utils/fs" ;
2+ import { writeFile } from "fs/promises" ;
3+ import { fileExists , manipulateJsonFile , validateFilePath } from "./utils/helpers" ;
4+ import { $ } from "execa" ;
5+ import { getRunnerCommand , detectPackageManager } from "@solid-cli/utils/package-manager" ;
6+ import { createSignal } from "@solid-cli/reactivity" ;
7+ import * as p from "@clack/prompts" ;
8+ import color from "picocolors" ;
9+ import { cancelable } from "@solid-cli/ui" ;
10+ import { flushQueue } from "@solid-cli/utils/updates" ;
11+ import { PluginOptions } from "@solid-cli/utils/transform" ;
12+
13+ // All the integrations/packages that we support
14+ export type Supported = keyof typeof integrations ;
15+
16+ export type IntegrationsValue = {
17+ pluginOptions ?: PluginOptions ;
18+ installs : string [ ] ;
19+ installsDev ?: string [ ] ;
20+ additionalConfig ?: ( ) => Promise < void > ;
21+ postInstall ?: ( ) => Promise < void > ;
22+ } ;
23+
24+ export type Integrations = Record < Supported , IntegrationsValue > ;
25+
26+ export const [ rootFile , setRootFile ] = createSignal < string | undefined > ( undefined ) ;
27+
28+ export const integrations : Record < string , IntegrationsValue > = {
29+ tailwind : {
30+ installs : [ "tailwindcss" , "postcss" , "autoprefixer" ] ,
31+ postInstall : async ( ) => {
32+ const pM = detectPackageManager ( ) ;
33+ await $ `${ getRunnerCommand ( pM ) } tailwindcss init -p` ;
34+ let tailwindConfig = "tailwind.config.js" ;
35+ if ( ! fileExists ( tailwindConfig ) ) {
36+ p . log . error ( color . red ( `Can't find tailwind config file` ) ) ;
37+ await cancelable (
38+ p . text ( {
39+ message : `Type path to tailwind config: ` ,
40+ validate ( value ) {
41+ if ( ! value . length ) return `Path can not be empty` ;
42+ const path = validateFilePath ( value , "tailwind.config" ) ;
43+ if ( ! path ) return `Tailwind config at \`${ value } \` not found. Please try again` ;
44+ else {
45+ tailwindConfig = path ;
46+ }
47+ } ,
48+ } ) ,
49+ ) ;
50+ }
51+
52+ let indexCss = "./src/index.css" ;
53+ if ( ! fileExists ( indexCss ) ) {
54+ p . log . error ( color . red ( `Can't find index.css` ) ) ;
55+ await cancelable (
56+ p . text ( {
57+ message : `Type path to index.css: ` ,
58+ validate ( value ) {
59+ if ( ! value . length ) return `Path can not be empty` ;
60+ const path = validateFilePath ( value , "index.css" ) ;
61+ if ( ! path ) return `index.css at \`${ value } \` not found. Please try again` ;
62+ else {
63+ indexCss = path ;
64+ }
65+ } ,
66+ } ) ,
67+ ) ;
68+ }
69+ p . log . info ( "Updating tailwind config" ) ;
70+ await insertAfter ( tailwindConfig , "content: [" , '"./index.html", "./src/**/*.{js,ts,jsx,tsx}"' ) ;
71+ await insertAtBeginning ( indexCss , "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n" ) ;
72+ // Instantly flush queue
73+ await flushQueue ( ) ;
74+ } ,
75+ } ,
76+ unocss : {
77+ pluginOptions : {
78+ importName : "UnoCss" ,
79+ importSource : "unocss/vite" ,
80+ isDefault : true ,
81+ options : { } ,
82+ } ,
83+ installs : [ "" ] ,
84+ installsDev : [ "unocss" ] ,
85+ additionalConfig : async ( ) => {
86+ const path = rootFile ( ) ;
87+ if ( ! path ) return ;
88+ await insertAtBeginning ( path , `import "virtual:uno.css";\n` ) ;
89+ } ,
90+ } ,
91+ vitepwa : {
92+ pluginOptions : {
93+ importName : "VitePWA" ,
94+ importSource : "vite-plugin-pwa" ,
95+ isDefault : false ,
96+ options : { } ,
97+ } ,
98+ installs : [ "vite-plugin-pwa" ] ,
99+ } ,
100+ "solid-devtools" : {
101+ pluginOptions : {
102+ importName : "devtools" ,
103+ importSource : "solid-devtools/vite" ,
104+ isDefault : true ,
105+ options : { } ,
106+ } ,
107+ installs : [ "solid-devtools" ] ,
108+ additionalConfig : async ( ) => {
109+ const path = rootFile ( ) ;
110+ if ( ! path ) return ;
111+ await insertAtBeginning ( path , `import "solid-devtools";\n` ) ;
112+ } ,
113+ } ,
114+ vitest : {
115+ installs : [ ] ,
116+ installsDev : [
117+ "vitest" ,
118+ "jsdom" ,
119+ "@solidjs/testing-library" ,
120+ "@testing-library/user-event" ,
121+ "@testing-library/jest-dom" ,
122+ ] ,
123+ additionalConfig : async ( ) => {
124+ try {
125+ p . log . info ( "Adding test script to package.json" ) ;
126+ let hasStart = false ;
127+ manipulateJsonFile ( "package.json" , ( packageJson ) => {
128+ if ( ! packageJson . scripts ) {
129+ packageJson . scripts = { } ;
130+ }
131+ if ( ! / \b v i t e s t \b / . test ( packageJson . scripts . test || "" ) ) {
132+ packageJson . scripts . test = "vitest" ;
133+ }
134+ hasStart = packageJson . dependencies [ "@solidjs/start" ] ;
135+ return packageJson ;
136+ } ) ;
137+ const hasTs = fileExists ( "tsconfig.json" ) ;
138+ if ( hasTs ) {
139+ p . log . info ( "Adding testing types to tsconfig.json" ) ;
140+ manipulateJsonFile ( "tsconfig.json" , ( tsConfig ) => {
141+ if ( ! tsConfig . compilerOptions ) {
142+ tsConfig . compilerOptions = { } ;
143+ }
144+ tsConfig . compilerOptions . types = [
145+ ...new Set ( [ ...( tsConfig . compilerOptions . types || [ ] ) , "vite/client" , "@testing-library/jest-dom" ] ) ,
146+ ] ;
147+ return tsConfig ;
148+ } ) ;
149+ }
150+ if (
151+ hasStart &&
152+ [ "ts" , "mjs" , "cjs" , "js" ] . every (
153+ ( suffix ) => ! fileExists ( `vite.config.${ suffix } ` ) && ! fileExists ( `vitest.config.${ suffix } ` ) ,
154+ )
155+ ) {
156+ const suffix = hasTs ? "ts" : "mjs" ;
157+ p . log . info ( `Adding vitest.config.${ suffix } ` ) ;
158+ await writeFile (
159+ `vitest.config.${ suffix } ` ,
160+ `import solid from "vite-plugin-solid";
161+ import { defineConfig } from "vitest/config";
162+
163+ export default defineConfig({
164+ plugins: [solid()],
165+ resolve: {
166+ conditions: ["development", "browser"],
167+ },
168+ });
169+ ` ,
170+ "utf-8" ,
171+ ) ;
172+ }
173+ } catch ( err ) {
174+ console . error ( err ) ;
175+ }
176+ } ,
177+ } ,
178+ "tauri-v1.x" : {
179+ installs : [ "@tauri-apps/cli" ] ,
180+ postInstall : async ( ) => {
181+ try {
182+ let name = "" ;
183+ manipulateJsonFile ( "package.json" , ( packageJson ) => {
184+ if ( ! packageJson . scripts ) {
185+ packageJson . scripts = { } ;
186+ }
187+ packageJson . scripts . tauri = "tauri" ;
188+ name = packageJson . name ;
189+ return packageJson ;
190+ } ) ;
191+ await flushQueue ( ) ;
192+ const pM = detectPackageManager ( ) ;
193+ await $ `${ getRunnerCommand ( pM ) } tauri init --ci -A ${ name } -W ${ name } -D ../dist -P http://localhost:3000` ;
194+ p . note (
195+ `Make sure you have installed all prerequisites: https://tauri.app/v1/guides/getting-started/prerequisites
196+
197+ Start tauri development with ${ color . bold ( pM . name ) } ${ color . bold ( pM . runScriptCommand ( "tauri dev" ) ) } ` ,
198+ ) ;
199+ } catch ( err ) {
200+ console . error ( err ) ;
201+ }
202+ } ,
203+ } ,
204+ "tauri-v2.x" : {
205+ installs : [ "@tauri-apps/cli@next" ] ,
206+ postInstall : async ( ) => {
207+ try {
208+ let name = "" ;
209+ manipulateJsonFile ( "package.json" , ( packageJson ) => {
210+ if ( ! packageJson . scripts ) {
211+ packageJson . scripts = { } ;
212+ }
213+ packageJson . scripts . tauri = "tauri" ;
214+ name = packageJson . name ;
215+ return packageJson ;
216+ } ) ;
217+ await flushQueue ( ) ;
218+ const pM = detectPackageManager ( ) ;
219+ await $ `${ getRunnerCommand ( pM ) } tauri init --ci -A ${ name } -W ${ name } -D ../dist -P http://localhost:3000` ;
220+ p . note (
221+ `Make sure you have installed all prerequisites: https://v2.tauri.app/start/prerequisites/
222+
223+ Start tauri development with ${ color . bold ( pM . name ) } ${ color . bold ( pM . runScriptCommand ( "tauri dev" ) ) } ` ,
224+ ) ;
225+ } catch ( err ) {
226+ console . error ( err ) ;
227+ }
228+ } ,
229+ } ,
230+ } ;
0 commit comments