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