duto 0.260906.0 → 0.261001.0

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 (75) hide show
  1. package/README.md +34 -12
  2. package/package.json +9 -3
  3. package/src/cli.ts +10 -7
  4. package/src/commands/new.ts +172 -0
  5. package/src/commands/templates/pages/.editorconfig +21 -0
  6. package/src/commands/templates/pages/README.md +21 -0
  7. package/src/commands/templates/pages/_gitignore +24 -0
  8. package/src/commands/templates/pages/components/locale-select.tsx +59 -0
  9. package/src/commands/templates/pages/components/select.tsx +95 -0
  10. package/src/commands/templates/pages/i18n/en.ts +17 -0
  11. package/src/commands/templates/pages/i18n/index.ts +19 -0
  12. package/src/commands/templates/pages/i18n/pt-br.ts +17 -0
  13. package/src/commands/templates/pages/package.json +22 -0
  14. package/src/commands/templates/pages/pages/404.tsx +12 -0
  15. package/src/commands/templates/pages/pages/index.tsx +16 -0
  16. package/src/commands/templates/pages/pages/layout.tsx +24 -0
  17. package/src/commands/templates/pages/style.css +24 -0
  18. package/src/commands/templates/pages/tsconfig.json +54 -0
  19. package/src/commands/templates/pages/types.ts +8 -0
  20. package/src/commands/templates/server/base/.editorconfig +21 -0
  21. package/src/commands/templates/server/base/.env.dev.example +2 -0
  22. package/src/commands/templates/server/base/.env.prod.example +2 -0
  23. package/src/commands/templates/server/base/README.md +29 -0
  24. package/src/commands/templates/server/base/_gitignore +100 -0
  25. package/src/commands/templates/server/base/actions/blog/index.get.ts +9 -0
  26. package/src/commands/templates/server/base/actions/blog/post/[id].get.ts +9 -0
  27. package/src/commands/templates/server/base/actions/index.get.ts +5 -0
  28. package/src/commands/templates/server/base/configs/duto.ts +11 -0
  29. package/src/commands/templates/server/base/configs/roles.ts +5 -0
  30. package/src/commands/templates/server/base/package.json +24 -0
  31. package/src/commands/templates/server/base/tsconfig.json +42 -0
  32. package/src/commands/templates/server/workerd/wrangler.toml +47 -0
  33. package/src/commands/upgrade.ts +30 -0
  34. package/src/index.ts +7 -2
  35. package/src/pages/{commands → cli/commands}/build.ts +13 -7
  36. package/src/pages/{commands → cli/commands}/dev.ts +19 -6
  37. package/src/pages/{commands → cli/commands}/preview.ts +6 -4
  38. package/src/pages/cli/index.ts +10 -0
  39. package/src/pages/cli/utils.ts +126 -0
  40. package/src/pages/client/app.tsx +27 -74
  41. package/src/pages/client/router.ts +15 -281
  42. package/src/pages/compiler/aliases.ts +2 -8
  43. package/src/pages/compiler/ast.ts +1 -538
  44. package/src/pages/compiler/constants.ts +95 -13
  45. package/src/pages/compiler/file.ts +1 -1
  46. package/src/pages/compiler/index.ts +20 -128
  47. package/src/pages/compiler/meta.ts +39 -228
  48. package/src/pages/compiler/routes.ts +4 -5
  49. package/src/pages/compiler/types.ts +11 -101
  50. package/src/pages/compiler/vite-plugin.ts +90 -69
  51. package/src/pages/i18n/client.ts +19 -7
  52. package/src/pages/i18n/element.ts +1 -1
  53. package/src/pages/i18n/server.ts +22 -7
  54. package/src/pages/index.ts +1 -2
  55. package/src/pages/preact/server.ts +1 -1
  56. package/src/server/app.ts +5 -10
  57. package/src/server/auth/ability.ts +1 -1
  58. package/src/server/auth/token.ts +5 -5
  59. package/src/server/cli/commands/build.ts +2 -2
  60. package/src/server/cli/commands/deploy.ts +1 -2
  61. package/src/server/cli/commands/dev.ts +6 -4
  62. package/src/server/cli/commands/routes.ts +0 -1
  63. package/src/server/cli/utils.ts +2 -8
  64. package/src/server/config.ts +18 -3
  65. package/src/server/entry.ts +3 -3
  66. package/src/server/open-api/register.ts +3 -3
  67. package/src/server/open-api/spec.ts +11 -4
  68. package/src/server/request.ts +46 -14
  69. package/src/server/routes.ts +8 -31
  70. package/src/server/utils.ts +25 -0
  71. package/src/utils.ts +43 -2
  72. package/src/pages/commands/dev-old.ts +0 -213
  73. package/src/pages/compiler/island.ts +0 -108
  74. package/src/pages/compiler/utils.ts +0 -5
  75. package/src/server/http.ts +0 -23
