rpr-cli 0.1.1__py3-none-any.whl
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.
- rpr/__init__.py +1 -0
- rpr/agent/__init__.py +29 -0
- rpr/agent/approval.py +19 -0
- rpr/agent/bootstrap.py +60 -0
- rpr/agent/client.py +115 -0
- rpr/agent/control.py +16 -0
- rpr/agent/mock.py +158 -0
- rpr/agent/runtime.py +291 -0
- rpr/agent/session.py +91 -0
- rpr/agent/tools/__init__.py +10 -0
- rpr/agent/tools/base.py +62 -0
- rpr/agent/tools/mutating.py +47 -0
- rpr/agent/tools/readonly.py +147 -0
- rpr/agent/tools/registry.py +30 -0
- rpr/application/__init__.py +1 -0
- rpr/application/catalog.py +427 -0
- rpr/application/chat_service.py +413 -0
- rpr/application/checks.py +49 -0
- rpr/application/cli_adapter.py +36 -0
- rpr/application/completer.py +163 -0
- rpr/application/conversation_service.py +92 -0
- rpr/application/prompt_service.py +85 -0
- rpr/application/selector.py +240 -0
- rpr/application/shell.py +543 -0
- rpr/checks/__init__.py +0 -0
- rpr/checks/base.py +13 -0
- rpr/checks/instructions.py +89 -0
- rpr/checks/packages.py +619 -0
- rpr/checks/workspace.py +170 -0
- rpr/cli.py +78 -0
- rpr/commands/__init__.py +0 -0
- rpr/commands/add.py +166 -0
- rpr/commands/chat.py +48 -0
- rpr/commands/check.py +53 -0
- rpr/commands/generate/__init__.py +0 -0
- rpr/commands/generate/api.py +228 -0
- rpr/commands/generate/domain.py +383 -0
- rpr/commands/generate/engine.py +148 -0
- rpr/commands/generate/storybook.py +442 -0
- rpr/commands/generate/ui.py +414 -0
- rpr/commands/init.py +822 -0
- rpr/commands/map.py +113 -0
- rpr/commands/settings.py +102 -0
- rpr/commands/sync.py +97 -0
- rpr/context.py +203 -0
- rpr/generators/__init__.py +0 -0
- rpr/generators/base.py +110 -0
- rpr/generators/claude.py +33 -0
- rpr/generators/copilot.py +36 -0
- rpr/generators/cursor.py +38 -0
- rpr/generators/gemini.py +33 -0
- rpr/map/__init__.py +0 -0
- rpr/map/architecture.py +495 -0
- rpr/map/chains.py +317 -0
- rpr/map/classifier.py +170 -0
- rpr/map/coverage.py +200 -0
- rpr/map/dependencies.py +243 -0
- rpr/map/extractor.py +223 -0
- rpr/map/graph.py +318 -0
- rpr/map/output.py +1030 -0
- rpr/map/responsibility.py +345 -0
- rpr/map/topology.py +327 -0
- rpr/map/walker.py +151 -0
- rpr/scaffolds/domain/base_entity.md +30 -0
- rpr/scaffolds/domain/base_repo.md +48 -0
- rpr/scaffolds/domain/container.md +76 -0
- rpr/scaffolds/domain/settings.md +57 -0
- rpr/scaffolds/instructions/all.instructions.md +50 -0
- rpr/scaffolds/instructions/api.instructions.md +42 -0
- rpr/scaffolds/instructions/domain.instructions.md +93 -0
- rpr/scaffolds/instructions/frontend.instructions.md +97 -0
- rpr/scaffolds/instructions/rust-engine.instructions.md +40 -0
- rpr/scaffolds/instructions/setup-guide.instructions.md +86 -0
- rpr/scaffolds/instructions/tooling-setup.instructions.md +97 -0
- rpr/scaffolds/instructions/tooling.instructions.md +42 -0
- rpr/scaffolds/js_special_files/fetch.service.md +222 -0
- rpr/scaffolds/js_special_files/sticky-navigation.md +164 -0
- rpr/scaffolds/special_files/domain_container.md +76 -0
- rpr/scaffolds/special_files/domain_settings.md +57 -0
- rpr/scaffolds/special_files/dto_util.md +62 -0
- rpr/scaffolds/special_files/encrypted_column.md +98 -0
- rpr/scaffolds/special_files/mapper_util.md +159 -0
- rpr/scaffolds/special_files/partial_update.md +61 -0
- rpr/templates/__init__.py +0 -0
- rpr/templates/registry.py +81 -0
- rpr/ui/__init__.py +0 -0
- rpr/ui/console.py +32 -0
- rpr/ui/markdown.py +59 -0
- rpr/ui/prompt_session.py +430 -0
- rpr/ui/renderers.py +167 -0
- rpr/ui/theme.py +286 -0
- rpr/workspace.py +131 -0
- rpr_cli-0.1.1.dist-info/METADATA +201 -0
- rpr_cli-0.1.1.dist-info/RECORD +97 -0
- rpr_cli-0.1.1.dist-info/WHEEL +4 -0
- rpr_cli-0.1.1.dist-info/entry_points.txt +2 -0
- rpr_cli-0.1.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
from rpr.cli import generate_app
|
|
11
|
+
from rpr.context import RunContext
|
|
12
|
+
from rpr.workspace import ensure_npm_workspaces, write_package_json
|
|
13
|
+
|
|
14
|
+
console = Console()
|
|
15
|
+
|
|
16
|
+
_UI_LIBRARY_DEPENDENCIES = {
|
|
17
|
+
"@mui/material": "^6",
|
|
18
|
+
"@emotion/react": "^11",
|
|
19
|
+
"@emotion/styled": "^11",
|
|
20
|
+
"@tanstack/react-query": "^5",
|
|
21
|
+
"@tanstack/react-router": "^1",
|
|
22
|
+
"react": "^19",
|
|
23
|
+
"react-dom": "^19",
|
|
24
|
+
}
|
|
25
|
+
_UI_LIBRARY_DEV_DEPENDENCIES = {
|
|
26
|
+
"@types/react": "^19",
|
|
27
|
+
"@types/react-dom": "^19",
|
|
28
|
+
"typescript": "^5",
|
|
29
|
+
"vite": "^6",
|
|
30
|
+
"vitest": "^3",
|
|
31
|
+
}
|
|
32
|
+
_WEB_APP_DEV_DEPENDENCIES = {
|
|
33
|
+
"@types/react": "^19",
|
|
34
|
+
"@types/react-dom": "^19",
|
|
35
|
+
"@vitejs/plugin-react": "^4",
|
|
36
|
+
"typescript": "^5",
|
|
37
|
+
"vite": "^6",
|
|
38
|
+
"vitest": "^3",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _web_app_dependencies(ui_pkg_name: str) -> dict[str, str]:
|
|
43
|
+
return {
|
|
44
|
+
f"@repo/{ui_pkg_name}": "workspace:*",
|
|
45
|
+
"react": "^19",
|
|
46
|
+
"react-dom": "^19",
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@generate_app.command()
|
|
51
|
+
def ui(
|
|
52
|
+
name: Annotated[
|
|
53
|
+
str | None, typer.Argument(help="App name (used as package prefix).")
|
|
54
|
+
] = None,
|
|
55
|
+
dry_run: Annotated[
|
|
56
|
+
bool, typer.Option("--dry-run", help="Preview changes without writing.")
|
|
57
|
+
] = False,
|
|
58
|
+
include_library: Annotated[
|
|
59
|
+
bool,
|
|
60
|
+
typer.Option(
|
|
61
|
+
"--library/--no-library",
|
|
62
|
+
help="Generate the reusable UI library.",
|
|
63
|
+
),
|
|
64
|
+
] = True,
|
|
65
|
+
include_web: Annotated[
|
|
66
|
+
bool,
|
|
67
|
+
typer.Option(
|
|
68
|
+
"--web/--no-web",
|
|
69
|
+
help="Generate the thin web app shell.",
|
|
70
|
+
),
|
|
71
|
+
] = True,
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Scaffold a React UI library and slim frontend app."""
|
|
74
|
+
if not name:
|
|
75
|
+
name = typer.prompt("App name")
|
|
76
|
+
if not include_library and not include_web:
|
|
77
|
+
raise typer.BadParameter("At least one of --library or --web must be enabled.")
|
|
78
|
+
|
|
79
|
+
ctx = RunContext(dry_run=dry_run, project_dir=Path.cwd())
|
|
80
|
+
ui_pkg_name = f"{name}-ui"
|
|
81
|
+
app_name = f"{name}-web"
|
|
82
|
+
|
|
83
|
+
generated_parts = []
|
|
84
|
+
if include_library:
|
|
85
|
+
generated_parts.append(ui_pkg_name)
|
|
86
|
+
if include_web:
|
|
87
|
+
generated_parts.append(app_name)
|
|
88
|
+
|
|
89
|
+
console.print(
|
|
90
|
+
f"\n[bold]Generating frontend projects:[/] {' + '.join(generated_parts)}\n"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
ensure_npm_workspaces(ctx, package_name=ctx.project_dir.name)
|
|
94
|
+
if include_library:
|
|
95
|
+
_scaffold_ui_library(ctx, ui_pkg_name)
|
|
96
|
+
if include_web:
|
|
97
|
+
_scaffold_frontend_app(ctx, app_name, ui_pkg_name)
|
|
98
|
+
|
|
99
|
+
if include_library:
|
|
100
|
+
ctx.preview_dependencies(
|
|
101
|
+
manager="npm",
|
|
102
|
+
target=f"packages/node/{ui_pkg_name}",
|
|
103
|
+
runtime=list(_UI_LIBRARY_DEPENDENCIES),
|
|
104
|
+
dev=list(_UI_LIBRARY_DEV_DEPENDENCIES),
|
|
105
|
+
)
|
|
106
|
+
if include_web:
|
|
107
|
+
ctx.preview_dependencies(
|
|
108
|
+
manager="npm",
|
|
109
|
+
target=f"apps/{app_name}",
|
|
110
|
+
runtime=list(_web_app_dependencies(ui_pkg_name)),
|
|
111
|
+
dev=list(_WEB_APP_DEV_DEPENDENCIES),
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
if not dry_run:
|
|
115
|
+
ctx.run_command(["npm", "install"], cwd=ctx.project_dir)
|
|
116
|
+
|
|
117
|
+
console.print("\n[bold green]Done![/] Frontend scaffolding created.")
|
|
118
|
+
if include_web:
|
|
119
|
+
console.print(f" Run with: npx nx serve {app_name}")
|
|
120
|
+
if include_library:
|
|
121
|
+
console.print(" Optional templates: rpr add template fetch_service")
|
|
122
|
+
console.print(" rpr add template sticky_navigation")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _scaffold_ui_library(ctx: RunContext, ui_pkg_name: str) -> None:
|
|
126
|
+
lib_root = ctx.project_dir / "packages" / "node" / ui_pkg_name
|
|
127
|
+
src = lib_root / "src"
|
|
128
|
+
|
|
129
|
+
for d in ["hooks", "components", "services/base", "state"]:
|
|
130
|
+
ctx.ensure_dir(src / d)
|
|
131
|
+
|
|
132
|
+
_write_ui_package_json(ctx, lib_root, ui_pkg_name)
|
|
133
|
+
_write_ui_project_json(ctx, lib_root, ui_pkg_name)
|
|
134
|
+
_write_ui_tsconfig(ctx, lib_root)
|
|
135
|
+
_write_ui_eslint_config(ctx, lib_root)
|
|
136
|
+
ctx.write_file(src / "index.ts", f'export const uiPackageName = "{ui_pkg_name}";\n')
|
|
137
|
+
_write_ui_test(ctx, src / "index.test.ts", ui_pkg_name)
|
|
138
|
+
ctx.write_file(src / "hooks" / ".gitkeep", "")
|
|
139
|
+
ctx.write_file(src / "components" / ".gitkeep", "")
|
|
140
|
+
ctx.write_file(src / "state" / ".gitkeep", "")
|
|
141
|
+
ctx.write_file(src / "services" / "base" / ".gitkeep", "")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _scaffold_frontend_app(ctx: RunContext, app_name: str, ui_pkg_name: str) -> None:
|
|
145
|
+
app_root = ctx.project_dir / "apps" / app_name
|
|
146
|
+
src = app_root / "src"
|
|
147
|
+
|
|
148
|
+
ctx.ensure_dir(src)
|
|
149
|
+
|
|
150
|
+
_write_app_package_json(ctx, app_root, app_name, ui_pkg_name)
|
|
151
|
+
_write_app_project_json(ctx, app_root, app_name)
|
|
152
|
+
_write_app_tsconfig(ctx, app_root)
|
|
153
|
+
_write_app_eslint_config(ctx, app_root)
|
|
154
|
+
_write_app_index_html(ctx, app_root, app_name)
|
|
155
|
+
_write_app_main_tsx(ctx, src)
|
|
156
|
+
_write_app_tsx(ctx, src, app_name, ui_pkg_name)
|
|
157
|
+
_write_app_test(ctx, src / "App.test.ts", app_name)
|
|
158
|
+
_write_vite_config(ctx, app_root, app_name)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _write_ui_package_json(ctx: RunContext, lib_root: Path, ui_pkg_name: str) -> None:
|
|
162
|
+
write_package_json(
|
|
163
|
+
ctx,
|
|
164
|
+
lib_root / "package.json",
|
|
165
|
+
defaults={
|
|
166
|
+
"name": f"@repo/{ui_pkg_name}",
|
|
167
|
+
"version": "0.1.0",
|
|
168
|
+
"private": True,
|
|
169
|
+
"main": "src/index.ts",
|
|
170
|
+
"types": "src/index.ts",
|
|
171
|
+
},
|
|
172
|
+
dependencies=_UI_LIBRARY_DEPENDENCIES,
|
|
173
|
+
dev_dependencies=_UI_LIBRARY_DEV_DEPENDENCIES,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _write_ui_project_json(ctx: RunContext, lib_root: Path, ui_pkg_name: str) -> None:
|
|
178
|
+
project = {
|
|
179
|
+
"name": ui_pkg_name,
|
|
180
|
+
"root": f"packages/node/{ui_pkg_name}",
|
|
181
|
+
"targets": {
|
|
182
|
+
"build": {
|
|
183
|
+
"executor": "nx:run-commands",
|
|
184
|
+
"options": {
|
|
185
|
+
"command": "npx tsc -p tsconfig.json",
|
|
186
|
+
"cwd": f"packages/node/{ui_pkg_name}",
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
"lint": {
|
|
190
|
+
"executor": "nx:run-commands",
|
|
191
|
+
"options": {
|
|
192
|
+
"command": "npx eslint .",
|
|
193
|
+
"cwd": f"packages/node/{ui_pkg_name}",
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
"test": {
|
|
197
|
+
"executor": "nx:run-commands",
|
|
198
|
+
"options": {
|
|
199
|
+
"command": "npx vitest run",
|
|
200
|
+
"cwd": f"packages/node/{ui_pkg_name}",
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
"typecheck": {
|
|
204
|
+
"executor": "nx:run-commands",
|
|
205
|
+
"options": {
|
|
206
|
+
"command": "npx tsc --noEmit",
|
|
207
|
+
"cwd": f"packages/node/{ui_pkg_name}",
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
ctx.write_file(lib_root / "project.json", json.dumps(project, indent=2) + "\n")
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _write_ui_tsconfig(ctx: RunContext, lib_root: Path) -> None:
|
|
216
|
+
content = """{
|
|
217
|
+
"extends": "../../../tsconfig.base.json",
|
|
218
|
+
"compilerOptions": {
|
|
219
|
+
"jsx": "react-jsx",
|
|
220
|
+
"outDir": "dist",
|
|
221
|
+
"rootDir": "src"
|
|
222
|
+
},
|
|
223
|
+
"include": ["src"]
|
|
224
|
+
}
|
|
225
|
+
"""
|
|
226
|
+
ctx.write_file(lib_root / "tsconfig.json", content)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def _write_ui_eslint_config(ctx: RunContext, lib_root: Path) -> None:
|
|
230
|
+
content = """import baseConfig from \"../../../eslint.config.mjs\";
|
|
231
|
+
|
|
232
|
+
export default [...baseConfig];
|
|
233
|
+
"""
|
|
234
|
+
ctx.write_file(lib_root / "eslint.config.mjs", content)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _write_app_package_json(
|
|
238
|
+
ctx: RunContext, app_root: Path, app_name: str, ui_pkg_name: str
|
|
239
|
+
) -> None:
|
|
240
|
+
write_package_json(
|
|
241
|
+
ctx,
|
|
242
|
+
app_root / "package.json",
|
|
243
|
+
defaults={
|
|
244
|
+
"name": f"@repo/{app_name}",
|
|
245
|
+
"version": "0.1.0",
|
|
246
|
+
"private": True,
|
|
247
|
+
"type": "module",
|
|
248
|
+
},
|
|
249
|
+
dependencies=_web_app_dependencies(ui_pkg_name),
|
|
250
|
+
dev_dependencies=_WEB_APP_DEV_DEPENDENCIES,
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _write_app_project_json(ctx: RunContext, app_root: Path, app_name: str) -> None:
|
|
255
|
+
project = {
|
|
256
|
+
"name": app_name,
|
|
257
|
+
"root": f"apps/{app_name}",
|
|
258
|
+
"targets": {
|
|
259
|
+
"serve": {
|
|
260
|
+
"executor": "nx:run-commands",
|
|
261
|
+
"options": {
|
|
262
|
+
"command": "npx vite",
|
|
263
|
+
"cwd": f"apps/{app_name}",
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
"build": {
|
|
267
|
+
"executor": "nx:run-commands",
|
|
268
|
+
"options": {
|
|
269
|
+
"command": "npx vite build",
|
|
270
|
+
"cwd": f"apps/{app_name}",
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
"lint": {
|
|
274
|
+
"executor": "nx:run-commands",
|
|
275
|
+
"options": {
|
|
276
|
+
"command": "npx eslint .",
|
|
277
|
+
"cwd": f"apps/{app_name}",
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
"test": {
|
|
281
|
+
"executor": "nx:run-commands",
|
|
282
|
+
"options": {
|
|
283
|
+
"command": "npx vitest run",
|
|
284
|
+
"cwd": f"apps/{app_name}",
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
"typecheck": {
|
|
288
|
+
"executor": "nx:run-commands",
|
|
289
|
+
"options": {
|
|
290
|
+
"command": "npx tsc --noEmit",
|
|
291
|
+
"cwd": f"apps/{app_name}",
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
}
|
|
296
|
+
ctx.write_file(app_root / "project.json", json.dumps(project, indent=2) + "\n")
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def _write_app_tsconfig(ctx: RunContext, app_root: Path) -> None:
|
|
300
|
+
content = """{
|
|
301
|
+
"extends": "../../tsconfig.base.json",
|
|
302
|
+
"compilerOptions": {
|
|
303
|
+
"jsx": "react-jsx",
|
|
304
|
+
"outDir": "dist",
|
|
305
|
+
"rootDir": "src"
|
|
306
|
+
},
|
|
307
|
+
"include": ["src"]
|
|
308
|
+
}
|
|
309
|
+
"""
|
|
310
|
+
ctx.write_file(app_root / "tsconfig.json", content)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def _write_app_eslint_config(ctx: RunContext, app_root: Path) -> None:
|
|
314
|
+
content = """import baseConfig from \"../../eslint.config.mjs\";
|
|
315
|
+
|
|
316
|
+
export default [...baseConfig];
|
|
317
|
+
"""
|
|
318
|
+
ctx.write_file(app_root / "eslint.config.mjs", content)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def _write_app_index_html(ctx: RunContext, app_root: Path, app_name: str) -> None:
|
|
322
|
+
title = app_name.replace("-", " ").title()
|
|
323
|
+
content = f"""<!DOCTYPE html>
|
|
324
|
+
<html lang="en">
|
|
325
|
+
<head>
|
|
326
|
+
<meta charset="UTF-8" />
|
|
327
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
328
|
+
<title>{title}</title>
|
|
329
|
+
</head>
|
|
330
|
+
<body>
|
|
331
|
+
<div id="root"></div>
|
|
332
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
333
|
+
</body>
|
|
334
|
+
</html>
|
|
335
|
+
"""
|
|
336
|
+
ctx.write_file(app_root / "index.html", content)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def _write_app_main_tsx(ctx: RunContext, src: Path) -> None:
|
|
340
|
+
content = """import React from "react";
|
|
341
|
+
import ReactDOM from "react-dom/client";
|
|
342
|
+
import { App } from "./App";
|
|
343
|
+
|
|
344
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
345
|
+
<React.StrictMode>
|
|
346
|
+
<App />
|
|
347
|
+
</React.StrictMode>,
|
|
348
|
+
);
|
|
349
|
+
"""
|
|
350
|
+
ctx.write_file(src / "main.tsx", content)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def _write_app_tsx(ctx: RunContext, src: Path, app_name: str, ui_pkg_name: str) -> None:
|
|
354
|
+
title = app_name.replace("-", " ").title()
|
|
355
|
+
content = f"""import {{ uiPackageName }} from "@repo/{ui_pkg_name}";
|
|
356
|
+
|
|
357
|
+
export const appTitle = "{title}";
|
|
358
|
+
|
|
359
|
+
export const App = () => {{
|
|
360
|
+
return (
|
|
361
|
+
<div>
|
|
362
|
+
<h1>{{appTitle}}</h1>
|
|
363
|
+
<p>Shared UI package: {{uiPackageName}}</p>
|
|
364
|
+
</div>
|
|
365
|
+
);
|
|
366
|
+
}};
|
|
367
|
+
"""
|
|
368
|
+
ctx.write_file(src / "App.tsx", content)
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def _write_vite_config(ctx: RunContext, app_root: Path, app_name: str) -> None:
|
|
372
|
+
content = """import { defineConfig } from "vite";
|
|
373
|
+
import react from "@vitejs/plugin-react";
|
|
374
|
+
|
|
375
|
+
export default defineConfig({
|
|
376
|
+
plugins: [react()],
|
|
377
|
+
server: {
|
|
378
|
+
port: 3000,
|
|
379
|
+
open: true,
|
|
380
|
+
},
|
|
381
|
+
});
|
|
382
|
+
"""
|
|
383
|
+
ctx.write_file(app_root / "vite.config.ts", content)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def _write_ui_test(ctx: RunContext, path: Path, ui_pkg_name: str) -> None:
|
|
387
|
+
content = f"""import {{ describe, expect, it }} from "vitest";
|
|
388
|
+
|
|
389
|
+
import {{ uiPackageName }} from "./index";
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
describe("ui package", () => {{
|
|
393
|
+
it("exports the package name", () => {{
|
|
394
|
+
expect(uiPackageName).toBe("{ui_pkg_name}");
|
|
395
|
+
}});
|
|
396
|
+
}});
|
|
397
|
+
"""
|
|
398
|
+
ctx.write_file(path, content)
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
def _write_app_test(ctx: RunContext, path: Path, app_name: str) -> None:
|
|
402
|
+
title = app_name.replace("-", " ").title()
|
|
403
|
+
content = f"""import {{ describe, expect, it }} from "vitest";
|
|
404
|
+
|
|
405
|
+
import {{ appTitle }} from "./App";
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
describe("web app", () => {{
|
|
409
|
+
it("exports the app title", () => {{
|
|
410
|
+
expect(appTitle).toBe("{title}");
|
|
411
|
+
}});
|
|
412
|
+
}});
|
|
413
|
+
"""
|
|
414
|
+
ctx.write_file(path, content)
|