duto 0.260808.0 → 0.260915.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.
- package/LICENSE +2 -2
- package/README.md +35 -13
- package/package.json +54 -13
- package/src/cli.ts +45 -0
- package/src/commands/new.ts +147 -0
- package/src/commands/templates/base/.editorconfig +21 -0
- package/src/commands/templates/base/.env.dev.example +2 -0
- package/src/commands/templates/base/.env.prod.example +2 -0
- package/src/commands/templates/base/README.md +29 -0
- package/src/commands/templates/base/_gitignore +100 -0
- package/src/commands/templates/base/actions/blog/index.get.ts +9 -0
- package/src/commands/templates/base/actions/blog/post/[id].get.ts +9 -0
- package/src/commands/templates/base/actions/index.get.ts +5 -0
- package/src/commands/templates/base/configs/duto.ts +11 -0
- package/src/commands/templates/base/configs/roles.ts +5 -0
- package/src/commands/templates/base/package.json +24 -0
- package/src/commands/templates/base/tsconfig.json +42 -0
- package/src/commands/templates/workerd/wrangler.toml +47 -0
- package/src/commands/upgrade.ts +30 -0
- package/src/enum.ts +2 -0
- package/src/index.d.ts +61 -0
- package/src/index.ts +19 -23
- package/src/middleware.ts +2 -0
- package/src/{cli → pages/cli}/commands/build.ts +13 -7
- package/src/{cli → pages/cli}/commands/dev.ts +11 -4
- package/src/{cli → pages/cli}/commands/preview.ts +6 -4
- package/src/pages/cli/index.ts +10 -0
- package/src/{cli → pages/cli}/utils.ts +4 -5
- package/src/{client → pages/client}/app.tsx +1 -1
- package/src/{client → pages/client}/router.ts +1 -1
- package/src/{compiler → pages/compiler}/file.ts +1 -1
- package/src/{compiler → pages/compiler}/index.ts +2 -4
- package/src/{compiler → pages/compiler}/meta.ts +2 -2
- package/src/{compiler → pages/compiler}/routes.ts +1 -1
- package/src/{compiler → pages/compiler}/types.ts +10 -0
- package/src/{compiler → pages/compiler}/vite-plugin.ts +20 -45
- package/src/{i18n → pages/i18n}/client.ts +2 -2
- package/src/{i18n → pages/i18n}/element.ts +1 -1
- package/src/{i18n → pages/i18n}/server.ts +1 -1
- package/src/pages/index.ts +28 -0
- package/src/{preact → pages/preact}/server.ts +1 -1
- package/src/server/adapter/aws.ts +4 -0
- package/src/server/adapter/workerd.ts +4 -0
- package/src/server/app.ts +91 -0
- package/src/server/auth/ability.ts +72 -0
- package/src/server/auth/authnz.ts +86 -0
- package/src/server/auth/index.ts +5 -0
- package/src/server/auth/token.ts +147 -0
- package/src/server/auth/types.ts +2 -0
- package/src/server/cli/commands/build.ts +41 -0
- package/src/server/cli/commands/deploy.ts +81 -0
- package/src/server/cli/commands/dev.ts +279 -0
- package/src/server/cli/commands/make.ts +98 -0
- package/src/server/cli/commands/migrate.ts +93 -0
- package/src/server/cli/commands/routes.ts +78 -0
- package/src/server/cli/index.ts +27 -0
- package/src/server/cli/stubs.ts +39 -0
- package/src/server/cli/types.ts +3 -0
- package/src/server/cli/utils.ts +437 -0
- package/src/server/config.ts +19 -0
- package/src/server/db/d1.d.ts +1 -0
- package/src/server/db/d1.ts +1 -0
- package/src/server/db/dynamodb.d.ts +1 -0
- package/src/server/db/dynamodb.ts +1 -0
- package/src/server/db/index.ts +1 -0
- package/src/server/entry.ts +19 -0
- package/src/server/handle.ts +30 -0
- package/src/server/middlewares/auth.ts +40 -0
- package/src/server/middlewares/logger.ts +30 -0
- package/src/server/open-api/register.ts +29 -0
- package/src/server/open-api/spec.ts +114 -0
- package/src/server/request.ts +265 -0
- package/src/server/response.ts +142 -0
- package/src/server/routes.ts +473 -0
- package/src/server/types.ts +142 -0
- package/src/server/utils/environment.ts +17 -0
- package/src/server/utils.ts +71 -0
- package/src/server/validator.ts +70 -0
- package/src/utils.ts +15 -0
- package/src/cli/commands/dev-old.ts +0 -213
- package/src/cli/index.ts +0 -28
- package/src/compiler/utils.ts +0 -5
- /package/src/{client → pages/client}/hmr.ts +0 -0
- /package/src/{client → pages/client}/island.ts +0 -0
- /package/src/{client → pages/client}/link.ts +0 -0
- /package/src/{client → pages/client}/storage.ts +0 -0
- /package/src/{compiler → pages/compiler}/aliases.ts +0 -0
- /package/src/{compiler → pages/compiler}/assets.ts +0 -0
- /package/src/{compiler → pages/compiler}/ast.ts +0 -0
- /package/src/{compiler → pages/compiler}/constants.ts +0 -0
- /package/src/{compiler → pages/compiler}/island.ts +0 -0
- /package/src/{components → pages/components}/link.tsx +0 -0
- /package/src/{preact → pages/preact}/client-dev.ts +0 -0
- /package/src/{preact → pages/preact}/client.ts +0 -0
- /package/src/{preact → pages/preact}/context.ts +0 -0
- /package/src/{preact → pages/preact}/signals.ts +0 -0
- /package/src/{preact → pages/preact}/static-html.ts +0 -0
- /package/src/{preact → pages/preact}/types.ts +0 -0
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025-present,
|
|
3
|
+
Copyright (c) 2025-present, HUB.BI
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,26 +1,48 @@
|
|
|
1
|
-
<h1 align="left">
|
|
1
|
+
<h1 align="left">
|
|
2
|
+
🛢 Duto
|
|
3
|
+
<a href="https://npmjs.com/package/duto"><img src="https://img.shields.io/npm/v/duto.svg" alt="npm package"></a>
|
|
4
|
+
<br/>
|
|
5
|
+
<a href="https://pr.new/attla/duto"><img align="right" src="https://developer.stackblitz.com/img/start_pr_dark_small.svg" alt="Start new PR in StackBlitz Codeflow"></a>
|
|
6
|
+
</h1>
|
|
2
7
|
|
|
3
8
|
> ⚠️ Duto is under ALFA development — expect updates, rough edges, and occasional breack changes.
|
|
4
9
|
<br/>
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Duto is minimalist framework, focused on client-side pages and serverless APIs.
|
|
12
|
+
|
|
13
|
+
Principles:
|
|
14
|
+
- No vendor lock-in! Deploy anywhere with: `duto deploy`
|
|
15
|
+
- Developer happiness as a design constraint
|
|
16
|
+
- Optimized by default!
|
|
17
|
+
|
|
18
|
+
Pages features:
|
|
19
|
+
- Static pages `/blog.tsx` `getStaticProps()`
|
|
20
|
+
- Prerendered dynamic pages `/blog/[slug].tsx` `getStaticProps()`
|
|
21
|
+
- Dynamic pages on client-side `/blog/[slug].tsx` `getProps()`
|
|
22
|
+
- Not found page on client-side `/blog/not-found.tsx`
|
|
23
|
+
- Efficient route hierarchy `/not-found.tsx`
|
|
24
|
+
- Catch-all page whitout SSR! `/blog/[...slug].tsx`
|
|
25
|
+
- Optional catch-all routes whitout SSR! `/blog/[[...slug]].tsx`
|
|
26
|
+
- Simple internationalization (i18n) integration `tˋfeaturesˋ`
|
|
27
|
+
|
|
28
|
+
Server features:
|
|
29
|
+
- Instant server and cold starts
|
|
30
|
+
- Optimized build, greater efficiency in less bundle size
|
|
31
|
+
- Built-in core shims for compatibility with custom runtimes
|
|
32
|
+
- Fully typed OpenAPI documentation
|
|
33
|
+
- Powerful request validations
|
|
34
|
+
- Fine-grained authentication
|
|
35
|
+
|
|
36
|
+
[Read the Docs to Learn More](https://hub.bi/docs/duto)
|
|
13
37
|
|
|
14
38
|
## Ecosystem Packages
|
|
15
39
|
|
|
16
40
|
| Package | Version | Description |
|
|
17
41
|
| -: | :- | :- |
|
|
18
|
-
| [
|
|
19
|
-
| [create-rajt](https://github.com/attla/create-rajt) | [](https://npm.im/create-rajt) | 📁 CLI tool for create new Rajt projects, from starter templates. |
|
|
20
|
-
| [forj](https://github.com/attla/forj) | [](https://npm.im/forj) | 🗂️ Just another query builder in typescript |
|
|
21
|
-
| [t0n](https://github.com/attla/t0n) | [](https://npm.im/t0n) | 🧰 Collection of elegant typescript resources for web artisans. |
|
|
42
|
+
| [forj](https://github.com/attla/forj) | [](https://npm.im/forj) | 🗂️ Fast and lightweight query builder in typescript |
|
|
22
43
|
| [cripta](https://github.com/attla/cripta) | [](https://npm.im/cripta) | 🧛 A layer of encryption a little too judicious. |
|
|
44
|
+
| [t0n](https://github.com/attla/t0n) | [](https://npm.im/t0n) | 🧰 Collection of elegant typescript resources for web artisans. |
|
|
23
45
|
|
|
24
46
|
## License
|
|
25
47
|
|
|
26
|
-
This package is licensed under the [MIT license](https://github.com/attla/duto/blob/main/LICENSE) © [
|
|
48
|
+
This package is licensed under the [MIT license](https://github.com/attla/duto/blob/main/LICENSE) © [HUB](https://hub.bi)
|
package/package.json
CHANGED
|
@@ -1,50 +1,90 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "duto",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "All-in-one serverless framework for web artisans",
|
|
4
|
+
"version": "0.260915.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
7
|
+
"types": "./src/index.d.ts",
|
|
8
|
+
"bin": "./src/cli.ts",
|
|
7
9
|
"files": ["src"],
|
|
8
|
-
"bin": "./src/cli/index.ts",
|
|
9
10
|
"exports": {
|
|
10
|
-
".": "./src/index.ts"
|
|
11
|
+
".": "./src/index.ts",
|
|
12
|
+
"./auth": "./src/server/auth/index.ts",
|
|
13
|
+
"./db": "./src/db/index.ts",
|
|
14
|
+
"./database": "./src/db/index.ts",
|
|
15
|
+
"./d1": "./src/server/db/d1.ts",
|
|
16
|
+
"./d1/types": "./src/server/db/d1.d.ts",
|
|
17
|
+
"./dynamodb": "./src/server/db/dynamodb.ts",
|
|
18
|
+
"./dynamodb/types": "./src/server/db/dynamodb.d.ts",
|
|
19
|
+
"./enum": "./src/enum.ts",
|
|
20
|
+
"./http": "./src/server/http.ts",
|
|
21
|
+
"./middleware": "./src/middleware.ts",
|
|
22
|
+
"./types": "./src/server/types.ts",
|
|
23
|
+
"./types/global": "./global.d.ts",
|
|
24
|
+
"./env": "./src/server/utils/environment.ts",
|
|
25
|
+
"./length": "./src/server/utils/length.ts"
|
|
11
26
|
},
|
|
12
27
|
"dependencies": {
|
|
28
|
+
"@inquirer/confirm": "^5.1.8",
|
|
29
|
+
"@inquirer/input": "^4.1.8",
|
|
30
|
+
"@inquirer/select": "^4.1.0",
|
|
31
|
+
"nanospinner": "^1.2.2",
|
|
32
|
+
"@hono/node-server": "^1.19.11",
|
|
33
|
+
"@hono/standard-validator": "^0.2.2",
|
|
34
|
+
"@hono/zod-validator": "^0.7.6",
|
|
35
|
+
"@scalar/hono-api-reference": "^0.12.0",
|
|
36
|
+
"@minify-html/node": "^0.18.1",
|
|
13
37
|
"@preact/signals": "^2.9.2",
|
|
14
38
|
"@swc/core": "^1.15.21",
|
|
15
39
|
"chokidar": "^3.5.2",
|
|
16
40
|
"citty": "^0.2.2",
|
|
17
41
|
"consola": "^3.4.2",
|
|
18
|
-
"
|
|
42
|
+
"cripta": "0.x",
|
|
43
|
+
"dotenv": "^16.5.0",
|
|
44
|
+
"esbuild": "^0.25.2",
|
|
45
|
+
"forj": "0.x",
|
|
46
|
+
"hono": "^4.13.7",
|
|
47
|
+
"hono-openapi": "^1.3.0",
|
|
48
|
+
"localflare-api": "^0.5.0",
|
|
49
|
+
"localflare-core": "^0.5.0",
|
|
50
|
+
"miniflare": "^4.20260730.0",
|
|
19
51
|
"pathe": "^2.0",
|
|
20
52
|
"preact": "^10.29.7",
|
|
21
53
|
"preact-render-to-string": "^6.6.6",
|
|
54
|
+
"quansync": "^0.2.11",
|
|
22
55
|
"t0n": "0.x",
|
|
23
56
|
"vite": "^8.0.0",
|
|
24
|
-
"wouter-preact": "^3.10.0"
|
|
57
|
+
"wouter-preact": "^3.10.0",
|
|
58
|
+
"wrangler": "^4.128.0",
|
|
59
|
+
"zod": "^4.3.6",
|
|
60
|
+
"zod-openapi": "^5.4.6"
|
|
25
61
|
},
|
|
26
62
|
"devDependencies": {
|
|
63
|
+
"@cloudflare/workers-types": "^4.20260113.0",
|
|
27
64
|
"@minify-html/node": "^0.18.1",
|
|
28
65
|
"@preact/preset-vite": "^2.10.5",
|
|
29
66
|
"@tailwindcss/vite": "^4.3.1",
|
|
30
|
-
"
|
|
31
|
-
"bun-types": "^1.3.14",
|
|
67
|
+
"bun-types": "^1.4.0",
|
|
32
68
|
"typescript": "^5.9.3"
|
|
33
69
|
},
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
"
|
|
70
|
+
"resolutions": {
|
|
71
|
+
"@smithy/types": "^4.3.0",
|
|
72
|
+
"zod": "^4.3.6"
|
|
37
73
|
},
|
|
74
|
+
"sideEffects": false,
|
|
75
|
+
"packageManager": "bun@1.4.0",
|
|
38
76
|
"publishConfig": {
|
|
39
77
|
"registry": "https://registry.npmjs.org"
|
|
40
78
|
},
|
|
41
|
-
"author": "
|
|
79
|
+
"author": "HUB <foss@hub.bi>",
|
|
42
80
|
"license": "MIT",
|
|
43
|
-
"homepage": "https://
|
|
81
|
+
"homepage": "https://hub.bi/docs/duto",
|
|
44
82
|
"repository": "git://github.com/attla/duto",
|
|
45
83
|
"bugs": "https://github.com/attla/duto/issues",
|
|
46
84
|
"keywords": [
|
|
47
85
|
"SSG",
|
|
86
|
+
"app",
|
|
87
|
+
"http",
|
|
48
88
|
"application",
|
|
49
89
|
"framework",
|
|
50
90
|
"router",
|
|
@@ -52,6 +92,7 @@
|
|
|
52
92
|
"typescript",
|
|
53
93
|
"cloudflare",
|
|
54
94
|
"workers",
|
|
95
|
+
"workerd",
|
|
55
96
|
"vercel",
|
|
56
97
|
"bun"
|
|
57
98
|
]
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
function exit(msg?: string, desc?: string) {
|
|
4
|
+
msg && console.error(msg)
|
|
5
|
+
desc && console.log(desc)
|
|
6
|
+
process.exit(0)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (!import.meta.main)
|
|
10
|
+
exit('Error: Duto must be used directly as CLI command.')
|
|
11
|
+
|
|
12
|
+
if (!process?.isBun || typeof Bun === 'undefined')
|
|
13
|
+
exit('Error: "Bun" is not available.', ' Try install: https://bun.sh/get')
|
|
14
|
+
|
|
15
|
+
global.__st = performance.now()
|
|
16
|
+
|
|
17
|
+
import { join } from 'pathe'
|
|
18
|
+
import { cli } from 't0n/cli'
|
|
19
|
+
import { setEnv } from 't0n'
|
|
20
|
+
import { version } from '!/package.json'
|
|
21
|
+
import { _root, _duto } from './utils'
|
|
22
|
+
|
|
23
|
+
const cmd = (c: string) => join(import.meta.dirname, 'commands', c)
|
|
24
|
+
|
|
25
|
+
let pkg
|
|
26
|
+
let commands = {}
|
|
27
|
+
try {
|
|
28
|
+
pkg = await import(join(_root, 'package.json'))
|
|
29
|
+
if (!pkg || !pkg.duto || !pkg?.duto?.type || !['pages', 'server'].includes(pkg.duto.type))
|
|
30
|
+
exit('Error: invalid app type.')
|
|
31
|
+
|
|
32
|
+
setEnv('duto', pkg.duto)
|
|
33
|
+
commands = (await import(join(_duto, pkg.duto.type, 'cli')))?.default
|
|
34
|
+
} catch {}
|
|
35
|
+
|
|
36
|
+
cli({
|
|
37
|
+
name: 'duto',
|
|
38
|
+
description: 'Duto',
|
|
39
|
+
version,
|
|
40
|
+
commands: {
|
|
41
|
+
new: cmd('new'),
|
|
42
|
+
upgrade: cmd('upgrade'),
|
|
43
|
+
...commands,
|
|
44
|
+
},
|
|
45
|
+
})
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { basename, join, relative, resolve } from 'pathe'
|
|
2
|
+
import { command } from 't0n/cli'
|
|
3
|
+
import { bold, dim, green, red } from 't0n/color'
|
|
4
|
+
import { event, error, step, log, rn } from 't0n/log'
|
|
5
|
+
import { _root } from '@/utils'
|
|
6
|
+
|
|
7
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'
|
|
8
|
+
import confirm from '@inquirer/confirm'
|
|
9
|
+
import input from '@inquirer/input'
|
|
10
|
+
import select from '@inquirer/select'
|
|
11
|
+
import { createSpinner } from 'nanospinner'
|
|
12
|
+
import { exit } from 'node:process'
|
|
13
|
+
|
|
14
|
+
const templates = [
|
|
15
|
+
'aws',
|
|
16
|
+
'workerd',
|
|
17
|
+
'vercel',
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
const renameFiles: Record<string, string | undefined> = {
|
|
21
|
+
_gitignore: '.gitignore',
|
|
22
|
+
_gitkeep: '.gitkeep',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
function mkdirp(dir: string) {
|
|
27
|
+
try {
|
|
28
|
+
mkdirSync(dir, { recursive: true })
|
|
29
|
+
} catch (e) {
|
|
30
|
+
if (e instanceof Error) {
|
|
31
|
+
if ('code' in e && e.code === 'EEXIST') {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throw e
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function copy(src: string, dest: string) {
|
|
40
|
+
const stat = statSync(src)
|
|
41
|
+
stat.isDirectory()
|
|
42
|
+
? copyDir(src, dest)
|
|
43
|
+
: copyFileSync(src, dest)
|
|
44
|
+
}
|
|
45
|
+
function copyDir(srcDir: string, destDir: string) {
|
|
46
|
+
mkdirSync(destDir, { recursive: true })
|
|
47
|
+
for (const file of readdirSync(srcDir)) {
|
|
48
|
+
const srcFile = resolve(srcDir, file)
|
|
49
|
+
const destFile = resolve(destDir, file)
|
|
50
|
+
copy(srcFile, destFile)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default command({
|
|
55
|
+
meta: {
|
|
56
|
+
name: 'new',
|
|
57
|
+
description: '📄 Create new project with duto\n',
|
|
58
|
+
},
|
|
59
|
+
args: {
|
|
60
|
+
install: {
|
|
61
|
+
alias: 'i',
|
|
62
|
+
description: 'Install dependencies',
|
|
63
|
+
type: 'boolean',
|
|
64
|
+
default: false,
|
|
65
|
+
},
|
|
66
|
+
template: {
|
|
67
|
+
alias: 't',
|
|
68
|
+
description: 'Template to use',
|
|
69
|
+
type: 'enum',
|
|
70
|
+
options: templates,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
async run({ args }) { // @ts-ignore
|
|
74
|
+
const root = process.cwd() || process.env?.PWD || process.stdin?.path
|
|
75
|
+
let dir = args._[0]
|
|
76
|
+
if (dir) {
|
|
77
|
+
step(bold('Using target directory: '+ dim('/'+ dir.replace(/^\//, ''))))
|
|
78
|
+
} else {
|
|
79
|
+
dir = await input({ message: 'Target directory', default: root })
|
|
80
|
+
if (!dir.startsWith(root))
|
|
81
|
+
dir = join(root, dir)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const name = basename(/^(\.\/|\.\\|\.)$/.test(dir) ? root : dir)
|
|
85
|
+
const template = args.template || (await select({
|
|
86
|
+
loop: true,
|
|
87
|
+
message: 'Which template do you want to use?',
|
|
88
|
+
choices: templates.map(v => ({ title: v, value: v})),
|
|
89
|
+
default: 'workerd',
|
|
90
|
+
}))
|
|
91
|
+
|
|
92
|
+
if (!template)
|
|
93
|
+
throw new Error('No template selected')
|
|
94
|
+
|
|
95
|
+
if (!templates.includes(template))
|
|
96
|
+
throw new Error(`Invalid template selected: ${template}`)
|
|
97
|
+
|
|
98
|
+
if (existsSync(dir) && readdirSync(dir).length > 0) {
|
|
99
|
+
const response = await confirm({ message: 'Directory not empty. Continue?', default: false })
|
|
100
|
+
if (!response) process.exit(1)
|
|
101
|
+
} else {
|
|
102
|
+
mkdirp(dir)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const spinner = createSpinner('Cloning the template').start()
|
|
106
|
+
for (const t of ['base', template]) {
|
|
107
|
+
const templateDir = resolve(import.meta.dir, './templates/'+ t)
|
|
108
|
+
const files = readdirSync(templateDir)
|
|
109
|
+
for (const file of files.filter(f => f !== 'package.json'))
|
|
110
|
+
copy(join(templateDir, file), join(dir, renameFiles[file] ?? file))
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
spinner.success()
|
|
114
|
+
|
|
115
|
+
const pkgPath = resolve(__dirname, `./templates/base/package.json`)
|
|
116
|
+
if (existsSync(pkgPath)) {
|
|
117
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))
|
|
118
|
+
pkg.name = name
|
|
119
|
+
writeFileSync(join(dir, 'package.json'), JSON.stringify(pkg, null, 2))
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (args?.install) {
|
|
123
|
+
const spinner2 = createSpinner('Installing project dependencies').start()
|
|
124
|
+
const proc = Bun.spawn(['bun', 'i'], { stdout: 'ignore', stderr: 'inherit' })
|
|
125
|
+
const procExit = await proc.exited
|
|
126
|
+
|
|
127
|
+
if (procExit === 0) {
|
|
128
|
+
spinner2.success()
|
|
129
|
+
} else {
|
|
130
|
+
spinner2.stop({
|
|
131
|
+
mark: red('×'),
|
|
132
|
+
text: 'Failed to install project dependencies',
|
|
133
|
+
})
|
|
134
|
+
exit(procExit)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
event('New project successfully created')
|
|
139
|
+
if (dir != root) {
|
|
140
|
+
rn()
|
|
141
|
+
console.log(
|
|
142
|
+
dim('Get started with:'),
|
|
143
|
+
bold(`cd ${name}`),
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
})
|
|
@@ -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,29 @@
|
|
|
1
|
+
# Duto - 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,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
|
+
}
|