@forinda/kickjs-cli 8.5.0 → 8.6.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/dist/{project-docs-Y6vOc-Uj.mjs → agent-docs-BFOgLbXq.mjs} +9 -71
- package/dist/agent-docs-BFOgLbXq.mjs.map +1 -0
- package/dist/{project-docs-BE8DKCWP.mjs → agent-docs-BU1rORKA.mjs} +3 -65
- package/dist/{build-D3rNfcxu.mjs → build-CdIpRyfy.mjs} +3 -3
- package/dist/{build-D3rNfcxu.mjs.map → build-CdIpRyfy.mjs.map} +1 -1
- package/dist/{build-DwfrMHgx.mjs → build-DlfIkjcw.mjs} +2 -2
- package/dist/{builtins-D4pwODzu.mjs → builtins-CfAXBoIM.mjs} +2 -2
- package/dist/{builtins-DtTYiDg0.mjs → builtins-CmuUgcIq.mjs} +36 -31
- package/dist/cli.mjs +2 -2
- package/dist/config-SvlcF3Ls.mjs +12 -0
- package/dist/config-ndsVdO8u.mjs +13 -0
- package/dist/config-ndsVdO8u.mjs.map +1 -0
- package/dist/{doctor-Df6zCPr5.mjs → doctor-D3RMXkxE.mjs} +6 -6
- package/dist/{doctor-Df6zCPr5.mjs.map → doctor-D3RMXkxE.mjs.map} +1 -1
- package/dist/fs-DdNMcW_P.mjs +12 -0
- package/dist/fs-DdNMcW_P.mjs.map +1 -0
- package/dist/fs-v57MCgpH.mjs +11 -0
- package/dist/fullstack-DOufUeMv.mjs +95 -0
- package/dist/fullstack-LJwhodT-.mjs +96 -0
- package/dist/fullstack-LJwhodT-.mjs.map +1 -0
- package/dist/index.d.mts +15 -24
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{plugin-B8fmVbk8.mjs → plugin-Dighdqh-.mjs} +2 -2
- package/dist/{plugin-B-mP0jvi.mjs → plugin-Dn67elEZ.mjs} +2 -2
- package/dist/project-AXCA1hD9.mjs +45 -0
- package/dist/project-Cb_NLUWI.mjs +46 -0
- package/dist/project-Cb_NLUWI.mjs.map +1 -0
- package/dist/{project-root-BzyIWFlH.mjs → project-root-C7TrLJlZ.mjs} +3 -3
- package/dist/{project-root-BzyIWFlH.mjs.map → project-root-C7TrLJlZ.mjs.map} +1 -1
- package/dist/{project-root-CSHMf3L7.mjs → project-root-Dgvy5kYG.mjs} +2 -2
- package/dist/{prompts-wFEGsPZt.mjs → prompts-CSATvwXw.mjs} +2 -2
- package/dist/{prompts-wFEGsPZt.mjs.map → prompts-CSATvwXw.mjs.map} +1 -1
- package/dist/{rolldown-runtime-DzFISCwE.mjs → rolldown-runtime-BhxEEqxa.mjs} +1 -1
- package/dist/{run-plugins-ByRyAAZe.mjs → run-plugins-Cf_6BgGZ.mjs} +34 -29
- package/dist/run-plugins-Cf_6BgGZ.mjs.map +1 -0
- package/dist/{typegen-BfOYvlWo.mjs → typegen-97E_RYNp.mjs} +4 -4
- package/dist/typegen-CYhFNfIu.mjs +132 -0
- package/dist/{typegen-Bx2IQ-w5.mjs.map → typegen-CYhFNfIu.mjs.map} +1 -1
- package/dist/{types-dUiZnaWm.mjs → types-lHwt_SNI.mjs} +1 -1
- package/package.json +10 -9
- package/templates/base/feature.json +18 -0
- package/templates/base/files/README.md +61 -0
- package/templates/base/files/_dot_editorconfig +13 -0
- package/templates/base/files/_dot_env +2 -0
- package/templates/base/files/_dot_env.example +2 -0
- package/templates/base/files/_dot_env.test +9 -0
- package/templates/base/files/_dot_env.test.example +11 -0
- package/templates/base/files/_dot_gitattributes +18 -0
- package/templates/base/files/_dot_gitignore +14 -0
- package/templates/base/files/_dot_oxfmtrc.json +9 -0
- package/templates/base/files/kick.config.ts +58 -0
- package/templates/base/files/src/modules/hello/hello.controller.ts +26 -0
- package/templates/base/files/src/modules/hello/hello.module.ts +21 -0
- package/templates/base/files/src/modules/hello/hello.service.ts +12 -0
- package/templates/base/files/src/modules/index.ts +7 -0
- package/templates/base/files/tsconfig.json +21 -0
- package/templates/base/files/vite.config.ts +31 -0
- package/templates/base/files/vitest.config.ts +18 -0
- package/templates/feature-devtools/feature.json +13 -0
- package/templates/feature-queue/feature.json +16 -0
- package/templates/feature-queue/files/_dot_env.append +2 -0
- package/templates/feature-queue/files/_dot_env.example.append +2 -0
- package/templates/feature-swagger/feature.json +16 -0
- package/templates/feature-ws/feature.json +13 -0
- package/templates/fullstack-root/files/_dot_gitignore +8 -0
- package/templates/fullstack-root/files/netlify.toml +13 -0
- package/templates/fullstack-root/files/vercel.json +5 -0
- package/templates/host-config/files/netlify.toml +6 -0
- package/templates/host-config/files/vercel.json +5 -0
- package/templates/runtime-express/feature.json +22 -0
- package/templates/runtime-fastify/feature.json +13 -0
- package/templates/runtime-h3/feature.json +13 -0
- package/templates/schema-valibot/feature.json +3 -0
- package/templates/schema-valibot/files/src/config/index.ts +41 -0
- package/templates/schema-yup/feature.json +3 -0
- package/templates/schema-yup/files/src/config/index.ts +43 -0
- package/templates/schema-zod/feature.json +3 -0
- package/templates/schema-zod/files/src/config/index.ts +41 -0
- package/templates/server-fullstack/feature.json +13 -0
- package/templates/template-minimal/feature.json +10 -0
- package/templates/template-minimal/files/src/index.ts +17 -0
- package/templates/template-rest/feature.json +10 -0
- package/templates/template-rest/files/src/index.ts +28 -0
- package/templates/web-kick/files/web/index.html +12 -0
- package/templates/web-kick/files/web/src/App.tsx +45 -0
- package/templates/web-kick/files/web/src/api.ts +14 -0
- package/templates/web-kick/files/web/src/main.tsx +9 -0
- package/templates/web-kick/files/web/tsconfig.json +15 -0
- package/templates/web-kick/files/web/vite.config.ts +13 -0
- package/dist/agent-docs-CXX06wib.mjs +0 -11
- package/dist/agent-docs-CXs5UDAM.mjs +0 -12
- package/dist/agent-docs-CXs5UDAM.mjs.map +0 -1
- package/dist/config-BUYf44lU.mjs +0 -13
- package/dist/config-BUYf44lU.mjs.map +0 -1
- package/dist/config-F1NW28_P.mjs +0 -12
- package/dist/fullstack-BcJ5lOwt.mjs +0 -194
- package/dist/fullstack-D3W7RS2W.mjs +0 -195
- package/dist/fullstack-D3W7RS2W.mjs.map +0 -1
- package/dist/project-5aAVIQV5.mjs +0 -450
- package/dist/project-DdYD7xPw.mjs +0 -451
- package/dist/project-DdYD7xPw.mjs.map +0 -1
- package/dist/project-docs-Y6vOc-Uj.mjs.map +0 -1
- package/dist/run-plugins-ByRyAAZe.mjs.map +0 -1
- package/dist/typegen-Bx2IQ-w5.mjs +0 -132
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forinda/kickjs-cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.6.0",
|
|
4
4
|
"description": "CLI for KickJS — project scaffolding, DDD module generation, dev/build/start",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kickjs",
|
|
@@ -29,30 +29,31 @@
|
|
|
29
29
|
},
|
|
30
30
|
"files": [
|
|
31
31
|
"bin.js",
|
|
32
|
-
"dist"
|
|
32
|
+
"dist",
|
|
33
|
+
"templates"
|
|
33
34
|
],
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"@clack/prompts": "^1.8.0",
|
|
36
37
|
"commander": "^15.0.0",
|
|
37
38
|
"glob": "^13.0.6",
|
|
38
39
|
"jiti": "^2.7.0",
|
|
39
|
-
"oxc-parser": "^0.
|
|
40
|
-
"oxfmt": "^0.
|
|
40
|
+
"oxc-parser": "^0.151.0",
|
|
41
|
+
"oxfmt": "^0.70.0",
|
|
41
42
|
"picocolors": "^1.1.1",
|
|
42
43
|
"pluralize": "^8.0.0",
|
|
43
|
-
"@forinda/kickjs": "8.
|
|
44
|
-
"@forinda/kickjs-
|
|
45
|
-
"@forinda/kickjs-
|
|
44
|
+
"@forinda/kickjs": "8.7.0",
|
|
45
|
+
"@forinda/kickjs-db": "7.4.0",
|
|
46
|
+
"@forinda/kickjs-cli-kit": "0.1.2"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@swc/core": "^1.16.2",
|
|
49
|
-
"@types/node": "^26.6.
|
|
50
|
+
"@types/node": "^26.6.2",
|
|
50
51
|
"@types/pg": "^8.23.1",
|
|
51
52
|
"@types/pluralize": "^0.0.33",
|
|
52
53
|
"@typescript/typescript6": "^6.0.2",
|
|
53
54
|
"pg": "^8.23.0",
|
|
54
55
|
"typescript": "^7.0.2",
|
|
55
|
-
"vite": "^8.3.
|
|
56
|
+
"vite": "^8.3.1",
|
|
56
57
|
"vitest": "^5.0.1",
|
|
57
58
|
"@forinda/kickjs-ai": "8.0.0"
|
|
58
59
|
},
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": ["@forinda/kickjs", "@forinda/kickjs-schema", "dotenv", "reflect-metadata"],
|
|
3
|
+
"devDependencies": [
|
|
4
|
+
"@forinda/kickjs-cli",
|
|
5
|
+
"@forinda/kickjs-testing",
|
|
6
|
+
"@forinda/kickjs-vite",
|
|
7
|
+
"@types/supertest",
|
|
8
|
+
"@swc/core",
|
|
9
|
+
"@types/node",
|
|
10
|
+
"unplugin-swc",
|
|
11
|
+
"vite",
|
|
12
|
+
"supertest",
|
|
13
|
+
"vitest",
|
|
14
|
+
"typescript",
|
|
15
|
+
"oxfmt",
|
|
16
|
+
"oxlint"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# {{name}}
|
|
2
|
+
|
|
3
|
+
A **{{templateLabel}}** built with [KickJS](https://kickjs.app/) — a decorator-driven Node.js framework for TypeScript that runs on Express, Fastify, or h3 (swap the engine in one line).
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
{{packageManager}} install
|
|
9
|
+
kick dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Scripts
|
|
13
|
+
|
|
14
|
+
| Command | Description |
|
|
15
|
+
| ------------------------------------ | ------------------------------------ |
|
|
16
|
+
| `kick dev` | Start dev server with Vite HMR |
|
|
17
|
+
| `kick build` | Production build |
|
|
18
|
+
| `kick start` | Run production build |
|
|
19
|
+
| `{{packageManager}} run test` | Run tests with Vitest |
|
|
20
|
+
| `kick g module <name>` | Generate a DDD module |
|
|
21
|
+
| `kick g scaffold <name> <fields...>` | Generate CRUD from field definitions |
|
|
22
|
+
| `kick add <package>` | Add a KickJS package |
|
|
23
|
+
|
|
24
|
+
## Project Structure
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
src/
|
|
28
|
+
├── index.ts # Application entry point
|
|
29
|
+
├── modules/ # Feature modules (controllers, services, repos)
|
|
30
|
+
│ └── index.ts # Module registry
|
|
31
|
+
└── ...
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Packages
|
|
35
|
+
|
|
36
|
+
{{packages}}
|
|
37
|
+
|
|
38
|
+
## Adding Features
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
kick add swagger # OpenAPI documentation
|
|
42
|
+
kick add ws # WebSocket support
|
|
43
|
+
kick add queue # Background job processing
|
|
44
|
+
kick add --list # Show all available packages
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
For email, scheduled tasks, multi-tenancy, OpenTelemetry, GraphQL, and notifications use the BYO recipes in the [KickJS guides](https://kickjs.app/guide/) — they wire the upstream library through `defineAdapter()` / `definePlugin()` directly, so you keep control of the integration.
|
|
48
|
+
|
|
49
|
+
## Environment Variables
|
|
50
|
+
|
|
51
|
+
Copy `.env.example` to `.env` and configure:
|
|
52
|
+
|
|
53
|
+
| Variable | Default | Description |
|
|
54
|
+
| ---------- | ------------- | ----------- |
|
|
55
|
+
| `PORT` | `3000` | Server port |
|
|
56
|
+
| `NODE_ENV` | `development` | Environment |
|
|
57
|
+
|
|
58
|
+
## Learn More
|
|
59
|
+
|
|
60
|
+
- [KickJS Documentation](https://kickjs.app/)
|
|
61
|
+
- [CLI Reference](https://kickjs.app/api/cli.html)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Read INSTEAD of .env when NODE_ENV=test (or under vitest).
|
|
2
|
+
# No fallback to .env — declare here everything the suite needs, so a
|
|
3
|
+
# missing var fails the run instead of silently resolving to your dev value.
|
|
4
|
+
#
|
|
5
|
+
# Not committed. Add new keys to .env.test.example too, with placeholder
|
|
6
|
+
# values — never real endpoints or credentials.
|
|
7
|
+
NODE_ENV=test
|
|
8
|
+
PORT=0
|
|
9
|
+
LOG_LEVEL=silent
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Template for .env.test. Copy it and fill in your machine's values:
|
|
2
|
+
# cp .env.test.example .env.test
|
|
3
|
+
# Read INSTEAD of .env when NODE_ENV=test (or under vitest).
|
|
4
|
+
# No fallback to .env — declare here everything the suite needs, so a
|
|
5
|
+
# missing var fails the run instead of silently resolving to your dev value.
|
|
6
|
+
#
|
|
7
|
+
# This file is committed; .env.test is not. Keep the two in step, with
|
|
8
|
+
# placeholder values here — never real endpoints or credentials.
|
|
9
|
+
NODE_ENV=test
|
|
10
|
+
PORT=0
|
|
11
|
+
LOG_LEVEL=silent
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Auto-detect text files and normalise line endings to LF
|
|
2
|
+
* text=auto eol=lf
|
|
3
|
+
|
|
4
|
+
# Explicitly mark generated / binary files
|
|
5
|
+
*.png binary
|
|
6
|
+
*.jpg binary
|
|
7
|
+
*.jpeg binary
|
|
8
|
+
*.gif binary
|
|
9
|
+
*.ico binary
|
|
10
|
+
*.woff binary
|
|
11
|
+
*.woff2 binary
|
|
12
|
+
*.ttf binary
|
|
13
|
+
*.eot binary
|
|
14
|
+
|
|
15
|
+
# Lock files — treat as generated
|
|
16
|
+
pnpm-lock.yaml -diff linguist-generated
|
|
17
|
+
yarn.lock -diff linguist-generated
|
|
18
|
+
package-lock.json -diff linguist-generated
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
node_modules/
|
|
2
|
+
dist/
|
|
3
|
+
.env
|
|
4
|
+
# Machine-specific: each developer's test env differs (database names, ports).
|
|
5
|
+
# The shared template is the committed `.env.test.example`.
|
|
6
|
+
.env.test
|
|
7
|
+
*.local
|
|
8
|
+
coverage/
|
|
9
|
+
.DS_Store
|
|
10
|
+
*.tsbuildinfo
|
|
11
|
+
.kickjs/
|
|
12
|
+
# Platform build output — written by `kick build:netlify` / `kick build:vercel`.
|
|
13
|
+
.netlify/
|
|
14
|
+
.vercel/
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { defineConfig } from '@forinda/kickjs-cli'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
pattern: '{{template}}',
|
|
5
|
+
// The HTTP engine this app boots on (matches `bootstrap({ runtime })` in
|
|
6
|
+
// src/index.ts). Dep-aware commands read it: `kick add upload` installs the
|
|
7
|
+
// engine's multipart driver, `kick doctor` checks the engine peers, and
|
|
8
|
+
// `kick typegen` flips the runtime escape-hatch types to this engine.
|
|
9
|
+
runtime: '{{runtime}}',
|
|
10
|
+
// Pinned so `kick add` and other dep-installing commands always use the
|
|
11
|
+
// project's intended package manager, regardless of which lockfile exists.
|
|
12
|
+
packageManager: '{{packageManager}}',
|
|
13
|
+
modules: {
|
|
14
|
+
dir: 'src/modules',
|
|
15
|
+
// @kick:repo
|
|
16
|
+
pluralize: true,
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
// `kick typegen` populates `.kickjs/types/` so `Ctx<KickRoutes.X['method']>`
|
|
20
|
+
// resolves to fully-typed params/body/query. Auto-runs on `kick dev`.
|
|
21
|
+
// `'kickjs-schema'` routes inference through `InferSchemaOutput` so the
|
|
22
|
+
// typegen works for any wrapped schema (Zod / Valibot / Yup). Switch
|
|
23
|
+
// to `'zod'` if you ship Zod schemas without `fromZod()` wrapping, or
|
|
24
|
+
// set `schemaValidator: false` to skip schema-driven body typing.
|
|
25
|
+
typegen: {
|
|
26
|
+
schemaValidator: 'kickjs-schema',
|
|
27
|
+
// @kick:typegen-option
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
commands: [
|
|
31
|
+
{
|
|
32
|
+
name: 'test',
|
|
33
|
+
description: 'Run tests with Vitest',
|
|
34
|
+
steps: 'vitest run',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'lint',
|
|
38
|
+
description: 'Lint with oxlint',
|
|
39
|
+
steps: 'oxlint src/',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'format',
|
|
43
|
+
description: 'Format code with oxfmt',
|
|
44
|
+
steps: 'oxfmt src/',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'format:check',
|
|
48
|
+
description: 'Check formatting without writing',
|
|
49
|
+
steps: 'oxfmt --check src/',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'ci:check',
|
|
53
|
+
description: 'Run typecheck + lint + format check',
|
|
54
|
+
steps: ['kick typecheck', 'oxlint src/', 'oxfmt --check src/'],
|
|
55
|
+
aliases: ['verify'],
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
|
|
2
|
+
import { HelloService } from './hello.service'
|
|
3
|
+
|
|
4
|
+
// `Ctx<KickRoutes.HelloController['<method>']>` is generated by
|
|
5
|
+
// `kick typegen` (auto-run on `kick dev`). The first run after a fresh
|
|
6
|
+
// scaffold creates `.kickjs/types/routes.ts` so this file typechecks.
|
|
7
|
+
// See https://kickjs.app/guide/typegen.
|
|
8
|
+
|
|
9
|
+
@Controller()
|
|
10
|
+
export class HelloController {
|
|
11
|
+
@Autowired() private readonly helloService!: HelloService
|
|
12
|
+
|
|
13
|
+
// Return-value handlers: the runtime sends the returned payload as
|
|
14
|
+
// 200 json, and `kick typegen` infers the response type into
|
|
15
|
+
// `KickRoutes.Api` — which is what makes the typed client
|
|
16
|
+
// (@forinda/kickjs-client) end-to-end type-safe.
|
|
17
|
+
@Get('/')
|
|
18
|
+
index(_ctx: Ctx<KickRoutes.HelloController['index']>) {
|
|
19
|
+
return this.helloService.greet('World')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Get('/health')
|
|
23
|
+
health(_ctx: Ctx<KickRoutes.HelloController['health']>) {
|
|
24
|
+
return this.helloService.healthCheck()
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineModule } from '@forinda/kickjs'
|
|
2
|
+
import { HelloController } from './hello.controller'
|
|
3
|
+
|
|
4
|
+
export const HelloModule = defineModule({
|
|
5
|
+
name: 'HelloModule',
|
|
6
|
+
build: () => ({
|
|
7
|
+
// `register(container)` is optional — only implement it when you need
|
|
8
|
+
// to bind a token to a concrete implementation, e.g.
|
|
9
|
+
// register(container) {
|
|
10
|
+
// container.registerFactory(USER_REPOSITORY, () => container.resolve(InMemoryUserRepository))
|
|
11
|
+
// }
|
|
12
|
+
// The HelloService uses @Service() so the decorator handles registration.
|
|
13
|
+
|
|
14
|
+
routes() {
|
|
15
|
+
return {
|
|
16
|
+
path: '/hello',
|
|
17
|
+
controller: HelloController,
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Service } from '@forinda/kickjs'
|
|
2
|
+
|
|
3
|
+
@Service()
|
|
4
|
+
export class HelloService {
|
|
5
|
+
greet(name: string) {
|
|
6
|
+
return { message: `Hello ${name} from KickJS!`, timestamp: new Date().toISOString() }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
healthCheck() {
|
|
10
|
+
return { status: 'ok', uptime: process.uptime() }
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { defineModules } from '@forinda/kickjs'
|
|
2
|
+
import { HelloModule } from './hello/hello.module'
|
|
3
|
+
|
|
4
|
+
// Remove HelloModule and run: kick g module <name>
|
|
5
|
+
// `defineModules()` returns a chainable list — `kick g module` appends
|
|
6
|
+
// `.mount(NewModule())` to the chain on every generation.
|
|
7
|
+
export const modules = defineModules().mount(HelloModule())
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"types": ["node", "vite/client"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"sourceMap": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"experimentalDecorators": true,
|
|
14
|
+
"emitDecoratorMetadata": true,
|
|
15
|
+
"outDir": "dist",
|
|
16
|
+
"paths": {
|
|
17
|
+
"@/*": ["./src/*"]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"include": ["src", ".kickjs/types/**/*.d.ts", ".kickjs/types/**/*.ts"]
|
|
21
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import swc from 'unplugin-swc'
|
|
4
|
+
import { kickjsVitePlugin, envWatchPlugin } from '@forinda/kickjs-vite'
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
oxc: false,
|
|
8
|
+
plugins: [
|
|
9
|
+
swc.vite(),
|
|
10
|
+
kickjsVitePlugin({ entry: 'src/index.ts' }),
|
|
11
|
+
// Watches .env files and triggers a full reload on change so the
|
|
12
|
+
// dev server picks up env tweaks without a manual restart.
|
|
13
|
+
envWatchPlugin(),
|
|
14
|
+
],
|
|
15
|
+
// @kick:vite-option
|
|
16
|
+
resolve: {
|
|
17
|
+
alias: {
|
|
18
|
+
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
build: {
|
|
22
|
+
target: 'node20',
|
|
23
|
+
ssr: true,
|
|
24
|
+
outDir: 'dist',
|
|
25
|
+
sourcemap: true,
|
|
26
|
+
rollupOptions: {
|
|
27
|
+
input: fileURLToPath(new URL('./src/index.ts', import.meta.url)),
|
|
28
|
+
output: { format: 'esm' },
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
})
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig, mergeConfig } from 'vitest/config'
|
|
2
|
+
import viteConfig from './vite.config.ts'
|
|
3
|
+
|
|
4
|
+
// A `vitest.config.ts` OVERRIDES `vite.config.ts` outright — vitest does not
|
|
5
|
+
// merge the two, and it never reads tsconfig `paths`. Restating settings here
|
|
6
|
+
// would mean the `@` alias lives in three files and drifts in two of them, so
|
|
7
|
+
// merge the real config instead: the alias, plugins, and ssr externals all come
|
|
8
|
+
// from one place.
|
|
9
|
+
export default mergeConfig(
|
|
10
|
+
viteConfig,
|
|
11
|
+
defineConfig({
|
|
12
|
+
test: {
|
|
13
|
+
globals: true,
|
|
14
|
+
environment: 'node',
|
|
15
|
+
include: ['src/**/*.test.ts'],
|
|
16
|
+
},
|
|
17
|
+
}),
|
|
18
|
+
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": ["@forinda/kickjs-queue", "bullmq", "ioredis"],
|
|
3
|
+
"builds": {
|
|
4
|
+
"msgpackr-extract": false
|
|
5
|
+
},
|
|
6
|
+
"integrations": [
|
|
7
|
+
{
|
|
8
|
+
"import": {
|
|
9
|
+
"from": "@forinda/kickjs-queue",
|
|
10
|
+
"names": ["QueueAdapter"]
|
|
11
|
+
},
|
|
12
|
+
"slot": "adapter",
|
|
13
|
+
"code": "// BullMQ over Redis. Nothing connects until a @Job class or a queue\n// is used, so the app boots without Redis running.\nQueueAdapter({\n redis: {\n host: process.env.REDIS_HOST ?? '127.0.0.1',\n port: Number(process.env.REDIS_PORT ?? 6379),\n },\n})"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": ["@forinda/kickjs-swagger"],
|
|
3
|
+
"builds": {
|
|
4
|
+
"@scarf/scarf": true
|
|
5
|
+
},
|
|
6
|
+
"integrations": [
|
|
7
|
+
{
|
|
8
|
+
"import": {
|
|
9
|
+
"from": "@forinda/kickjs-swagger",
|
|
10
|
+
"names": ["SwaggerAdapter"]
|
|
11
|
+
},
|
|
12
|
+
"slot": "adapter",
|
|
13
|
+
"code": "SwaggerAdapter({ info: { title: '{{name}}', version: '{{version}}' } })"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": ["@forinda/kickjs-ws", "ws"],
|
|
3
|
+
"integrations": [
|
|
4
|
+
{
|
|
5
|
+
"import": {
|
|
6
|
+
"from": "@forinda/kickjs-ws",
|
|
7
|
+
"names": ["WsAdapter"]
|
|
8
|
+
},
|
|
9
|
+
"slot": "adapter",
|
|
10
|
+
"code": "// WebSocket upgrades on /ws \u2014 see guide/websockets.\nWsAdapter({ path: '/ws' })"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[build]
|
|
2
|
+
command = "{{packageManager}} run build:netlify"
|
|
3
|
+
publish = "web/dist"
|
|
4
|
+
|
|
5
|
+
[build.environment]
|
|
6
|
+
NODE_VERSION = "22"
|
|
7
|
+
|
|
8
|
+
# Client-side routes fall back to the app shell. The function claims /api/*
|
|
9
|
+
# through its own `config.path`, so this rule never sees those requests.
|
|
10
|
+
[[redirects]]
|
|
11
|
+
from = "/*"
|
|
12
|
+
to = "/index.html"
|
|
13
|
+
status = 200
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": ["express"],
|
|
3
|
+
"devDependencies": ["@types/express"],
|
|
4
|
+
"integrations": [
|
|
5
|
+
{
|
|
6
|
+
"import": {
|
|
7
|
+
"from": "@forinda/kickjs",
|
|
8
|
+
"names": ["expressRuntime"]
|
|
9
|
+
},
|
|
10
|
+
"slot": "runtime",
|
|
11
|
+
"code": "runtime: expressRuntime()"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"import": {
|
|
15
|
+
"from": "express",
|
|
16
|
+
"default": "express"
|
|
17
|
+
},
|
|
18
|
+
"slot": "middleware",
|
|
19
|
+
"code": "// Express needs a body parser; Fastify and h3 parse bodies natively.\nexpress.json()"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { loadEnvFromSchema } from '@forinda/kickjs/config'
|
|
2
|
+
import { fromValibot } from '@forinda/kickjs-schema/valibot'
|
|
3
|
+
import * as v from 'valibot'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Project environment schema (Valibot).
|
|
7
|
+
*
|
|
8
|
+
* `fromValibot` wraps the Valibot schema as a `KickSchema` so the
|
|
9
|
+
* env loader, validate middleware, and swagger spec generator all see
|
|
10
|
+
* the same shape. The default export is the contract `kick typegen`
|
|
11
|
+
* reads to populate `KickEnv` via `InferSchemaOutput<typeof _envSchema>`
|
|
12
|
+
* — that's what makes `@Value('FOO')` autocomplete and
|
|
13
|
+
* `process.env.FOO` typed.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* DATABASE_URL: v.pipe(v.string(), v.url()),
|
|
17
|
+
* JWT_SECRET: v.pipe(v.string(), v.minLength(32)),
|
|
18
|
+
* REDIS_URL: v.optional(v.pipe(v.string(), v.url())),
|
|
19
|
+
*/
|
|
20
|
+
const envSchema = fromValibot(
|
|
21
|
+
v.object({
|
|
22
|
+
PORT: v.optional(v.pipe(v.string(), v.transform(Number)), '3000'),
|
|
23
|
+
NODE_ENV: v.optional(v.picklist(['development', 'production', 'test']), 'development'),
|
|
24
|
+
LOG_LEVEL: v.optional(v.string(), 'info'),
|
|
25
|
+
// DATABASE_URL: v.pipe(v.string(), v.url()),
|
|
26
|
+
}),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* IMPORTANT — side effect: register the schema with kickjs's env cache
|
|
31
|
+
* **at module-load time**. `ConfigService` and `@Value()` both consume
|
|
32
|
+
* this cache, and they will fall back to the base schema (or undefined)
|
|
33
|
+
* if no extended schema has been registered before they're resolved.
|
|
34
|
+
*
|
|
35
|
+
* As long as `src/index.ts` imports this file (`import './config'`) at
|
|
36
|
+
* the top — before `bootstrap()` runs — every controller and service
|
|
37
|
+
* in the app sees the typed extended values.
|
|
38
|
+
*/
|
|
39
|
+
export const env = loadEnvFromSchema(envSchema)
|
|
40
|
+
|
|
41
|
+
export default envSchema
|