@@ -0,0 +1,24 @@
1
+ @import "tailwindcss";
2
+
3
+ html, body {
4
+ @apply overscroll-none
5
+ }
6
+
7
+ .text-mono {
8
+ font-family: ui-monospace,SFMono-Regular,monospace;
9
+ --tw-font-weight: 300;
10
+ font-weight: 300
11
+ }
12
+
13
+ .text-sky-gratient {
14
+ @apply bg-clip-text text-transparent;
15
+ background-image: radial-gradient(138.06% 1036.51% at 95.25% -2.54%, rgb(112, 209, 255) 14.06%, rgb(173, 228, 255) 51.02%, rgb(219, 243, 255) 79.09%);
16
+ }
17
+
18
+ .title {
19
+ @apply text-4xl lg:text-[3.5rem] leading-[1.1] font-semibold tracking-tight text-balance
20
+ }
21
+
22
+ .sub-title {
23
+ @apply mt-4 max-w-[60ch] text-lg text-balance md:mt-6 md:text-xl
24
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "lib": ["ES2023", "DOM", "DOM.Iterable"],
6
+ "types": ["vite/client", "bun-types", "node"],
7
+
8
+ /* Bundler mode */
9
+ "moduleResolution": "bundler",
10
+ "allowImportingTsExtensions": true,
11
+ "verbatimModuleSyntax": true,
12
+ "moduleDetection": "force",
13
+ "noEmit": true,
14
+ "jsx": "react-jsx",
15
+ "jsxImportSource": "preact",
16
+ "useDefineForClassFields": true,
17
+
18
+ /* Linting */
19
+ "strict": true,
20
+ "skipLibCheck": true,
21
+ "noUnusedLocals": true,
22
+ "noUnusedParameters": true,
23
+ "erasableSyntaxOnly": true,
24
+ "noFallthroughCasesInSwitch": true,
25
+ "noUncheckedSideEffectImports": true,
26
+
27
+ "paths": {
28
+ "react": ["./node_modules/preact/compat/"],
29
+ "react-dom": ["./node_modules/preact/compat/"],
30
+ // "@duto/*": ["./@duto/*"],
31
+ // "duto/*": ["./node_modules/duto/*"],
32
+ // "~icons/*": ["./@iconify-json/*"],
33
+ "@/*": ["./*"]
34
+ }
35
+ },
36
+ "include": [
37
+ "components",
38
+ "configs",
39
+ "enums",
40
+ "libs",
41
+ "i18n",
42
+ "pages",
43
+ "tests/**/*",
44
+ "utils",
45
+ "i18n.ts",
46
+ "i18n.tsx",
47
+ "config.ts",
48
+ "types.ts"
49
+ ],
50
+ "exclude": [
51
+ ".duto",
52
+ "node_modules"
53
+ ]
54
+ }
@@ -0,0 +1,8 @@
1
+
2
+ export type Posts = Post[]
3
+ export type Post = {
4
+ id: number | string,
5
+ userid?: string,
6
+ title: string,
7
+ body: string,
8
+ }
@@ -0,0 +1,21 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+ indent_style = space
9
+ indent_size = 2
10
+
11
+ # [*.{js,jsx,ts,tsx,json,yaml,yml}]
12
+ # Inherits all settings from [*] and applies to these extensions
13
+
14
+ [*.{json,jsonc}]
15
+ insert_final_newline = false
16
+
17
+ [*.md]
18
+ trim_trailing_whitespace = false
19
+
20
+ [Dockerfile]
21
+ indent_size = 4
@@ -0,0 +1,2 @@
1
+ APP_NAME=duto-api
2
+ KEY=YOUR_ENCRYPT_KEY
@@ -0,0 +1,2 @@
1
+ APP_NAME=duto-api
2
+ KEY=YOUR_ENCRYPT_KEY
@@ -0,0 +1,29 @@
1
+ # Duto Server - Starter Template
2
+
3
+ This template should help get you started developing.
4
+
5
+ ## Install dependencies
6
+
7
+ To install, run:
8
+
9
+ ```bash
10
+ bun i
11
+ ```
12
+
13
+ ## Tests
14
+
15
+ To perform the tests, run:
16
+
17
+ ```bash
18
+ bun test
19
+ ```
20
+
21
+ ## Development environment
22
+
23
+ Test the application locally in an environment identical to production using the command:
24
+
25
+ ```bash
26
+ duto dev
27
+ ```
28
+
29
+ [Read the Full Docs to Learn More](https://hub.bi/docs/duto)
@@ -0,0 +1,100 @@
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ ## custom
4
+ .duto/
5
+ .trash
6
+ .trash*
7
+ .aws-sam
8
+ lambda.zip
9
+ packaged.yaml
10
+
11
+ # dependencies
12
+ .wrangler/
13
+ node_modules
14
+ dist/
15
+ out/
16
+ dist-ssr
17
+
18
+ # production
19
+ /build
20
+
21
+ # misc
22
+ *.pem
23
+
24
+ # debug
25
+ logs
26
+ *.log
27
+ npm-debug.log*
28
+ yarn-debug.log*
29
+ yarn-error.log*
30
+ pnpm-debug.log*
31
+ lerna-debug.log*
32
+
33
+ # local env files
34
+ .env*.local
35
+ *.local
36
+ # .env
37
+
38
+ # vercel
39
+ .vercel
40
+
41
+ # tinybird
42
+ .venv
43
+ .tinyb
44
+
45
+ # typescript
46
+ *.tsbuildinfo
47
+
48
+ # miscellaneous
49
+ /pages/api/scripts*
50
+ apps/docs/openapi.json
51
+ packages/stripe-app/.build/*
52
+ .react-email
53
+ .contentlayer
54
+ .vscode
55
+ !.vscode/extensions.json
56
+ .idea
57
+ *.suo
58
+ *.ntvs*
59
+ *.njsproj
60
+ *.sln
61
+ *.sw?
62
+ *.csv
63
+ *.ndjson
64
+ .vitest
65
+
66
+ # tests
67
+ coverage
68
+ /cypress/videos/
69
+ /cypress/screenshots/
70
+
71
+ ### macOS ###
72
+ # General
73
+ .DS_Store
74
+ .AppleDouble
75
+ .LSOverride
76
+
77
+ # Thumbnails
78
+ ._*
79
+
80
+ # Files that might appear in the root of a volume
81
+ .DocumentRevisions-V100
82
+ .fseventsd
83
+ .Spotlight-V100
84
+ .TemporaryItems
85
+ .Trashes
86
+ .VolumeIcon.icns
87
+ .com.apple.timemachine.donotpresent
88
+
89
+ # Directories potentially created on remote AFP share
90
+ .AppleDB
91
+ .AppleDesktop
92
+ Network Trash Folder
93
+ Temporary Items
94
+ .apdisk
95
+
96
+ ### macOS Patch ###
97
+ # iCloud generated files
98
+ *.icloud
99
+ # Localflare generated files
100
+ .localflare/
@@ -0,0 +1,9 @@
1
+ import type { Req, Res } from 'duto'
2
+ import { newID } from 't0n'
3
+
4
+ export async function handle(req: Req, res: Res) {
5
+ return res.ok(Array.from({ length: 5 }, () => {
6
+ const id = newID()
7
+ return { id, desc: 'Blog post #'+ id }
8
+ }))
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { Req, Res } from 'duto'
2
+
3
+ export async function handle(req: Req, res: Res) {
4
+ const id = req.param('id')
5
+
6
+ return res.ok({
7
+ id, desc: 'Blog post #'+ id,
8
+ })
9
+ }
@@ -0,0 +1,5 @@
1
+ import type { Req, Res } from 'duto'
2
+
3
+ export async function handle(req: Req, res: Res) {
4
+ return res.ok({ message: 'Duto index' })
5
+ }
@@ -0,0 +1,11 @@
1
+ export default {
2
+ docs: {
3
+ path: '/docs',
4
+ agent: false,
5
+ // auth: {
6
+ // username: 'duto',
7
+ // password: 'duto',
8
+ // realm: 'Docs',
9
+ // },
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ admin: '*',
3
+ user: [],
4
+ guest: [],
5
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "$NAME",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "main": ".duto/index.js",
6
+ "type": "module",
7
+ "dependencies": {
8
+ "cripta": "0.x",
9
+ "t0n": "0.x"
10
+ },
11
+ "devDependencies": {
12
+ "bun-types": "catalog:",
13
+ "duto": "workspace:*",
14
+ "typescript": "catalog:",
15
+ "wrangler": "catalog:"
16
+ },
17
+ "duto": {
18
+ "type": "server",
19
+ "platform": "workerd",
20
+ "dev": {
21
+ "port": 3000
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "compilerOptions": {
3
+ "noEmit": true,
4
+ "target": "ESNext",
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "lib": ["ES2022"],
8
+ "types": ["duto"],
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "skipLibCheck": true,
13
+ "allowJs": true,
14
+ "resolveJsonModule": true,
15
+ "experimentalDecorators": true,
16
+ "emitDecoratorMetadata": true,
17
+ "useDefineForClassFields": false,
18
+ "rootDir": "./",
19
+ "paths": {
20
+ "@/*": [
21
+ "./*"
22
+ ]
23
+ }
24
+ },
25
+ "include": [
26
+ "actions",
27
+ "features",
28
+ "routes",
29
+ "configs",
30
+ "enums",
31
+ "libs",
32
+ "locales",
33
+ "middlewares",
34
+ "models",
35
+ "utils",
36
+ "tests/**/*"
37
+ ],
38
+ "exclude": [
39
+ ".duto",
40
+ "node_modules"
41
+ ]
42
+ }
@@ -0,0 +1,47 @@
1
+ name = "duto-api"
2
+ main = ".duto/index.js"
3
+ compatibility_date = "2026-08-06"
4
+
5
+ # workers_dev = false
6
+ # preview_urls = false
7
+ no_bundle = true
8
+ send_metrics = false
9
+ compatibility_flags = [ "no_nodejs_compat", "no_nodejs_compat_v2" ]
10
+
11
+ # route = "example.com"
12
+ # route = { pattern = "api.example.com", custom_domain = true }
13
+
14
+ # [[routes]]
15
+ # pattern = "api.example.com/*"
16
+ # zone_name = "example.com"
17
+ # [[routes]]
18
+ # pattern = "api.example.com"
19
+ # custom_domain = true
20
+
21
+ # [observability]
22
+ # enabled = true
23
+ # head_sampling_rate = 0.1 # 10% of requests are logged
24
+
25
+ # PAID
26
+ # [limits]
27
+ # # The maximum CPU time allowed per invocation, in milliseconds
28
+ # cpu_ms = 100
29
+
30
+ # Bindings (KV, D1, R2..)
31
+ # kv_namespaces = []
32
+ # d1_databases = []
33
+
34
+ # [[d1_databases]]
35
+ # binding = "SCRIPT_NAME"
36
+ # database_name = "DB_NAME"
37
+ # database_id = "DB_UUID"
38
+ # preview_database_id = "PREVIEW_UUID"
39
+ # migrations_table = "MIGRATION_TABLE_NAME"
40
+ # migrations_dir = "migrations/sql"
41
+ # persist_to = "./.wrangler/state"
42
+
43
+ # [env.production]
44
+ # name = "rajt-api-prod"
45
+
46
+ # [vars]
47
+ # API_HOST = "api.example.com"
@@ -0,0 +1,30 @@
1
+ import { command } from 't0n/cli'
2
+ import { dim, green } from 't0n/color'
3
+ import { event, error, step, log, rn } from 't0n/log'
4
+ import { _root } from '@/utils'
5
+ import { version } from '!/package.json'
6
+
7
+ import { createSpinner } from 'nanospinner'
8
+
9
+ export default command({
10
+ meta: {
11
+ name: 'upgrade',
12
+ description: '📄 Upgrade to latest version of Duto\n',
13
+ },
14
+ async run({ args }) { // @ts-ignore
15
+ const spinner = createSpinner('Upgrading...').start()
16
+
17
+ const proc = Bun.spawn(['bun', 'update', '-g', 'duto'], { stdout: 'ignore', stderr: 'ignore' })
18
+ const exitCode = await proc.exited
19
+
20
+ if (exitCode === 0) {
21
+ spinner.success({ text: 'Upgraded' })
22
+ } else {
23
+ spinner.error({ text: `Falha ao atualizar duto (exit ${exitCode})` })
24
+ process.exit(exitCode)
25
+ }
26
+
27
+ event(green('Congrats!') + ` You're already on the latest version of Duto.`)
28
+ // event(green('Congrats!') + ` You're already on the latest version of Duto ${dim(`(which is v${version})`)}`)
29
+ },
30
+ })
package/src/index.ts CHANGED
@@ -1,7 +1,12 @@
1
+ export * from './pages'
2
+
1
3
  export { default as Response } from './server/response'
