Skip to content
This repository was archived by the owner on Apr 6, 2023. It is now read-only.
/frameworkPublic archive
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f2ac27c
feat: add cli schematic
Baroshem Mar 22, 2022
a0a1ea7
Update packages/nuxi/src/commands/add.ts
pi0 Mar 22, 2022
54256ae
Merge branch 'main' into feat/add-cli-schematic
Baroshem Mar 22, 2022
66ad7ad
Merge branch 'main' into feat/add-cli-schematic
Baroshem Mar 23, 2022
0879b40
feat: refactor after CR
Baroshem Mar 23, 2022
b5eda88
Merge branch 'main' into feat/add-cli-schematic
Baroshem Mar 23, 2022
bb0a422
feat: add basic error handling
Baroshem Mar 23, 2022
41878bf
Merge branch 'feat/add-cli-schematic' of github.com:Baroshem/framewor…
Baroshem Mar 23, 2022
8e3661d
feat: lint
Baroshem Mar 23, 2022
4a5ebc1
Merge branch 'main' into feat/add-cli-schematic
Baroshem Mar 23, 2022
3961c42
feat: add docs
Baroshem Mar 23, 2022
a06159c
feat: add docs
Baroshem Mar 23, 2022
152f6b5
feat: refactor with CR fixes
Baroshem Mar 23, 2022
8af59ae
Merge branch 'feat/add-cli-schematic' of github.com:Baroshem/framewor…
Baroshem Mar 23, 2022
b7a5c75
Merge branch 'main' into feat/add-cli-schematic
Baroshem Mar 23, 2022
ae2b52c
Merge branch 'main' into feat/add-cli-schematic
Baroshem Mar 24, 2022
a2d4ea5
Merge branch 'main' into feat/add-cli-schematic
pi0 Mar 24, 2022
f4a2dce
Update docs/content/3.docs/1.usage/8.cli.md
pi0 Mar 24, 2022
1d1ac2e
Update docs/content/3.docs/1.usage/8.cli.md
pi0 Mar 24, 2022
3f9126f
Merge branch 'main' into feat/add-cli-schematic
pi0 Mar 25, 2022
00e37cc
refactor: update templates
pi0 Mar 25, 2022
2fff4ef
improve add behavior
pi0 Mar 25, 2022
aa507b2
respect srcDir
pi0 Mar 25, 2022
dbd0d4a
update cli description and add new alias
pi0 Mar 25, 2022
ac36d80
update docs
pi0 Mar 25, 2022
af7f794
update name
pi0 Mar 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions docs/content/3.docs/1.usage/8.cli.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -102,3 +102,32 @@ The `upgrade` command upgrades Nuxt 3 to the latest version.
Option | Default | Description
-------------------------|-----------------|------------------
`--force, -f` | `false` | Removes `node_modules` and lock files before upgrade.

## Add

```{bash}
npx nuxi add [--cwd] [--force] <TEMPLATE> <NAME>
```

Option | Default | Description
-------------------------|-----------------|------------------
`TEMPLATE` | - | Specify a template of the file to be generated.
`NAME` | - | Specify a name of the file that will be created.
`--cwd` | `.` | The directory of the target application.
`--force` | `false` | Force override file if already exsits.

**Example:**

```{bash}
npx nuxi add component TheHeader
```

The `add` command generates new elements:

* **component**: `npx nuxi add component TheHeader`
* **composable**: `npx nuxi add composable foo`
* **layout**: `npx nuxi add layout custom`
* **plugin**: `npx nuxi add plugin analytics`
* **page**: `npx nuxi add page about` or `npx nuxi add page "category/[id]"`
* **middleware**: `npx nuxi add middleware auth`
* **api**: `npx nuxi add api hello` (CLI will generate file under `/server/api`)
62 changes: 62 additions & 0 deletions packages/nuxi/src/commands/add.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
import { existsSync, promises as fsp } from 'fs'
import { resolve, dirname } from 'pathe'
import consola from 'consola'
import { loadKit } from '../utils/kit'
import { templates } from '../utils/templates'
import { defineNuxtCommand } from './index'

