jac-client 0.2.11__tar.gz → 0.2.12__tar.gz
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-0.2.11 → jac_client-0.2.12}/PKG-INFO +2 -2
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/vite_bundler.impl.jac +35 -19
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/utils/__init__.jac +1 -0
- jac_client-0.2.12/jac_client/plugin/utils/client_deps.jac +14 -0
- jac_client-0.2.12/jac_client/plugin/utils/impl/client_deps.impl.jac +73 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/templates/client.jacpack +0 -4
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/templates/fullstack.jacpack +0 -4
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/test_cli.py +68 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client.egg-info/PKG-INFO +2 -2
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client.egg-info/SOURCES.txt +2 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client.egg-info/requires.txt +1 -1
- {jac_client-0.2.11 → jac_client-0.2.12}/pyproject.toml +2 -2
- {jac_client-0.2.11 → jac_client-0.2.12}/README.md +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/assets/workers/worker.py +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/button.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/CategoryFilter.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/Header.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/ProfitOverview.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/Summary.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/TransactionForm.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/TransactionItem.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/TransactionList.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/button.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/navigation.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/constants/categories.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/constants/clients.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/context/BudgetContext.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/hooks/useBudget.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/hooks/useLocalStorage.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/BudgetPlanner.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/FeaturesTest.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/LandingPage.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/loginPage.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/nestedDemo.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/notFound.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/signupPage.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/utils/formatters.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/asset-serving/css-with-image/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/asset-serving/image-asset/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/asset-serving/import-alias/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/basic/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/basic-auth/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/basic-auth-with-router/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/basic-full-stack/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/js-styling/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/material-ui/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/pure-css/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/sass-example/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/styled-components/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/tailwind-example/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/full-stack-with-auth/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/little-x/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/little-x/src/submit-button.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-advance/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-advance/src/ButtonRoot.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-advance/src/level1/ButtonSecondL.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-advance/src/level1/Card.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-advance/src/level1/level2/ButtonThirdL.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-basic/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-basic/src/button.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-basic/src/components/button.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/ts-support/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/with-router/main.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/cli.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/client.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/client_runtime.cl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/impl/client.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/impl/client_runtime.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/impl/vite_client_bundle.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/plugin_config.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/__init__.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/asset_processor.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/compiler.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/config_loader.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/desktop_config.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/asset_processor.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/compiler.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/config_loader.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/desktop_config.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/import_processor.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/jac_to_js.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/package_installer.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/import_processor.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/jac_to_js.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/package_installer.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/desktop/sidecar/main.py +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/desktop_target.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/impl/desktop_target.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/impl/registry.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/impl/web_target.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/register.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/registry.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/web_target.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/vite_bundler.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/utils/bun_installer.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/utils/impl/bun_installer.impl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/vite_client_bundle.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/__init__.py +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/conftest.py +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/basic-app/app.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/cl_file/app.cl.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/cl_file/app.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/client_app_with_antd/app.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/js_import/app.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/relative_import/app.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/relative_import/button.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/spawn_test/app.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/test_fragments_spread/app.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/with-ts/app.jac +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/test_e2e.py +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/test_helpers.py +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/test_it.py +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/test_it_desktop.py +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client.egg-info/dependency_links.txt +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client.egg-info/entry_points.txt +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/jac_client.egg-info/top_level.txt +0 -0
- {jac_client-0.2.11 → jac_client-0.2.12}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jac-client
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.12
|
|
4
4
|
Summary: Build full-stack web applications with Jac - one language for frontend and backend.
|
|
5
5
|
Author-email: Jason Mars <jason@mars.ninja>
|
|
6
6
|
Maintainer-email: Jason Mars <jason@mars.ninja>
|
|
@@ -11,7 +11,7 @@ Project-URL: Documentation, https://jac-lang.org
|
|
|
11
11
|
Keywords: jac,jaclang,jaseci,frontend,full-stack,web-development
|
|
12
12
|
Requires-Python: >=3.12
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
|
-
Requires-Dist: jaclang>=0.9.
|
|
14
|
+
Requires-Dist: jaclang>=0.9.12
|
|
15
15
|
Provides-Extra: dev
|
|
16
16
|
Requires-Dist: python-dotenv==1.0.1; extra == "dev"
|
|
17
17
|
Requires-Dist: pytest==8.3.5; extra == "dev"
|
|
@@ -426,22 +426,29 @@ impl ViteBundler.build(self: ViteBundler, entry_file: Optional[Path] = None) ->
|
|
|
426
426
|
import sys;
|
|
427
427
|
import time;
|
|
428
428
|
import shutil;
|
|
429
|
-
import from jac_client.plugin.utils { ensure_bun_available }
|
|
429
|
+
import from jac_client.plugin.utils { ensure_bun_available, ensure_client_deps }
|
|
430
430
|
# Ensure bun is available before proceeding
|
|
431
431
|
if not ensure_bun_available() {
|
|
432
432
|
raise ClientBundleError('Bun is required. Install manually: https://bun.sh') from None ;
|
|
433
433
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
self.create_tsconfig();
|
|
434
|
+
# Ensure client npm deps are configured; prompt to install defaults if missing
|
|
435
|
+
if not ensure_client_deps(self.config_loader) {
|
|
436
|
+
raise ClientBundleError(
|
|
437
|
+
'Client dependencies not configured. Add [dependencies.npm] to jac.toml '
|
|
438
|
+
'or create a project with: jac create --use client'
|
|
439
|
+
) from None ;
|
|
441
440
|
}
|
|
441
|
+
self.output_dir.mkdir(parents=True, exist_ok=True);
|
|
442
|
+
# Always regenerate package.json to pick up any dependency changes
|
|
443
|
+
self.create_package_json();
|
|
442
444
|
try {
|
|
443
445
|
build_dir = self._get_client_dir();
|
|
444
446
|
node_modules = build_dir / 'node_modules';
|
|
447
|
+
# Reinstall if node_modules is missing or stale (e.g. empty from a prior failed install)
|
|
448
|
+
vite_bin = node_modules / '.bin' / 'vite';
|
|
449
|
+
if node_modules.exists() and not vite_bin.exists() {
|
|
450
|
+
shutil.rmtree(node_modules);
|
|
451
|
+
}
|
|
445
452
|
if not node_modules.exists() {
|
|
446
453
|
# Temporarily copy package.json to client build dir for bun install
|
|
447
454
|
build_package_json = build_dir / 'package.json';
|
|
@@ -455,15 +462,17 @@ impl ViteBundler.build(self: ViteBundler, entry_file: Optional[Path] = None) ->
|
|
|
455
462
|
print("\n ⏳ Installing dependencies...\n", flush=True);
|
|
456
463
|
start_time = time.time();
|
|
457
464
|
result = subprocess.run(
|
|
458
|
-
['bun', 'install'],
|
|
465
|
+
['bun', 'install'],
|
|
466
|
+
cwd=build_dir,
|
|
467
|
+
check=False,
|
|
468
|
+
text=True,
|
|
469
|
+
capture_output=True
|
|
459
470
|
);
|
|
460
471
|
elapsed = time.time() - start_time;
|
|
461
472
|
if result.returncode != 0 {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
);
|
|
466
|
-
raise ClientBundleError("Failed to install dependencies") ;
|
|
473
|
+
error_output = result.stderr or result.stdout;
|
|
474
|
+
error_msg = f"Dependency installation failed after {elapsed:.1f}s\n\n{error_output}\nCommand: bun install";
|
|
475
|
+
raise ClientBundleError(error_msg) from None ;
|
|
467
476
|
}
|
|
468
477
|
print(f"\n ✔ Dependencies installed ({elapsed:.1f}s)", flush=True);
|
|
469
478
|
} except FileNotFoundError {
|
|
@@ -500,13 +509,16 @@ impl ViteBundler.build(self: ViteBundler, entry_file: Optional[Path] = None) ->
|
|
|
500
509
|
# Run vite from client build directory so it can find node_modules
|
|
501
510
|
print("\n ⏳ Building client bundle...\n", flush=True);
|
|
502
511
|
start_time = time.time();
|
|
503
|
-
result = subprocess.run(
|
|
512
|
+
result = subprocess.run(
|
|
513
|
+
command, cwd=build_dir, check=False, text=True, capture_output=True
|
|
514
|
+
);
|
|
504
515
|
elapsed = time.time() - start_time;
|
|
505
516
|
if result.returncode != 0 {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
)
|
|
517
|
+
error_output = result.stderr or result.stdout;
|
|
518
|
+
error_msg = f"Vite build failed after {elapsed:.1f}s\n\n{error_output}\nCommand: {' '.join(
|
|
519
|
+
command
|
|
520
|
+
)}";
|
|
521
|
+
raise ClientBundleError(error_msg) from None ;
|
|
510
522
|
}
|
|
511
523
|
print(f"\n ✔ Client bundle built ({elapsed:.1f}s)", flush=True);
|
|
512
524
|
} finally {
|
|
@@ -615,6 +627,10 @@ export default defineConfig({{
|
|
|
615
627
|
target: "http://localhost:{api_port}",
|
|
616
628
|
changeOrigin: true,
|
|
617
629
|
}},
|
|
630
|
+
"/static": {{
|
|
631
|
+
target: "http://localhost:{api_port}",
|
|
632
|
+
changeOrigin: true,
|
|
633
|
+
}},
|
|
618
634
|
}},
|
|
619
635
|
}},
|
|
620
636
|
resolve: {{
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Client dependency checker utility for jac-client.
|
|
2
|
+
|
|
3
|
+
Provides a function to check if required npm dependencies are configured
|
|
4
|
+
and prompt the user to install defaults if missing.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
"""Check if client npm dependencies are configured, prompt to install if missing.
|
|
8
|
+
|
|
9
|
+
Takes a JacClientConfig instance, checks if dependencies and devDependencies
|
|
10
|
+
are both empty, and if so prompts the user to install default jac-client deps.
|
|
11
|
+
|
|
12
|
+
Returns True if deps are configured (or were just installed), False if user declined.
|
|
13
|
+
"""
|
|
14
|
+
def ensure_client_deps(config_loader: object) -> bool;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Implementation of client dependency checker utility."""
|
|
2
|
+
|
|
3
|
+
"""Check if client npm dependencies are configured, prompt to install if missing."""
|
|
4
|
+
impl ensure_client_deps(config_loader: object) -> bool {
|
|
5
|
+
package_config = config_loader.get_package_config();
|
|
6
|
+
dependencies = package_config.get('dependencies', {});
|
|
7
|
+
dev_dependencies = package_config.get('devDependencies', {});
|
|
8
|
+
# If either deps or devDeps has entries, assume configured
|
|
9
|
+
if dependencies or dev_dependencies {
|
|
10
|
+
return True;
|
|
11
|
+
}
|
|
12
|
+
# No deps configured — prompt the user
|
|
13
|
+
return prompt_install_client_deps(config_loader);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
"""Prompt user to install default jac-client npm dependencies."""
|
|
17
|
+
def prompt_install_client_deps(config_loader: object) -> bool {
|
|
18
|
+
import sys;
|
|
19
|
+
print("\n ⚠ Client dependencies are not configured.", file=sys.stderr);
|
|
20
|
+
print(
|
|
21
|
+
" jac-client requires npm packages (react, vite, etc.) to build client pages.",
|
|
22
|
+
file=sys.stderr
|
|
23
|
+
);
|
|
24
|
+
print(" These will be added to your jac.toml file.\n", file=sys.stderr);
|
|
25
|
+
try {
|
|
26
|
+
response = input(" Install default client dependencies now? [Y/n]: ").strip().lower();
|
|
27
|
+
} except (EOFError, KeyboardInterrupt) {
|
|
28
|
+
print("", file=sys.stderr);
|
|
29
|
+
return False;
|
|
30
|
+
}
|
|
31
|
+
if response and response not in ('y', 'yes', '') {
|
|
32
|
+
print(
|
|
33
|
+
"\n To configure manually, add [dependencies.npm] to your jac.toml.",
|
|
34
|
+
file=sys.stderr
|
|
35
|
+
);
|
|
36
|
+
print(
|
|
37
|
+
" Or create a new project with: jac create --use client\n",
|
|
38
|
+
file=sys.stderr
|
|
39
|
+
);
|
|
40
|
+
return False;
|
|
41
|
+
}
|
|
42
|
+
# Default runtime dependencies
|
|
43
|
+
default_deps: dict[str, str] = {
|
|
44
|
+
'react': '^18.2.0',
|
|
45
|
+
'react-dom': '^18.2.0',
|
|
46
|
+
'react-router-dom': '^6.22.0',
|
|
47
|
+
'react-error-boundary': '^5.0.0'
|
|
48
|
+
};
|
|
49
|
+
# Default build infrastructure dependencies
|
|
50
|
+
default_dev_deps: dict[str, str] = {
|
|
51
|
+
'vite': '^6.4.1',
|
|
52
|
+
'@vitejs/plugin-react': '^4.2.1',
|
|
53
|
+
'typescript': '^5.3.3',
|
|
54
|
+
'@types/react': '^18.2.0',
|
|
55
|
+
'@types/react-dom': '^18.2.0'
|
|
56
|
+
};
|
|
57
|
+
print("\n ⏳ Adding default client dependencies to jac.toml...", flush=True);
|
|
58
|
+
try {
|
|
59
|
+
for (name, version) in default_deps.items() {
|
|
60
|
+
config_loader.add_dependency(name, version, is_dev=False);
|
|
61
|
+
}
|
|
62
|
+
for (name, version) in default_dev_deps.items() {
|
|
63
|
+
config_loader.add_dependency(name, version, is_dev=True);
|
|
64
|
+
}
|
|
65
|
+
config_loader.save();
|
|
66
|
+
config_loader.invalidate();
|
|
67
|
+
print(" ✔ Default client dependencies added to jac.toml\n", flush=True);
|
|
68
|
+
return True;
|
|
69
|
+
} except Exception as e {
|
|
70
|
+
print(f" ✖ Failed to add dependencies: {e}", file=sys.stderr);
|
|
71
|
+
return False;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""Test create-jac-app command."""
|
|
2
2
|
|
|
3
|
+
import contextlib
|
|
3
4
|
import os
|
|
4
5
|
import tempfile
|
|
5
6
|
import tomllib
|
|
6
7
|
from subprocess import PIPE, Popen, run
|
|
8
|
+
from unittest.mock import patch
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
def test_create_jac_app() -> None:
|
|
@@ -920,3 +922,69 @@ def test_create_cl_and_run_no_root_files() -> None:
|
|
|
920
922
|
|
|
921
923
|
finally:
|
|
922
924
|
os.chdir(original_cwd)
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
def test_vite_build_prompts_for_missing_client_deps() -> None:
|
|
928
|
+
"""Test that ViteBundler.build() prompts to install deps when jac.toml is missing.
|
|
929
|
+
|
|
930
|
+
Exercises the same code path as `jac start` → server.start() → ensure_bundle()
|
|
931
|
+
→ ViteBundler.build(), which checks for npm deps before building.
|
|
932
|
+
"""
|
|
933
|
+
import json
|
|
934
|
+
from pathlib import Path
|
|
935
|
+
|
|
936
|
+
from jac_client.plugin.src.vite_bundler import ViteBundler
|
|
937
|
+
|
|
938
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
939
|
+
project_dir = Path(temp_dir)
|
|
940
|
+
config_file = project_dir / "jac.toml"
|
|
941
|
+
|
|
942
|
+
# No jac.toml — ViteBundler.build() should prompt via ensure_client_deps
|
|
943
|
+
bundler = ViteBundler(project_dir)
|
|
944
|
+
|
|
945
|
+
# Mock input to accept, and mock bun/vite so we don't need real installs.
|
|
946
|
+
# We only care that ensure_client_deps wrote jac.toml before reaching bun.
|
|
947
|
+
with (
|
|
948
|
+
patch("builtins.input", return_value="Y"),
|
|
949
|
+
patch(
|
|
950
|
+
"jac_client.plugin.utils.bun_installer.ensure_bun_available",
|
|
951
|
+
return_value=True,
|
|
952
|
+
),
|
|
953
|
+
patch("subprocess.run") as mock_subprocess,
|
|
954
|
+
):
|
|
955
|
+
# bun install returns success, vite build returns failure
|
|
956
|
+
# (we don't have real vite — that's fine, we're testing the dep prompt)
|
|
957
|
+
mock_subprocess.side_effect = [
|
|
958
|
+
type("Result", (), {"returncode": 0})(), # bun install
|
|
959
|
+
type("Result", (), {"returncode": 1})(), # vite build
|
|
960
|
+
]
|
|
961
|
+
with contextlib.suppress(Exception):
|
|
962
|
+
bundler.build() # vite build failure is expected
|
|
963
|
+
|
|
964
|
+
# The key assertion: jac.toml was created with default client deps
|
|
965
|
+
assert config_file.exists(), (
|
|
966
|
+
"jac.toml should have been created after accepting the prompt"
|
|
967
|
+
)
|
|
968
|
+
|
|
969
|
+
with open(config_file, "rb") as f:
|
|
970
|
+
data = tomllib.load(f)
|
|
971
|
+
|
|
972
|
+
npm_deps = data.get("dependencies", {}).get("npm", {})
|
|
973
|
+
assert "react" in npm_deps, "react should be in dependencies.npm"
|
|
974
|
+
assert "react-dom" in npm_deps, "react-dom should be in dependencies.npm"
|
|
975
|
+
|
|
976
|
+
npm_dev = npm_deps.get("dev", {})
|
|
977
|
+
assert "vite" in npm_dev, "vite should be in dev dependencies"
|
|
978
|
+
assert "@vitejs/plugin-react" in npm_dev, (
|
|
979
|
+
"@vitejs/plugin-react should be in dev deps"
|
|
980
|
+
)
|
|
981
|
+
|
|
982
|
+
# Verify the generated package.json also picked up the deps
|
|
983
|
+
package_json = project_dir / ".jac" / "client" / "configs" / "package.json"
|
|
984
|
+
assert package_json.exists(), "package.json should have been generated"
|
|
985
|
+
|
|
986
|
+
with open(package_json) as f:
|
|
987
|
+
pkg = json.load(f)
|
|
988
|
+
|
|
989
|
+
assert pkg["dependencies"].get("react"), "package.json should have react"
|
|
990
|
+
assert pkg["devDependencies"].get("vite"), "package.json should have vite"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jac-client
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.12
|
|
4
4
|
Summary: Build full-stack web applications with Jac - one language for frontend and backend.
|
|
5
5
|
Author-email: Jason Mars <jason@mars.ninja>
|
|
6
6
|
Maintainer-email: Jason Mars <jason@mars.ninja>
|
|
@@ -11,7 +11,7 @@ Project-URL: Documentation, https://jac-lang.org
|
|
|
11
11
|
Keywords: jac,jaclang,jaseci,frontend,full-stack,web-development
|
|
12
12
|
Requires-Python: >=3.12
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
|
-
Requires-Dist: jaclang>=0.9.
|
|
14
|
+
Requires-Dist: jaclang>=0.9.12
|
|
15
15
|
Provides-Extra: dev
|
|
16
16
|
Requires-Dist: python-dotenv==1.0.1; extra == "dev"
|
|
17
17
|
Requires-Dist: pytest==8.3.5; extra == "dev"
|
|
@@ -94,7 +94,9 @@ jac_client/plugin/src/targets/impl/registry.impl.jac
|
|
|
94
94
|
jac_client/plugin/src/targets/impl/web_target.impl.jac
|
|
95
95
|
jac_client/plugin/utils/__init__.jac
|
|
96
96
|
jac_client/plugin/utils/bun_installer.jac
|
|
97
|
+
jac_client/plugin/utils/client_deps.jac
|
|
97
98
|
jac_client/plugin/utils/impl/bun_installer.impl.jac
|
|
99
|
+
jac_client/plugin/utils/impl/client_deps.impl.jac
|
|
98
100
|
jac_client/templates/client.jacpack
|
|
99
101
|
jac_client/templates/fullstack.jacpack
|
|
100
102
|
jac_client/tests/__init__.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "jac-client"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.12"
|
|
4
4
|
description = "Build full-stack web applications with Jac - one language for frontend and backend."
|
|
5
5
|
authors = [{name = "Jason Mars", email = "jason@mars.ninja"}]
|
|
6
6
|
maintainers = [{name = "Jason Mars", email = "jason@mars.ninja"}]
|
|
@@ -16,7 +16,7 @@ keywords = [
|
|
|
16
16
|
]
|
|
17
17
|
requires-python = ">=3.12"
|
|
18
18
|
dependencies = [
|
|
19
|
-
"jaclang>=0.9.
|
|
19
|
+
"jaclang>=0.9.12",
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
[project.urls]
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/assets/workers/worker.py
RENAMED
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/CategoryFilter.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/Header.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/ProfitOverview.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/Summary.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/button.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/components/navigation.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/constants/categories.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/constants/clients.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/context/BudgetContext.jac
RENAMED
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/hooks/useLocalStorage.jac
RENAMED
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/BudgetPlanner.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/FeaturesTest.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/LandingPage.jac
RENAMED
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/all-in-one/pages/features_test_ui.cl.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/asset-serving/css-with-image/main.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/asset-serving/image-asset/main.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/asset-serving/import-alias/main.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/material-ui/main.jac
RENAMED
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/sass-example/main.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/styled-components/main.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/css-styling/tailwind-example/main.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-advance/main.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/examples/nested-folders/nested-basic/main.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/import_processor.impl.jac
RENAMED
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/impl/package_installer.impl.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/desktop/sidecar/main.py
RENAMED
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/impl/desktop_target.impl.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/impl/registry.impl.jac
RENAMED
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/plugin/src/targets/impl/web_target.impl.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/client_app_with_antd/app.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/relative_import/button.jac
RENAMED
|
File without changes
|
|
File without changes
|
{jac_client-0.2.11 → jac_client-0.2.12}/jac_client/tests/fixtures/test_fragments_spread/app.jac
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|