2
- export { default as Config } from './server/config'
4
+ export * from './server/config'
3
5
 
4
- export { Enum, Envir } from 't0n'
6
+ export {
7
+ Enum,
8
+ Envir, hasEnv, getEnv, setEnv, addEnv, removeEnv
9
+ } from 't0n'
5
10
  export type { EnumStatic, EnumValue, EnumType } from 't0n'
6
11
 
7
12
  export type {
@@ -1,22 +1,29 @@
1
1
  import { build } from 'vite'
2
- import { filesize } from 'filesize'
2
+ import { setEnv } from 't0n'
3
3
  import { command } from 't0n/cli'
4
4
  import { dim, underline } from 't0n/color'
5
5
  import { wait, error, rn, event } from 't0n/log'
6
- import { meta } from '@/vite-plugin'
7
- import { getConfig } from '~/utils'
8
- import type { SummaryMetadata } from '@/types'
6
+ import { meta } from '#/compiler/vite-plugin'
7
+ import type { SummaryMetadata } from '#/compiler/types'
8
+ import { getConfig } from '../utils'
9
+ import { filesize } from '@/utils'
9
10
 
10
11
  export default command({
11
12
  meta: {
12
13
  name: 'build',
13
14
  description: '🗂️ Perform the build for production\n',
14
15
  },
15
- args: {
16
+ args: {
17
+ minify: {
18
+ description: 'Minify the result',
19
+ type: 'boolean',
20
+ default: true,
21
+ },
16
22
  },
17
23
  async run({ args }) {
18
- global.__hmr = !!args?.hmr
19
24
  wait('Building..')
25
+ setEnv('duto.hmr', !!args?.hmr)
26
+ setEnv('duto.minify', args.minify ?? true)
20
27
 
21
28
  try {
22
29
  await build(await getConfig())
@@ -65,7 +72,6 @@ export default command({
65
72
  event(`Builded successfully${st ? dim(` in ${st} ms`) : ''}`)
66
73
  } catch (e: any) {
67
74
  error(e)
68
- // error('Build failed:', e?.message || e)
69
75
  process.exit(0)
70
76
  } finally {
71
77
  rn()
@@ -2,9 +2,10 @@ import { command, watch, killProcess } from 't0n/cli'
2
2
  import { dim } from 't0n/color'
3
3
  import { error, log, rn } from 't0n/log'
4
4
  import { withPort } from 't0n/port'
5
- import { getMetadata } from '@/meta'
5
+ import { getMetadata } from '#/compiler/meta'
6
6
  import { _root } from '@/utils'
7
- import { getConfig, preview, reload } from '~/utils'
7
+ import { getConfig, preview, reload } from '../utils'
8
+ import { getEnv, setEnv } from 't0n'
8
9
 
9
10
  export const args = {
10
11
  port: {
@@ -25,17 +26,26 @@ export default command({
25
26
  name: 'dev',
26
27
  description: '🧪 Start dev server\n',
27
28
  }, // @ts-ignore
28
- args,
29
+ args: {
30
+ ...args,
31
+ minify: {
32
+ description: 'Minify the result',
33
+ type: 'boolean',
34
+ default: true,
35
+ },
36
+ },
29
37
  async run({ args }) {
30
38
  const config = await getConfig()
31
- const desiredPort = args.port ? Number(args.port) : (config?.preview?.port ? Number(config.preview.port) : 3000)
32
- const host = args.host ? String(args.host) : (config?.preview?.host ? String(config.preview.host) : 'localhost')
39
+ const duto = getEnv('duto', {})
40
+ const desiredPort = Number(args.port || duto?.dev?.port || 3000)
41
+ const host = String(args.host || duto?.dev?.host || 'localhost')
33
42
 
43
+ const minify = args.minify ?? true
34
44
  let buildProcess: Bun.Subprocess | null = null
35
45
 
36
46
  const _build = async () => {
37
47
  if (buildProcess) await killProcess(buildProcess)
38
- buildProcess = Bun.spawn(['duto', 'build', '--hmr'], {stdin: 'inherit', stdout: 'ignore', stderr: 'inherit'})
48
+ buildProcess = Bun.spawn(['duto', 'build', '--hmr', minify ? '' : '--no-minify'], {stdin: 'inherit', stdout: 'ignore', stderr: 'inherit'})
39
49
 
40
50
  try {
41
51
  const code = await buildProcess.exited
@@ -48,6 +58,9 @@ export default command({
48
58
  }
49
59
 
50
60
  withPort(desiredPort, async (port) => {
61
+ setEnv('duto.dev.port', port)
62
+ setEnv('duto.dev.host', host)
63
+
51
64
  const ignore = [
52
65
  /(^|[\/\\])\.(duto|git|cache|vscode|idea|next|nuxt|nyc_output)([\/\\]|$)/,
53
66
  /(^|[\/\\])(node_modules|tmp|dist|build|out|coverage)([\/\\]|$)/,
@@ -2,10 +2,11 @@ import { command } from 't0n/cli'
2
2
  import { dim } from 't0n/color'
3
3
  import { error, log, rn } from 't0n/log'
4
4
  import { withPort } from 't0n/port'
5
- import { getMetadata } from '@/meta'
5
+ import { getMetadata } from '#/compiler/meta'
6
6
  import { _root } from '@/utils'
7
7
  import { args } from './dev'
8
- import { getConfig, preview } from '~/utils'
8
+ import { getConfig, preview } from '../utils'
9
+ import { getEnv } from 't0n'
9
10
 
10
11
  export default command({
11
12
  meta: {
@@ -15,8 +16,9 @@ export default command({
15
16
  args,
16
17
  async run({ args }) {
17
18
  const config = await getConfig()
18
- const desiredPort = args.port ? Number(args.port) : (config?.preview?.port ? Number(config.preview.port) : 3000)
19
- const host = args.host ? String(args.host) : (config?.preview?.host ? config.preview.host as string : 'localhost')
19
+ const duto = getEnv('duto', {})
20
+ const desiredPort = Number(args.port || duto?.dev?.port || 3000)
21
+ const host = String(args.host || duto?.dev?.host || 'localhost')
20
22
 
21
23
  withPort(desiredPort, async (port) => {
22
24
  try {
@@ -0,0 +1,10 @@
1
+ import { join } from 'pathe'
2
+
3
+ const cmd = (c: string) => join(import.meta.dirname, 'commands', c)
4
+
5
+ export default {
6
+ dev: cmd('dev'),
7
+ build: cmd('build'),
8
+ preview: cmd('preview'),
9
+ // deploy: cmd('deploy'),
10
+ }