jac-client 0.2.7__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/{src/app.jac → main.jac} +5 -5
- jac_client/examples/all-in-one/{src/pages → pages}/BudgetPlanner.jac +8 -1
- jac_client/examples/all-in-one/{src/pages → pages}/FeaturesTest.jac +16 -1
- jac_client/examples/all-in-one/{src/pages/FeaturesTest.cl.jac → pages/features_test_ui.cl.jac} +11 -0
- jac_client/examples/all-in-one/{src/pages → pages}/nestedDemo.jac +1 -1
- jac_client/examples/all-in-one/{src/pages → pages}/notFound.jac +2 -7
- jac_client/plugin/cli.jac +162 -430
- jac_client/plugin/client.jac +30 -12
- jac_client/plugin/client_runtime.cl.jac +19 -15
- jac_client/plugin/impl/client.impl.jac +107 -69
- jac_client/plugin/impl/client_runtime.impl.jac +181 -9
- 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 +2 -4
- jac_client/plugin/src/impl/config_loader.impl.jac +8 -0
- jac_client/plugin/src/impl/vite_bundler.impl.jac +241 -11
- jac_client/plugin/src/vite_bundler.jac +14 -1
- 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 +189 -73
- jac_client/tests/test_e2e.py +232 -0
- jac_client/tests/test_helpers.py +65 -0
- jac_client/tests/test_it.py +97 -137
- {jac_client-0.2.7.dist-info → jac_client-0.2.9.dist-info}/METADATA +4 -4
- jac_client-0.2.9.dist-info/RECORD +104 -0
- {jac_client-0.2.7.dist-info → jac_client-0.2.9.dist-info}/WHEEL +1 -1
- jac_client-0.2.7.dist-info/RECORD +0 -97
- /jac_client/examples/all-in-one/{src/button.jac → button.jac} +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/CategoryFilter.jac +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/Header.jac +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/ProfitOverview.jac +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/Summary.jac +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/TransactionForm.jac +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/TransactionItem.jac +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/TransactionList.jac +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/button.jac +0 -0
- /jac_client/examples/all-in-one/{src/components → components}/navigation.jac +0 -0
- /jac_client/examples/all-in-one/{src/constants → constants}/categories.jac +0 -0
- /jac_client/examples/all-in-one/{src/constants → constants}/clients.jac +0 -0
- /jac_client/examples/all-in-one/{src/context → context}/BudgetContext.jac +0 -0
- /jac_client/examples/all-in-one/{src/hooks → hooks}/useBudget.jac +0 -0
- /jac_client/examples/all-in-one/{src/hooks → hooks}/useLocalStorage.jac +0 -0
- /jac_client/examples/all-in-one/{src/pages → pages}/LandingPage.jac +0 -0
- /jac_client/examples/all-in-one/{src/pages/BudgetPlanner.cl.jac → pages/budget_planner_ui.cl.jac} +0 -0
- /jac_client/examples/all-in-one/{src/pages → pages}/loginPage.jac +0 -0
- /jac_client/examples/all-in-one/{src/pages → pages}/signupPage.jac +0 -0
- /jac_client/examples/all-in-one/{src/utils → utils}/formatters.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.7.dist-info → jac_client-0.2.9.dist-info}/entry_points.txt +0 -0
- {jac_client-0.2.7.dist-info → jac_client-0.2.9.dist-info}/top_level.txt +0 -0
jac_client/plugin/cli.jac
CHANGED
|
@@ -1,499 +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.npm]
|
|
155
|
-
"jac-client-node" = "1.0.3"
|
|
156
|
-
|
|
157
|
-
[dependencies.npm.dev]
|
|
158
|
-
"@jac-client/dev-deps" = "1.0.0"
|
|
159
|
-
|
|
160
|
-
[serve]
|
|
161
|
-
base_route_app = "app"
|
|
162
|
-
|
|
163
|
-
[plugins.client]
|
|
164
|
-
# Vite bundler configuration (optional overrides)
|
|
165
|
-
# vite.plugins = []
|
|
166
|
-
# vite.build = {{}}
|
|
167
|
-
''';
|
|
168
|
-
with open(toml_path, 'w') as f {
|
|
169
|
-
f.write(toml_content);
|
|
170
|
-
}
|
|
171
|
-
print(f"Created {toml_path}");
|
|
172
|
-
|
|
173
|
-
main_jac_content = '''"""Main entry point for the Jac client application."""
|
|
174
|
-
|
|
175
|
-
# Client-side imports (useState is auto-injected when using `has` variables)
|
|
176
|
-
cl import from react { useEffect }
|
|
177
|
-
cl import from .components.Button { Button }
|
|
178
|
-
|
|
179
|
-
# Client-side component
|
|
180
|
-
cl {
|
|
181
|
-
def:pub app() -> any {
|
|
182
|
-
has count: int = 0;
|
|
183
|
-
|
|
184
|
-
useEffect(lambda -> None {
|
|
185
|
-
console.log("Count updated:", count);
|
|
186
|
-
}, [count]);
|
|
187
|
-
|
|
188
|
-
return <div style={{padding: "2rem", fontFamily: "Arial, sans-serif"}}>
|
|
189
|
-
<h1>Hello, World!</h1>
|
|
190
|
-
<p>Count: {count}</p>
|
|
191
|
-
<div style={{display: "flex", gap: "1rem", marginTop: "1rem"}}>
|
|
192
|
-
<Button
|
|
193
|
-
label="Increment"
|
|
194
|
-
onClick={lambda -> None { count = count + 1; }}
|
|
195
|
-
variant="primary"
|
|
196
|
-
/>
|
|
197
|
-
<Button
|
|
198
|
-
label="Reset"
|
|
199
|
-
onClick={lambda -> None { count = 0; }}
|
|
200
|
-
variant="secondary"
|
|
201
|
-
/>
|
|
202
|
-
</div>
|
|
203
|
-
</div>;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
''';
|
|
207
|
-
with open(project_path / "main.jac", 'w') as f {
|
|
208
|
-
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;
|
|
209
151
|
}
|
|
210
|
-
print("Created main.jac");
|
|
211
152
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
variant_styles = {
|
|
226
|
-
"primary": {
|
|
227
|
-
"backgroundColor": "#9ca3af" if disabled else "#3b82f6",
|
|
228
|
-
"color": "#ffffff"
|
|
229
|
-
},
|
|
230
|
-
"secondary": {
|
|
231
|
-
"backgroundColor": "#e5e7eb" if disabled else "#6b7280",
|
|
232
|
-
"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");
|
|
233
165
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
</button>;
|
|
243
|
-
}
|
|
244
|
-
''';
|
|
245
|
-
with open(components_dir / "Button.cl.jac", 'w') as f {
|
|
246
|
-
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);
|
|
247
174
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
readme_content = f''' # {project_name}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
A Jac client-side application with React support.
|
|
254
|
-
|
|
255
|
-
## Project Structure
|
|
256
|
-
|
|
257
|
-
```
|
|
258
|
-
{project_name}/
|
|
259
|
-
├── jac.toml # Project configuration
|
|
260
|
-
├── main.jac # Main application entry
|
|
261
|
-
├── components/ # Reusable components
|
|
262
|
-
│ └── Button.cl.jac # Example Jac component
|
|
263
|
-
├── assets/ # Static assets (images, fonts, etc.)
|
|
264
|
-
└── build/ # Build output (generated)
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Getting Started
|
|
268
|
-
|
|
269
|
-
Start the development server:
|
|
270
|
-
|
|
271
|
-
```bash
|
|
272
|
-
jac start main.jac
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Components
|
|
276
|
-
|
|
277
|
-
Create Jac components in `components/` as `.cl.jac` files and import them:
|
|
278
|
-
|
|
279
|
-
```jac
|
|
280
|
-
cl import from .components.Button {{ Button }}
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Adding Dependencies
|
|
284
|
-
|
|
285
|
-
Add npm packages with the --cl flag:
|
|
175
|
+
}
|
|
286
176
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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;
|
|
293
184
|
}
|
|
294
|
-
print("Created README.md");
|
|
295
185
|
|
|
296
|
-
|
|
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 }
|
|
297
189
|
|
|
298
|
-
|
|
299
|
-
if
|
|
300
|
-
|
|
301
|
-
|
|
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;
|
|
302
196
|
}
|
|
303
197
|
|
|
304
|
-
|
|
305
|
-
if
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
print("\nNext steps:");
|
|
311
|
-
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;
|
|
312
204
|
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
"""Create .gitignore file with client-specific entries."""
|
|
316
|
-
def _create_gitignore(project_path: pathlib.Path) -> None {
|
|
317
|
-
gitignore_entries = [
|
|
318
|
-
"# Jac project",
|
|
319
|
-
"packages/",
|
|
320
|
-
".jac_cache/",
|
|
321
|
-
"*.jbc",
|
|
322
|
-
"*.jir",
|
|
323
|
-
"__jaccache__/",
|
|
324
|
-
"",
|
|
325
|
-
"# Python",
|
|
326
|
-
"__pycache__/",
|
|
327
|
-
"*.py[cod]",
|
|
328
|
-
".venv/",
|
|
329
|
-
"venv/",
|
|
330
|
-
"",
|
|
331
|
-
"# IDE",
|
|
332
|
-
".idea/",
|
|
333
|
-
".vscode/",
|
|
334
|
-
"*.swp",
|
|
335
|
-
"",
|
|
336
|
-
"# Node.js",
|
|
337
|
-
"node_modules/",
|
|
338
|
-
"",
|
|
339
|
-
"# Jac build artifacts",
|
|
340
|
-
".jac/",
|
|
341
|
-
"*.session",
|
|
342
|
-
"*.session.*"
|
|
343
|
-
];
|
|
344
205
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
new_entries.append(entry);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
if new_entries {
|
|
357
|
-
with open(gitignore_path, "a") as f {
|
|
358
|
-
f.write("\n" + "\n".join(new_entries));
|
|
359
|
-
}
|
|
360
|
-
print("Updated .gitignore");
|
|
361
|
-
}
|
|
362
|
-
} else {
|
|
363
|
-
with open(gitignore_path, "w") as f {
|
|
364
|
-
f.write("\n".join(gitignore_entries) + "\n");
|
|
365
|
-
}
|
|
366
|
-
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;
|
|
367
214
|
}
|
|
368
|
-
}
|
|
369
215
|
|
|
370
|
-
|
|
371
|
-
def _install_default_packages(
|
|
372
|
-
project_path: pathlib.Path, verbose: bool = False
|
|
373
|
-
) -> None {
|
|
374
|
-
import from jac_client.plugin.src.vite_bundler { ViteBundler }
|
|
216
|
+
dev = ctx.get_arg("dev", False);
|
|
375
217
|
|
|
376
218
|
try {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
print(
|
|
381
|
-
"Warning: jac.toml not found, skipping package installation",
|
|
382
|
-
file=sys.stderr
|
|
383
|
-
);
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
# Get project name from jac.toml or use directory name
|
|
388
|
-
project_name = project_path.name;
|
|
389
|
-
|
|
390
|
-
# Create ViteBundler instance (it will load config internally)
|
|
391
|
-
bundler = ViteBundler(project_path);
|
|
392
|
-
|
|
393
|
-
# Generate package.json with default packages (defaults are added automatically)
|
|
394
|
-
bundler.create_package_json(project_name=project_name);
|
|
395
|
-
|
|
396
|
-
# Ensure .jac/client directory exists
|
|
397
|
-
client_dir = bundler._get_client_dir();
|
|
398
|
-
client_dir.mkdir(parents=True, exist_ok=True);
|
|
399
|
-
|
|
400
|
-
# Copy package.json to .jac/client/ for npm install
|
|
401
|
-
configs_package_json = client_dir / 'configs' / 'package.json';
|
|
402
|
-
build_package_json = client_dir / 'package.json';
|
|
403
|
-
|
|
404
|
-
if not configs_package_json.exists() {
|
|
405
|
-
print(
|
|
406
|
-
"Warning: package.json was not generated, skipping package installation",
|
|
407
|
-
file=sys.stderr
|
|
408
|
-
);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
# Always copy the generated package.json to .jac/client/ for npm install
|
|
413
|
-
shutil.copy2(configs_package_json, build_package_json);
|
|
414
|
-
|
|
415
|
-
# Read package data for verbose output
|
|
416
|
-
import json;
|
|
417
|
-
with open(configs_package_json, 'r') as f {
|
|
418
|
-
pkg_data = json.load(f);
|
|
419
|
-
}
|
|
420
|
-
deps = pkg_data.get('dependencies', {});
|
|
421
|
-
dev_deps = pkg_data.get('devDependencies', {});
|
|
422
|
-
|
|
423
|
-
if verbose {
|
|
424
|
-
# Verbose mode: show detailed package list and stream npm output
|
|
425
|
-
if deps {
|
|
426
|
-
print(" Dependencies:");
|
|
427
|
-
for (name, version) in deps.items() {
|
|
428
|
-
print(f" - {name}@{version}");
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
if dev_deps {
|
|
432
|
-
print(" Dev dependencies:");
|
|
433
|
-
for (name, version) in dev_deps.items() {
|
|
434
|
-
print(f" - {name}@{version}");
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
print("\nRunning npm install...");
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
# Run npm install in .jac/client/ directory
|
|
441
|
-
try {
|
|
442
|
-
if verbose {
|
|
443
|
-
# Stream output for visibility in verbose mode
|
|
444
|
-
subprocess.run(
|
|
445
|
-
['npm', 'install', '--progress'], cwd=client_dir, check=True
|
|
446
|
-
);
|
|
447
|
-
} else {
|
|
448
|
-
# Quiet mode: capture output
|
|
449
|
-
subprocess.run(
|
|
450
|
-
['npm', 'install'],
|
|
451
|
-
cwd=client_dir,
|
|
452
|
-
check=True,
|
|
453
|
-
capture_output=True,
|
|
454
|
-
text=True
|
|
455
|
-
);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
# Move package-lock.json to configs/ if it was created
|
|
459
|
-
build_package_lock = client_dir / 'package-lock.json';
|
|
460
|
-
configs_dir = client_dir / 'configs';
|
|
461
|
-
configs_package_lock = configs_dir / 'package-lock.json';
|
|
462
|
-
if build_package_lock.exists() {
|
|
463
|
-
configs_dir.mkdir(parents=True, exist_ok=True);
|
|
464
|
-
if configs_package_lock.exists() {
|
|
465
|
-
configs_package_lock.unlink();
|
|
466
|
-
}
|
|
467
|
-
shutil.move(str(build_package_lock), str(configs_package_lock));
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
print("Default packages installed successfully");
|
|
471
|
-
} except subprocess.CalledProcessError as e {
|
|
472
|
-
if verbose {
|
|
473
|
-
print(
|
|
474
|
-
f"Warning: Failed to install packages (exit code {e.returncode})",
|
|
475
|
-
file=sys.stderr
|
|
476
|
-
);
|
|
477
|
-
} else {
|
|
478
|
-
print(
|
|
479
|
-
f"Warning: Failed to install packages: {e.stderr}", file=sys.stderr
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
|
-
print("You can install packages later with: jac add --cl", file=sys.stderr);
|
|
483
|
-
} except FileNotFoundError {
|
|
484
|
-
print(
|
|
485
|
-
"Warning: npm command not found. Install Node.js and npm to install packages.",
|
|
486
|
-
file=sys.stderr
|
|
487
|
-
);
|
|
488
|
-
print("You can install packages later with: jac add --cl", file=sys.stderr);
|
|
489
|
-
} finally {
|
|
490
|
-
# Clean up temporary package.json in .jac/client/
|
|
491
|
-
if build_package_json.exists() {
|
|
492
|
-
build_package_json.unlink();
|
|
493
|
-
}
|
|
219
|
+
for name in packages {
|
|
220
|
+
console.info(f"Removing {name} ({dep_type.name})...");
|
|
221
|
+
dep_type.remove_handler(config, name, dev);
|
|
494
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);
|
|
495
226
|
} except Exception as e {
|
|
496
|
-
|
|
497
|
-
|
|
227
|
+
console.error(f"Error removing packages: {e}");
|
|
228
|
+
ctx.set_data("cancel_execution", True);
|
|
229
|
+
ctx.set_data("cancel_return_code", 1);
|
|
498
230
|
}
|
|
499
231
|
}
|