export default defineNuxtCommand({
meta: {
name: 'add',
usage: `npx nuxi add [--cwd] [--force] ${Object.keys(templates).join('|')} <name>`,
description: 'Create a new template file.'
},
async invoke (args) {
const cwd = resolve(args.cwd || '.')

const template = args._[0]
const name = args._[1]

// Validate template name
if (!templates[template]) {
consola.error(`Template ${template} is not supported. Possible values: ${Object.keys(templates).join(', ')}`)
process.exit(1)
}

// Validate options
if (!name) {
consola.error('name argument is missing!')
process.exit(1)
}

// Load config in order to respect srcDir
const kit = await loadKit(cwd)
const config = await kit.loadNuxtConfig({ cwd })

// Resolve template
const res = templates[template]({ name })

// Resolve full path to generated file
const path = resolve(config.srcDir, res.path)

// Ensure not overriding user code
if (!args.force && existsSync(path)) {
consola.error(`File exists: ${path} . Use --force to override or use a different name.`)
process.exit(1)
}

// Ensure parent directory exists
const parentDir = dirname(path)
if (!existsSync(parentDir)) {
consola.info('Creating directory', parentDir)
if (template === 'page') {
consola.info('This enables vue-router functionality!')
}
await fsp.mkdir(parentDir, { recursive: true })
}

// Write file
await fsp.writeFile(path, res.contents.trim() + '\n')
consola.info(`πŸͺ„ Generated a new ${template} in ${path}`)
}
})
4 changes: 3 additions & 1 deletion packages/nuxi/src/commands/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,9 @@ export const commands = {
init: () => import('./init').then(_rDefault),
create: () => import('./init').then(_rDefault),
upgrade: () => import('./upgrade').then(_rDefault),
test: () => import('./test').then(_rDefault)
test: () => import('./test').then(_rDefault),
add: () => import('./add').then(_rDefault),
new: () => import('./add').then(_rDefault)
}

export type Command = keyof typeof commands
Expand Down
98 changes: 98 additions & 0 deletions packages/nuxi/src/utils/templates.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
import { upperFirst } from 'scule'

interface Template {
(options: { name: string }): { path: string, contents: string }
}

const api: Template = ({ name }) => ({
path: `server/api/${name}.ts`,
contents: `
import { defineHandle } from 'h3'

export default defineHandle((req, res) => {
return 'Hello ${name}'
})
`
})

const plugin: Template = ({ name }) => ({
path: `plugins/${name}.ts`,
contents: `
export default defineNuxtPlugin((nuxtApp) => {})
`
})

const component: Template = ({ name }) => ({
path: `components/${name}.vue`,
contents: `
<script lang="ts" setup></script>

<template>
<div>
Component: ${name}
</div>
</template>

<style scoped></style>
`
})

const composable: Template = ({ name }) => {
const nameWithUsePrefix = name.startsWith('use') ? name : `use${upperFirst(name)}`
return {
path: `composables/${name}.ts`,
contents: `
export const ${nameWithUsePrefix} = () => {
return ref()
}
`
}
}

const middleware: Template = ({ name }) => ({
path: `middleware/${name}.ts`,
contents: `
export default defineNuxtRouteMiddleware((to, from) => {})
`
})

const layout: Template = ({ name }) => ({
path: `layouts/${name}.vue`,
contents: `
<script lang="ts" setup></script>

<template>
<div>
Layout: ${name}
<slot />
</div>
</template>

<style scoped></style>
`
})

const page: Template = ({ name }) => ({
path: `pages/${name}.vue`,
contents: `
<script lang="ts" setup></script>

<template>
<div>
Page: foo
</div>
</template>

<style scoped></style>
`
})

export const templates = {
api,
plugin,
component,
composable,
middleware,
layout,
page
} as Record<string, Template>