Skip to content

Commit

Permalink
feat: improve configure hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien-R44 committed Feb 17, 2024
1 parent 1b13e41 commit 8af6c36
Show file tree
Hide file tree
Showing 14 changed files with 351 additions and 41 deletions.
3 changes: 2 additions & 1 deletion bin/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assert } from '@japa/assert'
import { processCLIArgs, configure, run } from '@japa/runner'
import { fileSystem } from '@japa/file-system'
import { expectTypeOf } from '@japa/expect-type'
import { BASE_URL } from '../tests_helpers/index.js'

/*
|--------------------------------------------------------------------------
Expand All @@ -19,7 +20,7 @@ import { expectTypeOf } from '@japa/expect-type'
processCLIArgs(process.argv.slice(2))
configure({
files: ['tests/**/*.spec.ts'],
plugins: [assert(), fileSystem(), expectTypeOf()],
plugins: [assert(), fileSystem({ basePath: BASE_URL }), expectTypeOf()],
})

/*
Expand Down
82 changes: 60 additions & 22 deletions configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,37 @@

import type Configure from '@adonisjs/core/commands/configure'
import { stubsRoot } from './stubs/main.js'
import { Codemods } from '@adonisjs/core/ace/codemods'

const ADAPTERS = ['Vue 3', 'React', 'Svelte'] as const
const ADAPTERS = ['Vue 3', 'React', 'Svelte', 'Solid'] as const
const ADAPTERS_INFO: {
[K in (typeof ADAPTERS)[number]]: {
dependencies: {
name: string
isDevDependency: boolean
}[]
ssrDependencies?: {
name: string
isDevDependency: boolean
}[]
stubFolder: string
extension: string
dependencies: { name: string; isDevDependency: boolean }[]
ssrDependencies?: { name: string; isDevDependency: boolean }[]
viteRegister: {
pluginCall: Parameters<Codemods['registerVitePlugin']>[0]

Check failure on line 22 in configure.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Property 'registerVitePlugin' does not exist on type 'Codemods'.
importDeclarations: Parameters<Codemods['registerVitePlugin']>[1]

Check failure on line 23 in configure.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Property 'registerVitePlugin' does not exist on type 'Codemods'.
}
}
} = {
'Vue 3': {
stubFolder: 'vue',
extension: 'ts',
dependencies: [
{ name: '@inertiajs/vue3', isDevDependency: false },
{ name: 'vue', isDevDependency: false },
{ name: '@vitejs/plugin-vue', isDevDependency: true },
],
viteRegister: {
pluginCall: 'vue()',
importDeclarations: [{ isNamed: true, module: '@vitejs/plugin-vue', identifier: 'vue' }],
},
},
'React': {
stubFolder: 'react',
extension: 'tsx',
dependencies: [
{ name: '@inertiajs/react', isDevDependency: false },
{ name: 'react', isDevDependency: false },
Expand All @@ -39,13 +48,38 @@ const ADAPTERS_INFO: {
{ name: '@types/react', isDevDependency: true },
{ name: '@types/react-dom', isDevDependency: true },
],
viteRegister: {
pluginCall: 'react()',
importDeclarations: [{ isNamed: true, module: '@vitejs/plugin-react', identifier: 'react' }],
},
},
'Svelte': {
stubFolder: 'svelte',
extension: 'ts',
dependencies: [
{ name: '@inertiajs/svelte', isDevDependency: false },
{ name: 'svelte', isDevDependency: false },
{ name: '@sveltejs/vite-plugin-svelte', isDevDependency: true },
],
viteRegister: {
pluginCall: 'svelte()',
importDeclarations: [
{ isNamed: true, module: '@sveltejs/vite-plugin-svelte', identifier: 'svelte' },
],
},
},
'Solid': {
stubFolder: 'solid',
extension: 'tsx',
dependencies: [
{ name: 'solid-js', isDevDependency: false },
{ name: 'inertia-adapter-solid', isDevDependency: false },
{ name: 'vite-plugin-solid', isDevDependency: true },
],
viteRegister: {
pluginCall: 'solid()',
importDeclarations: [{ isNamed: true, module: 'vite-plugin-solid', identifier: 'solid' }],
},
},
}

Expand All @@ -61,19 +95,8 @@ export async function configure(command: Configure) {
ADAPTERS,
{ name: 'adapter' }
)
const pkgToInstall = ADAPTERS_INFO[adapter].dependencies

/**
* Prompt for SSR
*/
const withSsr = await command.prompt.confirm('Do you want to enable server-side rendering?', {
name: 'ssr',
})

if (withSsr) {
pkgToInstall.push(...(ADAPTERS_INFO[adapter].ssrDependencies || []))
}

const adapterInfo = ADAPTERS_INFO[adapter]
const codemods = await command.createCodemods()

/**
Expand All @@ -91,13 +114,28 @@ export async function configure(command: Configure) {
])

/**
* Publish config
* Publish stubs
*/
const extension = adapterInfo.extension
const stubFolder = adapterInfo.stubFolder

await codemods.makeUsingStub(stubsRoot, 'config.stub', {})
await codemods.makeUsingStub(stubsRoot, `${stubFolder}/root.edge.stub`, {})
await codemods.makeUsingStub(stubsRoot, `${stubFolder}/tsconfig.json.stub`, {})
await codemods.makeUsingStub(stubsRoot, `${stubFolder}/app.${extension}.stub`, {})

/**
* Update vite config
*/
await codemods.registerVitePlugin(

Check failure on line 130 in configure.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Property 'registerVitePlugin' does not exist on type 'Codemods'.
adapterInfo.viteRegister.pluginCall,
adapterInfo.viteRegister.importDeclarations
)

