jac-client 0.2.8__py3-none-any.whl → 0.2.9__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.
- jac_client/examples/all-in-one/{app.jac → main.jac} +5 -5
- jac_client/examples/all-in-one/pages/BudgetPlanner.jac +8 -1
- jac_client/examples/all-in-one/pages/FeaturesTest.jac +16 -1
- jac_client/examples/all-in-one/pages/{FeaturesTest.cl.jac → features_test_ui.cl.jac} +11 -0
- jac_client/examples/all-in-one/pages/nestedDemo.jac +1 -1
- jac_client/examples/all-in-one/pages/notFound.jac +2 -7
- jac_client/plugin/cli.jac +162 -435
- jac_client/plugin/client.jac +25 -0
- jac_client/plugin/client_runtime.cl.jac +5 -1
- jac_client/plugin/impl/client.impl.jac +96 -55
- jac_client/plugin/impl/client_runtime.impl.jac +154 -0
- jac_client/plugin/plugin_config.jac +243 -15
- jac_client/plugin/src/config_loader.jac +1 -0
- jac_client/plugin/src/impl/compiler.impl.jac +1 -1
- jac_client/plugin/src/impl/config_loader.impl.jac +8 -0
- jac_client/plugin/src/impl/vite_bundler.impl.jac +97 -16
- jac_client/plugin/src/vite_bundler.jac +6 -0
- jac_client/plugin/utils/__init__.jac +1 -0
- jac_client/plugin/utils/impl/node_installer.impl.jac +249 -0
- jac_client/plugin/utils/node_installer.jac +41 -0
- jac_client/templates/client.jacpack +72 -0
- jac_client/templates/fullstack.jacpack +61 -0
- jac_client/tests/conftest.py +48 -7
- jac_client/tests/test_cli.py +184 -70
- jac_client/tests/test_e2e.py +232 -0
- jac_client/tests/test_helpers.py +65 -0
- jac_client/tests/test_it.py +91 -135
- {jac_client-0.2.8.dist-info → jac_client-0.2.9.dist-info}/METADATA +4 -4
- {jac_client-0.2.8.dist-info → jac_client-0.2.9.dist-info}/RECORD +52 -45
- {jac_client-0.2.8.dist-info → jac_client-0.2.9.dist-info}/WHEEL +1 -1
- /jac_client/examples/all-in-one/pages/{BudgetPlanner.cl.jac → budget_planner_ui.cl.jac} +0 -0
- /jac_client/examples/asset-serving/css-with-image/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/asset-serving/image-asset/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/asset-serving/import-alias/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/basic/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/basic-auth/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/basic-auth-with-router/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/basic-full-stack/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/css-styling/js-styling/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/css-styling/material-ui/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/css-styling/pure-css/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/css-styling/sass-example/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/css-styling/styled-components/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/css-styling/tailwind-example/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/full-stack-with-auth/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/little-x/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/nested-folders/nested-advance/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/nested-folders/nested-basic/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/ts-support/{src/app.jac → main.jac} +0 -0
- /jac_client/examples/with-router/{src/app.jac → main.jac} +0 -0
- {jac_client-0.2.8.dist-info → jac_client-0.2.9.dist-info}/entry_points.txt +0 -0
- {jac_client-0.2.8.dist-info → jac_client-0.2.9.dist-info}/top_level.txt +0 -0
jac_client/plugin/cli.jac
CHANGED
|
@@ -1,504 +1,231 @@
|
|
|
1
1
|
"""Command line interface tool for the Jac Client.
|
|
2
2
|
|
|
3
|
-
This module extends
|
|
4
|
-
|
|
3
|
+
This module extends core CLI commands to add the --npm flag for
|
|
4
|
+
client-side (frontend) package management:
|
|
5
|
+
- `jac add --npm`: Add npm dependencies
|
|
6
|
+
- `jac remove --npm`: Remove npm dependencies
|
|
7
|
+
|
|
8
|
+
For creating client projects, use: `jac create --use client`
|
|
5
9
|
"""
|
|
6
10
|
|
|
7
|
-
import os;
|
|
8
|
-
import re;
|
|
9
|
-
import sys;
|
|
10
|
-
import pathlib;
|
|
11
|
-
import subprocess;
|
|
12
|
-
import shutil;
|
|
13
11
|
import from jaclang.cli.registry { get_registry }
|
|
14
|
-
import from jaclang.cli.command { Arg,
|
|
12
|
+
import from jaclang.cli.command { Arg, HookContext }
|
|
15
13
|
import from jaclang.pycore.runtime { hookimpl }
|
|
16
|
-
import
|
|
14
|
+
import os;
|
|
17
15
|
|
|
18
16
|
"""Jac CLI extensions for client-side development."""
|
|
19
17
|
class JacCmd {
|
|
20
18
|
"""Create Jac CLI cmds."""
|
|
21
19
|
@hookimpl
|
|
22
20
|
static def create_cmd -> None {
|
|
23
|
-
"""Extend core
|
|
21
|
+
"""Extend core commands to add --npm flag for npm package management.""";
|
|
24
22
|
registry = get_registry();
|
|
25
23
|
|
|
26
|
-
# Extend the core 'create' command with client
|
|
24
|
+
# Extend the core 'create' command with --skip flag for client template
|
|
27
25
|
registry.extend_command(
|
|
28
26
|
command_name="create",
|
|
29
27
|
args=[
|
|
30
28
|
Arg.create(
|
|
31
|
-
"
|
|
29
|
+
"skip",
|
|
32
30
|
typ=bool,
|
|
33
31
|
default=False,
|
|
34
|
-
help="
|
|
35
|
-
short="c"
|
|
32
|
+
help="Skip npm package installation (for --use client)"
|
|
36
33
|
),
|
|
34
|
+
|
|
35
|
+
],
|
|
36
|
+
pre_hook=_handle_create_skip,
|
|
37
|
+
source="jac-client"
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
# Extend the core 'add' command with --npm flag
|
|
41
|
+
registry.extend_command(
|
|
42
|
+
command_name="add",
|
|
43
|
+
args=[
|
|
37
44
|
Arg.create(
|
|
38
|
-
"
|
|
45
|
+
"npm",
|
|
39
46
|
typ=bool,
|
|
40
47
|
default=False,
|
|
41
|
-
help="
|
|
42
|
-
short="s"
|
|
48
|
+
help="Add as npm (client-side) dependency"
|
|
43
49
|
),
|
|
50
|
+
|
|
51
|
+
],
|
|
52
|
+
pre_hook=_handle_npm_add,
|
|
53
|
+
source="jac-client"
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
# Extend the core 'remove' command with --npm flag
|
|
57
|
+
registry.extend_command(
|
|
58
|
+
command_name="remove",
|
|
59
|
+
args=[
|
|
44
60
|
Arg.create(
|
|
45
|
-
"
|
|
61
|
+
"npm",
|
|
46
62
|
typ=bool,
|
|
47
63
|
default=False,
|
|
48
|
-
help="
|
|
49
|
-
short="v"
|
|
64
|
+
help="Remove npm (client-side) dependency"
|
|
50
65
|
),
|
|
51
66
|
|
|
52
67
|
],
|
|
53
|
-
pre_hook=
|
|
68
|
+
pre_hook=_handle_npm_remove,
|
|
54
69
|
source="jac-client"
|
|
55
70
|
);
|
|
56
71
|
}
|
|
57
72
|
}
|
|
58
73
|
|
|
59
|
-
"""Pre-hook to handle --
|
|
60
|
-
def
|
|
61
|
-
# Check if --
|
|
62
|
-
|
|
63
|
-
if
|
|
64
|
-
#
|
|
65
|
-
|
|
74
|
+
"""Pre-hook to handle --skip flag for create command."""
|
|
75
|
+
def _handle_create_skip(ctx: HookContext) -> None {
|
|
76
|
+
# Check if --skip flag is set
|
|
77
|
+
skip_flag = ctx.get_arg("skip", False);
|
|
78
|
+
if skip_flag {
|
|
79
|
+
# Set environment variable to skip npm installation
|
|
80
|
+
os.environ["JAC_CLIENT_SKIP_NPM_INSTALL"] = "1";
|
|
66
81
|
}
|
|
82
|
+
# Let core create command run normally
|
|
83
|
+
}
|
|
67
84
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
_create_client_project(cwd, name, force, skip_install, verbose);
|
|
77
|
-
# Cancel core handler with success code
|
|
78
|
-
ctx.set_data("cancel_execution", True);
|
|
79
|
-
ctx.set_data("cancel_return_code", 0);
|
|
80
|
-
} except SystemExit as e {
|
|
81
|
-
# Preserve exit code from sys.exit() calls
|
|
82
|
-
ctx.set_data("cancel_execution", True);
|
|
83
|
-
ctx.set_data("cancel_return_code", e.code if e.code is not None else 1);
|
|
84
|
-
} except Exception as e {
|
|
85
|
-
print(f"Error creating client project: {e}", file=sys.stderr);
|
|
86
|
-
ctx.set_data("cancel_execution", True);
|
|
87
|
-
ctx.set_data("cancel_return_code", 1);
|
|
85
|
+
"""Pre-hook to handle --npm flag for adding npm dependencies."""
|
|
86
|
+
def _handle_npm_add(ctx: HookContext) -> None {
|
|
87
|
+
# Check if --npm flag is set
|
|
88
|
+
npm_flag = ctx.get_arg("npm", False);
|
|
89
|
+
if not npm_flag {
|
|
90
|
+
# Let core add command run normally
|
|
91
|
+
return;
|
|
88
92
|
}
|
|
89
|
-
}
|
|
90
93
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
force: bool,
|
|
96
|
-
skip: bool = False,
|
|
97
|
-
verbose: bool = False
|
|
98
|
-
) -> None {
|
|
99
|
-
project_name = name or cwd.name;
|
|
94
|
+
import from jaclang.project.config { get_config }
|
|
95
|
+
import from jaclang.project.dep_registry { get_dependency_registry }
|
|
96
|
+
import from jaclang.project.dependencies { DependencyResolver }
|
|
97
|
+
import from jaclang.cli.console { console }
|
|
100
98
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
config = get_config();
|
|
100
|
+
if config is None {
|
|
101
|
+
console.error(
|
|
102
|
+
"No jac.toml found", hint="Run 'jac create' to create a project."
|
|
105
103
|
);
|
|
106
|
-
|
|
104
|
+
ctx.set_data("cancel_execution", True);
|
|
105
|
+
ctx.set_data("cancel_return_code", 1);
|
|
106
|
+
return;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
registry = get_dependency_registry();
|
|
110
|
+
dep_type = registry.get_by_flag("--npm");
|
|
111
|
+
if dep_type is None {
|
|
112
|
+
console.error(
|
|
113
|
+
"--npm flag requires jac-client plugin",
|
|
114
|
+
hint="Install with: pip install jac-client"
|
|
113
115
|
);
|
|
114
|
-
|
|
116
|
+
ctx.set_data("cancel_execution", True);
|
|
117
|
+
ctx.set_data("cancel_return_code", 1);
|
|
118
|
+
return;
|
|
115
119
|
}
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
(project_root, toml_path) = existing;
|
|
120
|
-
print(f"Already in a Jac project: {toml_path}", file=sys.stderr);
|
|
121
|
-
print("Use --force to reinitialize.", file=sys.stderr);
|
|
122
|
-
<>exit(1);
|
|
123
|
-
}
|
|
121
|
+
packages = ctx.get_arg("packages", []);
|
|
122
|
+
dev = ctx.get_arg("dev", False);
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
if
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
# If no packages specified, install all npm packages from jac.toml
|
|
125
|
+
if not packages {
|
|
126
|
+
if dep_type.install_all_handler is None {
|
|
127
|
+
console.error(f"No install_all handler registered for {dep_type.name}");
|
|
128
|
+
ctx.set_data("cancel_execution", True);
|
|
129
|
+
ctx.set_data("cancel_return_code", 1);
|
|
130
|
+
return;
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
description = "Jac client application: {project_name}"
|
|
152
|
-
entry-point = "main.jac"
|
|
153
|
-
|
|
154
|
-
[dependencies]
|
|
155
|
-
|
|
156
|
-
[dependencies.npm]
|
|
157
|
-
"jac-client-node" = "1.0.3"
|
|
158
|
-
|
|
159
|
-
[dependencies.npm.dev]
|
|
160
|
-
"@jac-client/dev-deps" = "1.0.0"
|
|
161
|
-
|
|
162
|
-
[dev-dependencies]
|
|
163
|
-
watchdog = ">=3.0.0"
|
|
164
|
-
|
|
165
|
-
[serve]
|
|
166
|
-
base_route_app = "app"
|
|
167
|
-
|
|
168
|
-
[plugins.client]
|
|
169
|
-
# Vite bundler configuration (optional overrides)
|
|
170
|
-
# vite.plugins = []
|
|
171
|
-
# vite.build = {{}}
|
|
172
|
-
''';
|
|
173
|
-
with open(toml_path, 'w') as f {
|
|
174
|
-
f.write(toml_content);
|
|
175
|
-
}
|
|
176
|
-
print(f"Created {toml_path}");
|
|
177
|
-
|
|
178
|
-
main_jac_content = '''"""Main entry point for the Jac client application."""
|
|
179
|
-
|
|
180
|
-
# Client-side imports (useState is auto-injected when using `has` variables)
|
|
181
|
-
cl import from react { useEffect }
|
|
182
|
-
cl import from .components.Button { Button }
|
|
183
|
-
|
|
184
|
-
# Client-side component
|
|
185
|
-
cl {
|
|
186
|
-
def:pub app() -> any {
|
|
187
|
-
has count: int = 0;
|
|
188
|
-
|
|
189
|
-
useEffect(lambda -> None {
|
|
190
|
-
console.log("Count updated:", count);
|
|
191
|
-
}, [count]);
|
|
192
|
-
|
|
193
|
-
return <div style={{padding: "2rem", fontFamily: "Arial, sans-serif"}}>
|
|
194
|
-
<h1>Hello, World!</h1>
|
|
195
|
-
<p>Count: {count}</p>
|
|
196
|
-
<div style={{display: "flex", gap: "1rem", marginTop: "1rem"}}>
|
|
197
|
-
<Button
|
|
198
|
-
label="Increment"
|
|
199
|
-
onClick={lambda -> None { count = count + 1; }}
|
|
200
|
-
variant="primary"
|
|
201
|
-
/>
|
|
202
|
-
<Button
|
|
203
|
-
label="Reset"
|
|
204
|
-
onClick={lambda -> None { count = 0; }}
|
|
205
|
-
variant="secondary"
|
|
206
|
-
/>
|
|
207
|
-
</div>
|
|
208
|
-
</div>;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
''';
|
|
212
|
-
with open(project_path / "main.jac", 'w') as f {
|
|
213
|
-
f.write(main_jac_content);
|
|
132
|
+
try {
|
|
133
|
+
console.print(
|
|
134
|
+
f"\n📦 Installing all {dep_type.name} packages from jac.toml",
|
|
135
|
+
style="bold"
|
|
136
|
+
);
|
|
137
|
+
with console.status(
|
|
138
|
+
f"[cyan]Installing {dep_type.name} packages...[/cyan]", spinner="dots"
|
|
139
|
+
) as status {
|
|
140
|
+
dep_type.install_all_handler(config);
|
|
141
|
+
}
|
|
142
|
+
console.success(f"Installed all {dep_type.name} packages");
|
|
143
|
+
ctx.set_data("cancel_execution", True);
|
|
144
|
+
ctx.set_data("cancel_return_code", 0);
|
|
145
|
+
} except Exception as e {
|
|
146
|
+
console.error(f"Failed to install packages: {e}");
|
|
147
|
+
ctx.set_data("cancel_execution", True);
|
|
148
|
+
ctx.set_data("cancel_return_code", 1);
|
|
149
|
+
}
|
|
150
|
+
return;
|
|
214
151
|
}
|
|
215
|
-
print("Created main.jac");
|
|
216
|
-
|
|
217
|
-
button_cl_jac_content = '''"""Button component for the Jac client application."""
|
|
218
152
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
"primary": {
|
|
232
|
-
"backgroundColor": "#9ca3af" if disabled else "#3b82f6",
|
|
233
|
-
"color": "#ffffff"
|
|
234
|
-
},
|
|
235
|
-
"secondary": {
|
|
236
|
-
"backgroundColor": "#e5e7eb" if disabled else "#6b7280",
|
|
237
|
-
"color": "#ffffff"
|
|
153
|
+
# Install specific packages
|
|
154
|
+
try {
|
|
155
|
+
resolver = DependencyResolver(config=config);
|
|
156
|
+
console.print(
|
|
157
|
+
f"\n📦 Adding {len(packages)} {dep_type.name} package(s)", style="bold"
|
|
158
|
+
);
|
|
159
|
+
for pkg_spec in packages {
|
|
160
|
+
(name, version) = resolver.parse_spec(pkg_spec);
|
|
161
|
+
with console.status(f"[cyan]Installing {name}...[/cyan]", spinner="dots") as status {
|
|
162
|
+
dep_type.install_handler(config, name, version, dev);
|
|
163
|
+
}
|
|
164
|
+
console.print(f" ✔ {name}", style="success");
|
|
238
165
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
</button>;
|
|
248
|
-
}
|
|
249
|
-
''';
|
|
250
|
-
with open(components_dir / "Button.cl.jac", 'w') as f {
|
|
251
|
-
f.write(button_cl_jac_content);
|
|
166
|
+
section = f"dependencies.{dep_type.dev_name if dev else dep_type.name}";
|
|
167
|
+
console.print(f"\n ✔ Updated jac.toml [{section}]", style="muted");
|
|
168
|
+
ctx.set_data("cancel_execution", True);
|
|
169
|
+
ctx.set_data("cancel_return_code", 0);
|
|
170
|
+
} except Exception as e {
|
|
171
|
+
console.error(f"Failed to install packages: {e}");
|
|
172
|
+
ctx.set_data("cancel_execution", True);
|
|
173
|
+
ctx.set_data("cancel_return_code", 1);
|
|
252
174
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
readme_content = f''' # {project_name}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
A Jac client-side application with React support.
|
|
259
|
-
|
|
260
|
-
## Project Structure
|
|
261
|
-
|
|
262
|
-
```
|
|
263
|
-
{project_name}/
|
|
264
|
-
├── jac.toml # Project configuration
|
|
265
|
-
├── main.jac # Main application entry
|
|
266
|
-
├── components/ # Reusable components
|
|
267
|
-
│ └── Button.cl.jac # Example Jac component
|
|
268
|
-
├── assets/ # Static assets (images, fonts, etc.)
|
|
269
|
-
└── build/ # Build output (generated)
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
## Getting Started
|
|
273
|
-
|
|
274
|
-
Start the development server:
|
|
275
|
-
|
|
276
|
-
```bash
|
|
277
|
-
jac start main.jac
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## Components
|
|
281
|
-
|
|
282
|
-
Create Jac components in `components/` as `.cl.jac` files and import them:
|
|
283
|
-
|
|
284
|
-
```jac
|
|
285
|
-
cl import from .components.Button {{ Button }}
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
## Adding Dependencies
|
|
289
|
-
|
|
290
|
-
Add npm packages with the --cl flag:
|
|
175
|
+
}
|
|
291
176
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
177
|
+
"""Pre-hook to handle --npm flag for removing npm dependencies."""
|
|
178
|
+
def _handle_npm_remove(ctx: HookContext) -> None {
|
|
179
|
+
# Check if --npm flag is set
|
|
180
|
+
npm_flag = ctx.get_arg("npm", False);
|
|
181
|
+
if not npm_flag {
|
|
182
|
+
# Let core remove command run normally
|
|
183
|
+
return;
|
|
298
184
|
}
|
|
299
|
-
print("Created README.md");
|
|
300
185
|
|
|
301
|
-
|
|
186
|
+
import from jaclang.project.config { get_config }
|
|
187
|
+
import from jaclang.project.dep_registry { get_dependency_registry }
|
|
188
|
+
import from jaclang.cli.console { console }
|
|
302
189
|
|
|
303
|
-
|
|
304
|
-
if
|
|
305
|
-
|
|
306
|
-
|
|
190
|
+
config = get_config();
|
|
191
|
+
if config is None {
|
|
192
|
+
console.error("No jac.toml found. Run 'jac create' to create a project.");
|
|
193
|
+
ctx.set_data("cancel_execution", True);
|
|
194
|
+
ctx.set_data("cancel_return_code", 1);
|
|
195
|
+
return;
|
|
307
196
|
}
|
|
308
197
|
|
|
309
|
-
|
|
310
|
-
if
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
print("\nNext steps:");
|
|
316
|
-
print(" jac start main.jac");
|
|
198
|
+
packages = ctx.get_arg("packages", []);
|
|
199
|
+
if not packages {
|
|
200
|
+
console.error("No packages specified.");
|
|
201
|
+
ctx.set_data("cancel_execution", True);
|
|
202
|
+
ctx.set_data("cancel_return_code", 1);
|
|
203
|
+
return;
|
|
317
204
|
}
|
|
318
|
-
}
|
|
319
205
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
"
|
|
324
|
-
"
|
|
325
|
-
|
|
326
|
-
"
|
|
327
|
-
|
|
328
|
-
"__jaccache__/",
|
|
329
|
-
"",
|
|
330
|
-
"# Python",
|
|
331
|
-
"__pycache__/",
|
|
332
|
-
"*.py[cod]",
|
|
333
|
-
".venv/",
|
|
334
|
-
"venv/",
|
|
335
|
-
"",
|
|
336
|
-
"# IDE",
|
|
337
|
-
".idea/",
|
|
338
|
-
".vscode/",
|
|
339
|
-
"*.swp",
|
|
340
|
-
"",
|
|
341
|
-
"# Node.js",
|
|
342
|
-
"node_modules/",
|
|
343
|
-
"",
|
|
344
|
-
"# Jac build artifacts",
|
|
345
|
-
".jac/",
|
|
346
|
-
"*.session",
|
|
347
|
-
"*.session.*"
|
|
348
|
-
];
|
|
349
|
-
|
|
350
|
-
gitignore_path = project_path / ".gitignore";
|
|
351
|
-
if gitignore_path.exists() {
|
|
352
|
-
with open(gitignore_path, "r") as f {
|
|
353
|
-
existing_content = f.read();
|
|
354
|
-
}
|
|
355
|
-
new_entries: list = [];
|
|
356
|
-
for entry in gitignore_entries {
|
|
357
|
-
if entry and entry not in existing_content {
|
|
358
|
-
new_entries.append(entry);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if new_entries {
|
|
362
|
-
with open(gitignore_path, "a") as f {
|
|
363
|
-
f.write("\n" + "\n".join(new_entries));
|
|
364
|
-
}
|
|
365
|
-
print("Updated .gitignore");
|
|
366
|
-
}
|
|
367
|
-
} else {
|
|
368
|
-
with open(gitignore_path, "w") as f {
|
|
369
|
-
f.write("\n".join(gitignore_entries) + "\n");
|
|
370
|
-
}
|
|
371
|
-
print("Created .gitignore");
|
|
206
|
+
registry = get_dependency_registry();
|
|
207
|
+
dep_type = registry.get_by_flag("--npm");
|
|
208
|
+
if dep_type is None {
|
|
209
|
+
console.error("--npm flag requires jac-client plugin to be installed.");
|
|
210
|
+
console.print("Install with: pip install jac-client", style="muted");
|
|
211
|
+
ctx.set_data("cancel_execution", True);
|
|
212
|
+
ctx.set_data("cancel_return_code", 1);
|
|
213
|
+
return;
|
|
372
214
|
}
|
|
373
|
-
}
|
|
374
215
|
|
|
375
|
-
|
|
376
|
-
def _install_default_packages(
|
|
377
|
-
project_path: pathlib.Path, verbose: bool = False
|
|
378
|
-
) -> None {
|
|
379
|
-
import from jac_client.plugin.src.vite_bundler { ViteBundler }
|
|
216
|
+
dev = ctx.get_arg("dev", False);
|
|
380
217
|
|
|
381
218
|
try {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
print(
|
|
386
|
-
"Warning: jac.toml not found, skipping package installation",
|
|
387
|
-
file=sys.stderr
|
|
388
|
-
);
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
# Get project name from jac.toml or use directory name
|
|
393
|
-
project_name = project_path.name;
|
|
394
|
-
|
|
395
|
-
# Create ViteBundler instance (it will load config internally)
|
|
396
|
-
bundler = ViteBundler(project_path);
|
|
397
|
-
|
|
398
|
-
# Generate package.json with default packages (defaults are added automatically)
|
|
399
|
-
bundler.create_package_json(project_name=project_name);
|
|
400
|
-
|
|
401
|
-
# Ensure .jac/client directory exists
|
|
402
|
-
client_dir = bundler._get_client_dir();
|
|
403
|
-
client_dir.mkdir(parents=True, exist_ok=True);
|
|
404
|
-
|
|
405
|
-
# Copy package.json to .jac/client/ for npm install
|
|
406
|
-
configs_package_json = client_dir / 'configs' / 'package.json';
|
|
407
|
-
build_package_json = client_dir / 'package.json';
|
|
408
|
-
|
|
409
|
-
if not configs_package_json.exists() {
|
|
410
|
-
print(
|
|
411
|
-
"Warning: package.json was not generated, skipping package installation",
|
|
412
|
-
file=sys.stderr
|
|
413
|
-
);
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
# Always copy the generated package.json to .jac/client/ for npm install
|
|
418
|
-
shutil.copy2(configs_package_json, build_package_json);
|
|
419
|
-
|
|
420
|
-
# Read package data for verbose output
|
|
421
|
-
import json;
|
|
422
|
-
with open(configs_package_json, 'r') as f {
|
|
423
|
-
pkg_data = json.load(f);
|
|
424
|
-
}
|
|
425
|
-
deps = pkg_data.get('dependencies', {});
|
|
426
|
-
dev_deps = pkg_data.get('devDependencies', {});
|
|
427
|
-
|
|
428
|
-
if verbose {
|
|
429
|
-
# Verbose mode: show detailed package list and stream npm output
|
|
430
|
-
if deps {
|
|
431
|
-
print(" Dependencies:");
|
|
432
|
-
for (name, version) in deps.items() {
|
|
433
|
-
print(f" - {name}@{version}");
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
if dev_deps {
|
|
437
|
-
print(" Dev dependencies:");
|
|
438
|
-
for (name, version) in dev_deps.items() {
|
|
439
|
-
print(f" - {name}@{version}");
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
print("\nRunning npm install...");
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
# Run npm install in .jac/client/ directory
|
|
446
|
-
try {
|
|
447
|
-
if verbose {
|
|
448
|
-
# Stream output for visibility in verbose mode
|
|
449
|
-
subprocess.run(
|
|
450
|
-
['npm', 'install', '--progress'], cwd=client_dir, check=True
|
|
451
|
-
);
|
|
452
|
-
} else {
|
|
453
|
-
# Quiet mode: capture output
|
|
454
|
-
subprocess.run(
|
|
455
|
-
['npm', 'install'],
|
|
456
|
-
cwd=client_dir,
|
|
457
|
-
check=True,
|
|
458
|
-
capture_output=True,
|
|
459
|
-
text=True
|
|
460
|
-
);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
# Move package-lock.json to configs/ if it was created
|
|
464
|
-
build_package_lock = client_dir / 'package-lock.json';
|
|
465
|
-
configs_dir = client_dir / 'configs';
|
|
466
|
-
configs_package_lock = configs_dir / 'package-lock.json';
|
|
467
|
-
if build_package_lock.exists() {
|
|
468
|
-
configs_dir.mkdir(parents=True, exist_ok=True);
|
|
469
|
-
if configs_package_lock.exists() {
|
|
470
|
-
configs_package_lock.unlink();
|
|
471
|
-
}
|
|
472
|
-
shutil.move(str(build_package_lock), str(configs_package_lock));
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
print("Default packages installed successfully");
|
|
476
|
-
} except subprocess.CalledProcessError as e {
|
|
477
|
-
if verbose {
|
|
478
|
-
print(
|
|
479
|
-
f"Warning: Failed to install packages (exit code {e.returncode})",
|
|
480
|
-
file=sys.stderr
|
|
481
|
-
);
|
|
482
|
-
} else {
|
|
483
|
-
print(
|
|
484
|
-
f"Warning: Failed to install packages: {e.stderr}", file=sys.stderr
|
|
485
|
-
);
|
|
486
|
-
}
|
|
487
|
-
print("You can install packages later with: jac add --cl", file=sys.stderr);
|
|
488
|
-
} except FileNotFoundError {
|
|
489
|
-
print(
|
|
490
|
-
"Warning: npm command not found. Install Node.js and npm to install packages.",
|
|
491
|
-
file=sys.stderr
|
|
492
|
-
);
|
|
493
|
-
print("You can install packages later with: jac add --cl", file=sys.stderr);
|
|
494
|
-
} finally {
|
|
495
|
-
# Clean up temporary package.json in .jac/client/
|
|
496
|
-
if build_package_json.exists() {
|
|
497
|
-
build_package_json.unlink();
|
|
498
|
-
}
|
|
219
|
+
for name in packages {
|
|
220
|
+
console.info(f"Removing {name} ({dep_type.name})...");
|
|
221
|
+
dep_type.remove_handler(config, name, dev);
|
|
499
222
|
}
|
|
223
|
+
console.success(f"Removed {len(packages)} package(s)");
|
|
224
|
+
ctx.set_data("cancel_execution", True);
|
|
225
|
+
ctx.set_data("cancel_return_code", 0);
|
|
500
226
|
} except Exception as e {
|
|
501
|
-
|
|
502
|
-
|
|
227
|
+
console.error(f"Error removing packages: {e}");
|
|
228
|
+
ctx.set_data("cancel_execution", True);
|
|
229
|
+
ctx.set_data("cancel_return_code", 1);
|
|
503
230
|
}
|
|
504
231
|
}
|