/**
* Install packages
*/
const pkgToInstall = adapterInfo.dependencies
const shouldInstallPackages = await command.prompt.confirm(
`Do you want to install dependencies ${pkgToInstall.map((pkg) => pkg.name).join(', ')}?`,
{ name: 'install' }
Expand Down
2 changes: 1 addition & 1 deletion stubs/config.stub
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default defineConfig({
/**
* Path to the Edge view that will be used as the root view for Inertia responses
*/
rootView: 'home',
rootView: 'root',

/**
* Data that should be shared with all rendered pages
Expand Down
25 changes: 25 additions & 0 deletions stubs/react/app.tsx.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{{{
exports({ to: app.makePath('resources/app.tsx') })
}}}
import './css/app.css';

import { createRoot } from 'react-dom/client';
import { createInertiaApp } from '@inertiajs/react';

const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'

createInertiaApp({
progress: { color: '#5468FF' },

title: (title) => {{ '`${title} - ${appName}`' }},

resolve: (name) => {
const pages = import.meta.glob('./pages/**/*.vue', { eager: true })
{{ 'return pages[`./pages/${name}.vue`]' }}
},

setup({ el, App, props }) {
const root = createRoot(el);
root.render(<App {...props} />);
},
});
22 changes: 22 additions & 0 deletions stubs/react/root.edge.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{{
exports({ to: app.makePath('resources/views/root.edge') })
}}}
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title inertia>AdonisJS x Inertia x React</title>

@viteReactRefresh()
@vite(['resources/app.tsx'])
@inertiaHead()
</head>

<body>
@inertia()
</body>

</html>
25 changes: 25 additions & 0 deletions stubs/react/tsconfig.json.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{{{
exports({ to: app.makePath('resources/tsconfig.json') })
}}}
{
"compilerOptions": {
"target": "ESNext",
"jsx": "react-jsx",
"lib": ["DOM", "ESNext", "DOM.Iterable", "ES2020"],
"useDefineForClassFields": true,
"baseUrl": ".",
"module": "ESNext",
"moduleResolution": "Bundler",
"paths": {
"@/*": ["./*"],
"~/*": ["../*"],
},
"resolveJsonModule": true,
"types": ["vite/client"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
},
"include": ["./**/*.ts", "./**/*.tsx", "app.tsx.stub"],
}
24 changes: 24 additions & 0 deletions stubs/solid/app.tsx.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{{{
exports({ to: app.makePath('resources/app.tsx') })
}}}
import './css/app.css'

import { render } from 'solid-js/web'
import { createInertiaApp } from 'inertia-adapter-solid'

const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'

createInertiaApp({
progress: { color: '#5468FF' },

title: (title) => {{ '`${title} - ${appName}`' }},

resolve(name) {
const pages = import.meta.glob('./pages/**/*.tsx', { eager: true })
{{ 'return pages[`./pages/${name}.tsx`]' }}
},

setup({ el, App, props }) {
render(() => <App {...props} />, el)
},
})
21 changes: 21 additions & 0 deletions stubs/solid/root.edge.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{{{
exports({ to: app.makePath('resources/views/root.edge') })
}}}
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title inertia>AdonisJS x Inertia x SolidJS</title>

@vite(['resources/app.tsx'])
@inertiaHead()
</head>

<body>
@inertia()
</body>

</html>
26 changes: 26 additions & 0 deletions stubs/solid/tsconfig.json.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{{
exports({ to: app.makePath('resources/tsconfig.json') })
}}}
{
"compilerOptions": {
"target": "ESNext",
"jsx": "preserve",
"jsxImportSource": "solid-js",
"lib": ["DOM", "ESNext", "DOM.Iterable", "ES2020"],
"useDefineForClassFields": true,
"baseUrl": ".",
"module": "ESNext",
"moduleResolution": "Bundler",
"paths": {
"@/*": ["./*"],
"~/*": ["../*"],
},
"resolveJsonModule": true,
"types": ["vite/client"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
},
"include": ["./**/*.ts", "./**/*.tsx", "app.tsx.stub"],
}
27 changes: 27 additions & 0 deletions stubs/vue/app.ts.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{{{
exports({ to: app.makePath('resources/app.ts') })
}}}
import './css/app.css';

import { createApp, h } from 'vue'
import type { DefineComponent } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'

const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'

createInertiaApp({
progress: { color: '#5468FF' },

title: (title) => {{ '`${title} - ${appName}`' }},

resolve: (name) => {
const pages = import.meta.glob<DefineComponent>('./pages/**/*.vue', { eager: true })
{{ 'return pages[`./pages/${name}.vue`]' }}
},

setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el)
},
})
21 changes: 21 additions & 0 deletions stubs/vue/root.edge.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{{{
exports({ to: app.makePath('resources/views/root.edge') })
}}}
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title inertia>AdonisJS x Inertia x VueJS</title>

@vite(['resources/app.ts'])
@inertiaHead()
</head>

<body>
@inertia()
</body>

</html>
26 changes: 26 additions & 0 deletions stubs/vue/tsconfig.json.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{{
exports({ to: app.makePath('resources/tsconfig.json') })
}}}
{
"compilerOptions": {
"target": "ESNext",
"jsx": "preserve",
"jsxImportSource": "vue",
"lib": ["DOM", "ESNext", "DOM.Iterable", "ES2020"],
"useDefineForClassFields": true,
"baseUrl": ".",
"module": "ESNext",
"moduleResolution": "Bundler",
"paths": {
"@/*": ["./*"],
"~/*": ["../*"],
},
"resolveJsonModule": true,
"types": ["vite/client"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
},
"include": ["./**/*.ts", "./**/*.vue"],
}
Loading

0 comments on commit 8af6c36

Please sign in to comment.